All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] extend flow director's IP fields in i40e driver
@ 2015-12-25  8:29 Jingjing Wu
  2015-12-25  8:29 ` [PATCH 1/4] ethdev: extend flow director to support input set selection Jingjing Wu
                   ` (4 more replies)
  0 siblings, 5 replies; 105+ messages in thread
From: Jingjing Wu @ 2015-12-25  8:29 UTC (permalink / raw)
  To: dev

This patch set extends flow director to support filtering by TOS,
Protocol and TTL in i40e driver.

Jingjing Wu (4):
  ethdev: extend flow director to support input set selection
  i40e: split function for input set change of hash and fdir
  i40e: extend flow director to filter by more IP Header fields
  testpmd: extend commands for filter's input set changing

 app/test-pmd/cmdline.c                      | 100 ++++++--
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  34 +--
 drivers/net/i40e/i40e_ethdev.c              | 367 ++++++++++++++++------------
 drivers/net/i40e/i40e_ethdev.h              |  11 +-
 drivers/net/i40e/i40e_fdir.c                |  31 ++-
 lib/librte_ether/rte_eth_ctrl.h             |   8 +
 6 files changed, 344 insertions(+), 207 deletions(-)

-- 
2.4.0

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

* [PATCH 1/4] ethdev: extend flow director to support input set selection
  2015-12-25  8:29 [PATCH 0/4] extend flow director's IP fields in i40e driver Jingjing Wu
@ 2015-12-25  8:29 ` Jingjing Wu
  2015-12-25  8:29 ` [PATCH 2/4] i40e: split function for input set change of hash and fdir Jingjing Wu
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2015-12-25  8:29 UTC (permalink / raw)
  To: dev

This patch add RTE_ETH_INPUT_SET_L3_IP4_TTL,
RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extends
struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
by tos, protocol and ttl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index ce224ad..248f719 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -337,9 +337,11 @@ enum rte_eth_input_set_field {
 	RTE_ETH_INPUT_SET_L3_SRC_IP6,
 	RTE_ETH_INPUT_SET_L3_DST_IP6,
 	RTE_ETH_INPUT_SET_L3_IP4_TOS,
+	RTE_ETH_INPUT_SET_L3_IP4_TTL,
 	RTE_ETH_INPUT_SET_L3_IP4_PROTO,
 	RTE_ETH_INPUT_SET_L3_IP6_TC,
 	RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
+	RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
 
 	/* L4 */
 	RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT = 257,
@@ -407,6 +409,9 @@ struct rte_eth_l2_flow {
 struct rte_eth_ipv4_flow {
 	uint32_t src_ip;      /**< IPv4 source address to match. */
 	uint32_t dst_ip;      /**< IPv4 destination address to match. */
+	uint8_t  tos;         /**< Type of service to match. */
+	uint8_t  ttl;         /**< Time to live */
+	uint8_t  proto;
 };
 
 /**
@@ -443,6 +448,9 @@ struct rte_eth_sctpv4_flow {
 struct rte_eth_ipv6_flow {
 	uint32_t src_ip[4];      /**< IPv6 source address to match. */
 	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
+	uint8_t  tc;             /**< Traffic class to match. */
+	uint8_t  proto;          /**< Protocol, next header. */
+	uint8_t  hop_limits;
 };
 
 /**
-- 
2.4.0

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

* [PATCH 2/4] i40e: split function for input set change of hash and fdir
  2015-12-25  8:29 [PATCH 0/4] extend flow director's IP fields in i40e driver Jingjing Wu
  2015-12-25  8:29 ` [PATCH 1/4] ethdev: extend flow director to support input set selection Jingjing Wu
@ 2015-12-25  8:29 ` Jingjing Wu
  2016-01-20 20:04   ` Chilikin, Andrey
  2015-12-25  8:29 ` [PATCH 3/4] i40e: extend flow director to filter by more IP Header fields Jingjing Wu
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 105+ messages in thread
From: Jingjing Wu @ 2015-12-25  8:29 UTC (permalink / raw)
  To: dev

This patch splited function for input set change of hash and fdir,
and added a new function to set the input set to default when
initialization.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 330 +++++++++++++++++++++--------------------
 drivers/net/i40e/i40e_ethdev.h |  11 +-
 drivers/net/i40e/i40e_fdir.c   |   5 +-
 3 files changed, 180 insertions(+), 166 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index bf6220d..b919aac 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -262,7 +262,8 @@
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD7        0x0000000000000080ULL
 /* 8th word of flex payload */
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD8        0x0000000000000040ULL
-
+/* all 8 words flex payload */
+#define I40E_REG_INSET_FLEX_PAYLOAD_WORDS        0x0000000000003FC0ULL
 #define I40E_REG_INSET_MASK_DEFAULT              0x0000000000000000ULL
 
 #define I40E_TRANSLATE_INSET 0
@@ -373,6 +374,7 @@ static int i40e_dev_udp_tunnel_add(struct rte_eth_dev *dev,
 				struct rte_eth_udp_tunnel *udp_tunnel);
 static int i40e_dev_udp_tunnel_del(struct rte_eth_dev *dev,
 				struct rte_eth_udp_tunnel *udp_tunnel);
+static void i40e_filter_input_set_init(struct i40e_pf *pf);
 static int i40e_ethertype_filter_set(struct i40e_pf *pf,
 			struct rte_eth_ethertype_filter *filter,
 			bool add);
@@ -787,6 +789,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	 * It should be removed once issues are fixed in NVM.
 	 */
 	i40e_flex_payload_reg_init(hw);
+	/* Initialize the input set for filters (hash and fd) to default value */
+	i40e_filter_input_set_init(pf);
 
 	/* Initialize the parameters for adminq */
 	i40e_init_adminq_parameter(hw);
@@ -6545,43 +6549,32 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
-		I40E_INSET_LAST_ETHER_TYPE | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
 	if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD)
@@ -6809,7 +6802,7 @@ i40e_translate_input_set_reg(uint64_t input)
 	return val;
 }
 
-static uint8_t
+static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
@@ -6827,16 +6820,13 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-	if (!inset && nb_elem >= I40E_INSET_MASK_NUM_REG) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++)
-			mask[i] = 0;
-		return I40E_INSET_MASK_NUM_REG;
-	}
 
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if (idx >= nb_elem)
-			break;
-		if (inset & inset_mask_map[i].inset) {
+		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+			if (idx >= nb_elem) {
+				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
+				return -EINVAL;
+			}
 			mask[idx] = inset_mask_map[i].mask;
 			idx++;
 		}
@@ -6845,25 +6835,6 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	return idx;
 }
 
-static uint64_t
-i40e_get_reg_inset(struct i40e_hw *hw, enum rte_filter_type filter,
-			    enum i40e_filter_pctype pctype)
-{
-	uint64_t reg = 0;
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		reg = I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(1, pctype));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(0, pctype));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		reg = I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 1));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 0));
-	}
-
-	return reg;
-}
-
 static void
 i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 {
@@ -6876,103 +6847,149 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)I40E_READ_REG(hw, addr));
 }
 
-static int
-i40e_set_hash_inset_mask(struct i40e_hw *hw,
-			 enum i40e_filter_pctype pctype,
-			 enum rte_filter_input_set_op op,
-			 uint32_t *mask_reg,
-			 uint8_t num)
+static void
+i40e_filter_input_set_init(struct i40e_pf *pf)
 {
-	uint32_t reg;
-	uint8_t i;
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int num, i;
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
-		return -EINVAL;
+	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
+		if (!I40E_VALID_PCTYPE(pctype))
+			continue;
+		input_set = i40e_get_default_input_set(pctype);
 
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
+		num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+						   I40E_INSET_MASK_NUM_REG);
+		if (num < 0)
+			return;
+		inset_reg = i40e_translate_input_set_reg(input_set);
+
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+		for (i = 0; i < num; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     mask_reg[i]);
 			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
 					     mask_reg[i]);
 		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = I40E_READ_REG(hw, I40E_GLQF_HASH_MSK(i, pctype));
-			if (reg & I40E_GLQF_HASH_MSK_FIELD)
-				count++;
+		/*clear unused mask registers of the pctype */
+		for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     0);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     0);
 		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
+		I40E_WRITE_FLUSH(hw);
 
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[j]);
+		/* store the default input set */
+		pf->hash_input_set[pctype] = input_set;
+		pf->fdir.input_set[pctype] = input_set;
 	}
-
-	return 0;
 }
 
-static int
-i40e_set_fd_inset_mask(struct i40e_hw *hw,
-		       enum i40e_filter_pctype pctype,
-		       enum rte_filter_input_set_op op,
-		       uint32_t *mask_reg,
-		       uint8_t num)
+int
+i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			 struct rte_eth_input_set_conf *conf)
 {
-	uint32_t reg;
-	uint8_t i;
+	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	if (!hw || !conf) {
+		PMD_DRV_LOG(ERR, "Invalid pointer");
+		return -EFAULT;
+	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
 		return -EINVAL;
+	}
 
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = I40E_READ_REG(hw, I40E_GLQF_FD_MSK(i, pctype));
-			if (reg & I40E_GLQF_FD_MSK_FIELD)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
+	pctype = i40e_flowtype_to_pctype(conf->flow_type);
+	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
+		PMD_DRV_LOG(ERR, "Not supported flow type (%u)",
+			    conf->flow_type);
+		return -EINVAL;
+	}
 
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[j]);
+	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
+				   conf->inset_size);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to parse input set");
+		return -EINVAL;
 	}
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
+				    input_set) != 0) {
+		PMD_DRV_LOG(ERR, "Invalid input set");
+		return -EINVAL;
+	}
+	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
+		/* get inset value in register */
+		inset_reg = I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(1, pctype));
+		inset_reg <<= I40E_32_BIT_WIDTH;
+		inset_reg |= I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(0, pctype));
+		input_set |= pf->hash_input_set[pctype];
+	}
+	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+					   I40E_INSET_MASK_NUM_REG);
+	if (num < 0)
+		return -EINVAL;
+
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     0);
+	I40E_WRITE_FLUSH(hw);
+
+	pf->hash_input_set[pctype] = input_set;
 	return 0;
 }
 
 int
-i40e_filter_inset_select(struct i40e_hw *hw,
-			 struct rte_eth_input_set_conf *conf,
-			 enum rte_filter_type filter)
+i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			 struct rte_eth_input_set_conf *conf)
 {
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	enum i40e_filter_pctype pctype;
-	uint64_t inset_reg = 0, input_set;
-	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG];
-	uint8_t num;
-	int ret;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
 	if (!hw || !conf) {
 		PMD_DRV_LOG(ERR, "Invalid pointer");
 		return -EFAULT;
 	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
+		return -EINVAL;
+	}
 
 	pctype = i40e_flowtype_to_pctype(conf->flow_type);
 	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
@@ -6980,60 +6997,54 @@ i40e_filter_inset_select(struct i40e_hw *hw,
 			    conf->flow_type);
 		return -EINVAL;
 	}
-	if (filter != RTE_ETH_FILTER_HASH && filter != RTE_ETH_FILTER_FDIR) {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
-
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, filter, input_set) != 0) {
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
+				    input_set) != 0) {
 		PMD_DRV_LOG(ERR, "Invalid input set");
 		return -EINVAL;
 	}
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
-		inset_reg |= i40e_get_reg_inset(hw, filter, pctype);
-	} else if (conf->op != RTE_ETH_INPUT_SET_SELECT) {
-		PMD_DRV_LOG(ERR, "Unsupported input set operation");
-		return -EINVAL;
-	}
+	/* get inset value in register */
+	inset_reg = I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 1));
+	inset_reg <<= I40E_32_BIT_WIDTH;
+	inset_reg |= I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 0));
+
+	/*Can not change the inset reg for flex payload for fdir,
+	 * it is done by writing I40E_PRTQF_FD_FLXINSET
+	 * in i40e_set_flex_mask_on_pctype.
+	 */
+	if (conf->op == RTE_ETH_INPUT_SET_SELECT)
+		inset_reg &= I40E_REG_INSET_FLEX_PAYLOAD_WORDS;
+	else
+		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-	inset_reg |= i40e_translate_input_set_reg(input_set);
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		ret = i40e_set_hash_inset_mask(hw, pctype, conf->op, mask_reg,
-					       num);
-		if (ret)
-			return -EINVAL;
+	if (num < 0)
+		return -EINVAL;
 
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		ret = i40e_set_fd_inset_mask(hw, pctype, conf->op, mask_reg,
-					     num);
-		if (ret)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     0);
 	I40E_WRITE_FLUSH(hw);
 
+	pf->fdir.input_set[pctype] = input_set;
 	return 0;
 }
 
@@ -7085,9 +7096,8 @@ i40e_hash_filter_set(struct i40e_hw *hw, struct rte_eth_hash_filter_info *info)
 				&(info->info.global_conf));
 		break;
 	case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-					       &(info->info.input_set_conf),
-					       RTE_ETH_FILTER_HASH);
+		ret = i40e_hash_filter_inset_select(hw,
+					       &(info->info.input_set_conf));
 		break;
 
 	default:
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 1f9792b..4dc7e1e 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -361,6 +361,8 @@ struct i40e_fdir_info {
 	struct i40e_rx_queue *rxq;
 	void *prg_pkt;                 /* memory for fdir program packet */
 	uint64_t dma_addr;             /* physic address of packet memory*/
+	/* input set bits for each pctype */
+	uint64_t input_set[I40E_FILTER_PCTYPE_MAX];
 	/*
 	 * the rule how bytes stream is extracted as flexible payload
 	 * for each payload layer, the setting can up to three elements
@@ -427,6 +429,8 @@ struct i40e_pf {
 	uint16_t fdir_qp_offset;
 
 	uint16_t hash_lut_size; /* The size of hash lookup table */
+	/* input set bits for each pctype */
+	uint64_t hash_input_set[I40E_FILTER_PCTYPE_MAX];
 	/* store VXLAN UDP ports */
 	uint16_t vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];
 	uint16_t vxlan_bitmap; /* Vxlan bit mask */
@@ -569,9 +573,10 @@ int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 int i40e_select_filter_input_set(struct i40e_hw *hw,
 				 struct rte_eth_input_set_conf *conf,
 				 enum rte_filter_type filter);
-int i40e_filter_inset_select(struct i40e_hw *hw,
-			     struct rte_eth_input_set_conf *conf,
-			     enum rte_filter_type filter);
+int i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			     struct rte_eth_input_set_conf *conf);
+int i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			     struct rte_eth_input_set_conf *conf);
 
 void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct rte_eth_rxq_info *qinfo);
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 9ad6981..155a34a 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -1361,7 +1361,6 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 		     struct rte_eth_fdir_filter_info *info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	int ret = 0;
 
 	if (!info) {
@@ -1371,8 +1370,8 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 
 	switch (info->info_type) {
 	case RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-			&(info->info.input_set_conf), RTE_ETH_FILTER_FDIR);
+		ret = i40e_fdir_filter_inset_select(pf,
+				&(info->info.input_set_conf));
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "FD filter info type (%d) not supported",
-- 
2.4.0

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

* [PATCH 3/4] i40e: extend flow director to filter by more IP Header fields
  2015-12-25  8:29 [PATCH 0/4] extend flow director's IP fields in i40e driver Jingjing Wu
  2015-12-25  8:29 ` [PATCH 1/4] ethdev: extend flow director to support input set selection Jingjing Wu
  2015-12-25  8:29 ` [PATCH 2/4] i40e: split function for input set change of hash and fdir Jingjing Wu
@ 2015-12-25  8:29 ` Jingjing Wu
  2015-12-25  8:30 ` [PATCH 4/4] testpmd: extend commands for filter's input set changing Jingjing Wu
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
  4 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2015-12-25  8:29 UTC (permalink / raw)
  To: dev

This patch extended flow director to select more IP Header fields
as filter input set.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 69 ++++++++++++++++++++++++++++++++++--------
 drivers/net/i40e/i40e_fdir.c   | 26 +++++++++++-----
 2 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index b919aac..290776e 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -218,6 +218,8 @@
 #define I40E_REG_INSET_L3_IP4_TOS                0x0040000000000000ULL
 /* IPv4 Protocol */
 #define I40E_REG_INSET_L3_IP4_PROTO              0x0004000000000000ULL
+/* IPv4 Time to Live */
+#define I40E_REG_INSET_L3_IP4_TTL                0x0004000000000000ULL
 /* Source IPv6 address */
 #define I40E_REG_INSET_L3_SRC_IP6                0x0007F80000000000ULL
 /* Destination IPv6 address */
@@ -226,6 +228,8 @@
 #define I40E_REG_INSET_L3_IP6_TC                 0x0040000000000000ULL
 /* IPv6 Next Header */
 #define I40E_REG_INSET_L3_IP6_NEXT_HDR           0x0008000000000000ULL
+/* IPv6 Hop Limitr */
+#define I40E_REG_INSET_L3_IP6_HOP_LIMIT          0x0008000000000000ULL
 /* Source L4 port */
 #define I40E_REG_INSET_L4_SRC_PORT               0x0000000400000000ULL
 /* Destination L4 port */
@@ -269,10 +273,12 @@
 #define I40E_TRANSLATE_INSET 0
 #define I40E_TRANSLATE_REG   1
 
-#define I40E_INSET_IPV4_TOS_MASK      0x0009FF00UL
-#define I40E_INSET_IPV4_PROTO_MASK    0x000DFF00UL
-#define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
-#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
+#define I40E_INSET_IPV4_TOS_MASK        0x0009FF00UL
+#define I40E_INSET_IPv4_TTL_MASK        0x000D00FFUL
+#define I40E_INSET_IPV4_PROTO_MASK      0x000DFF00UL
+#define I40E_INSET_IPV6_TC_MASK         0x0009F00FUL
+#define I40E_INSET_IPV6_HOP_LIMIT_MASK  0x000CFF00UL
+#define I40E_INSET_IPV6_NEXT_HDR_MASK   0x000C00FFUL
 
 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
@@ -6549,30 +6555,47 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
@@ -6672,11 +6695,14 @@ i40e_parse_input_set(uint64_t *inset,
 		{RTE_ETH_INPUT_SET_L3_DST_IP4, I40E_INSET_IPV4_DST},
 		{RTE_ETH_INPUT_SET_L3_IP4_TOS, I40E_INSET_IPV4_TOS},
 		{RTE_ETH_INPUT_SET_L3_IP4_PROTO, I40E_INSET_IPV4_PROTO},
+		{RTE_ETH_INPUT_SET_L3_IP4_TTL, I40E_INSET_IPV4_TTL},
 		{RTE_ETH_INPUT_SET_L3_SRC_IP6, I40E_INSET_IPV6_SRC},
 		{RTE_ETH_INPUT_SET_L3_DST_IP6, I40E_INSET_IPV6_DST},
 		{RTE_ETH_INPUT_SET_L3_IP6_TC, I40E_INSET_IPV6_TC},
 		{RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
 			I40E_INSET_IPV6_NEXT_HDR},
+		{RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
+			I40E_INSET_IPV6_HOP_LIMIT},
 		{RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT, I40E_INSET_SRC_PORT},
@@ -6763,10 +6789,12 @@ i40e_translate_input_set_reg(uint64_t input)
 		{I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4},
 		{I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS},
 		{I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO},
+		{I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL},
 		{I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6},
 		{I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6},
 		{I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_REG_INSET_L3_IP6_NEXT_HDR},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_REG_INSET_L3_IP6_HOP_LIMIT},
 		{I40E_INSET_SRC_PORT, I40E_REG_INSET_L4_SRC_PORT},
 		{I40E_INSET_DST_PORT, I40E_REG_INSET_L4_DST_PORT},
 		{I40E_INSET_SCTP_VT, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG},
@@ -6806,23 +6834,38 @@ static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
+	uint64_t inset_need_mask = inset;
 
 	static const struct {
 		uint64_t inset;
 		uint32_t mask;
 	} inset_mask_map[] = {
 		{I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK},
+		{I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0},
 		{I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK},
+		{I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK},
 		{I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK},
+		{I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK}
 	};
 
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+		/* Clear the inset bit, if no MASK is required,
+		 * for example proto + ttl
+		 */
+		if ((inset & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset && inset_mask_map[i].mask == 0)
+			inset_need_mask &= ~inset_mask_map[i].inset;
+		if (!inset_need_mask)
+			return 0;
+	}
+	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
+		if ((inset_need_mask & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset) {
 			if (idx >= nb_elem) {
 				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
 				return -EINVAL;
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 155a34a..5ea97e5 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -65,7 +65,9 @@
 #define I40E_FDIR_IP_DEFAULT_TTL            0x40
 #define I40E_FDIR_IP_DEFAULT_VERSION_IHL    0x45
 #define I40E_FDIR_TCP_DEFAULT_DATAOFF       0x50
-#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60300000
+#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60000000
+#define I40E_FDIR_IPv6_TC_OFFSET            20
+
 #define I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS   0xFF
 #define I40E_FDIR_IPv6_PAYLOAD_LEN          380
 #define I40E_FDIR_UDP_DEFAULT_LEN           400
@@ -719,7 +721,13 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
-		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+		ip->next_proto_id = fdir_input->flow.ip4_flow.proto ?
+					fdir_input->flow.ip4_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip->time_to_live = fdir_input->flow.ip4_flow.ttl ?
+					fdir_input->flow.ip4_flow.ttl :
+					I40E_FDIR_IP_DEFAULT_TTL;
+		ip->type_of_service = fdir_input->flow.ip4_flow.tos;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -727,7 +735,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		 */
 		ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
 		ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
-		ip->next_proto_id = next_proto[fdir_input->flow_type];
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
@@ -738,11 +745,17 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 
 		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
-			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
+					 (fdir_input->flow.ipv6_flow.tc <<
+					  I40E_FDIR_IPv6_TC_OFFSET));
 		ip6->payload_len =
 			rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
-		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
-
+		ip6->proto = fdir_input->flow.ipv6_flow.proto ?
+					fdir_input->flow.ipv6_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ?
+					fdir_input->flow.ipv6_flow.hop_limits :
+					I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -754,7 +767,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		rte_memcpy(&(ip6->dst_addr),
 			   &(fdir_input->flow.ipv6_flow.src_ip),
 			   IPV6_ADDR_LEN);
-		ip6->proto = next_proto[fdir_input->flow_type];
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
-- 
2.4.0

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

* [PATCH 4/4] testpmd: extend commands for filter's input set changing
  2015-12-25  8:29 [PATCH 0/4] extend flow director's IP fields in i40e driver Jingjing Wu
                   ` (2 preceding siblings ...)
  2015-12-25  8:29 ` [PATCH 3/4] i40e: extend flow director to filter by more IP Header fields Jingjing Wu
@ 2015-12-25  8:30 ` Jingjing Wu
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
  4 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2015-12-25  8:30 UTC (permalink / raw)
  To: dev

This patch extends commands for filter's input set changing.
It added tos, protocol and ttl as filter's input fields, and
remove the words selection from flex payloads for flow director.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 100 ++++++++++++++++++++++------
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  34 +++++-----
 2 files changed, 97 insertions(+), 37 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 73298c9..da1d3f2 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -640,6 +640,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"flow_director_filter (port_id) mode IP (add|del|update)"
 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
+			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -649,6 +650,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
+			" tos (tos_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -658,7 +660,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-sctp|ipv6-sctp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
-			" tag (verification_tag) vlan (vlan_value)"
+			" tag (verification_tag) "
+			" tos (tos_value) ttl (ttl_value)"
+			" vlan (vlan_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -738,14 +742,15 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"fld-8th|none) (select|add)\n"
 			"    Set the input set for hash.\n\n"
 
-			"set_fdir_input_set (port_id) (ipv4|ipv4-frag|"
-			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+			"set_fdir_input_set (port_id) "
+			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
-			"udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|"
-			"sctp-src-port|sctp-dst-port|sctp-veri-tag|fld-1st|"
-			"fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
-			"fld-8th|none) (select|add)\n"
+			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
+			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
+			"udp-dst-port|tcp-src-port|tcp-dst-port|"
+			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
+			" (select|add)\n"
 			"    Set the input set for FDir.\n\n"
 		);
 	}
@@ -7983,6 +7988,12 @@ struct cmd_flow_director_result {
 	uint16_t port_dst;
 	cmdline_fixed_string_t verify_tag;
 	uint32_t verify_tag_value;
+	cmdline_ipaddr_t tos;
+	uint8_t tos_value;
+	cmdline_ipaddr_t proto;
+	uint8_t proto_value;
+	cmdline_ipaddr_t ttl;
+	uint8_t ttl_value;
 	cmdline_fixed_string_t vlan;
 	uint16_t vlan_value;
 	cmdline_fixed_string_t flexbytes;
@@ -8162,12 +8173,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 	switch (entry.input.flow_type) {
 	case RTE_ETH_FLOW_FRAG_IPV4:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+		entry.input.flow.ip4_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 		IPV4_ADDR_TO_UINT(res->ip_dst,
 			entry.input.flow.ip4_flow.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.ip4_flow.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8179,6 +8193,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp4_flow.ip.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.sctp4_flow.ip.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8189,12 +8205,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 		break;
 	case RTE_ETH_FLOW_FRAG_IPV6:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+		entry.input.flow.ipv6_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 		IPV6_ADDR_TO_ARRAY(res->ip_dst,
 			entry.input.flow.ipv6_flow.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.ipv6_flow.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8206,6 +8225,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp6_flow.ip.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.sctp6_flow.ip.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8333,6 +8354,24 @@ cmdline_parse_token_string_t cmd_flow_director_verify_tag =
 cmdline_parse_token_num_t cmd_flow_director_verify_tag_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
 			      verify_tag_value, UINT32);
+cmdline_parse_token_string_t cmd_flow_director_tos =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 tos, "tos");
+cmdline_parse_token_num_t cmd_flow_director_tos_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      tos_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_proto =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 proto, "proto");
+cmdline_parse_token_num_t cmd_flow_director_proto_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      proto_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_ttl =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 ttl, "ttl");
+cmdline_parse_token_num_t cmd_flow_director_ttl_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      ttl_value, UINT8);
 cmdline_parse_token_string_t cmd_flow_director_vlan =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 vlan, "vlan");
@@ -8411,6 +8450,12 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ip_src,
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_proto,
+		(void *)&cmd_flow_director_proto_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8443,6 +8488,10 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
 		(void *)&cmd_flow_director_port_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8477,6 +8526,10 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_port_dst,
 		(void *)&cmd_flow_director_verify_tag,
 		(void *)&cmd_flow_director_verify_tag_value,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -9403,16 +9456,19 @@ str2inset(char *string)
 		char str[32];
 		enum rte_eth_input_set_field inset;
 	} inset_table[] = {
+		{"ethertype", RTE_ETH_INPUT_SET_L2_ETHERTYPE},
 		{"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
 		{"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
 		{"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
 		{"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
 		{"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
 		{"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
+		{"ipv4-ttl", RTE_ETH_INPUT_SET_L3_IP4_TTL},
 		{"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
 		{"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
 		{"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
 		{"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
+		{"ipv6-hop-limits", RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS},
 		{"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
 		{"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
 		{"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
@@ -9471,7 +9527,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
 		flow_type,
-		"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
@@ -9490,8 +9546,8 @@ cmdline_parse_inst_t cmd_set_hash_input_set = {
 	.f = cmd_set_hash_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_hash_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
@@ -9546,15 +9602,16 @@ cmdline_parse_token_num_t cmd_set_fdir_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	flow_type,
-	"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+	"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 	"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#udp-src-port#udp-dst-port#"
+	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
+	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
-	"sctp-veri-tag#fld-1st#fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#"
-	"fld-7th#fld-8th#none");
+	"sctp-veri-tag#none");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	select, "select#add");
@@ -9563,12 +9620,13 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.f = cmd_set_fdir_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_fdir_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port|"
-	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|"
-	"fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
-	"fld-7th|fld-8th|none select|add",
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
+	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
+	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
+	"sctp-veri-tag|none select|add",
 	.tokens = {
 		(void *)&cmd_set_fdir_input_set_cmd,
 		(void *)&cmd_set_fdir_input_set_port_id,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index a520cc5..ba249b4 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1678,8 +1678,9 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 # Commands to add flow director filters of different flow types::
 
    flow_director_filter (port_id) mode IP (add|del|update) \
-                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)
+                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag) \
                         src (src_ip_address) dst (dst_ip_address) \
+                        tos (tos_value) proto (proto_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) pf|vf(vf_id) queue (queue_id) \
                         fd_id (fd_id_value)
@@ -1688,6 +1689,7 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp) \
                         src (src_ip_address) (src_port) \
                         dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) queue pf|vf(vf_id) (queue_id) \
                         fd_id (fd_id_value)
@@ -1695,7 +1697,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
    flow_director_filter (port_id) mode IP (add|del|update) \
                         flow (ipv4-sctp|ipv6-sctp) \
                         src (src_ip_address) (src_port) \
-                        dst (dst_ip_address) (dst_port)
+                        dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         tag (verification_tag) vlan (vlan_value) \
                         flexbytes (flexbytes_value) (drop|fwd) \
                         pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)
@@ -1841,33 +1844,32 @@ set_hash_input_set
 
 Set the input set for hash::
 
-   set_hash_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   set_hash_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
    l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port| \
    tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
    udp-key|gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th| \
    fld-8th|none) (select|add)
 
-For example, to add source IP to hash input set for flow type of ipv4 on port 0::
+For example, to add source IP to hash input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_hash_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_hash_input_set 0 ipv4-udp src-ipv4 add
 
 set_fdir_input_set
 ~~~~~~~~~~~~~~~~~~
+Set the input set for flow dirrctor::
 
-Set the input set for Fdir::
-
-   set_fdir_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)
-   (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port| \
-   tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
-   fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|fld-8th|none) \
-   (select|add)
+   set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
+   tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
+   sctp-dst-port|sctp-veri-tag|none) (select|add)
 
-For example to add source IP to FD input set for flow type of ipv4 on port 0::
+For example to add source IP to FD input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_fdir_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_fdir_input_set 0 ipv4-udp src-ipv4 add
 
 global_config
 ~~~~~~~~~~~~~
-- 
2.4.0

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

* Re: [PATCH 2/4] i40e: split function for input set change of hash and fdir
  2015-12-25  8:29 ` [PATCH 2/4] i40e: split function for input set change of hash and fdir Jingjing Wu
@ 2016-01-20 20:04   ` Chilikin, Andrey
  2016-01-21  1:28     ` Wu, Jingjing
  0 siblings, 1 reply; 105+ messages in thread
From: Chilikin, Andrey @ 2016-01-20 20:04 UTC (permalink / raw)
  To: Wu, Jingjing, dev

Hi Jingjing,

As I can see this patch not only splits fdir functionality from common fdir/hash code but also removes compatibility with DPDK 2.2 as it deletes I40E_INSET_FLEX_PAYLOAD from valid fdir input set values. Yes, flexible payload configuration can be set for fdir separately at the port initialization, but this is more legacy from the previous generations of NICs which did not support dynamic input set configuration. I believe it would better to have I40E_INSET_FLEX_PAYLOAD valid for fdir input set same as in DPDK 2.2. So in legacy mode, when application has to run on an old NIC and on a new one, only legacy configuration would be used, but for applications targeting new HW single point of configuration would be used instead of mix of two.

Regards,
Andrey

> -----Original Message-----
> From: Wu, Jingjing
> Sent: Friday, December 25, 2015 8:30 AM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; Zhang, Helin; Chilikin, Andrey; Pei, Yulong
> Subject: [PATCH 2/4] i40e: split function for input set change of hash and fdir
> 
> This patch splited function for input set change of hash and fdir, and added a
> new function to set the input set to default when initialization.
> 
> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c | 330 +++++++++++++++++++++--------------------
>  drivers/net/i40e/i40e_ethdev.h |  11 +-
>  drivers/net/i40e/i40e_fdir.c   |   5 +-
>  3 files changed, 180 insertions(+), 166 deletions(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index bf6220d..b919aac 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -262,7 +262,8 @@
>  #define I40E_REG_INSET_FLEX_PAYLOAD_WORD7
> 0x0000000000000080ULL
>  /* 8th word of flex payload */
>  #define I40E_REG_INSET_FLEX_PAYLOAD_WORD8
> 0x0000000000000040ULL
> -
> +/* all 8 words flex payload */
> +#define I40E_REG_INSET_FLEX_PAYLOAD_WORDS
> 0x0000000000003FC0ULL
>  #define I40E_REG_INSET_MASK_DEFAULT              0x0000000000000000ULL
> 
>  #define I40E_TRANSLATE_INSET 0
> @@ -373,6 +374,7 @@ static int i40e_dev_udp_tunnel_add(struct rte_eth_dev
> *dev,
>  				struct rte_eth_udp_tunnel *udp_tunnel);  static
> int i40e_dev_udp_tunnel_del(struct rte_eth_dev *dev,
>  				struct rte_eth_udp_tunnel *udp_tunnel);
> +static void i40e_filter_input_set_init(struct i40e_pf *pf);
>  static int i40e_ethertype_filter_set(struct i40e_pf *pf,
>  			struct rte_eth_ethertype_filter *filter,
>  			bool add);
> @@ -787,6 +789,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
>  	 * It should be removed once issues are fixed in NVM.
>  	 */
>  	i40e_flex_payload_reg_init(hw);
> +	/* Initialize the input set for filters (hash and fd) to default value */
> +	i40e_filter_input_set_init(pf);
> 
>  	/* Initialize the parameters for adminq */
>  	i40e_init_adminq_parameter(hw);
> @@ -6545,43 +6549,32 @@ i40e_get_valid_input_set(enum i40e_filter_pctype
> pctype,
>  	 */
>  	static const uint64_t valid_fdir_inset_table[] = {
>  		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
> -		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
>  		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
>  		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
> -		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
>  		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
> -		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
> -		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
>  		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
>  		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
>  		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_SCTP_VT,
>  		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
> -		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
>  		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
> -		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
>  		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
> -		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
> -		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
>  		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
> -		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
> -		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
>  		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
>  		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
>  		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
> -		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_SCTP_VT,
>  		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
> -		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
> -		I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
>  		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
> -		I40E_INSET_LAST_ETHER_TYPE | I40E_INSET_FLEX_PAYLOAD,
> +		I40E_INSET_LAST_ETHER_TYPE,
>  	};
> 
>  	if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) @@ -6809,7 +6802,7
> @@ i40e_translate_input_set_reg(uint64_t input)
>  	return val;
>  }
> 
> -static uint8_t
> +static int
>  i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t
> nb_elem)  {
>  	uint8_t i, idx = 0;
> @@ -6827,16 +6820,13 @@ i40e_generate_inset_mask_reg(uint64_t inset,
> uint32_t *mask, uint8_t nb_elem)
>  	if (!inset || !mask || !nb_elem)
>  		return 0;
> 
> -	if (!inset && nb_elem >= I40E_INSET_MASK_NUM_REG) {
> -		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++)
> -			mask[i] = 0;
> -		return I40E_INSET_MASK_NUM_REG;
> -	}
> 
>  	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
> -		if (idx >= nb_elem)
> -			break;
> -		if (inset & inset_mask_map[i].inset) {
> +		if ((inset & inset_mask_map[i].inset) ==
> inset_mask_map[i].inset) {
> +			if (idx >= nb_elem) {
> +				PMD_DRV_LOG(ERR, "exceed maximal
> number of bitmasks");
> +				return -EINVAL;
> +			}
>  			mask[idx] = inset_mask_map[i].mask;
>  			idx++;
>  		}
> @@ -6845,25 +6835,6 @@ i40e_generate_inset_mask_reg(uint64_t inset,
> uint32_t *mask, uint8_t nb_elem)
>  	return idx;
>  }
> 
> -static uint64_t
> -i40e_get_reg_inset(struct i40e_hw *hw, enum rte_filter_type filter,
> -			    enum i40e_filter_pctype pctype)
> -{
> -	uint64_t reg = 0;
> -
> -	if (filter == RTE_ETH_FILTER_HASH) {
> -		reg = I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(1,
> pctype));
> -		reg <<= I40E_32_BIT_WIDTH;
> -		reg |= I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(0,
> pctype));
> -	} else if (filter == RTE_ETH_FILTER_FDIR) {
> -		reg = I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 1));
> -		reg <<= I40E_32_BIT_WIDTH;
> -		reg |= I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 0));
> -	}
> -
> -	return reg;
> -}
> -
>  static void
>  i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)  { @@
> -6876,103 +6847,149 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t
> addr, uint32_t val)
>  		    (uint32_t)I40E_READ_REG(hw, addr));  }
> 
> -static int
> -i40e_set_hash_inset_mask(struct i40e_hw *hw,
> -			 enum i40e_filter_pctype pctype,
> -			 enum rte_filter_input_set_op op,
> -			 uint32_t *mask_reg,
> -			 uint8_t num)
> +static void
> +i40e_filter_input_set_init(struct i40e_pf *pf)
>  {
> -	uint32_t reg;
> -	uint8_t i;
> +	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> +	enum i40e_filter_pctype pctype;
> +	uint64_t input_set, inset_reg;
> +	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
> +	int num, i;
> 
> -	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
> -		return -EINVAL;
> +	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
> +	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
> +		if (!I40E_VALID_PCTYPE(pctype))
> +			continue;
> +		input_set = i40e_get_default_input_set(pctype);
> 
> -	if (op == RTE_ETH_INPUT_SET_SELECT) {
> -		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
> -			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i,
> pctype),
> -					     0);
> -			if (i >= num)
> -				continue;
> +		num = i40e_generate_inset_mask_reg(input_set, mask_reg,
> +
> I40E_INSET_MASK_NUM_REG);
> +		if (num < 0)
> +			return;
> +		inset_reg = i40e_translate_input_set_reg(input_set);
> +
> +		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
> +				      (uint32_t)(inset_reg & UINT32_MAX));
> +		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
> +				     (uint32_t)((inset_reg >>
> +				     I40E_32_BIT_WIDTH) & UINT32_MAX));
> +		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
> +				      (uint32_t)(inset_reg & UINT32_MAX));
> +		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
> +				     (uint32_t)((inset_reg >>
> +				     I40E_32_BIT_WIDTH) & UINT32_MAX));
> +
> +		for (i = 0; i < num; i++) {
> +			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i,
> pctype),
> +					     mask_reg[i]);
>  			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i,
> pctype),
>  					     mask_reg[i]);
>  		}
> -	} else if (op == RTE_ETH_INPUT_SET_ADD) {
> -		uint8_t j, count = 0;
> -
> -		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
> -			reg = I40E_READ_REG(hw, I40E_GLQF_HASH_MSK(i,
> pctype));
> -			if (reg & I40E_GLQF_HASH_MSK_FIELD)
> -				count++;
> +		/*clear unused mask registers of the pctype */
> +		for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
> +			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i,
> pctype),
> +					     0);
> +			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i,
> pctype),
> +					     0);
>  		}
> -		if (count + num > I40E_INSET_MASK_NUM_REG)
> -			return -EINVAL;
> +		I40E_WRITE_FLUSH(hw);
> 
> -		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
> -			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i,
> pctype),
> -					     mask_reg[j]);
> +		/* store the default input set */
> +		pf->hash_input_set[pctype] = input_set;
> +		pf->fdir.input_set[pctype] = input_set;
>  	}
> -
> -	return 0;
>  }
> 
> -static int
> -i40e_set_fd_inset_mask(struct i40e_hw *hw,
> -		       enum i40e_filter_pctype pctype,
> -		       enum rte_filter_input_set_op op,
> -		       uint32_t *mask_reg,
> -		       uint8_t num)
> +int
> +i40e_hash_filter_inset_select(struct i40e_hw *hw,
> +			 struct rte_eth_input_set_conf *conf)
>  {
> -	uint32_t reg;
> -	uint8_t i;
> +	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
> +	enum i40e_filter_pctype pctype;
> +	uint64_t input_set, inset_reg = 0;
> +	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
> +	int ret, i, num;
> 
> -	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
> +	if (!hw || !conf) {
> +		PMD_DRV_LOG(ERR, "Invalid pointer");
> +		return -EFAULT;
> +	}
> +	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
> +	    conf->op != RTE_ETH_INPUT_SET_ADD) {
> +		PMD_DRV_LOG(ERR, "Unsupported input set operation");
>  		return -EINVAL;
> +	}
> 
> -	if (op == RTE_ETH_INPUT_SET_SELECT) {
> -		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
> -			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i,
> pctype),
> -					     0);
> -			if (i >= num)
> -				continue;
> -			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i,
> pctype),
> -					     mask_reg[i]);
> -		}
> -	} else if (op == RTE_ETH_INPUT_SET_ADD) {
> -		uint8_t j, count = 0;
> -
> -		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
> -			reg = I40E_READ_REG(hw, I40E_GLQF_FD_MSK(i,
> pctype));
> -			if (reg & I40E_GLQF_FD_MSK_FIELD)
> -				count++;
> -		}
> -		if (count + num > I40E_INSET_MASK_NUM_REG)
> -			return -EINVAL;
> +	pctype = i40e_flowtype_to_pctype(conf->flow_type);
> +	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
> +		PMD_DRV_LOG(ERR, "Not supported flow type (%u)",
> +			    conf->flow_type);
> +		return -EINVAL;
> +	}
> 
> -		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
> -			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i,
> pctype),
> -					     mask_reg[j]);
> +	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
> +				   conf->inset_size);
> +	if (ret) {
> +		PMD_DRV_LOG(ERR, "Failed to parse input set");
> +		return -EINVAL;
>  	}
> +	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
> +				    input_set) != 0) {
> +		PMD_DRV_LOG(ERR, "Invalid input set");
> +		return -EINVAL;
> +	}
> +	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
> +		/* get inset value in register */
> +		inset_reg = I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(1,
> pctype));
> +		inset_reg <<= I40E_32_BIT_WIDTH;
> +		inset_reg |= I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(0,
> pctype));
> +		input_set |= pf->hash_input_set[pctype];
> +	}
> +	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
> +					   I40E_INSET_MASK_NUM_REG);
> +	if (num < 0)
> +		return -EINVAL;
> +
> +	inset_reg |= i40e_translate_input_set_reg(input_set);
> 
> +	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
> +			      (uint32_t)(inset_reg & UINT32_MAX));
> +	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
> +			     (uint32_t)((inset_reg >>
> +			     I40E_32_BIT_WIDTH) & UINT32_MAX));
> +
> +	for (i = 0; i < num; i++)
> +		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
> +				     mask_reg[i]);
> +	/*clear unused mask registers of the pctype */
> +	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
> +		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
> +				     0);
> +	I40E_WRITE_FLUSH(hw);
> +
> +	pf->hash_input_set[pctype] = input_set;
>  	return 0;
>  }
> 
>  int
> -i40e_filter_inset_select(struct i40e_hw *hw,
> -			 struct rte_eth_input_set_conf *conf,
> -			 enum rte_filter_type filter)
> +i40e_fdir_filter_inset_select(struct i40e_pf *pf,
> +			 struct rte_eth_input_set_conf *conf)
>  {
> +	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
>  	enum i40e_filter_pctype pctype;
> -	uint64_t inset_reg = 0, input_set;
> -	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG];
> -	uint8_t num;
> -	int ret;
> +	uint64_t input_set, inset_reg = 0;
> +	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
> +	int ret, i, num;
> 
>  	if (!hw || !conf) {
>  		PMD_DRV_LOG(ERR, "Invalid pointer");
>  		return -EFAULT;
>  	}
> +	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
> +	    conf->op != RTE_ETH_INPUT_SET_ADD) {
> +		PMD_DRV_LOG(ERR, "Unsupported input set operation");
> +		return -EINVAL;
> +	}
> 
>  	pctype = i40e_flowtype_to_pctype(conf->flow_type);
>  	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) { @@ -
> 6980,60 +6997,54 @@ i40e_filter_inset_select(struct i40e_hw *hw,
>  			    conf->flow_type);
>  		return -EINVAL;
>  	}
> -	if (filter != RTE_ETH_FILTER_HASH && filter != RTE_ETH_FILTER_FDIR)
> {
> -		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
> -		return -EINVAL;
> -	}
> -
>  	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
>  				   conf->inset_size);
>  	if (ret) {
>  		PMD_DRV_LOG(ERR, "Failed to parse input set");
>  		return -EINVAL;
>  	}
> -	if (i40e_validate_input_set(pctype, filter, input_set) != 0) {
> +	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
> +				    input_set) != 0) {
>  		PMD_DRV_LOG(ERR, "Invalid input set");
>  		return -EINVAL;
>  	}
> 
> -	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
> -		inset_reg |= i40e_get_reg_inset(hw, filter, pctype);
> -	} else if (conf->op != RTE_ETH_INPUT_SET_SELECT) {
> -		PMD_DRV_LOG(ERR, "Unsupported input set operation");
> -		return -EINVAL;
> -	}
> +	/* get inset value in register */
> +	inset_reg = I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 1));
> +	inset_reg <<= I40E_32_BIT_WIDTH;
> +	inset_reg |= I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 0));
> +
> +	/*Can not change the inset reg for flex payload for fdir,
> +	 * it is done by writing I40E_PRTQF_FD_FLXINSET
> +	 * in i40e_set_flex_mask_on_pctype.
> +	 */
> +	if (conf->op == RTE_ETH_INPUT_SET_SELECT)
> +		inset_reg &= I40E_REG_INSET_FLEX_PAYLOAD_WORDS;
> +	else
> +		input_set |= pf->fdir.input_set[pctype];
>  	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
>  					   I40E_INSET_MASK_NUM_REG);
> -	inset_reg |= i40e_translate_input_set_reg(input_set);
> -
> -	if (filter == RTE_ETH_FILTER_HASH) {
> -		ret = i40e_set_hash_inset_mask(hw, pctype, conf->op,
> mask_reg,
> -					       num);
> -		if (ret)
> -			return -EINVAL;
> +	if (num < 0)
> +		return -EINVAL;
> 
> -		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
> -				      (uint32_t)(inset_reg & UINT32_MAX));
> -		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
> -				     (uint32_t)((inset_reg >>
> -				     I40E_32_BIT_WIDTH) & UINT32_MAX));
> -	} else if (filter == RTE_ETH_FILTER_FDIR) {
> -		ret = i40e_set_fd_inset_mask(hw, pctype, conf->op, mask_reg,
> -					     num);
> -		if (ret)
> -			return -EINVAL;
> +	inset_reg |= i40e_translate_input_set_reg(input_set);
> 
> -		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
> -				      (uint32_t)(inset_reg & UINT32_MAX));
> -		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
> -				     (uint32_t)((inset_reg >>
> -				     I40E_32_BIT_WIDTH) & UINT32_MAX));
> -	} else {
> -		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
> -		return -EINVAL;
> -	}
> +	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
> +			      (uint32_t)(inset_reg & UINT32_MAX));
> +	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
> +			     (uint32_t)((inset_reg >>
> +			     I40E_32_BIT_WIDTH) & UINT32_MAX));
> +
> +	for (i = 0; i < num; i++)
> +		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
> +				     mask_reg[i]);
> +	/*clear unused mask registers of the pctype */
> +	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
> +		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
> +				     0);
>  	I40E_WRITE_FLUSH(hw);
> 
> +	pf->fdir.input_set[pctype] = input_set;
>  	return 0;
>  }
> 
> @@ -7085,9 +7096,8 @@ i40e_hash_filter_set(struct i40e_hw *hw, struct
> rte_eth_hash_filter_info *info)
>  				&(info->info.global_conf));
>  		break;
>  	case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
> -		ret = i40e_filter_inset_select(hw,
> -					       &(info->info.input_set_conf),
> -					       RTE_ETH_FILTER_HASH);
> +		ret = i40e_hash_filter_inset_select(hw,
> +					       &(info->info.input_set_conf));
>  		break;
> 
>  	default:
> diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
> index 1f9792b..4dc7e1e 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -361,6 +361,8 @@ struct i40e_fdir_info {
>  	struct i40e_rx_queue *rxq;
>  	void *prg_pkt;                 /* memory for fdir program packet */
>  	uint64_t dma_addr;             /* physic address of packet memory*/
> +	/* input set bits for each pctype */
> +	uint64_t input_set[I40E_FILTER_PCTYPE_MAX];
>  	/*
>  	 * the rule how bytes stream is extracted as flexible payload
>  	 * for each payload layer, the setting can up to three elements @@ -
> 427,6 +429,8 @@ struct i40e_pf {
>  	uint16_t fdir_qp_offset;
> 
>  	uint16_t hash_lut_size; /* The size of hash lookup table */
> +	/* input set bits for each pctype */
> +	uint64_t hash_input_set[I40E_FILTER_PCTYPE_MAX];
>  	/* store VXLAN UDP ports */
>  	uint16_t vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];
>  	uint16_t vxlan_bitmap; /* Vxlan bit mask */ @@ -569,9 +573,10 @@
> int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,  int
> i40e_select_filter_input_set(struct i40e_hw *hw,
>  				 struct rte_eth_input_set_conf *conf,
>  				 enum rte_filter_type filter);
> -int i40e_filter_inset_select(struct i40e_hw *hw,
> -			     struct rte_eth_input_set_conf *conf,
> -			     enum rte_filter_type filter);
> +int i40e_hash_filter_inset_select(struct i40e_hw *hw,
> +			     struct rte_eth_input_set_conf *conf); int
> +i40e_fdir_filter_inset_select(struct i40e_pf *pf,
> +			     struct rte_eth_input_set_conf *conf);
> 
>  void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
>  	struct rte_eth_rxq_info *qinfo);
> diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index
> 9ad6981..155a34a 100644
> --- a/drivers/net/i40e/i40e_fdir.c
> +++ b/drivers/net/i40e/i40e_fdir.c
> @@ -1361,7 +1361,6 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
>  		     struct rte_eth_fdir_filter_info *info)  {
>  	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data-
> >dev_private);
> -	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
>  	int ret = 0;
> 
>  	if (!info) {
> @@ -1371,8 +1370,8 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
> 
>  	switch (info->info_type) {
>  	case RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT:
> -		ret = i40e_filter_inset_select(hw,
> -			&(info->info.input_set_conf), RTE_ETH_FILTER_FDIR);
> +		ret = i40e_fdir_filter_inset_select(pf,
> +				&(info->info.input_set_conf));
>  		break;
>  	default:
>  		PMD_DRV_LOG(ERR, "FD filter info type (%d) not supported",
> --
> 2.4.0

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

* Re: [PATCH 2/4] i40e: split function for input set change of hash and fdir
  2016-01-20 20:04   ` Chilikin, Andrey
@ 2016-01-21  1:28     ` Wu, Jingjing
  2016-01-21 20:06       ` Chilikin, Andrey
  0 siblings, 1 reply; 105+ messages in thread
From: Wu, Jingjing @ 2016-01-21  1:28 UTC (permalink / raw)
  To: Chilikin, Andrey, dev

Hi, Andrey

Thanks for your comments. You are correct, I removed the I40E_INSET_FLEX_PAYLOAD
from valid fdir input set values, and this is one reason why I splited function for input set
change of hash and and it is because all flex payload configuration can be
set in struct rte_fdir_conf during device configure phase. And it is a more flexible configuration
including flexpayload's selection, input set selection by word and mask setting in bits.

If I enable it in the input set change API, it will be duplicate. And the input set change on
flexible payload only on word, just some ability compared with rte_fdir_conf.
If flexible selection isn't done in  struct rte_fdir_conf, the input set 
selection in input set change API doesn't make sense. If flexible selection is done in
struct rte_fdir_conf, why not selection input set in struct rte_fdir_conf at the same time?

And about you concern, "when application has to run on an old NIC and on a new one",
The rte_fdir_conf is for each eth_dev, so it will be fine.

Thanks
Jingjing  


> -----Original Message-----
> From: Chilikin, Andrey
> Sent: Thursday, January 21, 2016 4:05 AM
> To: Wu, Jingjing; dev@dpdk.org
> Cc: Zhang, Helin; Pei, Yulong; Ananyev, Konstantin
> Subject: RE: [PATCH 2/4] i40e: split function for input set change of hash and
> fdir
> 
> Hi Jingjing,
> 
> As I can see this patch not only splits fdir functionality from common
> fdir/hash code but also removes compatibility with DPDK 2.2 as it deletes
> I40E_INSET_FLEX_PAYLOAD from valid fdir input set values. Yes, flexible
> payload configuration can be set for fdir separately at the port initialization,
> but this is more legacy from the previous generations of NICs which did not
> support dynamic input set configuration. I believe it would better to have
> I40E_INSET_FLEX_PAYLOAD valid for fdir input set same as in DPDK 2.2. So in
> legacy mode, when application has to run on an old NIC and on a new one,
> only legacy configuration would be used, but for applications targeting new
> HW single point of configuration would be used instead of mix of two.
> 
> Regards,
> Andrey
> 

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

* Re: [PATCH 2/4] i40e: split function for input set change of hash and fdir
  2016-01-21  1:28     ` Wu, Jingjing
@ 2016-01-21 20:06       ` Chilikin, Andrey
  2016-01-26  1:12         ` Wu, Jingjing
  0 siblings, 1 reply; 105+ messages in thread
From: Chilikin, Andrey @ 2016-01-21 20:06 UTC (permalink / raw)
  To: Wu, Jingjing, dev

Hi Jingjing,

> -----Original Message-----
> From: Wu, Jingjing
> Sent: Thursday, January 21, 2016 1:29 AM
> To: Chilikin, Andrey; dev@dpdk.org
> Cc: Zhang, Helin; Pei, Yulong; Ananyev, Konstantin
> Subject: RE: [PATCH 2/4] i40e: split function for input set change of hash and
> fdir
> 
> Hi, Andrey
> 
> Thanks for your comments. You are correct, I removed the
> I40E_INSET_FLEX_PAYLOAD from valid fdir input set values, and this is one
> reason why I splited function for input set change of hash and and it is because
> all flex payload configuration can be set in struct rte_fdir_conf during device
> configure phase. And it is a more flexible configuration including flexpayload's
> selection, input set selection by word and mask setting in bits.

Should it be then two patches? First patch to split fdir and hash input set configuration and then second one to remove existing functionality? At the moment it is not obvious that this patch not just splits fdir input set configuration but removes some features in a way that fdir it is not compatible with DPDK 2.2 anymore.

> 
> If I enable it in the input set change API, it will be duplicate. And the input set
> change on flexible payload only on word, just some ability compared with
> rte_fdir_conf.
> If flexible selection isn't done in  struct rte_fdir_conf, the input set selection in
> input set change API doesn't make sense. If flexible selection is done in struct
> rte_fdir_conf, why not selection input set in struct rte_fdir_conf at the same
> time?

I do not have a problem with selecting it at the same time - it always was this way with the legacy systems. But now new NIC supports new way of configuring input set with flexible payload as a part of this input set. So why not to have new way of configuration available as well and change input set using one API call instead of splitting single configuration in to two parts?

> And about you concern, "when application has to run on an old NIC and on a
> new one", The rte_fdir_conf is for each eth_dev, so it will be fine.
> 
> Thanks
> Jingjing

Regards,
Andrey

> 
> 
> > -----Original Message-----
> > From: Chilikin, Andrey
> > Sent: Thursday, January 21, 2016 4:05 AM
> > To: Wu, Jingjing; dev@dpdk.org
> > Cc: Zhang, Helin; Pei, Yulong; Ananyev, Konstantin
> > Subject: RE: [PATCH 2/4] i40e: split function for input set change of
> > hash and fdir
> >
> > Hi Jingjing,
> >
> > As I can see this patch not only splits fdir functionality from common
> > fdir/hash code but also removes compatibility with DPDK 2.2 as it
> > deletes I40E_INSET_FLEX_PAYLOAD from valid fdir input set values. Yes,
> > flexible payload configuration can be set for fdir separately at the
> > port initialization, but this is more legacy from the previous
> > generations of NICs which did not support dynamic input set
> > configuration. I believe it would better to have
> > I40E_INSET_FLEX_PAYLOAD valid for fdir input set same as in DPDK 2.2.
> > So in legacy mode, when application has to run on an old NIC and on a
> > new one, only legacy configuration would be used, but for applications
> targeting new HW single point of configuration would be used instead of mix of
> two.
> >
> > Regards,
> > Andrey
> >

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

* Re: [PATCH 2/4] i40e: split function for input set change of hash and fdir
  2016-01-21 20:06       ` Chilikin, Andrey
@ 2016-01-26  1:12         ` Wu, Jingjing
  0 siblings, 0 replies; 105+ messages in thread
From: Wu, Jingjing @ 2016-01-26  1:12 UTC (permalink / raw)
  To: Chilikin, Andrey, dev


> >
> > Thanks for your comments. You are correct, I removed the
> > I40E_INSET_FLEX_PAYLOAD from valid fdir input set values, and this is
> > one reason why I splited function for input set change of hash and and
> > it is because all flex payload configuration can be set in struct
> > rte_fdir_conf during device configure phase. And it is a more flexible
> > configuration including flexpayload's selection, input set selection by word
> and mask setting in bits.
> 
> Should it be then two patches? First patch to split fdir and hash input set
> configuration and then second one to remove existing functionality? At the
> moment it is not obvious that this patch not just splits fdir input set
> configuration but removes some features in a way that fdir it is not
> compatible with DPDK 2.2 anymore.
> 
OK. I will try to split it to two patches.

> >
> > If I enable it in the input set change API, it will be duplicate. And
> > the input set change on flexible payload only on word, just some
> > ability compared with rte_fdir_conf.
> > If flexible selection isn't done in  struct rte_fdir_conf, the input
> > set selection in input set change API doesn't make sense. If flexible
> > selection is done in struct rte_fdir_conf, why not selection input set
> > in struct rte_fdir_conf at the same time?
> 
> I do not have a problem with selecting it at the same time - it always was this
> way with the legacy systems. But now new NIC supports new way of
> configuring input set with flexible payload as a part of this input set. So why
> not to have new way of configuration available as well and change input set
> using one API call instead of splitting single configuration in to two parts?
> 
Yes, if we support two way, at least we need to make sure the consistency.
In this patch set, I didn't add new way to configure flexible selection and mask
Setting. So to make sure consistency, just remove the flexible payload in this
Patch.

Thanks
Jingjing
> > And about you concern, "when application has to run on an old NIC and
> > on a new one", The rte_fdir_conf is for each eth_dev, so it will be fine.
> >

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

* [PATCH 00/12] extend flow director's fields in i40e driver
  2015-12-25  8:29 [PATCH 0/4] extend flow director's IP fields in i40e driver Jingjing Wu
                   ` (3 preceding siblings ...)
  2015-12-25  8:30 ` [PATCH 4/4] testpmd: extend commands for filter's input set changing Jingjing Wu
@ 2016-01-26  6:26 ` Jingjing Wu
  2016-01-26  6:26   ` [PATCH 01/12] ethdev: extend flow director to support input set selection Jingjing Wu
                     ` (13 more replies)
  4 siblings, 14 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

This patch set extends flow director to support filtering by
additional fields below in i40e driver:
 - TOS, Protocol and TTL in IP header
 - Tunnel id if NVGRE/GRE/VxLAN packets
 - single vlan or inner vlan

Jingjing Wu (12):
  ethdev: extend flow director to support input set selection
  i40e: split function for input set change of hash and fdir
  i40e: remove flex payload from INPUT_SET_SELECT operation
  i40e: restore default setting on input set of filters
  i40e: extend flow director to filter by more IP Header fields
  testpmd: extend commands for filter's input set changing
  librte_ether: extend rte_eth_fdir_flow to support tunnel format
  i40e: extend flow director to filter by tunnel ID
  testpmd: extend commands for fdir's tunnel id input set
  i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels
  i40e: extend flow director to filter by vlan id
  testpmd: extend commands for fdir's vlan input set

 app/test-pmd/cmdline.c                      | 121 +++++++--
 doc/guides/rel_notes/release_2_3.rst        |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 ++--
 drivers/net/i40e/i40e_ethdev.c              | 401 +++++++++++++++++-----------
 drivers/net/i40e/i40e_ethdev.h              |  11 +-
 drivers/net/i40e/i40e_fdir.c                | 163 ++++++++---
 lib/librte_ether/rte_eth_ctrl.h             |  35 ++-
 7 files changed, 529 insertions(+), 263 deletions(-)

-- 
2.4.0

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

* [PATCH 01/12] ethdev: extend flow director to support input set selection
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-01-26  6:26   ` [PATCH 02/12] i40e: split function for input set change of hash and fdir Jingjing Wu
                     ` (12 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
by tos, protocol and ttl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index ce224ad..248f719 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -337,9 +337,11 @@ enum rte_eth_input_set_field {
 	RTE_ETH_INPUT_SET_L3_SRC_IP6,
 	RTE_ETH_INPUT_SET_L3_DST_IP6,
 	RTE_ETH_INPUT_SET_L3_IP4_TOS,
+	RTE_ETH_INPUT_SET_L3_IP4_TTL,
 	RTE_ETH_INPUT_SET_L3_IP4_PROTO,
 	RTE_ETH_INPUT_SET_L3_IP6_TC,
 	RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
+	RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
 
 	/* L4 */
 	RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT = 257,
@@ -407,6 +409,9 @@ struct rte_eth_l2_flow {
 struct rte_eth_ipv4_flow {
 	uint32_t src_ip;      /**< IPv4 source address to match. */
 	uint32_t dst_ip;      /**< IPv4 destination address to match. */
+	uint8_t  tos;         /**< Type of service to match. */
+	uint8_t  ttl;         /**< Time to live */
+	uint8_t  proto;
 };
 
 /**
@@ -443,6 +448,9 @@ struct rte_eth_sctpv4_flow {
 struct rte_eth_ipv6_flow {
 	uint32_t src_ip[4];      /**< IPv6 source address to match. */
 	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
+	uint8_t  tc;             /**< Traffic class to match. */
+	uint8_t  proto;          /**< Protocol, next header. */
+	uint8_t  hop_limits;
 };
 
 /**
-- 
2.4.0

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

* [PATCH 02/12] i40e: split function for input set change of hash and fdir
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
  2016-01-26  6:26   ` [PATCH 01/12] ethdev: extend flow director to support input set selection Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-02-25  8:51     ` Zhang, Helin
  2016-01-26  6:26   ` [PATCH 03/12] i40e: remove flex payload from INPUT_SET_SELECT operation Jingjing Wu
                     ` (11 subsequent siblings)
  13 siblings, 1 reply; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

This patch split function for input set changing of hash
and fdir to avoid multiple check on different situation.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 233 +++++++++++++++++------------------------
 drivers/net/i40e/i40e_ethdev.h |  11 +-
 drivers/net/i40e/i40e_fdir.c   |   5 +-
 3 files changed, 107 insertions(+), 142 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index bf6220d..004e206 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6845,25 +6845,6 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	return idx;
 }
 
-static uint64_t
-i40e_get_reg_inset(struct i40e_hw *hw, enum rte_filter_type filter,
-			    enum i40e_filter_pctype pctype)
-{
-	uint64_t reg = 0;
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		reg = I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(1, pctype));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(0, pctype));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		reg = I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 1));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 0));
-	}
-
-	return reg;
-}
-
 static void
 i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 {
@@ -6876,103 +6857,96 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)I40E_READ_REG(hw, addr));
 }
 
-static int
-i40e_set_hash_inset_mask(struct i40e_hw *hw,
-			 enum i40e_filter_pctype pctype,
-			 enum rte_filter_input_set_op op,
-			 uint32_t *mask_reg,
-			 uint8_t num)
+int
+i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			 struct rte_eth_input_set_conf *conf)
 {
-	uint32_t reg;
-	uint8_t i;
+	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	if (!hw || !conf) {
+		PMD_DRV_LOG(ERR, "Invalid pointer");
+		return -EFAULT;
+	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
 		return -EINVAL;
-
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = I40E_READ_REG(hw, I40E_GLQF_HASH_MSK(i, pctype));
-			if (reg & I40E_GLQF_HASH_MSK_FIELD)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
-
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[j]);
 	}
 
-	return 0;
-}
-
-static int
-i40e_set_fd_inset_mask(struct i40e_hw *hw,
-		       enum i40e_filter_pctype pctype,
-		       enum rte_filter_input_set_op op,
-		       uint32_t *mask_reg,
-		       uint8_t num)
-{
-	uint32_t reg;
-	uint8_t i;
-
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	pctype = i40e_flowtype_to_pctype(conf->flow_type);
+	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
+		PMD_DRV_LOG(ERR, "Not supported flow type (%u)",
+			    conf->flow_type);
 		return -EINVAL;
+	}
 
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
+	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
+				   conf->inset_size);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to parse input set");
+		return -EINVAL;
+	}
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
+				    input_set) != 0) {
+		PMD_DRV_LOG(ERR, "Invalid input set");
+		return -EINVAL;
+	}
+	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
+		/* get inset value in register */
+		inset_reg = I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(1, pctype));
+		inset_reg <<= I40E_32_BIT_WIDTH;
+		inset_reg |= I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(0, pctype));
+		input_set |= pf->hash_input_set[pctype];
+	}
+	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+					   I40E_INSET_MASK_NUM_REG);
+	if (num < 0)
+		return -EINVAL;
 
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = I40E_READ_REG(hw, I40E_GLQF_FD_MSK(i, pctype));
-			if (reg & I40E_GLQF_FD_MSK_FIELD)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[j]);
-	}
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     0);
+	I40E_WRITE_FLUSH(hw);
 
+	pf->hash_input_set[pctype] = input_set;
 	return 0;
 }
 
 int
-i40e_filter_inset_select(struct i40e_hw *hw,
-			 struct rte_eth_input_set_conf *conf,
-			 enum rte_filter_type filter)
+i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			 struct rte_eth_input_set_conf *conf)
 {
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	enum i40e_filter_pctype pctype;
-	uint64_t inset_reg = 0, input_set;
-	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG];
-	uint8_t num;
-	int ret;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
 	if (!hw || !conf) {
 		PMD_DRV_LOG(ERR, "Invalid pointer");
 		return -EFAULT;
 	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
+		return -EINVAL;
+	}
 
 	pctype = i40e_flowtype_to_pctype(conf->flow_type);
 	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
@@ -6980,60 +6954,48 @@ i40e_filter_inset_select(struct i40e_hw *hw,
 			    conf->flow_type);
 		return -EINVAL;
 	}
-	if (filter != RTE_ETH_FILTER_HASH && filter != RTE_ETH_FILTER_FDIR) {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
-
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, filter, input_set) != 0) {
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
+				    input_set) != 0) {
 		PMD_DRV_LOG(ERR, "Invalid input set");
 		return -EINVAL;
 	}
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
-		inset_reg |= i40e_get_reg_inset(hw, filter, pctype);
-	} else if (conf->op != RTE_ETH_INPUT_SET_SELECT) {
-		PMD_DRV_LOG(ERR, "Unsupported input set operation");
-		return -EINVAL;
-	}
+	/* get inset value in register */
+	inset_reg = I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 1));
+	inset_reg <<= I40E_32_BIT_WIDTH;
+	inset_reg |= I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 0));
+
+	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-	inset_reg |= i40e_translate_input_set_reg(input_set);
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		ret = i40e_set_hash_inset_mask(hw, pctype, conf->op, mask_reg,
-					       num);
-		if (ret)
-			return -EINVAL;
+	if (num < 0)
+		return -EINVAL;
 
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		ret = i40e_set_fd_inset_mask(hw, pctype, conf->op, mask_reg,
-					     num);
-		if (ret)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     0);
 	I40E_WRITE_FLUSH(hw);
 
+	pf->fdir.input_set[pctype] = input_set;
 	return 0;
 }
 
@@ -7085,9 +7047,8 @@ i40e_hash_filter_set(struct i40e_hw *hw, struct rte_eth_hash_filter_info *info)
 				&(info->info.global_conf));
 		break;
 	case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-					       &(info->info.input_set_conf),
-					       RTE_ETH_FILTER_HASH);
+		ret = i40e_hash_filter_inset_select(hw,
+					       &(info->info.input_set_conf));
 		break;
 
 	default:
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 1f9792b..4dc7e1e 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -361,6 +361,8 @@ struct i40e_fdir_info {
 	struct i40e_rx_queue *rxq;
 	void *prg_pkt;                 /* memory for fdir program packet */
 	uint64_t dma_addr;             /* physic address of packet memory*/
+	/* input set bits for each pctype */
+	uint64_t input_set[I40E_FILTER_PCTYPE_MAX];
 	/*
 	 * the rule how bytes stream is extracted as flexible payload
 	 * for each payload layer, the setting can up to three elements
@@ -427,6 +429,8 @@ struct i40e_pf {
 	uint16_t fdir_qp_offset;
 
 	uint16_t hash_lut_size; /* The size of hash lookup table */
+	/* input set bits for each pctype */
+	uint64_t hash_input_set[I40E_FILTER_PCTYPE_MAX];
 	/* store VXLAN UDP ports */
 	uint16_t vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];
 	uint16_t vxlan_bitmap; /* Vxlan bit mask */
@@ -569,9 +573,10 @@ int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 int i40e_select_filter_input_set(struct i40e_hw *hw,
 				 struct rte_eth_input_set_conf *conf,
 				 enum rte_filter_type filter);
-int i40e_filter_inset_select(struct i40e_hw *hw,
-			     struct rte_eth_input_set_conf *conf,
-			     enum rte_filter_type filter);
+int i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			     struct rte_eth_input_set_conf *conf);
+int i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			     struct rte_eth_input_set_conf *conf);
 
 void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct rte_eth_rxq_info *qinfo);
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 9ad6981..155a34a 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -1361,7 +1361,6 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 		     struct rte_eth_fdir_filter_info *info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	int ret = 0;
 
 	if (!info) {
@@ -1371,8 +1370,8 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 
 	switch (info->info_type) {
 	case RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-			&(info->info.input_set_conf), RTE_ETH_FILTER_FDIR);
+		ret = i40e_fdir_filter_inset_select(pf,
+				&(info->info.input_set_conf));
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "FD filter info type (%d) not supported",
-- 
2.4.0

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

* [PATCH 03/12] i40e: remove flex payload from INPUT_SET_SELECT operation
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
  2016-01-26  6:26   ` [PATCH 01/12] ethdev: extend flow director to support input set selection Jingjing Wu
  2016-01-26  6:26   ` [PATCH 02/12] i40e: split function for input set change of hash and fdir Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-01-26  6:26   ` [PATCH 04/12] i40e: restore default setting on input set of filters Jingjing Wu
                     ` (10 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

In this patch, flex payload is removed from valid fdir input set
values. It is because all flex payload configuration can be set
in struct rte_fdir_conf during device configure phase.
And it is a more flexible configuration including flexpayload's
selection, input set selection by word and mask setting in bits.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 59 +++++++++++++++++++-----------------------
 1 file changed, 26 insertions(+), 33 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 004e206..f3c2e94 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -262,7 +262,8 @@
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD7        0x0000000000000080ULL
 /* 8th word of flex payload */
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD8        0x0000000000000040ULL
-
+/* all 8 words flex payload */
+#define I40E_REG_INSET_FLEX_PAYLOAD_WORDS        0x0000000000003FC0ULL
 #define I40E_REG_INSET_MASK_DEFAULT              0x0000000000000000ULL
 
 #define I40E_TRANSLATE_INSET 0
@@ -6545,43 +6546,32 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
-		I40E_INSET_LAST_ETHER_TYPE | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
 	if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD)
@@ -6809,7 +6799,7 @@ i40e_translate_input_set_reg(uint64_t input)
 	return val;
 }
 
-static uint8_t
+static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
@@ -6827,16 +6817,13 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-	if (!inset && nb_elem >= I40E_INSET_MASK_NUM_REG) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++)
-			mask[i] = 0;
-		return I40E_INSET_MASK_NUM_REG;
-	}
 
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if (idx >= nb_elem)
-			break;
-		if (inset & inset_mask_map[i].inset) {
+		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+			if (idx >= nb_elem) {
+				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
+				return -EINVAL;
+			}
 			mask[idx] = inset_mask_map[i].mask;
 			idx++;
 		}
@@ -6971,7 +6958,13 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 	inset_reg <<= I40E_32_BIT_WIDTH;
 	inset_reg |= I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 0));
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+	/* Can not change the inset reg for flex payload for fdir,
+	 * it is done by writing I40E_PRTQF_FD_FLXINSET
+	 * in i40e_set_flex_mask_on_pctype.
+	 */
+	if (conf->op == RTE_ETH_INPUT_SET_SELECT)
+		inset_reg &= I40E_REG_INSET_FLEX_PAYLOAD_WORDS;
+	else
 		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-- 
2.4.0

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

* [PATCH 04/12] i40e: restore default setting on input set of filters
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
                     ` (2 preceding siblings ...)
  2016-01-26  6:26   ` [PATCH 03/12] i40e: remove flex payload from INPUT_SET_SELECT operation Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-01-26  6:26   ` [PATCH 05/12] i40e: extend flow director to filter by more IP Header fields Jingjing Wu
                     ` (9 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

This patch added a new function to set the input set to default
when initialization.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 56 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f3c2e94..7a09fbc 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -374,6 +374,7 @@ static int i40e_dev_udp_tunnel_add(struct rte_eth_dev *dev,
 				struct rte_eth_udp_tunnel *udp_tunnel);
 static int i40e_dev_udp_tunnel_del(struct rte_eth_dev *dev,
 				struct rte_eth_udp_tunnel *udp_tunnel);
+static void i40e_filter_input_set_init(struct i40e_pf *pf);
 static int i40e_ethertype_filter_set(struct i40e_pf *pf,
 			struct rte_eth_ethertype_filter *filter,
 			bool add);
@@ -788,6 +789,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	 * It should be removed once issues are fixed in NVM.
 	 */
 	i40e_flex_payload_reg_init(hw);
+	/* Initialize the input set for filters (hash and fd) to default value */
+	i40e_filter_input_set_init(pf);
 
 	/* Initialize the parameters for adminq */
 	i40e_init_adminq_parameter(hw);
@@ -6844,6 +6847,59 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)I40E_READ_REG(hw, addr));
 }
 
+static void
+i40e_filter_input_set_init(struct i40e_pf *pf)
+{
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int num, i;
+
+	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
+		if (!I40E_VALID_PCTYPE(pctype))
+			continue;
+		input_set = i40e_get_default_input_set(pctype);
+
+		num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+						   I40E_INSET_MASK_NUM_REG);
+		if (num < 0)
+			return;
+		inset_reg = i40e_translate_input_set_reg(input_set);
+
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+		for (i = 0; i < num; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     mask_reg[i]);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     mask_reg[i]);
+		}
+		/*clear unused mask registers of the pctype */
+		for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     0);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     0);
+		}
+		I40E_WRITE_FLUSH(hw);
+
+		/* store the default input set */
+		pf->hash_input_set[pctype] = input_set;
+		pf->fdir.input_set[pctype] = input_set;
+	}
+}
+
 int
 i40e_hash_filter_inset_select(struct i40e_hw *hw,
 			 struct rte_eth_input_set_conf *conf)
-- 
2.4.0

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

* [PATCH 05/12] i40e: extend flow director to filter by more IP Header fields
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
                     ` (3 preceding siblings ...)
  2016-01-26  6:26   ` [PATCH 04/12] i40e: restore default setting on input set of filters Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-01-26  6:26   ` [PATCH 06/12] testpmd: extend commands for filter's input set changing Jingjing Wu
                     ` (8 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

This patch extended flow director to select more IP Header fields
as filter input set.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 69 ++++++++++++++++++++++++++++++++++--------
 drivers/net/i40e/i40e_fdir.c   | 26 +++++++++++-----
 2 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 7a09fbc..32ffc9f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -218,6 +218,8 @@
 #define I40E_REG_INSET_L3_IP4_TOS                0x0040000000000000ULL
 /* IPv4 Protocol */
 #define I40E_REG_INSET_L3_IP4_PROTO              0x0004000000000000ULL
+/* IPv4 Time to Live */
+#define I40E_REG_INSET_L3_IP4_TTL                0x0004000000000000ULL
 /* Source IPv6 address */
 #define I40E_REG_INSET_L3_SRC_IP6                0x0007F80000000000ULL
 /* Destination IPv6 address */
@@ -226,6 +228,8 @@
 #define I40E_REG_INSET_L3_IP6_TC                 0x0040000000000000ULL
 /* IPv6 Next Header */
 #define I40E_REG_INSET_L3_IP6_NEXT_HDR           0x0008000000000000ULL
+/* IPv6 Hop Limitr */
+#define I40E_REG_INSET_L3_IP6_HOP_LIMIT          0x0008000000000000ULL
 /* Source L4 port */
 #define I40E_REG_INSET_L4_SRC_PORT               0x0000000400000000ULL
 /* Destination L4 port */
@@ -269,10 +273,12 @@
 #define I40E_TRANSLATE_INSET 0
 #define I40E_TRANSLATE_REG   1
 
-#define I40E_INSET_IPV4_TOS_MASK      0x0009FF00UL
-#define I40E_INSET_IPV4_PROTO_MASK    0x000DFF00UL
-#define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
-#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
+#define I40E_INSET_IPV4_TOS_MASK        0x0009FF00UL
+#define I40E_INSET_IPv4_TTL_MASK        0x000D00FFUL
+#define I40E_INSET_IPV4_PROTO_MASK      0x000DFF00UL
+#define I40E_INSET_IPV6_TC_MASK         0x0009F00FUL
+#define I40E_INSET_IPV6_HOP_LIMIT_MASK  0x000CFF00UL
+#define I40E_INSET_IPV6_NEXT_HDR_MASK   0x000C00FFUL
 
 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
@@ -6549,30 +6555,47 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
@@ -6672,11 +6695,14 @@ i40e_parse_input_set(uint64_t *inset,
 		{RTE_ETH_INPUT_SET_L3_DST_IP4, I40E_INSET_IPV4_DST},
 		{RTE_ETH_INPUT_SET_L3_IP4_TOS, I40E_INSET_IPV4_TOS},
 		{RTE_ETH_INPUT_SET_L3_IP4_PROTO, I40E_INSET_IPV4_PROTO},
+		{RTE_ETH_INPUT_SET_L3_IP4_TTL, I40E_INSET_IPV4_TTL},
 		{RTE_ETH_INPUT_SET_L3_SRC_IP6, I40E_INSET_IPV6_SRC},
 		{RTE_ETH_INPUT_SET_L3_DST_IP6, I40E_INSET_IPV6_DST},
 		{RTE_ETH_INPUT_SET_L3_IP6_TC, I40E_INSET_IPV6_TC},
 		{RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
 			I40E_INSET_IPV6_NEXT_HDR},
+		{RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
+			I40E_INSET_IPV6_HOP_LIMIT},
 		{RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT, I40E_INSET_SRC_PORT},
@@ -6763,10 +6789,12 @@ i40e_translate_input_set_reg(uint64_t input)
 		{I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4},
 		{I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS},
 		{I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO},
+		{I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL},
 		{I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6},
 		{I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6},
 		{I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_REG_INSET_L3_IP6_NEXT_HDR},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_REG_INSET_L3_IP6_HOP_LIMIT},
 		{I40E_INSET_SRC_PORT, I40E_REG_INSET_L4_SRC_PORT},
 		{I40E_INSET_DST_PORT, I40E_REG_INSET_L4_DST_PORT},
 		{I40E_INSET_SCTP_VT, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG},
@@ -6806,23 +6834,38 @@ static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
+	uint64_t inset_need_mask = inset;
 
 	static const struct {
 		uint64_t inset;
 		uint32_t mask;
 	} inset_mask_map[] = {
 		{I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK},
+		{I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0},
 		{I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK},
+		{I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK},
 		{I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK},
+		{I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK}
 	};
 
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+		/* Clear the inset bit, if no MASK is required,
+		 * for example proto + ttl
+		 */
+		if ((inset & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset && inset_mask_map[i].mask == 0)
+			inset_need_mask &= ~inset_mask_map[i].inset;
+		if (!inset_need_mask)
+			return 0;
+	}
+	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
+		if ((inset_need_mask & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset) {
 			if (idx >= nb_elem) {
 				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
 				return -EINVAL;
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 155a34a..5ea97e5 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -65,7 +65,9 @@
 #define I40E_FDIR_IP_DEFAULT_TTL            0x40
 #define I40E_FDIR_IP_DEFAULT_VERSION_IHL    0x45
 #define I40E_FDIR_TCP_DEFAULT_DATAOFF       0x50
-#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60300000
+#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60000000
+#define I40E_FDIR_IPv6_TC_OFFSET            20
+
 #define I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS   0xFF
 #define I40E_FDIR_IPv6_PAYLOAD_LEN          380
 #define I40E_FDIR_UDP_DEFAULT_LEN           400
@@ -719,7 +721,13 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
-		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+		ip->next_proto_id = fdir_input->flow.ip4_flow.proto ?
+					fdir_input->flow.ip4_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip->time_to_live = fdir_input->flow.ip4_flow.ttl ?
+					fdir_input->flow.ip4_flow.ttl :
+					I40E_FDIR_IP_DEFAULT_TTL;
+		ip->type_of_service = fdir_input->flow.ip4_flow.tos;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -727,7 +735,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		 */
 		ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
 		ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
-		ip->next_proto_id = next_proto[fdir_input->flow_type];
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
@@ -738,11 +745,17 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 
 		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
-			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
+					 (fdir_input->flow.ipv6_flow.tc <<
+					  I40E_FDIR_IPv6_TC_OFFSET));
 		ip6->payload_len =
 			rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
-		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
-
+		ip6->proto = fdir_input->flow.ipv6_flow.proto ?
+					fdir_input->flow.ipv6_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ?
+					fdir_input->flow.ipv6_flow.hop_limits :
+					I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -754,7 +767,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		rte_memcpy(&(ip6->dst_addr),
 			   &(fdir_input->flow.ipv6_flow.src_ip),
 			   IPV6_ADDR_LEN);
-		ip6->proto = next_proto[fdir_input->flow_type];
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
-- 
2.4.0

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

* [PATCH 06/12] testpmd: extend commands for filter's input set changing
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
                     ` (4 preceding siblings ...)
  2016-01-26  6:26   ` [PATCH 05/12] i40e: extend flow director to filter by more IP Header fields Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-01-26  6:26   ` [PATCH 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format Jingjing Wu
                     ` (7 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

This patch extended commands for filter's input set changing.
It added tos, protocol and ttl as filter's input fields, and
remove the words selection from flex payloads for flow director.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 100 ++++++++++++++++++++++------
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  42 +++++++-----
 2 files changed, 104 insertions(+), 38 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 73298c9..da1d3f2 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -640,6 +640,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"flow_director_filter (port_id) mode IP (add|del|update)"
 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
+			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -649,6 +650,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
+			" tos (tos_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -658,7 +660,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-sctp|ipv6-sctp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
-			" tag (verification_tag) vlan (vlan_value)"
+			" tag (verification_tag) "
+			" tos (tos_value) ttl (ttl_value)"
+			" vlan (vlan_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -738,14 +742,15 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"fld-8th|none) (select|add)\n"
 			"    Set the input set for hash.\n\n"
 
-			"set_fdir_input_set (port_id) (ipv4|ipv4-frag|"
-			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+			"set_fdir_input_set (port_id) "
+			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
-			"udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|"
-			"sctp-src-port|sctp-dst-port|sctp-veri-tag|fld-1st|"
-			"fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
-			"fld-8th|none) (select|add)\n"
+			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
+			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
+			"udp-dst-port|tcp-src-port|tcp-dst-port|"
+			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
+			" (select|add)\n"
 			"    Set the input set for FDir.\n\n"
 		);
 	}
@@ -7983,6 +7988,12 @@ struct cmd_flow_director_result {
 	uint16_t port_dst;
 	cmdline_fixed_string_t verify_tag;
 	uint32_t verify_tag_value;
+	cmdline_ipaddr_t tos;
+	uint8_t tos_value;
+	cmdline_ipaddr_t proto;
+	uint8_t proto_value;
+	cmdline_ipaddr_t ttl;
+	uint8_t ttl_value;
 	cmdline_fixed_string_t vlan;
 	uint16_t vlan_value;
 	cmdline_fixed_string_t flexbytes;
@@ -8162,12 +8173,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 	switch (entry.input.flow_type) {
 	case RTE_ETH_FLOW_FRAG_IPV4:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+		entry.input.flow.ip4_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 		IPV4_ADDR_TO_UINT(res->ip_dst,
 			entry.input.flow.ip4_flow.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.ip4_flow.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8179,6 +8193,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp4_flow.ip.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.sctp4_flow.ip.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8189,12 +8205,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 		break;
 	case RTE_ETH_FLOW_FRAG_IPV6:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+		entry.input.flow.ipv6_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 		IPV6_ADDR_TO_ARRAY(res->ip_dst,
 			entry.input.flow.ipv6_flow.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.ipv6_flow.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8206,6 +8225,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp6_flow.ip.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.sctp6_flow.ip.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8333,6 +8354,24 @@ cmdline_parse_token_string_t cmd_flow_director_verify_tag =
 cmdline_parse_token_num_t cmd_flow_director_verify_tag_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
 			      verify_tag_value, UINT32);
+cmdline_parse_token_string_t cmd_flow_director_tos =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 tos, "tos");
+cmdline_parse_token_num_t cmd_flow_director_tos_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      tos_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_proto =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 proto, "proto");
+cmdline_parse_token_num_t cmd_flow_director_proto_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      proto_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_ttl =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 ttl, "ttl");
+cmdline_parse_token_num_t cmd_flow_director_ttl_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      ttl_value, UINT8);
 cmdline_parse_token_string_t cmd_flow_director_vlan =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 vlan, "vlan");
@@ -8411,6 +8450,12 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ip_src,
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_proto,
+		(void *)&cmd_flow_director_proto_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8443,6 +8488,10 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
 		(void *)&cmd_flow_director_port_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8477,6 +8526,10 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_port_dst,
 		(void *)&cmd_flow_director_verify_tag,
 		(void *)&cmd_flow_director_verify_tag_value,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -9403,16 +9456,19 @@ str2inset(char *string)
 		char str[32];
 		enum rte_eth_input_set_field inset;
 	} inset_table[] = {
+		{"ethertype", RTE_ETH_INPUT_SET_L2_ETHERTYPE},
 		{"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
 		{"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
 		{"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
 		{"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
 		{"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
 		{"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
+		{"ipv4-ttl", RTE_ETH_INPUT_SET_L3_IP4_TTL},
 		{"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
 		{"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
 		{"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
 		{"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
+		{"ipv6-hop-limits", RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS},
 		{"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
 		{"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
 		{"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
@@ -9471,7 +9527,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
 		flow_type,
-		"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
@@ -9490,8 +9546,8 @@ cmdline_parse_inst_t cmd_set_hash_input_set = {
 	.f = cmd_set_hash_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_hash_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
@@ -9546,15 +9602,16 @@ cmdline_parse_token_num_t cmd_set_fdir_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	flow_type,
-	"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+	"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 	"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#udp-src-port#udp-dst-port#"
+	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
+	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
-	"sctp-veri-tag#fld-1st#fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#"
-	"fld-7th#fld-8th#none");
+	"sctp-veri-tag#none");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	select, "select#add");
@@ -9563,12 +9620,13 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.f = cmd_set_fdir_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_fdir_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port|"
-	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|"
-	"fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
-	"fld-7th|fld-8th|none select|add",
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
+	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
+	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
+	"sctp-veri-tag|none select|add",
 	.tokens = {
 		(void *)&cmd_set_fdir_input_set_cmd,
 		(void *)&cmd_set_fdir_input_set_port_id,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index a520cc5..f59e63e 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1678,8 +1678,9 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 # Commands to add flow director filters of different flow types::
 
    flow_director_filter (port_id) mode IP (add|del|update) \
-                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)
+                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag) \
                         src (src_ip_address) dst (dst_ip_address) \
+                        tos (tos_value) proto (proto_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) pf|vf(vf_id) queue (queue_id) \
                         fd_id (fd_id_value)
@@ -1688,6 +1689,7 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp) \
                         src (src_ip_address) (src_port) \
                         dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) queue pf|vf(vf_id) (queue_id) \
                         fd_id (fd_id_value)
@@ -1695,7 +1697,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
    flow_director_filter (port_id) mode IP (add|del|update) \
                         flow (ipv4-sctp|ipv6-sctp) \
                         src (src_ip_address) (src_port) \
-                        dst (dst_ip_address) (dst_port)
+                        dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         tag (verification_tag) vlan (vlan_value) \
                         flexbytes (flexbytes_value) (drop|fwd) \
                         pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)
@@ -1719,12 +1722,14 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 For example, to add an ipv4-udp flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-udp src 2.2.2.3 32 \
-            dst 2.2.2.5 33 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+            dst 2.2.2.5 33 tos 2 ttl 40 vlan 0x1 flexbytes (0x88,0x48) \
+            fwd pf queue 1 fd_id 1
 
 For example, add an ipv4-other flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
-             dst 2.2.2.5 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+             dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 \
+             flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
 flush_flow_director
 ~~~~~~~~~~~~~~~~~~~
@@ -1841,33 +1846,36 @@ set_hash_input_set
 
 Set the input set for hash::
 
-   set_hash_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   set_hash_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
    l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port| \
    tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
    udp-key|gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th| \
    fld-8th|none) (select|add)
 
-For example, to add source IP to hash input set for flow type of ipv4 on port 0::
+For example, to add source IP to hash input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_hash_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_hash_input_set 0 ipv4-udp src-ipv4 add
 
 set_fdir_input_set
 ~~~~~~~~~~~~~~~~~~
 
-Set the input set for Fdir::
+The Flow Director filters can match the different fields for different type of packet, i.e. specific input set
+on per flow type and the flexible payload. This command can be used to change input set for each flow type.
 
-   set_fdir_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)
-   (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port| \
-   tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
-   fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|fld-8th|none) \
-   (select|add)
+Set the input set for flow director::
+
+   set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
+   tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
+   sctp-dst-port|sctp-veri-tag|none) (select|add)
 
-For example to add source IP to FD input set for flow type of ipv4 on port 0::
+For example to add source IP to FD input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_fdir_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_fdir_input_set 0 ipv4-udp src-ipv4 add
 
 global_config
 ~~~~~~~~~~~~~
-- 
2.4.0

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

* [PATCH 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
                     ` (5 preceding siblings ...)
  2016-01-26  6:26   ` [PATCH 06/12] testpmd: extend commands for filter's input set changing Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-01-26  6:26   ` [PATCH 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
                     ` (6 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

This patch changed rte_eth_fdir_flow from union to struct to
support more packets formats, for example, Vxlan and GRE tunnel
packets with IP inner frame.

This patch also add new RTE_FDIR_TUNNEL_TYPE_GRE enum.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/rel_notes/release_2_3.rst |  4 ++++
 lib/librte_ether/rte_eth_ctrl.h      | 27 +++++++++++++++------------
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/doc/guides/rel_notes/release_2_3.rst b/doc/guides/rel_notes/release_2_3.rst
index 99de186..2216fee 100644
--- a/doc/guides/rel_notes/release_2_3.rst
+++ b/doc/guides/rel_notes/release_2_3.rst
@@ -39,6 +39,10 @@ API Changes
 ABI Changes
 -----------
 
+* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
+  changed. New fields were added to extend flow director's input set, and
+  organizing is also changed to support multiple input format.
+
 
 Shared Library Versions
 -----------------------
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 248f719..eb4c13d 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -495,6 +495,7 @@ enum rte_eth_fdir_tunnel_type {
 	RTE_FDIR_TUNNEL_TYPE_UNKNOWN = 0,
 	RTE_FDIR_TUNNEL_TYPE_NVGRE,
 	RTE_FDIR_TUNNEL_TYPE_VXLAN,
+	RTE_FDIR_TUNNEL_TYPE_GRE,
 };
 
 /**
@@ -508,18 +509,20 @@ struct rte_eth_tunnel_flow {
 };
 
 /**
- * An union contains the inputs for all types of flow
+ * A struct contains the inputs for all types of flow
  */
-union rte_eth_fdir_flow {
-	struct rte_eth_l2_flow     l2_flow;
-	struct rte_eth_udpv4_flow  udp4_flow;
-	struct rte_eth_tcpv4_flow  tcp4_flow;
-	struct rte_eth_sctpv4_flow sctp4_flow;
-	struct rte_eth_ipv4_flow   ip4_flow;
-	struct rte_eth_udpv6_flow  udp6_flow;
-	struct rte_eth_tcpv6_flow  tcp6_flow;
-	struct rte_eth_sctpv6_flow sctp6_flow;
-	struct rte_eth_ipv6_flow   ipv6_flow;
+struct rte_eth_fdir_flow {
+	union {
+		struct rte_eth_l2_flow     l2_flow;
+		struct rte_eth_udpv4_flow  udp4_flow;
+		struct rte_eth_tcpv4_flow  tcp4_flow;
+		struct rte_eth_sctpv4_flow sctp4_flow;
+		struct rte_eth_ipv4_flow   ip4_flow;
+		struct rte_eth_udpv6_flow  udp6_flow;
+		struct rte_eth_tcpv6_flow  tcp6_flow;
+		struct rte_eth_sctpv6_flow sctp6_flow;
+		struct rte_eth_ipv6_flow   ipv6_flow;
+	};
 	struct rte_eth_mac_vlan_flow mac_vlan_flow;
 	struct rte_eth_tunnel_flow   tunnel_flow;
 };
@@ -540,7 +543,7 @@ struct rte_eth_fdir_flow_ext {
  */
 struct rte_eth_fdir_input {
 	uint16_t flow_type;
-	union rte_eth_fdir_flow flow;
+	struct rte_eth_fdir_flow flow;
 	/**< Flow fields to match, dependent on flow_type */
 	struct rte_eth_fdir_flow_ext flow_ext;
 	/**< Additional fields to match */
-- 
2.4.0

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

* [PATCH 08/12] i40e: extend flow director to filter by tunnel ID
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
                     ` (6 preceding siblings ...)
  2016-01-26  6:26   ` [PATCH 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-01-26  6:26   ` [PATCH 09/12] testpmd: extend commands for fdir's tunnel id input set Jingjing Wu
                     ` (5 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

This patch extended flow director to select Vxlan/GRE tunnel ID
as filter's input set and program the filter rule with the defined
tunnel type.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c |  11 ++++
 drivers/net/i40e/i40e_fdir.c   | 125 ++++++++++++++++++++++++++++++-----------
 2 files changed, 102 insertions(+), 34 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 32ffc9f..62cdf81 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6555,48 +6555,59 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 5ea97e5..7566017 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -688,11 +688,13 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 
 static inline void
 i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
-			       unsigned char *raw_pkt)
+			       unsigned char *pkt, bool need_mac)
 {
-	struct ether_hdr *ether = (struct ether_hdr *)raw_pkt;
-	struct ipv4_hdr *ip;
-	struct ipv6_hdr *ip6;
+	struct ether_hdr *ether = (struct ether_hdr *)pkt;
+	struct ipv4_hdr *ip =
+			(struct ipv4_hdr *)(pkt + sizeof(struct ether_hdr));
+	struct ipv6_hdr *ip6 =
+			(struct ipv6_hdr *)(pkt + sizeof(struct ether_hdr));
 	static const uint8_t next_proto[] = {
 		[RTE_ETH_FLOW_FRAG_IPV4] = IPPROTO_IP,
 		[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] = IPPROTO_TCP,
@@ -708,16 +710,18 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
+		if (need_mac)
+			ether->ether_type = fdir_input->flow.l2_flow.ether_type;
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		ip = (struct ipv4_hdr *)(raw_pkt + sizeof(struct ether_hdr));
-
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		if (!need_mac)
+			ip = (struct ipv4_hdr *)pkt;
+		else
+			ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
@@ -741,9 +745,10 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		ip6 = (struct ipv6_hdr *)(raw_pkt + sizeof(struct ether_hdr));
-
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		if (!need_mac)
+			ip6 = (struct ipv6_hdr *)pkt;
+		else
+			ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
 			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
 					 (fdir_input->flow.ipv6_flow.tc <<
@@ -775,7 +780,7 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 	}
 }
 
-
+#define I40E_TUNNEL_KEY_LEN 4
 /*
  * i40e_fdir_construct_pkt - construct packet based on fields in input
  * @pf: board private structure
@@ -787,21 +792,80 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			     const struct rte_eth_fdir_input *fdir_input,
 			     unsigned char *raw_pkt)
 {
-	unsigned char *payload, *ptr;
+	unsigned char *payload, *ptr, *inner_pkt = raw_pkt;
 	struct udp_hdr *udp;
 	struct tcp_hdr *tcp;
 	struct sctp_hdr *sctp;
 	uint8_t size, dst = 0;
 	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
-
-	/* fill the ethernet and IP head */
-	i40e_fdir_fill_eth_ip_head(fdir_input, raw_pkt);
-
+	bool need_mac = TRUE;
+	static uint8_t gre4_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x08, 0,
+			0, 0, 0, 0}; /* Mac+ IP + GRE hdr + key */
+	static uint8_t gre6_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x86, 0xDD,
+			0, 0, 0, 0, 0}; /* Mac+ IP + GRE hdr + key */
+	static uint8_t vxlan_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x11,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			0x12, 0xB5, 0x12, 0xB5, 0x08, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0}; /* Mac + IP + UDP + VXLAN hdr */
+	static uint8_t nvgre_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x65, 0x58,
+			0, 0, 0, 0}; /*Mac + IP + NVGRE hdr*/
+
+	inner_pkt += 2 * sizeof(struct ether_addr);
+	/* fill the tunnel header if required */
+	switch (fdir_input->flow.tunnel_flow.tunnel_type) {
+	case RTE_FDIR_TUNNEL_TYPE_GRE:
+		if (fdir_input->flow_type == RTE_ETH_FLOW_L2_PAYLOAD) {
+			PMD_DRV_LOG(ERR, "GRE's inner pkt shouldn't"
+				    " be L2 frame.");
+			return -EINVAL;
+		}
+		if ((fdir_input->flow_type) == RTE_ETH_FLOW_FRAG_IPV4 ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_TCP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_UDP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_SCTP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_OTHER)
+			rte_memcpy(inner_pkt, gre4_frame, sizeof(gre4_frame));
+		else
+			rte_memcpy(inner_pkt, gre6_frame, sizeof(gre6_frame));
+		/* gre4_frame and gre4_frame have the same size */
+		inner_pkt += sizeof(gre4_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		need_mac = FALSE;
+		break;
+	case RTE_FDIR_TUNNEL_TYPE_VXLAN:
+		rte_memcpy(inner_pkt, vxlan_frame, sizeof(vxlan_frame));
+		inner_pkt += sizeof(vxlan_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		break;
+	case RTE_FDIR_TUNNEL_TYPE_NVGRE:
+		rte_memcpy(inner_pkt, nvgre_frame, sizeof(nvgre_frame));
+		inner_pkt += sizeof(nvgre_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		break;
+	default:
+		break;
+	}
+	/* fill the ethernet and IP head of inner or single frame */
+	i40e_fdir_fill_eth_ip_head(fdir_input, inner_pkt, need_mac);
+	if (need_mac)
+		inner_pkt += sizeof(struct ether_hdr);
 	/* fill the L4 head */
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-				sizeof(struct ipv4_hdr));
+		udp = (struct udp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -814,8 +878,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv4_hdr));
+		tcp = (struct tcp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -828,8 +891,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv4_hdr));
+		sctp = (struct sctp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -843,14 +905,12 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv4_hdr);
+		payload = inner_pkt + sizeof(struct ipv4_hdr);
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		udp = (struct udp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -863,8 +923,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		tcp = (struct tcp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -877,8 +936,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv6_hdr));
+		sctp = (struct sctp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -892,12 +950,11 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv6_hdr);
+		payload = inner_pkt + sizeof(struct ipv6_hdr);
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		payload = raw_pkt + sizeof(struct ether_hdr);
+		payload = inner_pkt;
 		/*
 		 * ARP packet is a special case on which the payload
 		 * starts after the whole ARP header
-- 
2.4.0

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

* [PATCH 09/12] testpmd: extend commands for fdir's tunnel id input set
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
                     ` (7 preceding siblings ...)
  2016-01-26  6:26   ` [PATCH 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-01-26  6:26   ` [PATCH 10/12] i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels Jingjing Wu
                     ` (4 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

This patch extended commands for filter's input set changing.
It added GRE/Vxlan Tunnel as filter's input fields.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 27 +++++++++++++++++++++------
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 22 ++++++++++++++++------
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index da1d3f2..ecc822a 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -641,7 +641,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
 			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
-			" vlan (vlan_value) flexbytes (flexbytes_value)"
+			" vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel)"
+			" (tunnel_id_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
 			"    Add/Del an IP type flow director filter.\n\n"
@@ -651,7 +652,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
 			" tos (tos_value) ttl (ttl_value)"
-			" vlan (vlan_value) flexbytes (flexbytes_value)"
+			" vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel)"
+			" (tunnel_id_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
 			"    Add/Del an UDP/TCP type flow director filter.\n\n"
@@ -663,6 +665,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" tag (verification_tag) "
 			" tos (tos_value) ttl (ttl_value)"
 			" vlan (vlan_value)"
+			" (NVGRE|VxLAN|GRE|Notunnel) (tunnel_id_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -749,7 +752,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
 			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
 			"udp-dst-port|tcp-src-port|tcp-dst-port|"
-			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
+			"sctp-src-port|sctp-dst-port|sctp-veri-tag|"
+			"udp-key|gre-key|none)"
 			" (select|add)\n"
 			"    Set the input set for FDir.\n\n"
 		);
@@ -8092,6 +8096,7 @@ str2fdir_tunneltype(char *string)
 	} tunneltype_str[] = {
 		{"NVGRE", RTE_FDIR_TUNNEL_TYPE_NVGRE},
 		{"VxLAN", RTE_FDIR_TUNNEL_TYPE_VXLAN},
+		{"GRE",   RTE_FDIR_TUNNEL_TYPE_GRE},
 	};
 
 	for (i = 0; i < RTE_DIM(tunneltype_str); i++) {
@@ -8263,6 +8268,10 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 		   RTE_ETH_FDIR_MAX_FLEXLEN);
 
 	entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value);
+	entry.input.flow.tunnel_flow.tunnel_type =
+		str2fdir_tunneltype(res->tunnel_type);
+	entry.input.flow.tunnel_flow.tunnel_id =
+			rte_cpu_to_be_32(res->tunnel_id_value);
 
 	entry.action.flex_off = 0;  /*use 0 by default */
 	if (!strcmp(res->drop, "drop"))
@@ -8426,7 +8435,7 @@ cmdline_parse_token_string_t cmd_flow_director_tunnel =
 				 tunnel, "tunnel");
 cmdline_parse_token_string_t cmd_flow_director_tunnel_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
-				 tunnel_type, "NVGRE#VxLAN");
+				 tunnel_type, "NVGRE#VxLAN#GRE#Notunnel");
 cmdline_parse_token_string_t cmd_flow_director_tunnel_id =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 tunnel_id, "tunnel-id");
@@ -8458,6 +8467,8 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -8494,6 +8505,8 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -8532,6 +8545,8 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -9611,7 +9626,7 @@ cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
 	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
-	"sctp-veri-tag#none");
+	"sctp-veri-tag#udp-key#gre-key#none");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	select, "select#add");
@@ -9626,7 +9641,7 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
 	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
 	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
-	"sctp-veri-tag|none select|add",
+	"sctp-veri-tag|udp-key|gre-key|none select|add",
 	.tokens = {
 		(void *)&cmd_set_fdir_input_set_cmd,
 		(void *)&cmd_set_fdir_input_set_port_id,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f59e63e..417ddde 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1681,7 +1681,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag) \
                         src (src_ip_address) dst (dst_ip_address) \
                         tos (tos_value) proto (proto_value) ttl (ttl_value) \
-                        vlan (vlan_value) flexbytes (flexbytes_value) \
+                        vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel) \
+                        (tunnel_id_value) flexbytes (flexbytes_value) \
                         (drop|fwd) pf|vf(vf_id) queue (queue_id) \
                         fd_id (fd_id_value)
 
@@ -1690,7 +1691,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         src (src_ip_address) (src_port) \
                         dst (dst_ip_address) (dst_port) \
                         tos (tos_value) ttl (ttl_value) \
-                        vlan (vlan_value) flexbytes (flexbytes_value) \
+                        vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel) \
+                        (tunnel_id_value) flexbytes (flexbytes_value) \
                         (drop|fwd) queue pf|vf(vf_id) (queue_id) \
                         fd_id (fd_id_value)
 
@@ -1700,6 +1702,7 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         dst (dst_ip_address) (dst_port) \
                         tos (tos_value) ttl (ttl_value) \
                         tag (verification_tag) vlan (vlan_value) \
+                        (NVGRE|VxLAN|GRE|Notunnel) (tunnel_id_value) \
                         flexbytes (flexbytes_value) (drop|fwd) \
                         pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)
 
@@ -1722,15 +1725,21 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 For example, to add an ipv4-udp flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-udp src 2.2.2.3 32 \
-            dst 2.2.2.5 33 tos 2 ttl 40 vlan 0x1 flexbytes (0x88,0x48) \
-            fwd pf queue 1 fd_id 1
+            dst 2.2.2.5 33  tos 2 ttl 40 vlan 0x1 Notunnel 0 \
+            flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
 For example, add an ipv4-other flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
-             dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 \
+             dst 2.2.2.5  tos 2 proto 20 ttl 40 vlan 0x1 Notunnel 0 \
              flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
+For example, add a ipv4-other flow type filter with GRE key 0x0a0b0c0d:
+
+   testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
+            dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 GRE 0x0a0b0c0d \
+            flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+
 flush_flow_director
 ~~~~~~~~~~~~~~~~~~~
 
@@ -1861,6 +1870,7 @@ For example, to add source IP to hash input set for flow type of ipv4-udp on por
 set_fdir_input_set
 ~~~~~~~~~~~~~~~~~~
 
+
 The Flow Director filters can match the different fields for different type of packet, i.e. specific input set
 on per flow type and the flexible payload. This command can be used to change input set for each flow type.
 
@@ -1871,7 +1881,7 @@ Set the input set for flow director::
    l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
    tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
-   sctp-dst-port|sctp-veri-tag|none) (select|add)
+   sctp-dst-port|sctp-veri-tag|udp-key|gre-key|none) (select|add)
 
 For example to add source IP to FD input set for flow type of ipv4-udp on port 0::
 
-- 
2.4.0

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

* [PATCH 10/12] i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
                     ` (8 preceding siblings ...)
  2016-01-26  6:26   ` [PATCH 09/12] testpmd: extend commands for fdir's tunnel id input set Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-01-26  6:26   ` [PATCH 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
                     ` (3 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

From: Andrey Chilikin <andrey.chilikin@intel.com>

This patch adds missing VLAN bitmask for inner frame in case of
tunneling and fixes VLAN tags bitmasks for single or outer frame
in case of tunneling.

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 62cdf81..66e3a46 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -206,10 +206,12 @@
 #define I40E_REG_INSET_L2_DMAC                   0xE000000000000000ULL
 /* Source MAC address */
 #define I40E_REG_INSET_L2_SMAC                   0x1C00000000000000ULL
-/* VLAN tag in the outer L2 header */
-#define I40E_REG_INSET_L2_OUTER_VLAN             0x0080000000000000ULL
-/* VLAN tag in the inner L2 header */
-#define I40E_REG_INSET_L2_INNER_VLAN             0x0100000000000000ULL
+/* Outer (S-Tag) VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_OUTER_VLAN             0x0200000000000000ULL
+/* Inner (C-Tag) or single VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_INNER_VLAN             0x0080000000000000ULL
+/* Single VLAN tag in the inner L2 header */
+#define I40E_REG_INSET_TUNNEL_VLAN               0x0100000000000000ULL
 /* Source IPv4 address */
 #define I40E_REG_INSET_L3_SRC_IP4                0x0001800000000000ULL
 /* Destination IPv4 address */
@@ -6818,7 +6820,7 @@ i40e_translate_input_set_reg(uint64_t input)
 			I40E_REG_INSET_TUNNEL_L4_UDP_SRC_PORT},
 		{I40E_INSET_TUNNEL_DST_PORT,
 			I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT},
-		{I40E_INSET_TUNNEL_ID, I40E_REG_INSET_TUNNEL_ID},
+		{I40E_INSET_VLAN_TUNNEL, I40E_REG_INSET_TUNNEL_VLAN},
 		{I40E_INSET_FLEX_PAYLOAD_W1, I40E_REG_INSET_FLEX_PAYLOAD_WORD1},
 		{I40E_INSET_FLEX_PAYLOAD_W2, I40E_REG_INSET_FLEX_PAYLOAD_WORD2},
 		{I40E_INSET_FLEX_PAYLOAD_W3, I40E_REG_INSET_FLEX_PAYLOAD_WORD3},
-- 
2.4.0

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

* [PATCH 11/12] i40e: extend flow director to filter by vlan id
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
                     ` (9 preceding siblings ...)
  2016-01-26  6:26   ` [PATCH 10/12] i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-01-26  6:26   ` [PATCH 12/12] testpmd: extend commands for fdir's vlan input set Jingjing Wu
                     ` (2 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

This patch extended flow director to select vlan id
as filter's input set and program the filter rule with vlan id.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/rel_notes/release_2_3.rst |  1 +
 drivers/net/i40e/i40e_ethdev.c       | 11 +++++++++++
 drivers/net/i40e/i40e_fdir.c         |  9 +++++++++
 3 files changed, 21 insertions(+)

diff --git a/doc/guides/rel_notes/release_2_3.rst b/doc/guides/rel_notes/release_2_3.rst
index 2216fee..63c7e04 100644
--- a/doc/guides/rel_notes/release_2_3.rst
+++ b/doc/guides/rel_notes/release_2_3.rst
@@ -4,6 +4,7 @@ DPDK Release 2.3
 New Features
 ------------
 
+* **Added Flow director enhancements on Intel X710/XL710.**
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 66e3a46..b4bd24b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6557,58 +6557,69 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 7566017..bbe6f1f 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -799,6 +799,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 	uint8_t size, dst = 0;
 	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
 	bool need_mac = TRUE;
+	static uint8_t vlan_frame[] = {0x81, 0, 0, 0};
 	static uint8_t gre4_frame[] = {0x08, 0,
 			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x08, 0,
@@ -818,6 +819,14 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			0, 0, 0, 0}; /*Mac + IP + NVGRE hdr*/
 
 	inner_pkt += 2 * sizeof(struct ether_addr);
+	if (fdir_input->flow_ext.vlan_tci) {
+		rte_memcpy(inner_pkt, vlan_frame, sizeof(vlan_frame));
+		rte_memcpy(inner_pkt + sizeof(uint16_t),
+			   &fdir_input->flow_ext.vlan_tci,
+			   sizeof(uint16_t));
+		inner_pkt += sizeof(vlan_frame);
+	}
+
 	/* fill the tunnel header if required */
 	switch (fdir_input->flow.tunnel_flow.tunnel_type) {
 	case RTE_FDIR_TUNNEL_TYPE_GRE:
-- 
2.4.0

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

* [PATCH 12/12] testpmd: extend commands for fdir's vlan input set
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
                     ` (10 preceding siblings ...)
  2016-01-26  6:26   ` [PATCH 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
@ 2016-01-26  6:26   ` Jingjing Wu
  2016-02-24 11:44   ` [PATCH 00/12] extend flow director's fields in i40e driver Bruce Richardson
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-01-26  6:26 UTC (permalink / raw)
  To: dev

This patch extended commands for filter's input set changing.
It added vlan as filter's input fields.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 6 +++---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index ecc822a..f7ffce1 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -748,7 +748,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set_fdir_input_set (port_id) "
 			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|"
 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
 			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
 			"udp-dst-port|tcp-src-port|tcp-dst-port|"
@@ -9622,7 +9622,7 @@ cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ivlan#ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
 	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
 	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
@@ -9637,7 +9637,7 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.help_str = "set_fdir_input_set <port_id> "
 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
 	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
 	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
 	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 417ddde..aa20d5a 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1878,7 +1878,7 @@ Set the input set for flow director::
 
    set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
    ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
-   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
    tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
    sctp-dst-port|sctp-veri-tag|udp-key|gre-key|none) (select|add)
-- 
2.4.0

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

* Re: [PATCH 00/12] extend flow director's fields in i40e driver
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
                     ` (11 preceding siblings ...)
  2016-01-26  6:26   ` [PATCH 12/12] testpmd: extend commands for fdir's vlan input set Jingjing Wu
@ 2016-02-24 11:44   ` Bruce Richardson
  2016-02-25  7:42     ` Zhang, Helin
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
  13 siblings, 1 reply; 105+ messages in thread
From: Bruce Richardson @ 2016-02-24 11:44 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev

On Tue, Jan 26, 2016 at 02:26:03PM +0800, Jingjing Wu wrote:
> This patch set extends flow director to support filtering by
> additional fields below in i40e driver:
>  - TOS, Protocol and TTL in IP header
>  - Tunnel id if NVGRE/GRE/VxLAN packets
>  - single vlan or inner vlan
> 
> Jingjing Wu (12):
>   ethdev: extend flow director to support input set selection
>   i40e: split function for input set change of hash and fdir
>   i40e: remove flex payload from INPUT_SET_SELECT operation
>   i40e: restore default setting on input set of filters
>   i40e: extend flow director to filter by more IP Header fields
>   testpmd: extend commands for filter's input set changing
>   librte_ether: extend rte_eth_fdir_flow to support tunnel format
>   i40e: extend flow director to filter by tunnel ID
>   testpmd: extend commands for fdir's tunnel id input set
>   i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels
>   i40e: extend flow director to filter by vlan id
>   testpmd: extend commands for fdir's vlan input set
> 
>  app/test-pmd/cmdline.c                      | 121 +++++++--
>  doc/guides/rel_notes/release_2_3.rst        |   5 +
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 ++--
>  drivers/net/i40e/i40e_ethdev.c              | 401 +++++++++++++++++-----------
>  drivers/net/i40e/i40e_ethdev.h              |  11 +-
>  drivers/net/i40e/i40e_fdir.c                | 163 ++++++++---
>  lib/librte_ether/rte_eth_ctrl.h             |  35 ++-
>  7 files changed, 529 insertions(+), 263 deletions(-)
> 
> -- 
> 2.4.0
> 

Any review or comments on this patchset?

/Bruce

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

* Re: [PATCH 00/12] extend flow director's fields in i40e driver
  2016-02-24 11:44   ` [PATCH 00/12] extend flow director's fields in i40e driver Bruce Richardson
@ 2016-02-25  7:42     ` Zhang, Helin
  0 siblings, 0 replies; 105+ messages in thread
From: Zhang, Helin @ 2016-02-25  7:42 UTC (permalink / raw)
  To: Richardson, Bruce, Wu, Jingjing; +Cc: dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Bruce Richardson
> Sent: Wednesday, February 24, 2016 7:45 PM
> To: Wu, Jingjing
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 00/12] extend flow director's fields in i40e
> driver
> 
> On Tue, Jan 26, 2016 at 02:26:03PM +0800, Jingjing Wu wrote:
> > This patch set extends flow director to support filtering by
> > additional fields below in i40e driver:
> >  - TOS, Protocol and TTL in IP header
> >  - Tunnel id if NVGRE/GRE/VxLAN packets
> >  - single vlan or inner vlan
> >
> > Jingjing Wu (12):
> >   ethdev: extend flow director to support input set selection
> >   i40e: split function for input set change of hash and fdir
> >   i40e: remove flex payload from INPUT_SET_SELECT operation
> >   i40e: restore default setting on input set of filters
> >   i40e: extend flow director to filter by more IP Header fields
> >   testpmd: extend commands for filter's input set changing
> >   librte_ether: extend rte_eth_fdir_flow to support tunnel format
> >   i40e: extend flow director to filter by tunnel ID
> >   testpmd: extend commands for fdir's tunnel id input set
> >   i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels
> >   i40e: extend flow director to filter by vlan id
> >   testpmd: extend commands for fdir's vlan input set
> >
> >  app/test-pmd/cmdline.c                      | 121 +++++++--
> >  doc/guides/rel_notes/release_2_3.rst        |   5 +
> >  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 ++--
> >  drivers/net/i40e/i40e_ethdev.c              | 401 +++++++++++++++++----------
> -
> >  drivers/net/i40e/i40e_ethdev.h              |  11 +-
> >  drivers/net/i40e/i40e_fdir.c                | 163 ++++++++---
> >  lib/librte_ether/rte_eth_ctrl.h             |  35 ++-
> >  7 files changed, 529 insertions(+), 263 deletions(-)
> >
> > --
> > 2.4.0
> >
> 
> Any review or comments on this patchset?
I am now reviewing it, hopefully review comments will be sent out in
the following days.

Thanks,
Helin

> 
> /Bruce

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

* Re: [PATCH 02/12] i40e: split function for input set change of hash and fdir
  2016-01-26  6:26   ` [PATCH 02/12] i40e: split function for input set change of hash and fdir Jingjing Wu
@ 2016-02-25  8:51     ` Zhang, Helin
  2016-02-26  0:32       ` Wu, Jingjing
  0 siblings, 1 reply; 105+ messages in thread
From: Zhang, Helin @ 2016-02-25  8:51 UTC (permalink / raw)
  To: Wu, Jingjing, dev

Jingjing

Your patches have depencies on my i40e base driver udpate patch set.
Some registers should be read/written by AQ commands, with using interfaces
of i40e_read_rx_ctl() and i40e_write_rx_ctl().

Please check below link and see the list of those registers.
http://www.dpdk.org/dev/patchwork/patch/10654/

Regards,
Helin

> -----Original Message-----
> From: Wu, Jingjing
> Sent: Tuesday, January 26, 2016 2:26 PM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; Zhang, Helin; Chilikin, Andrey; Lu, Wenzhuo; Pei, Yulong
> Subject: [PATCH 02/12] i40e: split function for input set change of hash and
> fdir
> 
> This patch split function for input set changing of hash and fdir to avoid
> multiple check on different situation.
> 
> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c | 233 +++++++++++++++++--------------------
> ----
>  drivers/net/i40e/i40e_ethdev.h |  11 +-
>  drivers/net/i40e/i40e_fdir.c   |   5 +-
>  3 files changed, 107 insertions(+), 142 deletions(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index bf6220d..004e206 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -6845,25 +6845,6 @@ i40e_generate_inset_mask_reg(uint64_t inset,
> uint32_t *mask, uint8_t nb_elem)
>  	return idx;
>  }
> 
> -static uint64_t
> -i40e_get_reg_inset(struct i40e_hw *hw, enum rte_filter_type filter,
> -			    enum i40e_filter_pctype pctype)
> -{
> -	uint64_t reg = 0;
> -
> -	if (filter == RTE_ETH_FILTER_HASH) {
> -		reg = I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(1,
> pctype));
> -		reg <<= I40E_32_BIT_WIDTH;
> -		reg |= I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(0,
> pctype));
> -	} else if (filter == RTE_ETH_FILTER_FDIR) {
> -		reg = I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype,
> 1));
> -		reg <<= I40E_32_BIT_WIDTH;
> -		reg |= I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype,
> 0));
> -	}
> -
> -	return reg;
> -}
> -
>  static void
>  i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
> { @@ -6876,103 +6857,96 @@ i40e_check_write_reg(struct i40e_hw *hw,
> uint32_t addr, uint32_t val)
>  		    (uint32_t)I40E_READ_REG(hw, addr));  }
> 
> -static int
> -i40e_set_hash_inset_mask(struct i40e_hw *hw,
> -			 enum i40e_filter_pctype pctype,
> -			 enum rte_filter_input_set_op op,
> -			 uint32_t *mask_reg,
> -			 uint8_t num)
> +int
> +i40e_hash_filter_inset_select(struct i40e_hw *hw,
> +			 struct rte_eth_input_set_conf *conf)
>  {
> -	uint32_t reg;
> -	uint8_t i;
> +	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
If you have check of 'if (!hw || !conf)', above line is not good.

> +	enum i40e_filter_pctype pctype;
> +	uint64_t input_set, inset_reg = 0;
> +	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
> +	int ret, i, num;
> 
> -	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
> +	if (!hw || !conf) {
Check hw might not be needed at all.

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

* Re: [PATCH 02/12] i40e: split function for input set change of hash and fdir
  2016-02-25  8:51     ` Zhang, Helin
@ 2016-02-26  0:32       ` Wu, Jingjing
  0 siblings, 0 replies; 105+ messages in thread
From: Wu, Jingjing @ 2016-02-26  0:32 UTC (permalink / raw)
  To: Zhang, Helin, dev, Richardson, Bruce



> -----Original Message-----
> From: Zhang, Helin
> Sent: Thursday, February 25, 2016 4:51 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>; dev@dpdk.org
> Cc: Chilikin, Andrey <andrey.chilikin@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> Pei, Yulong <yulong.pei@intel.com>
> Subject: RE: [PATCH 02/12] i40e: split function for input set change of hash and fdir
> 
> Jingjing
> 
> Your patches have depencies on my i40e base driver udpate patch set.
> Some registers should be read/written by AQ commands, with using interfaces
> of i40e_read_rx_ctl() and i40e_write_rx_ctl().
> 
> Please check below link and see the list of those registers.
> http://www.dpdk.org/dev/patchwork/patch/10654/
> 
Yes, I know that. I was planning to rebase this or send a fix after "i40e base driver update" is merged.
> 

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

* [PATCH v2 00/12] extend flow director's fields in i40e driver
  2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
                     ` (12 preceding siblings ...)
  2016-02-24 11:44   ` [PATCH 00/12] extend flow director's fields in i40e driver Bruce Richardson
@ 2016-03-02 11:29   ` Jingjing Wu
  2016-03-02 11:29     ` [PATCH v2 01/12] ethdev: extend flow director to support input set selection Jingjing Wu
                       ` (12 more replies)
  13 siblings, 13 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:29 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

v2 changes:
 - rebase on dpdk-next-net/rel_16_04
 - comments rewording.
 - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to avoid ABI breaking.
 - remove ABI announce in Deprecation.
 - fix the ethertype setting when program filter in v1 patch set.

This patch set extends flow director to support filtering by
additional fields below in i40e driver:
 - TOS, Protocol and TTL in IP header
 - Tunnel id if NVGRE/GRE/VxLAN packets
 - single vlan or inner vlan

Andrey Chilikin (1):
  i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels

Jingjing Wu (11):
  ethdev: extend flow director to support input set selection
  i40e: split function for input set change of hash and fdir
  i40e: remove flex payload from INPUT_SET_SELECT operation
  i40e: restore default setting on input set of filters
  i40e: extend flow director to filter by more IP Header fields
  testpmd: extend commands for filter's input set changing
  librte_ether: extend rte_eth_fdir_flow to support tunnel format
  i40e: extend flow director to filter by tunnel ID
  testpmd: extend commands for fdir's tunnel id input set
  i40e: extend flow director to filter by vlan id
  testpmd: extend commands for fdir's vlan input set

 app/test-pmd/cmdline.c                      | 121 +++++++--
 doc/guides/rel_notes/deprecation.rst        |   4 -
 doc/guides/rel_notes/release_16_04.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 ++--
 drivers/net/i40e/i40e_ethdev.c              | 401 +++++++++++++++++-----------
 drivers/net/i40e/i40e_ethdev.h              |  11 +-
 drivers/net/i40e/i40e_fdir.c                | 206 ++++++++++----
 lib/librte_ether/rte_eth_ctrl.h             |  35 ++-
 8 files changed, 570 insertions(+), 269 deletions(-)

-- 
2.4.0

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

* [PATCH v2 01/12] ethdev: extend flow director to support input set selection
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
@ 2016-03-02 11:29     ` Jingjing Wu
  2016-03-02 11:29     ` [PATCH v2 02/12] i40e: split function for input set change of hash and fdir Jingjing Wu
                       ` (11 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:29 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
by tos, protocol and ttl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index ce224ad..8c51023 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -340,6 +340,8 @@ enum rte_eth_input_set_field {
 	RTE_ETH_INPUT_SET_L3_IP4_PROTO,
 	RTE_ETH_INPUT_SET_L3_IP6_TC,
 	RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
+	RTE_ETH_INPUT_SET_L3_IP4_TTL,
+	RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
 
 	/* L4 */
 	RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT = 257,
@@ -407,6 +409,9 @@ struct rte_eth_l2_flow {
 struct rte_eth_ipv4_flow {
 	uint32_t src_ip;      /**< IPv4 source address to match. */
 	uint32_t dst_ip;      /**< IPv4 destination address to match. */
+	uint8_t  tos;         /**< Type of service to match. */
+	uint8_t  ttl;         /**< Time to live */
+	uint8_t  proto;
 };
 
 /**
@@ -443,6 +448,9 @@ struct rte_eth_sctpv4_flow {
 struct rte_eth_ipv6_flow {
 	uint32_t src_ip[4];      /**< IPv6 source address to match. */
 	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
+	uint8_t  tc;             /**< Traffic class to match. */
+	uint8_t  proto;          /**< Protocol, next header. */
+	uint8_t  hop_limits;
 };
 
 /**
-- 
2.4.0

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

* [PATCH v2 02/12] i40e: split function for input set change of hash and fdir
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
  2016-03-02 11:29     ` [PATCH v2 01/12] ethdev: extend flow director to support input set selection Jingjing Wu
@ 2016-03-02 11:29     ` Jingjing Wu
  2016-03-02 11:29     ` [PATCH v2 03/12] i40e: remove flex payload from INPUT_SET_SELECT operation Jingjing Wu
                       ` (10 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:29 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch split function for input set changing of hash
and fdir to avoid multiple check on different situation.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 233 +++++++++++++++++------------------------
 drivers/net/i40e/i40e_ethdev.h |  11 +-
 drivers/net/i40e/i40e_fdir.c   |   5 +-
 3 files changed, 107 insertions(+), 142 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index c86febc..85419ab 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6914,25 +6914,6 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	return idx;
 }
 
-static uint64_t
-i40e_get_reg_inset(struct i40e_hw *hw, enum rte_filter_type filter,
-			    enum i40e_filter_pctype pctype)
-{
-	uint64_t reg = 0;
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		reg = I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(1, pctype));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(0, pctype));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		reg = I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 1));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 0));
-	}
-
-	return reg;
-}
-
 static void
 i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 {
@@ -6945,103 +6926,96 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)I40E_READ_REG(hw, addr));
 }
 
-static int
-i40e_set_hash_inset_mask(struct i40e_hw *hw,
-			 enum i40e_filter_pctype pctype,
-			 enum rte_filter_input_set_op op,
-			 uint32_t *mask_reg,
-			 uint8_t num)
+int
+i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			 struct rte_eth_input_set_conf *conf)
 {
-	uint32_t reg;
-	uint8_t i;
+	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	if (!hw || !conf) {
+		PMD_DRV_LOG(ERR, "Invalid pointer");
+		return -EFAULT;
+	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
 		return -EINVAL;
-
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = I40E_READ_REG(hw, I40E_GLQF_HASH_MSK(i, pctype));
-			if (reg & I40E_GLQF_HASH_MSK_FIELD)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
-
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[j]);
 	}
 
-	return 0;
-}
-
-static int
-i40e_set_fd_inset_mask(struct i40e_hw *hw,
-		       enum i40e_filter_pctype pctype,
-		       enum rte_filter_input_set_op op,
-		       uint32_t *mask_reg,
-		       uint8_t num)
-{
-	uint32_t reg;
-	uint8_t i;
-
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	pctype = i40e_flowtype_to_pctype(conf->flow_type);
+	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
+		PMD_DRV_LOG(ERR, "Not supported flow type (%u)",
+			    conf->flow_type);
 		return -EINVAL;
+	}
 
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
+	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
+				   conf->inset_size);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to parse input set");
+		return -EINVAL;
+	}
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
+				    input_set) != 0) {
+		PMD_DRV_LOG(ERR, "Invalid input set");
+		return -EINVAL;
+	}
+	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
+		/* get inset value in register */
+		inset_reg = I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(1, pctype));
+		inset_reg <<= I40E_32_BIT_WIDTH;
+		inset_reg |= I40E_READ_REG(hw, I40E_GLQF_HASH_INSET(0, pctype));
+		input_set |= pf->hash_input_set[pctype];
+	}
+	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+					   I40E_INSET_MASK_NUM_REG);
+	if (num < 0)
+		return -EINVAL;
 
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = I40E_READ_REG(hw, I40E_GLQF_FD_MSK(i, pctype));
-			if (reg & I40E_GLQF_FD_MSK_FIELD)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[j]);
-	}
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     0);
+	I40E_WRITE_FLUSH(hw);
 
+	pf->hash_input_set[pctype] = input_set;
 	return 0;
 }
 
 int
-i40e_filter_inset_select(struct i40e_hw *hw,
-			 struct rte_eth_input_set_conf *conf,
-			 enum rte_filter_type filter)
+i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			 struct rte_eth_input_set_conf *conf)
 {
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	enum i40e_filter_pctype pctype;
-	uint64_t inset_reg = 0, input_set;
-	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG];
-	uint8_t num;
-	int ret;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
 	if (!hw || !conf) {
 		PMD_DRV_LOG(ERR, "Invalid pointer");
 		return -EFAULT;
 	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
+		return -EINVAL;
+	}
 
 	pctype = i40e_flowtype_to_pctype(conf->flow_type);
 	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
@@ -7049,60 +7023,48 @@ i40e_filter_inset_select(struct i40e_hw *hw,
 			    conf->flow_type);
 		return -EINVAL;
 	}
-	if (filter != RTE_ETH_FILTER_HASH && filter != RTE_ETH_FILTER_FDIR) {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
-
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, filter, input_set) != 0) {
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
+				    input_set) != 0) {
 		PMD_DRV_LOG(ERR, "Invalid input set");
 		return -EINVAL;
 	}
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
-		inset_reg |= i40e_get_reg_inset(hw, filter, pctype);
-	} else if (conf->op != RTE_ETH_INPUT_SET_SELECT) {
-		PMD_DRV_LOG(ERR, "Unsupported input set operation");
-		return -EINVAL;
-	}
+	/* get inset value in register */
+	inset_reg = I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 1));
+	inset_reg <<= I40E_32_BIT_WIDTH;
+	inset_reg |= I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 0));
+
+	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-	inset_reg |= i40e_translate_input_set_reg(input_set);
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		ret = i40e_set_hash_inset_mask(hw, pctype, conf->op, mask_reg,
-					       num);
-		if (ret)
-			return -EINVAL;
+	if (num < 0)
+		return -EINVAL;
 
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		ret = i40e_set_fd_inset_mask(hw, pctype, conf->op, mask_reg,
-					     num);
-		if (ret)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     0);
 	I40E_WRITE_FLUSH(hw);
 
+	pf->fdir.input_set[pctype] = input_set;
 	return 0;
 }
 
@@ -7154,9 +7116,8 @@ i40e_hash_filter_set(struct i40e_hw *hw, struct rte_eth_hash_filter_info *info)
 				&(info->info.global_conf));
 		break;
 	case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-					       &(info->info.input_set_conf),
-					       RTE_ETH_FILTER_HASH);
+		ret = i40e_hash_filter_inset_select(hw,
+					       &(info->info.input_set_conf));
 		break;
 
 	default:
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index db6173a..50763a3 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -361,6 +361,8 @@ struct i40e_fdir_info {
 	struct i40e_rx_queue *rxq;
 	void *prg_pkt;                 /* memory for fdir program packet */
 	uint64_t dma_addr;             /* physic address of packet memory*/
+	/* input set bits for each pctype */
+	uint64_t input_set[I40E_FILTER_PCTYPE_MAX];
 	/*
 	 * the rule how bytes stream is extracted as flexible payload
 	 * for each payload layer, the setting can up to three elements
@@ -427,6 +429,8 @@ struct i40e_pf {
 	uint16_t fdir_qp_offset;
 
 	uint16_t hash_lut_size; /* The size of hash lookup table */
+	/* input set bits for each pctype */
+	uint64_t hash_input_set[I40E_FILTER_PCTYPE_MAX];
 	/* store VXLAN UDP ports */
 	uint16_t vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];
 	uint16_t vxlan_bitmap; /* Vxlan bit mask */
@@ -570,9 +574,10 @@ int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 int i40e_select_filter_input_set(struct i40e_hw *hw,
 				 struct rte_eth_input_set_conf *conf,
 				 enum rte_filter_type filter);
-int i40e_filter_inset_select(struct i40e_hw *hw,
-			     struct rte_eth_input_set_conf *conf,
-			     enum rte_filter_type filter);
+int i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			     struct rte_eth_input_set_conf *conf);
+int i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			     struct rte_eth_input_set_conf *conf);
 
 void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct rte_eth_rxq_info *qinfo);
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 9ad6981..155a34a 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -1361,7 +1361,6 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 		     struct rte_eth_fdir_filter_info *info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	int ret = 0;
 
 	if (!info) {
@@ -1371,8 +1370,8 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 
 	switch (info->info_type) {
 	case RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-			&(info->info.input_set_conf), RTE_ETH_FILTER_FDIR);
+		ret = i40e_fdir_filter_inset_select(pf,
+				&(info->info.input_set_conf));
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "FD filter info type (%d) not supported",
-- 
2.4.0

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

* [PATCH v2 03/12] i40e: remove flex payload from INPUT_SET_SELECT operation
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
  2016-03-02 11:29     ` [PATCH v2 01/12] ethdev: extend flow director to support input set selection Jingjing Wu
  2016-03-02 11:29     ` [PATCH v2 02/12] i40e: split function for input set change of hash and fdir Jingjing Wu
@ 2016-03-02 11:29     ` Jingjing Wu
  2016-03-02 11:29     ` [PATCH v2 04/12] i40e: restore default setting on input set of filters Jingjing Wu
                       ` (9 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:29 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

In this patch, flex payload is removed from valid fdir input set
values. It is because all flex payload configuration can be set
in struct rte_fdir_conf during device configure phase.
And it is a more flexible configuration including flexpayload's
selection, input set selection by word and mask setting in bits.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 59 +++++++++++++++++++-----------------------
 1 file changed, 26 insertions(+), 33 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 85419ab..63a1df3 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -262,7 +262,8 @@
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD7        0x0000000000000080ULL
 /* 8th word of flex payload */
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD8        0x0000000000000040ULL
-
+/* all 8 words flex payload */
+#define I40E_REG_INSET_FLEX_PAYLOAD_WORDS        0x0000000000003FC0ULL
 #define I40E_REG_INSET_MASK_DEFAULT              0x0000000000000000ULL
 
 #define I40E_TRANSLATE_INSET 0
@@ -6614,43 +6615,32 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
-		I40E_INSET_LAST_ETHER_TYPE | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
 	if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD)
@@ -6878,7 +6868,7 @@ i40e_translate_input_set_reg(uint64_t input)
 	return val;
 }
 
-static uint8_t
+static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
@@ -6896,16 +6886,13 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-	if (!inset && nb_elem >= I40E_INSET_MASK_NUM_REG) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++)
-			mask[i] = 0;
-		return I40E_INSET_MASK_NUM_REG;
-	}
 
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if (idx >= nb_elem)
-			break;
-		if (inset & inset_mask_map[i].inset) {
+		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+			if (idx >= nb_elem) {
+				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
+				return -EINVAL;
+			}
 			mask[idx] = inset_mask_map[i].mask;
 			idx++;
 		}
@@ -7040,7 +7027,13 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 	inset_reg <<= I40E_32_BIT_WIDTH;
 	inset_reg |= I40E_READ_REG(hw, I40E_PRTQF_FD_INSET(pctype, 0));
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+	/* Can not change the inset reg for flex payload for fdir,
+	 * it is done by writing I40E_PRTQF_FD_FLXINSET
+	 * in i40e_set_flex_mask_on_pctype.
+	 */
+	if (conf->op == RTE_ETH_INPUT_SET_SELECT)
+		inset_reg &= I40E_REG_INSET_FLEX_PAYLOAD_WORDS;
+	else
 		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-- 
2.4.0

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

* [PATCH v2 04/12] i40e: restore default setting on input set of filters
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
                       ` (2 preceding siblings ...)
  2016-03-02 11:29     ` [PATCH v2 03/12] i40e: remove flex payload from INPUT_SET_SELECT operation Jingjing Wu
@ 2016-03-02 11:29     ` Jingjing Wu
  2016-03-02 11:30     ` [PATCH v2 05/12] i40e: extend flow director to filter by more IP Header fields Jingjing Wu
                       ` (8 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:29 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch added a new function to set the input set to default
when initialization.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 56 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 63a1df3..d13fde3 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -374,6 +374,7 @@ static int i40e_dev_udp_tunnel_add(struct rte_eth_dev *dev,
 				struct rte_eth_udp_tunnel *udp_tunnel);
 static int i40e_dev_udp_tunnel_del(struct rte_eth_dev *dev,
 				struct rte_eth_udp_tunnel *udp_tunnel);
+static void i40e_filter_input_set_init(struct i40e_pf *pf);
 static int i40e_ethertype_filter_set(struct i40e_pf *pf,
 			struct rte_eth_ethertype_filter *filter,
 			bool add);
@@ -788,6 +789,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	 * It should be removed once issues are fixed in NVM.
 	 */
 	i40e_flex_payload_reg_init(hw);
+	/* Initialize the input set for filters (hash and fd) to default value */
+	i40e_filter_input_set_init(pf);
 
 	/* Initialize the parameters for adminq */
 	i40e_init_adminq_parameter(hw);
@@ -6913,6 +6916,59 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)I40E_READ_REG(hw, addr));
 }
 
+static void
+i40e_filter_input_set_init(struct i40e_pf *pf)
+{
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int num, i;
+
+	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
+		if (!I40E_VALID_PCTYPE(pctype))
+			continue;
+		input_set = i40e_get_default_input_set(pctype);
+
+		num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+						   I40E_INSET_MASK_NUM_REG);
+		if (num < 0)
+			return;
+		inset_reg = i40e_translate_input_set_reg(input_set);
+
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+		for (i = 0; i < num; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     mask_reg[i]);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     mask_reg[i]);
+		}
+		/*clear unused mask registers of the pctype */
+		for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     0);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     0);
+		}
+		I40E_WRITE_FLUSH(hw);
+
+		/* store the default input set */
+		pf->hash_input_set[pctype] = input_set;
+		pf->fdir.input_set[pctype] = input_set;
+	}
+}
+
 int
 i40e_hash_filter_inset_select(struct i40e_hw *hw,
 			 struct rte_eth_input_set_conf *conf)
-- 
2.4.0

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

* [PATCH v2 05/12] i40e: extend flow director to filter by more IP Header fields
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
                       ` (3 preceding siblings ...)
  2016-03-02 11:29     ` [PATCH v2 04/12] i40e: restore default setting on input set of filters Jingjing Wu
@ 2016-03-02 11:30     ` Jingjing Wu
  2016-03-02 11:30     ` [PATCH v2 06/12] testpmd: extend commands for filter's input set changing Jingjing Wu
                       ` (7 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:30 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended flow director to select more IP Header fields
as filter input set.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 69 ++++++++++++++++++++++++++++++++++--------
 drivers/net/i40e/i40e_fdir.c   | 26 +++++++++++-----
 2 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index d13fde3..80c703d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -218,6 +218,8 @@
 #define I40E_REG_INSET_L3_IP4_TOS                0x0040000000000000ULL
 /* IPv4 Protocol */
 #define I40E_REG_INSET_L3_IP4_PROTO              0x0004000000000000ULL
+/* IPv4 Time to Live */
+#define I40E_REG_INSET_L3_IP4_TTL                0x0004000000000000ULL
 /* Source IPv6 address */
 #define I40E_REG_INSET_L3_SRC_IP6                0x0007F80000000000ULL
 /* Destination IPv6 address */
@@ -226,6 +228,8 @@
 #define I40E_REG_INSET_L3_IP6_TC                 0x0040000000000000ULL
 /* IPv6 Next Header */
 #define I40E_REG_INSET_L3_IP6_NEXT_HDR           0x0008000000000000ULL
+/* IPv6 Hop Limitr */
+#define I40E_REG_INSET_L3_IP6_HOP_LIMIT          0x0008000000000000ULL
 /* Source L4 port */
 #define I40E_REG_INSET_L4_SRC_PORT               0x0000000400000000ULL
 /* Destination L4 port */
@@ -269,10 +273,12 @@
 #define I40E_TRANSLATE_INSET 0
 #define I40E_TRANSLATE_REG   1
 
-#define I40E_INSET_IPV4_TOS_MASK      0x0009FF00UL
-#define I40E_INSET_IPV4_PROTO_MASK    0x000DFF00UL
-#define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
-#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
+#define I40E_INSET_IPV4_TOS_MASK        0x0009FF00UL
+#define I40E_INSET_IPv4_TTL_MASK        0x000D00FFUL
+#define I40E_INSET_IPV4_PROTO_MASK      0x000DFF00UL
+#define I40E_INSET_IPV6_TC_MASK         0x0009F00FUL
+#define I40E_INSET_IPV6_HOP_LIMIT_MASK  0x000CFF00UL
+#define I40E_INSET_IPV6_NEXT_HDR_MASK   0x000C00FFUL
 
 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
@@ -6618,30 +6624,47 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
@@ -6741,11 +6764,14 @@ i40e_parse_input_set(uint64_t *inset,
 		{RTE_ETH_INPUT_SET_L3_DST_IP4, I40E_INSET_IPV4_DST},
 		{RTE_ETH_INPUT_SET_L3_IP4_TOS, I40E_INSET_IPV4_TOS},
 		{RTE_ETH_INPUT_SET_L3_IP4_PROTO, I40E_INSET_IPV4_PROTO},
+		{RTE_ETH_INPUT_SET_L3_IP4_TTL, I40E_INSET_IPV4_TTL},
 		{RTE_ETH_INPUT_SET_L3_SRC_IP6, I40E_INSET_IPV6_SRC},
 		{RTE_ETH_INPUT_SET_L3_DST_IP6, I40E_INSET_IPV6_DST},
 		{RTE_ETH_INPUT_SET_L3_IP6_TC, I40E_INSET_IPV6_TC},
 		{RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
 			I40E_INSET_IPV6_NEXT_HDR},
+		{RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
+			I40E_INSET_IPV6_HOP_LIMIT},
 		{RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT, I40E_INSET_SRC_PORT},
@@ -6832,10 +6858,12 @@ i40e_translate_input_set_reg(uint64_t input)
 		{I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4},
 		{I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS},
 		{I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO},
+		{I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL},
 		{I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6},
 		{I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6},
 		{I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_REG_INSET_L3_IP6_NEXT_HDR},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_REG_INSET_L3_IP6_HOP_LIMIT},
 		{I40E_INSET_SRC_PORT, I40E_REG_INSET_L4_SRC_PORT},
 		{I40E_INSET_DST_PORT, I40E_REG_INSET_L4_DST_PORT},
 		{I40E_INSET_SCTP_VT, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG},
@@ -6875,23 +6903,38 @@ static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
+	uint64_t inset_need_mask = inset;
 
 	static const struct {
 		uint64_t inset;
 		uint32_t mask;
 	} inset_mask_map[] = {
 		{I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK},
+		{I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0},
 		{I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK},
+		{I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK},
 		{I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK},
+		{I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK}
 	};
 
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+		/* Clear the inset bit, if no MASK is required,
+		 * for example proto + ttl
+		 */
+		if ((inset & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset && inset_mask_map[i].mask == 0)
+			inset_need_mask &= ~inset_mask_map[i].inset;
+		if (!inset_need_mask)
+			return 0;
+	}
+	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
+		if ((inset_need_mask & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset) {
 			if (idx >= nb_elem) {
 				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
 				return -EINVAL;
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 155a34a..5ea97e5 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -65,7 +65,9 @@
 #define I40E_FDIR_IP_DEFAULT_TTL            0x40
 #define I40E_FDIR_IP_DEFAULT_VERSION_IHL    0x45
 #define I40E_FDIR_TCP_DEFAULT_DATAOFF       0x50
-#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60300000
+#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60000000
+#define I40E_FDIR_IPv6_TC_OFFSET            20
+
 #define I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS   0xFF
 #define I40E_FDIR_IPv6_PAYLOAD_LEN          380
 #define I40E_FDIR_UDP_DEFAULT_LEN           400
@@ -719,7 +721,13 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
-		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+		ip->next_proto_id = fdir_input->flow.ip4_flow.proto ?
+					fdir_input->flow.ip4_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip->time_to_live = fdir_input->flow.ip4_flow.ttl ?
+					fdir_input->flow.ip4_flow.ttl :
+					I40E_FDIR_IP_DEFAULT_TTL;
+		ip->type_of_service = fdir_input->flow.ip4_flow.tos;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -727,7 +735,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		 */
 		ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
 		ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
-		ip->next_proto_id = next_proto[fdir_input->flow_type];
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
@@ -738,11 +745,17 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 
 		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
-			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
+					 (fdir_input->flow.ipv6_flow.tc <<
+					  I40E_FDIR_IPv6_TC_OFFSET));
 		ip6->payload_len =
 			rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
-		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
-
+		ip6->proto = fdir_input->flow.ipv6_flow.proto ?
+					fdir_input->flow.ipv6_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ?
+					fdir_input->flow.ipv6_flow.hop_limits :
+					I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -754,7 +767,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		rte_memcpy(&(ip6->dst_addr),
 			   &(fdir_input->flow.ipv6_flow.src_ip),
 			   IPV6_ADDR_LEN);
-		ip6->proto = next_proto[fdir_input->flow_type];
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
-- 
2.4.0

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

* [PATCH v2 06/12] testpmd: extend commands for filter's input set changing
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
                       ` (4 preceding siblings ...)
  2016-03-02 11:30     ` [PATCH v2 05/12] i40e: extend flow director to filter by more IP Header fields Jingjing Wu
@ 2016-03-02 11:30     ` Jingjing Wu
  2016-03-02 11:30     ` [PATCH v2 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format Jingjing Wu
                       ` (6 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:30 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended commands for filter's input set changing.
It added tos, protocol and ttl as filter's input fields, and
remove the words selection from flex payloads for flow director.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 100 ++++++++++++++++++++++------
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  42 +++++++-----
 2 files changed, 104 insertions(+), 38 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..5787f57 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -642,6 +642,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"flow_director_filter (port_id) mode IP (add|del|update)"
 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
+			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -651,6 +652,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
+			" tos (tos_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -660,7 +662,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-sctp|ipv6-sctp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
-			" tag (verification_tag) vlan (vlan_value)"
+			" tag (verification_tag) "
+			" tos (tos_value) ttl (ttl_value)"
+			" vlan (vlan_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -740,14 +744,15 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"fld-8th|none) (select|add)\n"
 			"    Set the input set for hash.\n\n"
 
-			"set_fdir_input_set (port_id) (ipv4|ipv4-frag|"
-			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+			"set_fdir_input_set (port_id) "
+			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
-			"udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|"
-			"sctp-src-port|sctp-dst-port|sctp-veri-tag|fld-1st|"
-			"fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
-			"fld-8th|none) (select|add)\n"
+			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
+			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
+			"udp-dst-port|tcp-src-port|tcp-dst-port|"
+			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
+			" (select|add)\n"
 			"    Set the input set for FDir.\n\n"
 		);
 	}
@@ -7985,6 +7990,12 @@ struct cmd_flow_director_result {
 	uint16_t port_dst;
 	cmdline_fixed_string_t verify_tag;
 	uint32_t verify_tag_value;
+	cmdline_ipaddr_t tos;
+	uint8_t tos_value;
+	cmdline_ipaddr_t proto;
+	uint8_t proto_value;
+	cmdline_ipaddr_t ttl;
+	uint8_t ttl_value;
 	cmdline_fixed_string_t vlan;
 	uint16_t vlan_value;
 	cmdline_fixed_string_t flexbytes;
@@ -8164,12 +8175,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 	switch (entry.input.flow_type) {
 	case RTE_ETH_FLOW_FRAG_IPV4:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+		entry.input.flow.ip4_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 		IPV4_ADDR_TO_UINT(res->ip_dst,
 			entry.input.flow.ip4_flow.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.ip4_flow.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8181,6 +8195,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp4_flow.ip.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.sctp4_flow.ip.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8191,12 +8207,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 		break;
 	case RTE_ETH_FLOW_FRAG_IPV6:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+		entry.input.flow.ipv6_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 		IPV6_ADDR_TO_ARRAY(res->ip_dst,
 			entry.input.flow.ipv6_flow.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.ipv6_flow.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8208,6 +8227,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp6_flow.ip.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.sctp6_flow.ip.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8335,6 +8356,24 @@ cmdline_parse_token_string_t cmd_flow_director_verify_tag =
 cmdline_parse_token_num_t cmd_flow_director_verify_tag_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
 			      verify_tag_value, UINT32);
+cmdline_parse_token_string_t cmd_flow_director_tos =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 tos, "tos");
+cmdline_parse_token_num_t cmd_flow_director_tos_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      tos_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_proto =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 proto, "proto");
+cmdline_parse_token_num_t cmd_flow_director_proto_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      proto_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_ttl =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 ttl, "ttl");
+cmdline_parse_token_num_t cmd_flow_director_ttl_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      ttl_value, UINT8);
 cmdline_parse_token_string_t cmd_flow_director_vlan =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 vlan, "vlan");
@@ -8413,6 +8452,12 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ip_src,
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_proto,
+		(void *)&cmd_flow_director_proto_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8445,6 +8490,10 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
 		(void *)&cmd_flow_director_port_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8479,6 +8528,10 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_port_dst,
 		(void *)&cmd_flow_director_verify_tag,
 		(void *)&cmd_flow_director_verify_tag_value,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -9405,16 +9458,19 @@ str2inset(char *string)
 		char str[32];
 		enum rte_eth_input_set_field inset;
 	} inset_table[] = {
+		{"ethertype", RTE_ETH_INPUT_SET_L2_ETHERTYPE},
 		{"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
 		{"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
 		{"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
 		{"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
 		{"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
 		{"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
+		{"ipv4-ttl", RTE_ETH_INPUT_SET_L3_IP4_TTL},
 		{"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
 		{"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
 		{"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
 		{"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
+		{"ipv6-hop-limits", RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS},
 		{"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
 		{"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
 		{"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
@@ -9473,7 +9529,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
 		flow_type,
-		"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
@@ -9492,8 +9548,8 @@ cmdline_parse_inst_t cmd_set_hash_input_set = {
 	.f = cmd_set_hash_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_hash_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
@@ -9548,15 +9604,16 @@ cmdline_parse_token_num_t cmd_set_fdir_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	flow_type,
-	"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+	"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 	"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#udp-src-port#udp-dst-port#"
+	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
+	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
-	"sctp-veri-tag#fld-1st#fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#"
-	"fld-7th#fld-8th#none");
+	"sctp-veri-tag#none");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	select, "select#add");
@@ -9565,12 +9622,13 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.f = cmd_set_fdir_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_fdir_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port|"
-	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|"
-	"fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
-	"fld-7th|fld-8th|none select|add",
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
+	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
+	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
+	"sctp-veri-tag|none select|add",
 	.tokens = {
 		(void *)&cmd_set_fdir_input_set_cmd,
 		(void *)&cmd_set_fdir_input_set_port_id,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index a520cc5..f59e63e 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1678,8 +1678,9 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 # Commands to add flow director filters of different flow types::
 
    flow_director_filter (port_id) mode IP (add|del|update) \
-                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)
+                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag) \
                         src (src_ip_address) dst (dst_ip_address) \
+                        tos (tos_value) proto (proto_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) pf|vf(vf_id) queue (queue_id) \
                         fd_id (fd_id_value)
@@ -1688,6 +1689,7 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp) \
                         src (src_ip_address) (src_port) \
                         dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) queue pf|vf(vf_id) (queue_id) \
                         fd_id (fd_id_value)
@@ -1695,7 +1697,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
    flow_director_filter (port_id) mode IP (add|del|update) \
                         flow (ipv4-sctp|ipv6-sctp) \
                         src (src_ip_address) (src_port) \
-                        dst (dst_ip_address) (dst_port)
+                        dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         tag (verification_tag) vlan (vlan_value) \
                         flexbytes (flexbytes_value) (drop|fwd) \
                         pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)
@@ -1719,12 +1722,14 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 For example, to add an ipv4-udp flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-udp src 2.2.2.3 32 \
-            dst 2.2.2.5 33 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+            dst 2.2.2.5 33 tos 2 ttl 40 vlan 0x1 flexbytes (0x88,0x48) \
+            fwd pf queue 1 fd_id 1
 
 For example, add an ipv4-other flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
-             dst 2.2.2.5 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+             dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 \
+             flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
 flush_flow_director
 ~~~~~~~~~~~~~~~~~~~
@@ -1841,33 +1846,36 @@ set_hash_input_set
 
 Set the input set for hash::
 
-   set_hash_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   set_hash_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
    l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port| \
    tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
    udp-key|gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th| \
    fld-8th|none) (select|add)
 
-For example, to add source IP to hash input set for flow type of ipv4 on port 0::
+For example, to add source IP to hash input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_hash_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_hash_input_set 0 ipv4-udp src-ipv4 add
 
 set_fdir_input_set
 ~~~~~~~~~~~~~~~~~~
 
-Set the input set for Fdir::
+The Flow Director filters can match the different fields for different type of packet, i.e. specific input set
+on per flow type and the flexible payload. This command can be used to change input set for each flow type.
 
-   set_fdir_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)
-   (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port| \
-   tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
-   fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|fld-8th|none) \
-   (select|add)
+Set the input set for flow director::
+
+   set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
+   tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
+   sctp-dst-port|sctp-veri-tag|none) (select|add)
 
-For example to add source IP to FD input set for flow type of ipv4 on port 0::
+For example to add source IP to FD input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_fdir_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_fdir_input_set 0 ipv4-udp src-ipv4 add
 
 global_config
 ~~~~~~~~~~~~~
-- 
2.4.0

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

* [PATCH v2 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
                       ` (5 preceding siblings ...)
  2016-03-02 11:30     ` [PATCH v2 06/12] testpmd: extend commands for filter's input set changing Jingjing Wu
@ 2016-03-02 11:30     ` Jingjing Wu
  2016-03-02 11:30     ` [PATCH v2 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
                       ` (5 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:30 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch changed rte_eth_fdir_flow from union to struct to
support more packets formats, for example, Vxlan and GRE tunnel
packets with IP inner frame.

This patch also add new RTE_FDIR_TUNNEL_TYPE_GRE enum.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/rel_notes/deprecation.rst   |  4 ----
 doc/guides/rel_notes/release_16_04.rst |  3 +++
 lib/librte_ether/rte_eth_ctrl.h        | 27 +++++++++++++++------------
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..7fa8639 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -20,10 +20,6 @@ Deprecation Notices
   tables (512 queues).
   It should be integrated in release 2.3.
 
-* ABI changes are planned for struct rte_eth_fdir_flow in order to support
-  extend flow director's input set. The release 2.2 does not contain these ABI
-  changes, but release 2.3 will, and no backwards compatibility is planned.
-
 * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow to
   include more fields to be matched against. The release 2.2 does not
   contain these ABI changes, but release 2.3 will.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 73494f9..1d784d3 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -183,6 +183,9 @@ ABI Changes
   the previous releases and made in this release. Use fixed width quotes for
   ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
+* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
+  changed. New fields were added to extend flow director's input set, and
+  organizing is also changed to support multiple input format.
 
 Shared Library Versions
 -----------------------
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 8c51023..b6a5c50 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -495,6 +495,7 @@ enum rte_eth_fdir_tunnel_type {
 	RTE_FDIR_TUNNEL_TYPE_UNKNOWN = 0,
 	RTE_FDIR_TUNNEL_TYPE_NVGRE,
 	RTE_FDIR_TUNNEL_TYPE_VXLAN,
+	RTE_FDIR_TUNNEL_TYPE_GRE,
 };
 
 /**
@@ -508,18 +509,20 @@ struct rte_eth_tunnel_flow {
 };
 
 /**
- * An union contains the inputs for all types of flow
+ * A struct contains the inputs for all types of flow
  */
-union rte_eth_fdir_flow {
-	struct rte_eth_l2_flow     l2_flow;
-	struct rte_eth_udpv4_flow  udp4_flow;
-	struct rte_eth_tcpv4_flow  tcp4_flow;
-	struct rte_eth_sctpv4_flow sctp4_flow;
-	struct rte_eth_ipv4_flow   ip4_flow;
-	struct rte_eth_udpv6_flow  udp6_flow;
-	struct rte_eth_tcpv6_flow  tcp6_flow;
-	struct rte_eth_sctpv6_flow sctp6_flow;
-	struct rte_eth_ipv6_flow   ipv6_flow;
+struct rte_eth_fdir_flow {
+	union {
+		struct rte_eth_l2_flow     l2_flow;
+		struct rte_eth_udpv4_flow  udp4_flow;
+		struct rte_eth_tcpv4_flow  tcp4_flow;
+		struct rte_eth_sctpv4_flow sctp4_flow;
+		struct rte_eth_ipv4_flow   ip4_flow;
+		struct rte_eth_udpv6_flow  udp6_flow;
+		struct rte_eth_tcpv6_flow  tcp6_flow;
+		struct rte_eth_sctpv6_flow sctp6_flow;
+		struct rte_eth_ipv6_flow   ipv6_flow;
+	};
 	struct rte_eth_mac_vlan_flow mac_vlan_flow;
 	struct rte_eth_tunnel_flow   tunnel_flow;
 };
@@ -540,7 +543,7 @@ struct rte_eth_fdir_flow_ext {
  */
 struct rte_eth_fdir_input {
 	uint16_t flow_type;
-	union rte_eth_fdir_flow flow;
+	struct rte_eth_fdir_flow flow;
 	/**< Flow fields to match, dependent on flow_type */
 	struct rte_eth_fdir_flow_ext flow_ext;
 	/**< Additional fields to match */
-- 
2.4.0

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

* [PATCH v2 08/12] i40e: extend flow director to filter by tunnel ID
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
                       ` (6 preceding siblings ...)
  2016-03-02 11:30     ` [PATCH v2 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format Jingjing Wu
@ 2016-03-02 11:30     ` Jingjing Wu
  2016-03-02 11:30     ` [PATCH v2 09/12] testpmd: extend commands for fdir's tunnel id input set Jingjing Wu
                       ` (4 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:30 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended flow director to select Vxlan/GRE tunnel ID
as filter's input set and program the filter rule with the defined
tunnel type.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c |  11 +++
 drivers/net/i40e/i40e_fdir.c   | 150 +++++++++++++++++++++++++++++++----------
 2 files changed, 125 insertions(+), 36 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 80c703d..df20b6c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6624,48 +6624,59 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 5ea97e5..48ec63b 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -687,12 +687,41 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 }
 
 static inline void
-i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
-			       unsigned char *raw_pkt)
+i40e_fdir_fill_ether_head(const struct rte_eth_fdir_input *fdir_input,
+			       unsigned char *pkt)
 {
-	struct ether_hdr *ether = (struct ether_hdr *)raw_pkt;
-	struct ipv4_hdr *ip;
-	struct ipv6_hdr *ip6;
+	struct ether_hdr *ether = (struct ether_hdr *)pkt;
+	switch (fdir_input->flow_type) {
+	case RTE_ETH_FLOW_L2_PAYLOAD:
+		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
+		break;
+	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
+	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
+	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
+	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+	case RTE_ETH_FLOW_FRAG_IPV4:
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		break;
+	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
+	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
+	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
+	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+	case RTE_ETH_FLOW_FRAG_IPV6:
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unknown flow type %u.",
+			    fdir_input->flow_type);
+		break;
+	}
+}
+
+static inline void
+i40e_fdir_fill_ip_head(const struct rte_eth_fdir_input *fdir_input,
+			       unsigned char *pkt)
+{
+	struct ipv4_hdr *ip = (struct ipv4_hdr *)pkt;
+	struct ipv6_hdr *ip6 = (struct ipv6_hdr *)pkt;
 	static const uint8_t next_proto[] = {
 		[RTE_ETH_FLOW_FRAG_IPV4] = IPPROTO_IP,
 		[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] = IPPROTO_TCP,
@@ -707,17 +736,11 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 	};
 
 	switch (fdir_input->flow_type) {
-	case RTE_ETH_FLOW_L2_PAYLOAD:
-		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
-		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		ip = (struct ipv4_hdr *)(raw_pkt + sizeof(struct ether_hdr));
-
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
@@ -741,9 +764,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		ip6 = (struct ipv6_hdr *)(raw_pkt + sizeof(struct ether_hdr));
-
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
 			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
 					 (fdir_input->flow.ipv6_flow.tc <<
@@ -775,7 +795,7 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 	}
 }
 
-
+#define I40E_TUNNEL_KEY_LEN 4
 /*
  * i40e_fdir_construct_pkt - construct packet based on fields in input
  * @pf: board private structure
@@ -787,21 +807,86 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			     const struct rte_eth_fdir_input *fdir_input,
 			     unsigned char *raw_pkt)
 {
-	unsigned char *payload, *ptr;
+	unsigned char *payload, *ptr, *inner_pkt = raw_pkt;
 	struct udp_hdr *udp;
 	struct tcp_hdr *tcp;
 	struct sctp_hdr *sctp;
 	uint8_t size, dst = 0;
 	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
+	static uint8_t gre4_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x08, 0,
+			0, 0, 0, 0}; /* Mac+ IP + GRE hdr + key */
+	static uint8_t gre6_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x86, 0xDD,
+			0, 0, 0, 0}; /* Mac+ IP + GRE hdr + key */
+	static uint8_t vxlan_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x11,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			0x12, 0xB5, 0x12, 0xB5, 0x08, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0}; /* Mac + IP + UDP + VXLAN hdr */
+	static uint8_t nvgre_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x65, 0x58,
+			0, 0, 0, 0}; /*Mac + IP + NVGRE hdr*/
+
+	inner_pkt += 2 * sizeof(struct ether_addr);
+	/* fill the tunnel header if required */
+	switch (fdir_input->flow.tunnel_flow.tunnel_type) {
+	case RTE_FDIR_TUNNEL_TYPE_GRE:
+		if (fdir_input->flow_type == RTE_ETH_FLOW_L2_PAYLOAD) {
+			PMD_DRV_LOG(ERR, "GRE's inner pkt shouldn't"
+				    " be L2 frame.");
+			return -EINVAL;
+		}
+		if ((fdir_input->flow_type) == RTE_ETH_FLOW_FRAG_IPV4 ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_TCP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_UDP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_SCTP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_OTHER)
+			rte_memcpy(inner_pkt, gre4_frame, sizeof(gre4_frame));
+		else
+			rte_memcpy(inner_pkt, gre6_frame, sizeof(gre6_frame));
+		/* gre4_frame and gre6_frame have the same size */
+		inner_pkt += sizeof(gre4_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		break;
+	case RTE_FDIR_TUNNEL_TYPE_VXLAN:
+		rte_memcpy(inner_pkt, vxlan_frame, sizeof(vxlan_frame));
+		inner_pkt += sizeof(vxlan_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		/* fill the ethernet and IP head of inner frame */
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		inner_pkt += sizeof(struct ether_hdr);
+		break;
+	case RTE_FDIR_TUNNEL_TYPE_NVGRE:
+		rte_memcpy(inner_pkt, nvgre_frame, sizeof(nvgre_frame));
+		inner_pkt += sizeof(nvgre_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		/* fill the Ether header of inner frame */
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		inner_pkt += sizeof(struct ether_hdr);
+		break;
+	default:
+		/* fill the Ether header of single frame */
+		i40e_fdir_fill_ether_head(fdir_input, raw_pkt);
+		inner_pkt = raw_pkt + sizeof(struct ether_hdr);
+		break;
+	}
 
-	/* fill the ethernet and IP head */
-	i40e_fdir_fill_eth_ip_head(fdir_input, raw_pkt);
-
+	/* fill the IP header of inner or single frame */
+	i40e_fdir_fill_ip_head(fdir_input, inner_pkt);
 	/* fill the L4 head */
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-				sizeof(struct ipv4_hdr));
+		udp = (struct udp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -814,8 +899,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv4_hdr));
+		tcp = (struct tcp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -828,8 +912,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv4_hdr));
+		sctp = (struct sctp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -843,14 +926,12 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv4_hdr);
+		payload = inner_pkt + sizeof(struct ipv4_hdr);
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		udp = (struct udp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -863,8 +944,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		tcp = (struct tcp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -877,8 +957,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv6_hdr));
+		sctp = (struct sctp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -892,12 +971,11 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv6_hdr);
+		payload = inner_pkt + sizeof(struct ipv6_hdr);
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		payload = raw_pkt + sizeof(struct ether_hdr);
+		payload = inner_pkt;
 		/*
 		 * ARP packet is a special case on which the payload
 		 * starts after the whole ARP header
-- 
2.4.0

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

* [PATCH v2 09/12] testpmd: extend commands for fdir's tunnel id input set
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
                       ` (7 preceding siblings ...)
  2016-03-02 11:30     ` [PATCH v2 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
@ 2016-03-02 11:30     ` Jingjing Wu
  2016-03-02 11:30     ` [PATCH v2 10/12] i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels Jingjing Wu
                       ` (3 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:30 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended commands for filter's input set changing.
It added GRE/Vxlan Tunnel as filter's input fields.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 27 +++++++++++++++++++++------
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 22 ++++++++++++++++------
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 5787f57..9cba2cc 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -643,7 +643,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
 			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
-			" vlan (vlan_value) flexbytes (flexbytes_value)"
+			" vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel)"
+			" (tunnel_id_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
 			"    Add/Del an IP type flow director filter.\n\n"
@@ -653,7 +654,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
 			" tos (tos_value) ttl (ttl_value)"
-			" vlan (vlan_value) flexbytes (flexbytes_value)"
+			" vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel)"
+			" (tunnel_id_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
 			"    Add/Del an UDP/TCP type flow director filter.\n\n"
@@ -665,6 +667,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" tag (verification_tag) "
 			" tos (tos_value) ttl (ttl_value)"
 			" vlan (vlan_value)"
+			" (NVGRE|VxLAN|GRE|Notunnel) (tunnel_id_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -751,7 +754,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
 			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
 			"udp-dst-port|tcp-src-port|tcp-dst-port|"
-			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
+			"sctp-src-port|sctp-dst-port|sctp-veri-tag|"
+			"udp-key|gre-key|none)"
 			" (select|add)\n"
 			"    Set the input set for FDir.\n\n"
 		);
@@ -8094,6 +8098,7 @@ str2fdir_tunneltype(char *string)
 	} tunneltype_str[] = {
 		{"NVGRE", RTE_FDIR_TUNNEL_TYPE_NVGRE},
 		{"VxLAN", RTE_FDIR_TUNNEL_TYPE_VXLAN},
+		{"GRE",   RTE_FDIR_TUNNEL_TYPE_GRE},
 	};
 
 	for (i = 0; i < RTE_DIM(tunneltype_str); i++) {
@@ -8265,6 +8270,10 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 		   RTE_ETH_FDIR_MAX_FLEXLEN);
 
 	entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value);
+	entry.input.flow.tunnel_flow.tunnel_type =
+		str2fdir_tunneltype(res->tunnel_type);
+	entry.input.flow.tunnel_flow.tunnel_id =
+			rte_cpu_to_be_32(res->tunnel_id_value);
 
 	entry.action.flex_off = 0;  /*use 0 by default */
 	if (!strcmp(res->drop, "drop"))
@@ -8428,7 +8437,7 @@ cmdline_parse_token_string_t cmd_flow_director_tunnel =
 				 tunnel, "tunnel");
 cmdline_parse_token_string_t cmd_flow_director_tunnel_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
-				 tunnel_type, "NVGRE#VxLAN");
+				 tunnel_type, "NVGRE#VxLAN#GRE#Notunnel");
 cmdline_parse_token_string_t cmd_flow_director_tunnel_id =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 tunnel_id, "tunnel-id");
@@ -8460,6 +8469,8 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -8496,6 +8507,8 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -8534,6 +8547,8 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -9613,7 +9628,7 @@ cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
 	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
-	"sctp-veri-tag#none");
+	"sctp-veri-tag#udp-key#gre-key#none");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	select, "select#add");
@@ -9628,7 +9643,7 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
 	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
 	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
-	"sctp-veri-tag|none select|add",
+	"sctp-veri-tag|udp-key|gre-key|none select|add",
 	.tokens = {
 		(void *)&cmd_set_fdir_input_set_cmd,
 		(void *)&cmd_set_fdir_input_set_port_id,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f59e63e..417ddde 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1681,7 +1681,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag) \
                         src (src_ip_address) dst (dst_ip_address) \
                         tos (tos_value) proto (proto_value) ttl (ttl_value) \
-                        vlan (vlan_value) flexbytes (flexbytes_value) \
+                        vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel) \
+                        (tunnel_id_value) flexbytes (flexbytes_value) \
                         (drop|fwd) pf|vf(vf_id) queue (queue_id) \
                         fd_id (fd_id_value)
 
@@ -1690,7 +1691,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         src (src_ip_address) (src_port) \
                         dst (dst_ip_address) (dst_port) \
                         tos (tos_value) ttl (ttl_value) \
-                        vlan (vlan_value) flexbytes (flexbytes_value) \
+                        vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel) \
+                        (tunnel_id_value) flexbytes (flexbytes_value) \
                         (drop|fwd) queue pf|vf(vf_id) (queue_id) \
                         fd_id (fd_id_value)
 
@@ -1700,6 +1702,7 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         dst (dst_ip_address) (dst_port) \
                         tos (tos_value) ttl (ttl_value) \
                         tag (verification_tag) vlan (vlan_value) \
+                        (NVGRE|VxLAN|GRE|Notunnel) (tunnel_id_value) \
                         flexbytes (flexbytes_value) (drop|fwd) \
                         pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)
 
@@ -1722,15 +1725,21 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 For example, to add an ipv4-udp flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-udp src 2.2.2.3 32 \
-            dst 2.2.2.5 33 tos 2 ttl 40 vlan 0x1 flexbytes (0x88,0x48) \
-            fwd pf queue 1 fd_id 1
+            dst 2.2.2.5 33  tos 2 ttl 40 vlan 0x1 Notunnel 0 \
+            flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
 For example, add an ipv4-other flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
-             dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 \
+             dst 2.2.2.5  tos 2 proto 20 ttl 40 vlan 0x1 Notunnel 0 \
              flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
+For example, add a ipv4-other flow type filter with GRE key 0x0a0b0c0d:
+
+   testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
+            dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 GRE 0x0a0b0c0d \
+            flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+
 flush_flow_director
 ~~~~~~~~~~~~~~~~~~~
 
@@ -1861,6 +1870,7 @@ For example, to add source IP to hash input set for flow type of ipv4-udp on por
 set_fdir_input_set
 ~~~~~~~~~~~~~~~~~~
 
+
 The Flow Director filters can match the different fields for different type of packet, i.e. specific input set
 on per flow type and the flexible payload. This command can be used to change input set for each flow type.
 
@@ -1871,7 +1881,7 @@ Set the input set for flow director::
    l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
    tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
-   sctp-dst-port|sctp-veri-tag|none) (select|add)
+   sctp-dst-port|sctp-veri-tag|udp-key|gre-key|none) (select|add)
 
 For example to add source IP to FD input set for flow type of ipv4-udp on port 0::
 
-- 
2.4.0

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

* [PATCH v2 10/12] i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
                       ` (8 preceding siblings ...)
  2016-03-02 11:30     ` [PATCH v2 09/12] testpmd: extend commands for fdir's tunnel id input set Jingjing Wu
@ 2016-03-02 11:30     ` Jingjing Wu
  2016-03-02 11:30     ` [PATCH v2 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
                       ` (2 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:30 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

From: Andrey Chilikin <andrey.chilikin@intel.com>

This patch adds missing VLAN bitmask for inner frame in case of
tunneling and fixes VLAN tags bitmasks for single or outer frame
in case of tunneling.

Fixes: 98f055707685 ("i40e: configure input fields for RSS or flow director")

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index df20b6c..6401768 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -206,10 +206,12 @@
 #define I40E_REG_INSET_L2_DMAC                   0xE000000000000000ULL
 /* Source MAC address */
 #define I40E_REG_INSET_L2_SMAC                   0x1C00000000000000ULL
-/* VLAN tag in the outer L2 header */
-#define I40E_REG_INSET_L2_OUTER_VLAN             0x0080000000000000ULL
-/* VLAN tag in the inner L2 header */
-#define I40E_REG_INSET_L2_INNER_VLAN             0x0100000000000000ULL
+/* Outer (S-Tag) VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_OUTER_VLAN             0x0200000000000000ULL
+/* Inner (C-Tag) or single VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_INNER_VLAN             0x0080000000000000ULL
+/* Single VLAN tag in the inner L2 header */
+#define I40E_REG_INSET_TUNNEL_VLAN               0x0100000000000000ULL
 /* Source IPv4 address */
 #define I40E_REG_INSET_L3_SRC_IP4                0x0001800000000000ULL
 /* Destination IPv4 address */
@@ -6887,7 +6889,7 @@ i40e_translate_input_set_reg(uint64_t input)
 			I40E_REG_INSET_TUNNEL_L4_UDP_SRC_PORT},
 		{I40E_INSET_TUNNEL_DST_PORT,
 			I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT},
-		{I40E_INSET_TUNNEL_ID, I40E_REG_INSET_TUNNEL_ID},
+		{I40E_INSET_VLAN_TUNNEL, I40E_REG_INSET_TUNNEL_VLAN},
 		{I40E_INSET_FLEX_PAYLOAD_W1, I40E_REG_INSET_FLEX_PAYLOAD_WORD1},
 		{I40E_INSET_FLEX_PAYLOAD_W2, I40E_REG_INSET_FLEX_PAYLOAD_WORD2},
 		{I40E_INSET_FLEX_PAYLOAD_W3, I40E_REG_INSET_FLEX_PAYLOAD_WORD3},
-- 
2.4.0

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

* [PATCH v2 11/12] i40e: extend flow director to filter by vlan id
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
                       ` (9 preceding siblings ...)
  2016-03-02 11:30     ` [PATCH v2 10/12] i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels Jingjing Wu
@ 2016-03-02 11:30     ` Jingjing Wu
  2016-03-02 11:30     ` [PATCH v2 12/12] testpmd: extend commands for fdir's vlan input set Jingjing Wu
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:30 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended flow director to select vlan id
as filter's input set and program the filter rule with vlan id.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst |  2 ++
 drivers/net/i40e/i40e_ethdev.c         | 11 ++++++++
 drivers/net/i40e/i40e_fdir.c           | 49 ++++++++++++++++++++++++++--------
 3 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 1d784d3..8c7b3e1 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -74,6 +74,8 @@ This section should contain new features added in this release. Sample format:
 
 * **szedata2: Add functions for setting link up/down.**
 
+* **Added Flow director enhancements on Intel X710/XL710.**
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 6401768..a829e8b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6626,58 +6626,69 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 48ec63b..33be634 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -686,34 +686,50 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 	return ret;
 }
 
-static inline void
+static inline int
 i40e_fdir_fill_ether_head(const struct rte_eth_fdir_input *fdir_input,
-			       unsigned char *pkt)
+			       unsigned char *pkt, bool vlan)
 {
-	struct ether_hdr *ether = (struct ether_hdr *)pkt;
+	static uint8_t vlan_frame[] = {0x81, 0, 0, 0};
+	uint16_t *ether_type;
+	uint8_t len = 2 * sizeof(struct ether_addr);
+
+	pkt += 2 * sizeof(struct ether_addr);
+	if (vlan && fdir_input->flow_ext.vlan_tci) {
+		rte_memcpy(pkt, vlan_frame, sizeof(vlan_frame));
+		rte_memcpy(pkt + sizeof(uint16_t),
+			   &fdir_input->flow_ext.vlan_tci,
+			   sizeof(uint16_t));
+		pkt += sizeof(vlan_frame);
+		len += sizeof(vlan_frame);
+	}
+	ether_type = (uint16_t *)pkt;
+
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
+		*ether_type = fdir_input->flow.l2_flow.ether_type;
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		*ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		*ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
 			    fdir_input->flow_type);
-		break;
+		return -1;
 	}
+	len += sizeof(uint16_t);
+	return len;
 }
 
 static inline void
@@ -813,6 +829,8 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 	struct sctp_hdr *sctp;
 	uint8_t size, dst = 0;
 	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
+	int len;
+	static uint8_t vlan_frame[] = {0x81, 0, 0, 0};
 	static uint8_t gre4_frame[] = {0x08, 0,
 			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x08, 0,
@@ -832,6 +850,14 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			0, 0, 0, 0}; /*Mac + IP + NVGRE hdr*/
 
 	inner_pkt += 2 * sizeof(struct ether_addr);
+	if (fdir_input->flow_ext.vlan_tci) {
+		rte_memcpy(inner_pkt, vlan_frame, sizeof(vlan_frame));
+		rte_memcpy(inner_pkt + sizeof(uint16_t),
+			   &fdir_input->flow_ext.vlan_tci,
+			   sizeof(uint16_t));
+		inner_pkt += sizeof(vlan_frame);
+	}
+
 	/* fill the tunnel header if required */
 	switch (fdir_input->flow.tunnel_flow.tunnel_type) {
 	case RTE_FDIR_TUNNEL_TYPE_GRE:
@@ -861,7 +887,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			   &fdir_input->flow.tunnel_flow.tunnel_id,
 			   I40E_TUNNEL_KEY_LEN);
 		/* fill the ethernet and IP head of inner frame */
-		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt, FALSE);
 		inner_pkt += sizeof(struct ether_hdr);
 		break;
 	case RTE_FDIR_TUNNEL_TYPE_NVGRE:
@@ -871,13 +897,13 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			   &fdir_input->flow.tunnel_flow.tunnel_id,
 			   I40E_TUNNEL_KEY_LEN);
 		/* fill the Ether header of inner frame */
-		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt, FALSE);
 		inner_pkt += sizeof(struct ether_hdr);
 		break;
 	default:
 		/* fill the Ether header of single frame */
-		i40e_fdir_fill_ether_head(fdir_input, raw_pkt);
-		inner_pkt = raw_pkt + sizeof(struct ether_hdr);
+		len = i40e_fdir_fill_ether_head(fdir_input, raw_pkt, TRUE);
+		inner_pkt = raw_pkt + len;
 		break;
 	}
 
@@ -1122,6 +1148,7 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 		PMD_DRV_LOG(ERR, "construct packet for fdir fails.");
 		return ret;
 	}
+
 	pctype = i40e_flowtype_to_pctype(filter->input.flow_type);
 	ret = i40e_fdir_filter_programming(pf, pctype, filter, add);
 	if (ret < 0) {
-- 
2.4.0

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

* [PATCH v2 12/12] testpmd: extend commands for fdir's vlan input set
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
                       ` (10 preceding siblings ...)
  2016-03-02 11:30     ` [PATCH v2 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
@ 2016-03-02 11:30     ` Jingjing Wu
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-02 11:30 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended commands for filter's input set changing.
It added vlan as filter's input fields.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 6 +++---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 9cba2cc..6679a86 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -750,7 +750,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set_fdir_input_set (port_id) "
 			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|"
 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
 			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
 			"udp-dst-port|tcp-src-port|tcp-dst-port|"
@@ -9624,7 +9624,7 @@ cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ivlan#ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
 	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
 	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
@@ -9639,7 +9639,7 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.help_str = "set_fdir_input_set <port_id> "
 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
 	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
 	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
 	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 417ddde..aa20d5a 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1878,7 +1878,7 @@ Set the input set for flow director::
 
    set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
    ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
-   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
    tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
    sctp-dst-port|sctp-veri-tag|udp-key|gre-key|none) (select|add)
-- 
2.4.0

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

* [PATCH v3 00/12] extend flow director fields in i40e driver
  2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
                       ` (11 preceding siblings ...)
  2016-03-02 11:30     ` [PATCH v2 12/12] testpmd: extend commands for fdir's vlan input set Jingjing Wu
@ 2016-03-09  5:42     ` Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 01/12] ethdev: extend flow director for input selection Jingjing Wu
                         ` (13 more replies)
  12 siblings, 14 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

v3 changes:
 - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
 - use AQ rx control register read/write for some registers
 - remove few useless lines
 - patch title rewording

v2 changes:
 - rebase on dpdk-next-net/rel_16_04
 - comments rewording.
 - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to avoid ABI breaking.
 - remove ABI announce in Deprecation.
 - fix the ethertype setting when program filter in v1 patch set.

This patch set extends flow director to support filtering by additional fields below in i40e driver:
 - TOS, Protocol and TTL in IP header
 - Tunnel id if NVGRE/GRE/VxLAN packets
 - single vlan or inner vlan 


Andrey Chilikin (1):
  i40e: fix VLAN bitmasks for input set

Jingjing Wu (11):
  ethdev: extend flow director for input selection
  i40e: split function for hash and fdir input
  i40e: remove flex payload from input selection
  i40e: restore default setting on input set
  i40e: extend flow director to filter by IP Header
  testpmd: extend input set related commands
  librte_ether: extend flow director struct
  i40e: extend flow director to filter by tunnel ID
  testpmd: extend flow director commands
  i40e: extend flow director to filter by vlan id
  testpmd: extend flow director commands

 app/test-pmd/cmdline.c                      | 121 +++++++--
 doc/guides/rel_notes/deprecation.rst        |   4 -
 doc/guides/rel_notes/release_16_04.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 ++--
 drivers/net/i40e/i40e_ethdev.c              | 403 +++++++++++++++++-----------
 drivers/net/i40e/i40e_ethdev.h              |  11 +-
 drivers/net/i40e/i40e_fdir.c                | 206 ++++++++++----
 lib/librte_ether/rte_eth_ctrl.h             |  35 ++-
 8 files changed, 570 insertions(+), 271 deletions(-)

-- 
2.4.0

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

* [PATCH v3 01/12] ethdev: extend flow director for input selection
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
@ 2016-03-09  5:42       ` Jingjing Wu
  2016-03-09  9:52         ` Thomas Monjalon
  2016-03-09  9:54         ` Thomas Monjalon
  2016-03-09  5:42       ` [PATCH v3 02/12] i40e: split function for hash and fdir input Jingjing Wu
                         ` (12 subsequent siblings)
  13 siblings, 2 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
by tos, protocol and ttl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index ce224ad..8c51023 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -340,6 +340,8 @@ enum rte_eth_input_set_field {
 	RTE_ETH_INPUT_SET_L3_IP4_PROTO,
 	RTE_ETH_INPUT_SET_L3_IP6_TC,
 	RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
+	RTE_ETH_INPUT_SET_L3_IP4_TTL,
+	RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
 
 	/* L4 */
 	RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT = 257,
@@ -407,6 +409,9 @@ struct rte_eth_l2_flow {
 struct rte_eth_ipv4_flow {
 	uint32_t src_ip;      /**< IPv4 source address to match. */
 	uint32_t dst_ip;      /**< IPv4 destination address to match. */
+	uint8_t  tos;         /**< Type of service to match. */
+	uint8_t  ttl;         /**< Time to live */
+	uint8_t  proto;
 };
 
 /**
@@ -443,6 +448,9 @@ struct rte_eth_sctpv4_flow {
 struct rte_eth_ipv6_flow {
 	uint32_t src_ip[4];      /**< IPv6 source address to match. */
 	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
+	uint8_t  tc;             /**< Traffic class to match. */
+	uint8_t  proto;          /**< Protocol, next header. */
+	uint8_t  hop_limits;
 };
 
 /**
-- 
2.4.0

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

* [PATCH v3 02/12] i40e: split function for hash and fdir input
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 01/12] ethdev: extend flow director for input selection Jingjing Wu
@ 2016-03-09  5:42       ` Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 03/12] i40e: remove flex payload from input selection Jingjing Wu
                         ` (11 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch split function for input set changing of hash
and fdir to avoid multiple check on different situation.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 235 +++++++++++++++++------------------------
 drivers/net/i40e/i40e_ethdev.h |  11 +-
 drivers/net/i40e/i40e_fdir.c   |   5 +-
 3 files changed, 107 insertions(+), 144 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 0c87ec1..c8a62b8 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6906,25 +6906,6 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	return idx;
 }
 
-static uint64_t
-i40e_get_reg_inset(struct i40e_hw *hw, enum rte_filter_type filter,
-			    enum i40e_filter_pctype pctype)
-{
-	uint64_t reg = 0;
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
-	}
-
-	return reg;
-}
-
 static void
 i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 {
@@ -6937,105 +6918,96 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)i40e_read_rx_ctl(hw, addr));
 }
 
-static int
-i40e_set_hash_inset_mask(struct i40e_hw *hw,
-			 enum i40e_filter_pctype pctype,
-			 enum rte_filter_input_set_op op,
-			 uint32_t *mask_reg,
-			 uint8_t num)
+int
+i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			 struct rte_eth_input_set_conf *conf)
 {
-	uint32_t reg;
-	uint8_t i;
+	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	if (!conf) {
+		PMD_DRV_LOG(ERR, "Invalid pointer");
+		return -EFAULT;
+	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
 		return -EINVAL;
-
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = i40e_read_rx_ctl(hw,
-					       I40E_GLQF_HASH_MSK(i, pctype));
-			if (reg & I40E_GLQF_HASH_MSK_MASK_MASK)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
-
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[j]);
 	}
 
-	return 0;
-}
-
-static int
-i40e_set_fd_inset_mask(struct i40e_hw *hw,
-		       enum i40e_filter_pctype pctype,
-		       enum rte_filter_input_set_op op,
-		       uint32_t *mask_reg,
-		       uint8_t num)
-{
-	uint32_t reg;
-	uint8_t i;
+	pctype = i40e_flowtype_to_pctype(conf->flow_type);
+	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
+		PMD_DRV_LOG(ERR, "Not supported flow type (%u)",
+			    conf->flow_type);
+		return -EINVAL;
+	}
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
+				   conf->inset_size);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to parse input set");
+		return -EINVAL;
+	}
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
+				    input_set) != 0) {
+		PMD_DRV_LOG(ERR, "Invalid input set");
+		return -EINVAL;
+	}
+	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
+		/* get inset value in register */
+		inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
+		inset_reg <<= I40E_32_BIT_WIDTH;
+		inset_reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype));
+		input_set |= pf->hash_input_set[pctype];
+	}
+	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+					   I40E_INSET_MASK_NUM_REG);
+	if (num < 0)
 		return -EINVAL;
 
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = i40e_read_rx_ctl(hw,
-					       I40E_GLQF_FD_MSK(i, pctype));
-			if (reg & I40E_GLQF_FD_MSK_MASK_MASK)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[j]);
-	}
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     0);
+	I40E_WRITE_FLUSH(hw);
 
+	pf->hash_input_set[pctype] = input_set;
 	return 0;
 }
 
 int
-i40e_filter_inset_select(struct i40e_hw *hw,
-			 struct rte_eth_input_set_conf *conf,
-			 enum rte_filter_type filter)
+i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			 struct rte_eth_input_set_conf *conf)
 {
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	enum i40e_filter_pctype pctype;
-	uint64_t inset_reg = 0, input_set;
-	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG];
-	uint8_t num;
-	int ret;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
 	if (!hw || !conf) {
 		PMD_DRV_LOG(ERR, "Invalid pointer");
 		return -EFAULT;
 	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
+		return -EINVAL;
+	}
 
 	pctype = i40e_flowtype_to_pctype(conf->flow_type);
 	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
@@ -7043,60 +7015,48 @@ i40e_filter_inset_select(struct i40e_hw *hw,
 			    conf->flow_type);
 		return -EINVAL;
 	}
-	if (filter != RTE_ETH_FILTER_HASH && filter != RTE_ETH_FILTER_FDIR) {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
-
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, filter, input_set) != 0) {
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
+				    input_set) != 0) {
 		PMD_DRV_LOG(ERR, "Invalid input set");
 		return -EINVAL;
 	}
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
-		inset_reg |= i40e_get_reg_inset(hw, filter, pctype);
-	} else if (conf->op != RTE_ETH_INPUT_SET_SELECT) {
-		PMD_DRV_LOG(ERR, "Unsupported input set operation");
-		return -EINVAL;
-	}
+	/* get inset value in register */
+	inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
+	inset_reg <<= I40E_32_BIT_WIDTH;
+	inset_reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
+
+	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-	inset_reg |= i40e_translate_input_set_reg(input_set);
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		ret = i40e_set_hash_inset_mask(hw, pctype, conf->op, mask_reg,
-					       num);
-		if (ret)
-			return -EINVAL;
+	if (num < 0)
+		return -EINVAL;
 
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		ret = i40e_set_fd_inset_mask(hw, pctype, conf->op, mask_reg,
-					     num);
-		if (ret)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     0);
 	I40E_WRITE_FLUSH(hw);
 
+	pf->fdir.input_set[pctype] = input_set;
 	return 0;
 }
 
@@ -7148,9 +7108,8 @@ i40e_hash_filter_set(struct i40e_hw *hw, struct rte_eth_hash_filter_info *info)
 				&(info->info.global_conf));
 		break;
 	case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-					       &(info->info.input_set_conf),
-					       RTE_ETH_FILTER_HASH);
+		ret = i40e_hash_filter_inset_select(hw,
+					       &(info->info.input_set_conf));
 		break;
 
 	default:
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index a9b805e..d869124 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -364,6 +364,8 @@ struct i40e_fdir_info {
 	struct i40e_rx_queue *rxq;
 	void *prg_pkt;                 /* memory for fdir program packet */
 	uint64_t dma_addr;             /* physic address of packet memory*/
+	/* input set bits for each pctype */
+	uint64_t input_set[I40E_FILTER_PCTYPE_MAX];
 	/*
 	 * the rule how bytes stream is extracted as flexible payload
 	 * for each payload layer, the setting can up to three elements
@@ -430,6 +432,8 @@ struct i40e_pf {
 	uint16_t fdir_qp_offset;
 
 	uint16_t hash_lut_size; /* The size of hash lookup table */
+	/* input set bits for each pctype */
+	uint64_t hash_input_set[I40E_FILTER_PCTYPE_MAX];
 	/* store VXLAN UDP ports */
 	uint16_t vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];
 	uint16_t vxlan_bitmap; /* Vxlan bit mask */
@@ -573,9 +577,10 @@ int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 int i40e_select_filter_input_set(struct i40e_hw *hw,
 				 struct rte_eth_input_set_conf *conf,
 				 enum rte_filter_type filter);
-int i40e_filter_inset_select(struct i40e_hw *hw,
-			     struct rte_eth_input_set_conf *conf,
-			     enum rte_filter_type filter);
+int i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			     struct rte_eth_input_set_conf *conf);
+int i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			     struct rte_eth_input_set_conf *conf);
 
 void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct rte_eth_rxq_info *qinfo);
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 14c51ce..f8055e7 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -1362,7 +1362,6 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 		     struct rte_eth_fdir_filter_info *info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	int ret = 0;
 
 	if (!info) {
@@ -1372,8 +1371,8 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 
 	switch (info->info_type) {
 	case RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-			&(info->info.input_set_conf), RTE_ETH_FILTER_FDIR);
+		ret = i40e_fdir_filter_inset_select(pf,
+				&(info->info.input_set_conf));
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "FD filter info type (%d) not supported",
-- 
2.4.0

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

* [PATCH v3 03/12] i40e: remove flex payload from input selection
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 01/12] ethdev: extend flow director for input selection Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 02/12] i40e: split function for hash and fdir input Jingjing Wu
@ 2016-03-09  5:42       ` Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 04/12] i40e: restore default setting on input set Jingjing Wu
                         ` (10 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

In this patch, flex payload is removed from valid fdir input set
values. It is because all flex payload configuration can be set
in struct rte_fdir_conf during device configure phase.
And it is a more flexible configuration including flexpayload's
selection, input set selection by word and mask setting in bits.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 59 +++++++++++++++++++-----------------------
 1 file changed, 26 insertions(+), 33 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index c8a62b8..fe340a5 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -255,7 +255,8 @@
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD7        0x0000000000000080ULL
 /* 8th word of flex payload */
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD8        0x0000000000000040ULL
-
+/* all 8 words flex payload */
+#define I40E_REG_INSET_FLEX_PAYLOAD_WORDS        0x0000000000003FC0ULL
 #define I40E_REG_INSET_MASK_DEFAULT              0x0000000000000000ULL
 
 #define I40E_TRANSLATE_INSET 0
@@ -6606,43 +6607,32 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
-		I40E_INSET_LAST_ETHER_TYPE | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
 	if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD)
@@ -6870,7 +6860,7 @@ i40e_translate_input_set_reg(uint64_t input)
 	return val;
 }
 
-static uint8_t
+static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
@@ -6888,16 +6878,13 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-	if (!inset && nb_elem >= I40E_INSET_MASK_NUM_REG) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++)
-			mask[i] = 0;
-		return I40E_INSET_MASK_NUM_REG;
-	}
 
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if (idx >= nb_elem)
-			break;
-		if (inset & inset_mask_map[i].inset) {
+		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+			if (idx >= nb_elem) {
+				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
+				return -EINVAL;
+			}
 			mask[idx] = inset_mask_map[i].mask;
 			idx++;
 		}
@@ -7032,7 +7019,13 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 	inset_reg <<= I40E_32_BIT_WIDTH;
 	inset_reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+	/* Can not change the inset reg for flex payload for fdir,
+	 * it is done by writing I40E_PRTQF_FD_FLXINSET
+	 * in i40e_set_flex_mask_on_pctype.
+	 */
+	if (conf->op == RTE_ETH_INPUT_SET_SELECT)
+		inset_reg &= I40E_REG_INSET_FLEX_PAYLOAD_WORDS;
+	else
 		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-- 
2.4.0

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

* [PATCH v3 04/12] i40e: restore default setting on input set
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
                         ` (2 preceding siblings ...)
  2016-03-09  5:42       ` [PATCH v3 03/12] i40e: remove flex payload from input selection Jingjing Wu
@ 2016-03-09  5:42       ` Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 05/12] i40e: extend flow director to filter by IP Header Jingjing Wu
                         ` (9 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch added a new function to set the input set to default
when initialization.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 56 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index fe340a5..1c672c1 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -367,6 +367,7 @@ static int i40e_dev_udp_tunnel_add(struct rte_eth_dev *dev,
 				struct rte_eth_udp_tunnel *udp_tunnel);
 static int i40e_dev_udp_tunnel_del(struct rte_eth_dev *dev,
 				struct rte_eth_udp_tunnel *udp_tunnel);
+static void i40e_filter_input_set_init(struct i40e_pf *pf);
 static int i40e_ethertype_filter_set(struct i40e_pf *pf,
 			struct rte_eth_ethertype_filter *filter,
 			bool add);
@@ -781,6 +782,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	 * It should be removed once issues are fixed in NVM.
 	 */
 	i40e_flex_payload_reg_init(hw);
+	/* Initialize the input set for filters (hash and fd) to default value */
+	i40e_filter_input_set_init(pf);
 
 	/* Initialize the parameters for adminq */
 	i40e_init_adminq_parameter(hw);
@@ -6905,6 +6908,59 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)i40e_read_rx_ctl(hw, addr));
 }
 
+static void
+i40e_filter_input_set_init(struct i40e_pf *pf)
+{
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int num, i;
+
+	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
+		if (!I40E_VALID_PCTYPE(pctype))
+			continue;
+		input_set = i40e_get_default_input_set(pctype);
+
+		num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+						   I40E_INSET_MASK_NUM_REG);
+		if (num < 0)
+			return;
+		inset_reg = i40e_translate_input_set_reg(input_set);
+
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+		for (i = 0; i < num; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     mask_reg[i]);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     mask_reg[i]);
+		}
+		/*clear unused mask registers of the pctype */
+		for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     0);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     0);
+		}
+		I40E_WRITE_FLUSH(hw);
+
+		/* store the default input set */
+		pf->hash_input_set[pctype] = input_set;
+		pf->fdir.input_set[pctype] = input_set;
+	}
+}
+
 int
 i40e_hash_filter_inset_select(struct i40e_hw *hw,
 			 struct rte_eth_input_set_conf *conf)
-- 
2.4.0

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

* [PATCH v3 05/12] i40e: extend flow director to filter by IP Header
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
                         ` (3 preceding siblings ...)
  2016-03-09  5:42       ` [PATCH v3 04/12] i40e: restore default setting on input set Jingjing Wu
@ 2016-03-09  5:42       ` Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 06/12] testpmd: extend input set related commands Jingjing Wu
                         ` (8 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended flow director to select more IP Header fields
as filter input set.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 69 ++++++++++++++++++++++++++++++++++--------
 drivers/net/i40e/i40e_fdir.c   | 26 +++++++++++-----
 2 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 1c672c1..e24b026 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -211,6 +211,8 @@
 #define I40E_REG_INSET_L3_IP4_TOS                0x0040000000000000ULL
 /* IPv4 Protocol */
 #define I40E_REG_INSET_L3_IP4_PROTO              0x0004000000000000ULL
+/* IPv4 Time to Live */
+#define I40E_REG_INSET_L3_IP4_TTL                0x0004000000000000ULL
 /* Source IPv6 address */
 #define I40E_REG_INSET_L3_SRC_IP6                0x0007F80000000000ULL
 /* Destination IPv6 address */
@@ -219,6 +221,8 @@
 #define I40E_REG_INSET_L3_IP6_TC                 0x0040000000000000ULL
 /* IPv6 Next Header */
 #define I40E_REG_INSET_L3_IP6_NEXT_HDR           0x0008000000000000ULL
+/* IPv6 Hop Limitr */
+#define I40E_REG_INSET_L3_IP6_HOP_LIMIT          0x0008000000000000ULL
 /* Source L4 port */
 #define I40E_REG_INSET_L4_SRC_PORT               0x0000000400000000ULL
 /* Destination L4 port */
@@ -262,10 +266,12 @@
 #define I40E_TRANSLATE_INSET 0
 #define I40E_TRANSLATE_REG   1
 
-#define I40E_INSET_IPV4_TOS_MASK      0x0009FF00UL
-#define I40E_INSET_IPV4_PROTO_MASK    0x000DFF00UL
-#define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
-#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
+#define I40E_INSET_IPV4_TOS_MASK        0x0009FF00UL
+#define I40E_INSET_IPv4_TTL_MASK        0x000D00FFUL
+#define I40E_INSET_IPV4_PROTO_MASK      0x000DFF00UL
+#define I40E_INSET_IPV6_TC_MASK         0x0009F00FUL
+#define I40E_INSET_IPV6_HOP_LIMIT_MASK  0x000CFF00UL
+#define I40E_INSET_IPV6_NEXT_HDR_MASK   0x000C00FFUL
 
 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
@@ -6610,30 +6616,47 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
@@ -6733,11 +6756,14 @@ i40e_parse_input_set(uint64_t *inset,
 		{RTE_ETH_INPUT_SET_L3_DST_IP4, I40E_INSET_IPV4_DST},
 		{RTE_ETH_INPUT_SET_L3_IP4_TOS, I40E_INSET_IPV4_TOS},
 		{RTE_ETH_INPUT_SET_L3_IP4_PROTO, I40E_INSET_IPV4_PROTO},
+		{RTE_ETH_INPUT_SET_L3_IP4_TTL, I40E_INSET_IPV4_TTL},
 		{RTE_ETH_INPUT_SET_L3_SRC_IP6, I40E_INSET_IPV6_SRC},
 		{RTE_ETH_INPUT_SET_L3_DST_IP6, I40E_INSET_IPV6_DST},
 		{RTE_ETH_INPUT_SET_L3_IP6_TC, I40E_INSET_IPV6_TC},
 		{RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
 			I40E_INSET_IPV6_NEXT_HDR},
+		{RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
+			I40E_INSET_IPV6_HOP_LIMIT},
 		{RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT, I40E_INSET_SRC_PORT},
@@ -6824,10 +6850,12 @@ i40e_translate_input_set_reg(uint64_t input)
 		{I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4},
 		{I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS},
 		{I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO},
+		{I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL},
 		{I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6},
 		{I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6},
 		{I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_REG_INSET_L3_IP6_NEXT_HDR},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_REG_INSET_L3_IP6_HOP_LIMIT},
 		{I40E_INSET_SRC_PORT, I40E_REG_INSET_L4_SRC_PORT},
 		{I40E_INSET_DST_PORT, I40E_REG_INSET_L4_DST_PORT},
 		{I40E_INSET_SCTP_VT, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG},
@@ -6867,23 +6895,38 @@ static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
+	uint64_t inset_need_mask = inset;
 
 	static const struct {
 		uint64_t inset;
 		uint32_t mask;
 	} inset_mask_map[] = {
 		{I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK},
+		{I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0},
 		{I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK},
+		{I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK},
 		{I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK},
+		{I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK}
 	};
 
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+		/* Clear the inset bit, if no MASK is required,
+		 * for example proto + ttl
+		 */
+		if ((inset & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset && inset_mask_map[i].mask == 0)
+			inset_need_mask &= ~inset_mask_map[i].inset;
+		if (!inset_need_mask)
+			return 0;
+	}
+	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
+		if ((inset_need_mask & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset) {
 			if (idx >= nb_elem) {
 				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
 				return -EINVAL;
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index f8055e7..ebbe612 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -66,7 +66,9 @@
 #define I40E_FDIR_IP_DEFAULT_TTL            0x40
 #define I40E_FDIR_IP_DEFAULT_VERSION_IHL    0x45
 #define I40E_FDIR_TCP_DEFAULT_DATAOFF       0x50
-#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60300000
+#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60000000
+#define I40E_FDIR_IPv6_TC_OFFSET            20
+
 #define I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS   0xFF
 #define I40E_FDIR_IPv6_PAYLOAD_LEN          380
 #define I40E_FDIR_UDP_DEFAULT_LEN           400
@@ -720,7 +722,13 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
-		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+		ip->next_proto_id = fdir_input->flow.ip4_flow.proto ?
+					fdir_input->flow.ip4_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip->time_to_live = fdir_input->flow.ip4_flow.ttl ?
+					fdir_input->flow.ip4_flow.ttl :
+					I40E_FDIR_IP_DEFAULT_TTL;
+		ip->type_of_service = fdir_input->flow.ip4_flow.tos;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -728,7 +736,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		 */
 		ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
 		ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
-		ip->next_proto_id = next_proto[fdir_input->flow_type];
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
@@ -739,11 +746,17 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 
 		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
-			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
+					 (fdir_input->flow.ipv6_flow.tc <<
+					  I40E_FDIR_IPv6_TC_OFFSET));
 		ip6->payload_len =
 			rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
-		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
-
+		ip6->proto = fdir_input->flow.ipv6_flow.proto ?
+					fdir_input->flow.ipv6_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ?
+					fdir_input->flow.ipv6_flow.hop_limits :
+					I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -755,7 +768,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		rte_memcpy(&(ip6->dst_addr),
 			   &(fdir_input->flow.ipv6_flow.src_ip),
 			   IPV6_ADDR_LEN);
-		ip6->proto = next_proto[fdir_input->flow_type];
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
-- 
2.4.0

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

* [PATCH v3 06/12] testpmd: extend input set related commands
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
                         ` (4 preceding siblings ...)
  2016-03-09  5:42       ` [PATCH v3 05/12] i40e: extend flow director to filter by IP Header Jingjing Wu
@ 2016-03-09  5:42       ` Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 07/12] librte_ether: extend flow director struct Jingjing Wu
                         ` (7 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended commands for filter's input set changing.
It added tos, protocol and ttl as filter's input fields, and
remove the words selection from flex payloads for flow director.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 100 ++++++++++++++++++++++------
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  42 +++++++-----
 2 files changed, 104 insertions(+), 38 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..5787f57 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -642,6 +642,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"flow_director_filter (port_id) mode IP (add|del|update)"
 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
+			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -651,6 +652,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
+			" tos (tos_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -660,7 +662,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-sctp|ipv6-sctp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
-			" tag (verification_tag) vlan (vlan_value)"
+			" tag (verification_tag) "
+			" tos (tos_value) ttl (ttl_value)"
+			" vlan (vlan_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -740,14 +744,15 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"fld-8th|none) (select|add)\n"
 			"    Set the input set for hash.\n\n"
 
-			"set_fdir_input_set (port_id) (ipv4|ipv4-frag|"
-			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+			"set_fdir_input_set (port_id) "
+			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
-			"udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|"
-			"sctp-src-port|sctp-dst-port|sctp-veri-tag|fld-1st|"
-			"fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
-			"fld-8th|none) (select|add)\n"
+			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
+			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
+			"udp-dst-port|tcp-src-port|tcp-dst-port|"
+			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
+			" (select|add)\n"
 			"    Set the input set for FDir.\n\n"
 		);
 	}
@@ -7985,6 +7990,12 @@ struct cmd_flow_director_result {
 	uint16_t port_dst;
 	cmdline_fixed_string_t verify_tag;
 	uint32_t verify_tag_value;
+	cmdline_ipaddr_t tos;
+	uint8_t tos_value;
+	cmdline_ipaddr_t proto;
+	uint8_t proto_value;
+	cmdline_ipaddr_t ttl;
+	uint8_t ttl_value;
 	cmdline_fixed_string_t vlan;
 	uint16_t vlan_value;
 	cmdline_fixed_string_t flexbytes;
@@ -8164,12 +8175,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 	switch (entry.input.flow_type) {
 	case RTE_ETH_FLOW_FRAG_IPV4:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+		entry.input.flow.ip4_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 		IPV4_ADDR_TO_UINT(res->ip_dst,
 			entry.input.flow.ip4_flow.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.ip4_flow.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8181,6 +8195,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp4_flow.ip.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.sctp4_flow.ip.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8191,12 +8207,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 		break;
 	case RTE_ETH_FLOW_FRAG_IPV6:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+		entry.input.flow.ipv6_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 		IPV6_ADDR_TO_ARRAY(res->ip_dst,
 			entry.input.flow.ipv6_flow.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.ipv6_flow.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8208,6 +8227,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp6_flow.ip.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.sctp6_flow.ip.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8335,6 +8356,24 @@ cmdline_parse_token_string_t cmd_flow_director_verify_tag =
 cmdline_parse_token_num_t cmd_flow_director_verify_tag_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
 			      verify_tag_value, UINT32);
+cmdline_parse_token_string_t cmd_flow_director_tos =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 tos, "tos");
+cmdline_parse_token_num_t cmd_flow_director_tos_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      tos_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_proto =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 proto, "proto");
+cmdline_parse_token_num_t cmd_flow_director_proto_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      proto_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_ttl =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 ttl, "ttl");
+cmdline_parse_token_num_t cmd_flow_director_ttl_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      ttl_value, UINT8);
 cmdline_parse_token_string_t cmd_flow_director_vlan =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 vlan, "vlan");
@@ -8413,6 +8452,12 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ip_src,
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_proto,
+		(void *)&cmd_flow_director_proto_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8445,6 +8490,10 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
 		(void *)&cmd_flow_director_port_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8479,6 +8528,10 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_port_dst,
 		(void *)&cmd_flow_director_verify_tag,
 		(void *)&cmd_flow_director_verify_tag_value,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -9405,16 +9458,19 @@ str2inset(char *string)
 		char str[32];
 		enum rte_eth_input_set_field inset;
 	} inset_table[] = {
+		{"ethertype", RTE_ETH_INPUT_SET_L2_ETHERTYPE},
 		{"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
 		{"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
 		{"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
 		{"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
 		{"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
 		{"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
+		{"ipv4-ttl", RTE_ETH_INPUT_SET_L3_IP4_TTL},
 		{"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
 		{"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
 		{"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
 		{"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
+		{"ipv6-hop-limits", RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS},
 		{"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
 		{"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
 		{"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
@@ -9473,7 +9529,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
 		flow_type,
-		"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
@@ -9492,8 +9548,8 @@ cmdline_parse_inst_t cmd_set_hash_input_set = {
 	.f = cmd_set_hash_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_hash_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
@@ -9548,15 +9604,16 @@ cmdline_parse_token_num_t cmd_set_fdir_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	flow_type,
-	"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+	"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 	"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#udp-src-port#udp-dst-port#"
+	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
+	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
-	"sctp-veri-tag#fld-1st#fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#"
-	"fld-7th#fld-8th#none");
+	"sctp-veri-tag#none");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	select, "select#add");
@@ -9565,12 +9622,13 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.f = cmd_set_fdir_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_fdir_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port|"
-	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|"
-	"fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
-	"fld-7th|fld-8th|none select|add",
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
+	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
+	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
+	"sctp-veri-tag|none select|add",
 	.tokens = {
 		(void *)&cmd_set_fdir_input_set_cmd,
 		(void *)&cmd_set_fdir_input_set_port_id,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index a520cc5..f59e63e 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1678,8 +1678,9 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 # Commands to add flow director filters of different flow types::
 
    flow_director_filter (port_id) mode IP (add|del|update) \
-                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)
+                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag) \
                         src (src_ip_address) dst (dst_ip_address) \
+                        tos (tos_value) proto (proto_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) pf|vf(vf_id) queue (queue_id) \
                         fd_id (fd_id_value)
@@ -1688,6 +1689,7 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp) \
                         src (src_ip_address) (src_port) \
                         dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) queue pf|vf(vf_id) (queue_id) \
                         fd_id (fd_id_value)
@@ -1695,7 +1697,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
    flow_director_filter (port_id) mode IP (add|del|update) \
                         flow (ipv4-sctp|ipv6-sctp) \
                         src (src_ip_address) (src_port) \
-                        dst (dst_ip_address) (dst_port)
+                        dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         tag (verification_tag) vlan (vlan_value) \
                         flexbytes (flexbytes_value) (drop|fwd) \
                         pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)
@@ -1719,12 +1722,14 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 For example, to add an ipv4-udp flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-udp src 2.2.2.3 32 \
-            dst 2.2.2.5 33 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+            dst 2.2.2.5 33 tos 2 ttl 40 vlan 0x1 flexbytes (0x88,0x48) \
+            fwd pf queue 1 fd_id 1
 
 For example, add an ipv4-other flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
-             dst 2.2.2.5 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+             dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 \
+             flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
 flush_flow_director
 ~~~~~~~~~~~~~~~~~~~
@@ -1841,33 +1846,36 @@ set_hash_input_set
 
 Set the input set for hash::
 
-   set_hash_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   set_hash_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
    l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port| \
    tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
    udp-key|gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th| \
    fld-8th|none) (select|add)
 
-For example, to add source IP to hash input set for flow type of ipv4 on port 0::
+For example, to add source IP to hash input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_hash_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_hash_input_set 0 ipv4-udp src-ipv4 add
 
 set_fdir_input_set
 ~~~~~~~~~~~~~~~~~~
 
-Set the input set for Fdir::
+The Flow Director filters can match the different fields for different type of packet, i.e. specific input set
+on per flow type and the flexible payload. This command can be used to change input set for each flow type.
 
-   set_fdir_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)
-   (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port| \
-   tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
-   fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|fld-8th|none) \
-   (select|add)
+Set the input set for flow director::
+
+   set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
+   tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
+   sctp-dst-port|sctp-veri-tag|none) (select|add)
 
-For example to add source IP to FD input set for flow type of ipv4 on port 0::
+For example to add source IP to FD input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_fdir_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_fdir_input_set 0 ipv4-udp src-ipv4 add
 
 global_config
 ~~~~~~~~~~~~~
-- 
2.4.0

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

* [PATCH v3 07/12] librte_ether: extend flow director struct
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
                         ` (5 preceding siblings ...)
  2016-03-09  5:42       ` [PATCH v3 06/12] testpmd: extend input set related commands Jingjing Wu
@ 2016-03-09  5:42       ` Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
                         ` (6 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch changed rte_eth_fdir_flow from union to struct to
support more packets formats, for example, Vxlan and GRE tunnel
packets with IP inner frame.

This patch also add new RTE_FDIR_TUNNEL_TYPE_GRE enum.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/rel_notes/deprecation.rst   |  4 ----
 doc/guides/rel_notes/release_16_04.rst |  3 +++
 lib/librte_ether/rte_eth_ctrl.h        | 27 +++++++++++++++------------
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..7fa8639 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -20,10 +20,6 @@ Deprecation Notices
   tables (512 queues).
   It should be integrated in release 2.3.
 
-* ABI changes are planned for struct rte_eth_fdir_flow in order to support
-  extend flow director's input set. The release 2.2 does not contain these ABI
-  changes, but release 2.3 will, and no backwards compatibility is planned.
-
 * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow to
   include more fields to be matched against. The release 2.2 does not
   contain these ABI changes, but release 2.3 will.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index eab5f92..26af339 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -224,6 +224,9 @@ ABI Changes
   the previous releases and made in this release. Use fixed width quotes for
   ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
+* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
+  changed. New fields were added to extend flow director's input set, and
+  organizing is also changed to support multiple input format.
 
 Shared Library Versions
 -----------------------
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 8c51023..b6a5c50 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -495,6 +495,7 @@ enum rte_eth_fdir_tunnel_type {
 	RTE_FDIR_TUNNEL_TYPE_UNKNOWN = 0,
 	RTE_FDIR_TUNNEL_TYPE_NVGRE,
 	RTE_FDIR_TUNNEL_TYPE_VXLAN,
+	RTE_FDIR_TUNNEL_TYPE_GRE,
 };
 
 /**
@@ -508,18 +509,20 @@ struct rte_eth_tunnel_flow {
 };
 
 /**
- * An union contains the inputs for all types of flow
+ * A struct contains the inputs for all types of flow
  */
-union rte_eth_fdir_flow {
-	struct rte_eth_l2_flow     l2_flow;
-	struct rte_eth_udpv4_flow  udp4_flow;
-	struct rte_eth_tcpv4_flow  tcp4_flow;
-	struct rte_eth_sctpv4_flow sctp4_flow;
-	struct rte_eth_ipv4_flow   ip4_flow;
-	struct rte_eth_udpv6_flow  udp6_flow;
-	struct rte_eth_tcpv6_flow  tcp6_flow;
-	struct rte_eth_sctpv6_flow sctp6_flow;
-	struct rte_eth_ipv6_flow   ipv6_flow;
+struct rte_eth_fdir_flow {
+	union {
+		struct rte_eth_l2_flow     l2_flow;
+		struct rte_eth_udpv4_flow  udp4_flow;
+		struct rte_eth_tcpv4_flow  tcp4_flow;
+		struct rte_eth_sctpv4_flow sctp4_flow;
+		struct rte_eth_ipv4_flow   ip4_flow;
+		struct rte_eth_udpv6_flow  udp6_flow;
+		struct rte_eth_tcpv6_flow  tcp6_flow;
+		struct rte_eth_sctpv6_flow sctp6_flow;
+		struct rte_eth_ipv6_flow   ipv6_flow;
+	};
 	struct rte_eth_mac_vlan_flow mac_vlan_flow;
 	struct rte_eth_tunnel_flow   tunnel_flow;
 };
@@ -540,7 +543,7 @@ struct rte_eth_fdir_flow_ext {
  */
 struct rte_eth_fdir_input {
 	uint16_t flow_type;
-	union rte_eth_fdir_flow flow;
+	struct rte_eth_fdir_flow flow;
 	/**< Flow fields to match, dependent on flow_type */
 	struct rte_eth_fdir_flow_ext flow_ext;
 	/**< Additional fields to match */
-- 
2.4.0

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

* [PATCH v3 08/12] i40e: extend flow director to filter by tunnel ID
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
                         ` (6 preceding siblings ...)
  2016-03-09  5:42       ` [PATCH v3 07/12] librte_ether: extend flow director struct Jingjing Wu
@ 2016-03-09  5:42       ` Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 09/12] testpmd: extend flow director commands Jingjing Wu
                         ` (5 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended flow director to select Vxlan/GRE tunnel ID
as filter's input set and program the filter rule with the defined
tunnel type.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c |  11 +++
 drivers/net/i40e/i40e_fdir.c   | 150 +++++++++++++++++++++++++++++++----------
 2 files changed, 125 insertions(+), 36 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index e24b026..70a1c6c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6616,48 +6616,59 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index ebbe612..e4ac79d 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -688,12 +688,41 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 }
 
 static inline void
-i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
-			       unsigned char *raw_pkt)
+i40e_fdir_fill_ether_head(const struct rte_eth_fdir_input *fdir_input,
+			       unsigned char *pkt)
 {
-	struct ether_hdr *ether = (struct ether_hdr *)raw_pkt;
-	struct ipv4_hdr *ip;
-	struct ipv6_hdr *ip6;
+	struct ether_hdr *ether = (struct ether_hdr *)pkt;
+	switch (fdir_input->flow_type) {
+	case RTE_ETH_FLOW_L2_PAYLOAD:
+		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
+		break;
+	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
+	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
+	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
+	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+	case RTE_ETH_FLOW_FRAG_IPV4:
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		break;
+	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
+	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
+	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
+	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+	case RTE_ETH_FLOW_FRAG_IPV6:
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unknown flow type %u.",
+			    fdir_input->flow_type);
+		break;
+	}
+}
+
+static inline void
+i40e_fdir_fill_ip_head(const struct rte_eth_fdir_input *fdir_input,
+			       unsigned char *pkt)
+{
+	struct ipv4_hdr *ip = (struct ipv4_hdr *)pkt;
+	struct ipv6_hdr *ip6 = (struct ipv6_hdr *)pkt;
 	static const uint8_t next_proto[] = {
 		[RTE_ETH_FLOW_FRAG_IPV4] = IPPROTO_IP,
 		[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] = IPPROTO_TCP,
@@ -708,17 +737,11 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 	};
 
 	switch (fdir_input->flow_type) {
-	case RTE_ETH_FLOW_L2_PAYLOAD:
-		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
-		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		ip = (struct ipv4_hdr *)(raw_pkt + sizeof(struct ether_hdr));
-
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
@@ -742,9 +765,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		ip6 = (struct ipv6_hdr *)(raw_pkt + sizeof(struct ether_hdr));
-
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
 			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
 					 (fdir_input->flow.ipv6_flow.tc <<
@@ -776,7 +796,7 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 	}
 }
 
-
+#define I40E_TUNNEL_KEY_LEN 4
 /*
  * i40e_fdir_construct_pkt - construct packet based on fields in input
  * @pf: board private structure
@@ -788,21 +808,86 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			     const struct rte_eth_fdir_input *fdir_input,
 			     unsigned char *raw_pkt)
 {
-	unsigned char *payload, *ptr;
+	unsigned char *payload, *ptr, *inner_pkt = raw_pkt;
 	struct udp_hdr *udp;
 	struct tcp_hdr *tcp;
 	struct sctp_hdr *sctp;
 	uint8_t size, dst = 0;
 	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
+	static uint8_t gre4_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x08, 0,
+			0, 0, 0, 0}; /* Mac+ IP + GRE hdr + key */
+	static uint8_t gre6_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x86, 0xDD,
+			0, 0, 0, 0}; /* Mac+ IP + GRE hdr + key */
+	static uint8_t vxlan_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x11,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			0x12, 0xB5, 0x12, 0xB5, 0x08, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0}; /* Mac + IP + UDP + VXLAN hdr */
+	static uint8_t nvgre_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x65, 0x58,
+			0, 0, 0, 0}; /*Mac + IP + NVGRE hdr*/
+
+	inner_pkt += 2 * sizeof(struct ether_addr);
+	/* fill the tunnel header if required */
+	switch (fdir_input->flow.tunnel_flow.tunnel_type) {
+	case RTE_FDIR_TUNNEL_TYPE_GRE:
+		if (fdir_input->flow_type == RTE_ETH_FLOW_L2_PAYLOAD) {
+			PMD_DRV_LOG(ERR, "GRE's inner pkt shouldn't"
+				    " be L2 frame.");
+			return -EINVAL;
+		}
+		if ((fdir_input->flow_type) == RTE_ETH_FLOW_FRAG_IPV4 ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_TCP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_UDP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_SCTP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_OTHER)
+			rte_memcpy(inner_pkt, gre4_frame, sizeof(gre4_frame));
+		else
+			rte_memcpy(inner_pkt, gre6_frame, sizeof(gre6_frame));
+		/* gre4_frame and gre6_frame have the same size */
+		inner_pkt += sizeof(gre4_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		break;
+	case RTE_FDIR_TUNNEL_TYPE_VXLAN:
+		rte_memcpy(inner_pkt, vxlan_frame, sizeof(vxlan_frame));
+		inner_pkt += sizeof(vxlan_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		/* fill the ethernet and IP head of inner frame */
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		inner_pkt += sizeof(struct ether_hdr);
+		break;
+	case RTE_FDIR_TUNNEL_TYPE_NVGRE:
+		rte_memcpy(inner_pkt, nvgre_frame, sizeof(nvgre_frame));
+		inner_pkt += sizeof(nvgre_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		/* fill the Ether header of inner frame */
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		inner_pkt += sizeof(struct ether_hdr);
+		break;
+	default:
+		/* fill the Ether header of single frame */
+		i40e_fdir_fill_ether_head(fdir_input, raw_pkt);
+		inner_pkt = raw_pkt + sizeof(struct ether_hdr);
+		break;
+	}
 
-	/* fill the ethernet and IP head */
-	i40e_fdir_fill_eth_ip_head(fdir_input, raw_pkt);
-
+	/* fill the IP header of inner or single frame */
+	i40e_fdir_fill_ip_head(fdir_input, inner_pkt);
 	/* fill the L4 head */
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-				sizeof(struct ipv4_hdr));
+		udp = (struct udp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -815,8 +900,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv4_hdr));
+		tcp = (struct tcp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -829,8 +913,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv4_hdr));
+		sctp = (struct sctp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -844,14 +927,12 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv4_hdr);
+		payload = inner_pkt + sizeof(struct ipv4_hdr);
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		udp = (struct udp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -864,8 +945,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		tcp = (struct tcp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -878,8 +958,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv6_hdr));
+		sctp = (struct sctp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -893,12 +972,11 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv6_hdr);
+		payload = inner_pkt + sizeof(struct ipv6_hdr);
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		payload = raw_pkt + sizeof(struct ether_hdr);
+		payload = inner_pkt;
 		/*
 		 * ARP packet is a special case on which the payload
 		 * starts after the whole ARP header
-- 
2.4.0

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

* [PATCH v3 09/12] testpmd: extend flow director commands
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
                         ` (7 preceding siblings ...)
  2016-03-09  5:42       ` [PATCH v3 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
@ 2016-03-09  5:42       ` Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 10/12] i40e: fix VLAN bitmasks for input set Jingjing Wu
                         ` (4 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended commands for filter's input set changing.
It added GRE/Vxlan Tunnel as filter's input fields.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 27 +++++++++++++++++++++------
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 22 ++++++++++++++++------
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 5787f57..9cba2cc 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -643,7 +643,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
 			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
-			" vlan (vlan_value) flexbytes (flexbytes_value)"
+			" vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel)"
+			" (tunnel_id_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
 			"    Add/Del an IP type flow director filter.\n\n"
@@ -653,7 +654,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
 			" tos (tos_value) ttl (ttl_value)"
-			" vlan (vlan_value) flexbytes (flexbytes_value)"
+			" vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel)"
+			" (tunnel_id_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
 			"    Add/Del an UDP/TCP type flow director filter.\n\n"
@@ -665,6 +667,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" tag (verification_tag) "
 			" tos (tos_value) ttl (ttl_value)"
 			" vlan (vlan_value)"
+			" (NVGRE|VxLAN|GRE|Notunnel) (tunnel_id_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -751,7 +754,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
 			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
 			"udp-dst-port|tcp-src-port|tcp-dst-port|"
-			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
+			"sctp-src-port|sctp-dst-port|sctp-veri-tag|"
+			"udp-key|gre-key|none)"
 			" (select|add)\n"
 			"    Set the input set for FDir.\n\n"
 		);
@@ -8094,6 +8098,7 @@ str2fdir_tunneltype(char *string)
 	} tunneltype_str[] = {
 		{"NVGRE", RTE_FDIR_TUNNEL_TYPE_NVGRE},
 		{"VxLAN", RTE_FDIR_TUNNEL_TYPE_VXLAN},
+		{"GRE",   RTE_FDIR_TUNNEL_TYPE_GRE},
 	};
 
 	for (i = 0; i < RTE_DIM(tunneltype_str); i++) {
@@ -8265,6 +8270,10 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 		   RTE_ETH_FDIR_MAX_FLEXLEN);
 
 	entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value);
+	entry.input.flow.tunnel_flow.tunnel_type =
+		str2fdir_tunneltype(res->tunnel_type);
+	entry.input.flow.tunnel_flow.tunnel_id =
+			rte_cpu_to_be_32(res->tunnel_id_value);
 
 	entry.action.flex_off = 0;  /*use 0 by default */
 	if (!strcmp(res->drop, "drop"))
@@ -8428,7 +8437,7 @@ cmdline_parse_token_string_t cmd_flow_director_tunnel =
 				 tunnel, "tunnel");
 cmdline_parse_token_string_t cmd_flow_director_tunnel_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
-				 tunnel_type, "NVGRE#VxLAN");
+				 tunnel_type, "NVGRE#VxLAN#GRE#Notunnel");
 cmdline_parse_token_string_t cmd_flow_director_tunnel_id =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 tunnel_id, "tunnel-id");
@@ -8460,6 +8469,8 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -8496,6 +8507,8 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -8534,6 +8547,8 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -9613,7 +9628,7 @@ cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
 	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
-	"sctp-veri-tag#none");
+	"sctp-veri-tag#udp-key#gre-key#none");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	select, "select#add");
@@ -9628,7 +9643,7 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
 	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
 	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
-	"sctp-veri-tag|none select|add",
+	"sctp-veri-tag|udp-key|gre-key|none select|add",
 	.tokens = {
 		(void *)&cmd_set_fdir_input_set_cmd,
 		(void *)&cmd_set_fdir_input_set_port_id,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f59e63e..417ddde 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1681,7 +1681,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag) \
                         src (src_ip_address) dst (dst_ip_address) \
                         tos (tos_value) proto (proto_value) ttl (ttl_value) \
-                        vlan (vlan_value) flexbytes (flexbytes_value) \
+                        vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel) \
+                        (tunnel_id_value) flexbytes (flexbytes_value) \
                         (drop|fwd) pf|vf(vf_id) queue (queue_id) \
                         fd_id (fd_id_value)
 
@@ -1690,7 +1691,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         src (src_ip_address) (src_port) \
                         dst (dst_ip_address) (dst_port) \
                         tos (tos_value) ttl (ttl_value) \
-                        vlan (vlan_value) flexbytes (flexbytes_value) \
+                        vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel) \
+                        (tunnel_id_value) flexbytes (flexbytes_value) \
                         (drop|fwd) queue pf|vf(vf_id) (queue_id) \
                         fd_id (fd_id_value)
 
@@ -1700,6 +1702,7 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         dst (dst_ip_address) (dst_port) \
                         tos (tos_value) ttl (ttl_value) \
                         tag (verification_tag) vlan (vlan_value) \
+                        (NVGRE|VxLAN|GRE|Notunnel) (tunnel_id_value) \
                         flexbytes (flexbytes_value) (drop|fwd) \
                         pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)
 
@@ -1722,15 +1725,21 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 For example, to add an ipv4-udp flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-udp src 2.2.2.3 32 \
-            dst 2.2.2.5 33 tos 2 ttl 40 vlan 0x1 flexbytes (0x88,0x48) \
-            fwd pf queue 1 fd_id 1
+            dst 2.2.2.5 33  tos 2 ttl 40 vlan 0x1 Notunnel 0 \
+            flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
 For example, add an ipv4-other flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
-             dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 \
+             dst 2.2.2.5  tos 2 proto 20 ttl 40 vlan 0x1 Notunnel 0 \
              flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
+For example, add a ipv4-other flow type filter with GRE key 0x0a0b0c0d:
+
+   testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
+            dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 GRE 0x0a0b0c0d \
+            flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+
 flush_flow_director
 ~~~~~~~~~~~~~~~~~~~
 
@@ -1861,6 +1870,7 @@ For example, to add source IP to hash input set for flow type of ipv4-udp on por
 set_fdir_input_set
 ~~~~~~~~~~~~~~~~~~
 
+
 The Flow Director filters can match the different fields for different type of packet, i.e. specific input set
 on per flow type and the flexible payload. This command can be used to change input set for each flow type.
 
@@ -1871,7 +1881,7 @@ Set the input set for flow director::
    l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
    tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
-   sctp-dst-port|sctp-veri-tag|none) (select|add)
+   sctp-dst-port|sctp-veri-tag|udp-key|gre-key|none) (select|add)
 
 For example to add source IP to FD input set for flow type of ipv4-udp on port 0::
 
-- 
2.4.0

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

* [PATCH v3 10/12] i40e: fix VLAN bitmasks for input set
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
                         ` (8 preceding siblings ...)
  2016-03-09  5:42       ` [PATCH v3 09/12] testpmd: extend flow director commands Jingjing Wu
@ 2016-03-09  5:42       ` Jingjing Wu
  2016-03-09  5:42       ` [PATCH v3 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
                         ` (3 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch adds missing VLAN bitmask for inner frame in case of
tunneling and fixes VLAN tags bitmasks for single or outer frame
in case of tunneling.

Fixes: 98f055707685 ("i40e: configure input fields for RSS or flow director")

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 70a1c6c..af87298 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -199,10 +199,12 @@
 #define I40E_REG_INSET_L2_DMAC                   0xE000000000000000ULL
 /* Source MAC address */
 #define I40E_REG_INSET_L2_SMAC                   0x1C00000000000000ULL
-/* VLAN tag in the outer L2 header */
-#define I40E_REG_INSET_L2_OUTER_VLAN             0x0080000000000000ULL
-/* VLAN tag in the inner L2 header */
-#define I40E_REG_INSET_L2_INNER_VLAN             0x0100000000000000ULL
+/* Outer (S-Tag) VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_OUTER_VLAN             0x0200000000000000ULL
+/* Inner (C-Tag) or single VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_INNER_VLAN             0x0080000000000000ULL
+/* Single VLAN tag in the inner L2 header */
+#define I40E_REG_INSET_TUNNEL_VLAN               0x0100000000000000ULL
 /* Source IPv4 address */
 #define I40E_REG_INSET_L3_SRC_IP4                0x0001800000000000ULL
 /* Destination IPv4 address */
@@ -6879,7 +6881,7 @@ i40e_translate_input_set_reg(uint64_t input)
 			I40E_REG_INSET_TUNNEL_L4_UDP_SRC_PORT},
 		{I40E_INSET_TUNNEL_DST_PORT,
 			I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT},
-		{I40E_INSET_TUNNEL_ID, I40E_REG_INSET_TUNNEL_ID},
+		{I40E_INSET_VLAN_TUNNEL, I40E_REG_INSET_TUNNEL_VLAN},
 		{I40E_INSET_FLEX_PAYLOAD_W1, I40E_REG_INSET_FLEX_PAYLOAD_WORD1},
 		{I40E_INSET_FLEX_PAYLOAD_W2, I40E_REG_INSET_FLEX_PAYLOAD_WORD2},
 		{I40E_INSET_FLEX_PAYLOAD_W3, I40E_REG_INSET_FLEX_PAYLOAD_WORD3},
-- 
2.4.0

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

* [PATCH v3 11/12] i40e: extend flow director to filter by vlan id
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
                         ` (9 preceding siblings ...)
  2016-03-09  5:42       ` [PATCH v3 10/12] i40e: fix VLAN bitmasks for input set Jingjing Wu
@ 2016-03-09  5:42       ` Jingjing Wu
  2016-03-09  5:43       ` [PATCH v3 12/12] testpmd: extend flow director commands Jingjing Wu
                         ` (2 subsequent siblings)
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:42 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended flow director to select vlan id
as filter's input set and program the filter rule with vlan id.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst |  2 ++
 drivers/net/i40e/i40e_ethdev.c         | 11 ++++++++
 drivers/net/i40e/i40e_fdir.c           | 49 ++++++++++++++++++++++++++--------
 3 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 26af339..b6ee8b3 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -105,6 +105,8 @@ This section should contain new features added in this release. Sample format:
   be down.
   We added the support of auto-neg by SW to avoid this link down issue.
 
+* **Added Flow director enhancements on Intel X710/XL710.**
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index af87298..39a7280 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6618,58 +6618,69 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index e4ac79d..e905f9f 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -687,34 +687,50 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 	return ret;
 }
 
-static inline void
+static inline int
 i40e_fdir_fill_ether_head(const struct rte_eth_fdir_input *fdir_input,
-			       unsigned char *pkt)
+			       unsigned char *pkt, bool vlan)
 {
-	struct ether_hdr *ether = (struct ether_hdr *)pkt;
+	static uint8_t vlan_frame[] = {0x81, 0, 0, 0};
+	uint16_t *ether_type;
+	uint8_t len = 2 * sizeof(struct ether_addr);
+
+	pkt += 2 * sizeof(struct ether_addr);
+	if (vlan && fdir_input->flow_ext.vlan_tci) {
+		rte_memcpy(pkt, vlan_frame, sizeof(vlan_frame));
+		rte_memcpy(pkt + sizeof(uint16_t),
+			   &fdir_input->flow_ext.vlan_tci,
+			   sizeof(uint16_t));
+		pkt += sizeof(vlan_frame);
+		len += sizeof(vlan_frame);
+	}
+	ether_type = (uint16_t *)pkt;
+
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
+		*ether_type = fdir_input->flow.l2_flow.ether_type;
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		*ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		*ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
 			    fdir_input->flow_type);
-		break;
+		return -1;
 	}
+	len += sizeof(uint16_t);
+	return len;
 }
 
 static inline void
@@ -814,6 +830,8 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 	struct sctp_hdr *sctp;
 	uint8_t size, dst = 0;
 	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
+	int len;
+	static uint8_t vlan_frame[] = {0x81, 0, 0, 0};
 	static uint8_t gre4_frame[] = {0x08, 0,
 			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x08, 0,
@@ -833,6 +851,14 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			0, 0, 0, 0}; /*Mac + IP + NVGRE hdr*/
 
 	inner_pkt += 2 * sizeof(struct ether_addr);
+	if (fdir_input->flow_ext.vlan_tci) {
+		rte_memcpy(inner_pkt, vlan_frame, sizeof(vlan_frame));
+		rte_memcpy(inner_pkt + sizeof(uint16_t),
+			   &fdir_input->flow_ext.vlan_tci,
+			   sizeof(uint16_t));
+		inner_pkt += sizeof(vlan_frame);
+	}
+
 	/* fill the tunnel header if required */
 	switch (fdir_input->flow.tunnel_flow.tunnel_type) {
 	case RTE_FDIR_TUNNEL_TYPE_GRE:
@@ -862,7 +888,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			   &fdir_input->flow.tunnel_flow.tunnel_id,
 			   I40E_TUNNEL_KEY_LEN);
 		/* fill the ethernet and IP head of inner frame */
-		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt, FALSE);
 		inner_pkt += sizeof(struct ether_hdr);
 		break;
 	case RTE_FDIR_TUNNEL_TYPE_NVGRE:
@@ -872,13 +898,13 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			   &fdir_input->flow.tunnel_flow.tunnel_id,
 			   I40E_TUNNEL_KEY_LEN);
 		/* fill the Ether header of inner frame */
-		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt, FALSE);
 		inner_pkt += sizeof(struct ether_hdr);
 		break;
 	default:
 		/* fill the Ether header of single frame */
-		i40e_fdir_fill_ether_head(fdir_input, raw_pkt);
-		inner_pkt = raw_pkt + sizeof(struct ether_hdr);
+		len = i40e_fdir_fill_ether_head(fdir_input, raw_pkt, TRUE);
+		inner_pkt = raw_pkt + len;
 		break;
 	}
 
@@ -1123,6 +1149,7 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 		PMD_DRV_LOG(ERR, "construct packet for fdir fails.");
 		return ret;
 	}
+
 	pctype = i40e_flowtype_to_pctype(filter->input.flow_type);
 	ret = i40e_fdir_filter_programming(pf, pctype, filter, add);
 	if (ret < 0) {
-- 
2.4.0

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

* [PATCH v3 12/12] testpmd: extend flow director commands
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
                         ` (10 preceding siblings ...)
  2016-03-09  5:42       ` [PATCH v3 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
@ 2016-03-09  5:43       ` Jingjing Wu
  2016-03-09  6:18       ` [PATCH v3 00/12] extend flow director fields in i40e driver Zhang, Helin
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
  13 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-09  5:43 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended commands for filter's input set changing.
It added vlan as filter's input fields.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 6 +++---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 9cba2cc..6679a86 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -750,7 +750,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set_fdir_input_set (port_id) "
 			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|"
 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
 			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
 			"udp-dst-port|tcp-src-port|tcp-dst-port|"
@@ -9624,7 +9624,7 @@ cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ivlan#ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
 	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
 	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
@@ -9639,7 +9639,7 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.help_str = "set_fdir_input_set <port_id> "
 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
 	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
 	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
 	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 417ddde..aa20d5a 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1878,7 +1878,7 @@ Set the input set for flow director::
 
    set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
    ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
-   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
    tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
    sctp-dst-port|sctp-veri-tag|udp-key|gre-key|none) (select|add)
-- 
2.4.0

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

* Re: [PATCH v3 00/12] extend flow director fields in i40e driver
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
                         ` (11 preceding siblings ...)
  2016-03-09  5:43       ` [PATCH v3 12/12] testpmd: extend flow director commands Jingjing Wu
@ 2016-03-09  6:18       ` Zhang, Helin
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
  13 siblings, 0 replies; 105+ messages in thread
From: Zhang, Helin @ 2016-03-09  6:18 UTC (permalink / raw)
  To: Wu, Jingjing, Richardson, Bruce; +Cc: dev

Acked-by: Helin Zhang <helin.zhang@intel.com>

> -----Original Message-----
> From: Wu, Jingjing
> Sent: Wednesday, March 9, 2016 1:43 PM
> To: Richardson, Bruce <bruce.richardson@intel.com>
> Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Zhang, Helin
> <helin.zhang@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Pei, Yulong
> <yulong.pei@intel.com>
> Subject: [PATCH v3 00/12] extend flow director fields in i40e driver
> 
> v3 changes:
>  - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
>  - use AQ rx control register read/write for some registers
>  - remove few useless lines
>  - patch title rewording
> 
> v2 changes:
>  - rebase on dpdk-next-net/rel_16_04
>  - comments rewording.
>  - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to avoid ABI breaking.
>  - remove ABI announce in Deprecation.
>  - fix the ethertype setting when program filter in v1 patch set.
> 
> This patch set extends flow director to support filtering by additional fields below
> in i40e driver:
>  - TOS, Protocol and TTL in IP header
>  - Tunnel id if NVGRE/GRE/VxLAN packets
>  - single vlan or inner vlan
> 
> 
> Andrey Chilikin (1):
>   i40e: fix VLAN bitmasks for input set
> 
> Jingjing Wu (11):
>   ethdev: extend flow director for input selection
>   i40e: split function for hash and fdir input
>   i40e: remove flex payload from input selection
>   i40e: restore default setting on input set
>   i40e: extend flow director to filter by IP Header
>   testpmd: extend input set related commands
>   librte_ether: extend flow director struct
>   i40e: extend flow director to filter by tunnel ID
>   testpmd: extend flow director commands
>   i40e: extend flow director to filter by vlan id
>   testpmd: extend flow director commands
> 
>  app/test-pmd/cmdline.c                      | 121 +++++++--
>  doc/guides/rel_notes/deprecation.rst        |   4 -
>  doc/guides/rel_notes/release_16_04.rst      |   5 +
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 ++--
>  drivers/net/i40e/i40e_ethdev.c              | 403
> +++++++++++++++++-----------
>  drivers/net/i40e/i40e_ethdev.h              |  11 +-
>  drivers/net/i40e/i40e_fdir.c                | 206 ++++++++++----
>  lib/librte_ether/rte_eth_ctrl.h             |  35 ++-
>  8 files changed, 570 insertions(+), 271 deletions(-)
> 
> --
> 2.4.0

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

* Re: [PATCH v3 01/12] ethdev: extend flow director for input selection
  2016-03-09  5:42       ` [PATCH v3 01/12] ethdev: extend flow director for input selection Jingjing Wu
@ 2016-03-09  9:52         ` Thomas Monjalon
  2016-03-09  9:56           ` Thomas Monjalon
  2016-03-09  9:54         ` Thomas Monjalon
  1 sibling, 1 reply; 105+ messages in thread
From: Thomas Monjalon @ 2016-03-09  9:52 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev

2016-03-09 13:42, Jingjing Wu:
> This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
> RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
> struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
> by tos, protocol and ttl.
> 
> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> ---
>  lib/librte_ether/rte_eth_ctrl.h | 8 ++++++++
>  1 file changed, 8 insertions(+)

You should remove the deprecation notice in this patch.

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

* Re: [PATCH v3 01/12] ethdev: extend flow director for input selection
  2016-03-09  5:42       ` [PATCH v3 01/12] ethdev: extend flow director for input selection Jingjing Wu
  2016-03-09  9:52         ` Thomas Monjalon
@ 2016-03-09  9:54         ` Thomas Monjalon
  2016-03-09 10:26           ` Wu, Jingjing
  1 sibling, 1 reply; 105+ messages in thread
From: Thomas Monjalon @ 2016-03-09  9:54 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev

2016-03-09 13:42, Jingjing Wu:
>  struct rte_eth_ipv4_flow {
>  	uint32_t src_ip;      /**< IPv4 source address to match. */
>  	uint32_t dst_ip;      /**< IPv4 destination address to match. */
> +	uint8_t  tos;         /**< Type of service to match. */
> +	uint8_t  ttl;         /**< Time to live */
> +	uint8_t  proto;

L4 protocol?

>  };
>  
>  /**
> @@ -443,6 +448,9 @@ struct rte_eth_sctpv4_flow {
>  struct rte_eth_ipv6_flow {
>  	uint32_t src_ip[4];      /**< IPv6 source address to match. */
>  	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
> +	uint8_t  tc;             /**< Traffic class to match. */
> +	uint8_t  proto;          /**< Protocol, next header. */
> +	uint8_t  hop_limits;
>  };

Why some fields are not commented?
I guess the values must be the ones found in the IPv4 header.

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

* Re: [PATCH v3 01/12] ethdev: extend flow director for input selection
  2016-03-09  9:52         ` Thomas Monjalon
@ 2016-03-09  9:56           ` Thomas Monjalon
  0 siblings, 0 replies; 105+ messages in thread
From: Thomas Monjalon @ 2016-03-09  9:56 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev

2016-03-09 10:52, Thomas Monjalon:
> 2016-03-09 13:42, Jingjing Wu:
> > This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
> > RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
> > struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
> > by tos, protocol and ttl.
> > 
> > Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> > ---
> >  lib/librte_ether/rte_eth_ctrl.h | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> 
> You should remove the deprecation notice in this patch.

Forget that, I've seen the patch 7 which makes more important changes.

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

* Re: [PATCH v3 01/12] ethdev: extend flow director for input selection
  2016-03-09  9:54         ` Thomas Monjalon
@ 2016-03-09 10:26           ` Wu, Jingjing
  2016-03-09 10:36             ` Thomas Monjalon
  0 siblings, 1 reply; 105+ messages in thread
From: Wu, Jingjing @ 2016-03-09 10:26 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Wednesday, March 09, 2016 5:55 PM
> To: Wu, Jingjing
> Cc: dev@dpdk.org; Richardson, Bruce
> Subject: Re: [dpdk-dev] [PATCH v3 01/12] ethdev: extend flow director for
> input selection
> 
> 2016-03-09 13:42, Jingjing Wu:
> >  struct rte_eth_ipv4_flow {
> >  	uint32_t src_ip;      /**< IPv4 source address to match. */
> >  	uint32_t dst_ip;      /**< IPv4 destination address to match. */
> > +	uint8_t  tos;         /**< Type of service to match. */
> > +	uint8_t  ttl;         /**< Time to live */
> > +	uint8_t  proto;
> 
> L4 protocol?
> 
> >  };
> >
> >  /**
> > @@ -443,6 +448,9 @@ struct rte_eth_sctpv4_flow {  struct
> > rte_eth_ipv6_flow {
> >  	uint32_t src_ip[4];      /**< IPv6 source address to match. */
> >  	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
> > +	uint8_t  tc;             /**< Traffic class to match. */
> > +	uint8_t  proto;          /**< Protocol, next header. */
> > +	uint8_t  hop_limits;
> >  };
> 
> Why some fields are not commented?
> I guess the values must be the ones found in the IPv4 header.

Yes, you are correct. The fields defined in rte_eth_ipvx_flow are the ones in IP header.
Should I comments all of them?

Thanks
Jingjing 

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

* Re: [PATCH v3 01/12] ethdev: extend flow director for input selection
  2016-03-09 10:26           ` Wu, Jingjing
@ 2016-03-09 10:36             ` Thomas Monjalon
  2016-03-09 11:22               ` Wu, Jingjing
  0 siblings, 1 reply; 105+ messages in thread
From: Thomas Monjalon @ 2016-03-09 10:36 UTC (permalink / raw)
  To: Wu, Jingjing; +Cc: dev

2016-03-09 10:26, Wu, Jingjing:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > 2016-03-09 13:42, Jingjing Wu:
> > >  struct rte_eth_ipv4_flow {
> > >  	uint32_t src_ip;      /**< IPv4 source address to match. */
> > >  	uint32_t dst_ip;      /**< IPv4 destination address to match. */
> > > +	uint8_t  tos;         /**< Type of service to match. */
> > > +	uint8_t  ttl;         /**< Time to live */
> > > +	uint8_t  proto;
> > 
> > L4 protocol?
> > 
> > >  };
> > >
> > >  /**
> > > @@ -443,6 +448,9 @@ struct rte_eth_sctpv4_flow {  struct
> > > rte_eth_ipv6_flow {
> > >  	uint32_t src_ip[4];      /**< IPv6 source address to match. */
> > >  	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
> > > +	uint8_t  tc;             /**< Traffic class to match. */
> > > +	uint8_t  proto;          /**< Protocol, next header. */
> > > +	uint8_t  hop_limits;
> > >  };
> > 
> > Why some fields are not commented?
> > I guess the values must be the ones found in the IPv4 header.
> 
> Yes, you are correct. The fields defined in rte_eth_ipvx_flow are the ones in IP header.
> Should I comments all of them?

Please, do I really need to confirm that the API must be clearly documented?

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

* Re: [PATCH v3 01/12] ethdev: extend flow director for input selection
  2016-03-09 10:36             ` Thomas Monjalon
@ 2016-03-09 11:22               ` Wu, Jingjing
  0 siblings, 0 replies; 105+ messages in thread
From: Wu, Jingjing @ 2016-03-09 11:22 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Wednesday, March 09, 2016 6:37 PM
> To: Wu, Jingjing
> Cc: dev@dpdk.org; Richardson, Bruce
> Subject: Re: [dpdk-dev] [PATCH v3 01/12] ethdev: extend flow director for
> input selection
> 
> 2016-03-09 10:26, Wu, Jingjing:
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > 2016-03-09 13:42, Jingjing Wu:
> > > >  struct rte_eth_ipv4_flow {
> > > >  	uint32_t src_ip;      /**< IPv4 source address to match. */
> > > >  	uint32_t dst_ip;      /**< IPv4 destination address to match. */
> > > > +	uint8_t  tos;         /**< Type of service to match. */
> > > > +	uint8_t  ttl;         /**< Time to live */
> > > > +	uint8_t  proto;
> > >
> > > L4 protocol?
> > >
> > > >  };
> > > >
> > > >  /**
> > > > @@ -443,6 +448,9 @@ struct rte_eth_sctpv4_flow {  struct
> > > > rte_eth_ipv6_flow {
> > > >  	uint32_t src_ip[4];      /**< IPv6 source address to match. */
> > > >  	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
> > > > +	uint8_t  tc;             /**< Traffic class to match. */
> > > > +	uint8_t  proto;          /**< Protocol, next header. */
> > > > +	uint8_t  hop_limits;
> > > >  };
> > >
> > > Why some fields are not commented?
> > > I guess the values must be the ones found in the IPv4 header.
> >
> > Yes, you are correct. The fields defined in rte_eth_ipvx_flow are the ones
> in IP header.
> > Should I comments all of them?
> 
> Please, do I really need to confirm that the API must be clearly documented?
OK. Just asking for your view to avoid meaningless comments. Anyway, will update.
Thanks

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

* [PATCH v4 00/12] extend flow director fields in i40e driver
  2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
                         ` (12 preceding siblings ...)
  2016-03-09  6:18       ` [PATCH v3 00/12] extend flow director fields in i40e driver Zhang, Helin
@ 2016-03-10  3:25       ` Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 01/12] ethdev: extend flow director for input selection Jingjing Wu
                           ` (12 more replies)
  13 siblings, 13 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

v4 changes:
 - rebase to latest dpdk-next-net/rel_16_04.
 - comments on new fields in API structure.

v3 changes:
 - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
 - use AQ rx control register read/write for some registers
 - remove few useless lines
 - patch title rewording

v2 changes:
 - rebase on dpdk-next-net/rel_16_04
 - comments rewording.
 - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to
   avoid ABI breaking.
 - remove ABI announce in Deprecation.
 - fix the ethertype setting when program filter in v1 patch set.

This patch set extends flow director to support filtering by
additional fields below in i40e driver:
 - TOS, Protocol and TTL in IP header
 - Tunnel id if NVGRE/GRE/VxLAN packets
 - single vlan or inner vlan 


Andrey Chilikin (1):
  i40e: fix VLAN bitmasks for input set

Jingjing Wu (11):
  ethdev: extend flow director for input selection
  i40e: split function for hash and fdir input
  i40e: remove flex payload from input selection
  i40e: restore default setting on input set
  i40e: extend flow director to filter by IP Header
  testpmd: extend input set related commands
  librte_ether: extend flow director struct
  i40e: extend flow director to filter by tunnel ID
  testpmd: extend flow director commands
  i40e: extend flow director to filter by vlan id
  testpmd: extend flow director commands

 app/test-pmd/cmdline.c                      | 121 +++++++--
 doc/guides/rel_notes/deprecation.rst        |   4 -
 doc/guides/rel_notes/release_16_04.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  56 ++--
 drivers/net/i40e/i40e_ethdev.c              | 403 +++++++++++++++++-----------
 drivers/net/i40e/i40e_ethdev.h              |  11 +-
 drivers/net/i40e/i40e_fdir.c                | 206 ++++++++++----
 lib/librte_ether/rte_eth_ctrl.h             |  35 ++-
 8 files changed, 570 insertions(+), 271 deletions(-)

-- 
2.4.0

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

* [PATCH v4 01/12] ethdev: extend flow director for input selection
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 02/12] i40e: split function for hash and fdir input Jingjing Wu
                           ` (11 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
by tos, protocol and ttl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index ce224ad..e2ac686 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -340,6 +340,8 @@ enum rte_eth_input_set_field {
 	RTE_ETH_INPUT_SET_L3_IP4_PROTO,
 	RTE_ETH_INPUT_SET_L3_IP6_TC,
 	RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
+	RTE_ETH_INPUT_SET_L3_IP4_TTL,
+	RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
 
 	/* L4 */
 	RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT = 257,
@@ -407,6 +409,9 @@ struct rte_eth_l2_flow {
 struct rte_eth_ipv4_flow {
 	uint32_t src_ip;      /**< IPv4 source address to match. */
 	uint32_t dst_ip;      /**< IPv4 destination address to match. */
+	uint8_t  tos;         /**< Type of service to match. */
+	uint8_t  ttl;         /**< Time to live to match. */
+	uint8_t  proto;       /**< Protocol, next header to match. */
 };
 
 /**
@@ -443,6 +448,9 @@ struct rte_eth_sctpv4_flow {
 struct rte_eth_ipv6_flow {
 	uint32_t src_ip[4];      /**< IPv6 source address to match. */
 	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
+	uint8_t  tc;             /**< Traffic class to match. */
+	uint8_t  proto;          /**< Protocol, next header to match. */
+	uint8_t  hop_limits;     /**< Hop limits to match. */
 };
 
 /**
-- 
2.4.0

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

* [PATCH v4 02/12] i40e: split function for hash and fdir input
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 01/12] ethdev: extend flow director for input selection Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 03/12] i40e: remove flex payload from input selection Jingjing Wu
                           ` (10 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch split function for input set changing of hash
and fdir to avoid multiple check on different situation.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 235 +++++++++++++++++------------------------
 drivers/net/i40e/i40e_ethdev.h |  11 +-
 drivers/net/i40e/i40e_fdir.c   |   5 +-
 3 files changed, 107 insertions(+), 144 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 0c87ec1..c8a62b8 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6906,25 +6906,6 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	return idx;
 }
 
-static uint64_t
-i40e_get_reg_inset(struct i40e_hw *hw, enum rte_filter_type filter,
-			    enum i40e_filter_pctype pctype)
-{
-	uint64_t reg = 0;
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
-	}
-
-	return reg;
-}
-
 static void
 i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 {
@@ -6937,105 +6918,96 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)i40e_read_rx_ctl(hw, addr));
 }
 
-static int
-i40e_set_hash_inset_mask(struct i40e_hw *hw,
-			 enum i40e_filter_pctype pctype,
-			 enum rte_filter_input_set_op op,
-			 uint32_t *mask_reg,
-			 uint8_t num)
+int
+i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			 struct rte_eth_input_set_conf *conf)
 {
-	uint32_t reg;
-	uint8_t i;
+	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	if (!conf) {
+		PMD_DRV_LOG(ERR, "Invalid pointer");
+		return -EFAULT;
+	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
 		return -EINVAL;
-
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = i40e_read_rx_ctl(hw,
-					       I40E_GLQF_HASH_MSK(i, pctype));
-			if (reg & I40E_GLQF_HASH_MSK_MASK_MASK)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
-
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[j]);
 	}
 
-	return 0;
-}
-
-static int
-i40e_set_fd_inset_mask(struct i40e_hw *hw,
-		       enum i40e_filter_pctype pctype,
-		       enum rte_filter_input_set_op op,
-		       uint32_t *mask_reg,
-		       uint8_t num)
-{
-	uint32_t reg;
-	uint8_t i;
+	pctype = i40e_flowtype_to_pctype(conf->flow_type);
+	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
+		PMD_DRV_LOG(ERR, "Not supported flow type (%u)",
+			    conf->flow_type);
+		return -EINVAL;
+	}
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
+				   conf->inset_size);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to parse input set");
+		return -EINVAL;
+	}
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
+				    input_set) != 0) {
+		PMD_DRV_LOG(ERR, "Invalid input set");
+		return -EINVAL;
+	}
+	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
+		/* get inset value in register */
+		inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
+		inset_reg <<= I40E_32_BIT_WIDTH;
+		inset_reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype));
+		input_set |= pf->hash_input_set[pctype];
+	}
+	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+					   I40E_INSET_MASK_NUM_REG);
+	if (num < 0)
 		return -EINVAL;
 
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = i40e_read_rx_ctl(hw,
-					       I40E_GLQF_FD_MSK(i, pctype));
-			if (reg & I40E_GLQF_FD_MSK_MASK_MASK)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[j]);
-	}
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     0);
+	I40E_WRITE_FLUSH(hw);
 
+	pf->hash_input_set[pctype] = input_set;
 	return 0;
 }
 
 int
-i40e_filter_inset_select(struct i40e_hw *hw,
-			 struct rte_eth_input_set_conf *conf,
-			 enum rte_filter_type filter)
+i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			 struct rte_eth_input_set_conf *conf)
 {
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	enum i40e_filter_pctype pctype;
-	uint64_t inset_reg = 0, input_set;
-	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG];
-	uint8_t num;
-	int ret;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
 	if (!hw || !conf) {
 		PMD_DRV_LOG(ERR, "Invalid pointer");
 		return -EFAULT;
 	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
+		return -EINVAL;
+	}
 
 	pctype = i40e_flowtype_to_pctype(conf->flow_type);
 	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
@@ -7043,60 +7015,48 @@ i40e_filter_inset_select(struct i40e_hw *hw,
 			    conf->flow_type);
 		return -EINVAL;
 	}
-	if (filter != RTE_ETH_FILTER_HASH && filter != RTE_ETH_FILTER_FDIR) {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
-
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, filter, input_set) != 0) {
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
+				    input_set) != 0) {
 		PMD_DRV_LOG(ERR, "Invalid input set");
 		return -EINVAL;
 	}
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
-		inset_reg |= i40e_get_reg_inset(hw, filter, pctype);
-	} else if (conf->op != RTE_ETH_INPUT_SET_SELECT) {
-		PMD_DRV_LOG(ERR, "Unsupported input set operation");
-		return -EINVAL;
-	}
+	/* get inset value in register */
+	inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
+	inset_reg <<= I40E_32_BIT_WIDTH;
+	inset_reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
+
+	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-	inset_reg |= i40e_translate_input_set_reg(input_set);
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		ret = i40e_set_hash_inset_mask(hw, pctype, conf->op, mask_reg,
-					       num);
-		if (ret)
-			return -EINVAL;
+	if (num < 0)
+		return -EINVAL;
 
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		ret = i40e_set_fd_inset_mask(hw, pctype, conf->op, mask_reg,
-					     num);
-		if (ret)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     0);
 	I40E_WRITE_FLUSH(hw);
 
+	pf->fdir.input_set[pctype] = input_set;
 	return 0;
 }
 
@@ -7148,9 +7108,8 @@ i40e_hash_filter_set(struct i40e_hw *hw, struct rte_eth_hash_filter_info *info)
 				&(info->info.global_conf));
 		break;
 	case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-					       &(info->info.input_set_conf),
-					       RTE_ETH_FILTER_HASH);
+		ret = i40e_hash_filter_inset_select(hw,
+					       &(info->info.input_set_conf));
 		break;
 
 	default:
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index a9b805e..d869124 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -364,6 +364,8 @@ struct i40e_fdir_info {
 	struct i40e_rx_queue *rxq;
 	void *prg_pkt;                 /* memory for fdir program packet */
 	uint64_t dma_addr;             /* physic address of packet memory*/
+	/* input set bits for each pctype */
+	uint64_t input_set[I40E_FILTER_PCTYPE_MAX];
 	/*
 	 * the rule how bytes stream is extracted as flexible payload
 	 * for each payload layer, the setting can up to three elements
@@ -430,6 +432,8 @@ struct i40e_pf {
 	uint16_t fdir_qp_offset;
 
 	uint16_t hash_lut_size; /* The size of hash lookup table */
+	/* input set bits for each pctype */
+	uint64_t hash_input_set[I40E_FILTER_PCTYPE_MAX];
 	/* store VXLAN UDP ports */
 	uint16_t vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];
 	uint16_t vxlan_bitmap; /* Vxlan bit mask */
@@ -573,9 +577,10 @@ int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 int i40e_select_filter_input_set(struct i40e_hw *hw,
 				 struct rte_eth_input_set_conf *conf,
 				 enum rte_filter_type filter);
-int i40e_filter_inset_select(struct i40e_hw *hw,
-			     struct rte_eth_input_set_conf *conf,
-			     enum rte_filter_type filter);
+int i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			     struct rte_eth_input_set_conf *conf);
+int i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			     struct rte_eth_input_set_conf *conf);
 
 void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct rte_eth_rxq_info *qinfo);
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 14c51ce..f8055e7 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -1362,7 +1362,6 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 		     struct rte_eth_fdir_filter_info *info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	int ret = 0;
 
 	if (!info) {
@@ -1372,8 +1371,8 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 
 	switch (info->info_type) {
 	case RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-			&(info->info.input_set_conf), RTE_ETH_FILTER_FDIR);
+		ret = i40e_fdir_filter_inset_select(pf,
+				&(info->info.input_set_conf));
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "FD filter info type (%d) not supported",
-- 
2.4.0

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

* [PATCH v4 03/12] i40e: remove flex payload from input selection
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 01/12] ethdev: extend flow director for input selection Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 02/12] i40e: split function for hash and fdir input Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 04/12] i40e: restore default setting on input set Jingjing Wu
                           ` (9 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

In this patch, flex payload is removed from valid fdir input set
values. It is because all flex payload configuration can be set
in struct rte_fdir_conf during device configure phase.
And it is a more flexible configuration including flexpayload's
selection, input set selection by word and mask setting in bits.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 59 +++++++++++++++++++-----------------------
 1 file changed, 26 insertions(+), 33 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index c8a62b8..fe340a5 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -255,7 +255,8 @@
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD7        0x0000000000000080ULL
 /* 8th word of flex payload */
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD8        0x0000000000000040ULL
-
+/* all 8 words flex payload */
+#define I40E_REG_INSET_FLEX_PAYLOAD_WORDS        0x0000000000003FC0ULL
 #define I40E_REG_INSET_MASK_DEFAULT              0x0000000000000000ULL
 
 #define I40E_TRANSLATE_INSET 0
@@ -6606,43 +6607,32 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
-		I40E_INSET_LAST_ETHER_TYPE | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
 	if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD)
@@ -6870,7 +6860,7 @@ i40e_translate_input_set_reg(uint64_t input)
 	return val;
 }
 
-static uint8_t
+static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
@@ -6888,16 +6878,13 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-	if (!inset && nb_elem >= I40E_INSET_MASK_NUM_REG) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++)
-			mask[i] = 0;
-		return I40E_INSET_MASK_NUM_REG;
-	}
 
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if (idx >= nb_elem)
-			break;
-		if (inset & inset_mask_map[i].inset) {
+		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+			if (idx >= nb_elem) {
+				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
+				return -EINVAL;
+			}
 			mask[idx] = inset_mask_map[i].mask;
 			idx++;
 		}
@@ -7032,7 +7019,13 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 	inset_reg <<= I40E_32_BIT_WIDTH;
 	inset_reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+	/* Can not change the inset reg for flex payload for fdir,
+	 * it is done by writing I40E_PRTQF_FD_FLXINSET
+	 * in i40e_set_flex_mask_on_pctype.
+	 */
+	if (conf->op == RTE_ETH_INPUT_SET_SELECT)
+		inset_reg &= I40E_REG_INSET_FLEX_PAYLOAD_WORDS;
+	else
 		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-- 
2.4.0

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

* [PATCH v4 04/12] i40e: restore default setting on input set
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
                           ` (2 preceding siblings ...)
  2016-03-10  3:25         ` [PATCH v4 03/12] i40e: remove flex payload from input selection Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 05/12] i40e: extend flow director to filter by IP Header Jingjing Wu
                           ` (8 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch added a new function to set the input set to default
when initialization.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 56 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index fe340a5..1c672c1 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -367,6 +367,7 @@ static int i40e_dev_udp_tunnel_add(struct rte_eth_dev *dev,
 				struct rte_eth_udp_tunnel *udp_tunnel);
 static int i40e_dev_udp_tunnel_del(struct rte_eth_dev *dev,
 				struct rte_eth_udp_tunnel *udp_tunnel);
+static void i40e_filter_input_set_init(struct i40e_pf *pf);
 static int i40e_ethertype_filter_set(struct i40e_pf *pf,
 			struct rte_eth_ethertype_filter *filter,
 			bool add);
@@ -781,6 +782,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	 * It should be removed once issues are fixed in NVM.
 	 */
 	i40e_flex_payload_reg_init(hw);
+	/* Initialize the input set for filters (hash and fd) to default value */
+	i40e_filter_input_set_init(pf);
 
 	/* Initialize the parameters for adminq */
 	i40e_init_adminq_parameter(hw);
@@ -6905,6 +6908,59 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)i40e_read_rx_ctl(hw, addr));
 }
 
+static void
+i40e_filter_input_set_init(struct i40e_pf *pf)
+{
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int num, i;
+
+	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
+		if (!I40E_VALID_PCTYPE(pctype))
+			continue;
+		input_set = i40e_get_default_input_set(pctype);
+
+		num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+						   I40E_INSET_MASK_NUM_REG);
+		if (num < 0)
+			return;
+		inset_reg = i40e_translate_input_set_reg(input_set);
+
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+		for (i = 0; i < num; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     mask_reg[i]);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     mask_reg[i]);
+		}
+		/*clear unused mask registers of the pctype */
+		for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     0);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     0);
+		}
+		I40E_WRITE_FLUSH(hw);
+
+		/* store the default input set */
+		pf->hash_input_set[pctype] = input_set;
+		pf->fdir.input_set[pctype] = input_set;
+	}
+}
+
 int
 i40e_hash_filter_inset_select(struct i40e_hw *hw,
 			 struct rte_eth_input_set_conf *conf)
-- 
2.4.0

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

* [PATCH v4 05/12] i40e: extend flow director to filter by IP Header
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
                           ` (3 preceding siblings ...)
  2016-03-10  3:25         ` [PATCH v4 04/12] i40e: restore default setting on input set Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 06/12] testpmd: extend input set related commands Jingjing Wu
                           ` (7 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended flow director to select more IP Header fields
as filter input set.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 69 ++++++++++++++++++++++++++++++++++--------
 drivers/net/i40e/i40e_fdir.c   | 26 +++++++++++-----
 2 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 1c672c1..e24b026 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -211,6 +211,8 @@
 #define I40E_REG_INSET_L3_IP4_TOS                0x0040000000000000ULL
 /* IPv4 Protocol */
 #define I40E_REG_INSET_L3_IP4_PROTO              0x0004000000000000ULL
+/* IPv4 Time to Live */
+#define I40E_REG_INSET_L3_IP4_TTL                0x0004000000000000ULL
 /* Source IPv6 address */
 #define I40E_REG_INSET_L3_SRC_IP6                0x0007F80000000000ULL
 /* Destination IPv6 address */
@@ -219,6 +221,8 @@
 #define I40E_REG_INSET_L3_IP6_TC                 0x0040000000000000ULL
 /* IPv6 Next Header */
 #define I40E_REG_INSET_L3_IP6_NEXT_HDR           0x0008000000000000ULL
+/* IPv6 Hop Limitr */
+#define I40E_REG_INSET_L3_IP6_HOP_LIMIT          0x0008000000000000ULL
 /* Source L4 port */
 #define I40E_REG_INSET_L4_SRC_PORT               0x0000000400000000ULL
 /* Destination L4 port */
@@ -262,10 +266,12 @@
 #define I40E_TRANSLATE_INSET 0
 #define I40E_TRANSLATE_REG   1
 
-#define I40E_INSET_IPV4_TOS_MASK      0x0009FF00UL
-#define I40E_INSET_IPV4_PROTO_MASK    0x000DFF00UL
-#define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
-#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
+#define I40E_INSET_IPV4_TOS_MASK        0x0009FF00UL
+#define I40E_INSET_IPv4_TTL_MASK        0x000D00FFUL
+#define I40E_INSET_IPV4_PROTO_MASK      0x000DFF00UL
+#define I40E_INSET_IPV6_TC_MASK         0x0009F00FUL
+#define I40E_INSET_IPV6_HOP_LIMIT_MASK  0x000CFF00UL
+#define I40E_INSET_IPV6_NEXT_HDR_MASK   0x000C00FFUL
 
 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
@@ -6610,30 +6616,47 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
@@ -6733,11 +6756,14 @@ i40e_parse_input_set(uint64_t *inset,
 		{RTE_ETH_INPUT_SET_L3_DST_IP4, I40E_INSET_IPV4_DST},
 		{RTE_ETH_INPUT_SET_L3_IP4_TOS, I40E_INSET_IPV4_TOS},
 		{RTE_ETH_INPUT_SET_L3_IP4_PROTO, I40E_INSET_IPV4_PROTO},
+		{RTE_ETH_INPUT_SET_L3_IP4_TTL, I40E_INSET_IPV4_TTL},
 		{RTE_ETH_INPUT_SET_L3_SRC_IP6, I40E_INSET_IPV6_SRC},
 		{RTE_ETH_INPUT_SET_L3_DST_IP6, I40E_INSET_IPV6_DST},
 		{RTE_ETH_INPUT_SET_L3_IP6_TC, I40E_INSET_IPV6_TC},
 		{RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
 			I40E_INSET_IPV6_NEXT_HDR},
+		{RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
+			I40E_INSET_IPV6_HOP_LIMIT},
 		{RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT, I40E_INSET_SRC_PORT},
@@ -6824,10 +6850,12 @@ i40e_translate_input_set_reg(uint64_t input)
 		{I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4},
 		{I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS},
 		{I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO},
+		{I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL},
 		{I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6},
 		{I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6},
 		{I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_REG_INSET_L3_IP6_NEXT_HDR},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_REG_INSET_L3_IP6_HOP_LIMIT},
 		{I40E_INSET_SRC_PORT, I40E_REG_INSET_L4_SRC_PORT},
 		{I40E_INSET_DST_PORT, I40E_REG_INSET_L4_DST_PORT},
 		{I40E_INSET_SCTP_VT, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG},
@@ -6867,23 +6895,38 @@ static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
+	uint64_t inset_need_mask = inset;
 
 	static const struct {
 		uint64_t inset;
 		uint32_t mask;
 	} inset_mask_map[] = {
 		{I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK},
+		{I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0},
 		{I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK},
+		{I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK},
 		{I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK},
+		{I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK}
 	};
 
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+		/* Clear the inset bit, if no MASK is required,
+		 * for example proto + ttl
+		 */
+		if ((inset & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset && inset_mask_map[i].mask == 0)
+			inset_need_mask &= ~inset_mask_map[i].inset;
+		if (!inset_need_mask)
+			return 0;
+	}
+	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
+		if ((inset_need_mask & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset) {
 			if (idx >= nb_elem) {
 				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
 				return -EINVAL;
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index f8055e7..ebbe612 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -66,7 +66,9 @@
 #define I40E_FDIR_IP_DEFAULT_TTL            0x40
 #define I40E_FDIR_IP_DEFAULT_VERSION_IHL    0x45
 #define I40E_FDIR_TCP_DEFAULT_DATAOFF       0x50
-#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60300000
+#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60000000
+#define I40E_FDIR_IPv6_TC_OFFSET            20
+
 #define I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS   0xFF
 #define I40E_FDIR_IPv6_PAYLOAD_LEN          380
 #define I40E_FDIR_UDP_DEFAULT_LEN           400
@@ -720,7 +722,13 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
-		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+		ip->next_proto_id = fdir_input->flow.ip4_flow.proto ?
+					fdir_input->flow.ip4_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip->time_to_live = fdir_input->flow.ip4_flow.ttl ?
+					fdir_input->flow.ip4_flow.ttl :
+					I40E_FDIR_IP_DEFAULT_TTL;
+		ip->type_of_service = fdir_input->flow.ip4_flow.tos;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -728,7 +736,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		 */
 		ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
 		ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
-		ip->next_proto_id = next_proto[fdir_input->flow_type];
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
@@ -739,11 +746,17 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 
 		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
-			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
+					 (fdir_input->flow.ipv6_flow.tc <<
+					  I40E_FDIR_IPv6_TC_OFFSET));
 		ip6->payload_len =
 			rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
-		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
-
+		ip6->proto = fdir_input->flow.ipv6_flow.proto ?
+					fdir_input->flow.ipv6_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ?
+					fdir_input->flow.ipv6_flow.hop_limits :
+					I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -755,7 +768,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		rte_memcpy(&(ip6->dst_addr),
 			   &(fdir_input->flow.ipv6_flow.src_ip),
 			   IPV6_ADDR_LEN);
-		ip6->proto = next_proto[fdir_input->flow_type];
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
-- 
2.4.0

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

* [PATCH v4 06/12] testpmd: extend input set related commands
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
                           ` (4 preceding siblings ...)
  2016-03-10  3:25         ` [PATCH v4 05/12] i40e: extend flow director to filter by IP Header Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 07/12] librte_ether: extend flow director struct Jingjing Wu
                           ` (6 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended commands for filter's input set changing.
It added tos, protocol and ttl as filter's input fields, and
remove the words selection from flex payloads for flow director.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 app/test-pmd/cmdline.c                      | 100 ++++++++++++++++++++++------
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  42 +++++++-----
 2 files changed, 104 insertions(+), 38 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 52e9f5f..5787f57 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -642,6 +642,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"flow_director_filter (port_id) mode IP (add|del|update)"
 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
+			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -651,6 +652,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
+			" tos (tos_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -660,7 +662,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-sctp|ipv6-sctp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
-			" tag (verification_tag) vlan (vlan_value)"
+			" tag (verification_tag) "
+			" tos (tos_value) ttl (ttl_value)"
+			" vlan (vlan_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -740,14 +744,15 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"fld-8th|none) (select|add)\n"
 			"    Set the input set for hash.\n\n"
 
-			"set_fdir_input_set (port_id) (ipv4|ipv4-frag|"
-			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+			"set_fdir_input_set (port_id) "
+			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
-			"udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|"
-			"sctp-src-port|sctp-dst-port|sctp-veri-tag|fld-1st|"
-			"fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
-			"fld-8th|none) (select|add)\n"
+			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
+			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
+			"udp-dst-port|tcp-src-port|tcp-dst-port|"
+			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
+			" (select|add)\n"
 			"    Set the input set for FDir.\n\n"
 		);
 	}
@@ -7985,6 +7990,12 @@ struct cmd_flow_director_result {
 	uint16_t port_dst;
 	cmdline_fixed_string_t verify_tag;
 	uint32_t verify_tag_value;
+	cmdline_ipaddr_t tos;
+	uint8_t tos_value;
+	cmdline_ipaddr_t proto;
+	uint8_t proto_value;
+	cmdline_ipaddr_t ttl;
+	uint8_t ttl_value;
 	cmdline_fixed_string_t vlan;
 	uint16_t vlan_value;
 	cmdline_fixed_string_t flexbytes;
@@ -8164,12 +8175,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 	switch (entry.input.flow_type) {
 	case RTE_ETH_FLOW_FRAG_IPV4:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+		entry.input.flow.ip4_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 		IPV4_ADDR_TO_UINT(res->ip_dst,
 			entry.input.flow.ip4_flow.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.ip4_flow.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8181,6 +8195,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp4_flow.ip.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.sctp4_flow.ip.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8191,12 +8207,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 		break;
 	case RTE_ETH_FLOW_FRAG_IPV6:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+		entry.input.flow.ipv6_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 		IPV6_ADDR_TO_ARRAY(res->ip_dst,
 			entry.input.flow.ipv6_flow.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.ipv6_flow.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8208,6 +8227,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp6_flow.ip.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.sctp6_flow.ip.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8335,6 +8356,24 @@ cmdline_parse_token_string_t cmd_flow_director_verify_tag =
 cmdline_parse_token_num_t cmd_flow_director_verify_tag_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
 			      verify_tag_value, UINT32);
+cmdline_parse_token_string_t cmd_flow_director_tos =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 tos, "tos");
+cmdline_parse_token_num_t cmd_flow_director_tos_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      tos_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_proto =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 proto, "proto");
+cmdline_parse_token_num_t cmd_flow_director_proto_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      proto_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_ttl =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 ttl, "ttl");
+cmdline_parse_token_num_t cmd_flow_director_ttl_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      ttl_value, UINT8);
 cmdline_parse_token_string_t cmd_flow_director_vlan =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 vlan, "vlan");
@@ -8413,6 +8452,12 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ip_src,
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_proto,
+		(void *)&cmd_flow_director_proto_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8445,6 +8490,10 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
 		(void *)&cmd_flow_director_port_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8479,6 +8528,10 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_port_dst,
 		(void *)&cmd_flow_director_verify_tag,
 		(void *)&cmd_flow_director_verify_tag_value,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -9405,16 +9458,19 @@ str2inset(char *string)
 		char str[32];
 		enum rte_eth_input_set_field inset;
 	} inset_table[] = {
+		{"ethertype", RTE_ETH_INPUT_SET_L2_ETHERTYPE},
 		{"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
 		{"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
 		{"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
 		{"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
 		{"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
 		{"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
+		{"ipv4-ttl", RTE_ETH_INPUT_SET_L3_IP4_TTL},
 		{"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
 		{"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
 		{"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
 		{"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
+		{"ipv6-hop-limits", RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS},
 		{"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
 		{"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
 		{"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
@@ -9473,7 +9529,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
 		flow_type,
-		"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
@@ -9492,8 +9548,8 @@ cmdline_parse_inst_t cmd_set_hash_input_set = {
 	.f = cmd_set_hash_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_hash_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
@@ -9548,15 +9604,16 @@ cmdline_parse_token_num_t cmd_set_fdir_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	flow_type,
-	"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+	"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 	"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#udp-src-port#udp-dst-port#"
+	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
+	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
-	"sctp-veri-tag#fld-1st#fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#"
-	"fld-7th#fld-8th#none");
+	"sctp-veri-tag#none");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	select, "select#add");
@@ -9565,12 +9622,13 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.f = cmd_set_fdir_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_fdir_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port|"
-	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|"
-	"fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
-	"fld-7th|fld-8th|none select|add",
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
+	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
+	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
+	"sctp-veri-tag|none select|add",
 	.tokens = {
 		(void *)&cmd_set_fdir_input_set_cmd,
 		(void *)&cmd_set_fdir_input_set_port_id,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index a520cc5..f59e63e 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1678,8 +1678,9 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 # Commands to add flow director filters of different flow types::
 
    flow_director_filter (port_id) mode IP (add|del|update) \
-                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)
+                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag) \
                         src (src_ip_address) dst (dst_ip_address) \
+                        tos (tos_value) proto (proto_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) pf|vf(vf_id) queue (queue_id) \
                         fd_id (fd_id_value)
@@ -1688,6 +1689,7 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp) \
                         src (src_ip_address) (src_port) \
                         dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) queue pf|vf(vf_id) (queue_id) \
                         fd_id (fd_id_value)
@@ -1695,7 +1697,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
    flow_director_filter (port_id) mode IP (add|del|update) \
                         flow (ipv4-sctp|ipv6-sctp) \
                         src (src_ip_address) (src_port) \
-                        dst (dst_ip_address) (dst_port)
+                        dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         tag (verification_tag) vlan (vlan_value) \
                         flexbytes (flexbytes_value) (drop|fwd) \
                         pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)
@@ -1719,12 +1722,14 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 For example, to add an ipv4-udp flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-udp src 2.2.2.3 32 \
-            dst 2.2.2.5 33 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+            dst 2.2.2.5 33 tos 2 ttl 40 vlan 0x1 flexbytes (0x88,0x48) \
+            fwd pf queue 1 fd_id 1
 
 For example, add an ipv4-other flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
-             dst 2.2.2.5 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+             dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 \
+             flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
 flush_flow_director
 ~~~~~~~~~~~~~~~~~~~
@@ -1841,33 +1846,36 @@ set_hash_input_set
 
 Set the input set for hash::
 
-   set_hash_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   set_hash_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
    l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port| \
    tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
    udp-key|gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th| \
    fld-8th|none) (select|add)
 
-For example, to add source IP to hash input set for flow type of ipv4 on port 0::
+For example, to add source IP to hash input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_hash_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_hash_input_set 0 ipv4-udp src-ipv4 add
 
 set_fdir_input_set
 ~~~~~~~~~~~~~~~~~~
 
-Set the input set for Fdir::
+The Flow Director filters can match the different fields for different type of packet, i.e. specific input set
+on per flow type and the flexible payload. This command can be used to change input set for each flow type.
 
-   set_fdir_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)
-   (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port| \
-   tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
-   fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|fld-8th|none) \
-   (select|add)
+Set the input set for flow director::
+
+   set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
+   tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
+   sctp-dst-port|sctp-veri-tag|none) (select|add)
 
-For example to add source IP to FD input set for flow type of ipv4 on port 0::
+For example to add source IP to FD input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_fdir_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_fdir_input_set 0 ipv4-udp src-ipv4 add
 
 global_config
 ~~~~~~~~~~~~~
-- 
2.4.0

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

* [PATCH v4 07/12] librte_ether: extend flow director struct
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
                           ` (5 preceding siblings ...)
  2016-03-10  3:25         ` [PATCH v4 06/12] testpmd: extend input set related commands Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-18 11:44           ` Thomas Monjalon
  2016-03-10  3:25         ` [PATCH v4 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
                           ` (5 subsequent siblings)
  12 siblings, 1 reply; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch changed rte_eth_fdir_flow from union to struct to
support more packets formats, for example, Vxlan and GRE tunnel
packets with IP inner frame.

This patch also add new RTE_FDIR_TUNNEL_TYPE_GRE enum.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 doc/guides/rel_notes/deprecation.rst   |  4 ----
 doc/guides/rel_notes/release_16_04.rst |  3 +++
 lib/librte_ether/rte_eth_ctrl.h        | 27 +++++++++++++++------------
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e94d4a2..7fa8639 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -20,10 +20,6 @@ Deprecation Notices
   tables (512 queues).
   It should be integrated in release 2.3.
 
-* ABI changes are planned for struct rte_eth_fdir_flow in order to support
-  extend flow director's input set. The release 2.2 does not contain these ABI
-  changes, but release 2.3 will, and no backwards compatibility is planned.
-
 * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow to
   include more fields to be matched against. The release 2.2 does not
   contain these ABI changes, but release 2.3 will.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 5abf48a..87ec402 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -238,6 +238,9 @@ ABI Changes
   the previous releases and made in this release. Use fixed width quotes for
   ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
 
+* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
+  changed. New fields were added to extend flow director's input set, and
+  organizing is also changed to support multiple input format.
 
 Shared Library Versions
 -----------------------
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index e2ac686..5b2a6ed 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -495,6 +495,7 @@ enum rte_eth_fdir_tunnel_type {
 	RTE_FDIR_TUNNEL_TYPE_UNKNOWN = 0,
 	RTE_FDIR_TUNNEL_TYPE_NVGRE,
 	RTE_FDIR_TUNNEL_TYPE_VXLAN,
+	RTE_FDIR_TUNNEL_TYPE_GRE,
 };
 
 /**
@@ -508,18 +509,20 @@ struct rte_eth_tunnel_flow {
 };
 
 /**
- * An union contains the inputs for all types of flow
+ * A struct contains the inputs for all types of flow
  */
-union rte_eth_fdir_flow {
-	struct rte_eth_l2_flow     l2_flow;
-	struct rte_eth_udpv4_flow  udp4_flow;
-	struct rte_eth_tcpv4_flow  tcp4_flow;
-	struct rte_eth_sctpv4_flow sctp4_flow;
-	struct rte_eth_ipv4_flow   ip4_flow;
-	struct rte_eth_udpv6_flow  udp6_flow;
-	struct rte_eth_tcpv6_flow  tcp6_flow;
-	struct rte_eth_sctpv6_flow sctp6_flow;
-	struct rte_eth_ipv6_flow   ipv6_flow;
+struct rte_eth_fdir_flow {
+	union {
+		struct rte_eth_l2_flow     l2_flow;
+		struct rte_eth_udpv4_flow  udp4_flow;
+		struct rte_eth_tcpv4_flow  tcp4_flow;
+		struct rte_eth_sctpv4_flow sctp4_flow;
+		struct rte_eth_ipv4_flow   ip4_flow;
+		struct rte_eth_udpv6_flow  udp6_flow;
+		struct rte_eth_tcpv6_flow  tcp6_flow;
+		struct rte_eth_sctpv6_flow sctp6_flow;
+		struct rte_eth_ipv6_flow   ipv6_flow;
+	};
 	struct rte_eth_mac_vlan_flow mac_vlan_flow;
 	struct rte_eth_tunnel_flow   tunnel_flow;
 };
@@ -540,7 +543,7 @@ struct rte_eth_fdir_flow_ext {
  */
 struct rte_eth_fdir_input {
 	uint16_t flow_type;
-	union rte_eth_fdir_flow flow;
+	struct rte_eth_fdir_flow flow;
 	/**< Flow fields to match, dependent on flow_type */
 	struct rte_eth_fdir_flow_ext flow_ext;
 	/**< Additional fields to match */
-- 
2.4.0

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

* [PATCH v4 08/12] i40e: extend flow director to filter by tunnel ID
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
                           ` (6 preceding siblings ...)
  2016-03-10  3:25         ` [PATCH v4 07/12] librte_ether: extend flow director struct Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 09/12] testpmd: extend flow director commands Jingjing Wu
                           ` (4 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended flow director to select Vxlan/GRE tunnel ID
as filter's input set and program the filter rule with the defined
tunnel type.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c |  11 +++
 drivers/net/i40e/i40e_fdir.c   | 150 +++++++++++++++++++++++++++++++----------
 2 files changed, 125 insertions(+), 36 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index e24b026..70a1c6c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6616,48 +6616,59 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
+		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index ebbe612..e4ac79d 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -688,12 +688,41 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 }
 
 static inline void
-i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
-			       unsigned char *raw_pkt)
+i40e_fdir_fill_ether_head(const struct rte_eth_fdir_input *fdir_input,
+			       unsigned char *pkt)
 {
-	struct ether_hdr *ether = (struct ether_hdr *)raw_pkt;
-	struct ipv4_hdr *ip;
-	struct ipv6_hdr *ip6;
+	struct ether_hdr *ether = (struct ether_hdr *)pkt;
+	switch (fdir_input->flow_type) {
+	case RTE_ETH_FLOW_L2_PAYLOAD:
+		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
+		break;
+	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
+	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
+	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
+	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+	case RTE_ETH_FLOW_FRAG_IPV4:
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		break;
+	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
+	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
+	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
+	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+	case RTE_ETH_FLOW_FRAG_IPV6:
+		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unknown flow type %u.",
+			    fdir_input->flow_type);
+		break;
+	}
+}
+
+static inline void
+i40e_fdir_fill_ip_head(const struct rte_eth_fdir_input *fdir_input,
+			       unsigned char *pkt)
+{
+	struct ipv4_hdr *ip = (struct ipv4_hdr *)pkt;
+	struct ipv6_hdr *ip6 = (struct ipv6_hdr *)pkt;
 	static const uint8_t next_proto[] = {
 		[RTE_ETH_FLOW_FRAG_IPV4] = IPPROTO_IP,
 		[RTE_ETH_FLOW_NONFRAG_IPV4_TCP] = IPPROTO_TCP,
@@ -708,17 +737,11 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 	};
 
 	switch (fdir_input->flow_type) {
-	case RTE_ETH_FLOW_L2_PAYLOAD:
-		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
-		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		ip = (struct ipv4_hdr *)(raw_pkt + sizeof(struct ether_hdr));
-
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
@@ -742,9 +765,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		ip6 = (struct ipv6_hdr *)(raw_pkt + sizeof(struct ether_hdr));
-
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
 			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
 					 (fdir_input->flow.ipv6_flow.tc <<
@@ -776,7 +796,7 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 	}
 }
 
-
+#define I40E_TUNNEL_KEY_LEN 4
 /*
  * i40e_fdir_construct_pkt - construct packet based on fields in input
  * @pf: board private structure
@@ -788,21 +808,86 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			     const struct rte_eth_fdir_input *fdir_input,
 			     unsigned char *raw_pkt)
 {
-	unsigned char *payload, *ptr;
+	unsigned char *payload, *ptr, *inner_pkt = raw_pkt;
 	struct udp_hdr *udp;
 	struct tcp_hdr *tcp;
 	struct sctp_hdr *sctp;
 	uint8_t size, dst = 0;
 	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
+	static uint8_t gre4_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x08, 0,
+			0, 0, 0, 0}; /* Mac+ IP + GRE hdr + key */
+	static uint8_t gre6_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x86, 0xDD,
+			0, 0, 0, 0}; /* Mac+ IP + GRE hdr + key */
+	static uint8_t vxlan_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x11,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			0x12, 0xB5, 0x12, 0xB5, 0x08, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0}; /* Mac + IP + UDP + VXLAN hdr */
+	static uint8_t nvgre_frame[] = {0x08, 0,
+			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x65, 0x58,
+			0, 0, 0, 0}; /*Mac + IP + NVGRE hdr*/
+
+	inner_pkt += 2 * sizeof(struct ether_addr);
+	/* fill the tunnel header if required */
+	switch (fdir_input->flow.tunnel_flow.tunnel_type) {
+	case RTE_FDIR_TUNNEL_TYPE_GRE:
+		if (fdir_input->flow_type == RTE_ETH_FLOW_L2_PAYLOAD) {
+			PMD_DRV_LOG(ERR, "GRE's inner pkt shouldn't"
+				    " be L2 frame.");
+			return -EINVAL;
+		}
+		if ((fdir_input->flow_type) == RTE_ETH_FLOW_FRAG_IPV4 ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_TCP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_UDP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_SCTP ||
+		    (fdir_input->flow_type) == RTE_ETH_FLOW_NONFRAG_IPV4_OTHER)
+			rte_memcpy(inner_pkt, gre4_frame, sizeof(gre4_frame));
+		else
+			rte_memcpy(inner_pkt, gre6_frame, sizeof(gre6_frame));
+		/* gre4_frame and gre6_frame have the same size */
+		inner_pkt += sizeof(gre4_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		break;
+	case RTE_FDIR_TUNNEL_TYPE_VXLAN:
+		rte_memcpy(inner_pkt, vxlan_frame, sizeof(vxlan_frame));
+		inner_pkt += sizeof(vxlan_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		/* fill the ethernet and IP head of inner frame */
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		inner_pkt += sizeof(struct ether_hdr);
+		break;
+	case RTE_FDIR_TUNNEL_TYPE_NVGRE:
+		rte_memcpy(inner_pkt, nvgre_frame, sizeof(nvgre_frame));
+		inner_pkt += sizeof(nvgre_frame);
+		rte_memcpy(inner_pkt - I40E_TUNNEL_KEY_LEN,
+			   &fdir_input->flow.tunnel_flow.tunnel_id,
+			   I40E_TUNNEL_KEY_LEN);
+		/* fill the Ether header of inner frame */
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		inner_pkt += sizeof(struct ether_hdr);
+		break;
+	default:
+		/* fill the Ether header of single frame */
+		i40e_fdir_fill_ether_head(fdir_input, raw_pkt);
+		inner_pkt = raw_pkt + sizeof(struct ether_hdr);
+		break;
+	}
 
-	/* fill the ethernet and IP head */
-	i40e_fdir_fill_eth_ip_head(fdir_input, raw_pkt);
-
+	/* fill the IP header of inner or single frame */
+	i40e_fdir_fill_ip_head(fdir_input, inner_pkt);
 	/* fill the L4 head */
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-				sizeof(struct ipv4_hdr));
+		udp = (struct udp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -815,8 +900,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv4_hdr));
+		tcp = (struct tcp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -829,8 +913,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv4_hdr));
+		sctp = (struct sctp_hdr *)(inner_pkt + sizeof(struct ipv4_hdr));
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -844,14 +927,12 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv4_hdr);
+		payload = inner_pkt + sizeof(struct ipv4_hdr);
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		udp = (struct udp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -864,8 +945,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		tcp = (struct tcp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -878,8 +958,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv6_hdr));
+		sctp = (struct sctp_hdr *)(inner_pkt + sizeof(struct ipv6_hdr));
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -893,12 +972,11 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv6_hdr);
+		payload = inner_pkt + sizeof(struct ipv6_hdr);
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		payload = raw_pkt + sizeof(struct ether_hdr);
+		payload = inner_pkt;
 		/*
 		 * ARP packet is a special case on which the payload
 		 * starts after the whole ARP header
-- 
2.4.0

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

* [PATCH v4 09/12] testpmd: extend flow director commands
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
                           ` (7 preceding siblings ...)
  2016-03-10  3:25         ` [PATCH v4 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 10/12] i40e: fix VLAN bitmasks for input set Jingjing Wu
                           ` (3 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended commands for filter's input set changing.
It added GRE/Vxlan Tunnel as filter's input fields.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 app/test-pmd/cmdline.c                      | 27 +++++++++++++++++++++------
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 22 ++++++++++++++++------
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 5787f57..9cba2cc 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -643,7 +643,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
 			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
-			" vlan (vlan_value) flexbytes (flexbytes_value)"
+			" vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel)"
+			" (tunnel_id_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
 			"    Add/Del an IP type flow director filter.\n\n"
@@ -653,7 +654,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
 			" tos (tos_value) ttl (ttl_value)"
-			" vlan (vlan_value) flexbytes (flexbytes_value)"
+			" vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel)"
+			" (tunnel_id_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
 			"    Add/Del an UDP/TCP type flow director filter.\n\n"
@@ -665,6 +667,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" tag (verification_tag) "
 			" tos (tos_value) ttl (ttl_value)"
 			" vlan (vlan_value)"
+			" (NVGRE|VxLAN|GRE|Notunnel) (tunnel_id_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -751,7 +754,8 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
 			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
 			"udp-dst-port|tcp-src-port|tcp-dst-port|"
-			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
+			"sctp-src-port|sctp-dst-port|sctp-veri-tag|"
+			"udp-key|gre-key|none)"
 			" (select|add)\n"
 			"    Set the input set for FDir.\n\n"
 		);
@@ -8094,6 +8098,7 @@ str2fdir_tunneltype(char *string)
 	} tunneltype_str[] = {
 		{"NVGRE", RTE_FDIR_TUNNEL_TYPE_NVGRE},
 		{"VxLAN", RTE_FDIR_TUNNEL_TYPE_VXLAN},
+		{"GRE",   RTE_FDIR_TUNNEL_TYPE_GRE},
 	};
 
 	for (i = 0; i < RTE_DIM(tunneltype_str); i++) {
@@ -8265,6 +8270,10 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 		   RTE_ETH_FDIR_MAX_FLEXLEN);
 
 	entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value);
+	entry.input.flow.tunnel_flow.tunnel_type =
+		str2fdir_tunneltype(res->tunnel_type);
+	entry.input.flow.tunnel_flow.tunnel_id =
+			rte_cpu_to_be_32(res->tunnel_id_value);
 
 	entry.action.flex_off = 0;  /*use 0 by default */
 	if (!strcmp(res->drop, "drop"))
@@ -8428,7 +8437,7 @@ cmdline_parse_token_string_t cmd_flow_director_tunnel =
 				 tunnel, "tunnel");
 cmdline_parse_token_string_t cmd_flow_director_tunnel_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
-				 tunnel_type, "NVGRE#VxLAN");
+				 tunnel_type, "NVGRE#VxLAN#GRE#Notunnel");
 cmdline_parse_token_string_t cmd_flow_director_tunnel_id =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 tunnel_id, "tunnel-id");
@@ -8460,6 +8469,8 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -8496,6 +8507,8 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -8534,6 +8547,8 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
+		(void *)&cmd_flow_director_tunnel_type,
+		(void *)&cmd_flow_director_tunnel_id_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -9613,7 +9628,7 @@ cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
 	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
-	"sctp-veri-tag#none");
+	"sctp-veri-tag#udp-key#gre-key#none");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	select, "select#add");
@@ -9628,7 +9643,7 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
 	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
 	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
-	"sctp-veri-tag|none select|add",
+	"sctp-veri-tag|udp-key|gre-key|none select|add",
 	.tokens = {
 		(void *)&cmd_set_fdir_input_set_cmd,
 		(void *)&cmd_set_fdir_input_set_port_id,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f59e63e..417ddde 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1681,7 +1681,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag) \
                         src (src_ip_address) dst (dst_ip_address) \
                         tos (tos_value) proto (proto_value) ttl (ttl_value) \
-                        vlan (vlan_value) flexbytes (flexbytes_value) \
+                        vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel) \
+                        (tunnel_id_value) flexbytes (flexbytes_value) \
                         (drop|fwd) pf|vf(vf_id) queue (queue_id) \
                         fd_id (fd_id_value)
 
@@ -1690,7 +1691,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         src (src_ip_address) (src_port) \
                         dst (dst_ip_address) (dst_port) \
                         tos (tos_value) ttl (ttl_value) \
-                        vlan (vlan_value) flexbytes (flexbytes_value) \
+                        vlan (vlan_value) (NVGRE|VxLAN|GRE|Notunnel) \
+                        (tunnel_id_value) flexbytes (flexbytes_value) \
                         (drop|fwd) queue pf|vf(vf_id) (queue_id) \
                         fd_id (fd_id_value)
 
@@ -1700,6 +1702,7 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         dst (dst_ip_address) (dst_port) \
                         tos (tos_value) ttl (ttl_value) \
                         tag (verification_tag) vlan (vlan_value) \
+                        (NVGRE|VxLAN|GRE|Notunnel) (tunnel_id_value) \
                         flexbytes (flexbytes_value) (drop|fwd) \
                         pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)
 
@@ -1722,15 +1725,21 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 For example, to add an ipv4-udp flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-udp src 2.2.2.3 32 \
-            dst 2.2.2.5 33 tos 2 ttl 40 vlan 0x1 flexbytes (0x88,0x48) \
-            fwd pf queue 1 fd_id 1
+            dst 2.2.2.5 33  tos 2 ttl 40 vlan 0x1 Notunnel 0 \
+            flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
 For example, add an ipv4-other flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
-             dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 \
+             dst 2.2.2.5  tos 2 proto 20 ttl 40 vlan 0x1 Notunnel 0 \
              flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
+For example, add a ipv4-other flow type filter with GRE key 0x0a0b0c0d:
+
+   testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
+            dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 GRE 0x0a0b0c0d \
+            flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+
 flush_flow_director
 ~~~~~~~~~~~~~~~~~~~
 
@@ -1861,6 +1870,7 @@ For example, to add source IP to hash input set for flow type of ipv4-udp on por
 set_fdir_input_set
 ~~~~~~~~~~~~~~~~~~
 
+
 The Flow Director filters can match the different fields for different type of packet, i.e. specific input set
 on per flow type and the flexible payload. This command can be used to change input set for each flow type.
 
@@ -1871,7 +1881,7 @@ Set the input set for flow director::
    l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
    tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
-   sctp-dst-port|sctp-veri-tag|none) (select|add)
+   sctp-dst-port|sctp-veri-tag|udp-key|gre-key|none) (select|add)
 
 For example to add source IP to FD input set for flow type of ipv4-udp on port 0::
 
-- 
2.4.0

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

* [PATCH v4 10/12] i40e: fix VLAN bitmasks for input set
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
                           ` (8 preceding siblings ...)
  2016-03-10  3:25         ` [PATCH v4 09/12] testpmd: extend flow director commands Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
                           ` (2 subsequent siblings)
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

From: Andrey Chilikin <andrey.chilikin@intel.com>

This patch adds missing VLAN bitmask for inner frame in case of
tunneling and fixes VLAN tags bitmasks for single or outer frame
in case of tunneling.

Fixes: 98f055707685 ("i40e: configure input fields for RSS or flow director")

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 70a1c6c..af87298 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -199,10 +199,12 @@
 #define I40E_REG_INSET_L2_DMAC                   0xE000000000000000ULL
 /* Source MAC address */
 #define I40E_REG_INSET_L2_SMAC                   0x1C00000000000000ULL
-/* VLAN tag in the outer L2 header */
-#define I40E_REG_INSET_L2_OUTER_VLAN             0x0080000000000000ULL
-/* VLAN tag in the inner L2 header */
-#define I40E_REG_INSET_L2_INNER_VLAN             0x0100000000000000ULL
+/* Outer (S-Tag) VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_OUTER_VLAN             0x0200000000000000ULL
+/* Inner (C-Tag) or single VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_INNER_VLAN             0x0080000000000000ULL
+/* Single VLAN tag in the inner L2 header */
+#define I40E_REG_INSET_TUNNEL_VLAN               0x0100000000000000ULL
 /* Source IPv4 address */
 #define I40E_REG_INSET_L3_SRC_IP4                0x0001800000000000ULL
 /* Destination IPv4 address */
@@ -6879,7 +6881,7 @@ i40e_translate_input_set_reg(uint64_t input)
 			I40E_REG_INSET_TUNNEL_L4_UDP_SRC_PORT},
 		{I40E_INSET_TUNNEL_DST_PORT,
 			I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT},
-		{I40E_INSET_TUNNEL_ID, I40E_REG_INSET_TUNNEL_ID},
+		{I40E_INSET_VLAN_TUNNEL, I40E_REG_INSET_TUNNEL_VLAN},
 		{I40E_INSET_FLEX_PAYLOAD_W1, I40E_REG_INSET_FLEX_PAYLOAD_WORD1},
 		{I40E_INSET_FLEX_PAYLOAD_W2, I40E_REG_INSET_FLEX_PAYLOAD_WORD2},
 		{I40E_INSET_FLEX_PAYLOAD_W3, I40E_REG_INSET_FLEX_PAYLOAD_WORD3},
-- 
2.4.0

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

* [PATCH v4 11/12] i40e: extend flow director to filter by vlan id
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
                           ` (9 preceding siblings ...)
  2016-03-10  3:25         ` [PATCH v4 10/12] i40e: fix VLAN bitmasks for input set Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-10  3:25         ` [PATCH v4 12/12] testpmd: extend flow director commands Jingjing Wu
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended flow director to select vlan id
as filter's input set and program the filter rule with vlan id.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst |  2 ++
 drivers/net/i40e/i40e_ethdev.c         | 11 ++++++++
 drivers/net/i40e/i40e_fdir.c           | 49 ++++++++++++++++++++++++++--------
 3 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 87ec402..e1e13ba 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -119,6 +119,8 @@ This section should contain new features added in this release. Sample format:
 
   Only available with Mellanox OFED >= 3.2.
 
+* **Added Flow director enhancements on Intel X710/XL710.**
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index af87298..39a7280 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6618,58 +6618,69 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_TUNNEL_ID |
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index e4ac79d..e905f9f 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -687,34 +687,50 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 	return ret;
 }
 
-static inline void
+static inline int
 i40e_fdir_fill_ether_head(const struct rte_eth_fdir_input *fdir_input,
-			       unsigned char *pkt)
+			       unsigned char *pkt, bool vlan)
 {
-	struct ether_hdr *ether = (struct ether_hdr *)pkt;
+	static uint8_t vlan_frame[] = {0x81, 0, 0, 0};
+	uint16_t *ether_type;
+	uint8_t len = 2 * sizeof(struct ether_addr);
+
+	pkt += 2 * sizeof(struct ether_addr);
+	if (vlan && fdir_input->flow_ext.vlan_tci) {
+		rte_memcpy(pkt, vlan_frame, sizeof(vlan_frame));
+		rte_memcpy(pkt + sizeof(uint16_t),
+			   &fdir_input->flow_ext.vlan_tci,
+			   sizeof(uint16_t));
+		pkt += sizeof(vlan_frame);
+		len += sizeof(vlan_frame);
+	}
+	ether_type = (uint16_t *)pkt;
+
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
+		*ether_type = fdir_input->flow.l2_flow.ether_type;
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		*ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		*ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
 			    fdir_input->flow_type);
-		break;
+		return -1;
 	}
+	len += sizeof(uint16_t);
+	return len;
 }
 
 static inline void
@@ -814,6 +830,8 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 	struct sctp_hdr *sctp;
 	uint8_t size, dst = 0;
 	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
+	int len;
+	static uint8_t vlan_frame[] = {0x81, 0, 0, 0};
 	static uint8_t gre4_frame[] = {0x08, 0,
 			0x45, 0, 0, 0x3A, 0, 0, 0, 0, 0x40, 0x2F,
 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0x08, 0,
@@ -833,6 +851,14 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			0, 0, 0, 0}; /*Mac + IP + NVGRE hdr*/
 
 	inner_pkt += 2 * sizeof(struct ether_addr);
+	if (fdir_input->flow_ext.vlan_tci) {
+		rte_memcpy(inner_pkt, vlan_frame, sizeof(vlan_frame));
+		rte_memcpy(inner_pkt + sizeof(uint16_t),
+			   &fdir_input->flow_ext.vlan_tci,
+			   sizeof(uint16_t));
+		inner_pkt += sizeof(vlan_frame);
+	}
+
 	/* fill the tunnel header if required */
 	switch (fdir_input->flow.tunnel_flow.tunnel_type) {
 	case RTE_FDIR_TUNNEL_TYPE_GRE:
@@ -862,7 +888,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			   &fdir_input->flow.tunnel_flow.tunnel_id,
 			   I40E_TUNNEL_KEY_LEN);
 		/* fill the ethernet and IP head of inner frame */
-		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt, FALSE);
 		inner_pkt += sizeof(struct ether_hdr);
 		break;
 	case RTE_FDIR_TUNNEL_TYPE_NVGRE:
@@ -872,13 +898,13 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 			   &fdir_input->flow.tunnel_flow.tunnel_id,
 			   I40E_TUNNEL_KEY_LEN);
 		/* fill the Ether header of inner frame */
-		i40e_fdir_fill_ether_head(fdir_input, inner_pkt);
+		i40e_fdir_fill_ether_head(fdir_input, inner_pkt, FALSE);
 		inner_pkt += sizeof(struct ether_hdr);
 		break;
 	default:
 		/* fill the Ether header of single frame */
-		i40e_fdir_fill_ether_head(fdir_input, raw_pkt);
-		inner_pkt = raw_pkt + sizeof(struct ether_hdr);
+		len = i40e_fdir_fill_ether_head(fdir_input, raw_pkt, TRUE);
+		inner_pkt = raw_pkt + len;
 		break;
 	}
 
@@ -1123,6 +1149,7 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
 		PMD_DRV_LOG(ERR, "construct packet for fdir fails.");
 		return ret;
 	}
+
 	pctype = i40e_flowtype_to_pctype(filter->input.flow_type);
 	ret = i40e_fdir_filter_programming(pf, pctype, filter, add);
 	if (ret < 0) {
-- 
2.4.0

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

* [PATCH v4 12/12] testpmd: extend flow director commands
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
                           ` (10 preceding siblings ...)
  2016-03-10  3:25         ` [PATCH v4 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
@ 2016-03-10  3:25         ` Jingjing Wu
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
  12 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-10  3:25 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev

This patch extended commands for filter's input set changing.
It added vlan as filter's input fields.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 app/test-pmd/cmdline.c                      | 6 +++---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 9cba2cc..6679a86 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -750,7 +750,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set_fdir_input_set (port_id) "
 			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|"
 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
 			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
 			"udp-dst-port|tcp-src-port|tcp-dst-port|"
@@ -9624,7 +9624,7 @@ cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ivlan#ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
 	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
 	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
@@ -9639,7 +9639,7 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.help_str = "set_fdir_input_set <port_id> "
 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
 	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
 	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
 	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 417ddde..aa20d5a 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1878,7 +1878,7 @@ Set the input set for flow director::
 
    set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
    ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
-   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
    tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
    sctp-dst-port|sctp-veri-tag|udp-key|gre-key|none) (select|add)
-- 
2.4.0

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

* Re: [PATCH v4 07/12] librte_ether: extend flow director struct
  2016-03-10  3:25         ` [PATCH v4 07/12] librte_ether: extend flow director struct Jingjing Wu
@ 2016-03-18 11:44           ` Thomas Monjalon
  2016-03-20  8:56             ` Wu, Jingjing
  2016-03-20  9:02             ` Wu, Jingjing
  0 siblings, 2 replies; 105+ messages in thread
From: Thomas Monjalon @ 2016-03-18 11:44 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev, bruce.richardson

Hi Jingjing,

2016-03-10 11:25, Jingjing Wu:
> This patch changed rte_eth_fdir_flow from union to struct to
> support more packets formats, for example, Vxlan and GRE tunnel
> packets with IP inner frame.

I think we need a lot more explanations about how it should work.
>From this point we should collect some acknowledgements from the
maintainers of other drivers having this kind of flow steering need.
Maybe that a better API, more generic, is possible.

> This patch also add new RTE_FDIR_TUNNEL_TYPE_GRE enum.

OK to add GRE to the existing API.

> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> Acked-by: Helin Zhang <helin.zhang@intel.com>
[...]
>  /**
> - * An union contains the inputs for all types of flow
> + * A struct contains the inputs for all types of flow
>   */
> -union rte_eth_fdir_flow {
> -	struct rte_eth_l2_flow     l2_flow;
> -	struct rte_eth_udpv4_flow  udp4_flow;
> -	struct rte_eth_tcpv4_flow  tcp4_flow;
> -	struct rte_eth_sctpv4_flow sctp4_flow;
> -	struct rte_eth_ipv4_flow   ip4_flow;
> -	struct rte_eth_udpv6_flow  udp6_flow;
> -	struct rte_eth_tcpv6_flow  tcp6_flow;
> -	struct rte_eth_sctpv6_flow sctp6_flow;
> -	struct rte_eth_ipv6_flow   ipv6_flow;
> +struct rte_eth_fdir_flow {
> +	union {
> +		struct rte_eth_l2_flow     l2_flow;
> +		struct rte_eth_udpv4_flow  udp4_flow;
> +		struct rte_eth_tcpv4_flow  tcp4_flow;
> +		struct rte_eth_sctpv4_flow sctp4_flow;
> +		struct rte_eth_ipv4_flow   ip4_flow;
> +		struct rte_eth_udpv6_flow  udp6_flow;
> +		struct rte_eth_tcpv6_flow  tcp6_flow;
> +		struct rte_eth_sctpv6_flow sctp6_flow;
> +		struct rte_eth_ipv6_flow   ipv6_flow;
> +	};
>  	struct rte_eth_mac_vlan_flow mac_vlan_flow;
>  	struct rte_eth_tunnel_flow   tunnel_flow;
>  };

Please explain somewhere how to use this API change in order to have more
discussions with other maintainers.

I'm sorry to comment this change only now. I took time to realize that
we need more consensus about the filtering API to make it usable by
more drivers.

For the 16.04 release, I suggest to remove this change from the series.
Thanks for your understanding.

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

* Re: [PATCH v4 07/12] librte_ether: extend flow director struct
  2016-03-18 11:44           ` Thomas Monjalon
@ 2016-03-20  8:56             ` Wu, Jingjing
  2016-03-20  9:02             ` Wu, Jingjing
  1 sibling, 0 replies; 105+ messages in thread
From: Wu, Jingjing @ 2016-03-20  8:56 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Richardson, Bruce

Hi, Thomas


> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Friday, March 18, 2016 7:44 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>
> Cc: dev@dpdk.org; Richardson, Bruce <bruce.richardson@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v4 07/12] librte_ether: extend flow director struct
> 
> Hi Jingjing,
> 
> 2016-03-10 11:25, Jingjing Wu:
> > This patch changed rte_eth_fdir_flow from union to struct to
> > support more packets formats, for example, Vxlan and GRE tunnel
> > packets with IP inner frame.
> 
> I think we need a lot more explanations about how it should work.
> From this point we should collect some acknowledgements from the
> maintainers of other drivers having this kind of flow steering need.
> Maybe that a better API, more generic, is possible.
> 
> > This patch also add new RTE_FDIR_TUNNEL_TYPE_GRE enum.
> 
> OK to add GRE to the existing API.
> 
> > Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> > Acked-by: Helin Zhang <helin.zhang@intel.com>
> [...]
> >  /**
> > - * An union contains the inputs for all types of flow
> > + * A struct contains the inputs for all types of flow
> >   */
> > -union rte_eth_fdir_flow {
> > -	struct rte_eth_l2_flow     l2_flow;
> > -	struct rte_eth_udpv4_flow  udp4_flow;
> > -	struct rte_eth_tcpv4_flow  tcp4_flow;
> > -	struct rte_eth_sctpv4_flow sctp4_flow;
> > -	struct rte_eth_ipv4_flow   ip4_flow;
> > -	struct rte_eth_udpv6_flow  udp6_flow;
> > -	struct rte_eth_tcpv6_flow  tcp6_flow;
> > -	struct rte_eth_sctpv6_flow sctp6_flow;
> > -	struct rte_eth_ipv6_flow   ipv6_flow;
> > +struct rte_eth_fdir_flow {
> > +	union {
> > +		struct rte_eth_l2_flow     l2_flow;
> > +		struct rte_eth_udpv4_flow  udp4_flow;
> > +		struct rte_eth_tcpv4_flow  tcp4_flow;
> > +		struct rte_eth_sctpv4_flow sctp4_flow;
> > +		struct rte_eth_ipv4_flow   ip4_flow;
> > +		struct rte_eth_udpv6_flow  udp6_flow;
> > +		struct rte_eth_tcpv6_flow  tcp6_flow;
> > +		struct rte_eth_sctpv6_flow sctp6_flow;
> > +		struct rte_eth_ipv6_flow   ipv6_flow;
> > +	};
> >  	struct rte_eth_mac_vlan_flow mac_vlan_flow;
> >  	struct rte_eth_tunnel_flow   tunnel_flow;
> >  };
> 
> Please explain somewhere how to use this API change in order to have more
> discussions with other maintainers.
> 
> I'm sorry to comment this change only now. I took time to realize that
> we need more consensus about the filtering API to make it usable by
> more drivers.
>

> For the 16.04 release, I suggest to remove this change from the series.
> Thanks for your understanding.
OK. Understand that we need to comments more on the change. And as you know, the whole patch set actually contains two changes on filter API: One the change is in this patch, which adds tunnel filtering using flow director, another one is the patch "[PATCH v4,05/12] i40e: extend flow director to filter by IP " (http://www.dpdk.org/dev/patchwork/patch/11358/ ). If you are OK to the latter one, I will send another version which just contains the change and drops tunnel supporting in 16.04 release.
And let's discuss more on the filtering API in future.

Thanks
Jingjing

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

* Re: [PATCH v4 07/12] librte_ether: extend flow director struct
  2016-03-18 11:44           ` Thomas Monjalon
  2016-03-20  8:56             ` Wu, Jingjing
@ 2016-03-20  9:02             ` Wu, Jingjing
  2016-03-20 10:38               ` Thomas Monjalon
  1 sibling, 1 reply; 105+ messages in thread
From: Wu, Jingjing @ 2016-03-20  9:02 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Richardson, Bruce



> -----Original Message-----
> From: Wu, Jingjing
> Sent: Sunday, March 20, 2016 4:57 PM
> To: 'Thomas Monjalon' <thomas.monjalon@6wind.com>
> Cc: dev@dpdk.org; Richardson, Bruce <bruce.richardson@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v4 07/12] librte_ether: extend flow director struct
> 
> Hi, Thomas
> 
> 
> > -----Original Message-----
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > Sent: Friday, March 18, 2016 7:44 PM
> > To: Wu, Jingjing <jingjing.wu@intel.com>
> > Cc: dev@dpdk.org; Richardson, Bruce <bruce.richardson@intel.com>
> > Subject: Re: [dpdk-dev] [PATCH v4 07/12] librte_ether: extend flow director struct
> >
> > Hi Jingjing,
> >
> > 2016-03-10 11:25, Jingjing Wu:
> > > This patch changed rte_eth_fdir_flow from union to struct to
> > > support more packets formats, for example, Vxlan and GRE tunnel
> > > packets with IP inner frame.
> >
> > I think we need a lot more explanations about how it should work.
> > From this point we should collect some acknowledgements from the
> > maintainers of other drivers having this kind of flow steering need.
> > Maybe that a better API, more generic, is possible.
> >
> > > This patch also add new RTE_FDIR_TUNNEL_TYPE_GRE enum.
> >
> > OK to add GRE to the existing API.
> >
> > > Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> > > Acked-by: Helin Zhang <helin.zhang@intel.com>
> > [...]
> > >  /**
> > > - * An union contains the inputs for all types of flow
> > > + * A struct contains the inputs for all types of flow
> > >   */
> > > -union rte_eth_fdir_flow {
> > > -	struct rte_eth_l2_flow     l2_flow;
> > > -	struct rte_eth_udpv4_flow  udp4_flow;
> > > -	struct rte_eth_tcpv4_flow  tcp4_flow;
> > > -	struct rte_eth_sctpv4_flow sctp4_flow;
> > > -	struct rte_eth_ipv4_flow   ip4_flow;
> > > -	struct rte_eth_udpv6_flow  udp6_flow;
> > > -	struct rte_eth_tcpv6_flow  tcp6_flow;
> > > -	struct rte_eth_sctpv6_flow sctp6_flow;
> > > -	struct rte_eth_ipv6_flow   ipv6_flow;
> > > +struct rte_eth_fdir_flow {
> > > +	union {
> > > +		struct rte_eth_l2_flow     l2_flow;
> > > +		struct rte_eth_udpv4_flow  udp4_flow;
> > > +		struct rte_eth_tcpv4_flow  tcp4_flow;
> > > +		struct rte_eth_sctpv4_flow sctp4_flow;
> > > +		struct rte_eth_ipv4_flow   ip4_flow;
> > > +		struct rte_eth_udpv6_flow  udp6_flow;
> > > +		struct rte_eth_tcpv6_flow  tcp6_flow;
> > > +		struct rte_eth_sctpv6_flow sctp6_flow;
> > > +		struct rte_eth_ipv6_flow   ipv6_flow;
> > > +	};
> > >  	struct rte_eth_mac_vlan_flow mac_vlan_flow;
> > >  	struct rte_eth_tunnel_flow   tunnel_flow;
> > >  };
> >
> > Please explain somewhere how to use this API change in order to have more
> > discussions with other maintainers.
> >
> > I'm sorry to comment this change only now. I took time to realize that
> > we need more consensus about the filtering API to make it usable by
> > more drivers.
> >
> 
> > For the 16.04 release, I suggest to remove this change from the series.
> > Thanks for your understanding.
> OK. Understand that we need to comments more on the change. And as you know, the
> whole patch set actually contains two changes on filter API: One the change is in this patch,
> which adds tunnel filtering using flow director, another one is the patch "[PATCH v4,05/12]
> i40e: extend flow director to filter by IP "
> (http://www.dpdk.org/dev/patchwork/patch/11358/ ). If you are OK to the latter one, I will
> send another version which just contains the change and drops tunnel supporting in 16.04
> release.
Correct the mistake:
The other change is "[v4,01/12] ethdev: extend flow director for input selection" http://www.dpdk.org/dev/patchwork/patch/11354/. 

> And let's discuss more on the filtering API in future.
> 
> Thanks
> Jingjing

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

* Re: [PATCH v4 07/12] librte_ether: extend flow director struct
  2016-03-20  9:02             ` Wu, Jingjing
@ 2016-03-20 10:38               ` Thomas Monjalon
  0 siblings, 0 replies; 105+ messages in thread
From: Thomas Monjalon @ 2016-03-20 10:38 UTC (permalink / raw)
  To: Wu, Jingjing; +Cc: dev, Richardson, Bruce

2016-03-20 09:02, Wu, Jingjing:
> From: Wu, Jingjing
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > 2016-03-10 11:25, Jingjing Wu:
> > > > This patch changed rte_eth_fdir_flow from union to struct to
> > > > support more packets formats, for example, Vxlan and GRE tunnel
> > > > packets with IP inner frame.
> > >
> > > I think we need a lot more explanations about how it should work.
> > > From this point we should collect some acknowledgements from the
> > > maintainers of other drivers having this kind of flow steering need.
> > > Maybe that a better API, more generic, is possible.
> > >
> > > > This patch also add new RTE_FDIR_TUNNEL_TYPE_GRE enum.
> > >
> > > OK to add GRE to the existing API.
> > >
> > > > Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> > > > Acked-by: Helin Zhang <helin.zhang@intel.com>
> > > [...]
> > > >  /**
> > > > - * An union contains the inputs for all types of flow
> > > > + * A struct contains the inputs for all types of flow
> > > >   */
> > > > -union rte_eth_fdir_flow {
> > > > -	struct rte_eth_l2_flow     l2_flow;
> > > > -	struct rte_eth_udpv4_flow  udp4_flow;
> > > > -	struct rte_eth_tcpv4_flow  tcp4_flow;
> > > > -	struct rte_eth_sctpv4_flow sctp4_flow;
> > > > -	struct rte_eth_ipv4_flow   ip4_flow;
> > > > -	struct rte_eth_udpv6_flow  udp6_flow;
> > > > -	struct rte_eth_tcpv6_flow  tcp6_flow;
> > > > -	struct rte_eth_sctpv6_flow sctp6_flow;
> > > > -	struct rte_eth_ipv6_flow   ipv6_flow;
> > > > +struct rte_eth_fdir_flow {
> > > > +	union {
> > > > +		struct rte_eth_l2_flow     l2_flow;
> > > > +		struct rte_eth_udpv4_flow  udp4_flow;
> > > > +		struct rte_eth_tcpv4_flow  tcp4_flow;
> > > > +		struct rte_eth_sctpv4_flow sctp4_flow;
> > > > +		struct rte_eth_ipv4_flow   ip4_flow;
> > > > +		struct rte_eth_udpv6_flow  udp6_flow;
> > > > +		struct rte_eth_tcpv6_flow  tcp6_flow;
> > > > +		struct rte_eth_sctpv6_flow sctp6_flow;
> > > > +		struct rte_eth_ipv6_flow   ipv6_flow;
> > > > +	};
> > > >  	struct rte_eth_mac_vlan_flow mac_vlan_flow;
> > > >  	struct rte_eth_tunnel_flow   tunnel_flow;
> > > >  };
> > >
> > > Please explain somewhere how to use this API change in order to have more
> > > discussions with other maintainers.
> > >
> > > I'm sorry to comment this change only now. I took time to realize that
> > > we need more consensus about the filtering API to make it usable by
> > > more drivers.
> > >
> > 
> > > For the 16.04 release, I suggest to remove this change from the series.
> > > Thanks for your understanding.
> > OK. Understand that we need to comments more on the change. And as you know, the
> > whole patch set actually contains two changes on filter API: One the change is in this patch,
> > which adds tunnel filtering using flow director, another one is the patch "[PATCH v4,05/12]
> > i40e: extend flow director to filter by IP "
> > (http://www.dpdk.org/dev/patchwork/patch/11358/ ). If you are OK to the latter one, I will
> > send another version which just contains the change and drops tunnel supporting in 16.04
> > release.
> Correct the mistake:
> The other change is "[v4,01/12] ethdev: extend flow director for input selection" http://www.dpdk.org/dev/patchwork/patch/11354/. 

I'm OK with patch 01 and "RTE_FDIR_TUNNEL_TYPE_GRE" add in patch 07.

> > And let's discuss more on the filtering API in future.

Thanks

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

* [PATCH v5 0/9] extend flow director fields in i40e driver
  2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
                           ` (11 preceding siblings ...)
  2016-03-10  3:25         ` [PATCH v4 12/12] testpmd: extend flow director commands Jingjing Wu
@ 2016-03-21  6:18         ` Jingjing Wu
  2016-03-21  6:18           ` [PATCH v5 1/9] ethdev: extend flow director for input selection Jingjing Wu
                             ` (10 more replies)
  12 siblings, 11 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

v5 changes:
 - remove the reorganizing of struct rte_eth_fdir_flow
 - remove fdir supporting on Tunnel Id
 - rebase to latest dpdk/master

v4 changes:
 - rebase to latest dpdk-next-net/rel_16_04.
 - comments on new fields in API structure.

v3 changes:
 - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
 - use AQ rx control register read/write for some registers
 - remove few useless lines
 - patch title rewording

v2 changes:
 - rebase on dpdk-next-net/rel_16_04
 - comments rewording.
 - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to
   avoid ABI breaking.
 - remove ABI announce in Deprecation.
 - fix the ethertype setting when program filter in v1 patch set.

This patch set extends flow director to support filtering by
additional fields below in i40e driver:
 - TOS, Protocol and TTL in IP header
 - single vlan or inner vlan 




Andrey Chilikin (1):
  i40e: fix VLAN bitmasks for input set

Jingjing Wu (8):
  ethdev: extend flow director for input selection
  i40e: split function for hash and fdir input
  i40e: remove flex payload from input selection
  i40e: restore default setting on input set
  i40e: extend flow director to filter by IP Header
  testpmd: extend input set related commands
  i40e: extend flow director to filter by vlan id
  testpmd: extend flow director commands

 app/test-pmd/cmdline.c                      | 100 +++++--
 doc/guides/rel_notes/deprecation.rst        |   4 -
 doc/guides/rel_notes/release_16_04.rst      |   4 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  42 +--
 drivers/net/i40e/i40e_ethdev.c              | 393 ++++++++++++++++------------
 drivers/net/i40e/i40e_ethdev.h              |  11 +-
 drivers/net/i40e/i40e_fdir.c                | 100 ++++---
 lib/librte_ether/rte_eth_ctrl.h             |   8 +
 8 files changed, 416 insertions(+), 246 deletions(-)

-- 
2.4.0

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

* [PATCH v5 1/9] ethdev: extend flow director for input selection
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
@ 2016-03-21  6:18           ` Jingjing Wu
  2016-03-22 22:05             ` Thomas Monjalon
  2016-03-21  6:18           ` [PATCH v5 2/9] i40e: split function for hash and fdir input Jingjing Wu
                             ` (9 subsequent siblings)
  10 siblings, 1 reply; 105+ messages in thread
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
by tos, protocol and ttl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 doc/guides/rel_notes/deprecation.rst   | 4 ----
 doc/guides/rel_notes/release_16_04.rst | 2 ++
 lib/librte_ether/rte_eth_ctrl.h        | 8 ++++++++
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 252a096..e7a7c7f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -22,10 +22,6 @@ Deprecation Notices
 * The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
   must be updated to support 100G link and to have a cleaner link speed API.
 
-* ABI changes are planned for struct rte_eth_fdir_flow in order to support
-  extend flow director's input set. The release 2.2 does not contain these ABI
-  changes, but release 2.3 will, and no backwards compatibility is planned.
-
 * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow to
   include more fields to be matched against. The release 2.2 does not
   contain these ABI changes, but release 2.3 will.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 2785b29..5803684 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -435,6 +435,8 @@ ABI Changes
 
 * The cmdline buffer size has been increase from 256 to 512.
 
+* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
+  changed. New fields were added to extend flow director's input set.
 
 Shared Library Versions
 -----------------------
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 6e2f617..aabd724 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -343,6 +343,8 @@ enum rte_eth_input_set_field {
 	RTE_ETH_INPUT_SET_L3_IP4_PROTO,
 	RTE_ETH_INPUT_SET_L3_IP6_TC,
 	RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
+	RTE_ETH_INPUT_SET_L3_IP4_TTL,
+	RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
 
 	/* L4 */
 	RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT = 257,
@@ -410,6 +412,9 @@ struct rte_eth_l2_flow {
 struct rte_eth_ipv4_flow {
 	uint32_t src_ip;      /**< IPv4 source address to match. */
 	uint32_t dst_ip;      /**< IPv4 destination address to match. */
+	uint8_t  tos;         /**< Type of service to match. */
+	uint8_t  ttl;         /**< Time to live to match. */
+	uint8_t  proto;       /**< Protocol, next header to match. */
 };
 
 /**
@@ -446,6 +451,9 @@ struct rte_eth_sctpv4_flow {
 struct rte_eth_ipv6_flow {
 	uint32_t src_ip[4];      /**< IPv6 source address to match. */
 	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
+	uint8_t  tc;             /**< Traffic class to match. */
+	uint8_t  proto;          /**< Protocol, next header to match. */
+	uint8_t  hop_limits;     /**< Hop limits to match. */
 };
 
 /**
-- 
2.4.0

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

* [PATCH v5 2/9] i40e: split function for hash and fdir input
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
  2016-03-21  6:18           ` [PATCH v5 1/9] ethdev: extend flow director for input selection Jingjing Wu
@ 2016-03-21  6:18           ` Jingjing Wu
  2016-03-21  6:18           ` [PATCH v5 3/9] i40e: remove flex payload from input selection Jingjing Wu
                             ` (8 subsequent siblings)
  10 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

This patch split function for input set changing of hash
and fdir to avoid multiple check on different situation.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 235 +++++++++++++++++------------------------
 drivers/net/i40e/i40e_ethdev.h |  11 +-
 drivers/net/i40e/i40e_fdir.c   |   5 +-
 3 files changed, 107 insertions(+), 144 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 10e0d38..faceb8b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -7056,25 +7056,6 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	return idx;
 }
 
-static uint64_t
-i40e_get_reg_inset(struct i40e_hw *hw, enum rte_filter_type filter,
-			    enum i40e_filter_pctype pctype)
-{
-	uint64_t reg = 0;
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
-	}
-
-	return reg;
-}
-
 static void
 i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 {
@@ -7087,105 +7068,96 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)i40e_read_rx_ctl(hw, addr));
 }
 
-static int
-i40e_set_hash_inset_mask(struct i40e_hw *hw,
-			 enum i40e_filter_pctype pctype,
-			 enum rte_filter_input_set_op op,
-			 uint32_t *mask_reg,
-			 uint8_t num)
+int
+i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			 struct rte_eth_input_set_conf *conf)
 {
-	uint32_t reg;
-	uint8_t i;
+	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	if (!conf) {
+		PMD_DRV_LOG(ERR, "Invalid pointer");
+		return -EFAULT;
+	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
 		return -EINVAL;
-
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = i40e_read_rx_ctl(hw,
-					       I40E_GLQF_HASH_MSK(i, pctype));
-			if (reg & I40E_GLQF_HASH_MSK_MASK_MASK)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
-
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[j]);
 	}
 
-	return 0;
-}
-
-static int
-i40e_set_fd_inset_mask(struct i40e_hw *hw,
-		       enum i40e_filter_pctype pctype,
-		       enum rte_filter_input_set_op op,
-		       uint32_t *mask_reg,
-		       uint8_t num)
-{
-	uint32_t reg;
-	uint8_t i;
+	pctype = i40e_flowtype_to_pctype(conf->flow_type);
+	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
+		PMD_DRV_LOG(ERR, "Not supported flow type (%u)",
+			    conf->flow_type);
+		return -EINVAL;
+	}
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
+				   conf->inset_size);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to parse input set");
+		return -EINVAL;
+	}
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
+				    input_set) != 0) {
+		PMD_DRV_LOG(ERR, "Invalid input set");
+		return -EINVAL;
+	}
+	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
+		/* get inset value in register */
+		inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
+		inset_reg <<= I40E_32_BIT_WIDTH;
+		inset_reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype));
+		input_set |= pf->hash_input_set[pctype];
+	}
+	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+					   I40E_INSET_MASK_NUM_REG);
+	if (num < 0)
 		return -EINVAL;
 
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = i40e_read_rx_ctl(hw,
-					       I40E_GLQF_FD_MSK(i, pctype));
-			if (reg & I40E_GLQF_FD_MSK_MASK_MASK)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[j]);
-	}
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     0);
+	I40E_WRITE_FLUSH(hw);
 
+	pf->hash_input_set[pctype] = input_set;
 	return 0;
 }
 
 int
-i40e_filter_inset_select(struct i40e_hw *hw,
-			 struct rte_eth_input_set_conf *conf,
-			 enum rte_filter_type filter)
+i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			 struct rte_eth_input_set_conf *conf)
 {
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	enum i40e_filter_pctype pctype;
-	uint64_t inset_reg = 0, input_set;
-	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG];
-	uint8_t num;
-	int ret;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
 	if (!hw || !conf) {
 		PMD_DRV_LOG(ERR, "Invalid pointer");
 		return -EFAULT;
 	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
+		return -EINVAL;
+	}
 
 	pctype = i40e_flowtype_to_pctype(conf->flow_type);
 	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
@@ -7193,60 +7165,48 @@ i40e_filter_inset_select(struct i40e_hw *hw,
 			    conf->flow_type);
 		return -EINVAL;
 	}
-	if (filter != RTE_ETH_FILTER_HASH && filter != RTE_ETH_FILTER_FDIR) {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
-
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, filter, input_set) != 0) {
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
+				    input_set) != 0) {
 		PMD_DRV_LOG(ERR, "Invalid input set");
 		return -EINVAL;
 	}
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
-		inset_reg |= i40e_get_reg_inset(hw, filter, pctype);
-	} else if (conf->op != RTE_ETH_INPUT_SET_SELECT) {
-		PMD_DRV_LOG(ERR, "Unsupported input set operation");
-		return -EINVAL;
-	}
+	/* get inset value in register */
+	inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
+	inset_reg <<= I40E_32_BIT_WIDTH;
+	inset_reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
+
+	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-	inset_reg |= i40e_translate_input_set_reg(input_set);
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		ret = i40e_set_hash_inset_mask(hw, pctype, conf->op, mask_reg,
-					       num);
-		if (ret)
-			return -EINVAL;
+	if (num < 0)
+		return -EINVAL;
 
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		ret = i40e_set_fd_inset_mask(hw, pctype, conf->op, mask_reg,
-					     num);
-		if (ret)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     0);
 	I40E_WRITE_FLUSH(hw);
 
+	pf->fdir.input_set[pctype] = input_set;
 	return 0;
 }
 
@@ -7298,9 +7258,8 @@ i40e_hash_filter_set(struct i40e_hw *hw, struct rte_eth_hash_filter_info *info)
 				&(info->info.global_conf));
 		break;
 	case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-					       &(info->info.input_set_conf),
-					       RTE_ETH_FILTER_HASH);
+		ret = i40e_hash_filter_inset_select(hw,
+					       &(info->info.input_set_conf));
 		break;
 
 	default:
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 1c75672..1d49835 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -367,6 +367,8 @@ struct i40e_fdir_info {
 	struct i40e_rx_queue *rxq;
 	void *prg_pkt;                 /* memory for fdir program packet */
 	uint64_t dma_addr;             /* physic address of packet memory*/
+	/* input set bits for each pctype */
+	uint64_t input_set[I40E_FILTER_PCTYPE_MAX];
 	/*
 	 * the rule how bytes stream is extracted as flexible payload
 	 * for each payload layer, the setting can up to three elements
@@ -433,6 +435,8 @@ struct i40e_pf {
 	uint16_t fdir_qp_offset;
 
 	uint16_t hash_lut_size; /* The size of hash lookup table */
+	/* input set bits for each pctype */
+	uint64_t hash_input_set[I40E_FILTER_PCTYPE_MAX];
 	/* store VXLAN UDP ports */
 	uint16_t vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];
 	uint16_t vxlan_bitmap; /* Vxlan bit mask */
@@ -576,9 +580,10 @@ int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 int i40e_select_filter_input_set(struct i40e_hw *hw,
 				 struct rte_eth_input_set_conf *conf,
 				 enum rte_filter_type filter);
-int i40e_filter_inset_select(struct i40e_hw *hw,
-			     struct rte_eth_input_set_conf *conf,
-			     enum rte_filter_type filter);
+int i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			     struct rte_eth_input_set_conf *conf);
+int i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			     struct rte_eth_input_set_conf *conf);
 
 void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct rte_eth_rxq_info *qinfo);
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 14c51ce..f8055e7 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -1362,7 +1362,6 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 		     struct rte_eth_fdir_filter_info *info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	int ret = 0;
 
 	if (!info) {
@@ -1372,8 +1371,8 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 
 	switch (info->info_type) {
 	case RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-			&(info->info.input_set_conf), RTE_ETH_FILTER_FDIR);
+		ret = i40e_fdir_filter_inset_select(pf,
+				&(info->info.input_set_conf));
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "FD filter info type (%d) not supported",
-- 
2.4.0

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

* [PATCH v5 3/9] i40e: remove flex payload from input selection
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
  2016-03-21  6:18           ` [PATCH v5 1/9] ethdev: extend flow director for input selection Jingjing Wu
  2016-03-21  6:18           ` [PATCH v5 2/9] i40e: split function for hash and fdir input Jingjing Wu
@ 2016-03-21  6:18           ` Jingjing Wu
  2016-03-21  6:18           ` [PATCH v5 4/9] i40e: restore default setting on input set Jingjing Wu
                             ` (7 subsequent siblings)
  10 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

In this patch, flex payload is removed from valid fdir input set
values. It is because all flex payload configuration can be set
in struct rte_fdir_conf during device configure phase.
And it is a more flexible configuration including flexpayload's
selection, input set selection by word and mask setting in bits.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 59 +++++++++++++++++++-----------------------
 1 file changed, 26 insertions(+), 33 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index faceb8b..158910b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -254,7 +254,8 @@
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD7        0x0000000000000080ULL
 /* 8th word of flex payload */
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD8        0x0000000000000040ULL
-
+/* all 8 words flex payload */
+#define I40E_REG_INSET_FLEX_PAYLOAD_WORDS        0x0000000000003FC0ULL
 #define I40E_REG_INSET_MASK_DEFAULT              0x0000000000000000ULL
 
 #define I40E_TRANSLATE_INSET 0
@@ -6756,43 +6757,32 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
-		I40E_INSET_LAST_ETHER_TYPE | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
 	if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD)
@@ -7020,7 +7010,7 @@ i40e_translate_input_set_reg(uint64_t input)
 	return val;
 }
 
-static uint8_t
+static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
@@ -7038,16 +7028,13 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-	if (!inset && nb_elem >= I40E_INSET_MASK_NUM_REG) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++)
-			mask[i] = 0;
-		return I40E_INSET_MASK_NUM_REG;
-	}
 
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if (idx >= nb_elem)
-			break;
-		if (inset & inset_mask_map[i].inset) {
+		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+			if (idx >= nb_elem) {
+				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
+				return -EINVAL;
+			}
 			mask[idx] = inset_mask_map[i].mask;
 			idx++;
 		}
@@ -7182,7 +7169,13 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 	inset_reg <<= I40E_32_BIT_WIDTH;
 	inset_reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+	/* Can not change the inset reg for flex payload for fdir,
+	 * it is done by writing I40E_PRTQF_FD_FLXINSET
+	 * in i40e_set_flex_mask_on_pctype.
+	 */
+	if (conf->op == RTE_ETH_INPUT_SET_SELECT)
+		inset_reg &= I40E_REG_INSET_FLEX_PAYLOAD_WORDS;
+	else
 		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-- 
2.4.0

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

* [PATCH v5 4/9] i40e: restore default setting on input set
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
                             ` (2 preceding siblings ...)
  2016-03-21  6:18           ` [PATCH v5 3/9] i40e: remove flex payload from input selection Jingjing Wu
@ 2016-03-21  6:18           ` Jingjing Wu
  2016-03-21  6:18           ` [PATCH v5 5/9] i40e: extend flow director to filter by IP Header Jingjing Wu
                             ` (6 subsequent siblings)
  10 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

This patch added a new function to set the input set to default
when initialization.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 57 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 158910b..4cd9853 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -384,6 +384,7 @@ static int i40e_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
 					struct rte_eth_udp_tunnel *udp_tunnel);
 static int i40e_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
 					struct rte_eth_udp_tunnel *udp_tunnel);
+static void i40e_filter_input_set_init(struct i40e_pf *pf);
 static int i40e_ethertype_filter_set(struct i40e_pf *pf,
 			struct rte_eth_ethertype_filter *filter,
 			bool add);
@@ -816,6 +817,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	 */
 	i40e_flex_payload_reg_init(hw);
 
+	/* Initialize the input set for filters (hash and fd) to default value */
+	i40e_filter_input_set_init(pf);
+
 	/* Initialize the parameters for adminq */
 	i40e_init_adminq_parameter(hw);
 	ret = i40e_init_adminq(hw);
@@ -7055,6 +7059,59 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)i40e_read_rx_ctl(hw, addr));
 }
 
+static void
+i40e_filter_input_set_init(struct i40e_pf *pf)
+{
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int num, i;
+
+	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
+		if (!I40E_VALID_PCTYPE(pctype))
+			continue;
+		input_set = i40e_get_default_input_set(pctype);
+
+		num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+						   I40E_INSET_MASK_NUM_REG);
+		if (num < 0)
+			return;
+		inset_reg = i40e_translate_input_set_reg(input_set);
+
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+		for (i = 0; i < num; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     mask_reg[i]);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     mask_reg[i]);
+		}
+		/*clear unused mask registers of the pctype */
+		for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     0);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     0);
+		}
+		I40E_WRITE_FLUSH(hw);
+
+		/* store the default input set */
+		pf->hash_input_set[pctype] = input_set;
+		pf->fdir.input_set[pctype] = input_set;
+	}
+}
+
 int
 i40e_hash_filter_inset_select(struct i40e_hw *hw,
 			 struct rte_eth_input_set_conf *conf)
-- 
2.4.0

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

* [PATCH v5 5/9] i40e: extend flow director to filter by IP Header
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
                             ` (3 preceding siblings ...)
  2016-03-21  6:18           ` [PATCH v5 4/9] i40e: restore default setting on input set Jingjing Wu
@ 2016-03-21  6:18           ` Jingjing Wu
  2016-03-21  6:18           ` [PATCH v5 6/9] testpmd: extend input set related commands Jingjing Wu
                             ` (5 subsequent siblings)
  10 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

This patch extended flow director to select more IP Header fields
as filter input set.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 69 ++++++++++++++++++++++++++++++++++--------
 drivers/net/i40e/i40e_fdir.c   | 26 +++++++++++-----
 2 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 4cd9853..462d0d3 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -210,6 +210,8 @@
 #define I40E_REG_INSET_L3_IP4_TOS                0x0040000000000000ULL
 /* IPv4 Protocol */
 #define I40E_REG_INSET_L3_IP4_PROTO              0x0004000000000000ULL
+/* IPv4 Time to Live */
+#define I40E_REG_INSET_L3_IP4_TTL                0x0004000000000000ULL
 /* Source IPv6 address */
 #define I40E_REG_INSET_L3_SRC_IP6                0x0007F80000000000ULL
 /* Destination IPv6 address */
@@ -218,6 +220,8 @@
 #define I40E_REG_INSET_L3_IP6_TC                 0x0040000000000000ULL
 /* IPv6 Next Header */
 #define I40E_REG_INSET_L3_IP6_NEXT_HDR           0x0008000000000000ULL
+/* IPv6 Hop Limit */
+#define I40E_REG_INSET_L3_IP6_HOP_LIMIT          0x0008000000000000ULL
 /* Source L4 port */
 #define I40E_REG_INSET_L4_SRC_PORT               0x0000000400000000ULL
 /* Destination L4 port */
@@ -261,10 +265,12 @@
 #define I40E_TRANSLATE_INSET 0
 #define I40E_TRANSLATE_REG   1
 
-#define I40E_INSET_IPV4_TOS_MASK      0x0009FF00UL
-#define I40E_INSET_IPV4_PROTO_MASK    0x000DFF00UL
-#define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
-#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
+#define I40E_INSET_IPV4_TOS_MASK        0x0009FF00UL
+#define I40E_INSET_IPv4_TTL_MASK        0x000D00FFUL
+#define I40E_INSET_IPV4_PROTO_MASK      0x000DFF00UL
+#define I40E_INSET_IPV6_TC_MASK         0x0009F00FUL
+#define I40E_INSET_IPV6_HOP_LIMIT_MASK  0x000CFF00UL
+#define I40E_INSET_IPV6_NEXT_HDR_MASK   0x000C00FFUL
 
 #define I40E_GL_SWT_L2TAGCTRL(_i)             (0x001C0A70 + ((_i) * 4))
 #define I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT 16
@@ -6761,30 +6767,47 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
@@ -6884,11 +6907,14 @@ i40e_parse_input_set(uint64_t *inset,
 		{RTE_ETH_INPUT_SET_L3_DST_IP4, I40E_INSET_IPV4_DST},
 		{RTE_ETH_INPUT_SET_L3_IP4_TOS, I40E_INSET_IPV4_TOS},
 		{RTE_ETH_INPUT_SET_L3_IP4_PROTO, I40E_INSET_IPV4_PROTO},
+		{RTE_ETH_INPUT_SET_L3_IP4_TTL, I40E_INSET_IPV4_TTL},
 		{RTE_ETH_INPUT_SET_L3_SRC_IP6, I40E_INSET_IPV6_SRC},
 		{RTE_ETH_INPUT_SET_L3_DST_IP6, I40E_INSET_IPV6_DST},
 		{RTE_ETH_INPUT_SET_L3_IP6_TC, I40E_INSET_IPV6_TC},
 		{RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
 			I40E_INSET_IPV6_NEXT_HDR},
+		{RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
+			I40E_INSET_IPV6_HOP_LIMIT},
 		{RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT, I40E_INSET_SRC_PORT},
@@ -6975,10 +7001,12 @@ i40e_translate_input_set_reg(uint64_t input)
 		{I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4},
 		{I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS},
 		{I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO},
+		{I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL},
 		{I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6},
 		{I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6},
 		{I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_REG_INSET_L3_IP6_NEXT_HDR},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_REG_INSET_L3_IP6_HOP_LIMIT},
 		{I40E_INSET_SRC_PORT, I40E_REG_INSET_L4_SRC_PORT},
 		{I40E_INSET_DST_PORT, I40E_REG_INSET_L4_DST_PORT},
 		{I40E_INSET_SCTP_VT, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG},
@@ -7018,23 +7046,38 @@ static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
+	uint64_t inset_need_mask = inset;
 
 	static const struct {
 		uint64_t inset;
 		uint32_t mask;
 	} inset_mask_map[] = {
 		{I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK},
+		{I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0},
 		{I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK},
+		{I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK},
 		{I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK},
+		{I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK},
 	};
 
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+		/* Clear the inset bit, if no MASK is required,
+		 * for example proto + ttl
+		 */
+		if ((inset & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset && inset_mask_map[i].mask == 0)
+			inset_need_mask &= ~inset_mask_map[i].inset;
+		if (!inset_need_mask)
+			return 0;
+	}
+	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
+		if ((inset_need_mask & inset_mask_map[i].inset) ==
+		    inset_mask_map[i].inset) {
 			if (idx >= nb_elem) {
 				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
 				return -EINVAL;
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index f8055e7..ebbe612 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -66,7 +66,9 @@
 #define I40E_FDIR_IP_DEFAULT_TTL            0x40
 #define I40E_FDIR_IP_DEFAULT_VERSION_IHL    0x45
 #define I40E_FDIR_TCP_DEFAULT_DATAOFF       0x50
-#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60300000
+#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60000000
+#define I40E_FDIR_IPv6_TC_OFFSET            20
+
 #define I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS   0xFF
 #define I40E_FDIR_IPv6_PAYLOAD_LEN          380
 #define I40E_FDIR_UDP_DEFAULT_LEN           400
@@ -720,7 +722,13 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
-		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+		ip->next_proto_id = fdir_input->flow.ip4_flow.proto ?
+					fdir_input->flow.ip4_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip->time_to_live = fdir_input->flow.ip4_flow.ttl ?
+					fdir_input->flow.ip4_flow.ttl :
+					I40E_FDIR_IP_DEFAULT_TTL;
+		ip->type_of_service = fdir_input->flow.ip4_flow.tos;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -728,7 +736,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		 */
 		ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
 		ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
-		ip->next_proto_id = next_proto[fdir_input->flow_type];
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
@@ -739,11 +746,17 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 
 		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
-			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
+					 (fdir_input->flow.ipv6_flow.tc <<
+					  I40E_FDIR_IPv6_TC_OFFSET));
 		ip6->payload_len =
 			rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
-		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
-
+		ip6->proto = fdir_input->flow.ipv6_flow.proto ?
+					fdir_input->flow.ipv6_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ?
+					fdir_input->flow.ipv6_flow.hop_limits :
+					I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -755,7 +768,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		rte_memcpy(&(ip6->dst_addr),
 			   &(fdir_input->flow.ipv6_flow.src_ip),
 			   IPV6_ADDR_LEN);
-		ip6->proto = next_proto[fdir_input->flow_type];
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
-- 
2.4.0

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

* [PATCH v5 6/9] testpmd: extend input set related commands
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
                             ` (4 preceding siblings ...)
  2016-03-21  6:18           ` [PATCH v5 5/9] i40e: extend flow director to filter by IP Header Jingjing Wu
@ 2016-03-21  6:18           ` Jingjing Wu
  2016-03-21  6:18           ` [PATCH v5 7/9] i40e: fix VLAN bitmasks for input set Jingjing Wu
                             ` (4 subsequent siblings)
  10 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

This patch extended commands for filter's input set changing.
It added tos, protocol and ttl as filter's input fields, and
remove the words selection from flex payloads for flow director.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 app/test-pmd/cmdline.c                      | 100 ++++++++++++++++++++++------
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  42 +++++++-----
 2 files changed, 104 insertions(+), 38 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 9d52b8c..6d1b9f0 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -669,6 +669,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"flow_director_filter (port_id) mode IP (add|del|update)"
 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
+			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -678,6 +679,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
+			" tos (tos_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -687,7 +689,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-sctp|ipv6-sctp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
-			" tag (verification_tag) vlan (vlan_value)"
+			" tag (verification_tag) "
+			" tos (tos_value) ttl (ttl_value)"
+			" vlan (vlan_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -767,14 +771,15 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"fld-8th|none) (select|add)\n"
 			"    Set the input set for hash.\n\n"
 
-			"set_fdir_input_set (port_id) (ipv4|ipv4-frag|"
-			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+			"set_fdir_input_set (port_id) "
+			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
-			"udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|"
-			"sctp-src-port|sctp-dst-port|sctp-veri-tag|fld-1st|"
-			"fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
-			"fld-8th|none) (select|add)\n"
+			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
+			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
+			"udp-dst-port|tcp-src-port|tcp-dst-port|"
+			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
+			" (select|add)\n"
 			"    Set the input set for FDir.\n\n"
 		);
 	}
@@ -8027,6 +8032,12 @@ struct cmd_flow_director_result {
 	uint16_t port_dst;
 	cmdline_fixed_string_t verify_tag;
 	uint32_t verify_tag_value;
+	cmdline_ipaddr_t tos;
+	uint8_t tos_value;
+	cmdline_ipaddr_t proto;
+	uint8_t proto_value;
+	cmdline_ipaddr_t ttl;
+	uint8_t ttl_value;
 	cmdline_fixed_string_t vlan;
 	uint16_t vlan_value;
 	cmdline_fixed_string_t flexbytes;
@@ -8206,12 +8217,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 	switch (entry.input.flow_type) {
 	case RTE_ETH_FLOW_FRAG_IPV4:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+		entry.input.flow.ip4_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 		IPV4_ADDR_TO_UINT(res->ip_dst,
 			entry.input.flow.ip4_flow.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.ip4_flow.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8223,6 +8237,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp4_flow.ip.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.sctp4_flow.ip.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8233,12 +8249,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 		break;
 	case RTE_ETH_FLOW_FRAG_IPV6:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+		entry.input.flow.ipv6_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 		IPV6_ADDR_TO_ARRAY(res->ip_dst,
 			entry.input.flow.ipv6_flow.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.ipv6_flow.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8250,6 +8269,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp6_flow.ip.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.sctp6_flow.ip.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8377,6 +8398,24 @@ cmdline_parse_token_string_t cmd_flow_director_verify_tag =
 cmdline_parse_token_num_t cmd_flow_director_verify_tag_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
 			      verify_tag_value, UINT32);
+cmdline_parse_token_string_t cmd_flow_director_tos =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 tos, "tos");
+cmdline_parse_token_num_t cmd_flow_director_tos_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      tos_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_proto =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 proto, "proto");
+cmdline_parse_token_num_t cmd_flow_director_proto_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      proto_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_ttl =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 ttl, "ttl");
+cmdline_parse_token_num_t cmd_flow_director_ttl_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      ttl_value, UINT8);
 cmdline_parse_token_string_t cmd_flow_director_vlan =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 vlan, "vlan");
@@ -8455,6 +8494,12 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ip_src,
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_proto,
+		(void *)&cmd_flow_director_proto_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8487,6 +8532,10 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
 		(void *)&cmd_flow_director_port_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8521,6 +8570,10 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_port_dst,
 		(void *)&cmd_flow_director_verify_tag,
 		(void *)&cmd_flow_director_verify_tag_value,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -9447,16 +9500,19 @@ str2inset(char *string)
 		char str[32];
 		enum rte_eth_input_set_field inset;
 	} inset_table[] = {
+		{"ethertype", RTE_ETH_INPUT_SET_L2_ETHERTYPE},
 		{"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
 		{"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
 		{"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
 		{"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
 		{"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
 		{"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
+		{"ipv4-ttl", RTE_ETH_INPUT_SET_L3_IP4_TTL},
 		{"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
 		{"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
 		{"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
 		{"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
+		{"ipv6-hop-limits", RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS},
 		{"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
 		{"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
 		{"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
@@ -9515,7 +9571,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
 		flow_type,
-		"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
@@ -9534,8 +9590,8 @@ cmdline_parse_inst_t cmd_set_hash_input_set = {
 	.f = cmd_set_hash_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_hash_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
@@ -9590,15 +9646,16 @@ cmdline_parse_token_num_t cmd_set_fdir_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	flow_type,
-	"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+	"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 	"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#udp-src-port#udp-dst-port#"
+	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
+	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
-	"sctp-veri-tag#fld-1st#fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#"
-	"fld-7th#fld-8th#none");
+	"sctp-veri-tag#none");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	select, "select#add");
@@ -9607,12 +9664,13 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.f = cmd_set_fdir_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_fdir_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port|"
-	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|"
-	"fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
-	"fld-7th|fld-8th|none select|add",
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
+	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
+	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
+	"sctp-veri-tag|none select|add",
 	.tokens = {
 		(void *)&cmd_set_fdir_input_set_cmd,
 		(void *)&cmd_set_fdir_input_set_port_id,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index efaf2b5..52a4f11 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1739,8 +1739,9 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 # Commands to add flow director filters of different flow types::
 
    flow_director_filter (port_id) mode IP (add|del|update) \
-                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)
+                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag) \
                         src (src_ip_address) dst (dst_ip_address) \
+                        tos (tos_value) proto (proto_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) pf|vf(vf_id) queue (queue_id) \
                         fd_id (fd_id_value)
@@ -1749,6 +1750,7 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp) \
                         src (src_ip_address) (src_port) \
                         dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) queue pf|vf(vf_id) (queue_id) \
                         fd_id (fd_id_value)
@@ -1756,7 +1758,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
    flow_director_filter (port_id) mode IP (add|del|update) \
                         flow (ipv4-sctp|ipv6-sctp) \
                         src (src_ip_address) (src_port) \
-                        dst (dst_ip_address) (dst_port)
+                        dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         tag (verification_tag) vlan (vlan_value) \
                         flexbytes (flexbytes_value) (drop|fwd) \
                         pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)
@@ -1780,12 +1783,14 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 For example, to add an ipv4-udp flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-udp src 2.2.2.3 32 \
-            dst 2.2.2.5 33 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+            dst 2.2.2.5 33 tos 2 ttl 40 vlan 0x1 flexbytes (0x88,0x48) \
+            fwd pf queue 1 fd_id 1
 
 For example, add an ipv4-other flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
-             dst 2.2.2.5 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+             dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 \
+             flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
 flush_flow_director
 ~~~~~~~~~~~~~~~~~~~
@@ -1902,33 +1907,36 @@ set_hash_input_set
 
 Set the input set for hash::
 
-   set_hash_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   set_hash_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
    l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port| \
    tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
    udp-key|gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th| \
    fld-8th|none) (select|add)
 
-For example, to add source IP to hash input set for flow type of ipv4 on port 0::
+For example, to add source IP to hash input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_hash_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_hash_input_set 0 ipv4-udp src-ipv4 add
 
 set_fdir_input_set
 ~~~~~~~~~~~~~~~~~~
 
-Set the input set for Fdir::
+The Flow Director filters can match the different fields for different type of packet, i.e. specific input set
+on per flow type and the flexible payload. This command can be used to change input set for each flow type.
 
-   set_fdir_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)
-   (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port| \
-   tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
-   fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|fld-8th|none) \
-   (select|add)
+Set the input set for flow director::
+
+   set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
+   tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
+   sctp-dst-port|sctp-veri-tag|none) (select|add)
 
-For example to add source IP to FD input set for flow type of ipv4 on port 0::
+For example to add source IP to FD input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_fdir_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_fdir_input_set 0 ipv4-udp src-ipv4 add
 
 global_config
 ~~~~~~~~~~~~~
-- 
2.4.0

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

* [PATCH v5 7/9] i40e: fix VLAN bitmasks for input set
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
                             ` (5 preceding siblings ...)
  2016-03-21  6:18           ` [PATCH v5 6/9] testpmd: extend input set related commands Jingjing Wu
@ 2016-03-21  6:18           ` Jingjing Wu
  2016-03-21  6:18           ` [PATCH v5 8/9] i40e: extend flow director to filter by vlan id Jingjing Wu
                             ` (3 subsequent siblings)
  10 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang, Andrey Chilikin

From: Andrey Chilikin <andrey.chilikin@intel.com>

This patch adds missing VLAN bitmask for inner frame in case of
tunneling and fixes VLAN tags bitmasks for single or outer frame
in case of tunneling.

Fixes: 98f055707685 ("i40e: configure input fields for RSS or flow director")

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 462d0d3..ff034e7 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -198,10 +198,12 @@
 #define I40E_REG_INSET_L2_DMAC                   0xE000000000000000ULL
 /* Source MAC address */
 #define I40E_REG_INSET_L2_SMAC                   0x1C00000000000000ULL
-/* VLAN tag in the outer L2 header */
-#define I40E_REG_INSET_L2_OUTER_VLAN             0x0080000000000000ULL
-/* VLAN tag in the inner L2 header */
-#define I40E_REG_INSET_L2_INNER_VLAN             0x0100000000000000ULL
+/* Outer (S-Tag) VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_OUTER_VLAN             0x0200000000000000ULL
+/* Inner (C-Tag) or single VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_INNER_VLAN             0x0080000000000000ULL
+/* Single VLAN tag in the inner L2 header */
+#define I40E_REG_INSET_TUNNEL_VLAN               0x0100000000000000ULL
 /* Source IPv4 address */
 #define I40E_REG_INSET_L3_SRC_IP4                0x0001800000000000ULL
 /* Destination IPv4 address */
@@ -7019,7 +7021,7 @@ i40e_translate_input_set_reg(uint64_t input)
 			I40E_REG_INSET_TUNNEL_L4_UDP_SRC_PORT},
 		{I40E_INSET_TUNNEL_DST_PORT,
 			I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT},
-		{I40E_INSET_TUNNEL_ID, I40E_REG_INSET_TUNNEL_ID},
+		{I40E_INSET_VLAN_TUNNEL, I40E_REG_INSET_TUNNEL_VLAN},
 		{I40E_INSET_FLEX_PAYLOAD_W1, I40E_REG_INSET_FLEX_PAYLOAD_WORD1},
 		{I40E_INSET_FLEX_PAYLOAD_W2, I40E_REG_INSET_FLEX_PAYLOAD_WORD2},
 		{I40E_INSET_FLEX_PAYLOAD_W3, I40E_REG_INSET_FLEX_PAYLOAD_WORD3},
-- 
2.4.0

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

* [PATCH v5 8/9] i40e: extend flow director to filter by vlan id
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
                             ` (6 preceding siblings ...)
  2016-03-21  6:18           ` [PATCH v5 7/9] i40e: fix VLAN bitmasks for input set Jingjing Wu
@ 2016-03-21  6:18           ` Jingjing Wu
  2016-03-21  6:48             ` Zhang, Helin
  2016-03-21  6:18           ` [PATCH v5 9/9] testpmd: extend flow director commands Jingjing Wu
                             ` (2 subsequent siblings)
  10 siblings, 1 reply; 105+ messages in thread
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

This patch extended flow director to select vlan id
as filter's input set and program the filter rule with vlan id.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst |  2 +
 drivers/net/i40e/i40e_ethdev.c         | 11 ++++++
 drivers/net/i40e/i40e_fdir.c           | 69 +++++++++++++++++++++-------------
 3 files changed, 55 insertions(+), 27 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 5803684..0ff4e2c 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -172,6 +172,8 @@ This section should contain new features added in this release. Sample format:
 
 * **Added i40e VEB switching support.**
 
+* **Added Flow director enhancements in i40e.**
+
 * **Added fm10k Rx interrupt support.**
 
 * **Optimized fm10k Tx.**
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ff034e7..a475ad1 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6769,48 +6769,59 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index ebbe612..f15a080 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -687,11 +687,14 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 	return ret;
 }
 
-static inline void
+static inline int
 i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
-			       unsigned char *raw_pkt)
+			   unsigned char *raw_pkt,
+			   bool vlan)
 {
-	struct ether_hdr *ether = (struct ether_hdr *)raw_pkt;
+	static uint8_t vlan_frame[] = {0x81, 0, 0, 0};
+	uint16_t *ether_type;
+	uint8_t len = 2 * sizeof(struct ether_addr);
 	struct ipv4_hdr *ip;
 	struct ipv6_hdr *ip6;
 	static const uint8_t next_proto[] = {
@@ -707,18 +710,31 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] = IPPROTO_NONE,
 	};
 
+	raw_pkt += 2 * sizeof(struct ether_addr);
+	if (vlan && fdir_input->flow_ext.vlan_tci) {
+		rte_memcpy(raw_pkt, vlan_frame, sizeof(vlan_frame));
+		rte_memcpy(raw_pkt + sizeof(uint16_t),
+			   &fdir_input->flow_ext.vlan_tci,
+			   sizeof(uint16_t));
+		raw_pkt += sizeof(vlan_frame);
+		len += sizeof(vlan_frame);
+	}
+	ether_type = (uint16_t *)raw_pkt;
+	raw_pkt += sizeof(uint16_t);
+	len += sizeof(uint16_t);
+
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
+		*ether_type = fdir_input->flow.l2_flow.ether_type;
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		ip = (struct ipv4_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		ip = (struct ipv4_hdr *)raw_pkt;
 
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		*ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
@@ -736,15 +752,16 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		 */
 		ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
 		ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
+		len += sizeof(struct ipv4_hdr);
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		ip6 = (struct ipv6_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		ip6 = (struct ipv6_hdr *)raw_pkt;
 
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		*ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
 			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
 					 (fdir_input->flow.ipv6_flow.tc <<
@@ -768,12 +785,14 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		rte_memcpy(&(ip6->dst_addr),
 			   &(fdir_input->flow.ipv6_flow.src_ip),
 			   IPV6_ADDR_LEN);
+		len += sizeof(struct ipv6_hdr);
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
 			    fdir_input->flow_type);
-		break;
+		return -1;
 	}
+	return len;
 }
 
 
@@ -794,15 +813,18 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 	struct sctp_hdr *sctp;
 	uint8_t size, dst = 0;
 	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
+	int len;
 
 	/* fill the ethernet and IP head */
-	i40e_fdir_fill_eth_ip_head(fdir_input, raw_pkt);
+	len = i40e_fdir_fill_eth_ip_head(fdir_input, raw_pkt,
+					 !!fdir_input->flow_ext.vlan_tci);
+	if (len < 0)
+		return -EINVAL;
 
 	/* fill the L4 head */
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-				sizeof(struct ipv4_hdr));
+		udp = (struct udp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -815,8 +837,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv4_hdr));
+		tcp = (struct tcp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -829,8 +850,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv4_hdr));
+		sctp = (struct sctp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -844,14 +864,12 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv4_hdr);
+		payload = raw_pkt + len;
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		udp = (struct udp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -864,8 +882,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		tcp = (struct tcp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -878,8 +895,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv6_hdr));
+		sctp = (struct sctp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -893,12 +909,11 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv6_hdr);
+		payload = raw_pkt + len;
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		payload = raw_pkt + sizeof(struct ether_hdr);
+		payload = raw_pkt + len;
 		/*
 		 * ARP packet is a special case on which the payload
 		 * starts after the whole ARP header
-- 
2.4.0

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

* [PATCH v5 9/9] testpmd: extend flow director commands
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
                             ` (7 preceding siblings ...)
  2016-03-21  6:18           ` [PATCH v5 8/9] i40e: extend flow director to filter by vlan id Jingjing Wu
@ 2016-03-21  6:18           ` Jingjing Wu
  2016-03-21  6:48             ` Zhang, Helin
  2016-03-22 21:51           ` [PATCH v5 0/9] extend flow director fields in i40e driver Bruce Richardson
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
  10 siblings, 1 reply; 105+ messages in thread
From: Jingjing Wu @ 2016-03-21  6:18 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu, helin.zhang

This patch extended commands for filter's input set changing.
It added vlan as filter's input fields.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c                      | 6 +++---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 6d1b9f0..aa7ecfb 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -774,7 +774,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set_fdir_input_set (port_id) "
 			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|"
 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
 			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
 			"udp-dst-port|tcp-src-port|tcp-dst-port|"
@@ -9651,7 +9651,7 @@ cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ivlan#ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
 	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
 	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
@@ -9666,7 +9666,7 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.help_str = "set_fdir_input_set <port_id> "
 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
 	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
 	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
 	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 52a4f11..94fba6a 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1929,7 +1929,7 @@ Set the input set for flow director::
 
    set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
    ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
-   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
    tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
    sctp-dst-port|sctp-veri-tag|none) (select|add)
-- 
2.4.0

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

* Re: [PATCH v5 8/9] i40e: extend flow director to filter by vlan id
  2016-03-21  6:18           ` [PATCH v5 8/9] i40e: extend flow director to filter by vlan id Jingjing Wu
@ 2016-03-21  6:48             ` Zhang, Helin
  0 siblings, 0 replies; 105+ messages in thread
From: Zhang, Helin @ 2016-03-21  6:48 UTC (permalink / raw)
  To: Wu, Jingjing, dev



> -----Original Message-----
> From: Wu, Jingjing
> Sent: Monday, March 21, 2016 2:19 PM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; Zhang, Helin
> Subject: [PATCH v5 8/9] i40e: extend flow director to filter by vlan id
> 
> This patch extended flow director to select vlan id as filter's input set and
> program the filter rule with vlan id.
> 
> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>

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

* Re: [PATCH v5 9/9] testpmd: extend flow director commands
  2016-03-21  6:18           ` [PATCH v5 9/9] testpmd: extend flow director commands Jingjing Wu
@ 2016-03-21  6:48             ` Zhang, Helin
  0 siblings, 0 replies; 105+ messages in thread
From: Zhang, Helin @ 2016-03-21  6:48 UTC (permalink / raw)
  To: Wu, Jingjing, dev



> -----Original Message-----
> From: Wu, Jingjing
> Sent: Monday, March 21, 2016 2:19 PM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; Zhang, Helin
> Subject: [PATCH v5 9/9] testpmd: extend flow director commands
> 
> This patch extended commands for filter's input set changing.
> It added vlan as filter's input fields.
> 
> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>

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

* Re: [PATCH v5 0/9] extend flow director fields in i40e driver
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
                             ` (8 preceding siblings ...)
  2016-03-21  6:18           ` [PATCH v5 9/9] testpmd: extend flow director commands Jingjing Wu
@ 2016-03-22 21:51           ` Bruce Richardson
  2016-03-22 21:56             ` Thomas Monjalon
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
  10 siblings, 1 reply; 105+ messages in thread
From: Bruce Richardson @ 2016-03-22 21:51 UTC (permalink / raw)
  To: Jingjing Wu, thomas.monjalon; +Cc: dev, helin.zhang

On Mon, Mar 21, 2016 at 02:18:43PM +0800, Jingjing Wu wrote:
> v5 changes:
>  - remove the reorganizing of struct rte_eth_fdir_flow
>  - remove fdir supporting on Tunnel Id
>  - rebase to latest dpdk/master
>
Thomas, given the above removal, are you ok with the ethdev changes now present
in this patchset?

/Bruce

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

* Re: [PATCH v5 0/9] extend flow director fields in i40e driver
  2016-03-22 21:51           ` [PATCH v5 0/9] extend flow director fields in i40e driver Bruce Richardson
@ 2016-03-22 21:56             ` Thomas Monjalon
  0 siblings, 0 replies; 105+ messages in thread
From: Thomas Monjalon @ 2016-03-22 21:56 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: Jingjing Wu, dev, helin.zhang

2016-03-22 21:51, Bruce Richardson:
> On Mon, Mar 21, 2016 at 02:18:43PM +0800, Jingjing Wu wrote:
> > v5 changes:
> >  - remove the reorganizing of struct rte_eth_fdir_flow
> >  - remove fdir supporting on Tunnel Id
> >  - rebase to latest dpdk/master
> >
> Thomas, given the above removal, are you ok with the ethdev changes now present
> in this patchset?

Of course, yes.

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

* Re: [PATCH v5 1/9] ethdev: extend flow director for input selection
  2016-03-21  6:18           ` [PATCH v5 1/9] ethdev: extend flow director for input selection Jingjing Wu
@ 2016-03-22 22:05             ` Thomas Monjalon
  2016-03-23  0:42               ` Wu, Jingjing
  0 siblings, 1 reply; 105+ messages in thread
From: Thomas Monjalon @ 2016-03-22 22:05 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev, helin.zhang

2016-03-21 14:18, Jingjing Wu:
> This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
> RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
> struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
> by tos, protocol and ttl.
[...]
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -22,10 +22,6 @@ Deprecation Notices
>  * The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
>    must be updated to support 100G link and to have a cleaner link speed API.
>  
> -* ABI changes are planned for struct rte_eth_fdir_flow in order to support
> -  extend flow director's input set. The release 2.2 does not contain these ABI
> -  changes, but release 2.3 will, and no backwards compatibility is planned.

The changed structures are part of rte_eth_fdir_flow.
So this deprecation notice apply to this patch.

>  * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow to
>    include more fields to be matched against. The release 2.2 does not
>    contain these ABI changes, but release 2.3 will.

These are the structures changed in this patch.
I think this section must be also removed.

> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -435,6 +435,8 @@ ABI Changes
>  
>  * The cmdline buffer size has been increase from 256 to 512.
>  
> +* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
> +  changed. New fields were added to extend flow director's input set.

For reading ease, it's better to group ethdev changes (before cmdline change).

> --- a/lib/librte_ether/rte_eth_ctrl.h
> +++ b/lib/librte_ether/rte_eth_ctrl.h
> @@ -343,6 +343,8 @@ enum rte_eth_input_set_field {
>  	RTE_ETH_INPUT_SET_L3_IP4_PROTO,
>  	RTE_ETH_INPUT_SET_L3_IP6_TC,
>  	RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
> +	RTE_ETH_INPUT_SET_L3_IP4_TTL,
> +	RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
>  
>  	/* L4 */
>  	RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT = 257,
> @@ -410,6 +412,9 @@ struct rte_eth_l2_flow {
>  struct rte_eth_ipv4_flow {
>  	uint32_t src_ip;      /**< IPv4 source address to match. */
>  	uint32_t dst_ip;      /**< IPv4 destination address to match. */
> +	uint8_t  tos;         /**< Type of service to match. */
> +	uint8_t  ttl;         /**< Time to live to match. */
> +	uint8_t  proto;       /**< Protocol, next header to match. */
>  };
>  
>  /**
> @@ -446,6 +451,9 @@ struct rte_eth_sctpv4_flow {
>  struct rte_eth_ipv6_flow {
>  	uint32_t src_ip[4];      /**< IPv6 source address to match. */
>  	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
> +	uint8_t  tc;             /**< Traffic class to match. */
> +	uint8_t  proto;          /**< Protocol, next header to match. */
> +	uint8_t  hop_limits;     /**< Hop limits to match. */
>  };

This extension of the existing API looks OK.

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

* Re: [PATCH v5 1/9] ethdev: extend flow director for input selection
  2016-03-22 22:05             ` Thomas Monjalon
@ 2016-03-23  0:42               ` Wu, Jingjing
  2016-03-23  8:45                 ` Thomas Monjalon
  0 siblings, 1 reply; 105+ messages in thread
From: Wu, Jingjing @ 2016-03-23  0:42 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Zhang, Helin

Hi, Thomas

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Wednesday, March 23, 2016 6:06 AM
> To: Wu, Jingjing
> Cc: dev@dpdk.org; Zhang, Helin
> Subject: Re: [dpdk-dev] [PATCH v5 1/9] ethdev: extend flow director for
> input selection
> 
> 2016-03-21 14:18, Jingjing Wu:
> > This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
> > RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
> > struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering by
> > tos, protocol and ttl.
> [...]
> > --- a/doc/guides/rel_notes/deprecation.rst
> > +++ b/doc/guides/rel_notes/deprecation.rst
> > @@ -22,10 +22,6 @@ Deprecation Notices
> >  * The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
> >    must be updated to support 100G link and to have a cleaner link speed
> API.
> >
> > -* ABI changes are planned for struct rte_eth_fdir_flow in order to
> > support
> > -  extend flow director's input set. The release 2.2 does not contain
> > these ABI
> > -  changes, but release 2.3 will, and no backwards compatibility is planned.
> 
> The changed structures are part of rte_eth_fdir_flow.
> So this deprecation notice apply to this patch.
> 
> >  * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow
> to
> >    include more fields to be matched against. The release 2.2 does not
> >    contain these ABI changes, but release 2.3 will.
> 
> These are the structures changed in this patch.
> I think this section must be also removed.
> 


This deprecation notice is not raised by me. It is raised by rahul.lakkireddy@chelsio.com at commit 954f1545a1ab.
So, I'm not sure if it is OK for me to remove it in my patch.

/Jingjing

> > --- a/doc/guides/rel_notes/release_16_04.rst
> > +++ b/doc/guides/rel_notes/release_16_04.rst
> > @@ -435,6 +435,8 @@ ABI Changes
> >
> >  * The cmdline buffer size has been increase from 256 to 512.
> >
> > +* The ethdev flow director structure ``rte_eth_fdir_flow`` structure
> > +was
> > +  changed. New fields were added to extend flow director's input set.
> 
> For reading ease, it's better to group ethdev changes (before cmdline
> change).

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

* Re: [PATCH v5 1/9] ethdev: extend flow director for input selection
  2016-03-23  0:42               ` Wu, Jingjing
@ 2016-03-23  8:45                 ` Thomas Monjalon
  0 siblings, 0 replies; 105+ messages in thread
From: Thomas Monjalon @ 2016-03-23  8:45 UTC (permalink / raw)
  To: Wu, Jingjing; +Cc: dev, Zhang, Helin

2016-03-23 00:42, Wu, Jingjing:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > 2016-03-21 14:18, Jingjing Wu:
> > > This patch added RTE_ETH_INPUT_SET_L3_IP4_TTL,
> > > RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field type and extended
> > > struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering by
> > > tos, protocol and ttl.
> > [...]
> > > --- a/doc/guides/rel_notes/deprecation.rst
> > > +++ b/doc/guides/rel_notes/deprecation.rst
> > > @@ -22,10 +22,6 @@ Deprecation Notices
> > >  * The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
> > >    must be updated to support 100G link and to have a cleaner link speed
> > API.
> > >
> > > -* ABI changes are planned for struct rte_eth_fdir_flow in order to
> > > support
> > > -  extend flow director's input set. The release 2.2 does not contain
> > > these ABI
> > > -  changes, but release 2.3 will, and no backwards compatibility is planned.
> > 
> > The changed structures are part of rte_eth_fdir_flow.
> > So this deprecation notice apply to this patch.
> > 
> > >  * ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow
> > to
> > >    include more fields to be matched against. The release 2.2 does not
> > >    contain these ABI changes, but release 2.3 will.
> > 
> > These are the structures changed in this patch.
> > I think this section must be also removed.
> 
> This deprecation notice is not raised by me. It is raised by rahul.lakkireddy@chelsio.com at commit 954f1545a1ab.
> So, I'm not sure if it is OK for me to remove it in my patch.

It does not matter who raised the notice.
Your patch match with it. Please remove it.

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

* [PATCH v6 0/9] extend flow director fields in i40e driver
  2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
                             ` (9 preceding siblings ...)
  2016-03-22 21:51           ` [PATCH v5 0/9] extend flow director fields in i40e driver Bruce Richardson
@ 2016-03-23 13:07           ` Jingjing Wu
  2016-03-23 13:07             ` [PATCH v6 1/9] ethdev: extend flow director for input selection Jingjing Wu
                               ` (9 more replies)
  10 siblings, 10 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang

v6 changes:
 - remove ABI announce on rte_eth_ipv4_flow and rte_eth_ipv6_flow in deprecation.
 - reword commit logs. 

v5 changes:
 - remove the reorganizing of struct rte_eth_fdir_flow
 - remove fdir supporting on Tunnel Id
 - rebase to latest dpdk/master

v4 changes:
 - rebase to latest dpdk-next-net/rel_16_04.
 - comments on new fields in API structure.

v3 changes:
 - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
 - use AQ rx control register read/write for some registers
 - remove few useless lines
 - patch title rewording

v2 changes:
 - rebase on dpdk-next-net/rel_16_04
 - comments rewording.
 - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to
   avoid ABI breaking.
 - remove ABI announce in Deprecation.
 - fix the ethertype setting when program filter in v1 patch set.

This patch set extends flow director to support filtering by
additional fields below in i40e driver:
 - TOS, Protocol and TTL in IP header
 - single vlan or inner vlan


Andrey Chilikin (1):
  i40e: fix VLAN bitmasks for input set

Jingjing Wu (8):
  ethdev: extend flow director for input selection
  i40e: split function for hash and fdir input
  i40e: remove flex payload from input selection
  i40e: restore default setting on input set
  i40e: extend flow director to filter by IP Header
  testpmd: extend input set related commands
  i40e: extend flow director to filter by vlan id
  testpmd: extend flow director commands

 app/test-pmd/cmdline.c                      | 100 +++++--
 doc/guides/rel_notes/deprecation.rst        |   8 -
 doc/guides/rel_notes/release_16_04.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  42 +--
 drivers/net/i40e/i40e_ethdev.c              | 393 ++++++++++++++++------------
 drivers/net/i40e/i40e_ethdev.h              |  11 +-
 drivers/net/i40e/i40e_fdir.c                | 100 ++++---
 lib/librte_ether/rte_eth_ctrl.h             |   8 +
 8 files changed, 417 insertions(+), 250 deletions(-)

-- 
2.4.0

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

* [PATCH v6 1/9] ethdev: extend flow director for input selection
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
@ 2016-03-23 13:07             ` Jingjing Wu
  2016-03-23 14:02               ` Thomas Monjalon
  2016-03-23 13:07             ` [PATCH v6 2/9] i40e: split function for hash and fdir input Jingjing Wu
                               ` (8 subsequent siblings)
  9 siblings, 1 reply; 105+ messages in thread
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang

This patch adds RTE_ETH_INPUT_SET_L3_IP4_TTL,
RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field types and extends
struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
by tos, protocol and ttl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 doc/guides/rel_notes/deprecation.rst   | 8 --------
 doc/guides/rel_notes/release_16_04.rst | 3 +++
 lib/librte_ether/rte_eth_ctrl.h        | 8 ++++++++
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 252a096..bdbac15 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -22,14 +22,6 @@ Deprecation Notices
 * The ethdev structures rte_eth_link, rte_eth_dev_info and rte_eth_conf
   must be updated to support 100G link and to have a cleaner link speed API.
 
-* ABI changes are planned for struct rte_eth_fdir_flow in order to support
-  extend flow director's input set. The release 2.2 does not contain these ABI
-  changes, but release 2.3 will, and no backwards compatibility is planned.
-
-* ABI changes are planned for rte_eth_ipv4_flow and rte_eth_ipv6_flow to
-  include more fields to be matched against. The release 2.2 does not
-  contain these ABI changes, but release 2.3 will.
-
 * ABI changes are planned for adding four new flow types. This impacts
   RTE_ETH_FLOW_MAX. The release 2.2 does not contain these ABI changes,
   but release 2.3 will.
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 9922bcb..6e368f7 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -437,6 +437,9 @@ ABI Changes
 * The RETA entry size in ``rte_eth_rss_reta_entry64`` has been increased
   from 8-bit to 16-bit.
 
+* The ethdev flow director structure ``rte_eth_fdir_flow`` structure was
+  changed. New fields were added to extend flow director's input set.
+
 * The cmdline buffer size has been increase from 256 to 512.
 
 
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 6e2f617..aabd724 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -343,6 +343,8 @@ enum rte_eth_input_set_field {
 	RTE_ETH_INPUT_SET_L3_IP4_PROTO,
 	RTE_ETH_INPUT_SET_L3_IP6_TC,
 	RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
+	RTE_ETH_INPUT_SET_L3_IP4_TTL,
+	RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
 
 	/* L4 */
 	RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT = 257,
@@ -410,6 +412,9 @@ struct rte_eth_l2_flow {
 struct rte_eth_ipv4_flow {
 	uint32_t src_ip;      /**< IPv4 source address to match. */
 	uint32_t dst_ip;      /**< IPv4 destination address to match. */
+	uint8_t  tos;         /**< Type of service to match. */
+	uint8_t  ttl;         /**< Time to live to match. */
+	uint8_t  proto;       /**< Protocol, next header to match. */
 };
 
 /**
@@ -446,6 +451,9 @@ struct rte_eth_sctpv4_flow {
 struct rte_eth_ipv6_flow {
 	uint32_t src_ip[4];      /**< IPv6 source address to match. */
 	uint32_t dst_ip[4];      /**< IPv6 destination address to match. */
+	uint8_t  tc;             /**< Traffic class to match. */
+	uint8_t  proto;          /**< Protocol, next header to match. */
+	uint8_t  hop_limits;     /**< Hop limits to match. */
 };
 
 /**
-- 
2.4.0

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

* [PATCH v6 2/9] i40e: split function for hash and fdir input
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
  2016-03-23 13:07             ` [PATCH v6 1/9] ethdev: extend flow director for input selection Jingjing Wu
@ 2016-03-23 13:07             ` Jingjing Wu
  2016-03-23 13:07             ` [PATCH v6 3/9] i40e: remove flex payload from input selection Jingjing Wu
                               ` (7 subsequent siblings)
  9 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang

For the input set selection, Hash filter and Flow director shared
the same function, i.e. i40e_filter_inset_select.
For code readability, this patch replaces i40e_filter_inset_select
with two new functions: i40e_hash_filter_inset_select and
i40e_fdir_filter_inset_select for Hash filter and Flow director
respectively.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 235 +++++++++++++++++------------------------
 drivers/net/i40e/i40e_ethdev.h |  11 +-
 drivers/net/i40e/i40e_fdir.c   |   5 +-
 3 files changed, 107 insertions(+), 144 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 6fdae57..2867e60 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -7055,25 +7055,6 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	return idx;
 }
 
-static uint64_t
-i40e_get_reg_inset(struct i40e_hw *hw, enum rte_filter_type filter,
-			    enum i40e_filter_pctype pctype)
-{
-	uint64_t reg = 0;
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
-		reg <<= I40E_32_BIT_WIDTH;
-		reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
-	}
-
-	return reg;
-}
-
 static void
 i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 {
@@ -7086,105 +7067,96 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)i40e_read_rx_ctl(hw, addr));
 }
 
-static int
-i40e_set_hash_inset_mask(struct i40e_hw *hw,
-			 enum i40e_filter_pctype pctype,
-			 enum rte_filter_input_set_op op,
-			 uint32_t *mask_reg,
-			 uint8_t num)
+int
+i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			 struct rte_eth_input_set_conf *conf)
 {
-	uint32_t reg;
-	uint8_t i;
+	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	if (!conf) {
+		PMD_DRV_LOG(ERR, "Invalid pointer");
+		return -EFAULT;
+	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
 		return -EINVAL;
-
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = i40e_read_rx_ctl(hw,
-					       I40E_GLQF_HASH_MSK(i, pctype));
-			if (reg & I40E_GLQF_HASH_MSK_MASK_MASK)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
-
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
-					     mask_reg[j]);
 	}
 
-	return 0;
-}
-
-static int
-i40e_set_fd_inset_mask(struct i40e_hw *hw,
-		       enum i40e_filter_pctype pctype,
-		       enum rte_filter_input_set_op op,
-		       uint32_t *mask_reg,
-		       uint8_t num)
-{
-	uint32_t reg;
-	uint8_t i;
+	pctype = i40e_flowtype_to_pctype(conf->flow_type);
+	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
+		PMD_DRV_LOG(ERR, "Not supported flow type (%u)",
+			    conf->flow_type);
+		return -EINVAL;
+	}
 
-	if (!mask_reg || num > RTE_ETH_INPUT_SET_SELECT)
+	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
+				   conf->inset_size);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to parse input set");
+		return -EINVAL;
+	}
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_HASH,
+				    input_set) != 0) {
+		PMD_DRV_LOG(ERR, "Invalid input set");
+		return -EINVAL;
+	}
+	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
+		/* get inset value in register */
+		inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
+		inset_reg <<= I40E_32_BIT_WIDTH;
+		inset_reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype));
+		input_set |= pf->hash_input_set[pctype];
+	}
+	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+					   I40E_INSET_MASK_NUM_REG);
+	if (num < 0)
 		return -EINVAL;
 
-	if (op == RTE_ETH_INPUT_SET_SELECT) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     0);
-			if (i >= num)
-				continue;
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[i]);
-		}
-	} else if (op == RTE_ETH_INPUT_SET_ADD) {
-		uint8_t j, count = 0;
-
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++) {
-			reg = i40e_read_rx_ctl(hw,
-					       I40E_GLQF_FD_MSK(i, pctype));
-			if (reg & I40E_GLQF_FD_MSK_MASK_MASK)
-				count++;
-		}
-		if (count + num > I40E_INSET_MASK_NUM_REG)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		for (i = count, j = 0; i < I40E_INSET_MASK_NUM_REG; i++, j++)
-			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
-					     mask_reg[j]);
-	}
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+				     0);
+	I40E_WRITE_FLUSH(hw);
 
+	pf->hash_input_set[pctype] = input_set;
 	return 0;
 }
 
 int
-i40e_filter_inset_select(struct i40e_hw *hw,
-			 struct rte_eth_input_set_conf *conf,
-			 enum rte_filter_type filter)
+i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			 struct rte_eth_input_set_conf *conf)
 {
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	enum i40e_filter_pctype pctype;
-	uint64_t inset_reg = 0, input_set;
-	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG];
-	uint8_t num;
-	int ret;
+	uint64_t input_set, inset_reg = 0;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int ret, i, num;
 
 	if (!hw || !conf) {
 		PMD_DRV_LOG(ERR, "Invalid pointer");
 		return -EFAULT;
 	}
+	if (conf->op != RTE_ETH_INPUT_SET_SELECT &&
+	    conf->op != RTE_ETH_INPUT_SET_ADD) {
+		PMD_DRV_LOG(ERR, "Unsupported input set operation");
+		return -EINVAL;
+	}
 
 	pctype = i40e_flowtype_to_pctype(conf->flow_type);
 	if (pctype == 0 || pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) {
@@ -7192,60 +7164,48 @@ i40e_filter_inset_select(struct i40e_hw *hw,
 			    conf->flow_type);
 		return -EINVAL;
 	}
-	if (filter != RTE_ETH_FILTER_HASH && filter != RTE_ETH_FILTER_FDIR) {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
-
 	ret = i40e_parse_input_set(&input_set, pctype, conf->field,
 				   conf->inset_size);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to parse input set");
 		return -EINVAL;
 	}
-	if (i40e_validate_input_set(pctype, filter, input_set) != 0) {
+	if (i40e_validate_input_set(pctype, RTE_ETH_FILTER_FDIR,
+				    input_set) != 0) {
 		PMD_DRV_LOG(ERR, "Invalid input set");
 		return -EINVAL;
 	}
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD) {
-		inset_reg |= i40e_get_reg_inset(hw, filter, pctype);
-	} else if (conf->op != RTE_ETH_INPUT_SET_SELECT) {
-		PMD_DRV_LOG(ERR, "Unsupported input set operation");
-		return -EINVAL;
-	}
+	/* get inset value in register */
+	inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
+	inset_reg <<= I40E_32_BIT_WIDTH;
+	inset_reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
+
+	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-	inset_reg |= i40e_translate_input_set_reg(input_set);
-
-	if (filter == RTE_ETH_FILTER_HASH) {
-		ret = i40e_set_hash_inset_mask(hw, pctype, conf->op, mask_reg,
-					       num);
-		if (ret)
-			return -EINVAL;
+	if (num < 0)
+		return -EINVAL;
 
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else if (filter == RTE_ETH_FILTER_FDIR) {
-		ret = i40e_set_fd_inset_mask(hw, pctype, conf->op, mask_reg,
-					     num);
-		if (ret)
-			return -EINVAL;
+	inset_reg |= i40e_translate_input_set_reg(input_set);
 
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
-				      (uint32_t)(inset_reg & UINT32_MAX));
-		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
-				     (uint32_t)((inset_reg >>
-				     I40E_32_BIT_WIDTH) & UINT32_MAX));
-	} else {
-		PMD_DRV_LOG(ERR, "Not supported filter type (%u)", filter);
-		return -EINVAL;
-	}
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+			      (uint32_t)(inset_reg & UINT32_MAX));
+	i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+			     (uint32_t)((inset_reg >>
+			     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+	for (i = 0; i < num; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     mask_reg[i]);
+	/*clear unused mask registers of the pctype */
+	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+		i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+				     0);
 	I40E_WRITE_FLUSH(hw);
 
+	pf->fdir.input_set[pctype] = input_set;
 	return 0;
 }
 
@@ -7297,9 +7257,8 @@ i40e_hash_filter_set(struct i40e_hw *hw, struct rte_eth_hash_filter_info *info)
 				&(info->info.global_conf));
 		break;
 	case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-					       &(info->info.input_set_conf),
-					       RTE_ETH_FILTER_HASH);
+		ret = i40e_hash_filter_inset_select(hw,
+					       &(info->info.input_set_conf));
 		break;
 
 	default:
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 1c75672..1d49835 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -367,6 +367,8 @@ struct i40e_fdir_info {
 	struct i40e_rx_queue *rxq;
 	void *prg_pkt;                 /* memory for fdir program packet */
 	uint64_t dma_addr;             /* physic address of packet memory*/
+	/* input set bits for each pctype */
+	uint64_t input_set[I40E_FILTER_PCTYPE_MAX];
 	/*
 	 * the rule how bytes stream is extracted as flexible payload
 	 * for each payload layer, the setting can up to three elements
@@ -433,6 +435,8 @@ struct i40e_pf {
 	uint16_t fdir_qp_offset;
 
 	uint16_t hash_lut_size; /* The size of hash lookup table */
+	/* input set bits for each pctype */
+	uint64_t hash_input_set[I40E_FILTER_PCTYPE_MAX];
 	/* store VXLAN UDP ports */
 	uint16_t vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];
 	uint16_t vxlan_bitmap; /* Vxlan bit mask */
@@ -576,9 +580,10 @@ int i40e_fdir_ctrl_func(struct rte_eth_dev *dev,
 int i40e_select_filter_input_set(struct i40e_hw *hw,
 				 struct rte_eth_input_set_conf *conf,
 				 enum rte_filter_type filter);
-int i40e_filter_inset_select(struct i40e_hw *hw,
-			     struct rte_eth_input_set_conf *conf,
-			     enum rte_filter_type filter);
+int i40e_hash_filter_inset_select(struct i40e_hw *hw,
+			     struct rte_eth_input_set_conf *conf);
+int i40e_fdir_filter_inset_select(struct i40e_pf *pf,
+			     struct rte_eth_input_set_conf *conf);
 
 void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct rte_eth_rxq_info *qinfo);
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 14c51ce..f8055e7 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -1362,7 +1362,6 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 		     struct rte_eth_fdir_filter_info *info)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	int ret = 0;
 
 	if (!info) {
@@ -1372,8 +1371,8 @@ i40e_fdir_filter_set(struct rte_eth_dev *dev,
 
 	switch (info->info_type) {
 	case RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT:
-		ret = i40e_filter_inset_select(hw,
-			&(info->info.input_set_conf), RTE_ETH_FILTER_FDIR);
+		ret = i40e_fdir_filter_inset_select(pf,
+				&(info->info.input_set_conf));
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "FD filter info type (%d) not supported",
-- 
2.4.0

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

* [PATCH v6 3/9] i40e: remove flex payload from input selection
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
  2016-03-23 13:07             ` [PATCH v6 1/9] ethdev: extend flow director for input selection Jingjing Wu
  2016-03-23 13:07             ` [PATCH v6 2/9] i40e: split function for hash and fdir input Jingjing Wu
@ 2016-03-23 13:07             ` Jingjing Wu
  2016-03-23 13:07             ` [PATCH v6 4/9] i40e: use default filter input set on init Jingjing Wu
                               ` (6 subsequent siblings)
  9 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang

In this patch, flex payload is removed from valid fdir input set
values. It is because all flex payload configuration can be set
in struct rte_fdir_conf during device configure phase, which is
a more flexible way of setting this up.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 59 +++++++++++++++++++-----------------------
 1 file changed, 26 insertions(+), 33 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2867e60..5c549f7 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -254,7 +254,8 @@
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD7        0x0000000000000080ULL
 /* 8th word of flex payload */
 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD8        0x0000000000000040ULL
-
+/* all 8 words flex payload */
+#define I40E_REG_INSET_FLEX_PAYLOAD_WORDS        0x0000000000003FC0ULL
 #define I40E_REG_INSET_MASK_DEFAULT              0x0000000000000000ULL
 
 #define I40E_TRANSLATE_INSET 0
@@ -6755,43 +6756,32 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
-		I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
-		I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
-		I40E_INSET_LAST_ETHER_TYPE | I40E_INSET_FLEX_PAYLOAD,
+		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
 	if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD)
@@ -7019,7 +7009,7 @@ i40e_translate_input_set_reg(uint64_t input)
 	return val;
 }
 
-static uint8_t
+static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
@@ -7037,16 +7027,13 @@ i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-	if (!inset && nb_elem >= I40E_INSET_MASK_NUM_REG) {
-		for (i = 0; i < I40E_INSET_MASK_NUM_REG; i++)
-			mask[i] = 0;
-		return I40E_INSET_MASK_NUM_REG;
-	}
 
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if (idx >= nb_elem)
-			break;
-		if (inset & inset_mask_map[i].inset) {
+		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+			if (idx >= nb_elem) {
+				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
+				return -EINVAL;
+			}
 			mask[idx] = inset_mask_map[i].mask;
 			idx++;
 		}
@@ -7181,7 +7168,13 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
 	inset_reg <<= I40E_32_BIT_WIDTH;
 	inset_reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
 
-	if (conf->op == RTE_ETH_INPUT_SET_ADD)
+	/* Can not change the inset reg for flex payload for fdir,
+	 * it is done by writing I40E_PRTQF_FD_FLXINSET
+	 * in i40e_set_flex_mask_on_pctype.
+	 */
+	if (conf->op == RTE_ETH_INPUT_SET_SELECT)
+		inset_reg &= I40E_REG_INSET_FLEX_PAYLOAD_WORDS;
+	else
 		input_set |= pf->fdir.input_set[pctype];
 	num = i40e_generate_inset_mask_reg(input_set, mask_reg,
 					   I40E_INSET_MASK_NUM_REG);
-- 
2.4.0

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

* [PATCH v6 4/9] i40e: use default filter input set on init
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
                               ` (2 preceding siblings ...)
  2016-03-23 13:07             ` [PATCH v6 3/9] i40e: remove flex payload from input selection Jingjing Wu
@ 2016-03-23 13:07             ` Jingjing Wu
  2016-03-23 13:07             ` [PATCH v6 5/9] i40e: allow filtering on more IP Header fields Jingjing Wu
                               ` (5 subsequent siblings)
  9 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang

This patch adds a new function to set the input set to default
when initialization.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 57 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5c549f7..32249f9 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -384,6 +384,7 @@ static int i40e_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
 					struct rte_eth_udp_tunnel *udp_tunnel);
 static int i40e_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
 					struct rte_eth_udp_tunnel *udp_tunnel);
+static void i40e_filter_input_set_init(struct i40e_pf *pf);
 static int i40e_ethertype_filter_set(struct i40e_pf *pf,
 			struct rte_eth_ethertype_filter *filter,
 			bool add);
@@ -816,6 +817,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	 */
 	i40e_flex_payload_reg_init(hw);
 
+	/* Initialize the input set for filters (hash and fd) to default value */
+	i40e_filter_input_set_init(pf);
+
 	/* Initialize the parameters for adminq */
 	i40e_init_adminq_parameter(hw);
 	ret = i40e_init_adminq(hw);
@@ -7054,6 +7058,59 @@ i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
 		    (uint32_t)i40e_read_rx_ctl(hw, addr));
 }
 
+static void
+i40e_filter_input_set_init(struct i40e_pf *pf)
+{
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+	enum i40e_filter_pctype pctype;
+	uint64_t input_set, inset_reg;
+	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
+	int num, i;
+
+	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
+		if (!I40E_VALID_PCTYPE(pctype))
+			continue;
+		input_set = i40e_get_default_input_set(pctype);
+
+		num = i40e_generate_inset_mask_reg(input_set, mask_reg,
+						   I40E_INSET_MASK_NUM_REG);
+		if (num < 0)
+			return;
+		inset_reg = i40e_translate_input_set_reg(input_set);
+
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
+				      (uint32_t)(inset_reg & UINT32_MAX));
+		i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
+				     (uint32_t)((inset_reg >>
+				     I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+		for (i = 0; i < num; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     mask_reg[i]);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     mask_reg[i]);
+		}
+		/*clear unused mask registers of the pctype */
+		for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
+			i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
+					     0);
+			i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
+					     0);
+		}
+		I40E_WRITE_FLUSH(hw);
+
+		/* store the default input set */
+		pf->hash_input_set[pctype] = input_set;
+		pf->fdir.input_set[pctype] = input_set;
+	}
+}
+
 int
 i40e_hash_filter_inset_select(struct i40e_hw *hw,
 			 struct rte_eth_input_set_conf *conf)
-- 
2.4.0

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

* [PATCH v6 5/9] i40e: allow filtering on more IP Header fields
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
                               ` (3 preceding siblings ...)
  2016-03-23 13:07             ` [PATCH v6 4/9] i40e: use default filter input set on init Jingjing Wu
@ 2016-03-23 13:07             ` Jingjing Wu
  2016-03-23 13:07             ` [PATCH v6 6/9] testpmd: extend input set related commands Jingjing Wu
                               ` (4 subsequent siblings)
  9 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang

This patch extends flow director to select more IP Header fields
as filter input set.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 69 ++++++++++++++++++++++++++++++++++--------
 drivers/net/i40e/i40e_fdir.c   | 26 +++++++++++-----
 2 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 32249f9..ff0ee2e 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -210,6 +210,8 @@
 #define I40E_REG_INSET_L3_IP4_TOS                0x0040000000000000ULL
 /* IPv4 Protocol */
 #define I40E_REG_INSET_L3_IP4_PROTO              0x0004000000000000ULL
+/* IPv4 Time to Live */
+#define I40E_REG_INSET_L3_IP4_TTL                0x0004000000000000ULL
 /* Source IPv6 address */
 #define I40E_REG_INSET_L3_SRC_IP6                0x0007F80000000000ULL
 /* Destination IPv6 address */
@@ -218,6 +220,8 @@
 #define I40E_REG_INSET_L3_IP6_TC                 0x0040000000000000ULL
 /* IPv6 Next Header */
 #define I40E_REG_INSET_L3_IP6_NEXT_HDR           0x0008000000000000ULL
+/* IPv6 Hop Limit */
+#define I40E_REG_INSET_L3_IP6_HOP_LIMIT          0x0008000000000000ULL
 /* Source L4 port */
 #define I40E_REG_INSET_L4_SRC_PORT               0x0000000400000000ULL
 /* Destination L4 port */
@@ -261,10 +265,12 @@
 #define I40E_TRANSLATE_INSET 0
 #define I40E_TRANSLATE_REG   1
 
-#define I40E_INSET_IPV4_TOS_MASK      0x0009FF00UL
-#define I40E_INSET_IPV4_PROTO_MASK    0x000DFF00UL
-#define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
-#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
+#define I40E_INSET_IPV4_TOS_MASK        0x0009FF00UL
+#define I40E_INSET_IPv4_TTL_MASK        0x000D00FFUL
+#define I40E_INSET_IPV4_PROTO_MASK      0x000DFF00UL
+#define I40E_INSET_IPV6_TC_MASK         0x0009F00FUL
+#define I40E_INSET_IPV6_HOP_LIMIT_MASK  0x000CFF00UL
+#define I40E_INSET_IPV6_NEXT_HDR_MASK   0x000C00FFUL
 
 #define I40E_GL_SWT_L2TAGCTRL(_i)             (0x001C0A70 + ((_i) * 4))
 #define I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT 16
@@ -6760,30 +6766,47 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
@@ -6883,11 +6906,14 @@ i40e_parse_input_set(uint64_t *inset,
 		{RTE_ETH_INPUT_SET_L3_DST_IP4, I40E_INSET_IPV4_DST},
 		{RTE_ETH_INPUT_SET_L3_IP4_TOS, I40E_INSET_IPV4_TOS},
 		{RTE_ETH_INPUT_SET_L3_IP4_PROTO, I40E_INSET_IPV4_PROTO},
+		{RTE_ETH_INPUT_SET_L3_IP4_TTL, I40E_INSET_IPV4_TTL},
 		{RTE_ETH_INPUT_SET_L3_SRC_IP6, I40E_INSET_IPV6_SRC},
 		{RTE_ETH_INPUT_SET_L3_DST_IP6, I40E_INSET_IPV6_DST},
 		{RTE_ETH_INPUT_SET_L3_IP6_TC, I40E_INSET_IPV6_TC},
 		{RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
 			I40E_INSET_IPV6_NEXT_HDR},
+		{RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
+			I40E_INSET_IPV6_HOP_LIMIT},
 		{RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT, I40E_INSET_SRC_PORT},
@@ -6974,10 +7000,12 @@ i40e_translate_input_set_reg(uint64_t input)
 		{I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4},
 		{I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS},
 		{I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO},
+		{I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL},
 		{I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6},
 		{I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6},
 		{I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_REG_INSET_L3_IP6_NEXT_HDR},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_REG_INSET_L3_IP6_HOP_LIMIT},
 		{I40E_INSET_SRC_PORT, I40E_REG_INSET_L4_SRC_PORT},
 		{I40E_INSET_DST_PORT, I40E_REG_INSET_L4_DST_PORT},
 		{I40E_INSET_SCTP_VT, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG},
@@ -7017,23 +7045,38 @@ static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
+	uint64_t inset_need_mask = inset;
 
 	static const struct {
 		uint64_t inset;
 		uint32_t mask;
 	} inset_mask_map[] = {
 		{I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK},
+		{I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0},
 		{I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK},
+		{I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK},
 		{I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK},
+		{I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK},
 	};
 
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+		/* Clear the inset bit, if no MASK is required,
+		 * for example proto + ttl
+		 */
+		if ((inset & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset && inset_mask_map[i].mask == 0)
+			inset_need_mask &= ~inset_mask_map[i].inset;
+		if (!inset_need_mask)
+			return 0;
+	}
+	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
+		if ((inset_need_mask & inset_mask_map[i].inset) ==
+		    inset_mask_map[i].inset) {
 			if (idx >= nb_elem) {
 				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
 				return -EINVAL;
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index f8055e7..ebbe612 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -66,7 +66,9 @@
 #define I40E_FDIR_IP_DEFAULT_TTL            0x40
 #define I40E_FDIR_IP_DEFAULT_VERSION_IHL    0x45
 #define I40E_FDIR_TCP_DEFAULT_DATAOFF       0x50
-#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60300000
+#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60000000
+#define I40E_FDIR_IPv6_TC_OFFSET            20
+
 #define I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS   0xFF
 #define I40E_FDIR_IPv6_PAYLOAD_LEN          380
 #define I40E_FDIR_UDP_DEFAULT_LEN           400
@@ -720,7 +722,13 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
-		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+		ip->next_proto_id = fdir_input->flow.ip4_flow.proto ?
+					fdir_input->flow.ip4_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip->time_to_live = fdir_input->flow.ip4_flow.ttl ?
+					fdir_input->flow.ip4_flow.ttl :
+					I40E_FDIR_IP_DEFAULT_TTL;
+		ip->type_of_service = fdir_input->flow.ip4_flow.tos;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -728,7 +736,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		 */
 		ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
 		ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
-		ip->next_proto_id = next_proto[fdir_input->flow_type];
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
@@ -739,11 +746,17 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 
 		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
-			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
+					 (fdir_input->flow.ipv6_flow.tc <<
+					  I40E_FDIR_IPv6_TC_OFFSET));
 		ip6->payload_len =
 			rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
-		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
-
+		ip6->proto = fdir_input->flow.ipv6_flow.proto ?
+					fdir_input->flow.ipv6_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ?
+					fdir_input->flow.ipv6_flow.hop_limits :
+					I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -755,7 +768,6 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		rte_memcpy(&(ip6->dst_addr),
 			   &(fdir_input->flow.ipv6_flow.src_ip),
 			   IPV6_ADDR_LEN);
-		ip6->proto = next_proto[fdir_input->flow_type];
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
-- 
2.4.0

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

* [PATCH v6 6/9] testpmd: extend input set related commands
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
                               ` (4 preceding siblings ...)
  2016-03-23 13:07             ` [PATCH v6 5/9] i40e: allow filtering on more IP Header fields Jingjing Wu
@ 2016-03-23 13:07             ` Jingjing Wu
  2016-03-23 13:07             ` [PATCH v6 7/9] i40e: fix VLAN bitmasks for input set Jingjing Wu
                               ` (3 subsequent siblings)
  9 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang

This patch extends commands for changing a flow director filter's input
set. It adds tos, protocol and ttl as filter's input fields, and removes
the words selection from flex payloads.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 app/test-pmd/cmdline.c                      | 100 ++++++++++++++++++++++------
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  42 +++++++-----
 2 files changed, 104 insertions(+), 38 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index c34d4c1..95350de 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -669,6 +669,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"flow_director_filter (port_id) mode IP (add|del|update)"
 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
+			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -678,6 +679,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
+			" tos (tos_value) ttl (ttl_value)"
 			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
 			" fd_id (fd_id_value)\n"
@@ -687,7 +689,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" flow (ipv4-sctp|ipv6-sctp)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
-			" tag (verification_tag) vlan (vlan_value)"
+			" tag (verification_tag) "
+			" tos (tos_value) ttl (ttl_value)"
+			" vlan (vlan_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -767,14 +771,15 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"fld-8th|none) (select|add)\n"
 			"    Set the input set for hash.\n\n"
 
-			"set_fdir_input_set (port_id) (ipv4|ipv4-frag|"
-			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+			"set_fdir_input_set (port_id) "
+			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
-			"udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|"
-			"sctp-src-port|sctp-dst-port|sctp-veri-tag|fld-1st|"
-			"fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
-			"fld-8th|none) (select|add)\n"
+			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
+			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
+			"udp-dst-port|tcp-src-port|tcp-dst-port|"
+			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
+			" (select|add)\n"
 			"    Set the input set for FDir.\n\n"
 		);
 	}
@@ -8027,6 +8032,12 @@ struct cmd_flow_director_result {
 	uint16_t port_dst;
 	cmdline_fixed_string_t verify_tag;
 	uint32_t verify_tag_value;
+	cmdline_ipaddr_t tos;
+	uint8_t tos_value;
+	cmdline_ipaddr_t proto;
+	uint8_t proto_value;
+	cmdline_ipaddr_t ttl;
+	uint8_t ttl_value;
 	cmdline_fixed_string_t vlan;
 	uint16_t vlan_value;
 	cmdline_fixed_string_t flexbytes;
@@ -8206,12 +8217,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 	switch (entry.input.flow_type) {
 	case RTE_ETH_FLOW_FRAG_IPV4:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+		entry.input.flow.ip4_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 		IPV4_ADDR_TO_UINT(res->ip_dst,
 			entry.input.flow.ip4_flow.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.ip4_flow.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8223,6 +8237,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp4_flow.ip.dst_ip);
 		IPV4_ADDR_TO_UINT(res->ip_src,
 			entry.input.flow.sctp4_flow.ip.src_ip);
+		entry.input.flow.ip4_flow.tos = res->tos_value;
+		entry.input.flow.ip4_flow.ttl = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp4_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8233,12 +8249,15 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 		break;
 	case RTE_ETH_FLOW_FRAG_IPV6:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+		entry.input.flow.ipv6_flow.proto = res->proto_value;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 		IPV6_ADDR_TO_ARRAY(res->ip_dst,
 			entry.input.flow.ipv6_flow.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.ipv6_flow.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.udp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8250,6 +8269,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
 			entry.input.flow.sctp6_flow.ip.dst_ip);
 		IPV6_ADDR_TO_ARRAY(res->ip_src,
 			entry.input.flow.sctp6_flow.ip.src_ip);
+		entry.input.flow.ipv6_flow.tc = res->tos_value;
+		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
 		/* need convert to big endian. */
 		entry.input.flow.sctp6_flow.dst_port =
 				rte_cpu_to_be_16(res->port_dst);
@@ -8377,6 +8398,24 @@ cmdline_parse_token_string_t cmd_flow_director_verify_tag =
 cmdline_parse_token_num_t cmd_flow_director_verify_tag_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
 			      verify_tag_value, UINT32);
+cmdline_parse_token_string_t cmd_flow_director_tos =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 tos, "tos");
+cmdline_parse_token_num_t cmd_flow_director_tos_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      tos_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_proto =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 proto, "proto");
+cmdline_parse_token_num_t cmd_flow_director_proto_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      proto_value, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_ttl =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 ttl, "ttl");
+cmdline_parse_token_num_t cmd_flow_director_ttl_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      ttl_value, UINT8);
 cmdline_parse_token_string_t cmd_flow_director_vlan =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 vlan, "vlan");
@@ -8455,6 +8494,12 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ip_src,
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_proto,
+		(void *)&cmd_flow_director_proto_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8487,6 +8532,10 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
 		(void *)&cmd_flow_director_port_dst,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -8521,6 +8570,10 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_port_dst,
 		(void *)&cmd_flow_director_verify_tag,
 		(void *)&cmd_flow_director_verify_tag_value,
+		(void *)&cmd_flow_director_tos,
+		(void *)&cmd_flow_director_tos_value,
+		(void *)&cmd_flow_director_ttl,
+		(void *)&cmd_flow_director_ttl_value,
 		(void *)&cmd_flow_director_vlan,
 		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
@@ -9447,16 +9500,19 @@ str2inset(char *string)
 		char str[32];
 		enum rte_eth_input_set_field inset;
 	} inset_table[] = {
+		{"ethertype", RTE_ETH_INPUT_SET_L2_ETHERTYPE},
 		{"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
 		{"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
 		{"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
 		{"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
 		{"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
 		{"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
+		{"ipv4-ttl", RTE_ETH_INPUT_SET_L3_IP4_TTL},
 		{"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
 		{"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
 		{"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
 		{"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
+		{"ipv6-hop-limits", RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS},
 		{"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
 		{"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
 		{"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
@@ -9515,7 +9571,7 @@ cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
 		flow_type,
-		"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
@@ -9534,8 +9590,8 @@ cmdline_parse_inst_t cmd_set_hash_input_set = {
 	.f = cmd_set_hash_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_hash_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
@@ -9590,15 +9646,16 @@ cmdline_parse_token_num_t cmd_set_fdir_input_set_port_id =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	flow_type,
-	"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+	"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
 	"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#udp-src-port#udp-dst-port#"
+	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
+	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
-	"sctp-veri-tag#fld-1st#fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#"
-	"fld-7th#fld-8th#none");
+	"sctp-veri-tag#none");
 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	select, "select#add");
@@ -9607,12 +9664,13 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.f = cmd_set_fdir_input_set_parsed,
 	.data = NULL,
 	.help_str = "set_fdir_input_set <port_id> "
-	"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
-	"ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port|"
-	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|"
-	"fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
-	"fld-7th|fld-8th|none select|add",
+	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
+	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
+	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
+	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
+	"sctp-veri-tag|none select|add",
 	.tokens = {
 		(void *)&cmd_set_fdir_input_set_cmd,
 		(void *)&cmd_set_fdir_input_set_port_id,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index efaf2b5..52a4f11 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1739,8 +1739,9 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 # Commands to add flow director filters of different flow types::
 
    flow_director_filter (port_id) mode IP (add|del|update) \
-                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)
+                        flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag) \
                         src (src_ip_address) dst (dst_ip_address) \
+                        tos (tos_value) proto (proto_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) pf|vf(vf_id) queue (queue_id) \
                         fd_id (fd_id_value)
@@ -1749,6 +1750,7 @@ Different NICs may have different capabilities, command show port fdir (port_id)
                         flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp) \
                         src (src_ip_address) (src_port) \
                         dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         vlan (vlan_value) flexbytes (flexbytes_value) \
                         (drop|fwd) queue pf|vf(vf_id) (queue_id) \
                         fd_id (fd_id_value)
@@ -1756,7 +1758,8 @@ Different NICs may have different capabilities, command show port fdir (port_id)
    flow_director_filter (port_id) mode IP (add|del|update) \
                         flow (ipv4-sctp|ipv6-sctp) \
                         src (src_ip_address) (src_port) \
-                        dst (dst_ip_address) (dst_port)
+                        dst (dst_ip_address) (dst_port) \
+                        tos (tos_value) ttl (ttl_value) \
                         tag (verification_tag) vlan (vlan_value) \
                         flexbytes (flexbytes_value) (drop|fwd) \
                         pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)
@@ -1780,12 +1783,14 @@ Different NICs may have different capabilities, command show port fdir (port_id)
 For example, to add an ipv4-udp flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-udp src 2.2.2.3 32 \
-            dst 2.2.2.5 33 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+            dst 2.2.2.5 33 tos 2 ttl 40 vlan 0x1 flexbytes (0x88,0x48) \
+            fwd pf queue 1 fd_id 1
 
 For example, add an ipv4-other flow type filter::
 
    testpmd> flow_director_filter 0 add flow ipv4-other src 2.2.2.3 \
-             dst 2.2.2.5 vlan 0x1 flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
+             dst 2.2.2.5 tos 2 proto 20 ttl 40 vlan 0x1 \
+             flexbytes (0x88,0x48) fwd pf queue 1 fd_id 1
 
 flush_flow_director
 ~~~~~~~~~~~~~~~~~~~
@@ -1902,33 +1907,36 @@ set_hash_input_set
 
 Set the input set for hash::
 
-   set_hash_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   set_hash_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
    l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port| \
    tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
    udp-key|gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th| \
    fld-8th|none) (select|add)
 
-For example, to add source IP to hash input set for flow type of ipv4 on port 0::
+For example, to add source IP to hash input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_hash_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_hash_input_set 0 ipv4-udp src-ipv4 add
 
 set_fdir_input_set
 ~~~~~~~~~~~~~~~~~~
 
-Set the input set for Fdir::
+The Flow Director filters can match the different fields for different type of packet, i.e. specific input set
+on per flow type and the flexible payload. This command can be used to change input set for each flow type.
 
-   set_fdir_input_set (port_id) (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
-   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)
-   (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port| \
-   tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag| \
-   fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|fld-8th|none) \
-   (select|add)
+Set the input set for flow director::
+
+   set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
+   ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
+   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
+   tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
+   sctp-dst-port|sctp-veri-tag|none) (select|add)
 
-For example to add source IP to FD input set for flow type of ipv4 on port 0::
+For example to add source IP to FD input set for flow type of ipv4-udp on port 0::
 
-   testpmd> set_fdir_input_set 0 ipv4 src-ipv4 add
+   testpmd> set_fdir_input_set 0 ipv4-udp src-ipv4 add
 
 global_config
 ~~~~~~~~~~~~~
-- 
2.4.0

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

* [PATCH v6 7/9] i40e: fix VLAN bitmasks for input set
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
                               ` (5 preceding siblings ...)
  2016-03-23 13:07             ` [PATCH v6 6/9] testpmd: extend input set related commands Jingjing Wu
@ 2016-03-23 13:07             ` Jingjing Wu
  2016-03-23 13:07             ` [PATCH v6 8/9] i40e: extend flow director to filter by vlan id Jingjing Wu
                               ` (2 subsequent siblings)
  9 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang, Andrey Chilikin

From: Andrey Chilikin <andrey.chilikin@intel.com>

This patch adds missing VLAN bitmask for inner frame in case of
tunneling and fixes VLAN tags bitmasks for single or outer frame
in case of tunneling.

Fixes: 98f055707685 ("i40e: configure input fields for RSS or flow director")

Signed-off-by: Andrey Chilikin <andrey.chilikin@intel.com>
Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ff0ee2e..493db14 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -198,10 +198,12 @@
 #define I40E_REG_INSET_L2_DMAC                   0xE000000000000000ULL
 /* Source MAC address */
 #define I40E_REG_INSET_L2_SMAC                   0x1C00000000000000ULL
-/* VLAN tag in the outer L2 header */
-#define I40E_REG_INSET_L2_OUTER_VLAN             0x0080000000000000ULL
-/* VLAN tag in the inner L2 header */
-#define I40E_REG_INSET_L2_INNER_VLAN             0x0100000000000000ULL
+/* Outer (S-Tag) VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_OUTER_VLAN             0x0200000000000000ULL
+/* Inner (C-Tag) or single VLAN tag in the outer L2 header */
+#define I40E_REG_INSET_L2_INNER_VLAN             0x0080000000000000ULL
+/* Single VLAN tag in the inner L2 header */
+#define I40E_REG_INSET_TUNNEL_VLAN               0x0100000000000000ULL
 /* Source IPv4 address */
 #define I40E_REG_INSET_L3_SRC_IP4                0x0001800000000000ULL
 /* Destination IPv4 address */
@@ -7018,7 +7020,7 @@ i40e_translate_input_set_reg(uint64_t input)
 			I40E_REG_INSET_TUNNEL_L4_UDP_SRC_PORT},
 		{I40E_INSET_TUNNEL_DST_PORT,
 			I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT},
-		{I40E_INSET_TUNNEL_ID, I40E_REG_INSET_TUNNEL_ID},
+		{I40E_INSET_VLAN_TUNNEL, I40E_REG_INSET_TUNNEL_VLAN},
 		{I40E_INSET_FLEX_PAYLOAD_W1, I40E_REG_INSET_FLEX_PAYLOAD_WORD1},
 		{I40E_INSET_FLEX_PAYLOAD_W2, I40E_REG_INSET_FLEX_PAYLOAD_WORD2},
 		{I40E_INSET_FLEX_PAYLOAD_W3, I40E_REG_INSET_FLEX_PAYLOAD_WORD3},
-- 
2.4.0

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

* [PATCH v6 8/9] i40e: extend flow director to filter by vlan id
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
                               ` (6 preceding siblings ...)
  2016-03-23 13:07             ` [PATCH v6 7/9] i40e: fix VLAN bitmasks for input set Jingjing Wu
@ 2016-03-23 13:07             ` Jingjing Wu
  2016-03-23 13:07             ` [PATCH v6 9/9] testpmd: allow vlan as part of fdir input set Jingjing Wu
  2016-03-23 14:46             ` [PATCH v6 0/9] extend flow director fields in i40e driver Bruce Richardson
  9 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang

This patch extends flow director to select vlan id as part of
filter's input set and program the filter rule with vlan id.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst |  2 +
 drivers/net/i40e/i40e_ethdev.c         | 11 ++++++
 drivers/net/i40e/i40e_fdir.c           | 69 +++++++++++++++++++++-------------
 3 files changed, 55 insertions(+), 27 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 6e368f7..58a53fb 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -172,6 +172,8 @@ This section should contain new features added in this release. Sample format:
 
 * **Added i40e VEB switching support.**
 
+* **Added Flow director enhancements in i40e.**
+
 * **Added fm10k Rx interrupt support.**
 
 * **Optimized fm10k Tx.**
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 493db14..44042aa 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6768,48 +6768,59 @@ i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
 		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
 		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
+		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
 
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index ebbe612..f15a080 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -687,11 +687,14 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
 	return ret;
 }
 
-static inline void
+static inline int
 i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
-			       unsigned char *raw_pkt)
+			   unsigned char *raw_pkt,
+			   bool vlan)
 {
-	struct ether_hdr *ether = (struct ether_hdr *)raw_pkt;
+	static uint8_t vlan_frame[] = {0x81, 0, 0, 0};
+	uint16_t *ether_type;
+	uint8_t len = 2 * sizeof(struct ether_addr);
 	struct ipv4_hdr *ip;
 	struct ipv6_hdr *ip6;
 	static const uint8_t next_proto[] = {
@@ -707,18 +710,31 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		[RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] = IPPROTO_NONE,
 	};
 
+	raw_pkt += 2 * sizeof(struct ether_addr);
+	if (vlan && fdir_input->flow_ext.vlan_tci) {
+		rte_memcpy(raw_pkt, vlan_frame, sizeof(vlan_frame));
+		rte_memcpy(raw_pkt + sizeof(uint16_t),
+			   &fdir_input->flow_ext.vlan_tci,
+			   sizeof(uint16_t));
+		raw_pkt += sizeof(vlan_frame);
+		len += sizeof(vlan_frame);
+	}
+	ether_type = (uint16_t *)raw_pkt;
+	raw_pkt += sizeof(uint16_t);
+	len += sizeof(uint16_t);
+
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		ether->ether_type = fdir_input->flow.l2_flow.ether_type;
+		*ether_type = fdir_input->flow.l2_flow.ether_type;
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		ip = (struct ipv4_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		ip = (struct ipv4_hdr *)raw_pkt;
 
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+		*ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
@@ -736,15 +752,16 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		 */
 		ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
 		ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
+		len += sizeof(struct ipv4_hdr);
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		ip6 = (struct ipv6_hdr *)(raw_pkt + sizeof(struct ether_hdr));
+		ip6 = (struct ipv6_hdr *)raw_pkt;
 
-		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
+		*ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
 			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
 					 (fdir_input->flow.ipv6_flow.tc <<
@@ -768,12 +785,14 @@ i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		rte_memcpy(&(ip6->dst_addr),
 			   &(fdir_input->flow.ipv6_flow.src_ip),
 			   IPV6_ADDR_LEN);
+		len += sizeof(struct ipv6_hdr);
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",
 			    fdir_input->flow_type);
-		break;
+		return -1;
 	}
+	return len;
 }
 
 
@@ -794,15 +813,18 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 	struct sctp_hdr *sctp;
 	uint8_t size, dst = 0;
 	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
+	int len;
 
 	/* fill the ethernet and IP head */
-	i40e_fdir_fill_eth_ip_head(fdir_input, raw_pkt);
+	len = i40e_fdir_fill_eth_ip_head(fdir_input, raw_pkt,
+					 !!fdir_input->flow_ext.vlan_tci);
+	if (len < 0)
+		return -EINVAL;
 
 	/* fill the L4 head */
 	switch (fdir_input->flow_type) {
 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-				sizeof(struct ipv4_hdr));
+		udp = (struct udp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -815,8 +837,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv4_hdr));
+		tcp = (struct tcp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -829,8 +850,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv4_hdr));
+		sctp = (struct sctp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -844,14 +864,12 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV4:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv4_hdr);
+		payload = raw_pkt + len;
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
-		udp = (struct udp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		udp = (struct udp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)udp + sizeof(struct udp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -864,8 +882,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
-		tcp = (struct tcp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					 sizeof(struct ipv6_hdr));
+		tcp = (struct tcp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)tcp + sizeof(struct tcp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -878,8 +895,7 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 		break;
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
-		sctp = (struct sctp_hdr *)(raw_pkt + sizeof(struct ether_hdr) +
-					   sizeof(struct ipv6_hdr));
+		sctp = (struct sctp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)sctp + sizeof(struct sctp_hdr);
 		/*
 		 * The source and destination fields in the transmitted packet
@@ -893,12 +909,11 @@ i40e_fdir_construct_pkt(struct i40e_pf *pf,
 
 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
 	case RTE_ETH_FLOW_FRAG_IPV6:
-		payload = raw_pkt + sizeof(struct ether_hdr) +
-			  sizeof(struct ipv6_hdr);
+		payload = raw_pkt + len;
 		set_idx = I40E_FLXPLD_L3_IDX;
 		break;
 	case RTE_ETH_FLOW_L2_PAYLOAD:
-		payload = raw_pkt + sizeof(struct ether_hdr);
+		payload = raw_pkt + len;
 		/*
 		 * ARP packet is a special case on which the payload
 		 * starts after the whole ARP header
-- 
2.4.0

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

* [PATCH v6 9/9] testpmd: allow vlan as part of fdir input set
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
                               ` (7 preceding siblings ...)
  2016-03-23 13:07             ` [PATCH v6 8/9] i40e: extend flow director to filter by vlan id Jingjing Wu
@ 2016-03-23 13:07             ` Jingjing Wu
  2016-03-23 14:46             ` [PATCH v6 0/9] extend flow director fields in i40e driver Bruce Richardson
  9 siblings, 0 replies; 105+ messages in thread
From: Jingjing Wu @ 2016-03-23 13:07 UTC (permalink / raw)
  To: bruce.richardson; +Cc: dev, jingjing.wu, helin.zhang

This patch extends the commands for changing filter's input set.
It adds vlan as filter's possobile input fields.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 app/test-pmd/cmdline.c                      | 6 +++---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 95350de..25b87ca 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -774,7 +774,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set_fdir_input_set (port_id) "
 			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
-			"l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|"
+			"l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|"
 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
 			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
 			"udp-dst-port|tcp-src-port|tcp-dst-port|"
@@ -9651,7 +9651,7 @@ cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
 	inset_field,
-	"ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+	"ivlan#ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
 	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
 	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
@@ -9666,7 +9666,7 @@ cmdline_parse_inst_t cmd_set_fdir_input_set = {
 	.help_str = "set_fdir_input_set <port_id> "
 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
 	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
-	"ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+	"ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
 	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
 	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
 	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 52a4f11..94fba6a 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1929,7 +1929,7 @@ Set the input set for flow director::
 
    set_fdir_input_set (port_id) (ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp| \
    ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other| \
-   l2_payload) (ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
+   l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos| \
    ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|ipv6-hop-limits| \
    tudp-src-port|udp-dst-port|cp-src-port|tcp-dst-port|sctp-src-port| \
    sctp-dst-port|sctp-veri-tag|none) (select|add)
-- 
2.4.0

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

* Re: [PATCH v6 1/9] ethdev: extend flow director for input selection
  2016-03-23 13:07             ` [PATCH v6 1/9] ethdev: extend flow director for input selection Jingjing Wu
@ 2016-03-23 14:02               ` Thomas Monjalon
  0 siblings, 0 replies; 105+ messages in thread
From: Thomas Monjalon @ 2016-03-23 14:02 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev, bruce.richardson, helin.zhang

2016-03-23 21:07, Jingjing Wu:
> This patch adds RTE_ETH_INPUT_SET_L3_IP4_TTL,
> RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS input field types and extends
> struct rte_eth_ipv4_flow and rte_eth_ipv6_flow to support filtering
> by tos, protocol and ttl.
> 
> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> Acked-by: Helin Zhang <helin.zhang@intel.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

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

* Re: [PATCH v6 0/9] extend flow director fields in i40e driver
  2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
                               ` (8 preceding siblings ...)
  2016-03-23 13:07             ` [PATCH v6 9/9] testpmd: allow vlan as part of fdir input set Jingjing Wu
@ 2016-03-23 14:46             ` Bruce Richardson
  9 siblings, 0 replies; 105+ messages in thread
From: Bruce Richardson @ 2016-03-23 14:46 UTC (permalink / raw)
  To: Jingjing Wu; +Cc: dev, helin.zhang

On Wed, Mar 23, 2016 at 09:07:03PM +0800, Jingjing Wu wrote:
> v6 changes:
>  - remove ABI announce on rte_eth_ipv4_flow and rte_eth_ipv6_flow in deprecation.
>  - reword commit logs. 
> 
> v5 changes:
>  - remove the reorganizing of struct rte_eth_fdir_flow
>  - remove fdir supporting on Tunnel Id
>  - rebase to latest dpdk/master
> 
> v4 changes:
>  - rebase to latest dpdk-next-net/rel_16_04.
>  - comments on new fields in API structure.
> 
> v3 changes:
>  - rebase to latest dpdk-next-net/rel_16_04(commit: 0f9564a0e4f2)
>  - use AQ rx control register read/write for some registers
>  - remove few useless lines
>  - patch title rewording
> 
> v2 changes:
>  - rebase on dpdk-next-net/rel_16_04
>  - comments rewording.
>  - redefine the value of RTE_ETH_INPUT_SET_L3_IP4_TTL to
>    avoid ABI breaking.
>  - remove ABI announce in Deprecation.
>  - fix the ethertype setting when program filter in v1 patch set.
> 
> This patch set extends flow director to support filtering by
> additional fields below in i40e driver:
>  - TOS, Protocol and TTL in IP header
>  - single vlan or inner vlan
> 
> 
> Andrey Chilikin (1):
>   i40e: fix VLAN bitmasks for input set
> 
> Jingjing Wu (8):
>   ethdev: extend flow director for input selection
>   i40e: split function for hash and fdir input
>   i40e: remove flex payload from input selection
>   i40e: restore default setting on input set
>   i40e: extend flow director to filter by IP Header
>   testpmd: extend input set related commands
>   i40e: extend flow director to filter by vlan id
>   testpmd: extend flow director commands
>
Patchset applied to dpdk-next-net/rel_16_04.

Thanks,
/Bruce

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

end of thread, other threads:[~2016-03-23 14:47 UTC | newest]

Thread overview: 105+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-25  8:29 [PATCH 0/4] extend flow director's IP fields in i40e driver Jingjing Wu
2015-12-25  8:29 ` [PATCH 1/4] ethdev: extend flow director to support input set selection Jingjing Wu
2015-12-25  8:29 ` [PATCH 2/4] i40e: split function for input set change of hash and fdir Jingjing Wu
2016-01-20 20:04   ` Chilikin, Andrey
2016-01-21  1:28     ` Wu, Jingjing
2016-01-21 20:06       ` Chilikin, Andrey
2016-01-26  1:12         ` Wu, Jingjing
2015-12-25  8:29 ` [PATCH 3/4] i40e: extend flow director to filter by more IP Header fields Jingjing Wu
2015-12-25  8:30 ` [PATCH 4/4] testpmd: extend commands for filter's input set changing Jingjing Wu
2016-01-26  6:26 ` [PATCH 00/12] extend flow director's fields in i40e driver Jingjing Wu
2016-01-26  6:26   ` [PATCH 01/12] ethdev: extend flow director to support input set selection Jingjing Wu
2016-01-26  6:26   ` [PATCH 02/12] i40e: split function for input set change of hash and fdir Jingjing Wu
2016-02-25  8:51     ` Zhang, Helin
2016-02-26  0:32       ` Wu, Jingjing
2016-01-26  6:26   ` [PATCH 03/12] i40e: remove flex payload from INPUT_SET_SELECT operation Jingjing Wu
2016-01-26  6:26   ` [PATCH 04/12] i40e: restore default setting on input set of filters Jingjing Wu
2016-01-26  6:26   ` [PATCH 05/12] i40e: extend flow director to filter by more IP Header fields Jingjing Wu
2016-01-26  6:26   ` [PATCH 06/12] testpmd: extend commands for filter's input set changing Jingjing Wu
2016-01-26  6:26   ` [PATCH 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format Jingjing Wu
2016-01-26  6:26   ` [PATCH 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
2016-01-26  6:26   ` [PATCH 09/12] testpmd: extend commands for fdir's tunnel id input set Jingjing Wu
2016-01-26  6:26   ` [PATCH 10/12] i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels Jingjing Wu
2016-01-26  6:26   ` [PATCH 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
2016-01-26  6:26   ` [PATCH 12/12] testpmd: extend commands for fdir's vlan input set Jingjing Wu
2016-02-24 11:44   ` [PATCH 00/12] extend flow director's fields in i40e driver Bruce Richardson
2016-02-25  7:42     ` Zhang, Helin
2016-03-02 11:29   ` [PATCH v2 " Jingjing Wu
2016-03-02 11:29     ` [PATCH v2 01/12] ethdev: extend flow director to support input set selection Jingjing Wu
2016-03-02 11:29     ` [PATCH v2 02/12] i40e: split function for input set change of hash and fdir Jingjing Wu
2016-03-02 11:29     ` [PATCH v2 03/12] i40e: remove flex payload from INPUT_SET_SELECT operation Jingjing Wu
2016-03-02 11:29     ` [PATCH v2 04/12] i40e: restore default setting on input set of filters Jingjing Wu
2016-03-02 11:30     ` [PATCH v2 05/12] i40e: extend flow director to filter by more IP Header fields Jingjing Wu
2016-03-02 11:30     ` [PATCH v2 06/12] testpmd: extend commands for filter's input set changing Jingjing Wu
2016-03-02 11:30     ` [PATCH v2 07/12] librte_ether: extend rte_eth_fdir_flow to support tunnel format Jingjing Wu
2016-03-02 11:30     ` [PATCH v2 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
2016-03-02 11:30     ` [PATCH v2 09/12] testpmd: extend commands for fdir's tunnel id input set Jingjing Wu
2016-03-02 11:30     ` [PATCH v2 10/12] i40e: fix VLAN bitmasks for hash/fdir input sets for tunnels Jingjing Wu
2016-03-02 11:30     ` [PATCH v2 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
2016-03-02 11:30     ` [PATCH v2 12/12] testpmd: extend commands for fdir's vlan input set Jingjing Wu
2016-03-09  5:42     ` [PATCH v3 00/12] extend flow director fields in i40e driver Jingjing Wu
2016-03-09  5:42       ` [PATCH v3 01/12] ethdev: extend flow director for input selection Jingjing Wu
2016-03-09  9:52         ` Thomas Monjalon
2016-03-09  9:56           ` Thomas Monjalon
2016-03-09  9:54         ` Thomas Monjalon
2016-03-09 10:26           ` Wu, Jingjing
2016-03-09 10:36             ` Thomas Monjalon
2016-03-09 11:22               ` Wu, Jingjing
2016-03-09  5:42       ` [PATCH v3 02/12] i40e: split function for hash and fdir input Jingjing Wu
2016-03-09  5:42       ` [PATCH v3 03/12] i40e: remove flex payload from input selection Jingjing Wu
2016-03-09  5:42       ` [PATCH v3 04/12] i40e: restore default setting on input set Jingjing Wu
2016-03-09  5:42       ` [PATCH v3 05/12] i40e: extend flow director to filter by IP Header Jingjing Wu
2016-03-09  5:42       ` [PATCH v3 06/12] testpmd: extend input set related commands Jingjing Wu
2016-03-09  5:42       ` [PATCH v3 07/12] librte_ether: extend flow director struct Jingjing Wu
2016-03-09  5:42       ` [PATCH v3 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
2016-03-09  5:42       ` [PATCH v3 09/12] testpmd: extend flow director commands Jingjing Wu
2016-03-09  5:42       ` [PATCH v3 10/12] i40e: fix VLAN bitmasks for input set Jingjing Wu
2016-03-09  5:42       ` [PATCH v3 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
2016-03-09  5:43       ` [PATCH v3 12/12] testpmd: extend flow director commands Jingjing Wu
2016-03-09  6:18       ` [PATCH v3 00/12] extend flow director fields in i40e driver Zhang, Helin
2016-03-10  3:25       ` [PATCH v4 " Jingjing Wu
2016-03-10  3:25         ` [PATCH v4 01/12] ethdev: extend flow director for input selection Jingjing Wu
2016-03-10  3:25         ` [PATCH v4 02/12] i40e: split function for hash and fdir input Jingjing Wu
2016-03-10  3:25         ` [PATCH v4 03/12] i40e: remove flex payload from input selection Jingjing Wu
2016-03-10  3:25         ` [PATCH v4 04/12] i40e: restore default setting on input set Jingjing Wu
2016-03-10  3:25         ` [PATCH v4 05/12] i40e: extend flow director to filter by IP Header Jingjing Wu
2016-03-10  3:25         ` [PATCH v4 06/12] testpmd: extend input set related commands Jingjing Wu
2016-03-10  3:25         ` [PATCH v4 07/12] librte_ether: extend flow director struct Jingjing Wu
2016-03-18 11:44           ` Thomas Monjalon
2016-03-20  8:56             ` Wu, Jingjing
2016-03-20  9:02             ` Wu, Jingjing
2016-03-20 10:38               ` Thomas Monjalon
2016-03-10  3:25         ` [PATCH v4 08/12] i40e: extend flow director to filter by tunnel ID Jingjing Wu
2016-03-10  3:25         ` [PATCH v4 09/12] testpmd: extend flow director commands Jingjing Wu
2016-03-10  3:25         ` [PATCH v4 10/12] i40e: fix VLAN bitmasks for input set Jingjing Wu
2016-03-10  3:25         ` [PATCH v4 11/12] i40e: extend flow director to filter by vlan id Jingjing Wu
2016-03-10  3:25         ` [PATCH v4 12/12] testpmd: extend flow director commands Jingjing Wu
2016-03-21  6:18         ` [PATCH v5 0/9] extend flow director fields in i40e driver Jingjing Wu
2016-03-21  6:18           ` [PATCH v5 1/9] ethdev: extend flow director for input selection Jingjing Wu
2016-03-22 22:05             ` Thomas Monjalon
2016-03-23  0:42               ` Wu, Jingjing
2016-03-23  8:45                 ` Thomas Monjalon
2016-03-21  6:18           ` [PATCH v5 2/9] i40e: split function for hash and fdir input Jingjing Wu
2016-03-21  6:18           ` [PATCH v5 3/9] i40e: remove flex payload from input selection Jingjing Wu
2016-03-21  6:18           ` [PATCH v5 4/9] i40e: restore default setting on input set Jingjing Wu
2016-03-21  6:18           ` [PATCH v5 5/9] i40e: extend flow director to filter by IP Header Jingjing Wu
2016-03-21  6:18           ` [PATCH v5 6/9] testpmd: extend input set related commands Jingjing Wu
2016-03-21  6:18           ` [PATCH v5 7/9] i40e: fix VLAN bitmasks for input set Jingjing Wu
2016-03-21  6:18           ` [PATCH v5 8/9] i40e: extend flow director to filter by vlan id Jingjing Wu
2016-03-21  6:48             ` Zhang, Helin
2016-03-21  6:18           ` [PATCH v5 9/9] testpmd: extend flow director commands Jingjing Wu
2016-03-21  6:48             ` Zhang, Helin
2016-03-22 21:51           ` [PATCH v5 0/9] extend flow director fields in i40e driver Bruce Richardson
2016-03-22 21:56             ` Thomas Monjalon
2016-03-23 13:07           ` [PATCH v6 " Jingjing Wu
2016-03-23 13:07             ` [PATCH v6 1/9] ethdev: extend flow director for input selection Jingjing Wu
2016-03-23 14:02               ` Thomas Monjalon
2016-03-23 13:07             ` [PATCH v6 2/9] i40e: split function for hash and fdir input Jingjing Wu
2016-03-23 13:07             ` [PATCH v6 3/9] i40e: remove flex payload from input selection Jingjing Wu
2016-03-23 13:07             ` [PATCH v6 4/9] i40e: use default filter input set on init Jingjing Wu
2016-03-23 13:07             ` [PATCH v6 5/9] i40e: allow filtering on more IP Header fields Jingjing Wu
2016-03-23 13:07             ` [PATCH v6 6/9] testpmd: extend input set related commands Jingjing Wu
2016-03-23 13:07             ` [PATCH v6 7/9] i40e: fix VLAN bitmasks for input set Jingjing Wu
2016-03-23 13:07             ` [PATCH v6 8/9] i40e: extend flow director to filter by vlan id Jingjing Wu
2016-03-23 13:07             ` [PATCH v6 9/9] testpmd: allow vlan as part of fdir input set Jingjing Wu
2016-03-23 14:46             ` [PATCH v6 0/9] extend flow director fields in i40e driver Bruce Richardson

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.