All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [dpdk-dev] [PATCH 2/3] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-09-24 16:22 ` [dpdk-dev] [PATCH 2/3] " Junfeng Guo
@ 2021-09-24  8:45   ` Van Haaren, Harry
  0 siblings, 0 replies; 68+ messages in thread
From: Van Haaren, Harry @ 2021-09-24  8:45 UTC (permalink / raw)
  To: Guo, Junfeng, Zhang, Qi Z, Wu, Jingjing, Xing, Beilei; +Cc: dev, Guo, Junfeng

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Junfeng Guo
> Sent: Friday, September 24, 2021 5:22 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Guo, Junfeng <junfeng.guo@intel.com>
> Subject: [dpdk-dev] [PATCH 2/3] net/ice: enable protocol agnostic flow
> offloading in FDIR
> 
> Protocol agnostic flow offloading in Flow Director is enabled by this
> patch based on the Parser Library, using existing rte_flow raw API,
> without public API change.
> 
> Note that the raw flow requires:
> 1. byte string of raw target packet bits.
> 2. byte string of mask of target packet.
> 
> Here is an example:
> FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:
> 
> flow create 0 ingress pattern raw \
> pattern spec \
> 00000000000000000000000008004500001400004000401000000000000001020304 \
> pattern mask \
> 000000000000000000000000000000000000000000000000000000000000ffffffff \
> / end actions queue index 3 / mark id 3 / end

To improve the documentation in the commit message, should the "00000800" (0x0800)
EtherType not be masked with 0xFFFF too? Non IPv4 packets which happen to have the
masked data "01020304" in that position would incorrectly match. By adding 0xFFFF in
the mask to check ethertype == 0x8000, this issue is resolved.

> 00000000000000000000000008004500001400004000401000000000000001020304 \
> pattern mask \
> 00000000000000000000FFFFFFFF00000000000000000000000000000000ffffffff \

Difficult to see if I changed correct characters in the string from 0 to F, but I hope the point is clear.

Regards, -Harry

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

* [dpdk-dev] [PATCH 0/3] enable protocol agnostic flow offloading in FDIR
@ 2021-09-24 16:22 Junfeng Guo
  2021-09-24 16:22 ` [dpdk-dev] [PATCH 1/3] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
                   ` (2 more replies)
  0 siblings, 3 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-09-24 16:22 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch set based on the Parser Library, using existing rte_flow raw
API, without public API change.

[PATCH 1/3] app/testpmd: update Max RAW pattern size to 512.
[PATCH 2/3] net/ice: enable protocol agnostic flow offloading in FDIR.
[PATCH 3/3] doc: enable protocol agnostic flow in FDIR.


Junfeng Guo (3):
  app/testpmd: update Max RAW pattern size to 512
  net/ice: enable protocol agnostic flow offloading in FDIR
  doc: enable protocol agnostic flow in FDIR

 app/test-pmd/cmdline_flow.c            |   2 +-
 doc/guides/rel_notes/release_21_11.rst |   5 +
 drivers/net/ice/ice_ethdev.h           |   5 +
 drivers/net/ice/ice_fdir_filter.c      | 167 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 ++
 drivers/net/ice/ice_generic_flow.h     |   3 +
 6 files changed, 188 insertions(+), 1 deletion(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH 1/3] app/testpmd: update Max RAW pattern size to 512
  2021-09-24 16:22 [dpdk-dev] [PATCH 0/3] enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-09-24 16:22 ` Junfeng Guo
  2021-09-28 10:18   ` [dpdk-dev] [PATCH v2 0/3] enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-09-24 16:22 ` [dpdk-dev] [PATCH 2/3] " Junfeng Guo
  2021-09-24 16:22 ` [dpdk-dev] [PATCH 3/3] doc: enable protocol agnostic flow " Junfeng Guo
  2 siblings, 1 reply; 68+ messages in thread
From: Junfeng Guo @ 2021-09-24 16:22 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, junfeng.guo

Update max size for pattern in struct rte_flow_item_raw to enable
protocol agnostic flow offloading.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 app/test-pmd/cmdline_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 6cd99bf37f..d108fde048 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -459,7 +459,7 @@ enum index {
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
-#define ITEM_RAW_PATTERN_SIZE 40
+#define ITEM_RAW_PATTERN_SIZE 512
 
 /** Maximum size for GENEVE option data pattern in bytes. */
 #define ITEM_GENEVE_OPT_DATA_SIZE 124
-- 
2.25.1


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

* [dpdk-dev] [PATCH 2/3] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-09-24 16:22 [dpdk-dev] [PATCH 0/3] enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-09-24 16:22 ` [dpdk-dev] [PATCH 1/3] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-09-24 16:22 ` Junfeng Guo
  2021-09-24  8:45   ` Van Haaren, Harry
  2021-09-24 16:22 ` [dpdk-dev] [PATCH 3/3] doc: enable protocol agnostic flow " Junfeng Guo
  2 siblings, 1 reply; 68+ messages in thread
From: Junfeng Guo @ 2021-09-24 16:22 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch based on the Parser Library, using existing rte_flow raw API,
without public API change.

Note that the raw flow requires:
1. byte string of raw target packet bits.
2. byte string of mask of target packet.

Here is an example:
FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:

flow create 0 ingress pattern raw \
pattern spec \
00000000000000000000000008004500001400004000401000000000000001020304 \
pattern mask \
000000000000000000000000000000000000000000000000000000000000ffffffff \
/ end actions queue index 3 / mark id 3 / end

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/ice_ethdev.h       |   5 +
 drivers/net/ice/ice_fdir_filter.c  | 167 +++++++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c |   7 ++
 drivers/net/ice/ice_generic_flow.h |   3 +
 4 files changed, 182 insertions(+)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index b4bf651c1c..8dc0c54bd7 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -304,6 +304,11 @@ struct ice_fdir_filter_conf {
 	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
 	uint64_t input_set_i; /* only for tunnel inner fields */
 	uint32_t mark_flag;
+
+	struct ice_parser_profile *prof;
+	const u8 *pkt_buf;
+	bool parser_ena;
+	u8 pkt_len;
 };
 
 #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
index 7ba65b9b04..375308781f 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -107,6 +107,7 @@
 	ICE_INSET_NAT_T_ESP_SPI)
 
 static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+	{pattern_raw,					ICE_INSET_NONE,			ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_ethertype,				ICE_FDIR_INSET_ETH,		ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,	ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,	ICE_INSET_NONE,			ICE_INSET_NONE},
@@ -1190,6 +1191,24 @@ ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type)
 		return 0;
 }
 
+static int
+ice_fdir_add_del_raw(struct ice_pf *pf,
+		     struct ice_fdir_filter_conf *filter,
+		     bool add)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
+	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
+
+	struct ice_fltr_desc desc;
+	memset(&desc, 0, sizeof(desc));
+	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
+	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
+
+	return ice_fdir_programming(pf, &desc);
+}
+
 static int
 ice_fdir_add_del_filter(struct ice_pf *pf,
 			struct ice_fdir_filter_conf *filter,
@@ -1306,6 +1325,45 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 	bool is_tun;
 	int ret;
 
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+
+		ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
+					   filter->prof, ICE_BLK_FD);
+		if (ret)
+			return -rte_errno;
+
+		ret = ice_fdir_add_del_raw(pf, filter, true);
+		if (ret)
+			return -rte_errno;
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 1);
+
+		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
+		if (!entry)
+			return -rte_errno;
+
+		entry->pkt_buf = (u8 *)ice_malloc(hw, filter->pkt_len);
+		if (!entry->pkt_buf)
+			return -ENOMEM;
+
+		u8 *pkt_buf = (u8 *)ice_malloc(hw, filter->pkt_len);
+		if (!pkt_buf)
+			return -ENOMEM;
+
+		rte_memcpy(entry, filter, sizeof(*filter));
+		rte_memcpy(pkt_buf, filter->pkt_buf, filter->pkt_len);
+		entry->pkt_buf = pkt_buf;
+
+		flow->rule = entry;
+
+		return 0;
+	}
+
 	ice_fdir_extract_fltr_key(&key, filter);
 	node = ice_fdir_entry_lookup(fdir_info, &key);
 	if (node) {
@@ -1401,6 +1459,19 @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
 
 	filter = (struct ice_fdir_filter_conf *)flow->rule;
 
+	if (filter->parser_ena) {
+		ret = ice_fdir_add_del_raw(pf, filter, false);
+		if (ret)
+			return -rte_errno;
+
+		filter->pkt_buf = NULL;
+		flow->rule = NULL;
+
+		rte_free(filter);
+
+		return 0;
+	}
+
 	is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type);
 
 	if (filter->counter) {
@@ -1679,6 +1750,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
 	enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END;
 	enum ice_fdir_tunnel_type tunnel_type = ICE_FDIR_TUNNEL_TYPE_NONE;
+	const struct rte_flow_item_raw *raw_spec, *raw_mask;
 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
@@ -1706,6 +1778,9 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	struct ice_fdir_extra *p_ext_data;
 	struct ice_fdir_v4 *p_v4 = NULL;
 	struct ice_fdir_v6 *p_v6 = NULL;
+	struct ice_parser_result rslt;
+	struct ice_parser *psr;
+	uint8_t item_num = 0;
 
 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 		if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN)
@@ -1717,6 +1792,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 		    item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
 			is_outer = false;
 		}
+		item_num++;
 	}
 
 	/* This loop parse flow pattern and distinguish Non-tunnel and tunnel
@@ -1737,6 +1813,90 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 			    &input_set_i : &input_set_o;
 
 		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_RAW:
+			raw_spec = item->spec;
+			raw_mask = item->mask;
+
+			if (item_num != 1)
+				break;
+
+			/* convert raw sepc & mask from byte string to int */
+			unsigned char *tmp_spec =
+				(uint8_t *)(uintptr_t)raw_spec->pattern;
+			unsigned char *tmp_mask =
+				(uint8_t *)(uintptr_t)raw_mask->pattern;
+			uint16_t tmp_val = 0;
+			uint8_t pkt_len = 0;
+			uint8_t tmp = 0;
+			int i, j;
+
+			pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern);
+			if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
+				pkt_len)
+				return -rte_errno;
+
+			for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
+				tmp = tmp_spec[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_spec[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_spec[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_spec[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_spec[j] = tmp_val + tmp - '0';
+
+				tmp = tmp_mask[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_mask[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_mask[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_mask[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_mask[j] = tmp_val + tmp - '0';
+			}
+
+			pkt_len /= 2;
+
+			if (ice_parser_create(&ad->hw, &psr))
+				return -rte_errno;
+			if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt))
+				return -rte_errno;
+			ice_parser_destroy(psr);
+
+			if (!tmp_mask)
+				return -rte_errno;
+
+			filter->prof = (struct ice_parser_profile *)
+				ice_malloc(&ad->hw, sizeof(filter->prof));
+			if (!filter->prof)
+				return -ENOMEM;
+			if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask,
+				pkt_len, ICE_BLK_FD, true, filter->prof))
+				return -rte_errno;
+
+			filter->pkt_buf = tmp_spec;
+			filter->pkt_len = pkt_len;
+
+			filter->parser_ena = true;
+
+			break;
+
 		case RTE_FLOW_ITEM_TYPE_ETH:
 			flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
 			eth_spec = item->spec;
@@ -2202,6 +2362,7 @@ ice_fdir_parse(struct ice_adapter *ad,
 	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
 	struct ice_pattern_match_item *item = NULL;
 	uint64_t input_set;
+	bool raw = false;
 	int ret;
 
 	memset(filter, 0, sizeof(*filter));
@@ -2213,7 +2374,13 @@ ice_fdir_parse(struct ice_adapter *ad,
 	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
 	if (ret)
 		goto error;
+
+	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
+		raw = true;
+
 	input_set = filter->input_set_o | filter->input_set_i;
+	input_set = raw ? ~input_set : input_set;
+
 	if (!input_set || filter->input_set_o &
 	    ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) ||
 	    filter->input_set_i & ~item->input_set_mask_i) {
diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 9e03c2856c..c979fce080 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -65,6 +65,12 @@ enum rte_flow_item_type pattern_empty[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* raw */
+enum rte_flow_item_type pattern_raw[] = {
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 /* L2 */
 enum rte_flow_item_type pattern_ethertype[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
@@ -2081,6 +2087,7 @@ struct ice_ptype_match {
 };
 
 static struct ice_ptype_match ice_ptype_map[] = {
+	{pattern_raw,					ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4,				ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4_udp,				ICE_PTYPE_IPV4_UDP_PAY},
 	{pattern_eth_ipv4_tcp,				ICE_PTYPE_IPV4_TCP_PAY},
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index 8845a3e156..1b030c0466 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -124,6 +124,9 @@
 /* empty pattern */
 extern enum rte_flow_item_type pattern_empty[];
 
+/* raw pattern */
+extern enum rte_flow_item_type pattern_raw[];
+
 /* L2 */
 extern enum rte_flow_item_type pattern_ethertype[];
 extern enum rte_flow_item_type pattern_ethertype_vlan[];
-- 
2.25.1


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

* [dpdk-dev] [PATCH 3/3] doc: enable protocol agnostic flow in FDIR
  2021-09-24 16:22 [dpdk-dev] [PATCH 0/3] enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-09-24 16:22 ` [dpdk-dev] [PATCH 1/3] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
  2021-09-24 16:22 ` [dpdk-dev] [PATCH 2/3] " Junfeng Guo
@ 2021-09-24 16:22 ` Junfeng Guo
  2 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-09-24 16:22 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled based
on the Parser Library, using existing rte_flow raw API, using
existing rte_flow raw API, without public API change.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index f5d16993db..59ee3ef22c 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -62,6 +62,11 @@ New Features
   * Added bus-level parsing of the devargs syntax.
   * Kept compatibility with the legacy syntax as parsing fallback.
 
+* **Updated Intel ice driver.**
+
+  * Enabled protocol agnostic flow offloading in Flow Director based on the
+    parser library, using existing rte_flow raw API, without public API change.
+
 * **Add new RSS offload types for IPv4/L4 checksum in RSS flow.**
 
   Add macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and
-- 
2.25.1


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

* [dpdk-dev] [PATCH v2 0/3] enable protocol agnostic flow offloading in FDIR
  2021-09-24 16:22 ` [dpdk-dev] [PATCH 1/3] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-09-28 10:18   ` Junfeng Guo
  2021-09-28 10:18     ` [dpdk-dev] [PATCH v2 1/3] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
                       ` (2 more replies)
  0 siblings, 3 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-09-28 10:18 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ferruh.yigit, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch set based on the Parser Library using existing rte_flow raw API

[PATCH v2 1/3] app/testpmd: update Max RAW pattern size to 512.
[PATCH v2 2/3] net/ice: enable protocol agnostic flow offloading in FDIR.
[PATCH v2 3/3] doc: enable protocol agnostic flow in FDIR.

Junfeng Guo (3):
  app/testpmd: update Max RAW pattern size to 512
  net/ice: enable protocol agnostic flow offloading in FDIR
  doc: enable protocol agnostic flow in FDIR

* v2
Enabled vxlan port add for raw flow and updated commit message


 app/test-pmd/cmdline_flow.c            |   2 +-
 doc/guides/rel_notes/release_21_11.rst |   5 +
 drivers/net/ice/ice_ethdev.h           |   5 +
 drivers/net/ice/ice_fdir_filter.c      | 172 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 6 files changed, 193 insertions(+), 1 deletion(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH v2 1/3] app/testpmd: update Max RAW pattern size to 512
  2021-09-28 10:18   ` [dpdk-dev] [PATCH v2 0/3] enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-09-28 10:18     ` Junfeng Guo
  2021-09-28 10:18     ` [dpdk-dev] [PATCH v2 2/3] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-09-28 10:18     ` [dpdk-dev] [PATCH v2 3/3] doc: enable protocol agnostic flow " Junfeng Guo
  2 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-09-28 10:18 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ferruh.yigit, junfeng.guo

Update max size for pattern in struct rte_flow_item_raw to enable
protocol agnostic flow offloading.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 app/test-pmd/cmdline_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 6cd99bf37f..d108fde048 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -459,7 +459,7 @@ enum index {
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
-#define ITEM_RAW_PATTERN_SIZE 40
+#define ITEM_RAW_PATTERN_SIZE 512
 
 /** Maximum size for GENEVE option data pattern in bytes. */
 #define ITEM_GENEVE_OPT_DATA_SIZE 124
-- 
2.25.1


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

* [dpdk-dev] [PATCH v2 2/3] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-09-28 10:18   ` [dpdk-dev] [PATCH v2 0/3] enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-09-28 10:18     ` [dpdk-dev] [PATCH v2 1/3] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-09-28 10:18     ` Junfeng Guo
  2021-09-28 10:18     ` [dpdk-dev] [PATCH v2 3/3] doc: enable protocol agnostic flow " Junfeng Guo
  2 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-09-28 10:18 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ferruh.yigit, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch based on the Parser Library, using existing rte_flow raw API.

Note that the raw flow requires:
1. byte string of raw target packet bits.
2. byte string of mask of target packet.

Here is an example:
FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:

flow create 0 ingress pattern raw \
pattern spec \
00000000000000000000000008004500001400004000401000000000000001020304 \
pattern mask \
000000000000000000000000000000000000000000000000000000000000ffffffff \
/ end actions queue index 3 / mark id 3 / end

Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto)
is optional in our cases. To avoid redundancy, we just omit the mask
of 0x0800 (with 0xFFFF) in the mask byte string example. The prefix
'0x' for the spec and mask byte (hex) strings are also omitted here.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/ice_ethdev.h       |   5 +
 drivers/net/ice/ice_fdir_filter.c  | 172 +++++++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c |   7 ++
 drivers/net/ice/ice_generic_flow.h |   3 +
 4 files changed, 187 insertions(+)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 26f5c560f4..1ab883c7b8 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -316,6 +316,11 @@ struct ice_fdir_filter_conf {
 	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
 	uint64_t input_set_i; /* only for tunnel inner fields */
 	uint32_t mark_flag;
+
+	struct ice_parser_profile *prof;
+	const u8 *pkt_buf;
+	bool parser_ena;
+	u8 pkt_len;
 };
 
 #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
index af9669fac6..17f8cee06b 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -107,6 +107,7 @@
 	ICE_INSET_NAT_T_ESP_SPI)
 
 static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+	{pattern_raw,					ICE_INSET_NONE,			ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_ethertype,				ICE_FDIR_INSET_ETH,		ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,	ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,	ICE_INSET_NONE,			ICE_INSET_NONE},
@@ -1190,6 +1191,24 @@ ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type)
 		return 0;
 }
 
+static int
+ice_fdir_add_del_raw(struct ice_pf *pf,
+		     struct ice_fdir_filter_conf *filter,
+		     bool add)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
+	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
+
+	struct ice_fltr_desc desc;
+	memset(&desc, 0, sizeof(desc));
+	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
+	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
+
+	return ice_fdir_programming(pf, &desc);
+}
+
 static int
 ice_fdir_add_del_filter(struct ice_pf *pf,
 			struct ice_fdir_filter_conf *filter,
@@ -1306,6 +1325,45 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 	bool is_tun;
 	int ret;
 
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+
+		ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
+					   filter->prof, ICE_BLK_FD);
+		if (ret)
+			return -rte_errno;
+
+		ret = ice_fdir_add_del_raw(pf, filter, true);
+		if (ret)
+			return -rte_errno;
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 1);
+
+		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
+		if (!entry)
+			return -rte_errno;
+
+		entry->pkt_buf = (u8 *)ice_malloc(hw, filter->pkt_len);
+		if (!entry->pkt_buf)
+			return -ENOMEM;
+
+		u8 *pkt_buf = (u8 *)ice_malloc(hw, filter->pkt_len);
+		if (!pkt_buf)
+			return -ENOMEM;
+
+		rte_memcpy(entry, filter, sizeof(*filter));
+		rte_memcpy(pkt_buf, filter->pkt_buf, filter->pkt_len);
+		entry->pkt_buf = pkt_buf;
+
+		flow->rule = entry;
+
+		return 0;
+	}
+
 	ice_fdir_extract_fltr_key(&key, filter);
 	node = ice_fdir_entry_lookup(fdir_info, &key);
 	if (node) {
@@ -1401,6 +1459,19 @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
 
 	filter = (struct ice_fdir_filter_conf *)flow->rule;
 
+	if (filter->parser_ena) {
+		ret = ice_fdir_add_del_raw(pf, filter, false);
+		if (ret)
+			return -rte_errno;
+
+		filter->pkt_buf = NULL;
+		flow->rule = NULL;
+
+		rte_free(filter);
+
+		return 0;
+	}
+
 	is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type);
 
 	if (filter->counter) {
@@ -1679,6 +1750,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
 	enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END;
 	enum ice_fdir_tunnel_type tunnel_type = ICE_FDIR_TUNNEL_TYPE_NONE;
+	const struct rte_flow_item_raw *raw_spec, *raw_mask;
 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
@@ -1706,6 +1778,9 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	struct ice_fdir_extra *p_ext_data;
 	struct ice_fdir_v4 *p_v4 = NULL;
 	struct ice_fdir_v6 *p_v6 = NULL;
+	struct ice_parser_result rslt;
+	struct ice_parser *psr;
+	uint8_t item_num = 0;
 
 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 		if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN)
@@ -1717,6 +1792,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 		    item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
 			is_outer = false;
 		}
+		item_num++;
 	}
 
 	/* This loop parse flow pattern and distinguish Non-tunnel and tunnel
@@ -1737,6 +1813,95 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 			    &input_set_i : &input_set_o;
 
 		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_RAW:
+			raw_spec = item->spec;
+			raw_mask = item->mask;
+
+			if (item_num != 1)
+				break;
+
+			/* convert raw spec & mask from byte string to int */
+			unsigned char *tmp_spec =
+				(uint8_t *)(uintptr_t)raw_spec->pattern;
+			unsigned char *tmp_mask =
+				(uint8_t *)(uintptr_t)raw_mask->pattern;
+			uint16_t udp_port = 0;
+			uint16_t tmp_val = 0;
+			uint8_t pkt_len = 0;
+			uint8_t tmp = 0;
+			int i, j;
+
+			pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern);
+			if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
+				pkt_len)
+				return -rte_errno;
+
+			for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
+				tmp = tmp_spec[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_spec[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_spec[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_spec[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_spec[j] = tmp_val + tmp - '0';
+
+				tmp = tmp_mask[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_mask[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_mask[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_mask[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_mask[j] = tmp_val + tmp - '0';
+			}
+
+			pkt_len /= 2;
+
+			if (ice_parser_create(&ad->hw, &psr))
+				return -rte_errno;
+			if (ice_get_open_tunnel_port(&ad->hw, TNL_VXLAN,
+						     &udp_port))
+				ice_parser_vxlan_tunnel_set(psr, udp_port,
+							    true);
+			if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt))
+				return -rte_errno;
+			ice_parser_destroy(psr);
+
+			if (!tmp_mask)
+				return -rte_errno;
+
+			filter->prof = (struct ice_parser_profile *)
+				ice_malloc(&ad->hw, sizeof(filter->prof));
+			if (!filter->prof)
+				return -ENOMEM;
+			if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask,
+				pkt_len, ICE_BLK_FD, true, filter->prof))
+				return -rte_errno;
+
+			filter->pkt_buf = tmp_spec;
+			filter->pkt_len = pkt_len;
+
+			filter->parser_ena = true;
+
+			break;
+
 		case RTE_FLOW_ITEM_TYPE_ETH:
 			flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
 			eth_spec = item->spec;
@@ -2202,6 +2367,7 @@ ice_fdir_parse(struct ice_adapter *ad,
 	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
 	struct ice_pattern_match_item *item = NULL;
 	uint64_t input_set;
+	bool raw = false;
 	int ret;
 
 	memset(filter, 0, sizeof(*filter));
@@ -2217,7 +2383,13 @@ ice_fdir_parse(struct ice_adapter *ad,
 	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
 	if (ret)
 		goto error;
+
+	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
+		raw = true;
+
 	input_set = filter->input_set_o | filter->input_set_i;
+	input_set = raw ? ~input_set : input_set;
+
 	if (!input_set || filter->input_set_o &
 	    ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) ||
 	    filter->input_set_i & ~item->input_set_mask_i) {
diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 13e3734172..b6083ef0a4 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -65,6 +65,12 @@ enum rte_flow_item_type pattern_empty[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* raw */
+enum rte_flow_item_type pattern_raw[] = {
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 /* L2 */
 enum rte_flow_item_type pattern_ethertype[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
@@ -2081,6 +2087,7 @@ struct ice_ptype_match {
 };
 
 static struct ice_ptype_match ice_ptype_map[] = {
+	{pattern_raw,					ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4,				ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4_udp,				ICE_PTYPE_IPV4_UDP_PAY},
 	{pattern_eth_ipv4_tcp,				ICE_PTYPE_IPV4_TCP_PAY},
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index 8845a3e156..1b030c0466 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -124,6 +124,9 @@
 /* empty pattern */
 extern enum rte_flow_item_type pattern_empty[];
 
+/* raw pattern */
+extern enum rte_flow_item_type pattern_raw[];
+
 /* L2 */
 extern enum rte_flow_item_type pattern_ethertype[];
 extern enum rte_flow_item_type pattern_ethertype_vlan[];
-- 
2.25.1


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

* [dpdk-dev] [PATCH v2 3/3] doc: enable protocol agnostic flow in FDIR
  2021-09-28 10:18   ` [dpdk-dev] [PATCH v2 0/3] enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-09-28 10:18     ` [dpdk-dev] [PATCH v2 1/3] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
  2021-09-28 10:18     ` [dpdk-dev] [PATCH v2 2/3] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-09-28 10:18     ` Junfeng Guo
  2021-10-14 15:37       ` [dpdk-dev] [PATCH v3 0/5] enable protocol agnostic flow offloading " Junfeng Guo
  2 siblings, 1 reply; 68+ messages in thread
From: Junfeng Guo @ 2021-09-28 10:18 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ferruh.yigit, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled based
on the Parser Library, using existing rte_flow raw API.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 8e298337b4..0688233b8b 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -62,6 +62,11 @@ New Features
   * Added bus-level parsing of the devargs syntax.
   * Kept compatibility with the legacy syntax as parsing fallback.
 
+* **Updated Intel ice driver.**
+
+  * Enabled protocol agnostic flow offloading in Flow Director based on the
+    parser library, using existing rte_flow raw API.
+
 * **Add new RSS offload types for IPv4/L4 checksum in RSS flow.**
 
   Add macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and
-- 
2.25.1


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

* [dpdk-dev] [PATCH v3 0/5] enable protocol agnostic flow offloading in FDIR
  2021-09-28 10:18     ` [dpdk-dev] [PATCH v2 3/3] doc: enable protocol agnostic flow " Junfeng Guo
@ 2021-10-14 15:37       ` Junfeng Guo
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 1/5] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
                           ` (4 more replies)
  0 siblings, 5 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-14 15:37 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ferruh.yigit, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch set based on the Parser Library using existing rte_flow raw API

[PATCH v3 1/5] net/ice/base: add method to disable FDIR SWAP option.
[PATCH v3 2/5] net/ice/base: add function to set HW profile for raw flow.
[PATCH v3 3/5] app/testpmd: update Max RAW pattern size to 512.
[PATCH v3 4/5] net/ice: enable protocol agnostic flow offloading in FDIR.
[PATCH v3 5/5] doc: enable protocol agnostic flow in FDIR.

Junfeng Guo (5):
  net/ice/base: add method to disable FDIR SWAP option
  net/ice/base: add function to set HW profile for raw flow
  app/testpmd: update Max RAW pattern size to 512
  net/ice: enable protocol agnostic flow offloading in FDIR
  doc: enable protocol agnostic flow in FDIR

* v3:
Added necessary base code for raw flow in FDIR.

* v2:
Enabled vxlan port add for raw flow and updated commit message

 app/test-pmd/cmdline_flow.c            |   2 +-
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/base/ice_flex_pipe.c   | 100 +++++++++++++-
 drivers/net/ice/base/ice_flex_pipe.h   |   6 +-
 drivers/net/ice/base/ice_flow.c        |  86 ++++++++++++-
 drivers/net/ice/base/ice_flow.h        |   4 +
 drivers/net/ice/ice_ethdev.h           |   5 +
 drivers/net/ice/ice_fdir_filter.c      | 172 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 10 files changed, 381 insertions(+), 5 deletions(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH v3 1/5] net/ice/base: add method to disable FDIR SWAP option
  2021-10-14 15:37       ` [dpdk-dev] [PATCH v3 0/5] enable protocol agnostic flow offloading " Junfeng Guo
@ 2021-10-14 15:37         ` Junfeng Guo
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 2/5] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
                           ` (3 subsequent siblings)
  4 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-14 15:37 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ferruh.yigit, junfeng.guo

The SWAP Flag in the FDIR Programming Descriptor doesn't work, thus
add a method to disable the FDIR SWAP option by setting the swap and
inset register set with certain values. The boolean fd_swap is used
to enable/disable the SWAP option.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 44 ++++++++++++++++++++++++++--
 drivers/net/ice/base/ice_flex_pipe.h |  3 +-
 drivers/net/ice/base/ice_flow.c      |  2 +-
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index f35d59f4f5..06a233990f 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -4952,6 +4952,43 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 	return ICE_SUCCESS;
 }
 
+/**
+ * ice_disable_fd_swap - set register appropriately to disable FD swap
+ * @hw: pointer to the HW struct
+ * @prof_id: profile ID
+ */
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id)
+{
+	u8 swap_val = ICE_SWAP_VALID;
+	u8 i;
+	/* Since the SWAP Flag in the Programming Desc doesn't work,
+	 * here add method to disable the SWAP Option via setting
+	 * certain SWAP and INSET register set.
+	 */
+	for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw / 4; i++) {
+		u32 raw_swap = 0;
+		u32 raw_in = 0;
+		u8 j;
+
+		for (j = 0; j < 4; j++) {
+			raw_swap |= (swap_val++) << (j * BITS_PER_BYTE);
+			raw_in |= ICE_INSET_DFLT << (j * BITS_PER_BYTE);
+		}
+
+		/* write the FDIR swap register set */
+		wr32(hw, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		/* write the FDIR inset register set */
+		wr32(hw, GLQF_FDINSET(prof_id, i), raw_in);
+
+		ice_debug(hw, ICE_DBG_INIT, "inset wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDINSET(prof_id, i), raw_in);
+	}
+}
+
 /**
  * ice_add_prof - add profile
  * @hw: pointer to the HW struct
@@ -4962,6 +4999,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
  * @attr_cnt: number of elements in attrib array
  * @es: extraction sequence (length of array is determined by the block)
  * @masks: mask for extraction sequence
+ * @fd_swap: enable/disable FDIR paired src/dst fields swap option
  *
  * This function registers a profile, which matches a set of PTYPES with a
  * particular extraction sequence. While the hardware profile is allocated
@@ -4971,7 +5009,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks)
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap)
 {
 	u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE);
 	ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT);
@@ -4991,7 +5029,7 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 		status = ice_alloc_prof_id(hw, blk, &prof_id);
 		if (status)
 			goto err_ice_add_prof;
-		if (blk == ICE_BLK_FD) {
+		if (blk == ICE_BLK_FD && fd_swap) {
 			/* For Flow Director block, the extraction sequence may
 			 * need to be altered in the case where there are paired
 			 * fields that have no match. This is necessary because
@@ -5002,6 +5040,8 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 			status = ice_update_fd_swap(hw, prof_id, es);
 			if (status)
 				goto err_ice_add_prof;
+		} else if (blk == ICE_BLK_FD) {
+			ice_disable_fd_swap(hw, prof_id);
 		}
 		status = ice_update_prof_masking(hw, blk, prof_id, masks);
 		if (status)
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index 9733c4b214..dd332312dd 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -61,10 +61,11 @@ bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype);
 /* XLT2/VSI group functions */
 enum ice_status
 ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig);
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id);
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks);
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap);
 void ice_init_all_prof_masks(struct ice_hw *hw);
 void ice_shutdown_all_prof_masks(struct ice_hw *hw);
 struct ice_prof_map *
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 96d54b494d..77b6b130c1 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2244,7 +2244,7 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
 	/* Add a HW profile for this flow profile */
 	status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
 			      params->attr, params->attr_cnt, params->es,
-			      params->mask);
+			      params->mask, true);
 	if (status) {
 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
 		goto out;
-- 
2.25.1


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

* [dpdk-dev] [PATCH v3 2/5] net/ice/base: add function to set HW profile for raw flow
  2021-10-14 15:37       ` [dpdk-dev] [PATCH v3 0/5] enable protocol agnostic flow offloading " Junfeng Guo
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 1/5] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
@ 2021-10-14 15:37         ` Junfeng Guo
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 3/5] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-14 15:37 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ferruh.yigit, junfeng.guo

Based on the parser library, we can directly set HW profile and
associate the main/ctrl vsi.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 56 +++++++++++++++++++
 drivers/net/ice/base/ice_flex_pipe.h |  3 +
 drivers/net/ice/base/ice_flow.c      | 84 ++++++++++++++++++++++++++++
 drivers/net/ice/base/ice_flow.h      |  4 ++
 4 files changed, 147 insertions(+)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index 06a233990f..be8f014585 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -6365,3 +6365,59 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
 
 	return status;
 }
+
+/**
+ * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow entry
+ * @hw: pointer to the HW struct
+ * @blk: HW block
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @id: profile id (handle)
+ *
+ * Calling this function will update the hardware tables to enable the
+ * profile indicated by the ID parameter for the VSIs specified in the VSI
+ * array. Once successfully called, the flow will be enabled.
+ */
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id)
+{
+	enum ice_status status = ICE_SUCCESS;
+	u16 vsi_num;
+	u16 vsig;
+
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	if (!ice_vsig_find_vsi(hw, blk, vsi_num, &vsig) && !vsig)
+		if (!ice_has_prof_vsig(hw, blk, vsig, id)) {
+			status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+			if (status) {
+				ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for main VSI flow entry, %d\n",
+					  status);
+				goto err_add_prof;
+			}
+		}
+
+	if (blk != ICE_BLK_FD)
+		return status;
+
+	vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi_handle);
+	if (!ice_vsig_find_vsi(hw, blk, vsi_num, &vsig) && !vsig)
+		if (!ice_has_prof_vsig(hw, blk, vsig, id)) {
+			status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+			if (status) {
+				ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for ctrl VSI flow entry, %d\n",
+					  status);
+				goto err_add_entry;
+			}
+		}
+
+	return status;
+
+err_add_entry:
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+err_add_prof:
+	ice_flow_rem_prof(hw, blk, id);
+
+	return status;
+}
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index dd332312dd..23ba45564a 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -76,6 +76,9 @@ enum ice_status
 ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 enum ice_status
 ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id);
 enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
 enum ice_status
 ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 77b6b130c1..f699dbbc74 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2524,6 +2524,90 @@ ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
 	return status;
 }
 
+#define FLAG_GTP_EH_PDU_LINK	BIT_ULL(13)
+#define FLAG_GTP_EH_PDU		BIT_ULL(14)
+
+#define FLAG_GTPU_MSK	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_DW	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_UP	\
+	(FLAG_GTP_EH_PDU)
+/**
+ * ice_flow_set_hw_prof - Set HW flow profile based on the parsed profile info
+ * @hw: pointer to the HW struct
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @prof: stores parsed profile info from raw flow
+ * @blk: classification stage
+ */
+enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk)
+{
+	int id = ice_find_first_bit(prof->ptypes, UINT16_MAX);
+	struct ice_flow_prof_params *params;
+	u8 fv_words = hw->blk[blk].es.fvw;
+	enum ice_status status;
+	u16 vsi_num;
+	int i, idx;
+
+	params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
+	if (!params)
+		return ICE_ERR_NO_MEMORY;
+
+	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
+		params->es[i].prot_id = ICE_PROT_INVALID;
+		params->es[i].off = ICE_FV_OFFSET_INVAL;
+	}
+
+	for (i = 0; i < prof->fv_num; i++) {
+		if (hw->blk[blk].es.reverse)
+			idx = fv_words - i - 1;
+		else
+			idx = i;
+		params->es[idx].prot_id = prof->fv[i].proto_id;
+		params->es[idx].off = prof->fv[i].offset;
+		params->mask[idx] = CPU_TO_BE16(prof->fv[i].msk);
+	}
+
+	switch (prof->flags) {
+	case FLAG_GTPU_DW:
+		params->attr = ice_attr_gtpu_down;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
+		break;
+	case FLAG_GTPU_UP:
+		params->attr = ice_attr_gtpu_up;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
+		break;
+	default:
+		if (prof->flags_msk & FLAG_GTPU_MSK) {
+			params->attr = ice_attr_gtpu_session;
+			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
+		}
+		break;
+	}
+
+	status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
+			      params->attr, params->attr_cnt,
+			      params->es, params->mask, false);
+	if (status)
+		goto free_params;
+
+	status = ice_flow_assoc_hw_prof(hw, blk, dest_vsi_handle,
+					fdir_vsi_handle, id);
+	if (status)
+		goto free_params;
+
+	return ICE_SUCCESS;
+
+free_params:
+	ice_free(hw, params);
+
+	return status;
+}
+
 /**
  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
  * @hw: pointer to the HW struct
diff --git a/drivers/net/ice/base/ice_flow.h b/drivers/net/ice/base/ice_flow.h
index 371d960066..dea7b3c0e8 100644
--- a/drivers/net/ice/base/ice_flow.h
+++ b/drivers/net/ice/base/ice_flow.h
@@ -548,6 +548,10 @@ enum ice_status
 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
 			u16 vsig);
 enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk);
+enum ice_status
 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
 		     u8 *hw_prof);
 
-- 
2.25.1


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

* [dpdk-dev] [PATCH v3 3/5] app/testpmd: update Max RAW pattern size to 512
  2021-10-14 15:37       ` [dpdk-dev] [PATCH v3 0/5] enable protocol agnostic flow offloading " Junfeng Guo
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 1/5] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 2/5] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
@ 2021-10-14 15:37         ` Junfeng Guo
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 4/5] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 5/5] doc: enable protocol agnostic flow " Junfeng Guo
  4 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-14 15:37 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ferruh.yigit, junfeng.guo

Update max size for pattern in struct rte_flow_item_raw to enable
protocol agnostic flow offloading.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 app/test-pmd/cmdline_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 0b5856c7d5..c8f621a441 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -458,7 +458,7 @@ enum index {
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
-#define ITEM_RAW_PATTERN_SIZE 40
+#define ITEM_RAW_PATTERN_SIZE 512
 
 /** Maximum size for GENEVE option data pattern in bytes. */
 #define ITEM_GENEVE_OPT_DATA_SIZE 124
-- 
2.25.1


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

* [dpdk-dev] [PATCH v3 4/5] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-10-14 15:37       ` [dpdk-dev] [PATCH v3 0/5] enable protocol agnostic flow offloading " Junfeng Guo
                           ` (2 preceding siblings ...)
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 3/5] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-10-14 15:37         ` Junfeng Guo
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 5/5] doc: enable protocol agnostic flow " Junfeng Guo
  4 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-14 15:37 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ferruh.yigit, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch based on the Parser Library, using existing rte_flow raw API.

Note that the raw flow requires:
1. byte string of raw target packet bits.
2. byte string of mask of target packet.

Here is an example:
FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:

flow create 0 ingress pattern raw \
pattern spec \
00000000000000000000000008004500001400004000401000000000000001020304 \
pattern mask \
000000000000000000000000000000000000000000000000000000000000ffffffff \
/ end actions queue index 3 / mark id 3 / end

Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto)
is optional in our cases. To avoid redundancy, we just omit the mask
of 0x0800 (with 0xFFFF) in the mask byte string example. The prefix
'0x' for the spec and mask byte (hex) strings are also omitted here.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/ice_ethdev.h       |   5 +
 drivers/net/ice/ice_fdir_filter.c  | 172 +++++++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c |   7 ++
 drivers/net/ice/ice_generic_flow.h |   3 +
 4 files changed, 187 insertions(+)

diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 5845f44c86..e21d2349bc 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -317,6 +317,11 @@ struct ice_fdir_filter_conf {
 	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
 	uint64_t input_set_i; /* only for tunnel inner fields */
 	uint32_t mark_flag;
+
+	struct ice_parser_profile *prof;
+	const u8 *pkt_buf;
+	bool parser_ena;
+	u8 pkt_len;
 };
 
 #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
index bd627e3aa8..4af6f371f4 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -107,6 +107,7 @@
 	ICE_INSET_NAT_T_ESP_SPI)
 
 static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+	{pattern_raw,					ICE_INSET_NONE,			ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_ethertype,				ICE_FDIR_INSET_ETH,		ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,	ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,	ICE_INSET_NONE,			ICE_INSET_NONE},
@@ -1188,6 +1189,24 @@ ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type)
 		return 0;
 }
 
+static int
+ice_fdir_add_del_raw(struct ice_pf *pf,
+		     struct ice_fdir_filter_conf *filter,
+		     bool add)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
+	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
+
+	struct ice_fltr_desc desc;
+	memset(&desc, 0, sizeof(desc));
+	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
+	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
+
+	return ice_fdir_programming(pf, &desc);
+}
+
 static int
 ice_fdir_add_del_filter(struct ice_pf *pf,
 			struct ice_fdir_filter_conf *filter,
@@ -1304,6 +1323,45 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 	bool is_tun;
 	int ret;
 
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+
+		ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
+					   filter->prof, ICE_BLK_FD);
+		if (ret)
+			return -rte_errno;
+
+		ret = ice_fdir_add_del_raw(pf, filter, true);
+		if (ret)
+			return -rte_errno;
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 1);
+
+		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
+		if (!entry)
+			return -rte_errno;
+
+		entry->pkt_buf = (u8 *)ice_malloc(hw, filter->pkt_len);
+		if (!entry->pkt_buf)
+			return -ENOMEM;
+
+		u8 *pkt_buf = (u8 *)ice_malloc(hw, filter->pkt_len);
+		if (!pkt_buf)
+			return -ENOMEM;
+
+		rte_memcpy(entry, filter, sizeof(*filter));
+		rte_memcpy(pkt_buf, filter->pkt_buf, filter->pkt_len);
+		entry->pkt_buf = pkt_buf;
+
+		flow->rule = entry;
+
+		return 0;
+	}
+
 	ice_fdir_extract_fltr_key(&key, filter);
 	node = ice_fdir_entry_lookup(fdir_info, &key);
 	if (node) {
@@ -1397,6 +1455,19 @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
 
 	filter = (struct ice_fdir_filter_conf *)flow->rule;
 
+	if (filter->parser_ena) {
+		ret = ice_fdir_add_del_raw(pf, filter, false);
+		if (ret)
+			return -rte_errno;
+
+		filter->pkt_buf = NULL;
+		flow->rule = NULL;
+
+		rte_free(filter);
+
+		return 0;
+	}
+
 	is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type);
 
 	if (filter->counter) {
@@ -1675,6 +1746,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
 	enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END;
 	enum ice_fdir_tunnel_type tunnel_type = ICE_FDIR_TUNNEL_TYPE_NONE;
+	const struct rte_flow_item_raw *raw_spec, *raw_mask;
 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
@@ -1702,6 +1774,9 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	struct ice_fdir_extra *p_ext_data;
 	struct ice_fdir_v4 *p_v4 = NULL;
 	struct ice_fdir_v6 *p_v6 = NULL;
+	struct ice_parser_result rslt;
+	struct ice_parser *psr;
+	uint8_t item_num = 0;
 
 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 		if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN)
@@ -1713,6 +1788,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 		    item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
 			is_outer = false;
 		}
+		item_num++;
 	}
 
 	/* This loop parse flow pattern and distinguish Non-tunnel and tunnel
@@ -1733,6 +1809,95 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 			    &input_set_i : &input_set_o;
 
 		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_RAW:
+			raw_spec = item->spec;
+			raw_mask = item->mask;
+
+			if (item_num != 1)
+				break;
+
+			/* convert raw spec & mask from byte string to int */
+			unsigned char *tmp_spec =
+				(uint8_t *)(uintptr_t)raw_spec->pattern;
+			unsigned char *tmp_mask =
+				(uint8_t *)(uintptr_t)raw_mask->pattern;
+			uint16_t udp_port = 0;
+			uint16_t tmp_val = 0;
+			uint8_t pkt_len = 0;
+			uint8_t tmp = 0;
+			int i, j;
+
+			pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern);
+			if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
+				pkt_len)
+				return -rte_errno;
+
+			for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
+				tmp = tmp_spec[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_spec[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_spec[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_spec[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_spec[j] = tmp_val + tmp - '0';
+
+				tmp = tmp_mask[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_mask[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_mask[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_mask[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_mask[j] = tmp_val + tmp - '0';
+			}
+
+			pkt_len /= 2;
+
+			if (ice_parser_create(&ad->hw, &psr))
+				return -rte_errno;
+			if (ice_get_open_tunnel_port(&ad->hw, TNL_VXLAN,
+						     &udp_port))
+				ice_parser_vxlan_tunnel_set(psr, udp_port,
+							    true);
+			if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt))
+				return -rte_errno;
+			ice_parser_destroy(psr);
+
+			if (!tmp_mask)
+				return -rte_errno;
+
+			filter->prof = (struct ice_parser_profile *)
+				ice_malloc(&ad->hw, sizeof(filter->prof));
+			if (!filter->prof)
+				return -ENOMEM;
+			if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask,
+				pkt_len, ICE_BLK_FD, true, filter->prof))
+				return -rte_errno;
+
+			filter->pkt_buf = tmp_spec;
+			filter->pkt_len = pkt_len;
+
+			filter->parser_ena = true;
+
+			break;
+
 		case RTE_FLOW_ITEM_TYPE_ETH:
 			flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
 			eth_spec = item->spec;
@@ -2198,6 +2363,7 @@ ice_fdir_parse(struct ice_adapter *ad,
 	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
 	struct ice_pattern_match_item *item = NULL;
 	uint64_t input_set;
+	bool raw = false;
 	int ret;
 
 	memset(filter, 0, sizeof(*filter));
@@ -2213,7 +2379,13 @@ ice_fdir_parse(struct ice_adapter *ad,
 	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
 	if (ret)
 		goto error;
+
+	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
+		raw = true;
+
 	input_set = filter->input_set_o | filter->input_set_i;
+	input_set = raw ? ~input_set : input_set;
+
 	if (!input_set || filter->input_set_o &
 	    ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) ||
 	    filter->input_set_i & ~item->input_set_mask_i) {
diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 02f854666a..d3391c86c0 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -65,6 +65,12 @@ enum rte_flow_item_type pattern_empty[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* raw */
+enum rte_flow_item_type pattern_raw[] = {
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 /* L2 */
 enum rte_flow_item_type pattern_ethertype[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
@@ -2081,6 +2087,7 @@ struct ice_ptype_match {
 };
 
 static struct ice_ptype_match ice_ptype_map[] = {
+	{pattern_raw,					ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4,				ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4_udp,				ICE_PTYPE_IPV4_UDP_PAY},
 	{pattern_eth_ipv4_tcp,				ICE_PTYPE_IPV4_TCP_PAY},
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index 8845a3e156..1b030c0466 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -124,6 +124,9 @@
 /* empty pattern */
 extern enum rte_flow_item_type pattern_empty[];
 
+/* raw pattern */
+extern enum rte_flow_item_type pattern_raw[];
+
 /* L2 */
 extern enum rte_flow_item_type pattern_ethertype[];
 extern enum rte_flow_item_type pattern_ethertype_vlan[];
-- 
2.25.1


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

* [dpdk-dev] [PATCH v3 5/5] doc: enable protocol agnostic flow in FDIR
  2021-10-14 15:37       ` [dpdk-dev] [PATCH v3 0/5] enable protocol agnostic flow offloading " Junfeng Guo
                           ` (3 preceding siblings ...)
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 4/5] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-10-14 15:37         ` Junfeng Guo
  2021-10-26 12:00           ` [dpdk-dev] [PATCH v4 0/4] enable protocol agnostic flow offloading " Junfeng Guo
  4 siblings, 1 reply; 68+ messages in thread
From: Junfeng Guo @ 2021-10-14 15:37 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ferruh.yigit, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled based
on the Parser Library, using existing rte_flow raw API.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index d5c762df62..5a46be0a72 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -98,6 +98,7 @@ New Features
 
 * **Updated Intel ice driver.**
 
+  * Added protocol agnostic flow offloading support in Flow Director.
   * Added 1PPS out support by a devargs.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
   * Added DEV_RX_OFFLOAD_TIMESTAMP support.
-- 
2.25.1


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

* [dpdk-dev] [PATCH v4 0/4] enable protocol agnostic flow offloading in FDIR
  2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 5/5] doc: enable protocol agnostic flow " Junfeng Guo
@ 2021-10-26 12:00           ` Junfeng Guo
  2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
                               ` (3 more replies)
  0 siblings, 4 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-26 12:00 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, haiyue.wang, zhirun.yan, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch set based on the Parser Library using existing rte_flow raw API

[PATCH v4 1/4] net/ice/base: add method to disable FDIR SWAP option.
[PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow.
[PATCH v4 3/4] app/testpmd: update Max RAW pattern size to 512.
[PATCH v4 4/4] net/ice: enable protocol agnostic flow offloading in FDIR.

Junfeng Guo (4):
  net/ice/base: add method to disable FDIR SWAP option
  net/ice/base: add function to set HW profile for raw flow
  app/testpmd: update Max RAW pattern size to 512
  net/ice: enable protocol agnostic flow offloading in FDIR

* v4:
Added list to check inputset conflict.

* v3:
Added necessary base code for raw flow in FDIR.

* v2:
Enabled vxlan port add for raw flow and updated commit message

 app/test-pmd/cmdline_flow.c            |   2 +-
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/base/ice_flex_pipe.c   |  99 +++++++++-
 drivers/net/ice/base/ice_flex_pipe.h   |   7 +-
 drivers/net/ice/base/ice_flow.c        |  87 ++++++++-
 drivers/net/ice/base/ice_flow.h        |   4 +
 drivers/net/ice/ice_ethdev.h           |  17 ++
 drivers/net/ice/ice_fdir_filter.c      | 249 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 10 files changed, 471 insertions(+), 5 deletions(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH v4 1/4] net/ice/base: add method to disable FDIR SWAP option
  2021-10-26 12:00           ` [dpdk-dev] [PATCH v4 0/4] enable protocol agnostic flow offloading " Junfeng Guo
@ 2021-10-26 12:00             ` Junfeng Guo
  2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-26 12:00 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, haiyue.wang, zhirun.yan, junfeng.guo

The SWAP Flag in the FDIR Programming Descriptor doesn't work, thus
add a method to disable the FDIR SWAP option by setting the swap and
inset register set with certain values. The boolean fd_swap is used
to enable/disable the SWAP option.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 44 ++++++++++++++++++++++++++--
 drivers/net/ice/base/ice_flex_pipe.h |  3 +-
 drivers/net/ice/base/ice_flow.c      |  2 +-
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index f35d59f4f5..06a233990f 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -4952,6 +4952,43 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 	return ICE_SUCCESS;
 }
 
+/**
+ * ice_disable_fd_swap - set register appropriately to disable FD swap
+ * @hw: pointer to the HW struct
+ * @prof_id: profile ID
+ */
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id)
+{
+	u8 swap_val = ICE_SWAP_VALID;
+	u8 i;
+	/* Since the SWAP Flag in the Programming Desc doesn't work,
+	 * here add method to disable the SWAP Option via setting
+	 * certain SWAP and INSET register set.
+	 */
+	for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw / 4; i++) {
+		u32 raw_swap = 0;
+		u32 raw_in = 0;
+		u8 j;
+
+		for (j = 0; j < 4; j++) {
+			raw_swap |= (swap_val++) << (j * BITS_PER_BYTE);
+			raw_in |= ICE_INSET_DFLT << (j * BITS_PER_BYTE);
+		}
+
+		/* write the FDIR swap register set */
+		wr32(hw, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		/* write the FDIR inset register set */
+		wr32(hw, GLQF_FDINSET(prof_id, i), raw_in);
+
+		ice_debug(hw, ICE_DBG_INIT, "inset wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDINSET(prof_id, i), raw_in);
+	}
+}
+
 /**
  * ice_add_prof - add profile
  * @hw: pointer to the HW struct
@@ -4962,6 +4999,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
  * @attr_cnt: number of elements in attrib array
  * @es: extraction sequence (length of array is determined by the block)
  * @masks: mask for extraction sequence
+ * @fd_swap: enable/disable FDIR paired src/dst fields swap option
  *
  * This function registers a profile, which matches a set of PTYPES with a
  * particular extraction sequence. While the hardware profile is allocated
@@ -4971,7 +5009,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks)
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap)
 {
 	u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE);
 	ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT);
@@ -4991,7 +5029,7 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 		status = ice_alloc_prof_id(hw, blk, &prof_id);
 		if (status)
 			goto err_ice_add_prof;
-		if (blk == ICE_BLK_FD) {
+		if (blk == ICE_BLK_FD && fd_swap) {
 			/* For Flow Director block, the extraction sequence may
 			 * need to be altered in the case where there are paired
 			 * fields that have no match. This is necessary because
@@ -5002,6 +5040,8 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 			status = ice_update_fd_swap(hw, prof_id, es);
 			if (status)
 				goto err_ice_add_prof;
+		} else if (blk == ICE_BLK_FD) {
+			ice_disable_fd_swap(hw, prof_id);
 		}
 		status = ice_update_prof_masking(hw, blk, prof_id, masks);
 		if (status)
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index 9733c4b214..dd332312dd 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -61,10 +61,11 @@ bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype);
 /* XLT2/VSI group functions */
 enum ice_status
 ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig);
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id);
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks);
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap);
 void ice_init_all_prof_masks(struct ice_hw *hw);
 void ice_shutdown_all_prof_masks(struct ice_hw *hw);
 struct ice_prof_map *
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 96d54b494d..77b6b130c1 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2244,7 +2244,7 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
 	/* Add a HW profile for this flow profile */
 	status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
 			      params->attr, params->attr_cnt, params->es,
-			      params->mask);
+			      params->mask, true);
 	if (status) {
 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
 		goto out;
-- 
2.25.1


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

* [dpdk-dev] [PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-10-26 12:00           ` [dpdk-dev] [PATCH v4 0/4] enable protocol agnostic flow offloading " Junfeng Guo
  2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
@ 2021-10-26 12:00             ` Junfeng Guo
  2021-10-27  0:58               ` Zhang, Qi Z
  2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
  2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 4/4] net/ice: " Junfeng Guo
  3 siblings, 1 reply; 68+ messages in thread
From: Junfeng Guo @ 2021-10-26 12:00 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, haiyue.wang, zhirun.yan, junfeng.guo

Based on the parser library, we can directly set HW profile and
associate the main/ctrl vsi.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 55 ++++++++++++++++++
 drivers/net/ice/base/ice_flex_pipe.h |  4 ++
 drivers/net/ice/base/ice_flow.c      | 85 ++++++++++++++++++++++++++++
 drivers/net/ice/base/ice_flow.h      |  4 ++
 4 files changed, 148 insertions(+)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index 06a233990f..030655f3f0 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -6365,3 +6365,58 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
 
 	return status;
 }
+
+/**
+ * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow entry
+ * @hw: pointer to the HW struct
+ * @blk: HW block
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @id: profile id (handle)
+ * @fv_found: found fv in fdir fv list
+ *
+ * Calling this function will update the hardware tables to enable the
+ * profile indicated by the ID parameter for the VSIs specified in the VSI
+ * array. Once successfully called, the flow will be enabled.
+ */
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id,
+		       bool fv_found)
+{
+	enum ice_status status = ICE_SUCCESS;
+	u16 vsi_num;
+
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	if (!fv_found) {
+		status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+		if (status) {
+			ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for main VSI flow entry, %d\n",
+				  status);
+			goto err_add_prof;
+		}
+	}
+
+	if (blk != ICE_BLK_FD)
+		return status;
+
+	vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi_handle);
+	if (!fv_found) {
+		status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+		if (status) {
+			ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for ctrl VSI flow entry, %d\n",
+				  status);
+			goto err_add_entry;
+		}
+	}
+
+	return status;
+
+err_add_entry:
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+err_add_prof:
+	ice_flow_rem_prof(hw, blk, id);
+
+	return status;
+}
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index dd332312dd..3621de18dc 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -76,6 +76,10 @@ enum ice_status
 ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 enum ice_status
 ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id,
+		       bool fv_found);
 enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
 enum ice_status
 ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 77b6b130c1..43a72b0882 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2524,6 +2524,91 @@ ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
 	return status;
 }
 
+#define FLAG_GTP_EH_PDU_LINK	BIT_ULL(13)
+#define FLAG_GTP_EH_PDU		BIT_ULL(14)
+
+#define FLAG_GTPU_MSK	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_DW	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_UP	\
+	(FLAG_GTP_EH_PDU)
+/**
+ * ice_flow_set_hw_prof - Set HW flow profile based on the parsed profile info
+ * @hw: pointer to the HW struct
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @prof: stores parsed profile info from raw flow
+ * @blk: classification stage
+ * @fv_found: found fv in fdir fv list
+ */
+enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk, bool fv_found)
+{
+	int id = ice_find_first_bit(prof->ptypes, UINT16_MAX);
+	struct ice_flow_prof_params *params;
+	u8 fv_words = hw->blk[blk].es.fvw;
+	enum ice_status status;
+	u16 vsi_num;
+	int i, idx;
+
+	params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
+	if (!params)
+		return ICE_ERR_NO_MEMORY;
+
+	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
+		params->es[i].prot_id = ICE_PROT_INVALID;
+		params->es[i].off = ICE_FV_OFFSET_INVAL;
+	}
+
+	for (i = 0; i < prof->fv_num; i++) {
+		if (hw->blk[blk].es.reverse)
+			idx = fv_words - i - 1;
+		else
+			idx = i;
+		params->es[idx].prot_id = prof->fv[i].proto_id;
+		params->es[idx].off = prof->fv[i].offset;
+		params->mask[idx] = CPU_TO_BE16(prof->fv[i].msk);
+	}
+
+	switch (prof->flags) {
+	case FLAG_GTPU_DW:
+		params->attr = ice_attr_gtpu_down;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
+		break;
+	case FLAG_GTPU_UP:
+		params->attr = ice_attr_gtpu_up;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
+		break;
+	default:
+		if (prof->flags_msk & FLAG_GTPU_MSK) {
+			params->attr = ice_attr_gtpu_session;
+			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
+		}
+		break;
+	}
+
+	status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
+			      params->attr, params->attr_cnt,
+			      params->es, params->mask, false);
+	if (status)
+		goto free_params;
+
+	status = ice_flow_assoc_hw_prof(hw, blk, dest_vsi_handle,
+					fdir_vsi_handle, id, fv_found);
+	if (status)
+		goto free_params;
+
+	return ICE_SUCCESS;
+
+free_params:
+	ice_free(hw, params);
+
+	return status;
+}
+
 /**
  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
  * @hw: pointer to the HW struct
diff --git a/drivers/net/ice/base/ice_flow.h b/drivers/net/ice/base/ice_flow.h
index 371d960066..ec1fd1dcfc 100644
--- a/drivers/net/ice/base/ice_flow.h
+++ b/drivers/net/ice/base/ice_flow.h
@@ -548,6 +548,10 @@ enum ice_status
 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
 			u16 vsig);
 enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk, bool fv_found);
+enum ice_status
 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
 		     u8 *hw_prof);
 
-- 
2.25.1


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

* [dpdk-dev] [PATCH v4 3/4] app/testpmd: update Max RAW pattern size to 512
  2021-10-26 12:00           ` [dpdk-dev] [PATCH v4 0/4] enable protocol agnostic flow offloading " Junfeng Guo
  2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
  2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
@ 2021-10-26 12:00             ` Junfeng Guo
  2021-10-27  2:52               ` [dpdk-dev] [PATCH v5 0/4] enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 4/4] net/ice: " Junfeng Guo
  3 siblings, 1 reply; 68+ messages in thread
From: Junfeng Guo @ 2021-10-26 12:00 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, haiyue.wang, zhirun.yan, junfeng.guo

Update max size for pattern in struct rte_flow_item_raw to enable
protocol agnostic flow offloading.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 app/test-pmd/cmdline_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index d8218771fb..ef24710bd8 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -495,7 +495,7 @@ enum index {
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
-#define ITEM_RAW_PATTERN_SIZE 40
+#define ITEM_RAW_PATTERN_SIZE 512
 
 /** Maximum size for GENEVE option data pattern in bytes. */
 #define ITEM_GENEVE_OPT_DATA_SIZE 124
-- 
2.25.1


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

* [dpdk-dev] [PATCH v4 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-10-26 12:00           ` [dpdk-dev] [PATCH v4 0/4] enable protocol agnostic flow offloading " Junfeng Guo
                               ` (2 preceding siblings ...)
  2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-10-26 12:00             ` Junfeng Guo
  3 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-26 12:00 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, haiyue.wang, zhirun.yan, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch based on the Parser Library, using existing rte_flow raw API.

Note that the raw flow requires:
1. byte string of raw target packet bits.
2. byte string of mask of target packet.

Here is an example:
FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:

flow create 0 ingress pattern raw \
pattern spec \
00000000000000000000000008004500001400004000401000000000000001020304 \
pattern mask \
000000000000000000000000000000000000000000000000000000000000ffffffff \
/ end actions queue index 3 / mark id 3 / end

Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto)
is optional in our cases. To avoid redundancy, we just omit the mask
of 0x0800 (with 0xFFFF) in the mask byte string example. The prefix
'0x' for the spec and mask byte (hex) strings are also omitted here.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/ice_ethdev.h           |  17 ++
 drivers/net/ice/ice_fdir_filter.c      | 249 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 5 files changed, 277 insertions(+)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index b327c2bfca..f7f45b9fa5 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -155,6 +155,7 @@ New Features
 
 * **Updated Intel ice driver.**
 
+  * Added protocol agnostic flow offloading support in Flow Director.
   * Added 1PPS out support by a devargs.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
   * Added DEV_RX_OFFLOAD_TIMESTAMP support.
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 599e0028f7..6d93fca033 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -318,6 +318,11 @@ struct ice_fdir_filter_conf {
 	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
 	uint64_t input_set_i; /* only for tunnel inner fields */
 	uint32_t mark_flag;
+
+	struct ice_parser_profile *prof;
+	const u8 *pkt_buf;
+	bool parser_ena;
+	u8 pkt_len;
 };
 
 #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
@@ -487,6 +492,17 @@ struct ice_devargs {
 	uint8_t pps_out_ena;
 };
 
+/**
+ * Structure to store fdir fv entry.
+ */
+struct ice_fdir_prof_info {
+	struct LIST_ENTRY_TYPE l_entry;
+
+	struct ice_parser_profile prof;
+	u16 ptype;
+	u64 fdir_actived_cnt;
+};
+
 /**
  * Structure to store private data for each PF/VF instance.
  */
@@ -509,6 +525,7 @@ struct ice_adapter {
 	struct rte_timecounter rx_tstamp_tc;
 	struct rte_timecounter tx_tstamp_tc;
 	bool ptp_ena;
+	struct LIST_HEAD_TYPE fdir_prof_list;
 #ifdef RTE_ARCH_X86
 	bool rx_use_avx2;
 	bool rx_use_avx512;
diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
index bd627e3aa8..81a07f191a 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -107,6 +107,7 @@
 	ICE_INSET_NAT_T_ESP_SPI)
 
 static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+	{pattern_raw,					ICE_INSET_NONE,			ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_ethertype,				ICE_FDIR_INSET_ETH,		ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,	ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,	ICE_INSET_NONE,			ICE_INSET_NONE},
@@ -1158,6 +1159,8 @@ ice_fdir_init(struct ice_adapter *ad)
 	if (ret)
 		return ret;
 
+	INIT_LIST_HEAD(&ad->fdir_prof_list);
+
 	parser = &ice_fdir_parser;
 
 	return ice_register_parser(parser, ad);
@@ -1188,6 +1191,24 @@ ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type)
 		return 0;
 }
 
+static int
+ice_fdir_add_del_raw(struct ice_pf *pf,
+		     struct ice_fdir_filter_conf *filter,
+		     bool add)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
+	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
+
+	struct ice_fltr_desc desc;
+	memset(&desc, 0, sizeof(desc));
+	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
+	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
+
+	return ice_fdir_programming(pf, &desc);
+}
+
 static int
 ice_fdir_add_del_filter(struct ice_pf *pf,
 			struct ice_fdir_filter_conf *filter,
@@ -1303,6 +1324,91 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 	struct ice_fdir_fltr_pattern key;
 	bool is_tun;
 	int ret;
+	int i;
+
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+		bool fv_found = false;
+		u16 vsi_num;
+
+		struct ice_fdir_prof_info *pi;
+		LIST_FOR_EACH_ENTRY(pi, &ad->fdir_prof_list,
+				    ice_fdir_prof_info, l_entry) {
+			if (pi->ptype != id)
+				continue;
+			if (!pi->fdir_actived_cnt) {
+				vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi);
+				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
+							   vsi_num, id);
+
+				vsi_num = ice_get_hw_vsi_num(hw, main_vsi);
+				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
+							   vsi_num, id);
+			}
+			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
+				if (pi->prof.fv[i].proto_id !=
+				    filter->prof->fv[i].proto_id ||
+				    pi->prof.fv[i].offset !=
+				    filter->prof->fv[i].offset)
+					break;
+			if (i == ICE_MAX_FV_WORDS) {
+				fv_found = true;
+				pi->fdir_actived_cnt++;
+				break;
+			}
+		}
+
+		ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
+					   filter->prof, ICE_BLK_FD, fv_found);
+		if (ret)
+			return -rte_errno;
+
+		ret = ice_fdir_add_del_raw(pf, filter, true);
+		if (ret)
+			return -rte_errno;
+
+		if (!fv_found) {
+			pi = (struct ice_fdir_prof_info *)
+				ice_malloc(hw, sizeof(*pi));
+			if (!pi)
+				return ICE_ERR_NO_MEMORY;
+
+			memset(&pi->prof, 0, sizeof(pi->prof));
+
+			for (i = 0; i < filter->prof->fv_num; i++) {
+				pi->prof.fv[i].proto_id =
+					filter->prof->fv[i].proto_id;
+				pi->prof.fv[i].offset =
+					filter->prof->fv[i].offset;
+				pi->prof.fv[i].spec = filter->prof->fv[i].spec;
+				pi->prof.fv[i].msk = filter->prof->fv[i].msk;
+			}
+			pi->ptype = id;
+			pi->fdir_actived_cnt = 1;
+
+			LIST_ADD(&pi->l_entry, &ad->fdir_prof_list);
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 1);
+
+		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
+		if (!entry)
+			return -rte_errno;
+
+		rte_memcpy(entry, filter, sizeof(*filter));
+
+		filter->prof = NULL;
+		filter->pkt_buf = NULL;
+
+		flow->rule = entry;
+
+		return 0;
+	}
 
 	ice_fdir_extract_fltr_key(&key, filter);
 	node = ice_fdir_entry_lookup(fdir_info, &key);
@@ -1397,6 +1503,42 @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
 
 	filter = (struct ice_fdir_filter_conf *)flow->rule;
 
+	if (filter->parser_ena) {
+		ret = ice_fdir_add_del_raw(pf, filter, false);
+		if (ret)
+			return -rte_errno;
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		int i;
+		struct ice_fdir_prof_info *pi;
+		LIST_FOR_EACH_ENTRY(pi, &ad->fdir_prof_list,
+				    ice_fdir_prof_info, l_entry) {
+			if (pi->ptype != id)
+				continue;
+			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
+				if (pi->prof.fv[i].proto_id !=
+				    filter->prof->fv[i].proto_id ||
+				    pi->prof.fv[i].offset !=
+				    filter->prof->fv[i].offset)
+					break;
+			if (i == ICE_MAX_FV_WORDS) {
+				pi->fdir_actived_cnt--;
+				break;
+			}
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 0);
+
+		flow->rule = NULL;
+		filter->prof = NULL;
+		filter->pkt_buf = NULL;
+
+		rte_free(filter);
+
+		return 0;
+	}
+
 	is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type);
 
 	if (filter->counter) {
@@ -1675,6 +1817,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
 	enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END;
 	enum ice_fdir_tunnel_type tunnel_type = ICE_FDIR_TUNNEL_TYPE_NONE;
+	const struct rte_flow_item_raw *raw_spec, *raw_mask;
 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
@@ -1702,6 +1845,9 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	struct ice_fdir_extra *p_ext_data;
 	struct ice_fdir_v4 *p_v4 = NULL;
 	struct ice_fdir_v6 *p_v6 = NULL;
+	struct ice_parser_result rslt;
+	struct ice_parser *psr;
+	uint8_t item_num = 0;
 
 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 		if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN)
@@ -1713,6 +1859,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 		    item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
 			is_outer = false;
 		}
+		item_num++;
 	}
 
 	/* This loop parse flow pattern and distinguish Non-tunnel and tunnel
@@ -1733,6 +1880,101 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 			    &input_set_i : &input_set_o;
 
 		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_RAW:
+			raw_spec = item->spec;
+			raw_mask = item->mask;
+
+			if (item_num != 1)
+				break;
+
+			/* convert raw spec & mask from byte string to int */
+			unsigned char *tmp_spec =
+				(uint8_t *)(uintptr_t)raw_spec->pattern;
+			unsigned char *tmp_mask =
+				(uint8_t *)(uintptr_t)raw_mask->pattern;
+			uint16_t udp_port = 0;
+			uint16_t tmp_val = 0;
+			uint8_t pkt_len = 0;
+			uint8_t tmp = 0;
+			int i, j;
+
+			pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern);
+			if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
+				pkt_len)
+				return -rte_errno;
+
+			for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
+				tmp = tmp_spec[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_spec[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_spec[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_spec[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_spec[j] = tmp_val + tmp - '0';
+
+				tmp = tmp_mask[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_mask[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_mask[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_mask[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_mask[j] = tmp_val + tmp - '0';
+			}
+
+			pkt_len /= 2;
+
+			if (ice_parser_create(&ad->hw, &psr))
+				return -rte_errno;
+			if (ice_get_open_tunnel_port(&ad->hw, TNL_VXLAN,
+						     &udp_port))
+				ice_parser_vxlan_tunnel_set(psr, udp_port,
+							    true);
+			if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt))
+				return -rte_errno;
+			ice_parser_destroy(psr);
+
+			if (!tmp_mask)
+				return -rte_errno;
+
+			filter->prof = (struct ice_parser_profile *)
+				ice_malloc(&ad->hw, sizeof(*filter->prof));
+			if (!filter->prof)
+				return -ENOMEM;
+
+			if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask,
+				pkt_len, ICE_BLK_FD, true, filter->prof))
+				return -rte_errno;
+
+			u8 *pkt_buf = (u8 *)ice_malloc(&ad->hw, pkt_len + 1);
+			if (!pkt_buf)
+				return -ENOMEM;
+			rte_memcpy(pkt_buf, tmp_spec, pkt_len);
+			filter->pkt_buf = pkt_buf;
+
+			filter->pkt_len = pkt_len;
+
+			filter->parser_ena = true;
+
+			break;
+
 		case RTE_FLOW_ITEM_TYPE_ETH:
 			flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
 			eth_spec = item->spec;
@@ -2198,6 +2440,7 @@ ice_fdir_parse(struct ice_adapter *ad,
 	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
 	struct ice_pattern_match_item *item = NULL;
 	uint64_t input_set;
+	bool raw = false;
 	int ret;
 
 	memset(filter, 0, sizeof(*filter));
@@ -2213,7 +2456,13 @@ ice_fdir_parse(struct ice_adapter *ad,
 	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
 	if (ret)
 		goto error;
+
+	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
+		raw = true;
+
 	input_set = filter->input_set_o | filter->input_set_i;
+	input_set = raw ? ~input_set : input_set;
+
 	if (!input_set || filter->input_set_o &
 	    ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) ||
 	    filter->input_set_i & ~item->input_set_mask_i) {
diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 02f854666a..d3391c86c0 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -65,6 +65,12 @@ enum rte_flow_item_type pattern_empty[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* raw */
+enum rte_flow_item_type pattern_raw[] = {
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 /* L2 */
 enum rte_flow_item_type pattern_ethertype[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
@@ -2081,6 +2087,7 @@ struct ice_ptype_match {
 };
 
 static struct ice_ptype_match ice_ptype_map[] = {
+	{pattern_raw,					ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4,				ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4_udp,				ICE_PTYPE_IPV4_UDP_PAY},
 	{pattern_eth_ipv4_tcp,				ICE_PTYPE_IPV4_TCP_PAY},
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index 8845a3e156..1b030c0466 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -124,6 +124,9 @@
 /* empty pattern */
 extern enum rte_flow_item_type pattern_empty[];
 
+/* raw pattern */
+extern enum rte_flow_item_type pattern_raw[];
+
 /* L2 */
 extern enum rte_flow_item_type pattern_ethertype[];
 extern enum rte_flow_item_type pattern_ethertype_vlan[];
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
@ 2021-10-27  0:58               ` Zhang, Qi Z
  2021-10-27  1:58                 ` Guo, Junfeng
  0 siblings, 1 reply; 68+ messages in thread
From: Zhang, Qi Z @ 2021-10-27  0:58 UTC (permalink / raw)
  To: Guo, Junfeng, Wu, Jingjing, Xing, Beilei
  Cc: dev, Yigit, Ferruh, Wang, Haiyue, Yan, Zhirun



> -----Original Message-----
> From: Guo, Junfeng <junfeng.guo@intel.com>
> Sent: Tuesday, October 26, 2021 8:01 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Wang, Haiyue
> <haiyue.wang@intel.com>; Yan, Zhirun <zhirun.yan@intel.com>; Guo, Junfeng
> <junfeng.guo@intel.com>
> Subject: [PATCH v4 2/4] net/ice/base: add function to set HW profile for raw
> flow
> 
> Based on the parser library, we can directly set HW profile and associate the
> main/ctrl vsi.
> 
> Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
> ---
>  drivers/net/ice/base/ice_flex_pipe.c | 55 ++++++++++++++++++
> drivers/net/ice/base/ice_flex_pipe.h |  4 ++
>  drivers/net/ice/base/ice_flow.c      | 85 ++++++++++++++++++++++++++++
>  drivers/net/ice/base/ice_flow.h      |  4 ++
>  4 files changed, 148 insertions(+)
> 
> diff --git a/drivers/net/ice/base/ice_flex_pipe.c
> b/drivers/net/ice/base/ice_flex_pipe.c
> index 06a233990f..030655f3f0 100644
> --- a/drivers/net/ice/base/ice_flex_pipe.c
> +++ b/drivers/net/ice/base/ice_flex_pipe.c
> @@ -6365,3 +6365,58 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum
> ice_block blk, u16 vsi, u64 hdl)
> 
>  	return status;
>  }
> +
> +/**
> + * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow
> +entry
> + * @hw: pointer to the HW struct
> + * @blk: HW block
> + * @dest_vsi_handle: dest VSI handle
> + * @fdir_vsi_handle: fdir programming VSI handle
> + * @id: profile id (handle)
> + * @fv_found: found fv in fdir fv list
> + *
> + * Calling this function will update the hardware tables to enable the
> + * profile indicated by the ID parameter for the VSIs specified in the
> +VSI
> + * array. Once successfully called, the flow will be enabled.
> + */
> +enum ice_status
> +ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
> +		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id,
> +		       bool fv_found)

Do we really need this fv_found parameter?

If fv_found is true, seems nothing has been done in this function, why not just check the flag outside the function?




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

* Re: [dpdk-dev] [PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-10-27  0:58               ` Zhang, Qi Z
@ 2021-10-27  1:58                 ` Guo, Junfeng
  2021-10-27  2:17                   ` Zhang, Qi Z
  0 siblings, 1 reply; 68+ messages in thread
From: Guo, Junfeng @ 2021-10-27  1:58 UTC (permalink / raw)
  To: Zhang, Qi Z, Wu, Jingjing, Xing, Beilei
  Cc: dev, Yigit, Ferruh, Wang, Haiyue, Yan, Zhirun



> -----Original Message-----
> From: Zhang, Qi Z <qi.z.zhang@intel.com>
> Sent: Wednesday, October 27, 2021 08:58
> To: Guo, Junfeng <junfeng.guo@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Wang, Haiyue
> <haiyue.wang@intel.com>; Yan, Zhirun <Zhirun.Yan@intel.com>
> Subject: RE: [PATCH v4 2/4] net/ice/base: add function to set HW profile
> for raw flow
> 
> 
> 
> > -----Original Message-----
> > From: Guo, Junfeng <junfeng.guo@intel.com>
> > Sent: Tuesday, October 26, 2021 8:01 PM
> > To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>;
> > Xing, Beilei <beilei.xing@intel.com>
> > Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Wang,
> Haiyue
> > <haiyue.wang@intel.com>; Yan, Zhirun <zhirun.yan@intel.com>; Guo,
> Junfeng
> > <junfeng.guo@intel.com>
> > Subject: [PATCH v4 2/4] net/ice/base: add function to set HW profile for
> raw
> > flow
> >
> > Based on the parser library, we can directly set HW profile and associate
> the
> > main/ctrl vsi.
> >
> > Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
> > ---
> >  drivers/net/ice/base/ice_flex_pipe.c | 55 ++++++++++++++++++
> > drivers/net/ice/base/ice_flex_pipe.h |  4 ++
> >  drivers/net/ice/base/ice_flow.c      | 85
> ++++++++++++++++++++++++++++
> >  drivers/net/ice/base/ice_flow.h      |  4 ++
> >  4 files changed, 148 insertions(+)
> >
> > diff --git a/drivers/net/ice/base/ice_flex_pipe.c
> > b/drivers/net/ice/base/ice_flex_pipe.c
> > index 06a233990f..030655f3f0 100644
> > --- a/drivers/net/ice/base/ice_flex_pipe.c
> > +++ b/drivers/net/ice/base/ice_flex_pipe.c
> > @@ -6365,3 +6365,58 @@ ice_rem_prof_id_flow(struct ice_hw *hw,
> enum
> > ice_block blk, u16 vsi, u64 hdl)
> >
> >  return status;
> >  }
> > +
> > +/**
> > + * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow
> > +entry
> > + * @hw: pointer to the HW struct
> > + * @blk: HW block
> > + * @dest_vsi_handle: dest VSI handle
> > + * @fdir_vsi_handle: fdir programming VSI handle
> > + * @id: profile id (handle)
> > + * @fv_found: found fv in fdir fv list
> > + *
> > + * Calling this function will update the hardware tables to enable the
> > + * profile indicated by the ID parameter for the VSIs specified in the
> > +VSI
> > + * array. Once successfully called, the flow will be enabled.
> > + */
> > +enum ice_status
> > +ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
> > +       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id,
> > +       bool fv_found)
> 
> Do we really need this fv_found parameter?

The value of fv_found is set based on the maintained profile info list in the PMD.
So we need this parameter to add profile id flow for FDIR in the shared code.

> 
> If fv_found is true, seems nothing has been done in this function, why not
> just check the flag outside the function?

Yes, ice_add_prof_id_flow should be processed after ice_add_prof.
It's ok if we just move the ice_add_prof_id_flow processing into func ice_flow_set_hw_prof,
and delete the func ice_flow_assoc_hw_prof to reduce the code size.

For RSS, the ice_add_prof_id_flow for adding dest_vsi_handle should always be processed.
So this function has other RSS logic to add soon.

> 
> 
> 


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

* Re: [dpdk-dev] [PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-10-27  1:58                 ` Guo, Junfeng
@ 2021-10-27  2:17                   ` Zhang, Qi Z
  2021-10-27  2:51                     ` Guo, Junfeng
  0 siblings, 1 reply; 68+ messages in thread
From: Zhang, Qi Z @ 2021-10-27  2:17 UTC (permalink / raw)
  To: Guo, Junfeng, Wu, Jingjing, Xing, Beilei
  Cc: dev, Yigit, Ferruh, Wang, Haiyue, Yan, Zhirun



> -----Original Message-----
> From: Guo, Junfeng <junfeng.guo@intel.com>
> Sent: Wednesday, October 27, 2021 9:58 AM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Wang, Haiyue
> <haiyue.wang@intel.com>; Yan, Zhirun <zhirun.yan@intel.com>
> Subject: RE: [PATCH v4 2/4] net/ice/base: add function to set HW profile for
> raw flow
> 
> 
> 
> > -----Original Message-----
> > From: Zhang, Qi Z <qi.z.zhang@intel.com>
> > Sent: Wednesday, October 27, 2021 08:58
> > To: Guo, Junfeng <junfeng.guo@intel.com>; Wu, Jingjing
> > <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>
> > Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Wang, Haiyue
> > <haiyue.wang@intel.com>; Yan, Zhirun <Zhirun.Yan@intel.com>
> > Subject: RE: [PATCH v4 2/4] net/ice/base: add function to set HW
> > profile for raw flow
> >
> >
> >
> > > -----Original Message-----
> > > From: Guo, Junfeng <junfeng.guo@intel.com>
> > > Sent: Tuesday, October 26, 2021 8:01 PM
> > > To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing
> > <jingjing.wu@intel.com>;
> > > Xing, Beilei <beilei.xing@intel.com>
> > > Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Wang,
> > Haiyue
> > > <haiyue.wang@intel.com>; Yan, Zhirun <zhirun.yan@intel.com>; Guo,
> > Junfeng
> > > <junfeng.guo@intel.com>
> > > Subject: [PATCH v4 2/4] net/ice/base: add function to set HW profile
> > > for
> > raw
> > > flow
> > >
> > > Based on the parser library, we can directly set HW profile and
> > > associate
> > the
> > > main/ctrl vsi.
> > >
> > > Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
> > > ---
> > >  drivers/net/ice/base/ice_flex_pipe.c | 55 ++++++++++++++++++
> > > drivers/net/ice/base/ice_flex_pipe.h |  4 ++
> > >  drivers/net/ice/base/ice_flow.c      | 85
> > ++++++++++++++++++++++++++++
> > >  drivers/net/ice/base/ice_flow.h      |  4 ++
> > >  4 files changed, 148 insertions(+)
> > >
> > > diff --git a/drivers/net/ice/base/ice_flex_pipe.c
> > > b/drivers/net/ice/base/ice_flex_pipe.c
> > > index 06a233990f..030655f3f0 100644
> > > --- a/drivers/net/ice/base/ice_flex_pipe.c
> > > +++ b/drivers/net/ice/base/ice_flex_pipe.c
> > > @@ -6365,3 +6365,58 @@ ice_rem_prof_id_flow(struct ice_hw *hw,
> > enum
> > > ice_block blk, u16 vsi, u64 hdl)
> > >
> > >  return status;
> > >  }
> > > +
> > > +/**
> > > + * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI
> > > +flow entry
> > > + * @hw: pointer to the HW struct
> > > + * @blk: HW block
> > > + * @dest_vsi_handle: dest VSI handle
> > > + * @fdir_vsi_handle: fdir programming VSI handle
> > > + * @id: profile id (handle)
> > > + * @fv_found: found fv in fdir fv list
> > > + *
> > > + * Calling this function will update the hardware tables to enable
> > > +the
> > > + * profile indicated by the ID parameter for the VSIs specified in
> > > +the VSI
> > > + * array. Once successfully called, the flow will be enabled.
> > > + */
> > > +enum ice_status
> > > +ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
> > > +       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id,
> > > +       bool fv_found)
> >
> > Do we really need this fv_found parameter?
> 
> The value of fv_found is set based on the maintained profile info list in the PMD.
> So we need this parameter to add profile id flow for FDIR in the shared code.

I mean if we parse fv_found = true into ice_flow_assoc_hw_prof, nothing will happen,
So why not just remove the parameter and we can do below 

	If (!fv_found)
		ice_flow_assoc_hw_prof(...)

its always better to reduce unnecessary context for simple purpose in a function.
	

> 
> >
> > If fv_found is true, seems nothing has been done in this function, why
> > not just check the flag outside the function?
> 
> Yes, ice_add_prof_id_flow should be processed after ice_add_prof.
> It's ok if we just move the ice_add_prof_id_flow processing into func
> ice_flow_set_hw_prof, and delete the func ice_flow_assoc_hw_prof to reduce
> the code size.
> 
> For RSS, the ice_add_prof_id_flow for adding dest_vsi_handle should always be
> processed.
> So this function has other RSS logic to add soon.
> 
> >
> >
> >
> 


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

* Re: [dpdk-dev] [PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-10-27  2:17                   ` Zhang, Qi Z
@ 2021-10-27  2:51                     ` Guo, Junfeng
  0 siblings, 0 replies; 68+ messages in thread
From: Guo, Junfeng @ 2021-10-27  2:51 UTC (permalink / raw)
  To: Zhang, Qi Z, Wu, Jingjing, Xing, Beilei
  Cc: dev, Yigit, Ferruh, Wang, Haiyue, Yan, Zhirun



> -----Original Message-----
> From: Zhang, Qi Z <qi.z.zhang@intel.com>
> Sent: Wednesday, October 27, 2021 10:18
> To: Guo, Junfeng <junfeng.guo@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Wang, Haiyue
> <haiyue.wang@intel.com>; Yan, Zhirun <Zhirun.Yan@intel.com>
> Subject: RE: [PATCH v4 2/4] net/ice/base: add function to set HW profile
> for raw flow
> 
> 
> 
> > -----Original Message-----
> > From: Guo, Junfeng <junfeng.guo@intel.com>
> > Sent: Wednesday, October 27, 2021 9:58 AM
> > To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>;
> > Xing, Beilei <beilei.xing@intel.com>
> > Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Wang,
> Haiyue
> > <haiyue.wang@intel.com>; Yan, Zhirun <zhirun.yan@intel.com>
> > Subject: RE: [PATCH v4 2/4] net/ice/base: add function to set HW
> profile for
> > raw flow
> >
> >
> >
> > > -----Original Message-----
> > > From: Zhang, Qi Z <qi.z.zhang@intel.com>
> > > Sent: Wednesday, October 27, 2021 08:58
> > > To: Guo, Junfeng <junfeng.guo@intel.com>; Wu, Jingjing
> > > <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>
> > > Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Wang,
> Haiyue
> > > <haiyue.wang@intel.com>; Yan, Zhirun <Zhirun.Yan@intel.com>
> > > Subject: RE: [PATCH v4 2/4] net/ice/base: add function to set HW
> > > profile for raw flow
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Guo, Junfeng <junfeng.guo@intel.com>
> > > > Sent: Tuesday, October 26, 2021 8:01 PM
> > > > To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing
> > > <jingjing.wu@intel.com>;
> > > > Xing, Beilei <beilei.xing@intel.com>
> > > > Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Wang,
> > > Haiyue
> > > > <haiyue.wang@intel.com>; Yan, Zhirun <zhirun.yan@intel.com>;
> Guo,
> > > Junfeng
> > > > <junfeng.guo@intel.com>
> > > > Subject: [PATCH v4 2/4] net/ice/base: add function to set HW profile
> > > > for
> > > raw
> > > > flow
> > > >
> > > > Based on the parser library, we can directly set HW profile and
> > > > associate
> > > the
> > > > main/ctrl vsi.
> > > >
> > > > Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
> > > > ---
> > > >  drivers/net/ice/base/ice_flex_pipe.c | 55 ++++++++++++++++++
> > > > drivers/net/ice/base/ice_flex_pipe.h |  4 ++
> > > >  drivers/net/ice/base/ice_flow.c      | 85
> > > ++++++++++++++++++++++++++++
> > > >  drivers/net/ice/base/ice_flow.h      |  4 ++
> > > >  4 files changed, 148 insertions(+)
> > > >
> > > > diff --git a/drivers/net/ice/base/ice_flex_pipe.c
> > > > b/drivers/net/ice/base/ice_flex_pipe.c
> > > > index 06a233990f..030655f3f0 100644
> > > > --- a/drivers/net/ice/base/ice_flex_pipe.c
> > > > +++ b/drivers/net/ice/base/ice_flex_pipe.c
> > > > @@ -6365,3 +6365,58 @@ ice_rem_prof_id_flow(struct ice_hw
> *hw,
> > > enum
> > > > ice_block blk, u16 vsi, u64 hdl)
> > > >
> > > >  return status;
> > > >  }
> > > > +
> > > > +/**
> > > > + * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI
> > > > +flow entry
> > > > + * @hw: pointer to the HW struct
> > > > + * @blk: HW block
> > > > + * @dest_vsi_handle: dest VSI handle
> > > > + * @fdir_vsi_handle: fdir programming VSI handle
> > > > + * @id: profile id (handle)
> > > > + * @fv_found: found fv in fdir fv list
> > > > + *
> > > > + * Calling this function will update the hardware tables to enable
> > > > +the
> > > > + * profile indicated by the ID parameter for the VSIs specified in
> > > > +the VSI
> > > > + * array. Once successfully called, the flow will be enabled.
> > > > + */
> > > > +enum ice_status
> > > > +ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
> > > > +       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id,
> > > > +       bool fv_found)
> > >
> > > Do we really need this fv_found parameter?
> >
> > The value of fv_found is set based on the maintained profile info list in
> the PMD.
> > So we need this parameter to add profile id flow for FDIR in the shared
> code.
> 
> I mean if we parse fv_found = true into ice_flow_assoc_hw_prof, nothing
> will happen,
> So why not just remove the parameter and we can do below
> 
> If (!fv_found)
> ice_flow_assoc_hw_prof(...)
> 
> its always better to reduce unnecessary context for simple purpose in a
> function.

Sure, updated in the coming patch set. Thanks!

> 
> >
> > >
> > > If fv_found is true, seems nothing has been done in this function, why
> > > not just check the flag outside the function?
> >
> > Yes, ice_add_prof_id_flow should be processed after ice_add_prof.
> > It's ok if we just move the ice_add_prof_id_flow processing into func
> > ice_flow_set_hw_prof, and delete the func ice_flow_assoc_hw_prof to
> reduce
> > the code size.
> >
> > For RSS, the ice_add_prof_id_flow for adding dest_vsi_handle should
> always be
> > processed.
> > So this function has other RSS logic to add soon.
> >
> > >
> > >
> > >
> >
> 


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

* [dpdk-dev] [PATCH v5 0/4] enable protocol agnostic flow offloading in FDIR
  2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-10-27  2:52               ` Junfeng Guo
  2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
                                   ` (3 more replies)
  0 siblings, 4 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-27  2:52 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, haiyue.wang, zhirun.yan, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch set based on the Parser Library using existing rte_flow raw API

[PATCH v4 1/4] net/ice/base: add method to disable FDIR SWAP option.
[PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow.
[PATCH v4 3/4] app/testpmd: update Max RAW pattern size to 512.
[PATCH v4 4/4] net/ice: enable protocol agnostic flow offloading in FDIR.

Junfeng Guo (4):
  net/ice/base: add method to disable FDIR SWAP option
  net/ice/base: add function to set HW profile for raw flow
  app/testpmd: update Max RAW pattern size to 512
  net/ice: enable protocol agnostic flow offloading in FDIR

* v5:
Optimized some code logic.

* v4:
Added list to check inputset conflict.

* v3:
Added necessary base code for raw flow in FDIR.

* v2:
Enabled vxlan port add for raw flow and updated commit message

 app/test-pmd/cmdline_flow.c            |   2 +-
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/base/ice_flex_pipe.c   |  93 ++++++++-
 drivers/net/ice/base/ice_flex_pipe.h   |   6 +-
 drivers/net/ice/base/ice_flow.c        |  89 ++++++++-
 drivers/net/ice/base/ice_flow.h        |   4 +
 drivers/net/ice/ice_ethdev.h           |  17 ++
 drivers/net/ice/ice_fdir_filter.c      | 249 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 10 files changed, 466 insertions(+), 5 deletions(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH v5 1/4] net/ice/base: add method to disable FDIR SWAP option
  2021-10-27  2:52               ` [dpdk-dev] [PATCH v5 0/4] enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-10-27  2:52                 ` Junfeng Guo
  2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
                                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-27  2:52 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, haiyue.wang, zhirun.yan, junfeng.guo

The SWAP Flag in the FDIR Programming Descriptor doesn't work, thus
add a method to disable the FDIR SWAP option by setting the swap and
inset register set with certain values. The boolean fd_swap is used
to enable/disable the SWAP option.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 44 ++++++++++++++++++++++++++--
 drivers/net/ice/base/ice_flex_pipe.h |  3 +-
 drivers/net/ice/base/ice_flow.c      |  2 +-
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index f35d59f4f5..06a233990f 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -4952,6 +4952,43 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 	return ICE_SUCCESS;
 }
 
+/**
+ * ice_disable_fd_swap - set register appropriately to disable FD swap
+ * @hw: pointer to the HW struct
+ * @prof_id: profile ID
+ */
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id)
+{
+	u8 swap_val = ICE_SWAP_VALID;
+	u8 i;
+	/* Since the SWAP Flag in the Programming Desc doesn't work,
+	 * here add method to disable the SWAP Option via setting
+	 * certain SWAP and INSET register set.
+	 */
+	for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw / 4; i++) {
+		u32 raw_swap = 0;
+		u32 raw_in = 0;
+		u8 j;
+
+		for (j = 0; j < 4; j++) {
+			raw_swap |= (swap_val++) << (j * BITS_PER_BYTE);
+			raw_in |= ICE_INSET_DFLT << (j * BITS_PER_BYTE);
+		}
+
+		/* write the FDIR swap register set */
+		wr32(hw, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		/* write the FDIR inset register set */
+		wr32(hw, GLQF_FDINSET(prof_id, i), raw_in);
+
+		ice_debug(hw, ICE_DBG_INIT, "inset wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDINSET(prof_id, i), raw_in);
+	}
+}
+
 /**
  * ice_add_prof - add profile
  * @hw: pointer to the HW struct
@@ -4962,6 +4999,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
  * @attr_cnt: number of elements in attrib array
  * @es: extraction sequence (length of array is determined by the block)
  * @masks: mask for extraction sequence
+ * @fd_swap: enable/disable FDIR paired src/dst fields swap option
  *
  * This function registers a profile, which matches a set of PTYPES with a
  * particular extraction sequence. While the hardware profile is allocated
@@ -4971,7 +5009,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks)
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap)
 {
 	u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE);
 	ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT);
@@ -4991,7 +5029,7 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 		status = ice_alloc_prof_id(hw, blk, &prof_id);
 		if (status)
 			goto err_ice_add_prof;
-		if (blk == ICE_BLK_FD) {
+		if (blk == ICE_BLK_FD && fd_swap) {
 			/* For Flow Director block, the extraction sequence may
 			 * need to be altered in the case where there are paired
 			 * fields that have no match. This is necessary because
@@ -5002,6 +5040,8 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 			status = ice_update_fd_swap(hw, prof_id, es);
 			if (status)
 				goto err_ice_add_prof;
+		} else if (blk == ICE_BLK_FD) {
+			ice_disable_fd_swap(hw, prof_id);
 		}
 		status = ice_update_prof_masking(hw, blk, prof_id, masks);
 		if (status)
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index 9733c4b214..dd332312dd 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -61,10 +61,11 @@ bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype);
 /* XLT2/VSI group functions */
 enum ice_status
 ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig);
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id);
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks);
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap);
 void ice_init_all_prof_masks(struct ice_hw *hw);
 void ice_shutdown_all_prof_masks(struct ice_hw *hw);
 struct ice_prof_map *
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 96d54b494d..77b6b130c1 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2244,7 +2244,7 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
 	/* Add a HW profile for this flow profile */
 	status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
 			      params->attr, params->attr_cnt, params->es,
-			      params->mask);
+			      params->mask, true);
 	if (status) {
 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
 		goto out;
-- 
2.25.1


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

* [dpdk-dev] [PATCH v5 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-10-27  2:52               ` [dpdk-dev] [PATCH v5 0/4] enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
@ 2021-10-27  2:52                 ` Junfeng Guo
  2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
  2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  3 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-27  2:52 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, haiyue.wang, zhirun.yan, junfeng.guo

Based on the parser library, we can directly set HW profile and
associate the main/ctrl vsi.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 49 ++++++++++++++++
 drivers/net/ice/base/ice_flex_pipe.h |  3 +
 drivers/net/ice/base/ice_flow.c      | 87 ++++++++++++++++++++++++++++
 drivers/net/ice/base/ice_flow.h      |  4 ++
 4 files changed, 143 insertions(+)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index 06a233990f..395787806b 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -6365,3 +6365,52 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
 
 	return status;
 }
+
+/**
+ * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow entry
+ * @hw: pointer to the HW struct
+ * @blk: HW block
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @id: profile id (handle)
+ *
+ * Calling this function will update the hardware tables to enable the
+ * profile indicated by the ID parameter for the VSIs specified in the VSI
+ * array. Once successfully called, the flow will be enabled.
+ */
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id)
+{
+	enum ice_status status = ICE_SUCCESS;
+	u16 vsi_num;
+
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for main VSI flow entry, %d\n",
+			  status);
+		goto err_add_prof;
+	}
+
+	if (blk != ICE_BLK_FD)
+		return status;
+
+	vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for ctrl VSI flow entry, %d\n",
+			  status);
+		goto err_add_entry;
+	}
+
+	return status;
+
+err_add_entry:
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+err_add_prof:
+	ice_flow_rem_prof(hw, blk, id);
+
+	return status;
+}
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index dd332312dd..23ba45564a 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -76,6 +76,9 @@ enum ice_status
 ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 enum ice_status
 ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id);
 enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
 enum ice_status
 ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 77b6b130c1..66118fdbde 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2524,6 +2524,93 @@ ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
 	return status;
 }
 
+#define FLAG_GTP_EH_PDU_LINK	BIT_ULL(13)
+#define FLAG_GTP_EH_PDU		BIT_ULL(14)
+
+#define FLAG_GTPU_MSK	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_DW	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_UP	\
+	(FLAG_GTP_EH_PDU)
+/**
+ * ice_flow_set_hw_prof - Set HW flow profile based on the parsed profile info
+ * @hw: pointer to the HW struct
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @prof: stores parsed profile info from raw flow
+ * @blk: classification stage
+ * @fv_found: found fv in fdir fv list
+ */
+enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk, bool fv_found)
+{
+	int id = ice_find_first_bit(prof->ptypes, UINT16_MAX);
+	struct ice_flow_prof_params *params;
+	u8 fv_words = hw->blk[blk].es.fvw;
+	enum ice_status status;
+	u16 vsi_num;
+	int i, idx;
+
+	params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
+	if (!params)
+		return ICE_ERR_NO_MEMORY;
+
+	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
+		params->es[i].prot_id = ICE_PROT_INVALID;
+		params->es[i].off = ICE_FV_OFFSET_INVAL;
+	}
+
+	for (i = 0; i < prof->fv_num; i++) {
+		if (hw->blk[blk].es.reverse)
+			idx = fv_words - i - 1;
+		else
+			idx = i;
+		params->es[idx].prot_id = prof->fv[i].proto_id;
+		params->es[idx].off = prof->fv[i].offset;
+		params->mask[idx] = CPU_TO_BE16(prof->fv[i].msk);
+	}
+
+	switch (prof->flags) {
+	case FLAG_GTPU_DW:
+		params->attr = ice_attr_gtpu_down;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
+		break;
+	case FLAG_GTPU_UP:
+		params->attr = ice_attr_gtpu_up;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
+		break;
+	default:
+		if (prof->flags_msk & FLAG_GTPU_MSK) {
+			params->attr = ice_attr_gtpu_session;
+			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
+		}
+		break;
+	}
+
+	status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
+			      params->attr, params->attr_cnt,
+			      params->es, params->mask, false);
+	if (status)
+		goto free_params;
+
+	if (!fv_found) {
+		status = ice_flow_assoc_hw_prof(hw, blk, dest_vsi_handle,
+						fdir_vsi_handle, id);
+		if (status)
+			goto free_params;
+	}
+
+	return ICE_SUCCESS;
+
+free_params:
+	ice_free(hw, params);
+
+	return status;
+}
+
 /**
  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
  * @hw: pointer to the HW struct
diff --git a/drivers/net/ice/base/ice_flow.h b/drivers/net/ice/base/ice_flow.h
index 371d960066..ec1fd1dcfc 100644
--- a/drivers/net/ice/base/ice_flow.h
+++ b/drivers/net/ice/base/ice_flow.h
@@ -548,6 +548,10 @@ enum ice_status
 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
 			u16 vsig);
 enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk, bool fv_found);
+enum ice_status
 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
 		     u8 *hw_prof);
 
-- 
2.25.1


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

* [dpdk-dev] [PATCH v5 3/4] app/testpmd: update Max RAW pattern size to 512
  2021-10-27  2:52               ` [dpdk-dev] [PATCH v5 0/4] enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
  2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
@ 2021-10-27  2:52                 ` Junfeng Guo
  2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  3 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-27  2:52 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, haiyue.wang, zhirun.yan, junfeng.guo

Update max size for pattern in struct rte_flow_item_raw to enable
protocol agnostic flow offloading.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 app/test-pmd/cmdline_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index d8218771fb..ef24710bd8 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -495,7 +495,7 @@ enum index {
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
-#define ITEM_RAW_PATTERN_SIZE 40
+#define ITEM_RAW_PATTERN_SIZE 512
 
 /** Maximum size for GENEVE option data pattern in bytes. */
 #define ITEM_GENEVE_OPT_DATA_SIZE 124
-- 
2.25.1


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

* [dpdk-dev] [PATCH v5 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-10-27  2:52               ` [dpdk-dev] [PATCH v5 0/4] enable protocol agnostic flow offloading in FDIR Junfeng Guo
                                   ` (2 preceding siblings ...)
  2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-10-27  2:52                 ` Junfeng Guo
  2021-10-28  8:34                   ` [dpdk-dev] [PATCH v6 0/4] " Junfeng Guo
  3 siblings, 1 reply; 68+ messages in thread
From: Junfeng Guo @ 2021-10-27  2:52 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, haiyue.wang, zhirun.yan, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch based on the Parser Library, using existing rte_flow raw API.

Note that the raw flow requires:
1. byte string of raw target packet bits.
2. byte string of mask of target packet.

Here is an example:
FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:

flow create 0 ingress pattern raw \
pattern spec \
00000000000000000000000008004500001400004000401000000000000001020304 \
pattern mask \
000000000000000000000000000000000000000000000000000000000000ffffffff \
/ end actions queue index 3 / mark id 3 / end

Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto)
is optional in our cases. To avoid redundancy, we just omit the mask
of 0x0800 (with 0xFFFF) in the mask byte string example. The prefix
'0x' for the spec and mask byte (hex) strings are also omitted here.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/ice_ethdev.h           |  17 ++
 drivers/net/ice/ice_fdir_filter.c      | 249 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 5 files changed, 277 insertions(+)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index b327c2bfca..f7f45b9fa5 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -155,6 +155,7 @@ New Features
 
 * **Updated Intel ice driver.**
 
+  * Added protocol agnostic flow offloading support in Flow Director.
   * Added 1PPS out support by a devargs.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
   * Added DEV_RX_OFFLOAD_TIMESTAMP support.
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 599e0028f7..6d93fca033 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -318,6 +318,11 @@ struct ice_fdir_filter_conf {
 	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
 	uint64_t input_set_i; /* only for tunnel inner fields */
 	uint32_t mark_flag;
+
+	struct ice_parser_profile *prof;
+	const u8 *pkt_buf;
+	bool parser_ena;
+	u8 pkt_len;
 };
 
 #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
@@ -487,6 +492,17 @@ struct ice_devargs {
 	uint8_t pps_out_ena;
 };
 
+/**
+ * Structure to store fdir fv entry.
+ */
+struct ice_fdir_prof_info {
+	struct LIST_ENTRY_TYPE l_entry;
+
+	struct ice_parser_profile prof;
+	u16 ptype;
+	u64 fdir_actived_cnt;
+};
+
 /**
  * Structure to store private data for each PF/VF instance.
  */
@@ -509,6 +525,7 @@ struct ice_adapter {
 	struct rte_timecounter rx_tstamp_tc;
 	struct rte_timecounter tx_tstamp_tc;
 	bool ptp_ena;
+	struct LIST_HEAD_TYPE fdir_prof_list;
 #ifdef RTE_ARCH_X86
 	bool rx_use_avx2;
 	bool rx_use_avx512;
diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
index bd627e3aa8..81a07f191a 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -107,6 +107,7 @@
 	ICE_INSET_NAT_T_ESP_SPI)
 
 static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+	{pattern_raw,					ICE_INSET_NONE,			ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_ethertype,				ICE_FDIR_INSET_ETH,		ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,	ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,	ICE_INSET_NONE,			ICE_INSET_NONE},
@@ -1158,6 +1159,8 @@ ice_fdir_init(struct ice_adapter *ad)
 	if (ret)
 		return ret;
 
+	INIT_LIST_HEAD(&ad->fdir_prof_list);
+
 	parser = &ice_fdir_parser;
 
 	return ice_register_parser(parser, ad);
@@ -1188,6 +1191,24 @@ ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type)
 		return 0;
 }
 
+static int
+ice_fdir_add_del_raw(struct ice_pf *pf,
+		     struct ice_fdir_filter_conf *filter,
+		     bool add)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
+	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
+
+	struct ice_fltr_desc desc;
+	memset(&desc, 0, sizeof(desc));
+	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
+	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
+
+	return ice_fdir_programming(pf, &desc);
+}
+
 static int
 ice_fdir_add_del_filter(struct ice_pf *pf,
 			struct ice_fdir_filter_conf *filter,
@@ -1303,6 +1324,91 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 	struct ice_fdir_fltr_pattern key;
 	bool is_tun;
 	int ret;
+	int i;
+
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+		bool fv_found = false;
+		u16 vsi_num;
+
+		struct ice_fdir_prof_info *pi;
+		LIST_FOR_EACH_ENTRY(pi, &ad->fdir_prof_list,
+				    ice_fdir_prof_info, l_entry) {
+			if (pi->ptype != id)
+				continue;
+			if (!pi->fdir_actived_cnt) {
+				vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi);
+				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
+							   vsi_num, id);
+
+				vsi_num = ice_get_hw_vsi_num(hw, main_vsi);
+				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
+							   vsi_num, id);
+			}
+			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
+				if (pi->prof.fv[i].proto_id !=
+				    filter->prof->fv[i].proto_id ||
+				    pi->prof.fv[i].offset !=
+				    filter->prof->fv[i].offset)
+					break;
+			if (i == ICE_MAX_FV_WORDS) {
+				fv_found = true;
+				pi->fdir_actived_cnt++;
+				break;
+			}
+		}
+
+		ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
+					   filter->prof, ICE_BLK_FD, fv_found);
+		if (ret)
+			return -rte_errno;
+
+		ret = ice_fdir_add_del_raw(pf, filter, true);
+		if (ret)
+			return -rte_errno;
+
+		if (!fv_found) {
+			pi = (struct ice_fdir_prof_info *)
+				ice_malloc(hw, sizeof(*pi));
+			if (!pi)
+				return ICE_ERR_NO_MEMORY;
+
+			memset(&pi->prof, 0, sizeof(pi->prof));
+
+			for (i = 0; i < filter->prof->fv_num; i++) {
+				pi->prof.fv[i].proto_id =
+					filter->prof->fv[i].proto_id;
+				pi->prof.fv[i].offset =
+					filter->prof->fv[i].offset;
+				pi->prof.fv[i].spec = filter->prof->fv[i].spec;
+				pi->prof.fv[i].msk = filter->prof->fv[i].msk;
+			}
+			pi->ptype = id;
+			pi->fdir_actived_cnt = 1;
+
+			LIST_ADD(&pi->l_entry, &ad->fdir_prof_list);
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 1);
+
+		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
+		if (!entry)
+			return -rte_errno;
+
+		rte_memcpy(entry, filter, sizeof(*filter));
+
+		filter->prof = NULL;
+		filter->pkt_buf = NULL;
+
+		flow->rule = entry;
+
+		return 0;
+	}
 
 	ice_fdir_extract_fltr_key(&key, filter);
 	node = ice_fdir_entry_lookup(fdir_info, &key);
@@ -1397,6 +1503,42 @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
 
 	filter = (struct ice_fdir_filter_conf *)flow->rule;
 
+	if (filter->parser_ena) {
+		ret = ice_fdir_add_del_raw(pf, filter, false);
+		if (ret)
+			return -rte_errno;
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		int i;
+		struct ice_fdir_prof_info *pi;
+		LIST_FOR_EACH_ENTRY(pi, &ad->fdir_prof_list,
+				    ice_fdir_prof_info, l_entry) {
+			if (pi->ptype != id)
+				continue;
+			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
+				if (pi->prof.fv[i].proto_id !=
+				    filter->prof->fv[i].proto_id ||
+				    pi->prof.fv[i].offset !=
+				    filter->prof->fv[i].offset)
+					break;
+			if (i == ICE_MAX_FV_WORDS) {
+				pi->fdir_actived_cnt--;
+				break;
+			}
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 0);
+
+		flow->rule = NULL;
+		filter->prof = NULL;
+		filter->pkt_buf = NULL;
+
+		rte_free(filter);
+
+		return 0;
+	}
+
 	is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type);
 
 	if (filter->counter) {
@@ -1675,6 +1817,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
 	enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END;
 	enum ice_fdir_tunnel_type tunnel_type = ICE_FDIR_TUNNEL_TYPE_NONE;
+	const struct rte_flow_item_raw *raw_spec, *raw_mask;
 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
@@ -1702,6 +1845,9 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	struct ice_fdir_extra *p_ext_data;
 	struct ice_fdir_v4 *p_v4 = NULL;
 	struct ice_fdir_v6 *p_v6 = NULL;
+	struct ice_parser_result rslt;
+	struct ice_parser *psr;
+	uint8_t item_num = 0;
 
 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 		if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN)
@@ -1713,6 +1859,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 		    item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
 			is_outer = false;
 		}
+		item_num++;
 	}
 
 	/* This loop parse flow pattern and distinguish Non-tunnel and tunnel
@@ -1733,6 +1880,101 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 			    &input_set_i : &input_set_o;
 
 		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_RAW:
+			raw_spec = item->spec;
+			raw_mask = item->mask;
+
+			if (item_num != 1)
+				break;
+
+			/* convert raw spec & mask from byte string to int */
+			unsigned char *tmp_spec =
+				(uint8_t *)(uintptr_t)raw_spec->pattern;
+			unsigned char *tmp_mask =
+				(uint8_t *)(uintptr_t)raw_mask->pattern;
+			uint16_t udp_port = 0;
+			uint16_t tmp_val = 0;
+			uint8_t pkt_len = 0;
+			uint8_t tmp = 0;
+			int i, j;
+
+			pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern);
+			if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
+				pkt_len)
+				return -rte_errno;
+
+			for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
+				tmp = tmp_spec[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_spec[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_spec[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_spec[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_spec[j] = tmp_val + tmp - '0';
+
+				tmp = tmp_mask[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_mask[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_mask[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_mask[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_mask[j] = tmp_val + tmp - '0';
+			}
+
+			pkt_len /= 2;
+
+			if (ice_parser_create(&ad->hw, &psr))
+				return -rte_errno;
+			if (ice_get_open_tunnel_port(&ad->hw, TNL_VXLAN,
+						     &udp_port))
+				ice_parser_vxlan_tunnel_set(psr, udp_port,
+							    true);
+			if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt))
+				return -rte_errno;
+			ice_parser_destroy(psr);
+
+			if (!tmp_mask)
+				return -rte_errno;
+
+			filter->prof = (struct ice_parser_profile *)
+				ice_malloc(&ad->hw, sizeof(*filter->prof));
+			if (!filter->prof)
+				return -ENOMEM;
+
+			if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask,
+				pkt_len, ICE_BLK_FD, true, filter->prof))
+				return -rte_errno;
+
+			u8 *pkt_buf = (u8 *)ice_malloc(&ad->hw, pkt_len + 1);
+			if (!pkt_buf)
+				return -ENOMEM;
+			rte_memcpy(pkt_buf, tmp_spec, pkt_len);
+			filter->pkt_buf = pkt_buf;
+
+			filter->pkt_len = pkt_len;
+
+			filter->parser_ena = true;
+
+			break;
+
 		case RTE_FLOW_ITEM_TYPE_ETH:
 			flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
 			eth_spec = item->spec;
@@ -2198,6 +2440,7 @@ ice_fdir_parse(struct ice_adapter *ad,
 	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
 	struct ice_pattern_match_item *item = NULL;
 	uint64_t input_set;
+	bool raw = false;
 	int ret;
 
 	memset(filter, 0, sizeof(*filter));
@@ -2213,7 +2456,13 @@ ice_fdir_parse(struct ice_adapter *ad,
 	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
 	if (ret)
 		goto error;
+
+	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
+		raw = true;
+
 	input_set = filter->input_set_o | filter->input_set_i;
+	input_set = raw ? ~input_set : input_set;
+
 	if (!input_set || filter->input_set_o &
 	    ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) ||
 	    filter->input_set_i & ~item->input_set_mask_i) {
diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 02f854666a..d3391c86c0 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -65,6 +65,12 @@ enum rte_flow_item_type pattern_empty[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* raw */
+enum rte_flow_item_type pattern_raw[] = {
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 /* L2 */
 enum rte_flow_item_type pattern_ethertype[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
@@ -2081,6 +2087,7 @@ struct ice_ptype_match {
 };
 
 static struct ice_ptype_match ice_ptype_map[] = {
+	{pattern_raw,					ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4,				ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4_udp,				ICE_PTYPE_IPV4_UDP_PAY},
 	{pattern_eth_ipv4_tcp,				ICE_PTYPE_IPV4_TCP_PAY},
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index 8845a3e156..1b030c0466 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -124,6 +124,9 @@
 /* empty pattern */
 extern enum rte_flow_item_type pattern_empty[];
 
+/* raw pattern */
+extern enum rte_flow_item_type pattern_raw[];
+
 /* L2 */
 extern enum rte_flow_item_type pattern_ethertype[];
 extern enum rte_flow_item_type pattern_ethertype_vlan[];
-- 
2.25.1


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

* [dpdk-dev] [PATCH v6 0/4] enable protocol agnostic flow offloading in FDIR
  2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-10-28  8:34                   ` Junfeng Guo
  2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
                                       ` (3 more replies)
  0 siblings, 4 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-28  8:34 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch set based on the Parser Library using existing rte_flow raw API.

[PATCH v4 1/4] net/ice/base: add method to disable FDIR SWAP option.
[PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow.
[PATCH v4 3/4] app/testpmd: update Max RAW pattern size to 512.
[PATCH v4 4/4] net/ice: enable protocol agnostic flow offloading in FDIR.

Junfeng Guo (4):
  net/ice/base: add method to disable FDIR SWAP option
  net/ice/base: add function to set HW profile for raw flow
  app/testpmd: update Max RAW pattern size to 512
  net/ice: enable protocol agnostic flow offloading in FDIR

* v6:
Removed redundant code.

* v5:
Optimized some code logic.

* v4:
Added list to check inputset conflict.

* v3:
Added necessary base code for raw flow in FDIR.

* v2:
Enabled vxlan port add for raw flow and updated commit message

 app/test-pmd/cmdline_flow.c            |   2 +-
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/base/ice_flex_pipe.c   |  93 ++++++++-
 drivers/net/ice/base/ice_flex_pipe.h   |   6 +-
 drivers/net/ice/base/ice_flow.c        |  86 ++++++++-
 drivers/net/ice/base/ice_flow.h        |   4 +
 drivers/net/ice/ice_ethdev.h           |  17 ++
 drivers/net/ice/ice_fdir_filter.c      | 257 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 10 files changed, 471 insertions(+), 5 deletions(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH v6 1/4] net/ice/base: add method to disable FDIR SWAP option
  2021-10-28  8:34                   ` [dpdk-dev] [PATCH v6 0/4] " Junfeng Guo
@ 2021-10-28  8:34                     ` Junfeng Guo
  2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
                                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-28  8:34 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

The SWAP Flag in the FDIR Programming Descriptor doesn't work, thus
add a method to disable the FDIR SWAP option by setting the swap and
inset register set with certain values. The boolean fd_swap is used
to enable/disable the SWAP option.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 44 ++++++++++++++++++++++++++--
 drivers/net/ice/base/ice_flex_pipe.h |  3 +-
 drivers/net/ice/base/ice_flow.c      |  2 +-
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index f35d59f4f5..06a233990f 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -4952,6 +4952,43 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 	return ICE_SUCCESS;
 }
 
+/**
+ * ice_disable_fd_swap - set register appropriately to disable FD swap
+ * @hw: pointer to the HW struct
+ * @prof_id: profile ID
+ */
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id)
+{
+	u8 swap_val = ICE_SWAP_VALID;
+	u8 i;
+	/* Since the SWAP Flag in the Programming Desc doesn't work,
+	 * here add method to disable the SWAP Option via setting
+	 * certain SWAP and INSET register set.
+	 */
+	for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw / 4; i++) {
+		u32 raw_swap = 0;
+		u32 raw_in = 0;
+		u8 j;
+
+		for (j = 0; j < 4; j++) {
+			raw_swap |= (swap_val++) << (j * BITS_PER_BYTE);
+			raw_in |= ICE_INSET_DFLT << (j * BITS_PER_BYTE);
+		}
+
+		/* write the FDIR swap register set */
+		wr32(hw, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		/* write the FDIR inset register set */
+		wr32(hw, GLQF_FDINSET(prof_id, i), raw_in);
+
+		ice_debug(hw, ICE_DBG_INIT, "inset wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDINSET(prof_id, i), raw_in);
+	}
+}
+
 /**
  * ice_add_prof - add profile
  * @hw: pointer to the HW struct
@@ -4962,6 +4999,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
  * @attr_cnt: number of elements in attrib array
  * @es: extraction sequence (length of array is determined by the block)
  * @masks: mask for extraction sequence
+ * @fd_swap: enable/disable FDIR paired src/dst fields swap option
  *
  * This function registers a profile, which matches a set of PTYPES with a
  * particular extraction sequence. While the hardware profile is allocated
@@ -4971,7 +5009,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks)
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap)
 {
 	u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE);
 	ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT);
@@ -4991,7 +5029,7 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 		status = ice_alloc_prof_id(hw, blk, &prof_id);
 		if (status)
 			goto err_ice_add_prof;
-		if (blk == ICE_BLK_FD) {
+		if (blk == ICE_BLK_FD && fd_swap) {
 			/* For Flow Director block, the extraction sequence may
 			 * need to be altered in the case where there are paired
 			 * fields that have no match. This is necessary because
@@ -5002,6 +5040,8 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 			status = ice_update_fd_swap(hw, prof_id, es);
 			if (status)
 				goto err_ice_add_prof;
+		} else if (blk == ICE_BLK_FD) {
+			ice_disable_fd_swap(hw, prof_id);
 		}
 		status = ice_update_prof_masking(hw, blk, prof_id, masks);
 		if (status)
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index 9733c4b214..dd332312dd 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -61,10 +61,11 @@ bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype);
 /* XLT2/VSI group functions */
 enum ice_status
 ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig);
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id);
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks);
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap);
 void ice_init_all_prof_masks(struct ice_hw *hw);
 void ice_shutdown_all_prof_masks(struct ice_hw *hw);
 struct ice_prof_map *
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 96d54b494d..77b6b130c1 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2244,7 +2244,7 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
 	/* Add a HW profile for this flow profile */
 	status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
 			      params->attr, params->attr_cnt, params->es,
-			      params->mask);
+			      params->mask, true);
 	if (status) {
 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
 		goto out;
-- 
2.25.1


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

* [dpdk-dev] [PATCH v6 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-10-28  8:34                   ` [dpdk-dev] [PATCH v6 0/4] " Junfeng Guo
  2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
@ 2021-10-28  8:34                     ` Junfeng Guo
  2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
  2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  3 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-28  8:34 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Based on the parser library, we can directly set HW profile and
associate the main/ctrl vsi.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 49 ++++++++++++++++
 drivers/net/ice/base/ice_flex_pipe.h |  3 +
 drivers/net/ice/base/ice_flow.c      | 84 ++++++++++++++++++++++++++++
 drivers/net/ice/base/ice_flow.h      |  4 ++
 4 files changed, 140 insertions(+)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index 06a233990f..395787806b 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -6365,3 +6365,52 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
 
 	return status;
 }
+
+/**
+ * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow entry
+ * @hw: pointer to the HW struct
+ * @blk: HW block
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @id: profile id (handle)
+ *
+ * Calling this function will update the hardware tables to enable the
+ * profile indicated by the ID parameter for the VSIs specified in the VSI
+ * array. Once successfully called, the flow will be enabled.
+ */
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id)
+{
+	enum ice_status status = ICE_SUCCESS;
+	u16 vsi_num;
+
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for main VSI flow entry, %d\n",
+			  status);
+		goto err_add_prof;
+	}
+
+	if (blk != ICE_BLK_FD)
+		return status;
+
+	vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for ctrl VSI flow entry, %d\n",
+			  status);
+		goto err_add_entry;
+	}
+
+	return status;
+
+err_add_entry:
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+err_add_prof:
+	ice_flow_rem_prof(hw, blk, id);
+
+	return status;
+}
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index dd332312dd..23ba45564a 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -76,6 +76,9 @@ enum ice_status
 ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 enum ice_status
 ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id);
 enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
 enum ice_status
 ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 77b6b130c1..f699dbbc74 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2524,6 +2524,90 @@ ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
 	return status;
 }
 
+#define FLAG_GTP_EH_PDU_LINK	BIT_ULL(13)
+#define FLAG_GTP_EH_PDU		BIT_ULL(14)
+
+#define FLAG_GTPU_MSK	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_DW	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_UP	\
+	(FLAG_GTP_EH_PDU)
+/**
+ * ice_flow_set_hw_prof - Set HW flow profile based on the parsed profile info
+ * @hw: pointer to the HW struct
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @prof: stores parsed profile info from raw flow
+ * @blk: classification stage
+ */
+enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk)
+{
+	int id = ice_find_first_bit(prof->ptypes, UINT16_MAX);
+	struct ice_flow_prof_params *params;
+	u8 fv_words = hw->blk[blk].es.fvw;
+	enum ice_status status;
+	u16 vsi_num;
+	int i, idx;
+
+	params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
+	if (!params)
+		return ICE_ERR_NO_MEMORY;
+
+	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
+		params->es[i].prot_id = ICE_PROT_INVALID;
+		params->es[i].off = ICE_FV_OFFSET_INVAL;
+	}
+
+	for (i = 0; i < prof->fv_num; i++) {
+		if (hw->blk[blk].es.reverse)
+			idx = fv_words - i - 1;
+		else
+			idx = i;
+		params->es[idx].prot_id = prof->fv[i].proto_id;
+		params->es[idx].off = prof->fv[i].offset;
+		params->mask[idx] = CPU_TO_BE16(prof->fv[i].msk);
+	}
+
+	switch (prof->flags) {
+	case FLAG_GTPU_DW:
+		params->attr = ice_attr_gtpu_down;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
+		break;
+	case FLAG_GTPU_UP:
+		params->attr = ice_attr_gtpu_up;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
+		break;
+	default:
+		if (prof->flags_msk & FLAG_GTPU_MSK) {
+			params->attr = ice_attr_gtpu_session;
+			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
+		}
+		break;
+	}
+
+	status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
+			      params->attr, params->attr_cnt,
+			      params->es, params->mask, false);
+	if (status)
+		goto free_params;
+
+	status = ice_flow_assoc_hw_prof(hw, blk, dest_vsi_handle,
+					fdir_vsi_handle, id);
+	if (status)
+		goto free_params;
+
+	return ICE_SUCCESS;
+
+free_params:
+	ice_free(hw, params);
+
+	return status;
+}
+
 /**
  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
  * @hw: pointer to the HW struct
diff --git a/drivers/net/ice/base/ice_flow.h b/drivers/net/ice/base/ice_flow.h
index 371d960066..dea7b3c0e8 100644
--- a/drivers/net/ice/base/ice_flow.h
+++ b/drivers/net/ice/base/ice_flow.h
@@ -548,6 +548,10 @@ enum ice_status
 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
 			u16 vsig);
 enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk);
+enum ice_status
 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
 		     u8 *hw_prof);
 
-- 
2.25.1


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

* [dpdk-dev] [PATCH v6 3/4] app/testpmd: update Max RAW pattern size to 512
  2021-10-28  8:34                   ` [dpdk-dev] [PATCH v6 0/4] " Junfeng Guo
  2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
  2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
@ 2021-10-28  8:34                     ` Junfeng Guo
  2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  3 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-28  8:34 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Update max size for pattern in struct rte_flow_item_raw to enable
protocol agnostic flow offloading.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 app/test-pmd/cmdline_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index d8218771fb..ef24710bd8 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -495,7 +495,7 @@ enum index {
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
-#define ITEM_RAW_PATTERN_SIZE 40
+#define ITEM_RAW_PATTERN_SIZE 512
 
 /** Maximum size for GENEVE option data pattern in bytes. */
 #define ITEM_GENEVE_OPT_DATA_SIZE 124
-- 
2.25.1


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

* [dpdk-dev] [PATCH v6 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-10-28  8:34                   ` [dpdk-dev] [PATCH v6 0/4] " Junfeng Guo
                                       ` (2 preceding siblings ...)
  2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-10-28  8:34                     ` Junfeng Guo
  2021-10-28  9:13                       ` [dpdk-dev] [PATCH v7 0/4] " Junfeng Guo
  3 siblings, 1 reply; 68+ messages in thread
From: Junfeng Guo @ 2021-10-28  8:34 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch based on the Parser Library, using existing rte_flow raw API.

Note that the raw flow requires:
1. byte string of raw target packet bits.
2. byte string of mask of target packet.

Here is an example:
FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:

flow create 0 ingress pattern raw \
pattern spec \
00000000000000000000000008004500001400004000401000000000000001020304 \
pattern mask \
000000000000000000000000000000000000000000000000000000000000ffffffff \
/ end actions queue index 3 / mark id 3 / end

Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto)
is optional in our cases. To avoid redundancy, we just omit the mask
of 0x0800 (with 0xFFFF) in the mask byte string example. The prefix
'0x' for the spec and mask byte (hex) strings are also omitted here.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/ice_ethdev.h           |  17 ++
 drivers/net/ice/ice_fdir_filter.c      | 257 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 5 files changed, 285 insertions(+)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 9c13ceed1c..cc449a4340 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -167,6 +167,7 @@ New Features
 
 * **Updated Intel ice driver.**
 
+  * Added protocol agnostic flow offloading support in Flow Director.
   * Added 1PPS out support by a devargs.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
   * Added DEV_RX_OFFLOAD_TIMESTAMP support.
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 599e0028f7..441242ee89 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -318,6 +318,11 @@ struct ice_fdir_filter_conf {
 	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
 	uint64_t input_set_i; /* only for tunnel inner fields */
 	uint32_t mark_flag;
+
+	struct ice_parser_profile *prof;
+	const u8 *pkt_buf;
+	bool parser_ena;
+	u8 pkt_len;
 };
 
 #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
@@ -487,6 +492,17 @@ struct ice_devargs {
 	uint8_t pps_out_ena;
 };
 
+/**
+ * Structure to store fdir fv entry.
+ */
+struct ice_fdir_prof_info {
+	struct LIST_ENTRY_TYPE l_entry;
+
+	struct ice_parser_profile prof;
+	u16 ptg;
+	u64 fdir_actived_cnt;
+};
+
 /**
  * Structure to store private data for each PF/VF instance.
  */
@@ -509,6 +525,7 @@ struct ice_adapter {
 	struct rte_timecounter rx_tstamp_tc;
 	struct rte_timecounter tx_tstamp_tc;
 	bool ptp_ena;
+	struct LIST_HEAD_TYPE fdir_prof_list;
 #ifdef RTE_ARCH_X86
 	bool rx_use_avx2;
 	bool rx_use_avx512;
diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
index bd627e3aa8..d5ae84b86d 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -107,6 +107,7 @@
 	ICE_INSET_NAT_T_ESP_SPI)
 
 static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+	{pattern_raw,					ICE_INSET_NONE,			ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_ethertype,				ICE_FDIR_INSET_ETH,		ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,	ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,	ICE_INSET_NONE,			ICE_INSET_NONE},
@@ -1158,6 +1159,8 @@ ice_fdir_init(struct ice_adapter *ad)
 	if (ret)
 		return ret;
 
+	INIT_LIST_HEAD(&ad->fdir_prof_list);
+
 	parser = &ice_fdir_parser;
 
 	return ice_register_parser(parser, ad);
@@ -1188,6 +1191,24 @@ ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type)
 		return 0;
 }
 
+static int
+ice_fdir_add_del_raw(struct ice_pf *pf,
+		     struct ice_fdir_filter_conf *filter,
+		     bool add)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
+	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
+
+	struct ice_fltr_desc desc;
+	memset(&desc, 0, sizeof(desc));
+	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
+	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
+
+	return ice_fdir_programming(pf, &desc);
+}
+
 static int
 ice_fdir_add_del_filter(struct ice_pf *pf,
 			struct ice_fdir_filter_conf *filter,
@@ -1303,6 +1324,97 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 	struct ice_fdir_fltr_pattern key;
 	bool is_tun;
 	int ret;
+	int i;
+
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+		bool fv_found = false;
+		u16 vsi_num;
+
+		struct ice_fdir_prof_info *pi;
+		LIST_FOR_EACH_ENTRY(pi, &ad->fdir_prof_list,
+				    ice_fdir_prof_info, l_entry) {
+			if (pi->ptg != hw->blk[ICE_BLK_FD].xlt1.t[id])
+				continue;
+			if (!pi->fdir_actived_cnt) {
+				vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi);
+				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
+							   vsi_num, id);
+				if (ret)
+					return -rte_errno;
+
+				vsi_num = ice_get_hw_vsi_num(hw, main_vsi);
+				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
+							   vsi_num, id);
+				if (ret)
+					return -rte_errno;
+			}
+			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
+				if (pi->prof.fv[i].proto_id !=
+				    filter->prof->fv[i].proto_id ||
+				    pi->prof.fv[i].offset !=
+				    filter->prof->fv[i].offset)
+					break;
+			if (i == ICE_MAX_FV_WORDS) {
+				fv_found = true;
+				pi->fdir_actived_cnt++;
+				break;
+			}
+		}
+
+		if (!fv_found) {
+			ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
+						   filter->prof, ICE_BLK_FD);
+			if (ret)
+				return -rte_errno;
+		}
+
+		ret = ice_fdir_add_del_raw(pf, filter, true);
+		if (ret)
+			return -rte_errno;
+
+		if (!fv_found) {
+			pi = (struct ice_fdir_prof_info *)
+				ice_malloc(hw, sizeof(*pi));
+			if (!pi)
+				return ICE_ERR_NO_MEMORY;
+
+			memset(&pi->prof, 0, sizeof(pi->prof));
+
+			for (i = 0; i < filter->prof->fv_num; i++) {
+				pi->prof.fv[i].proto_id =
+					filter->prof->fv[i].proto_id;
+				pi->prof.fv[i].offset =
+					filter->prof->fv[i].offset;
+				pi->prof.fv[i].spec = filter->prof->fv[i].spec;
+				pi->prof.fv[i].msk = filter->prof->fv[i].msk;
+			}
+			pi->ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
+			pi->fdir_actived_cnt = 1;
+
+			LIST_ADD(&pi->l_entry, &ad->fdir_prof_list);
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 1);
+
+		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
+		if (!entry)
+			return -rte_errno;
+
+		rte_memcpy(entry, filter, sizeof(*filter));
+
+		filter->prof = NULL;
+		filter->pkt_buf = NULL;
+
+		flow->rule = entry;
+
+		return 0;
+	}
 
 	ice_fdir_extract_fltr_key(&key, filter);
 	node = ice_fdir_entry_lookup(fdir_info, &key);
@@ -1397,6 +1509,44 @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
 
 	filter = (struct ice_fdir_filter_conf *)flow->rule;
 
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		ret = ice_fdir_add_del_raw(pf, filter, false);
+		if (ret)
+			return -rte_errno;
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		int i;
+		struct ice_fdir_prof_info *pi;
+		LIST_FOR_EACH_ENTRY(pi, &ad->fdir_prof_list,
+				    ice_fdir_prof_info, l_entry) {
+			if (pi->ptg != hw->blk[ICE_BLK_FD].xlt1.t[id])
+				continue;
+			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
+				if (pi->prof.fv[i].proto_id !=
+				    filter->prof->fv[i].proto_id ||
+				    pi->prof.fv[i].offset !=
+				    filter->prof->fv[i].offset)
+					break;
+			if (i == ICE_MAX_FV_WORDS) {
+				pi->fdir_actived_cnt--;
+				break;
+			}
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 0);
+
+		flow->rule = NULL;
+		filter->prof = NULL;
+		filter->pkt_buf = NULL;
+
+		rte_free(filter);
+
+		return 0;
+	}
+
 	is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type);
 
 	if (filter->counter) {
@@ -1675,6 +1825,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
 	enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END;
 	enum ice_fdir_tunnel_type tunnel_type = ICE_FDIR_TUNNEL_TYPE_NONE;
+	const struct rte_flow_item_raw *raw_spec, *raw_mask;
 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
@@ -1702,6 +1853,9 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	struct ice_fdir_extra *p_ext_data;
 	struct ice_fdir_v4 *p_v4 = NULL;
 	struct ice_fdir_v6 *p_v6 = NULL;
+	struct ice_parser_result rslt;
+	struct ice_parser *psr;
+	uint8_t item_num = 0;
 
 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 		if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN)
@@ -1713,6 +1867,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 		    item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
 			is_outer = false;
 		}
+		item_num++;
 	}
 
 	/* This loop parse flow pattern and distinguish Non-tunnel and tunnel
@@ -1733,6 +1888,101 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 			    &input_set_i : &input_set_o;
 
 		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_RAW:
+			raw_spec = item->spec;
+			raw_mask = item->mask;
+
+			if (item_num != 1)
+				break;
+
+			/* convert raw spec & mask from byte string to int */
+			unsigned char *tmp_spec =
+				(uint8_t *)(uintptr_t)raw_spec->pattern;
+			unsigned char *tmp_mask =
+				(uint8_t *)(uintptr_t)raw_mask->pattern;
+			uint16_t udp_port = 0;
+			uint16_t tmp_val = 0;
+			uint8_t pkt_len = 0;
+			uint8_t tmp = 0;
+			int i, j;
+
+			pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern);
+			if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
+				pkt_len)
+				return -rte_errno;
+
+			for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
+				tmp = tmp_spec[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_spec[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_spec[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_spec[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_spec[j] = tmp_val + tmp - '0';
+
+				tmp = tmp_mask[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_mask[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_mask[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_mask[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_mask[j] = tmp_val + tmp - '0';
+			}
+
+			pkt_len /= 2;
+
+			if (ice_parser_create(&ad->hw, &psr))
+				return -rte_errno;
+			if (ice_get_open_tunnel_port(&ad->hw, TNL_VXLAN,
+						     &udp_port))
+				ice_parser_vxlan_tunnel_set(psr, udp_port,
+							    true);
+			if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt))
+				return -rte_errno;
+			ice_parser_destroy(psr);
+
+			if (!tmp_mask)
+				return -rte_errno;
+
+			filter->prof = (struct ice_parser_profile *)
+				ice_malloc(&ad->hw, sizeof(*filter->prof));
+			if (!filter->prof)
+				return -ENOMEM;
+
+			if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask,
+				pkt_len, ICE_BLK_FD, true, filter->prof))
+				return -rte_errno;
+
+			u8 *pkt_buf = (u8 *)ice_malloc(&ad->hw, pkt_len + 1);
+			if (!pkt_buf)
+				return -ENOMEM;
+			rte_memcpy(pkt_buf, tmp_spec, pkt_len);
+			filter->pkt_buf = pkt_buf;
+
+			filter->pkt_len = pkt_len;
+
+			filter->parser_ena = true;
+
+			break;
+
 		case RTE_FLOW_ITEM_TYPE_ETH:
 			flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
 			eth_spec = item->spec;
@@ -2198,6 +2448,7 @@ ice_fdir_parse(struct ice_adapter *ad,
 	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
 	struct ice_pattern_match_item *item = NULL;
 	uint64_t input_set;
+	bool raw = false;
 	int ret;
 
 	memset(filter, 0, sizeof(*filter));
@@ -2213,7 +2464,13 @@ ice_fdir_parse(struct ice_adapter *ad,
 	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
 	if (ret)
 		goto error;
+
+	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
+		raw = true;
+
 	input_set = filter->input_set_o | filter->input_set_i;
+	input_set = raw ? ~input_set : input_set;
+
 	if (!input_set || filter->input_set_o &
 	    ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) ||
 	    filter->input_set_i & ~item->input_set_mask_i) {
diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 02f854666a..d3391c86c0 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -65,6 +65,12 @@ enum rte_flow_item_type pattern_empty[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* raw */
+enum rte_flow_item_type pattern_raw[] = {
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 /* L2 */
 enum rte_flow_item_type pattern_ethertype[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
@@ -2081,6 +2087,7 @@ struct ice_ptype_match {
 };
 
 static struct ice_ptype_match ice_ptype_map[] = {
+	{pattern_raw,					ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4,				ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4_udp,				ICE_PTYPE_IPV4_UDP_PAY},
 	{pattern_eth_ipv4_tcp,				ICE_PTYPE_IPV4_TCP_PAY},
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index 8845a3e156..1b030c0466 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -124,6 +124,9 @@
 /* empty pattern */
 extern enum rte_flow_item_type pattern_empty[];
 
+/* raw pattern */
+extern enum rte_flow_item_type pattern_raw[];
+
 /* L2 */
 extern enum rte_flow_item_type pattern_ethertype[];
 extern enum rte_flow_item_type pattern_ethertype_vlan[];
-- 
2.25.1


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

* [dpdk-dev] [PATCH v7 0/4] enable protocol agnostic flow offloading in FDIR
  2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-10-28  9:13                       ` Junfeng Guo
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
                                           ` (3 more replies)
  0 siblings, 4 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-28  9:13 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch set based on the Parser Library using existing rte_flow raw API.

[PATCH v7 1/4] net/ice/base: add method to disable FDIR SWAP option.
[PATCH v7 2/4] net/ice/base: add function to set HW profile for raw flow.
[PATCH v7 3/4] app/testpmd: update Max RAW pattern size to 512.
[PATCH v7 4/4] net/ice: enable protocol agnostic flow offloading in FDIR.

Junfeng Guo (4):
  net/ice/base: add method to disable FDIR SWAP option
  net/ice/base: add function to set HW profile for raw flow
  app/testpmd: update Max RAW pattern size to 512
  net/ice: enable protocol agnostic flow offloading in FDIR

* v7:
Fix LIST_FOR_EACH_ENTRY logic.

* v6:
Removed redundant code.

* v5:
Optimized some code logic.

* v4:
Added list to check inputset conflict.

* v3:
Added necessary base code for raw flow in FDIR.

* v2:
Enabled vxlan port add for raw flow and updated commit message

 app/test-pmd/cmdline_flow.c            |   2 +-
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/base/ice_flex_pipe.c   |  93 ++++++++-
 drivers/net/ice/base/ice_flex_pipe.h   |   6 +-
 drivers/net/ice/base/ice_flow.c        |  86 +++++++-
 drivers/net/ice/base/ice_flow.h        |   4 +
 drivers/net/ice/ice_ethdev.h           |  17 ++
 drivers/net/ice/ice_fdir_filter.c      | 260 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 10 files changed, 474 insertions(+), 5 deletions(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH v7 1/4] net/ice/base: add method to disable FDIR SWAP option
  2021-10-28  9:13                       ` [dpdk-dev] [PATCH v7 0/4] " Junfeng Guo
@ 2021-10-28  9:13                         ` Junfeng Guo
  2021-10-28 11:26                           ` Zhang, Qi Z
  2021-10-28 15:09                           ` Ferruh Yigit
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
                                           ` (2 subsequent siblings)
  3 siblings, 2 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-28  9:13 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

The SWAP Flag in the FDIR Programming Descriptor doesn't work, thus
add a method to disable the FDIR SWAP option by setting the swap and
inset register set with certain values. The boolean fd_swap is used
to enable/disable the SWAP option.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 44 ++++++++++++++++++++++++++--
 drivers/net/ice/base/ice_flex_pipe.h |  3 +-
 drivers/net/ice/base/ice_flow.c      |  2 +-
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index f35d59f4f5..06a233990f 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -4952,6 +4952,43 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 	return ICE_SUCCESS;
 }
 
+/**
+ * ice_disable_fd_swap - set register appropriately to disable FD swap
+ * @hw: pointer to the HW struct
+ * @prof_id: profile ID
+ */
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id)
+{
+	u8 swap_val = ICE_SWAP_VALID;
+	u8 i;
+	/* Since the SWAP Flag in the Programming Desc doesn't work,
+	 * here add method to disable the SWAP Option via setting
+	 * certain SWAP and INSET register set.
+	 */
+	for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw / 4; i++) {
+		u32 raw_swap = 0;
+		u32 raw_in = 0;
+		u8 j;
+
+		for (j = 0; j < 4; j++) {
+			raw_swap |= (swap_val++) << (j * BITS_PER_BYTE);
+			raw_in |= ICE_INSET_DFLT << (j * BITS_PER_BYTE);
+		}
+
+		/* write the FDIR swap register set */
+		wr32(hw, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		/* write the FDIR inset register set */
+		wr32(hw, GLQF_FDINSET(prof_id, i), raw_in);
+
+		ice_debug(hw, ICE_DBG_INIT, "inset wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDINSET(prof_id, i), raw_in);
+	}
+}
+
 /**
  * ice_add_prof - add profile
  * @hw: pointer to the HW struct
@@ -4962,6 +4999,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
  * @attr_cnt: number of elements in attrib array
  * @es: extraction sequence (length of array is determined by the block)
  * @masks: mask for extraction sequence
+ * @fd_swap: enable/disable FDIR paired src/dst fields swap option
  *
  * This function registers a profile, which matches a set of PTYPES with a
  * particular extraction sequence. While the hardware profile is allocated
@@ -4971,7 +5009,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks)
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap)
 {
 	u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE);
 	ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT);
@@ -4991,7 +5029,7 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 		status = ice_alloc_prof_id(hw, blk, &prof_id);
 		if (status)
 			goto err_ice_add_prof;
-		if (blk == ICE_BLK_FD) {
+		if (blk == ICE_BLK_FD && fd_swap) {
 			/* For Flow Director block, the extraction sequence may
 			 * need to be altered in the case where there are paired
 			 * fields that have no match. This is necessary because
@@ -5002,6 +5040,8 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 			status = ice_update_fd_swap(hw, prof_id, es);
 			if (status)
 				goto err_ice_add_prof;
+		} else if (blk == ICE_BLK_FD) {
+			ice_disable_fd_swap(hw, prof_id);
 		}
 		status = ice_update_prof_masking(hw, blk, prof_id, masks);
 		if (status)
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index 9733c4b214..dd332312dd 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -61,10 +61,11 @@ bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype);
 /* XLT2/VSI group functions */
 enum ice_status
 ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig);
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id);
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks);
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap);
 void ice_init_all_prof_masks(struct ice_hw *hw);
 void ice_shutdown_all_prof_masks(struct ice_hw *hw);
 struct ice_prof_map *
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 96d54b494d..77b6b130c1 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2244,7 +2244,7 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
 	/* Add a HW profile for this flow profile */
 	status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
 			      params->attr, params->attr_cnt, params->es,
-			      params->mask);
+			      params->mask, true);
 	if (status) {
 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
 		goto out;
-- 
2.25.1


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

* [dpdk-dev] [PATCH v7 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-10-28  9:13                       ` [dpdk-dev] [PATCH v7 0/4] " Junfeng Guo
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
@ 2021-10-28  9:13                         ` Junfeng Guo
  2021-10-28 11:28                           ` Zhang, Qi Z
  2021-10-28 15:13                           ` Ferruh Yigit
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  3 siblings, 2 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-28  9:13 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Based on the parser library, we can directly set HW profile and
associate the main/ctrl vsi.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 49 ++++++++++++++++
 drivers/net/ice/base/ice_flex_pipe.h |  3 +
 drivers/net/ice/base/ice_flow.c      | 84 ++++++++++++++++++++++++++++
 drivers/net/ice/base/ice_flow.h      |  4 ++
 4 files changed, 140 insertions(+)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index 06a233990f..395787806b 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -6365,3 +6365,52 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
 
 	return status;
 }
+
+/**
+ * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow entry
+ * @hw: pointer to the HW struct
+ * @blk: HW block
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @id: profile id (handle)
+ *
+ * Calling this function will update the hardware tables to enable the
+ * profile indicated by the ID parameter for the VSIs specified in the VSI
+ * array. Once successfully called, the flow will be enabled.
+ */
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id)
+{
+	enum ice_status status = ICE_SUCCESS;
+	u16 vsi_num;
+
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for main VSI flow entry, %d\n",
+			  status);
+		goto err_add_prof;
+	}
+
+	if (blk != ICE_BLK_FD)
+		return status;
+
+	vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for ctrl VSI flow entry, %d\n",
+			  status);
+		goto err_add_entry;
+	}
+
+	return status;
+
+err_add_entry:
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+err_add_prof:
+	ice_flow_rem_prof(hw, blk, id);
+
+	return status;
+}
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index dd332312dd..23ba45564a 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -76,6 +76,9 @@ enum ice_status
 ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 enum ice_status
 ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id);
 enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
 enum ice_status
 ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 77b6b130c1..f699dbbc74 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2524,6 +2524,90 @@ ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
 	return status;
 }
 
+#define FLAG_GTP_EH_PDU_LINK	BIT_ULL(13)
+#define FLAG_GTP_EH_PDU		BIT_ULL(14)
+
+#define FLAG_GTPU_MSK	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_DW	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_UP	\
+	(FLAG_GTP_EH_PDU)
+/**
+ * ice_flow_set_hw_prof - Set HW flow profile based on the parsed profile info
+ * @hw: pointer to the HW struct
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @prof: stores parsed profile info from raw flow
+ * @blk: classification stage
+ */
+enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk)
+{
+	int id = ice_find_first_bit(prof->ptypes, UINT16_MAX);
+	struct ice_flow_prof_params *params;
+	u8 fv_words = hw->blk[blk].es.fvw;
+	enum ice_status status;
+	u16 vsi_num;
+	int i, idx;
+
+	params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
+	if (!params)
+		return ICE_ERR_NO_MEMORY;
+
+	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
+		params->es[i].prot_id = ICE_PROT_INVALID;
+		params->es[i].off = ICE_FV_OFFSET_INVAL;
+	}
+
+	for (i = 0; i < prof->fv_num; i++) {
+		if (hw->blk[blk].es.reverse)
+			idx = fv_words - i - 1;
+		else
+			idx = i;
+		params->es[idx].prot_id = prof->fv[i].proto_id;
+		params->es[idx].off = prof->fv[i].offset;
+		params->mask[idx] = CPU_TO_BE16(prof->fv[i].msk);
+	}
+
+	switch (prof->flags) {
+	case FLAG_GTPU_DW:
+		params->attr = ice_attr_gtpu_down;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
+		break;
+	case FLAG_GTPU_UP:
+		params->attr = ice_attr_gtpu_up;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
+		break;
+	default:
+		if (prof->flags_msk & FLAG_GTPU_MSK) {
+			params->attr = ice_attr_gtpu_session;
+			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
+		}
+		break;
+	}
+
+	status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
+			      params->attr, params->attr_cnt,
+			      params->es, params->mask, false);
+	if (status)
+		goto free_params;
+
+	status = ice_flow_assoc_hw_prof(hw, blk, dest_vsi_handle,
+					fdir_vsi_handle, id);
+	if (status)
+		goto free_params;
+
+	return ICE_SUCCESS;
+
+free_params:
+	ice_free(hw, params);
+
+	return status;
+}
+
 /**
  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
  * @hw: pointer to the HW struct
diff --git a/drivers/net/ice/base/ice_flow.h b/drivers/net/ice/base/ice_flow.h
index 371d960066..dea7b3c0e8 100644
--- a/drivers/net/ice/base/ice_flow.h
+++ b/drivers/net/ice/base/ice_flow.h
@@ -548,6 +548,10 @@ enum ice_status
 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
 			u16 vsig);
 enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk);
+enum ice_status
 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
 		     u8 *hw_prof);
 
-- 
2.25.1


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

* [dpdk-dev] [PATCH v7 3/4] app/testpmd: update Max RAW pattern size to 512
  2021-10-28  9:13                       ` [dpdk-dev] [PATCH v7 0/4] " Junfeng Guo
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
@ 2021-10-28  9:13                         ` Junfeng Guo
  2021-10-28 11:46                           ` Zhang, Qi Z
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  3 siblings, 1 reply; 68+ messages in thread
From: Junfeng Guo @ 2021-10-28  9:13 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Update max size for pattern in struct rte_flow_item_raw to enable
protocol agnostic flow offloading.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 app/test-pmd/cmdline_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index d8218771fb..ef24710bd8 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -495,7 +495,7 @@ enum index {
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
-#define ITEM_RAW_PATTERN_SIZE 40
+#define ITEM_RAW_PATTERN_SIZE 512
 
 /** Maximum size for GENEVE option data pattern in bytes. */
 #define ITEM_GENEVE_OPT_DATA_SIZE 124
-- 
2.25.1


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

* [dpdk-dev] [PATCH v7 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-10-28  9:13                       ` [dpdk-dev] [PATCH v7 0/4] " Junfeng Guo
                                           ` (2 preceding siblings ...)
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-10-28  9:13                         ` Junfeng Guo
  2021-10-28 11:10                           ` Zhang, Qi Z
  2021-11-01  8:36                           ` [dpdk-dev] [PATCH v8 0/4] " Junfeng Guo
  3 siblings, 2 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-10-28  9:13 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch based on the Parser Library, using existing rte_flow raw API.

Note that the raw flow requires:
1. byte string of raw target packet bits.
2. byte string of mask of target packet.

Here is an example:
FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:

flow create 0 ingress pattern raw \
pattern spec \
00000000000000000000000008004500001400004000401000000000000001020304 \
pattern mask \
000000000000000000000000000000000000000000000000000000000000ffffffff \
/ end actions queue index 3 / mark id 3 / end

Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto)
is optional in our cases. To avoid redundancy, we just omit the mask
of 0x0800 (with 0xFFFF) in the mask byte string example. The prefix
'0x' for the spec and mask byte (hex) strings are also omitted here.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/ice_ethdev.h           |  17 ++
 drivers/net/ice/ice_fdir_filter.c      | 260 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 5 files changed, 288 insertions(+)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 9c13ceed1c..cc449a4340 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -167,6 +167,7 @@ New Features
 
 * **Updated Intel ice driver.**
 
+  * Added protocol agnostic flow offloading support in Flow Director.
   * Added 1PPS out support by a devargs.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
   * Added DEV_RX_OFFLOAD_TIMESTAMP support.
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 599e0028f7..441242ee89 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -318,6 +318,11 @@ struct ice_fdir_filter_conf {
 	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
 	uint64_t input_set_i; /* only for tunnel inner fields */
 	uint32_t mark_flag;
+
+	struct ice_parser_profile *prof;
+	const u8 *pkt_buf;
+	bool parser_ena;
+	u8 pkt_len;
 };
 
 #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
@@ -487,6 +492,17 @@ struct ice_devargs {
 	uint8_t pps_out_ena;
 };
 
+/**
+ * Structure to store fdir fv entry.
+ */
+struct ice_fdir_prof_info {
+	struct LIST_ENTRY_TYPE l_entry;
+
+	struct ice_parser_profile prof;
+	u16 ptg;
+	u64 fdir_actived_cnt;
+};
+
 /**
  * Structure to store private data for each PF/VF instance.
  */
@@ -509,6 +525,7 @@ struct ice_adapter {
 	struct rte_timecounter rx_tstamp_tc;
 	struct rte_timecounter tx_tstamp_tc;
 	bool ptp_ena;
+	struct LIST_HEAD_TYPE fdir_prof_list;
 #ifdef RTE_ARCH_X86
 	bool rx_use_avx2;
 	bool rx_use_avx512;
diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
index bd627e3aa8..bcf105d1bd 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -107,6 +107,7 @@
 	ICE_INSET_NAT_T_ESP_SPI)
 
 static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+	{pattern_raw,					ICE_INSET_NONE,			ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_ethertype,				ICE_FDIR_INSET_ETH,		ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,	ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,	ICE_INSET_NONE,			ICE_INSET_NONE},
@@ -1158,6 +1159,8 @@ ice_fdir_init(struct ice_adapter *ad)
 	if (ret)
 		return ret;
 
+	INIT_LIST_HEAD(&ad->fdir_prof_list);
+
 	parser = &ice_fdir_parser;
 
 	return ice_register_parser(parser, ad);
@@ -1188,6 +1191,24 @@ ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type)
 		return 0;
 }
 
+static int
+ice_fdir_add_del_raw(struct ice_pf *pf,
+		     struct ice_fdir_filter_conf *filter,
+		     bool add)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
+	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
+
+	struct ice_fltr_desc desc;
+	memset(&desc, 0, sizeof(desc));
+	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
+	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
+
+	return ice_fdir_programming(pf, &desc);
+}
+
 static int
 ice_fdir_add_del_filter(struct ice_pf *pf,
 			struct ice_fdir_filter_conf *filter,
@@ -1303,6 +1324,100 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 	struct ice_fdir_fltr_pattern key;
 	bool is_tun;
 	int ret;
+	int i;
+
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+		bool fv_found = false;
+		u16 vsi_num;
+
+		struct ice_fdir_prof_info *pi;
+		LIST_FOR_EACH_ENTRY(pi, &ad->fdir_prof_list,
+				    ice_fdir_prof_info, l_entry) {
+			if (pi->ptg != hw->blk[ICE_BLK_FD].xlt1.t[id])
+				continue;
+			if (!pi->fdir_actived_cnt) {
+				vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi);
+				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
+							   vsi_num, id);
+				if (ret)
+					return -rte_errno;
+
+				vsi_num = ice_get_hw_vsi_num(hw, main_vsi);
+				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
+							   vsi_num, id);
+				if (ret)
+					return -rte_errno;
+
+				LIST_DEL(&pi->l_entry);
+				continue;
+			}
+			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
+				if (pi->prof.fv[i].proto_id !=
+				    filter->prof->fv[i].proto_id ||
+				    pi->prof.fv[i].offset !=
+				    filter->prof->fv[i].offset)
+					break;
+			if (i == ICE_MAX_FV_WORDS) {
+				fv_found = true;
+				pi->fdir_actived_cnt++;
+				break;
+			}
+		}
+
+		if (!fv_found) {
+			ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
+						   filter->prof, ICE_BLK_FD);
+			if (ret)
+				return -rte_errno;
+		}
+
+		ret = ice_fdir_add_del_raw(pf, filter, true);
+		if (ret)
+			return -rte_errno;
+
+		if (!fv_found) {
+			pi = (struct ice_fdir_prof_info *)
+				ice_malloc(hw, sizeof(*pi));
+			if (!pi)
+				return ICE_ERR_NO_MEMORY;
+
+			memset(&pi->prof, 0, sizeof(pi->prof));
+
+			for (i = 0; i < filter->prof->fv_num; i++) {
+				pi->prof.fv[i].proto_id =
+					filter->prof->fv[i].proto_id;
+				pi->prof.fv[i].offset =
+					filter->prof->fv[i].offset;
+				pi->prof.fv[i].spec = filter->prof->fv[i].spec;
+				pi->prof.fv[i].msk = filter->prof->fv[i].msk;
+			}
+			pi->ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
+			pi->fdir_actived_cnt = 1;
+
+			LIST_ADD(&pi->l_entry, &ad->fdir_prof_list);
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 1);
+
+		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
+		if (!entry)
+			return -rte_errno;
+
+		rte_memcpy(entry, filter, sizeof(*filter));
+
+		filter->prof = NULL;
+		filter->pkt_buf = NULL;
+
+		flow->rule = entry;
+
+		return 0;
+	}
 
 	ice_fdir_extract_fltr_key(&key, filter);
 	node = ice_fdir_entry_lookup(fdir_info, &key);
@@ -1397,6 +1512,44 @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
 
 	filter = (struct ice_fdir_filter_conf *)flow->rule;
 
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		ret = ice_fdir_add_del_raw(pf, filter, false);
+		if (ret)
+			return -rte_errno;
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		int i;
+		struct ice_fdir_prof_info *pi;
+		LIST_FOR_EACH_ENTRY(pi, &ad->fdir_prof_list,
+				    ice_fdir_prof_info, l_entry) {
+			if (pi->ptg != hw->blk[ICE_BLK_FD].xlt1.t[id])
+				continue;
+			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
+				if (pi->prof.fv[i].proto_id !=
+				    filter->prof->fv[i].proto_id ||
+				    pi->prof.fv[i].offset !=
+				    filter->prof->fv[i].offset)
+					break;
+			if (i == ICE_MAX_FV_WORDS) {
+				pi->fdir_actived_cnt--;
+				break;
+			}
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 0);
+
+		flow->rule = NULL;
+		filter->prof = NULL;
+		filter->pkt_buf = NULL;
+
+		rte_free(filter);
+
+		return 0;
+	}
+
 	is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type);
 
 	if (filter->counter) {
@@ -1675,6 +1828,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
 	enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END;
 	enum ice_fdir_tunnel_type tunnel_type = ICE_FDIR_TUNNEL_TYPE_NONE;
+	const struct rte_flow_item_raw *raw_spec, *raw_mask;
 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
@@ -1702,6 +1856,9 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	struct ice_fdir_extra *p_ext_data;
 	struct ice_fdir_v4 *p_v4 = NULL;
 	struct ice_fdir_v6 *p_v6 = NULL;
+	struct ice_parser_result rslt;
+	struct ice_parser *psr;
+	uint8_t item_num = 0;
 
 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 		if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN)
@@ -1713,6 +1870,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 		    item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
 			is_outer = false;
 		}
+		item_num++;
 	}
 
 	/* This loop parse flow pattern and distinguish Non-tunnel and tunnel
@@ -1733,6 +1891,101 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 			    &input_set_i : &input_set_o;
 
 		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_RAW:
+			raw_spec = item->spec;
+			raw_mask = item->mask;
+
+			if (item_num != 1)
+				break;
+
+			/* convert raw spec & mask from byte string to int */
+			unsigned char *tmp_spec =
+				(uint8_t *)(uintptr_t)raw_spec->pattern;
+			unsigned char *tmp_mask =
+				(uint8_t *)(uintptr_t)raw_mask->pattern;
+			uint16_t udp_port = 0;
+			uint16_t tmp_val = 0;
+			uint8_t pkt_len = 0;
+			uint8_t tmp = 0;
+			int i, j;
+
+			pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern);
+			if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
+				pkt_len)
+				return -rte_errno;
+
+			for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
+				tmp = tmp_spec[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_spec[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_spec[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_spec[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_spec[j] = tmp_val + tmp - '0';
+
+				tmp = tmp_mask[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_mask[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_mask[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_mask[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_mask[j] = tmp_val + tmp - '0';
+			}
+
+			pkt_len /= 2;
+
+			if (ice_parser_create(&ad->hw, &psr))
+				return -rte_errno;
+			if (ice_get_open_tunnel_port(&ad->hw, TNL_VXLAN,
+						     &udp_port))
+				ice_parser_vxlan_tunnel_set(psr, udp_port,
+							    true);
+			if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt))
+				return -rte_errno;
+			ice_parser_destroy(psr);
+
+			if (!tmp_mask)
+				return -rte_errno;
+
+			filter->prof = (struct ice_parser_profile *)
+				ice_malloc(&ad->hw, sizeof(*filter->prof));
+			if (!filter->prof)
+				return -ENOMEM;
+
+			if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask,
+				pkt_len, ICE_BLK_FD, true, filter->prof))
+				return -rte_errno;
+
+			u8 *pkt_buf = (u8 *)ice_malloc(&ad->hw, pkt_len + 1);
+			if (!pkt_buf)
+				return -ENOMEM;
+			rte_memcpy(pkt_buf, tmp_spec, pkt_len);
+			filter->pkt_buf = pkt_buf;
+
+			filter->pkt_len = pkt_len;
+
+			filter->parser_ena = true;
+
+			break;
+
 		case RTE_FLOW_ITEM_TYPE_ETH:
 			flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
 			eth_spec = item->spec;
@@ -2198,6 +2451,7 @@ ice_fdir_parse(struct ice_adapter *ad,
 	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
 	struct ice_pattern_match_item *item = NULL;
 	uint64_t input_set;
+	bool raw = false;
 	int ret;
 
 	memset(filter, 0, sizeof(*filter));
@@ -2213,7 +2467,13 @@ ice_fdir_parse(struct ice_adapter *ad,
 	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
 	if (ret)
 		goto error;
+
+	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
+		raw = true;
+
 	input_set = filter->input_set_o | filter->input_set_i;
+	input_set = raw ? ~input_set : input_set;
+
 	if (!input_set || filter->input_set_o &
 	    ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) ||
 	    filter->input_set_i & ~item->input_set_mask_i) {
diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 02f854666a..d3391c86c0 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -65,6 +65,12 @@ enum rte_flow_item_type pattern_empty[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* raw */
+enum rte_flow_item_type pattern_raw[] = {
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 /* L2 */
 enum rte_flow_item_type pattern_ethertype[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
@@ -2081,6 +2087,7 @@ struct ice_ptype_match {
 };
 
 static struct ice_ptype_match ice_ptype_map[] = {
+	{pattern_raw,					ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4,				ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4_udp,				ICE_PTYPE_IPV4_UDP_PAY},
 	{pattern_eth_ipv4_tcp,				ICE_PTYPE_IPV4_TCP_PAY},
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index 8845a3e156..1b030c0466 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -124,6 +124,9 @@
 /* empty pattern */
 extern enum rte_flow_item_type pattern_empty[];
 
+/* raw pattern */
+extern enum rte_flow_item_type pattern_raw[];
+
 /* L2 */
 extern enum rte_flow_item_type pattern_ethertype[];
 extern enum rte_flow_item_type pattern_ethertype_vlan[];
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v7 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-10-28 11:10                           ` Zhang, Qi Z
  2021-11-01  8:36                           ` [dpdk-dev] [PATCH v8 0/4] " Junfeng Guo
  1 sibling, 0 replies; 68+ messages in thread
From: Zhang, Qi Z @ 2021-10-28 11:10 UTC (permalink / raw)
  To: Guo, Junfeng, Wu, Jingjing, Xing, Beilei; +Cc: dev, Yigit, Ferruh, Xu, Ting



> -----Original Message-----
> From: Guo, Junfeng <junfeng.guo@intel.com>
> Sent: Thursday, October 28, 2021 5:14 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Xu, Ting
> <ting.xu@intel.com>; Guo, Junfeng <junfeng.guo@intel.com>
> Subject: [PATCH v7 4/4] net/ice: enable protocol agnostic flow offloading in
> FDIR
> 
> Protocol agnostic flow offloading in Flow Director is enabled by this patch
> based on the Parser Library, using existing rte_flow raw API.
> 
> Note that the raw flow requires:
> 1. byte string of raw target packet bits.
> 2. byte string of mask of target packet.
> 
> Here is an example:
> FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:
> 
> flow create 0 ingress pattern raw \
> pattern spec \
> 0000000000000000000000000800450000140000400040100000000000000
> 1020304 \ pattern mask \
> 000000000000000000000000000000000000000000000000000000000000ff
> ffffff \ / end actions queue index 3 / mark id 3 / end
> 
> Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto) is
> optional in our cases. To avoid redundancy, we just omit the mask of 0x0800
> (with 0xFFFF) in the mask byte string example. The prefix '0x' for the spec and
> mask byte (hex) strings are also omitted here.
> 
> Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
> ---
>  doc/guides/rel_notes/release_21_11.rst |   1 +
>  drivers/net/ice/ice_ethdev.h           |  17 ++
>  drivers/net/ice/ice_fdir_filter.c      | 260 +++++++++++++++++++++++++
>  drivers/net/ice/ice_generic_flow.c     |   7 +
>  drivers/net/ice/ice_generic_flow.h     |   3 +
>  5 files changed, 288 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/release_21_11.rst
> b/doc/guides/rel_notes/release_21_11.rst
> index 9c13ceed1c..cc449a4340 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -167,6 +167,7 @@ New Features
> 
>  * **Updated Intel ice driver.**
> 
> +  * Added protocol agnostic flow offloading support in Flow Director.
>    * Added 1PPS out support by a devargs.
>    * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
>    * Added DEV_RX_OFFLOAD_TIMESTAMP support.
> diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h index
> 599e0028f7..441242ee89 100644
> --- a/drivers/net/ice/ice_ethdev.h
> +++ b/drivers/net/ice/ice_ethdev.h
> @@ -318,6 +318,11 @@ struct ice_fdir_filter_conf {
>  	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
>  	uint64_t input_set_i; /* only for tunnel inner fields */
>  	uint32_t mark_flag;
> +
> +	struct ice_parser_profile *prof;
> +	const u8 *pkt_buf;
> +	bool parser_ena;
> +	u8 pkt_len;
>  };
> 
>  #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
> @@ -487,6 +492,17 @@ struct ice_devargs {
>  	uint8_t pps_out_ena;
>  };
> 
> +/**
> + * Structure to store fdir fv entry.
> + */
> +struct ice_fdir_prof_info {
> +	struct LIST_ENTRY_TYPE l_entry;
> +
> +	struct ice_parser_profile prof;
> +	u16 ptg;
> +	u64 fdir_actived_cnt;
> +};
> +
>  /**
>   * Structure to store private data for each PF/VF instance.
>   */
> @@ -509,6 +525,7 @@ struct ice_adapter {
>  	struct rte_timecounter rx_tstamp_tc;
>  	struct rte_timecounter tx_tstamp_tc;
>  	bool ptp_ena;
> +	struct LIST_HEAD_TYPE fdir_prof_list;
>  #ifdef RTE_ARCH_X86
>  	bool rx_use_avx2;
>  	bool rx_use_avx512;
> diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
> index bd627e3aa8..bcf105d1bd 100644
> --- a/drivers/net/ice/ice_fdir_filter.c
> +++ b/drivers/net/ice/ice_fdir_filter.c
> @@ -107,6 +107,7 @@
>  	ICE_INSET_NAT_T_ESP_SPI)
> 
>  static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
> +	{pattern_raw,					ICE_INSET_NONE,
> 	ICE_INSET_NONE,			ICE_INSET_NONE},
>  	{pattern_ethertype,				ICE_FDIR_INSET_ETH,
> 	ICE_INSET_NONE,			ICE_INSET_NONE},
>  	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,
> 	ICE_INSET_NONE,			ICE_INSET_NONE},
>  	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,
> 	ICE_INSET_NONE,			ICE_INSET_NONE},
> @@ -1158,6 +1159,8 @@ ice_fdir_init(struct ice_adapter *ad)
>  	if (ret)
>  		return ret;
> 
> +	INIT_LIST_HEAD(&ad->fdir_prof_list);
> +
>  	parser = &ice_fdir_parser;
> 
>  	return ice_register_parser(parser, ad); @@ -1188,6 +1191,24 @@
> ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type)
>  		return 0;
>  }
> 
> +static int
> +ice_fdir_add_del_raw(struct ice_pf *pf,
> +		     struct ice_fdir_filter_conf *filter,
> +		     bool add)
> +{
> +	struct ice_hw *hw = ICE_PF_TO_HW(pf);
> +
> +	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
> +	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
> +
> +	struct ice_fltr_desc desc;
> +	memset(&desc, 0, sizeof(desc));
> +	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
> +	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
> +
> +	return ice_fdir_programming(pf, &desc); }
> +
>  static int
>  ice_fdir_add_del_filter(struct ice_pf *pf,
>  			struct ice_fdir_filter_conf *filter, @@ -1303,6 +1324,100 @@
> ice_fdir_create_filter(struct ice_adapter *ad,
>  	struct ice_fdir_fltr_pattern key;
>  	bool is_tun;
>  	int ret;
> +	int i;
> +
> +	if (filter->parser_ena) {
> +		struct ice_hw *hw = ICE_PF_TO_HW(pf);
> +
> +		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
> +		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
> +		u16 main_vsi = pf->main_vsi->idx;
> +		bool fv_found = false;
> +		u16 vsi_num;
> +
> +		struct ice_fdir_prof_info *pi;
> +		LIST_FOR_EACH_ENTRY(pi, &ad->fdir_prof_list,
> +				    ice_fdir_prof_info, l_entry) {
> +			if (pi->ptg != hw->blk[ICE_BLK_FD].xlt1.t[id])
> +				continue;
> +			if (!pi->fdir_actived_cnt) {
> +				vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi);
> +				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
> +							   vsi_num, id);

Looks like you delay the "profile remove" until next call ice_fdir_add_del_filter, 
Why not just do this at the exact moment that "fdir_actived_cnt = 0"?



> +				if (ret)
> +					return -rte_errno;
> +
> +				vsi_num = ice_get_hw_vsi_num(hw, main_vsi);
> +				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
> +							   vsi_num, id);
> +				if (ret)
> +					return -rte_errno;
> +
> +				LIST_DEL(&pi->l_entry);
> +				continue;
> +			}
> +			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
> +				if (pi->prof.fv[i].proto_id !=
> +				    filter->prof->fv[i].proto_id ||
> +				    pi->prof.fv[i].offset !=
> +				    filter->prof->fv[i].offset)
> +					break;
> +			if (i == ICE_MAX_FV_WORDS) {
> +				fv_found = true;
> +				pi->fdir_actived_cnt++;
> +				break;
> +			}
> +		}
> +
> +		if (!fv_found) {
> +			ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
> +						   filter->prof, ICE_BLK_FD);
> +			if (ret)
> +				return -rte_errno;
> +		}
> +
> +		ret = ice_fdir_add_del_raw(pf, filter, true);
> +		if (ret)
> +			return -rte_errno;
> +
> +		if (!fv_found) {
> +			pi = (struct ice_fdir_prof_info *)
> +				ice_malloc(hw, sizeof(*pi));
> +			if (!pi)
> +				return ICE_ERR_NO_MEMORY;
> +
> +			memset(&pi->prof, 0, sizeof(pi->prof));
> +
> +			for (i = 0; i < filter->prof->fv_num; i++) {
> +				pi->prof.fv[i].proto_id =
> +					filter->prof->fv[i].proto_id;
> +				pi->prof.fv[i].offset =
> +					filter->prof->fv[i].offset;
> +				pi->prof.fv[i].spec = filter->prof->fv[i].spec;
> +				pi->prof.fv[i].msk = filter->prof->fv[i].msk;
> +			}
> +			pi->ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
> +			pi->fdir_actived_cnt = 1;
> +
> +			LIST_ADD(&pi->l_entry, &ad->fdir_prof_list);
> +		}
> +
> +		if (filter->mark_flag == 1)
> +			ice_fdir_rx_parsing_enable(ad, 1);
> +
> +		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
> +		if (!entry)
> +			return -rte_errno;
> +
> +		rte_memcpy(entry, filter, sizeof(*filter));
> +
> +		filter->prof = NULL;
> +		filter->pkt_buf = NULL;
> +
> +		flow->rule = entry;
> +
> +		return 0;
> +	}
> 
>  	ice_fdir_extract_fltr_key(&key, filter);
>  	node = ice_fdir_entry_lookup(fdir_info, &key); @@ -1397,6 +1512,44
> @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
> 
>  	filter = (struct ice_fdir_filter_conf *)flow->rule;
> 
> +	if (filter->parser_ena) {
> +		struct ice_hw *hw = ICE_PF_TO_HW(pf);
> +
> +		ret = ice_fdir_add_del_raw(pf, filter, false);
> +		if (ret)
> +			return -rte_errno;
> +
> +		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
> +		int i;
> +		struct ice_fdir_prof_info *pi;
> +		LIST_FOR_EACH_ENTRY(pi, &ad->fdir_prof_list,
> +				    ice_fdir_prof_info, l_entry) {
> +			if (pi->ptg != hw->blk[ICE_BLK_FD].xlt1.t[id])
> +				continue;
> +			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
> +				if (pi->prof.fv[i].proto_id !=
> +				    filter->prof->fv[i].proto_id ||
> +				    pi->prof.fv[i].offset !=
> +				    filter->prof->fv[i].offset)
> +					break;
> +			if (i == ICE_MAX_FV_WORDS) {
> +				pi->fdir_actived_cnt--;

Here you can remove the profile.

> +				break;
> +			}
> +		}

can all above part be moved into ice_fdir_add_del_filter, this make the add /delete implementation symmetric .

> +
> +		if (filter->mark_flag == 1)
> +			ice_fdir_rx_parsing_enable(ad, 0);
> +
> +		flow->rule = NULL;
> +		filter->prof = NULL;
> +		filter->pkt_buf = NULL;
> +
> +		rte_free(filter);
> +
> +		return 0;
> +	}
> +
>  	is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type);
> 
>  	if (filter->counter) {
> @@ -1675,6 +1828,7 @@ ice_fdir_parse_pattern(__rte_unused struct
> ice_adapter *ad,
>  	enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
>  	enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END;
>  	enum ice_fdir_tunnel_type tunnel_type =
> ICE_FDIR_TUNNEL_TYPE_NONE;
> +	const struct rte_flow_item_raw *raw_spec, *raw_mask;
>  	const struct rte_flow_item_eth *eth_spec, *eth_mask;
>  	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
>  	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask; @@ -1702,6
> +1856,9 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
>  	struct ice_fdir_extra *p_ext_data;
>  	struct ice_fdir_v4 *p_v4 = NULL;
>  	struct ice_fdir_v6 *p_v6 = NULL;
> +	struct ice_parser_result rslt;
> +	struct ice_parser *psr;
> +	uint8_t item_num = 0;
> 
>  	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
>  		if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) @@ -1713,6
> +1870,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
>  		    item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
>  			is_outer = false;
>  		}
> +		item_num++;
>  	}
> 
>  	/* This loop parse flow pattern and distinguish Non-tunnel and tunnel
> @@ -1733,6 +1891,101 @@ ice_fdir_parse_pattern(__rte_unused struct
> ice_adapter *ad,
>  			    &input_set_i : &input_set_o;
> 
>  		switch (item_type) {
> +		case RTE_FLOW_ITEM_TYPE_RAW:
> +			raw_spec = item->spec;
> +			raw_mask = item->mask;
> +
> +			if (item_num != 1)
> +				break;
> +
> +			/* convert raw spec & mask from byte string to int */
> +			unsigned char *tmp_spec =
> +				(uint8_t *)(uintptr_t)raw_spec->pattern;
> +			unsigned char *tmp_mask =
> +				(uint8_t *)(uintptr_t)raw_mask->pattern;
> +			uint16_t udp_port = 0;
> +			uint16_t tmp_val = 0;
> +			uint8_t pkt_len = 0;
> +			uint8_t tmp = 0;
> +			int i, j;
> +
> +			pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern);
> +			if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
> +				pkt_len)
> +				return -rte_errno;
> +
> +			for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
> +				tmp = tmp_spec[i];
> +				if (tmp >= 'a' && tmp <= 'f')
> +					tmp_val = tmp - 'a' + 10;
> +				if (tmp >= 'A' && tmp <= 'F')
> +					tmp_val = tmp - 'A' + 10;
> +				if (tmp >= '0' && tmp <= '9')
> +					tmp_val = tmp - '0';
> +
> +				tmp_val *= 16;
> +				tmp = tmp_spec[i + 1];
> +				if (tmp >= 'a' && tmp <= 'f')
> +					tmp_spec[j] = tmp_val + tmp - 'a' + 10;
> +				if (tmp >= 'A' && tmp <= 'F')
> +					tmp_spec[j] = tmp_val + tmp - 'A' + 10;
> +				if (tmp >= '0' && tmp <= '9')
> +					tmp_spec[j] = tmp_val + tmp - '0';
> +
> +				tmp = tmp_mask[i];
> +				if (tmp >= 'a' && tmp <= 'f')
> +					tmp_val = tmp - 'a' + 10;
> +				if (tmp >= 'A' && tmp <= 'F')
> +					tmp_val = tmp - 'A' + 10;
> +				if (tmp >= '0' && tmp <= '9')
> +					tmp_val = tmp - '0';
> +
> +				tmp_val *= 16;
> +				tmp = tmp_mask[i + 1];
> +				if (tmp >= 'a' && tmp <= 'f')
> +					tmp_mask[j] = tmp_val + tmp - 'a' + 10;
> +				if (tmp >= 'A' && tmp <= 'F')
> +					tmp_mask[j] = tmp_val + tmp - 'A' + 10;
> +				if (tmp >= '0' && tmp <= '9')
> +					tmp_mask[j] = tmp_val + tmp - '0';
> +			}
> +
> +			pkt_len /= 2;
> +
> +			if (ice_parser_create(&ad->hw, &psr))
> +				return -rte_errno;
> +			if (ice_get_open_tunnel_port(&ad->hw, TNL_VXLAN,
> +						     &udp_port))
> +				ice_parser_vxlan_tunnel_set(psr, udp_port,
> +							    true);
> +			if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt))
> +				return -rte_errno;
> +			ice_parser_destroy(psr);
> +
> +			if (!tmp_mask)
> +				return -rte_errno;
> +
> +			filter->prof = (struct ice_parser_profile *)
> +				ice_malloc(&ad->hw, sizeof(*filter->prof));
> +			if (!filter->prof)
> +				return -ENOMEM;
> +
> +			if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask,
> +				pkt_len, ICE_BLK_FD, true, filter->prof))
> +				return -rte_errno;
> +
> +			u8 *pkt_buf = (u8 *)ice_malloc(&ad->hw, pkt_len + 1);
> +			if (!pkt_buf)
> +				return -ENOMEM;
> +			rte_memcpy(pkt_buf, tmp_spec, pkt_len);
> +			filter->pkt_buf = pkt_buf;
> +
> +			filter->pkt_len = pkt_len;
> +
> +			filter->parser_ena = true;
> +
> +			break;
> +
>  		case RTE_FLOW_ITEM_TYPE_ETH:
>  			flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
>  			eth_spec = item->spec;
> @@ -2198,6 +2451,7 @@ ice_fdir_parse(struct ice_adapter *ad,
>  	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
>  	struct ice_pattern_match_item *item = NULL;
>  	uint64_t input_set;
> +	bool raw = false;
>  	int ret;
> 
>  	memset(filter, 0, sizeof(*filter));
> @@ -2213,7 +2467,13 @@ ice_fdir_parse(struct ice_adapter *ad,
>  	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
>  	if (ret)
>  		goto error;
> +
> +	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
> +		raw = true;
> +
>  	input_set = filter->input_set_o | filter->input_set_i;
> +	input_set = raw ? ~input_set : input_set;
> +
>  	if (!input_set || filter->input_set_o &
>  	    ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) ||
>  	    filter->input_set_i & ~item->input_set_mask_i) { diff --git
> a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
> index 02f854666a..d3391c86c0 100644
> --- a/drivers/net/ice/ice_generic_flow.c
> +++ b/drivers/net/ice/ice_generic_flow.c
> @@ -65,6 +65,12 @@ enum rte_flow_item_type pattern_empty[] = {
>  	RTE_FLOW_ITEM_TYPE_END,
>  };
> 
> +/* raw */
> +enum rte_flow_item_type pattern_raw[] = {
> +	RTE_FLOW_ITEM_TYPE_RAW,
> +	RTE_FLOW_ITEM_TYPE_END,
> +};
> +
>  /* L2 */
>  enum rte_flow_item_type pattern_ethertype[] = {
>  	RTE_FLOW_ITEM_TYPE_ETH,
> @@ -2081,6 +2087,7 @@ struct ice_ptype_match {  };
> 
>  static struct ice_ptype_match ice_ptype_map[] = {
> +	{pattern_raw,					ICE_PTYPE_IPV4_PAY},
>  	{pattern_eth_ipv4,				ICE_PTYPE_IPV4_PAY},
>  	{pattern_eth_ipv4_udp,				ICE_PTYPE_IPV4_UDP_PAY},
>  	{pattern_eth_ipv4_tcp,				ICE_PTYPE_IPV4_TCP_PAY},
> diff --git a/drivers/net/ice/ice_generic_flow.h
> b/drivers/net/ice/ice_generic_flow.h
> index 8845a3e156..1b030c0466 100644
> --- a/drivers/net/ice/ice_generic_flow.h
> +++ b/drivers/net/ice/ice_generic_flow.h
> @@ -124,6 +124,9 @@
>  /* empty pattern */
>  extern enum rte_flow_item_type pattern_empty[];
> 
> +/* raw pattern */
> +extern enum rte_flow_item_type pattern_raw[];
> +
>  /* L2 */
>  extern enum rte_flow_item_type pattern_ethertype[];  extern enum
> rte_flow_item_type pattern_ethertype_vlan[];
> --
> 2.25.1


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

* Re: [dpdk-dev] [PATCH v7 1/4] net/ice/base: add method to disable FDIR SWAP option
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
@ 2021-10-28 11:26                           ` Zhang, Qi Z
  2021-10-28 15:09                           ` Ferruh Yigit
  1 sibling, 0 replies; 68+ messages in thread
From: Zhang, Qi Z @ 2021-10-28 11:26 UTC (permalink / raw)
  To: Guo, Junfeng, Wu, Jingjing, Xing, Beilei; +Cc: dev, Yigit, Ferruh, Xu, Ting



> -----Original Message-----
> From: Guo, Junfeng <junfeng.guo@intel.com>
> Sent: Thursday, October 28, 2021 5:14 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Xu, Ting
> <ting.xu@intel.com>; Guo, Junfeng <junfeng.guo@intel.com>
> Subject: [PATCH v7 1/4] net/ice/base: add method to disable FDIR SWAP
> option
> 
> The SWAP Flag in the FDIR Programming Descriptor doesn't work, thus add a
> method to disable the FDIR SWAP option by setting the swap and inset register
> set with certain values. The boolean fd_swap is used to enable/disable the
> SWAP option.
> 
> Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>

Acked-by: Qi Zhang <qi.z.zhang@intel.com>

Applied to dpdk-next-net-intel.

Thanks.
Qi


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

* Re: [dpdk-dev] [PATCH v7 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
@ 2021-10-28 11:28                           ` Zhang, Qi Z
  2021-10-28 15:13                           ` Ferruh Yigit
  1 sibling, 0 replies; 68+ messages in thread
From: Zhang, Qi Z @ 2021-10-28 11:28 UTC (permalink / raw)
  To: Guo, Junfeng, Wu, Jingjing, Xing, Beilei; +Cc: dev, Yigit, Ferruh, Xu, Ting



> -----Original Message-----
> From: Guo, Junfeng <junfeng.guo@intel.com>
> Sent: Thursday, October 28, 2021 5:14 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Xu, Ting
> <ting.xu@intel.com>; Guo, Junfeng <junfeng.guo@intel.com>
> Subject: [PATCH v7 2/4] net/ice/base: add function to set HW profile for raw
> flow
> 
> Based on the parser library, we can directly set HW profile and associate the
> main/ctrl vsi.
> 
> Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>

Acked-by: Qi Zhang <qi.z.zhang@intel.com>

As this is the last base code patch for DPDK 21.11, update FreeBSD release version in driver/net/ice/base/README during merge.

Applied to dpdk-next-net-intel.

Thanks
Qi

> ---
>  drivers/net/ice/base/ice_flex_pipe.c | 49 ++++++++++++++++
> drivers/net/ice/base/ice_flex_pipe.h |  3 +
>  drivers/net/ice/base/ice_flow.c      | 84 ++++++++++++++++++++++++++++
>  drivers/net/ice/base/ice_flow.h      |  4 ++
>  4 files changed, 140 insertions(+)
> 
> diff --git a/drivers/net/ice/base/ice_flex_pipe.c
> b/drivers/net/ice/base/ice_flex_pipe.c
> index 06a233990f..395787806b 100644
> --- a/drivers/net/ice/base/ice_flex_pipe.c
> +++ b/drivers/net/ice/base/ice_flex_pipe.c
> @@ -6365,3 +6365,52 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum
> ice_block blk, u16 vsi, u64 hdl)
> 
>  	return status;
>  }
> +
> +/**
> + * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow
> +entry
> + * @hw: pointer to the HW struct
> + * @blk: HW block
> + * @dest_vsi_handle: dest VSI handle
> + * @fdir_vsi_handle: fdir programming VSI handle
> + * @id: profile id (handle)
> + *
> + * Calling this function will update the hardware tables to enable the
> + * profile indicated by the ID parameter for the VSIs specified in the
> +VSI
> + * array. Once successfully called, the flow will be enabled.
> + */
> +enum ice_status
> +ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
> +		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id) {
> +	enum ice_status status = ICE_SUCCESS;
> +	u16 vsi_num;
> +
> +	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
> +	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
> +	if (status) {
> +		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for main VSI
> flow entry, %d\n",
> +			  status);
> +		goto err_add_prof;
> +	}
> +
> +	if (blk != ICE_BLK_FD)
> +		return status;
> +
> +	vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi_handle);
> +	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
> +	if (status) {
> +		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for ctrl VSI
> flow entry, %d\n",
> +			  status);
> +		goto err_add_entry;
> +	}
> +
> +	return status;
> +
> +err_add_entry:
> +	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
> +	ice_rem_prof_id_flow(hw, blk, vsi_num, id);
> +err_add_prof:
> +	ice_flow_rem_prof(hw, blk, id);
> +
> +	return status;
> +}
> diff --git a/drivers/net/ice/base/ice_flex_pipe.h
> b/drivers/net/ice/base/ice_flex_pipe.h
> index dd332312dd..23ba45564a 100644
> --- a/drivers/net/ice/base/ice_flex_pipe.h
> +++ b/drivers/net/ice/base/ice_flex_pipe.h
> @@ -76,6 +76,9 @@ enum ice_status
>  ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64
> hdl);  enum ice_status  ice_rem_prof_id_flow(struct ice_hw *hw, enum
> ice_block blk, u16 vsi, u64 hdl);
> +enum ice_status
> +ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
> +		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id);
>  enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);  enum
> ice_status  ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
> diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
> index 77b6b130c1..f699dbbc74 100644
> --- a/drivers/net/ice/base/ice_flow.c
> +++ b/drivers/net/ice/base/ice_flow.c
> @@ -2524,6 +2524,90 @@ ice_flow_disassoc_prof(struct ice_hw *hw, enum
> ice_block blk,
>  	return status;
>  }
> 
> +#define FLAG_GTP_EH_PDU_LINK	BIT_ULL(13)
> +#define FLAG_GTP_EH_PDU		BIT_ULL(14)
> +
> +#define FLAG_GTPU_MSK	\
> +	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
> +#define FLAG_GTPU_DW	\
> +	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
> +#define FLAG_GTPU_UP	\
> +	(FLAG_GTP_EH_PDU)
> +/**
> + * ice_flow_set_hw_prof - Set HW flow profile based on the parsed
> +profile info
> + * @hw: pointer to the HW struct
> + * @dest_vsi_handle: dest VSI handle
> + * @fdir_vsi_handle: fdir programming VSI handle
> + * @prof: stores parsed profile info from raw flow
> + * @blk: classification stage
> + */
> +enum ice_status
> +ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
> +		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
> +		     enum ice_block blk)
> +{
> +	int id = ice_find_first_bit(prof->ptypes, UINT16_MAX);
> +	struct ice_flow_prof_params *params;
> +	u8 fv_words = hw->blk[blk].es.fvw;
> +	enum ice_status status;
> +	u16 vsi_num;
> +	int i, idx;
> +
> +	params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
> +	if (!params)
> +		return ICE_ERR_NO_MEMORY;
> +
> +	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
> +		params->es[i].prot_id = ICE_PROT_INVALID;
> +		params->es[i].off = ICE_FV_OFFSET_INVAL;
> +	}
> +
> +	for (i = 0; i < prof->fv_num; i++) {
> +		if (hw->blk[blk].es.reverse)
> +			idx = fv_words - i - 1;
> +		else
> +			idx = i;
> +		params->es[idx].prot_id = prof->fv[i].proto_id;
> +		params->es[idx].off = prof->fv[i].offset;
> +		params->mask[idx] = CPU_TO_BE16(prof->fv[i].msk);
> +	}
> +
> +	switch (prof->flags) {
> +	case FLAG_GTPU_DW:
> +		params->attr = ice_attr_gtpu_down;
> +		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
> +		break;
> +	case FLAG_GTPU_UP:
> +		params->attr = ice_attr_gtpu_up;
> +		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
> +		break;
> +	default:
> +		if (prof->flags_msk & FLAG_GTPU_MSK) {
> +			params->attr = ice_attr_gtpu_session;
> +			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
> +		}
> +		break;
> +	}
> +
> +	status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
> +			      params->attr, params->attr_cnt,
> +			      params->es, params->mask, false);
> +	if (status)
> +		goto free_params;
> +
> +	status = ice_flow_assoc_hw_prof(hw, blk, dest_vsi_handle,
> +					fdir_vsi_handle, id);
> +	if (status)
> +		goto free_params;
> +
> +	return ICE_SUCCESS;
> +
> +free_params:
> +	ice_free(hw, params);
> +
> +	return status;
> +}
> +
>  /**
>   * ice_flow_add_prof - Add a flow profile for packet segments and matched
> fields
>   * @hw: pointer to the HW struct
> diff --git a/drivers/net/ice/base/ice_flow.h b/drivers/net/ice/base/ice_flow.h
> index 371d960066..dea7b3c0e8 100644
> --- a/drivers/net/ice/base/ice_flow.h
> +++ b/drivers/net/ice/base/ice_flow.h
> @@ -548,6 +548,10 @@ enum ice_status
>  ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16
> vsi_handle,
>  			u16 vsig);
>  enum ice_status
> +ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
> +		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
> +		     enum ice_block blk);
> +enum ice_status
>  ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
>  		     u8 *hw_prof);
> 
> --
> 2.25.1


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

* Re: [dpdk-dev] [PATCH v7 3/4] app/testpmd: update Max RAW pattern size to 512
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-10-28 11:46                           ` Zhang, Qi Z
  0 siblings, 0 replies; 68+ messages in thread
From: Zhang, Qi Z @ 2021-10-28 11:46 UTC (permalink / raw)
  To: Guo, Junfeng, Wu, Jingjing, Xing, Beilei; +Cc: dev, Yigit, Ferruh, Xu, Ting



> -----Original Message-----
> From: Guo, Junfeng <junfeng.guo@intel.com>
> Sent: Thursday, October 28, 2021 5:14 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Xu, Ting
> <ting.xu@intel.com>; Guo, Junfeng <junfeng.guo@intel.com>
> Subject: [PATCH v7 3/4] app/testpmd: update Max RAW pattern size to 512
> 
> Update max size for pattern in struct rte_flow_item_raw to enable protocol
> agnostic flow offloading.
> 
> Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>

Reviewed-by: Qi Zhang <qi.z.zhang@intel.com>


> ---
>  app/test-pmd/cmdline_flow.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index
> d8218771fb..ef24710bd8 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -495,7 +495,7 @@ enum index {
>  };
> 
>  /** Maximum size for pattern in struct rte_flow_item_raw. */ -#define
> ITEM_RAW_PATTERN_SIZE 40
> +#define ITEM_RAW_PATTERN_SIZE 512
> 
>  /** Maximum size for GENEVE option data pattern in bytes. */  #define
> ITEM_GENEVE_OPT_DATA_SIZE 124
> --
> 2.25.1


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

* Re: [dpdk-dev] [PATCH v7 1/4] net/ice/base: add method to disable FDIR SWAP option
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
  2021-10-28 11:26                           ` Zhang, Qi Z
@ 2021-10-28 15:09                           ` Ferruh Yigit
  1 sibling, 0 replies; 68+ messages in thread
From: Ferruh Yigit @ 2021-10-28 15:09 UTC (permalink / raw)
  To: Junfeng Guo, qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ting.xu

On 10/28/2021 10:13 AM, Junfeng Guo wrote:
> The SWAP Flag in the FDIR Programming Descriptor doesn't work, thus
> add a method to disable the FDIR SWAP option by setting the swap and
> inset register set with certain values. 

Can you please briefly describe why 'SWAP Flag in the FDIR Programming Descriptor'
is not working?
Is it HW limitation, or specific FW version issue etc...

> The boolean fd_swap is used to enable/disable the SWAP option.
> 

In the code, 'fd_swap' set as 'true', so I assume swap is not disabled
by default, when the 'ice_disable_fd_swap()' is called?

> Signed-off-by: Junfeng Guo<junfeng.guo@intel.com>


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

* Re: [dpdk-dev] [PATCH v7 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
  2021-10-28 11:28                           ` Zhang, Qi Z
@ 2021-10-28 15:13                           ` Ferruh Yigit
  1 sibling, 0 replies; 68+ messages in thread
From: Ferruh Yigit @ 2021-10-28 15:13 UTC (permalink / raw)
  To: Junfeng Guo, qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ting.xu

On 10/28/2021 10:13 AM, Junfeng Guo wrote:
> Based on the parser library, we can directly set HW profile and
> associate the main/ctrl vsi.

This shared code function is not used by driver, will it be enabled
later or is it for shared code sync, can you please clarify in the
commit log.

> 
> Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
> ---
>   drivers/net/ice/base/ice_flex_pipe.c | 49 ++++++++++++++++
>   drivers/net/ice/base/ice_flex_pipe.h |  3 +
>   drivers/net/ice/base/ice_flow.c      | 84 ++++++++++++++++++++++++++++
>   drivers/net/ice/base/ice_flow.h      |  4 ++
>   4 files changed, 140 insertions(+)

The commit in the next-net-intel repo has README file too to update the
version, I think better to have it in the next version of the set to
keep record of the change.

Thanks,
ferruh


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

* [dpdk-dev] [PATCH v8 0/4] enable protocol agnostic flow offloading in FDIR
  2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-10-28 11:10                           ` Zhang, Qi Z
@ 2021-11-01  8:36                           ` Junfeng Guo
  2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
                                               ` (3 more replies)
  1 sibling, 4 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-01  8:36 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch set based on the Parser Library using existing rte_flow raw API.

[PATCH v8 1/4] net/ice/base: add method to disable FDIR SWAP option.
[PATCH v8 2/4] net/ice/base: add function to set HW profile for raw flow.
[PATCH v8 3/4] app/testpmd: update Max RAW pattern size to 512.
[PATCH v8 4/4] net/ice: enable protocol agnostic flow offloading in FDIR.

Junfeng Guo (4):
  net/ice/base: add method to disable FDIR SWAP option
  net/ice/base: add function to set HW profile for raw flow
  app/testpmd: update Max RAW pattern size to 512
  net/ice: enable protocol agnostic flow offloading in FDIR

* v8:
Replaced profile info list with a table.

* v7:
Fixed LIST_FOR_EACH_ENTRY logic.

* v6:
Removed redundant code.

* v5:
Optimized some code logic.

* v4:
Added list to check inputset conflict.

* v3:
Added necessary base code for raw flow in FDIR.

* v2:
Enabled vxlan port add for raw flow and updated commit message

 app/test-pmd/cmdline_flow.c            |   2 +-
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/base/README            |   2 +-
 drivers/net/ice/base/ice_flex_pipe.c   |  93 +++++++++-
 drivers/net/ice/base/ice_flex_pipe.h   |   6 +-
 drivers/net/ice/base/ice_flow.c        |  86 ++++++++-
 drivers/net/ice/base/ice_flow.h        |   4 +
 drivers/net/ice/ice_ethdev.h           |  14 ++
 drivers/net/ice/ice_fdir_filter.c      | 235 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 11 files changed, 447 insertions(+), 6 deletions(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH v8 1/4] net/ice/base: add method to disable FDIR SWAP option
  2021-11-01  8:36                           ` [dpdk-dev] [PATCH v8 0/4] " Junfeng Guo
@ 2021-11-01  8:36                             ` Junfeng Guo
  2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
                                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-01  8:36 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

In this patch, we introduced a new parameter to enable/disable the
FDIR SWAP option by setting the swap and inset register set with
certain values.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 44 ++++++++++++++++++++++++++--
 drivers/net/ice/base/ice_flex_pipe.h |  3 +-
 drivers/net/ice/base/ice_flow.c      |  2 +-
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index f35d59f4f5..06a233990f 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -4952,6 +4952,43 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 	return ICE_SUCCESS;
 }
 
+/**
+ * ice_disable_fd_swap - set register appropriately to disable FD swap
+ * @hw: pointer to the HW struct
+ * @prof_id: profile ID
+ */
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id)
+{
+	u8 swap_val = ICE_SWAP_VALID;
+	u8 i;
+	/* Since the SWAP Flag in the Programming Desc doesn't work,
+	 * here add method to disable the SWAP Option via setting
+	 * certain SWAP and INSET register set.
+	 */
+	for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw / 4; i++) {
+		u32 raw_swap = 0;
+		u32 raw_in = 0;
+		u8 j;
+
+		for (j = 0; j < 4; j++) {
+			raw_swap |= (swap_val++) << (j * BITS_PER_BYTE);
+			raw_in |= ICE_INSET_DFLT << (j * BITS_PER_BYTE);
+		}
+
+		/* write the FDIR swap register set */
+		wr32(hw, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		/* write the FDIR inset register set */
+		wr32(hw, GLQF_FDINSET(prof_id, i), raw_in);
+
+		ice_debug(hw, ICE_DBG_INIT, "inset wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDINSET(prof_id, i), raw_in);
+	}
+}
+
 /**
  * ice_add_prof - add profile
  * @hw: pointer to the HW struct
@@ -4962,6 +4999,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
  * @attr_cnt: number of elements in attrib array
  * @es: extraction sequence (length of array is determined by the block)
  * @masks: mask for extraction sequence
+ * @fd_swap: enable/disable FDIR paired src/dst fields swap option
  *
  * This function registers a profile, which matches a set of PTYPES with a
  * particular extraction sequence. While the hardware profile is allocated
@@ -4971,7 +5009,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks)
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap)
 {
 	u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE);
 	ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT);
@@ -4991,7 +5029,7 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 		status = ice_alloc_prof_id(hw, blk, &prof_id);
 		if (status)
 			goto err_ice_add_prof;
-		if (blk == ICE_BLK_FD) {
+		if (blk == ICE_BLK_FD && fd_swap) {
 			/* For Flow Director block, the extraction sequence may
 			 * need to be altered in the case where there are paired
 			 * fields that have no match. This is necessary because
@@ -5002,6 +5040,8 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 			status = ice_update_fd_swap(hw, prof_id, es);
 			if (status)
 				goto err_ice_add_prof;
+		} else if (blk == ICE_BLK_FD) {
+			ice_disable_fd_swap(hw, prof_id);
 		}
 		status = ice_update_prof_masking(hw, blk, prof_id, masks);
 		if (status)
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index 9733c4b214..dd332312dd 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -61,10 +61,11 @@ bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype);
 /* XLT2/VSI group functions */
 enum ice_status
 ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig);
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id);
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks);
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap);
 void ice_init_all_prof_masks(struct ice_hw *hw);
 void ice_shutdown_all_prof_masks(struct ice_hw *hw);
 struct ice_prof_map *
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 96d54b494d..77b6b130c1 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2244,7 +2244,7 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
 	/* Add a HW profile for this flow profile */
 	status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
 			      params->attr, params->attr_cnt, params->es,
-			      params->mask);
+			      params->mask, true);
 	if (status) {
 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
 		goto out;
-- 
2.25.1


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

* [dpdk-dev] [PATCH v8 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-11-01  8:36                           ` [dpdk-dev] [PATCH v8 0/4] " Junfeng Guo
  2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
@ 2021-11-01  8:36                             ` Junfeng Guo
  2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
  2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  3 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-01  8:36 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=a, Size: 6878 bytes --]

Based on the parser library, we can directly set HW profile and
associate the main/ctrl vsi.

This patch set also updated the release date in README.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/README          |  2 +-
 drivers/net/ice/base/ice_flex_pipe.c | 49 ++++++++++++++++
 drivers/net/ice/base/ice_flex_pipe.h |  3 +
 drivers/net/ice/base/ice_flow.c      | 84 ++++++++++++++++++++++++++++
 drivers/net/ice/base/ice_flow.h      |  4 ++
 5 files changed, 141 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ice/base/README b/drivers/net/ice/base/README
index 87a1cebfac..0b23fc4795 100644
--- a/drivers/net/ice/base/README
+++ b/drivers/net/ice/base/README
@@ -6,7 +6,7 @@ Intel® ICE driver
 ==================
 
 This directory contains source code of FreeBSD ice driver of version
-2021.04.29 released by the team which develops
+2021.10.28 released by the team which develops
 basic drivers for any ice NIC. The directory of base/ contains the
 original source package.
 This driver is valid for the product(s) listed below
diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index 06a233990f..395787806b 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -6365,3 +6365,52 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
 
 	return status;
 }
+
+/**
+ * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow entry
+ * @hw: pointer to the HW struct
+ * @blk: HW block
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @id: profile id (handle)
+ *
+ * Calling this function will update the hardware tables to enable the
+ * profile indicated by the ID parameter for the VSIs specified in the VSI
+ * array. Once successfully called, the flow will be enabled.
+ */
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id)
+{
+	enum ice_status status = ICE_SUCCESS;
+	u16 vsi_num;
+
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for main VSI flow entry, %d\n",
+			  status);
+		goto err_add_prof;
+	}
+
+	if (blk != ICE_BLK_FD)
+		return status;
+
+	vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for ctrl VSI flow entry, %d\n",
+			  status);
+		goto err_add_entry;
+	}
+
+	return status;
+
+err_add_entry:
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+err_add_prof:
+	ice_flow_rem_prof(hw, blk, id);
+
+	return status;
+}
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index dd332312dd..23ba45564a 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -76,6 +76,9 @@ enum ice_status
 ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 enum ice_status
 ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id);
 enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
 enum ice_status
 ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 77b6b130c1..f699dbbc74 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2524,6 +2524,90 @@ ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
 	return status;
 }
 
+#define FLAG_GTP_EH_PDU_LINK	BIT_ULL(13)
+#define FLAG_GTP_EH_PDU		BIT_ULL(14)
+
+#define FLAG_GTPU_MSK	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_DW	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_UP	\
+	(FLAG_GTP_EH_PDU)
+/**
+ * ice_flow_set_hw_prof - Set HW flow profile based on the parsed profile info
+ * @hw: pointer to the HW struct
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @prof: stores parsed profile info from raw flow
+ * @blk: classification stage
+ */
+enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk)
+{
+	int id = ice_find_first_bit(prof->ptypes, UINT16_MAX);
+	struct ice_flow_prof_params *params;
+	u8 fv_words = hw->blk[blk].es.fvw;
+	enum ice_status status;
+	u16 vsi_num;
+	int i, idx;
+
+	params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
+	if (!params)
+		return ICE_ERR_NO_MEMORY;
+
+	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
+		params->es[i].prot_id = ICE_PROT_INVALID;
+		params->es[i].off = ICE_FV_OFFSET_INVAL;
+	}
+
+	for (i = 0; i < prof->fv_num; i++) {
+		if (hw->blk[blk].es.reverse)
+			idx = fv_words - i - 1;
+		else
+			idx = i;
+		params->es[idx].prot_id = prof->fv[i].proto_id;
+		params->es[idx].off = prof->fv[i].offset;
+		params->mask[idx] = CPU_TO_BE16(prof->fv[i].msk);
+	}
+
+	switch (prof->flags) {
+	case FLAG_GTPU_DW:
+		params->attr = ice_attr_gtpu_down;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
+		break;
+	case FLAG_GTPU_UP:
+		params->attr = ice_attr_gtpu_up;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
+		break;
+	default:
+		if (prof->flags_msk & FLAG_GTPU_MSK) {
+			params->attr = ice_attr_gtpu_session;
+			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
+		}
+		break;
+	}
+
+	status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
+			      params->attr, params->attr_cnt,
+			      params->es, params->mask, false);
+	if (status)
+		goto free_params;
+
+	status = ice_flow_assoc_hw_prof(hw, blk, dest_vsi_handle,
+					fdir_vsi_handle, id);
+	if (status)
+		goto free_params;
+
+	return ICE_SUCCESS;
+
+free_params:
+	ice_free(hw, params);
+
+	return status;
+}
+
 /**
  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
  * @hw: pointer to the HW struct
diff --git a/drivers/net/ice/base/ice_flow.h b/drivers/net/ice/base/ice_flow.h
index 371d960066..dea7b3c0e8 100644
--- a/drivers/net/ice/base/ice_flow.h
+++ b/drivers/net/ice/base/ice_flow.h
@@ -548,6 +548,10 @@ enum ice_status
 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
 			u16 vsig);
 enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk);
+enum ice_status
 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
 		     u8 *hw_prof);
 
-- 
2.25.1


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

* [dpdk-dev] [PATCH v8 3/4] app/testpmd: update Max RAW pattern size to 512
  2021-11-01  8:36                           ` [dpdk-dev] [PATCH v8 0/4] " Junfeng Guo
  2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
  2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
@ 2021-11-01  8:36                             ` Junfeng Guo
  2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  3 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-01  8:36 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Update max size for pattern in struct rte_flow_item_raw to enable
protocol agnostic flow offloading.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 app/test-pmd/cmdline_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 24b224e632..0a2205804e 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -495,7 +495,7 @@ enum index {
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
-#define ITEM_RAW_PATTERN_SIZE 40
+#define ITEM_RAW_PATTERN_SIZE 512
 
 /** Maximum size for GENEVE option data pattern in bytes. */
 #define ITEM_GENEVE_OPT_DATA_SIZE 124
-- 
2.25.1


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

* [dpdk-dev] [PATCH v8 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-11-01  8:36                           ` [dpdk-dev] [PATCH v8 0/4] " Junfeng Guo
                                               ` (2 preceding siblings ...)
  2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-11-01  8:36                             ` Junfeng Guo
  2021-11-01 23:56                               ` Zhang, Qi Z
  2021-11-02  5:39                               ` [dpdk-dev] [PATCH v9 0/4] " Junfeng Guo
  3 siblings, 2 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-01  8:36 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch based on the Parser Library, using existing rte_flow raw API.

Note that the raw flow requires:
1. byte string of raw target packet bits.
2. byte string of mask of target packet.

Here is an example:
FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:

flow create 0 ingress pattern raw \
pattern spec \
00000000000000000000000008004500001400004000401000000000000001020304 \
pattern mask \
000000000000000000000000000000000000000000000000000000000000ffffffff \
/ end actions queue index 3 / mark id 3 / end

Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto)
is optional in our cases. To avoid redundancy, we just omit the mask
of 0x0800 (with 0xFFFF) in the mask byte string example. The prefix
'0x' for the spec and mask byte (hex) strings are also omitted here.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/ice_ethdev.h           |  14 ++
 drivers/net/ice/ice_fdir_filter.c      | 235 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 5 files changed, 260 insertions(+)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 98d50a160b..36fdee0a98 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -167,6 +167,7 @@ New Features
 
 * **Updated Intel ice driver.**
 
+  * Added protocol agnostic flow offloading support in Flow Director.
   * Added 1PPS out support by a devargs.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
   * Added DEV_RX_OFFLOAD_TIMESTAMP support.
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 0e42c4c063..bbfeb0cc23 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -318,6 +318,11 @@ struct ice_fdir_filter_conf {
 	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
 	uint64_t input_set_i; /* only for tunnel inner fields */
 	uint32_t mark_flag;
+
+	struct ice_parser_profile *prof;
+	const u8 *pkt_buf;
+	bool parser_ena;
+	u8 pkt_len;
 };
 
 #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
@@ -487,6 +492,14 @@ struct ice_devargs {
 	uint8_t pps_out_ena;
 };
 
+/**
+ * Structure to store fdir fv entry.
+ */
+struct ice_fdir_prof_info {
+	struct ice_parser_profile prof;
+	u64 fdir_actived_cnt;
+};
+
 /**
  * Structure to store private data for each PF/VF instance.
  */
@@ -510,6 +523,7 @@ struct ice_adapter {
 	struct rte_timecounter tx_tstamp_tc;
 	bool ptp_ena;
 	uint64_t time_hw;
+	struct ice_fdir_prof_info fdir_prof_info[ICE_MAX_PTGS];
 #ifdef RTE_ARCH_X86
 	bool rx_use_avx2;
 	bool rx_use_avx512;
diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
index bd627e3aa8..888f0dea6d 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -107,6 +107,7 @@
 	ICE_INSET_NAT_T_ESP_SPI)
 
 static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+	{pattern_raw,					ICE_INSET_NONE,			ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_ethertype,				ICE_FDIR_INSET_ETH,		ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,	ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,	ICE_INSET_NONE,			ICE_INSET_NONE},
@@ -1188,6 +1189,24 @@ ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type)
 		return 0;
 }
 
+static int
+ice_fdir_add_del_raw(struct ice_pf *pf,
+		     struct ice_fdir_filter_conf *filter,
+		     bool add)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
+	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
+
+	struct ice_fltr_desc desc;
+	memset(&desc, 0, sizeof(desc));
+	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
+	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
+
+	return ice_fdir_programming(pf, &desc);
+}
+
 static int
 ice_fdir_add_del_filter(struct ice_pf *pf,
 			struct ice_fdir_filter_conf *filter,
@@ -1303,6 +1322,72 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 	struct ice_fdir_fltr_pattern key;
 	bool is_tun;
 	int ret;
+	int i;
+
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+		bool fv_found = false;
+
+		struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg];
+		if (pi->fdir_actived_cnt != 0) {
+			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
+				if (pi->prof.fv[i].proto_id !=
+				    filter->prof->fv[i].proto_id ||
+				    pi->prof.fv[i].offset !=
+				    filter->prof->fv[i].offset ||
+				    pi->prof.fv[i].msk !=
+				    filter->prof->fv[i].msk)
+					break;
+			if (i == ICE_MAX_FV_WORDS) {
+				fv_found = true;
+				pi->fdir_actived_cnt++;
+			}
+		}
+
+		if (!fv_found) {
+			ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
+						   filter->prof, ICE_BLK_FD);
+			if (ret)
+				return -rte_errno;
+		}
+
+		ret = ice_fdir_add_del_raw(pf, filter, true);
+		if (ret)
+			return -rte_errno;
+
+		if (!fv_found) {
+			for (i = 0; i < filter->prof->fv_num; i++) {
+				pi->prof.fv[i].proto_id =
+					filter->prof->fv[i].proto_id;
+				pi->prof.fv[i].offset =
+					filter->prof->fv[i].offset;
+				pi->prof.fv[i].spec = filter->prof->fv[i].spec;
+				pi->prof.fv[i].msk = filter->prof->fv[i].msk;
+			}
+			pi->fdir_actived_cnt = 1;
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 1);
+
+		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
+		if (!entry)
+			return -rte_errno;
+
+		rte_memcpy(entry, filter, sizeof(*filter));
+
+		filter->prof = NULL;
+		filter->pkt_buf = NULL;
+
+		flow->rule = entry;
+
+		return 0;
+	}
 
 	ice_fdir_extract_fltr_key(&key, filter);
 	node = ice_fdir_entry_lookup(fdir_info, &key);
@@ -1397,6 +1482,49 @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
 
 	filter = (struct ice_fdir_filter_conf *)flow->rule;
 
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+		u16 vsi_num;
+
+		ret = ice_fdir_add_del_raw(pf, filter, false);
+		if (ret)
+			return -rte_errno;
+
+		struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg];
+		if (pi->fdir_actived_cnt != 0) {
+			pi->fdir_actived_cnt--;
+			if (!pi->fdir_actived_cnt) {
+				vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi);
+				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
+							   vsi_num, id);
+				if (ret)
+					return -rte_errno;
+
+				vsi_num = ice_get_hw_vsi_num(hw, main_vsi);
+				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
+							   vsi_num, id);
+				if (ret)
+					return -rte_errno;
+			}
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 0);
+
+		flow->rule = NULL;
+		filter->prof = NULL;
+		filter->pkt_buf = NULL;
+
+		rte_free(filter);
+
+		return 0;
+	}
+
 	is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type);
 
 	if (filter->counter) {
@@ -1675,6 +1803,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
 	enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END;
 	enum ice_fdir_tunnel_type tunnel_type = ICE_FDIR_TUNNEL_TYPE_NONE;
+	const struct rte_flow_item_raw *raw_spec, *raw_mask;
 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
@@ -1702,6 +1831,9 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	struct ice_fdir_extra *p_ext_data;
 	struct ice_fdir_v4 *p_v4 = NULL;
 	struct ice_fdir_v6 *p_v6 = NULL;
+	struct ice_parser_result rslt;
+	struct ice_parser *psr;
+	uint8_t item_num = 0;
 
 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 		if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN)
@@ -1713,6 +1845,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 		    item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
 			is_outer = false;
 		}
+		item_num++;
 	}
 
 	/* This loop parse flow pattern and distinguish Non-tunnel and tunnel
@@ -1733,6 +1866,101 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 			    &input_set_i : &input_set_o;
 
 		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_RAW:
+			raw_spec = item->spec;
+			raw_mask = item->mask;
+
+			if (item_num != 1)
+				break;
+
+			/* convert raw spec & mask from byte string to int */
+			unsigned char *tmp_spec =
+				(uint8_t *)(uintptr_t)raw_spec->pattern;
+			unsigned char *tmp_mask =
+				(uint8_t *)(uintptr_t)raw_mask->pattern;
+			uint16_t udp_port = 0;
+			uint16_t tmp_val = 0;
+			uint8_t pkt_len = 0;
+			uint8_t tmp = 0;
+			int i, j;
+
+			pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern);
+			if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
+				pkt_len)
+				return -rte_errno;
+
+			for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
+				tmp = tmp_spec[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_spec[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_spec[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_spec[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_spec[j] = tmp_val + tmp - '0';
+
+				tmp = tmp_mask[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_mask[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_mask[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_mask[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_mask[j] = tmp_val + tmp - '0';
+			}
+
+			pkt_len /= 2;
+
+			if (ice_parser_create(&ad->hw, &psr))
+				return -rte_errno;
+			if (ice_get_open_tunnel_port(&ad->hw, TNL_VXLAN,
+						     &udp_port))
+				ice_parser_vxlan_tunnel_set(psr, udp_port,
+							    true);
+			if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt))
+				return -rte_errno;
+			ice_parser_destroy(psr);
+
+			if (!tmp_mask)
+				return -rte_errno;
+
+			filter->prof = (struct ice_parser_profile *)
+				ice_malloc(&ad->hw, sizeof(*filter->prof));
+			if (!filter->prof)
+				return -ENOMEM;
+
+			if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask,
+				pkt_len, ICE_BLK_FD, true, filter->prof))
+				return -rte_errno;
+
+			u8 *pkt_buf = (u8 *)ice_malloc(&ad->hw, pkt_len + 1);
+			if (!pkt_buf)
+				return -ENOMEM;
+			rte_memcpy(pkt_buf, tmp_spec, pkt_len);
+			filter->pkt_buf = pkt_buf;
+
+			filter->pkt_len = pkt_len;
+
+			filter->parser_ena = true;
+
+			break;
+
 		case RTE_FLOW_ITEM_TYPE_ETH:
 			flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
 			eth_spec = item->spec;
@@ -2198,6 +2426,7 @@ ice_fdir_parse(struct ice_adapter *ad,
 	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
 	struct ice_pattern_match_item *item = NULL;
 	uint64_t input_set;
+	bool raw = false;
 	int ret;
 
 	memset(filter, 0, sizeof(*filter));
@@ -2213,7 +2442,13 @@ ice_fdir_parse(struct ice_adapter *ad,
 	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
 	if (ret)
 		goto error;
+
+	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
+		raw = true;
+
 	input_set = filter->input_set_o | filter->input_set_i;
+	input_set = raw ? ~input_set : input_set;
+
 	if (!input_set || filter->input_set_o &
 	    ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) ||
 	    filter->input_set_i & ~item->input_set_mask_i) {
diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 02f854666a..d3391c86c0 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -65,6 +65,12 @@ enum rte_flow_item_type pattern_empty[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* raw */
+enum rte_flow_item_type pattern_raw[] = {
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 /* L2 */
 enum rte_flow_item_type pattern_ethertype[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
@@ -2081,6 +2087,7 @@ struct ice_ptype_match {
 };
 
 static struct ice_ptype_match ice_ptype_map[] = {
+	{pattern_raw,					ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4,				ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4_udp,				ICE_PTYPE_IPV4_UDP_PAY},
 	{pattern_eth_ipv4_tcp,				ICE_PTYPE_IPV4_TCP_PAY},
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index 8845a3e156..1b030c0466 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -124,6 +124,9 @@
 /* empty pattern */
 extern enum rte_flow_item_type pattern_empty[];
 
+/* raw pattern */
+extern enum rte_flow_item_type pattern_raw[];
+
 /* L2 */
 extern enum rte_flow_item_type pattern_ethertype[];
 extern enum rte_flow_item_type pattern_ethertype_vlan[];
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v8 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-11-01 23:56                               ` Zhang, Qi Z
  2021-11-02  2:44                                 ` Guo, Junfeng
  2021-11-02  5:39                               ` [dpdk-dev] [PATCH v9 0/4] " Junfeng Guo
  1 sibling, 1 reply; 68+ messages in thread
From: Zhang, Qi Z @ 2021-11-01 23:56 UTC (permalink / raw)
  To: Guo, Junfeng, Wu, Jingjing, Xing, Beilei; +Cc: dev, Yigit, Ferruh, Xu, Ting



> -----Original Message-----
> From: Guo, Junfeng <junfeng.guo@intel.com>
> Sent: Monday, November 1, 2021 4:36 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Xu, Ting
> <ting.xu@intel.com>; Guo, Junfeng <junfeng.guo@intel.com>
> Subject: [PATCH v8 4/4] net/ice: enable protocol agnostic flow offloading in
> FDIR
> 
> Protocol agnostic flow offloading in Flow Director is enabled by this patch
> based on the Parser Library, using existing rte_flow raw API.
> 
> Note that the raw flow requires:
> 1. byte string of raw target packet bits.
> 2. byte string of mask of target packet.
> 
> Here is an example:
> FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:
> 
> flow create 0 ingress pattern raw \
> pattern spec \
> 0000000000000000000000000800450000140000400040100000000000000
> 1020304 \ pattern mask \
> 000000000000000000000000000000000000000000000000000000000000ff
> ffffff \ / end actions queue index 3 / mark id 3 / end
> 
> Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto) is
> optional in our cases. To avoid redundancy, we just omit the mask of 0x0800
> (with 0xFFFF) in the mask byte string example. The prefix '0x' for the spec and
> mask byte (hex) strings are also omitted here.
> 
> Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
> ---
>  doc/guides/rel_notes/release_21_11.rst |   1 +
>  drivers/net/ice/ice_ethdev.h           |  14 ++
>  drivers/net/ice/ice_fdir_filter.c      | 235 +++++++++++++++++++++++++
>  drivers/net/ice/ice_generic_flow.c     |   7 +
>  drivers/net/ice/ice_generic_flow.h     |   3 +
>  5 files changed, 260 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/release_21_11.rst
> b/doc/guides/rel_notes/release_21_11.rst
> index 98d50a160b..36fdee0a98 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -167,6 +167,7 @@ New Features
> 
>  * **Updated Intel ice driver.**
> 
> +  * Added protocol agnostic flow offloading support in Flow Director.
>    * Added 1PPS out support by a devargs.
>    * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
>    * Added DEV_RX_OFFLOAD_TIMESTAMP support.
> diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h index
> 0e42c4c063..bbfeb0cc23 100644
> --- a/drivers/net/ice/ice_ethdev.h
> +++ b/drivers/net/ice/ice_ethdev.h
> @@ -318,6 +318,11 @@ struct ice_fdir_filter_conf {
>  	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
>  	uint64_t input_set_i; /* only for tunnel inner fields */
>  	uint32_t mark_flag;
> +
> +	struct ice_parser_profile *prof;
> +	const u8 *pkt_buf;
> +	bool parser_ena;
> +	u8 pkt_len;
>  };
> 
>  #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
> @@ -487,6 +492,14 @@ struct ice_devargs {
>  	uint8_t pps_out_ena;
>  };
> 
> +/**
> + * Structure to store fdir fv entry.
> + */
> +struct ice_fdir_prof_info {
> +	struct ice_parser_profile prof;
> +	u64 fdir_actived_cnt;
> +};
> +
>  /**
>   * Structure to store private data for each PF/VF instance.
>   */
> @@ -510,6 +523,7 @@ struct ice_adapter {
>  	struct rte_timecounter tx_tstamp_tc;
>  	bool ptp_ena;
>  	uint64_t time_hw;
> +	struct ice_fdir_prof_info fdir_prof_info[ICE_MAX_PTGS];
>  #ifdef RTE_ARCH_X86
>  	bool rx_use_avx2;
>  	bool rx_use_avx512;
> diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
> index bd627e3aa8..888f0dea6d 100644
> --- a/drivers/net/ice/ice_fdir_filter.c
> +++ b/drivers/net/ice/ice_fdir_filter.c
> @@ -107,6 +107,7 @@
>  	ICE_INSET_NAT_T_ESP_SPI)
> 
>  static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
> +	{pattern_raw,					ICE_INSET_NONE,
> 	ICE_INSET_NONE,			ICE_INSET_NONE},
>  	{pattern_ethertype,				ICE_FDIR_INSET_ETH,
> 	ICE_INSET_NONE,			ICE_INSET_NONE},
>  	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,
> 	ICE_INSET_NONE,			ICE_INSET_NONE},
>  	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,
> 	ICE_INSET_NONE,			ICE_INSET_NONE},
> @@ -1188,6 +1189,24 @@ ice_fdir_is_tunnel_profile(enum
> ice_fdir_tunnel_type tunnel_type)
>  		return 0;
>  }
> 
> +static int
> +ice_fdir_add_del_raw(struct ice_pf *pf,
> +		     struct ice_fdir_filter_conf *filter,
> +		     bool add)
> +{
> +	struct ice_hw *hw = ICE_PF_TO_HW(pf);
> +
> +	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
> +	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
> +
> +	struct ice_fltr_desc desc;
> +	memset(&desc, 0, sizeof(desc));
> +	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
> +	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
> +
> +	return ice_fdir_programming(pf, &desc); }
> +
>  static int
>  ice_fdir_add_del_filter(struct ice_pf *pf,
>  			struct ice_fdir_filter_conf *filter, @@ -1303,6 +1322,72 @@
> ice_fdir_create_filter(struct ice_adapter *ad,
>  	struct ice_fdir_fltr_pattern key;
>  	bool is_tun;
>  	int ret;
> +	int i;
> +
> +	if (filter->parser_ena) {
> +		struct ice_hw *hw = ICE_PF_TO_HW(pf);
> +
> +		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
> +		int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
> +		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
> +		u16 main_vsi = pf->main_vsi->idx;
> +		bool fv_found = false;
> +
> +		struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg];
> +		if (pi->fdir_actived_cnt != 0) {
> +			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
> +				if (pi->prof.fv[i].proto_id !=
> +				    filter->prof->fv[i].proto_id ||
> +				    pi->prof.fv[i].offset !=
> +				    filter->prof->fv[i].offset ||
> +				    pi->prof.fv[i].msk !=
> +				    filter->prof->fv[i].msk)
> +					break;
> +			if (i == ICE_MAX_FV_WORDS) {
> +				fv_found = true;
> +				pi->fdir_actived_cnt++;
> +			}
> +		}
> +
> +		if (!fv_found) {
> +			ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
> +						   filter->prof, ICE_BLK_FD);
> +			if (ret)
> +				return -rte_errno;
> +		}
> +
> +		ret = ice_fdir_add_del_raw(pf, filter, true);
> +		if (ret)
> +			return -rte_errno;
> +
> +		if (!fv_found) {
> +			for (i = 0; i < filter->prof->fv_num; i++) {
> +				pi->prof.fv[i].proto_id =
> +					filter->prof->fv[i].proto_id;
> +				pi->prof.fv[i].offset =
> +					filter->prof->fv[i].offset;
> +				pi->prof.fv[i].spec = filter->prof->fv[i].spec;
> +				pi->prof.fv[i].msk = filter->prof->fv[i].msk;
> +			}
> +			pi->fdir_actived_cnt = 1;
> +		}
> +
> +		if (filter->mark_flag == 1)
> +			ice_fdir_rx_parsing_enable(ad, 1);
> +
> +		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
> +		if (!entry)
> +			return -rte_errno;
> +
> +		rte_memcpy(entry, filter, sizeof(*filter));
> +
> +		filter->prof = NULL;
> +		filter->pkt_buf = NULL;

Should we free filter here? as a copy of it already be assigned to flow->rule.

Actually the filter is assigned by meta, and it is created during parse_pattern_action, and assume to be freed in create_filter.

Or we can assign meta to flow->rule directly, then we only need to free it during destroy.  

> +
> +		flow->rule = entry;
> +
> +		return 0;
> +	}
> 
>  	ice_fdir_extract_fltr_key(&key, filter);
>  	node = ice_fdir_entry_lookup(fdir_info, &key); @@ -1397,6 +1482,49
> @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
> 
>  	filter = (struct ice_fdir_filter_conf *)flow->rule;
> 
> +	if (filter->parser_ena) {
> +		struct ice_hw *hw = ICE_PF_TO_HW(pf);
> +
> +		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
> +		int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
> +		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
> +		u16 main_vsi = pf->main_vsi->idx;
> +		u16 vsi_num;
> +
> +		ret = ice_fdir_add_del_raw(pf, filter, false);
> +		if (ret)
> +			return -rte_errno;
> +
> +		struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg];
> +		if (pi->fdir_actived_cnt != 0) {
> +			pi->fdir_actived_cnt--;
> +			if (!pi->fdir_actived_cnt) {
> +				vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi);
> +				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
> +							   vsi_num, id);
> +				if (ret)
> +					return -rte_errno;
> +
> +				vsi_num = ice_get_hw_vsi_num(hw, main_vsi);
> +				ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
> +							   vsi_num, id);
> +				if (ret)
> +					return -rte_errno;
> +			}
> +		}
> +
> +		if (filter->mark_flag == 1)
> +			ice_fdir_rx_parsing_enable(ad, 0);
> +
> +		flow->rule = NULL;
> +		filter->prof = NULL;
> +		filter->pkt_buf = NULL;

Should we free the pkt_buf and prof before assign them to NULL.
They are created during parse_pattern but never be freed before.

> +
> +		rte_free(filter);
> +
> +		return 0;
> +	}
> +


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

* Re: [dpdk-dev] [PATCH v8 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-11-01 23:56                               ` Zhang, Qi Z
@ 2021-11-02  2:44                                 ` Guo, Junfeng
  0 siblings, 0 replies; 68+ messages in thread
From: Guo, Junfeng @ 2021-11-02  2:44 UTC (permalink / raw)
  To: Zhang, Qi Z, Wu, Jingjing, Xing, Beilei; +Cc: dev, Yigit, Ferruh, Xu, Ting



> -----Original Message-----
> From: Zhang, Qi Z <qi.z.zhang@intel.com>
> Sent: Tuesday, November 2, 2021 07:56
> To: Guo, Junfeng <junfeng.guo@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Xu, Ting
> <Ting.Xu@intel.com>
> Subject: RE: [PATCH v8 4/4] net/ice: enable protocol agnostic flow
> offloading in FDIR
> 
> 
> 
> > -----Original Message-----
> > From: Guo, Junfeng <junfeng.guo@intel.com>
> > Sent: Monday, November 1, 2021 4:36 PM
> > To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>;
> > Xing, Beilei <beilei.xing@intel.com>
> > Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Xu, Ting
> > <ting.xu@intel.com>; Guo, Junfeng <junfeng.guo@intel.com>
> > Subject: [PATCH v8 4/4] net/ice: enable protocol agnostic flow
> offloading in
> > FDIR
> >
> > Protocol agnostic flow offloading in Flow Director is enabled by this
> patch
> > based on the Parser Library, using existing rte_flow raw API.
> >
> > Note that the raw flow requires:
> > 1. byte string of raw target packet bits.
> > 2. byte string of mask of target packet.
> >
> > Here is an example:
> > FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:
> >
> > flow create 0 ingress pattern raw \
> > pattern spec \
> >
> 000000000000000000000000080045000014000040004010000000000000
> 0
> > 1020304 \ pattern mask \
> >
> 000000000000000000000000000000000000000000000000000000000000
> ff
> > ffffff \ / end actions queue index 3 / mark id 3 / end
> >
> > Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto) is
> > optional in our cases. To avoid redundancy, we just omit the mask of
> 0x0800
> > (with 0xFFFF) in the mask byte string example. The prefix '0x' for the
> spec and
> > mask byte (hex) strings are also omitted here.
> >
> > Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
> > ---
> >  doc/guides/rel_notes/release_21_11.rst |   1 +
> >  drivers/net/ice/ice_ethdev.h           |  14 ++
> >  drivers/net/ice/ice_fdir_filter.c      | 235 +++++++++++++++++++++++++
> >  drivers/net/ice/ice_generic_flow.c     |   7 +
> >  drivers/net/ice/ice_generic_flow.h     |   3 +
> >  5 files changed, 260 insertions(+)
> >
> > diff --git a/doc/guides/rel_notes/release_21_11.rst
> > b/doc/guides/rel_notes/release_21_11.rst
> > index 98d50a160b..36fdee0a98 100644
> > --- a/doc/guides/rel_notes/release_21_11.rst
> > +++ b/doc/guides/rel_notes/release_21_11.rst
> > @@ -167,6 +167,7 @@ New Features
> >
> >  * **Updated Intel ice driver.**
> >
> > +  * Added protocol agnostic flow offloading support in Flow Director.
> >    * Added 1PPS out support by a devargs.
> >    * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS
> flow.
> >    * Added DEV_RX_OFFLOAD_TIMESTAMP support.
> > diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
> index
> > 0e42c4c063..bbfeb0cc23 100644
> > --- a/drivers/net/ice/ice_ethdev.h
> > +++ b/drivers/net/ice/ice_ethdev.h
> > @@ -318,6 +318,11 @@ struct ice_fdir_filter_conf {
> >  uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
> >  uint64_t input_set_i; /* only for tunnel inner fields */
> >  uint32_t mark_flag;
> > +
> > +struct ice_parser_profile *prof;
> > +const u8 *pkt_buf;
> > +bool parser_ena;
> > +u8 pkt_len;
> >  };
> >
> >  #define ICE_MAX_FDIR_FILTER_NUM(1024 * 16)
> > @@ -487,6 +492,14 @@ struct ice_devargs {
> >  uint8_t pps_out_ena;
> >  };
> >
> > +/**
> > + * Structure to store fdir fv entry.
> > + */
> > +struct ice_fdir_prof_info {
> > +struct ice_parser_profile prof;
> > +u64 fdir_actived_cnt;
> > +};
> > +
> >  /**
> >   * Structure to store private data for each PF/VF instance.
> >   */
> > @@ -510,6 +523,7 @@ struct ice_adapter {
> >  struct rte_timecounter tx_tstamp_tc;
> >  bool ptp_ena;
> >  uint64_t time_hw;
> > +struct ice_fdir_prof_info fdir_prof_info[ICE_MAX_PTGS];
> >  #ifdef RTE_ARCH_X86
> >  bool rx_use_avx2;
> >  bool rx_use_avx512;
> > diff --git a/drivers/net/ice/ice_fdir_filter.c
> b/drivers/net/ice/ice_fdir_filter.c
> > index bd627e3aa8..888f0dea6d 100644
> > --- a/drivers/net/ice/ice_fdir_filter.c
> > +++ b/drivers/net/ice/ice_fdir_filter.c
> > @@ -107,6 +107,7 @@
> >  ICE_INSET_NAT_T_ESP_SPI)
> >
> >  static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
> > +{pattern_raw,ICE_INSET_NONE,
> > ICE_INSET_NONE,ICE_INSET_NONE},
> >  {pattern_ethertype,ICE_FDIR_INSET_ETH,
> > ICE_INSET_NONE,ICE_INSET_NONE},
> >  {pattern_eth_ipv4,ICE_FDIR_INSET_ETH_IPV4,
> > ICE_INSET_NONE,ICE_INSET_NONE},
> >  {pattern_eth_ipv4_udp,ICE_FDIR_INSET_ETH_IPV4_UDP,
> > ICE_INSET_NONE,ICE_INSET_NONE},
> > @@ -1188,6 +1189,24 @@ ice_fdir_is_tunnel_profile(enum
> > ice_fdir_tunnel_type tunnel_type)
> >  return 0;
> >  }
> >
> > +static int
> > +ice_fdir_add_del_raw(struct ice_pf *pf,
> > +     struct ice_fdir_filter_conf *filter,
> > +     bool add)
> > +{
> > +struct ice_hw *hw = ICE_PF_TO_HW(pf);
> > +
> > +unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
> > +rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
> > +
> > +struct ice_fltr_desc desc;
> > +memset(&desc, 0, sizeof(desc));
> > +filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
> > +ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
> > +
> > +return ice_fdir_programming(pf, &desc); }
> > +
> >  static int
> >  ice_fdir_add_del_filter(struct ice_pf *pf,
> >  struct ice_fdir_filter_conf *filter, @@ -1303,6 +1322,72 @@
> > ice_fdir_create_filter(struct ice_adapter *ad,
> >  struct ice_fdir_fltr_pattern key;
> >  bool is_tun;
> >  int ret;
> > +int i;
> > +
> > +if (filter->parser_ena) {
> > +struct ice_hw *hw = ICE_PF_TO_HW(pf);
> > +
> > +int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
> > +int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
> > +u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
> > +u16 main_vsi = pf->main_vsi->idx;
> > +bool fv_found = false;
> > +
> > +struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg];
> > +if (pi->fdir_actived_cnt != 0) {
> > +for (i = 0; i < ICE_MAX_FV_WORDS; i++)
> > +if (pi->prof.fv[i].proto_id !=
> > +    filter->prof->fv[i].proto_id ||
> > +    pi->prof.fv[i].offset !=
> > +    filter->prof->fv[i].offset ||
> > +    pi->prof.fv[i].msk !=
> > +    filter->prof->fv[i].msk)
> > +break;
> > +if (i == ICE_MAX_FV_WORDS) {
> > +fv_found = true;
> > +pi->fdir_actived_cnt++;
> > +}
> > +}
> > +
> > +if (!fv_found) {
> > +ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
> > +   filter->prof, ICE_BLK_FD);
> > +if (ret)
> > +return -rte_errno;
> > +}
> > +
> > +ret = ice_fdir_add_del_raw(pf, filter, true);
> > +if (ret)
> > +return -rte_errno;
> > +
> > +if (!fv_found) {
> > +for (i = 0; i < filter->prof->fv_num; i++) {
> > +pi->prof.fv[i].proto_id =
> > +filter->prof->fv[i].proto_id;
> > +pi->prof.fv[i].offset =
> > +filter->prof->fv[i].offset;
> > +pi->prof.fv[i].spec = filter->prof->fv[i].spec;
> > +pi->prof.fv[i].msk = filter->prof->fv[i].msk;
> > +}
> > +pi->fdir_actived_cnt = 1;
> > +}
> > +
> > +if (filter->mark_flag == 1)
> > +ice_fdir_rx_parsing_enable(ad, 1);
> > +
> > +entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
> > +if (!entry)
> > +return -rte_errno;
> > +
> > +rte_memcpy(entry, filter, sizeof(*filter));
> > +
> > +filter->prof = NULL;
> > +filter->pkt_buf = NULL;
> 
> Should we free filter here? as a copy of it already be assigned to flow-
> >rule.

Here we just free the two filter members of "filter", which are allocated by us in func ice_fdir_parse_pattern.
Once the copy of "filter" to "entry" is ready, these two fields of "filter" will belong to "entry".
We set them to NULL to ensure that later free of meta ("filter") will not have impact on "entry".

> 
> Actually the filter is assigned by meta, and it is created during
> parse_pattern_action, and assume to be freed in create_filter.
> 
> Or we can assign meta to flow->rule directly, then we only need to free it
> during destroy.

The "filter" is assigned with a global variable in ice_fdir_parse with "*filter = &pf->fdir.conf".
So we cannot just assign meta to flow->rule directly.
The copy of "filter" will be added into the list of flow and used later for other purpose like destroy.

> 
> > +
> > +flow->rule = entry;
> > +
> > +return 0;
> > +}
> >
> >  ice_fdir_extract_fltr_key(&key, filter);
> >  node = ice_fdir_entry_lookup(fdir_info, &key); @@ -1397,6 +1482,49
> > @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
> >
> >  filter = (struct ice_fdir_filter_conf *)flow->rule;
> >
> > +if (filter->parser_ena) {
> > +struct ice_hw *hw = ICE_PF_TO_HW(pf);
> > +
> > +int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
> > +int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
> > +u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
> > +u16 main_vsi = pf->main_vsi->idx;
> > +u16 vsi_num;
> > +
> > +ret = ice_fdir_add_del_raw(pf, filter, false);
> > +if (ret)
> > +return -rte_errno;
> > +
> > +struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg];
> > +if (pi->fdir_actived_cnt != 0) {
> > +pi->fdir_actived_cnt--;
> > +if (!pi->fdir_actived_cnt) {
> > +vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi);
> > +ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
> > +   vsi_num, id);
> > +if (ret)
> > +return -rte_errno;
> > +
> > +vsi_num = ice_get_hw_vsi_num(hw, main_vsi);
> > +ret = ice_rem_prof_id_flow(hw, ICE_BLK_FD,
> > +   vsi_num, id);
> > +if (ret)
> > +return -rte_errno;
> > +}
> > +}
> > +
> > +if (filter->mark_flag == 1)
> > +ice_fdir_rx_parsing_enable(ad, 0);
> > +
> > +flow->rule = NULL;
> > +filter->prof = NULL;
> > +filter->pkt_buf = NULL;
> 
> Should we free the pkt_buf and prof before assign them to NULL.
> They are created during parse_pattern but never be freed before.

Since prof and pkt_buf is allocated by us, these two fields should also be freed by us before freeing "filter".

> 
> > +
> > +rte_free(filter);
> > +
> > +return 0;
> > +}
> > +
> 


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

* [dpdk-dev] [PATCH v9 0/4] enable protocol agnostic flow offloading in FDIR
  2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-11-01 23:56                               ` Zhang, Qi Z
@ 2021-11-02  5:39                               ` Junfeng Guo
  2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
                                                   ` (5 more replies)
  1 sibling, 6 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-02  5:39 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch set based on the Parser Library using existing rte_flow raw API.

[PATCH v9 1/4] net/ice/base: add method to disable FDIR SWAP option.
[PATCH v9 2/4] net/ice/base: add function to set HW profile for raw flow.
[PATCH v9 3/4] app/testpmd: update Max RAW pattern size to 512.
[PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in FDIR.

Junfeng Guo (4):
  net/ice/base: add method to disable FDIR SWAP option
  net/ice/base: add function to set HW profile for raw flow
  app/testpmd: update Max RAW pattern size to 512
  net/ice: enable protocol agnostic flow offloading in FDIR

* v8:
Added memory free logic.

* v8:
Replaced profile info list with a table.

* v7:
Fixed LIST_FOR_EACH_ENTRY logic.

* v6:
Removed redundant code.

* v5:
Optimized some code logic.

* v4:
Added list to check inputset conflict.

* v3:
Added necessary base code for raw flow in FDIR.

* v2:
Enabled vxlan port add for raw flow and updated commit message

 app/test-pmd/cmdline_flow.c            |   2 +-
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/base/README            |   2 +-
 drivers/net/ice/base/ice_flex_pipe.c   |  93 +++++++++-
 drivers/net/ice/base/ice_flex_pipe.h   |   6 +-
 drivers/net/ice/base/ice_flow.c        |  86 ++++++++-
 drivers/net/ice/base/ice_flow.h        |   4 +
 drivers/net/ice/ice_ethdev.h           |  14 ++
 drivers/net/ice/ice_fdir_filter.c      | 231 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 11 files changed, 443 insertions(+), 6 deletions(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH v9 1/4] net/ice/base: add method to disable FDIR SWAP option
  2021-11-02  5:39                               ` [dpdk-dev] [PATCH v9 0/4] " Junfeng Guo
@ 2021-11-02  5:39                                 ` Junfeng Guo
  2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
                                                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-02  5:39 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

In this patch, we introduced a new parameter to enable/disable the
FDIR SWAP option by setting the swap and inset register set with
certain values.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 44 ++++++++++++++++++++++++++--
 drivers/net/ice/base/ice_flex_pipe.h |  3 +-
 drivers/net/ice/base/ice_flow.c      |  2 +-
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index f35d59f4f5..06a233990f 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -4952,6 +4952,43 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 	return ICE_SUCCESS;
 }
 
+/**
+ * ice_disable_fd_swap - set register appropriately to disable FD swap
+ * @hw: pointer to the HW struct
+ * @prof_id: profile ID
+ */
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id)
+{
+	u8 swap_val = ICE_SWAP_VALID;
+	u8 i;
+	/* Since the SWAP Flag in the Programming Desc doesn't work,
+	 * here add method to disable the SWAP Option via setting
+	 * certain SWAP and INSET register set.
+	 */
+	for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw / 4; i++) {
+		u32 raw_swap = 0;
+		u32 raw_in = 0;
+		u8 j;
+
+		for (j = 0; j < 4; j++) {
+			raw_swap |= (swap_val++) << (j * BITS_PER_BYTE);
+			raw_in |= ICE_INSET_DFLT << (j * BITS_PER_BYTE);
+		}
+
+		/* write the FDIR swap register set */
+		wr32(hw, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		/* write the FDIR inset register set */
+		wr32(hw, GLQF_FDINSET(prof_id, i), raw_in);
+
+		ice_debug(hw, ICE_DBG_INIT, "inset wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDINSET(prof_id, i), raw_in);
+	}
+}
+
 /**
  * ice_add_prof - add profile
  * @hw: pointer to the HW struct
@@ -4962,6 +4999,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
  * @attr_cnt: number of elements in attrib array
  * @es: extraction sequence (length of array is determined by the block)
  * @masks: mask for extraction sequence
+ * @fd_swap: enable/disable FDIR paired src/dst fields swap option
  *
  * This function registers a profile, which matches a set of PTYPES with a
  * particular extraction sequence. While the hardware profile is allocated
@@ -4971,7 +5009,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks)
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap)
 {
 	u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE);
 	ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT);
@@ -4991,7 +5029,7 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 		status = ice_alloc_prof_id(hw, blk, &prof_id);
 		if (status)
 			goto err_ice_add_prof;
-		if (blk == ICE_BLK_FD) {
+		if (blk == ICE_BLK_FD && fd_swap) {
 			/* For Flow Director block, the extraction sequence may
 			 * need to be altered in the case where there are paired
 			 * fields that have no match. This is necessary because
@@ -5002,6 +5040,8 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 			status = ice_update_fd_swap(hw, prof_id, es);
 			if (status)
 				goto err_ice_add_prof;
+		} else if (blk == ICE_BLK_FD) {
+			ice_disable_fd_swap(hw, prof_id);
 		}
 		status = ice_update_prof_masking(hw, blk, prof_id, masks);
 		if (status)
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index 9733c4b214..dd332312dd 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -61,10 +61,11 @@ bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype);
 /* XLT2/VSI group functions */
 enum ice_status
 ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig);
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id);
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks);
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap);
 void ice_init_all_prof_masks(struct ice_hw *hw);
 void ice_shutdown_all_prof_masks(struct ice_hw *hw);
 struct ice_prof_map *
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 96d54b494d..77b6b130c1 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2244,7 +2244,7 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
 	/* Add a HW profile for this flow profile */
 	status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
 			      params->attr, params->attr_cnt, params->es,
-			      params->mask);
+			      params->mask, true);
 	if (status) {
 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
 		goto out;
-- 
2.25.1


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

* [dpdk-dev] [PATCH v9 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-11-02  5:39                               ` [dpdk-dev] [PATCH v9 0/4] " Junfeng Guo
  2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
@ 2021-11-02  5:39                                 ` Junfeng Guo
  2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
                                                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-02  5:39 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Based on the parser library, we can directly set HW profile and
associate the main/ctrl vsi.

This patch set also updated the release date in README.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 drivers/net/ice/base/README          |  2 +-
 drivers/net/ice/base/ice_flex_pipe.c | 49 ++++++++++++++++
 drivers/net/ice/base/ice_flex_pipe.h |  3 +
 drivers/net/ice/base/ice_flow.c      | 84 ++++++++++++++++++++++++++++
 drivers/net/ice/base/ice_flow.h      |  4 ++
 5 files changed, 141 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ice/base/README b/drivers/net/ice/base/README
index 87a1cebfac..0b23fc4795 100644
--- a/drivers/net/ice/base/README
+++ b/drivers/net/ice/base/README
@@ -6,7 +6,7 @@ Intel® ICE driver
 ==================
 
 This directory contains source code of FreeBSD ice driver of version
-2021.04.29 released by the team which develops
+2021.10.28 released by the team which develops
 basic drivers for any ice NIC. The directory of base/ contains the
 original source package.
 This driver is valid for the product(s) listed below
diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index 06a233990f..395787806b 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -6365,3 +6365,52 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
 
 	return status;
 }
+
+/**
+ * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow entry
+ * @hw: pointer to the HW struct
+ * @blk: HW block
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @id: profile id (handle)
+ *
+ * Calling this function will update the hardware tables to enable the
+ * profile indicated by the ID parameter for the VSIs specified in the VSI
+ * array. Once successfully called, the flow will be enabled.
+ */
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id)
+{
+	enum ice_status status = ICE_SUCCESS;
+	u16 vsi_num;
+
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for main VSI flow entry, %d\n",
+			  status);
+		goto err_add_prof;
+	}
+
+	if (blk != ICE_BLK_FD)
+		return status;
+
+	vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for ctrl VSI flow entry, %d\n",
+			  status);
+		goto err_add_entry;
+	}
+
+	return status;
+
+err_add_entry:
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+err_add_prof:
+	ice_flow_rem_prof(hw, blk, id);
+
+	return status;
+}
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index dd332312dd..23ba45564a 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -76,6 +76,9 @@ enum ice_status
 ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 enum ice_status
 ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id);
 enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
 enum ice_status
 ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 77b6b130c1..f699dbbc74 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2524,6 +2524,90 @@ ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
 	return status;
 }
 
+#define FLAG_GTP_EH_PDU_LINK	BIT_ULL(13)
+#define FLAG_GTP_EH_PDU		BIT_ULL(14)
+
+#define FLAG_GTPU_MSK	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_DW	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_UP	\
+	(FLAG_GTP_EH_PDU)
+/**
+ * ice_flow_set_hw_prof - Set HW flow profile based on the parsed profile info
+ * @hw: pointer to the HW struct
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @prof: stores parsed profile info from raw flow
+ * @blk: classification stage
+ */
+enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk)
+{
+	int id = ice_find_first_bit(prof->ptypes, UINT16_MAX);
+	struct ice_flow_prof_params *params;
+	u8 fv_words = hw->blk[blk].es.fvw;
+	enum ice_status status;
+	u16 vsi_num;
+	int i, idx;
+
+	params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
+	if (!params)
+		return ICE_ERR_NO_MEMORY;
+
+	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
+		params->es[i].prot_id = ICE_PROT_INVALID;
+		params->es[i].off = ICE_FV_OFFSET_INVAL;
+	}
+
+	for (i = 0; i < prof->fv_num; i++) {
+		if (hw->blk[blk].es.reverse)
+			idx = fv_words - i - 1;
+		else
+			idx = i;
+		params->es[idx].prot_id = prof->fv[i].proto_id;
+		params->es[idx].off = prof->fv[i].offset;
+		params->mask[idx] = CPU_TO_BE16(prof->fv[i].msk);
+	}
+
+	switch (prof->flags) {
+	case FLAG_GTPU_DW:
+		params->attr = ice_attr_gtpu_down;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
+		break;
+	case FLAG_GTPU_UP:
+		params->attr = ice_attr_gtpu_up;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
+		break;
+	default:
+		if (prof->flags_msk & FLAG_GTPU_MSK) {
+			params->attr = ice_attr_gtpu_session;
+			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
+		}
+		break;
+	}
+
+	status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
+			      params->attr, params->attr_cnt,
+			      params->es, params->mask, false);
+	if (status)
+		goto free_params;
+
+	status = ice_flow_assoc_hw_prof(hw, blk, dest_vsi_handle,
+					fdir_vsi_handle, id);
+	if (status)
+		goto free_params;
+
+	return ICE_SUCCESS;
+
+free_params:
+	ice_free(hw, params);
+
+	return status;
+}
+
 /**
  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
  * @hw: pointer to the HW struct
diff --git a/drivers/net/ice/base/ice_flow.h b/drivers/net/ice/base/ice_flow.h
index 371d960066..dea7b3c0e8 100644
--- a/drivers/net/ice/base/ice_flow.h
+++ b/drivers/net/ice/base/ice_flow.h
@@ -548,6 +548,10 @@ enum ice_status
 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
 			u16 vsig);
 enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk);
+enum ice_status
 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
 		     u8 *hw_prof);
 
-- 
2.25.1


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

* [dpdk-dev] [PATCH v9 3/4] app/testpmd: update Max RAW pattern size to 512
  2021-11-02  5:39                               ` [dpdk-dev] [PATCH v9 0/4] " Junfeng Guo
  2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
  2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
@ 2021-11-02  5:39                                 ` Junfeng Guo
  2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
                                                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-02  5:39 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Update max size for pattern in struct rte_flow_item_raw to enable
protocol agnostic flow offloading.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 app/test-pmd/cmdline_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 24b224e632..0a2205804e 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -495,7 +495,7 @@ enum index {
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
-#define ITEM_RAW_PATTERN_SIZE 40
+#define ITEM_RAW_PATTERN_SIZE 512
 
 /** Maximum size for GENEVE option data pattern in bytes. */
 #define ITEM_GENEVE_OPT_DATA_SIZE 124
-- 
2.25.1


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

* [dpdk-dev] [PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-11-02  5:39                               ` [dpdk-dev] [PATCH v9 0/4] " Junfeng Guo
                                                   ` (2 preceding siblings ...)
  2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-11-02  5:39                                 ` Junfeng Guo
  2021-11-02 16:22                                   ` Ferruh Yigit
  2021-11-03  4:39                                   ` [dpdk-dev] [PATCH v10 0/4] " Junfeng Guo
  2021-11-02  5:58                                 ` [dpdk-dev] [PATCH v9 " Zhang, Qi Z
  2021-11-02 16:29                                 ` Ferruh Yigit
  5 siblings, 2 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-02  5:39 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch based on the Parser Library, using existing rte_flow raw API.

Note that the raw flow requires:
1. byte string of raw target packet bits.
2. byte string of mask of target packet.

Here is an example:
FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:

flow create 0 ingress pattern raw \
pattern spec \
00000000000000000000000008004500001400004000401000000000000001020304 \
pattern mask \
000000000000000000000000000000000000000000000000000000000000ffffffff \
/ end actions queue index 3 / mark id 3 / end

Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto)
is optional in our cases. To avoid redundancy, we just omit the mask
of 0x0800 (with 0xFFFF) in the mask byte string example. The prefix
'0x' for the spec and mask byte (hex) strings are also omitted here.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/ice_ethdev.h           |  14 ++
 drivers/net/ice/ice_fdir_filter.c      | 231 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 5 files changed, 256 insertions(+)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 98d50a160b..36fdee0a98 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -167,6 +167,7 @@ New Features
 
 * **Updated Intel ice driver.**
 
+  * Added protocol agnostic flow offloading support in Flow Director.
   * Added 1PPS out support by a devargs.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
   * Added DEV_RX_OFFLOAD_TIMESTAMP support.
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 0e42c4c063..d021e7fd0b 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -318,6 +318,11 @@ struct ice_fdir_filter_conf {
 	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
 	uint64_t input_set_i; /* only for tunnel inner fields */
 	uint32_t mark_flag;
+
+	struct ice_parser_profile *prof;
+	bool parser_ena;
+	u8 *pkt_buf;
+	u8 pkt_len;
 };
 
 #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
@@ -487,6 +492,14 @@ struct ice_devargs {
 	uint8_t pps_out_ena;
 };
 
+/**
+ * Structure to store fdir fv entry.
+ */
+struct ice_fdir_prof_info {
+	struct ice_parser_profile prof;
+	u64 fdir_actived_cnt;
+};
+
 /**
  * Structure to store private data for each PF/VF instance.
  */
@@ -510,6 +523,7 @@ struct ice_adapter {
 	struct rte_timecounter tx_tstamp_tc;
 	bool ptp_ena;
 	uint64_t time_hw;
+	struct ice_fdir_prof_info fdir_prof_info[ICE_MAX_PTGS];
 #ifdef RTE_ARCH_X86
 	bool rx_use_avx2;
 	bool rx_use_avx512;
diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
index bd627e3aa8..b5cd6d4ae6 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -107,6 +107,7 @@
 	ICE_INSET_NAT_T_ESP_SPI)
 
 static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+	{pattern_raw,					ICE_INSET_NONE,			ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_ethertype,				ICE_FDIR_INSET_ETH,		ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,	ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,	ICE_INSET_NONE,			ICE_INSET_NONE},
@@ -1188,6 +1189,24 @@ ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type)
 		return 0;
 }
 
+static int
+ice_fdir_add_del_raw(struct ice_pf *pf,
+		     struct ice_fdir_filter_conf *filter,
+		     bool add)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
+	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
+
+	struct ice_fltr_desc desc;
+	memset(&desc, 0, sizeof(desc));
+	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
+	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
+
+	return ice_fdir_programming(pf, &desc);
+}
+
 static int
 ice_fdir_add_del_filter(struct ice_pf *pf,
 			struct ice_fdir_filter_conf *filter,
@@ -1303,6 +1322,68 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 	struct ice_fdir_fltr_pattern key;
 	bool is_tun;
 	int ret;
+	int i;
+
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+		bool fv_found = false;
+
+		struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg];
+		if (pi->fdir_actived_cnt != 0) {
+			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
+				if (pi->prof.fv[i].proto_id !=
+				    filter->prof->fv[i].proto_id ||
+				    pi->prof.fv[i].offset !=
+				    filter->prof->fv[i].offset ||
+				    pi->prof.fv[i].msk !=
+				    filter->prof->fv[i].msk)
+					break;
+			if (i == ICE_MAX_FV_WORDS) {
+				fv_found = true;
+				pi->fdir_actived_cnt++;
+			}
+		}
+
+		if (!fv_found) {
+			ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
+						   filter->prof, ICE_BLK_FD);
+			if (ret)
+				goto error;
+		}
+
+		ret = ice_fdir_add_del_raw(pf, filter, true);
+		if (ret)
+			goto error;
+
+		if (!fv_found) {
+			for (i = 0; i < filter->prof->fv_num; i++) {
+				pi->prof.fv[i].proto_id =
+					filter->prof->fv[i].proto_id;
+				pi->prof.fv[i].offset =
+					filter->prof->fv[i].offset;
+				pi->prof.fv[i].msk = filter->prof->fv[i].msk;
+			}
+			pi->fdir_actived_cnt = 1;
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 1);
+
+		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
+		if (!entry)
+			goto error;
+
+		rte_memcpy(entry, filter, sizeof(*filter));
+
+		flow->rule = entry;
+
+		return 0;
+	}
 
 	ice_fdir_extract_fltr_key(&key, filter);
 	node = ice_fdir_entry_lookup(fdir_info, &key);
@@ -1381,6 +1462,11 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 free_entry:
 	rte_free(entry);
 	return -rte_errno;
+
+error:
+	rte_free(filter->prof);
+	rte_free(filter->pkt_buf);
+	return -rte_errno;
 }
 
 static int
@@ -1397,6 +1483,44 @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
 
 	filter = (struct ice_fdir_filter_conf *)flow->rule;
 
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+		enum ice_block blk = ICE_BLK_FD;
+		u16 vsi_num;
+
+		ret = ice_fdir_add_del_raw(pf, filter, false);
+		if (ret)
+			return -rte_errno;
+
+		struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg];
+		if (pi->fdir_actived_cnt != 0) {
+			pi->fdir_actived_cnt--;
+			if (!pi->fdir_actived_cnt) {
+				vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi);
+				ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+
+				vsi_num = ice_get_hw_vsi_num(hw, main_vsi);
+				ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+			}
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 0);
+
+		flow->rule = NULL;
+
+		rte_free(filter->prof);
+		rte_free(filter->pkt_buf);
+		rte_free(filter);
+
+		return 0;
+	}
+
 	is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type);
 
 	if (filter->counter) {
@@ -1675,6 +1799,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
 	enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END;
 	enum ice_fdir_tunnel_type tunnel_type = ICE_FDIR_TUNNEL_TYPE_NONE;
+	const struct rte_flow_item_raw *raw_spec, *raw_mask;
 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
@@ -1702,6 +1827,9 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	struct ice_fdir_extra *p_ext_data;
 	struct ice_fdir_v4 *p_v4 = NULL;
 	struct ice_fdir_v6 *p_v6 = NULL;
+	struct ice_parser_result rslt;
+	struct ice_parser *psr;
+	uint8_t item_num = 0;
 
 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 		if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN)
@@ -1713,6 +1841,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 		    item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
 			is_outer = false;
 		}
+		item_num++;
 	}
 
 	/* This loop parse flow pattern and distinguish Non-tunnel and tunnel
@@ -1733,6 +1862,101 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 			    &input_set_i : &input_set_o;
 
 		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_RAW:
+			raw_spec = item->spec;
+			raw_mask = item->mask;
+
+			if (item_num != 1)
+				break;
+
+			/* convert raw spec & mask from byte string to int */
+			unsigned char *tmp_spec =
+				(uint8_t *)(uintptr_t)raw_spec->pattern;
+			unsigned char *tmp_mask =
+				(uint8_t *)(uintptr_t)raw_mask->pattern;
+			uint16_t udp_port = 0;
+			uint16_t tmp_val = 0;
+			uint8_t pkt_len = 0;
+			uint8_t tmp = 0;
+			int i, j;
+
+			pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern);
+			if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
+				pkt_len)
+				return -rte_errno;
+
+			for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
+				tmp = tmp_spec[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_spec[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_spec[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_spec[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_spec[j] = tmp_val + tmp - '0';
+
+				tmp = tmp_mask[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_mask[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_mask[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_mask[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_mask[j] = tmp_val + tmp - '0';
+			}
+
+			pkt_len /= 2;
+
+			if (ice_parser_create(&ad->hw, &psr))
+				return -rte_errno;
+			if (ice_get_open_tunnel_port(&ad->hw, TNL_VXLAN,
+						     &udp_port))
+				ice_parser_vxlan_tunnel_set(psr, udp_port,
+							    true);
+			if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt))
+				return -rte_errno;
+			ice_parser_destroy(psr);
+
+			if (!tmp_mask)
+				return -rte_errno;
+
+			filter->prof = (struct ice_parser_profile *)
+				ice_malloc(&ad->hw, sizeof(*filter->prof));
+			if (!filter->prof)
+				return -ENOMEM;
+
+			if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask,
+				pkt_len, ICE_BLK_FD, true, filter->prof))
+				return -rte_errno;
+
+			u8 *pkt_buf = (u8 *)ice_malloc(&ad->hw, pkt_len + 1);
+			if (!pkt_buf)
+				return -ENOMEM;
+			rte_memcpy(pkt_buf, tmp_spec, pkt_len);
+			filter->pkt_buf = pkt_buf;
+
+			filter->pkt_len = pkt_len;
+
+			filter->parser_ena = true;
+
+			break;
+
 		case RTE_FLOW_ITEM_TYPE_ETH:
 			flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
 			eth_spec = item->spec;
@@ -2198,6 +2422,7 @@ ice_fdir_parse(struct ice_adapter *ad,
 	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
 	struct ice_pattern_match_item *item = NULL;
 	uint64_t input_set;
+	bool raw = false;
 	int ret;
 
 	memset(filter, 0, sizeof(*filter));
@@ -2213,7 +2438,13 @@ ice_fdir_parse(struct ice_adapter *ad,
 	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
 	if (ret)
 		goto error;
+
+	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
+		raw = true;
+
 	input_set = filter->input_set_o | filter->input_set_i;
+	input_set = raw ? ~input_set : input_set;
+
 	if (!input_set || filter->input_set_o &
 	    ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) ||
 	    filter->input_set_i & ~item->input_set_mask_i) {
diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 02f854666a..d3391c86c0 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -65,6 +65,12 @@ enum rte_flow_item_type pattern_empty[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* raw */
+enum rte_flow_item_type pattern_raw[] = {
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 /* L2 */
 enum rte_flow_item_type pattern_ethertype[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
@@ -2081,6 +2087,7 @@ struct ice_ptype_match {
 };
 
 static struct ice_ptype_match ice_ptype_map[] = {
+	{pattern_raw,					ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4,				ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4_udp,				ICE_PTYPE_IPV4_UDP_PAY},
 	{pattern_eth_ipv4_tcp,				ICE_PTYPE_IPV4_TCP_PAY},
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index 8845a3e156..1b030c0466 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -124,6 +124,9 @@
 /* empty pattern */
 extern enum rte_flow_item_type pattern_empty[];
 
+/* raw pattern */
+extern enum rte_flow_item_type pattern_raw[];
+
 /* L2 */
 extern enum rte_flow_item_type pattern_ethertype[];
 extern enum rte_flow_item_type pattern_ethertype_vlan[];
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v9 0/4] enable protocol agnostic flow offloading in FDIR
  2021-11-02  5:39                               ` [dpdk-dev] [PATCH v9 0/4] " Junfeng Guo
                                                   ` (3 preceding siblings ...)
  2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-11-02  5:58                                 ` Zhang, Qi Z
  2021-11-02 16:29                                 ` Ferruh Yigit
  5 siblings, 0 replies; 68+ messages in thread
From: Zhang, Qi Z @ 2021-11-02  5:58 UTC (permalink / raw)
  To: Guo, Junfeng, Wu, Jingjing, Xing, Beilei; +Cc: dev, Yigit, Ferruh, Xu, Ting



> -----Original Message-----
> From: Guo, Junfeng <junfeng.guo@intel.com>
> Sent: Tuesday, November 2, 2021 1:39 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Xu, Ting
> <ting.xu@intel.com>; Guo, Junfeng <junfeng.guo@intel.com>
> Subject: [PATCH v9 0/4] enable protocol agnostic flow offloading in FDIR
> 
> Protocol agnostic flow offloading in Flow Director is enabled by this patch set
> based on the Parser Library using existing rte_flow raw API.
> 
> [PATCH v9 1/4] net/ice/base: add method to disable FDIR SWAP option.
> [PATCH v9 2/4] net/ice/base: add function to set HW profile for raw flow.
> [PATCH v9 3/4] app/testpmd: update Max RAW pattern size to 512.
> [PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in FDIR.
> 
> Junfeng Guo (4):
>   net/ice/base: add method to disable FDIR SWAP option
>   net/ice/base: add function to set HW profile for raw flow
>   app/testpmd: update Max RAW pattern size to 512
>   net/ice: enable protocol agnostic flow offloading in FDIR
> 
> * v8:
> Added memory free logic.
> 
> * v8:
> Replaced profile info list with a table.
> 
> * v7:
> Fixed LIST_FOR_EACH_ENTRY logic.
> 
> * v6:
> Removed redundant code.
> 
> * v5:
> Optimized some code logic.
> 
> * v4:
> Added list to check inputset conflict.
> 
> * v3:
> Added necessary base code for raw flow in FDIR.
> 
> * v2:
> Enabled vxlan port add for raw flow and updated commit message
> 
>  app/test-pmd/cmdline_flow.c            |   2 +-
>  doc/guides/rel_notes/release_21_11.rst |   1 +
>  drivers/net/ice/base/README            |   2 +-
>  drivers/net/ice/base/ice_flex_pipe.c   |  93 +++++++++-
>  drivers/net/ice/base/ice_flex_pipe.h   |   6 +-
>  drivers/net/ice/base/ice_flow.c        |  86 ++++++++-
>  drivers/net/ice/base/ice_flow.h        |   4 +
>  drivers/net/ice/ice_ethdev.h           |  14 ++
>  drivers/net/ice/ice_fdir_filter.c      | 231 +++++++++++++++++++++++++
>  drivers/net/ice/ice_generic_flow.c     |   7 +
>  drivers/net/ice/ice_generic_flow.h     |   3 +
>  11 files changed, 443 insertions(+), 6 deletions(-)
> 
> --
> 2.25.1

Acked-by: Qi Zhang <qi.z.zhang@intel.com>

Applied to dpdk-next-net-intel.

Thanks
Qi


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

* Re: [dpdk-dev] [PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-11-02 16:22                                   ` Ferruh Yigit
  2021-11-03  2:26                                     ` Guo, Junfeng
  2021-11-03  4:39                                   ` [dpdk-dev] [PATCH v10 0/4] " Junfeng Guo
  1 sibling, 1 reply; 68+ messages in thread
From: Ferruh Yigit @ 2021-11-02 16:22 UTC (permalink / raw)
  To: Junfeng Guo, qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ting.xu

On 11/2/2021 5:39 AM, Junfeng Guo wrote:
> @@ -1733,6 +1862,101 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
>   			    &input_set_i : &input_set_o;
>   
>   		switch (item_type) {
> +		case RTE_FLOW_ITEM_TYPE_RAW:
> +			raw_spec = item->spec;
> +			raw_mask = item->mask;
> +
> +			if (item_num != 1)
> +				break;
> +
> +			/* convert raw spec & mask from byte string to int */
> +			unsigned char *tmp_spec =
> +				(uint8_t *)(uintptr_t)raw_spec->pattern;
> +			unsigned char *tmp_mask =
> +				(uint8_t *)(uintptr_t)raw_mask->pattern;
> +			uint16_t udp_port = 0;
> +			uint16_t tmp_val = 0;
> +			uint8_t pkt_len = 0;
> +			uint8_t tmp = 0;
> +			int i, j;


Hi Junfeng, Qi, Jingjing, Beilei,

This is causing build error with icc.

Mainly the problem is switch case doesn't provide a scope, in C they
are just like labels. So these variables are valid for all switch statement
and compiler complains that some cases are not initializing these variables.

Can you please either:
1- move these variables above switch
2- Create a scope after 'case' with '{}'

2 can be done as:
case RTE_FLOW_ITEM_TYPE_RAW: {
	<...>
	break;
}

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

* Re: [dpdk-dev] [PATCH v9 0/4] enable protocol agnostic flow offloading in FDIR
  2021-11-02  5:39                               ` [dpdk-dev] [PATCH v9 0/4] " Junfeng Guo
                                                   ` (4 preceding siblings ...)
  2021-11-02  5:58                                 ` [dpdk-dev] [PATCH v9 " Zhang, Qi Z
@ 2021-11-02 16:29                                 ` Ferruh Yigit
  2021-11-03  3:16                                   ` Guo, Junfeng
  5 siblings, 1 reply; 68+ messages in thread
From: Ferruh Yigit @ 2021-11-02 16:29 UTC (permalink / raw)
  To: Junfeng Guo, qi.z.zhang, jingjing.wu, beilei.xing; +Cc: dev, ting.xu

On 11/2/2021 5:39 AM, Junfeng Guo wrote:
> Protocol agnostic flow offloading in Flow Director is enabled by this
> patch set based on the Parser Library using existing rte_flow raw API.
> 
> [PATCH v9 1/4] net/ice/base: add method to disable FDIR SWAP option.
> [PATCH v9 2/4] net/ice/base: add function to set HW profile for raw flow.
> [PATCH v9 3/4] app/testpmd: update Max RAW pattern size to 512.
> [PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in FDIR.
> 
> Junfeng Guo (4):
>    net/ice/base: add method to disable FDIR SWAP option
>    net/ice/base: add function to set HW profile for raw flow
>    app/testpmd: update Max RAW pattern size to 512
>    net/ice: enable protocol agnostic flow offloading in FDIR

Hi Junfeng,

Since there will be a new version, can you please fix following too?

$ ./devtools/check-doc-vs-code.sh
rte_flow doc out of sync for ice
         item raw

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

* Re: [dpdk-dev] [PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-11-02 16:22                                   ` Ferruh Yigit
@ 2021-11-03  2:26                                     ` Guo, Junfeng
  0 siblings, 0 replies; 68+ messages in thread
From: Guo, Junfeng @ 2021-11-03  2:26 UTC (permalink / raw)
  To: Yigit, Ferruh, Zhang, Qi Z, Wu, Jingjing, Xing, Beilei; +Cc: dev, Xu, Ting



> -----Original Message-----
> From: Yigit, Ferruh <ferruh.yigit@intel.com>
> Sent: Wednesday, November 3, 2021 00:23
> To: Guo, Junfeng <junfeng.guo@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Xing,
> Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Xu, Ting <Ting.Xu@intel.com>
> Subject: Re: [PATCH v9 4/4] net/ice: enable protocol agnostic flow
> offloading in FDIR
> 
> On 11/2/2021 5:39 AM, Junfeng Guo wrote:
> > @@ -1733,6 +1862,101 @@ ice_fdir_parse_pattern(__rte_unused
> struct ice_adapter *ad,
> >   			    &input_set_i : &input_set_o;
> >
> >   		switch (item_type) {
> > +		case RTE_FLOW_ITEM_TYPE_RAW:
> > +			raw_spec = item->spec;
> > +			raw_mask = item->mask;
> > +
> > +			if (item_num != 1)
> > +				break;
> > +
> > +			/* convert raw spec & mask from byte string to
> int */
> > +			unsigned char *tmp_spec =
> > +				(uint8_t *)(uintptr_t)raw_spec->pattern;
> > +			unsigned char *tmp_mask =
> > +				(uint8_t *)(uintptr_t)raw_mask->pattern;
> > +			uint16_t udp_port = 0;
> > +			uint16_t tmp_val = 0;
> > +			uint8_t pkt_len = 0;
> > +			uint8_t tmp = 0;
> > +			int i, j;
> 
> 
> Hi Junfeng, Qi, Jingjing, Beilei,
> 
> This is causing build error with icc.
> 
> Mainly the problem is switch case doesn't provide a scope, in C they
> are just like labels. So these variables are valid for all switch statement
> and compiler complains that some cases are not initializing these
> variables.
> 
> Can you please either:
> 1- move these variables above switch
> 2- Create a scope after 'case' with '{}'
> 
> 2 can be done as:
> case RTE_FLOW_ITEM_TYPE_RAW: {
> 	<...>
> 	break;
> }

Sure, will enclose these code with curly brackets. Thanks for the solution!

Regards,
Junfeng Guo

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

* Re: [dpdk-dev] [PATCH v9 0/4] enable protocol agnostic flow offloading in FDIR
  2021-11-02 16:29                                 ` Ferruh Yigit
@ 2021-11-03  3:16                                   ` Guo, Junfeng
  0 siblings, 0 replies; 68+ messages in thread
From: Guo, Junfeng @ 2021-11-03  3:16 UTC (permalink / raw)
  To: Yigit, Ferruh, Zhang, Qi Z, Wu, Jingjing, Xing, Beilei; +Cc: dev, Xu, Ting



> -----Original Message-----
> From: Yigit, Ferruh <ferruh.yigit@intel.com>
> Sent: Wednesday, November 3, 2021 00:29
> To: Guo, Junfeng <junfeng.guo@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Xing,
> Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Xu, Ting <Ting.Xu@intel.com>
> Subject: Re: [PATCH v9 0/4] enable protocol agnostic flow offloading in
> FDIR
> 
> On 11/2/2021 5:39 AM, Junfeng Guo wrote:
> > Protocol agnostic flow offloading in Flow Director is enabled by this
> > patch set based on the Parser Library using existing rte_flow raw API.
> >
> > [PATCH v9 1/4] net/ice/base: add method to disable FDIR SWAP option.
> > [PATCH v9 2/4] net/ice/base: add function to set HW profile for raw
> flow.
> > [PATCH v9 3/4] app/testpmd: update Max RAW pattern size to 512.
> > [PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in
> FDIR.
> >
> > Junfeng Guo (4):
> >    net/ice/base: add method to disable FDIR SWAP option
> >    net/ice/base: add function to set HW profile for raw flow
> >    app/testpmd: update Max RAW pattern size to 512
> >    net/ice: enable protocol agnostic flow offloading in FDIR
> 
> Hi Junfeng,
> 
> Since there will be a new version, can you please fix following too?
> 
> $ ./devtools/check-doc-vs-code.sh
> rte_flow doc out of sync for ice
>          item raw

Fixed in the coming patch set, thanks for your careful review!

Regards,
Junfeng Guo

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

* [dpdk-dev] [PATCH v10 0/4] enable protocol agnostic flow offloading in FDIR
  2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-11-02 16:22                                   ` Ferruh Yigit
@ 2021-11-03  4:39                                   ` Junfeng Guo
  2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
                                                       ` (4 more replies)
  1 sibling, 5 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-03  4:39 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch set based on the Parser Library using existing rte_flow raw API.

[PATCH v10 1/4] net/ice/base: add method to disable FDIR SWAP option.
[PATCH v10 2/4] net/ice/base: add function to set HW profile for raw flow.
[PATCH v10 3/4] app/testpmd: update Max RAW pattern size to 512.
[PATCH v10 4/4] net/ice: enable protocol agnostic flow offloading in FDIR.

Junfeng Guo (4):
  net/ice/base: add method to disable FDIR SWAP option
  net/ice/base: add function to set HW profile for raw flow
  app/testpmd: update Max RAW pattern size to 512
  net/ice: enable protocol agnostic flow offloading in FDIR

* v10:
Fixed ICC build issue.

* v9:
Added memory free logic.

* v8:
Replaced profile info list with a table.

* v7:
Fixed LIST_FOR_EACH_ENTRY logic.

* v6:
Removed redundant code.

* v5:
Optimized some code logic.

* v4:
Added list to check inputset conflict.

* v3:
Added necessary base code for raw flow in FDIR.

* v2:
Enabled vxlan port add for raw flow and updated commit message

 app/test-pmd/cmdline_flow.c            |   2 +-
 doc/guides/nics/features/ice.ini       |   1 +
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/base/README            |   2 +-
 drivers/net/ice/base/ice_flex_pipe.c   |  93 +++++++++-
 drivers/net/ice/base/ice_flex_pipe.h   |   6 +-
 drivers/net/ice/base/ice_flow.c        |  86 ++++++++-
 drivers/net/ice/base/ice_flow.h        |   4 +
 drivers/net/ice/ice_ethdev.h           |  14 ++
 drivers/net/ice/ice_fdir_filter.c      | 237 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 12 files changed, 450 insertions(+), 6 deletions(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH v10 1/4] net/ice/base: add method to disable FDIR SWAP option
  2021-11-03  4:39                                   ` [dpdk-dev] [PATCH v10 0/4] " Junfeng Guo
@ 2021-11-03  4:40                                     ` Junfeng Guo
  2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
                                                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-03  4:40 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

In this patch, we introduced a new parameter to enable/disable the
FDIR SWAP option by setting the swap and inset register set with
certain values.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
---
 drivers/net/ice/base/ice_flex_pipe.c | 44 ++++++++++++++++++++++++++--
 drivers/net/ice/base/ice_flex_pipe.h |  3 +-
 drivers/net/ice/base/ice_flow.c      |  2 +-
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index f35d59f4f5..06a233990f 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -4952,6 +4952,43 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 	return ICE_SUCCESS;
 }
 
+/**
+ * ice_disable_fd_swap - set register appropriately to disable FD swap
+ * @hw: pointer to the HW struct
+ * @prof_id: profile ID
+ */
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id)
+{
+	u8 swap_val = ICE_SWAP_VALID;
+	u8 i;
+	/* Since the SWAP Flag in the Programming Desc doesn't work,
+	 * here add method to disable the SWAP Option via setting
+	 * certain SWAP and INSET register set.
+	 */
+	for (i = 0; i < hw->blk[ICE_BLK_FD].es.fvw / 4; i++) {
+		u32 raw_swap = 0;
+		u32 raw_in = 0;
+		u8 j;
+
+		for (j = 0; j < 4; j++) {
+			raw_swap |= (swap_val++) << (j * BITS_PER_BYTE);
+			raw_in |= ICE_INSET_DFLT << (j * BITS_PER_BYTE);
+		}
+
+		/* write the FDIR swap register set */
+		wr32(hw, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		ice_debug(hw, ICE_DBG_INIT, "swap wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDSWAP(prof_id, i), raw_swap);
+
+		/* write the FDIR inset register set */
+		wr32(hw, GLQF_FDINSET(prof_id, i), raw_in);
+
+		ice_debug(hw, ICE_DBG_INIT, "inset wr(%d, %d): %x = %08x\n",
+				prof_id, i, GLQF_FDINSET(prof_id, i), raw_in);
+	}
+}
+
 /**
  * ice_add_prof - add profile
  * @hw: pointer to the HW struct
@@ -4962,6 +4999,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
  * @attr_cnt: number of elements in attrib array
  * @es: extraction sequence (length of array is determined by the block)
  * @masks: mask for extraction sequence
+ * @fd_swap: enable/disable FDIR paired src/dst fields swap option
  *
  * This function registers a profile, which matches a set of PTYPES with a
  * particular extraction sequence. While the hardware profile is allocated
@@ -4971,7 +5009,7 @@ ice_add_prof_attrib(struct ice_prof_map *prof, u8 ptg, u16 ptype,
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks)
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap)
 {
 	u32 bytes = DIVIDE_AND_ROUND_UP(ICE_FLOW_PTYPE_MAX, BITS_PER_BYTE);
 	ice_declare_bitmap(ptgs_used, ICE_XLT1_CNT);
@@ -4991,7 +5029,7 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 		status = ice_alloc_prof_id(hw, blk, &prof_id);
 		if (status)
 			goto err_ice_add_prof;
-		if (blk == ICE_BLK_FD) {
+		if (blk == ICE_BLK_FD && fd_swap) {
 			/* For Flow Director block, the extraction sequence may
 			 * need to be altered in the case where there are paired
 			 * fields that have no match. This is necessary because
@@ -5002,6 +5040,8 @@ ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 			status = ice_update_fd_swap(hw, prof_id, es);
 			if (status)
 				goto err_ice_add_prof;
+		} else if (blk == ICE_BLK_FD) {
+			ice_disable_fd_swap(hw, prof_id);
 		}
 		status = ice_update_prof_masking(hw, blk, prof_id, masks);
 		if (status)
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index 9733c4b214..dd332312dd 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -61,10 +61,11 @@ bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype);
 /* XLT2/VSI group functions */
 enum ice_status
 ice_vsig_find_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 *vsig);
+void ice_disable_fd_swap(struct ice_hw *hw, u16 prof_id);
 enum ice_status
 ice_add_prof(struct ice_hw *hw, enum ice_block blk, u64 id, u8 ptypes[],
 	     const struct ice_ptype_attributes *attr, u16 attr_cnt,
-	     struct ice_fv_word *es, u16 *masks);
+	     struct ice_fv_word *es, u16 *masks, bool fd_swap);
 void ice_init_all_prof_masks(struct ice_hw *hw);
 void ice_shutdown_all_prof_masks(struct ice_hw *hw);
 struct ice_prof_map *
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 96d54b494d..77b6b130c1 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2244,7 +2244,7 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk,
 	/* Add a HW profile for this flow profile */
 	status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes,
 			      params->attr, params->attr_cnt, params->es,
-			      params->mask);
+			      params->mask, true);
 	if (status) {
 		ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n");
 		goto out;
-- 
2.25.1


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

* [dpdk-dev] [PATCH v10 2/4] net/ice/base: add function to set HW profile for raw flow
  2021-11-03  4:39                                   ` [dpdk-dev] [PATCH v10 0/4] " Junfeng Guo
  2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
@ 2021-11-03  4:40                                     ` Junfeng Guo
  2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
                                                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-03  4:40 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Based on the parser library, we can directly set HW profile and
associate the main/ctrl vsi.

This patch set also updated the base code BSD release version.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
---
 drivers/net/ice/base/README          |  2 +-
 drivers/net/ice/base/ice_flex_pipe.c | 49 ++++++++++++++++
 drivers/net/ice/base/ice_flex_pipe.h |  3 +
 drivers/net/ice/base/ice_flow.c      | 84 ++++++++++++++++++++++++++++
 drivers/net/ice/base/ice_flow.h      |  4 ++
 5 files changed, 141 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ice/base/README b/drivers/net/ice/base/README
index 87a1cebfac..8123ec8c30 100644
--- a/drivers/net/ice/base/README
+++ b/drivers/net/ice/base/README
@@ -6,7 +6,7 @@ Intel® ICE driver
 ==================
 
 This directory contains source code of FreeBSD ice driver of version
-2021.04.29 released by the team which develops
+2021.11.02 released by the team which develops
 basic drivers for any ice NIC. The directory of base/ contains the
 original source package.
 This driver is valid for the product(s) listed below
diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c
index 06a233990f..395787806b 100644
--- a/drivers/net/ice/base/ice_flex_pipe.c
+++ b/drivers/net/ice/base/ice_flex_pipe.c
@@ -6365,3 +6365,52 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl)
 
 	return status;
 }
+
+/**
+ * ice_flow_assoc_hw_prof - add profile id flow for main/ctrl VSI flow entry
+ * @hw: pointer to the HW struct
+ * @blk: HW block
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @id: profile id (handle)
+ *
+ * Calling this function will update the hardware tables to enable the
+ * profile indicated by the ID parameter for the VSIs specified in the VSI
+ * array. Once successfully called, the flow will be enabled.
+ */
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id)
+{
+	enum ice_status status = ICE_SUCCESS;
+	u16 vsi_num;
+
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for main VSI flow entry, %d\n",
+			  status);
+		goto err_add_prof;
+	}
+
+	if (blk != ICE_BLK_FD)
+		return status;
+
+	vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi_handle);
+	status = ice_add_prof_id_flow(hw, blk, vsi_num, id);
+	if (status) {
+		ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed for ctrl VSI flow entry, %d\n",
+			  status);
+		goto err_add_entry;
+	}
+
+	return status;
+
+err_add_entry:
+	vsi_num = ice_get_hw_vsi_num(hw, dest_vsi_handle);
+	ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+err_add_prof:
+	ice_flow_rem_prof(hw, blk, id);
+
+	return status;
+}
diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h
index dd332312dd..23ba45564a 100644
--- a/drivers/net/ice/base/ice_flex_pipe.h
+++ b/drivers/net/ice/base/ice_flex_pipe.h
@@ -76,6 +76,9 @@ enum ice_status
 ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 enum ice_status
 ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
+enum ice_status
+ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,
+		       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id);
 enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
 enum ice_status
 ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 77b6b130c1..f699dbbc74 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -2524,6 +2524,90 @@ ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk,
 	return status;
 }
 
+#define FLAG_GTP_EH_PDU_LINK	BIT_ULL(13)
+#define FLAG_GTP_EH_PDU		BIT_ULL(14)
+
+#define FLAG_GTPU_MSK	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_DW	\
+	(FLAG_GTP_EH_PDU | FLAG_GTP_EH_PDU_LINK)
+#define FLAG_GTPU_UP	\
+	(FLAG_GTP_EH_PDU)
+/**
+ * ice_flow_set_hw_prof - Set HW flow profile based on the parsed profile info
+ * @hw: pointer to the HW struct
+ * @dest_vsi_handle: dest VSI handle
+ * @fdir_vsi_handle: fdir programming VSI handle
+ * @prof: stores parsed profile info from raw flow
+ * @blk: classification stage
+ */
+enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk)
+{
+	int id = ice_find_first_bit(prof->ptypes, UINT16_MAX);
+	struct ice_flow_prof_params *params;
+	u8 fv_words = hw->blk[blk].es.fvw;
+	enum ice_status status;
+	u16 vsi_num;
+	int i, idx;
+
+	params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params));
+	if (!params)
+		return ICE_ERR_NO_MEMORY;
+
+	for (i = 0; i < ICE_MAX_FV_WORDS; i++) {
+		params->es[i].prot_id = ICE_PROT_INVALID;
+		params->es[i].off = ICE_FV_OFFSET_INVAL;
+	}
+
+	for (i = 0; i < prof->fv_num; i++) {
+		if (hw->blk[blk].es.reverse)
+			idx = fv_words - i - 1;
+		else
+			idx = i;
+		params->es[idx].prot_id = prof->fv[i].proto_id;
+		params->es[idx].off = prof->fv[i].offset;
+		params->mask[idx] = CPU_TO_BE16(prof->fv[i].msk);
+	}
+
+	switch (prof->flags) {
+	case FLAG_GTPU_DW:
+		params->attr = ice_attr_gtpu_down;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_down);
+		break;
+	case FLAG_GTPU_UP:
+		params->attr = ice_attr_gtpu_up;
+		params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_up);
+		break;
+	default:
+		if (prof->flags_msk & FLAG_GTPU_MSK) {
+			params->attr = ice_attr_gtpu_session;
+			params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session);
+		}
+		break;
+	}
+
+	status = ice_add_prof(hw, blk, id, (u8 *)prof->ptypes,
+			      params->attr, params->attr_cnt,
+			      params->es, params->mask, false);
+	if (status)
+		goto free_params;
+
+	status = ice_flow_assoc_hw_prof(hw, blk, dest_vsi_handle,
+					fdir_vsi_handle, id);
+	if (status)
+		goto free_params;
+
+	return ICE_SUCCESS;
+
+free_params:
+	ice_free(hw, params);
+
+	return status;
+}
+
 /**
  * ice_flow_add_prof - Add a flow profile for packet segments and matched fields
  * @hw: pointer to the HW struct
diff --git a/drivers/net/ice/base/ice_flow.h b/drivers/net/ice/base/ice_flow.h
index 371d960066..dea7b3c0e8 100644
--- a/drivers/net/ice/base/ice_flow.h
+++ b/drivers/net/ice/base/ice_flow.h
@@ -548,6 +548,10 @@ enum ice_status
 ice_flow_assoc_vsig_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi_handle,
 			u16 vsig);
 enum ice_status
+ice_flow_set_hw_prof(struct ice_hw *hw, u16 dest_vsi_handle,
+		     u16 fdir_vsi_handle, struct ice_parser_profile *prof,
+		     enum ice_block blk);
+enum ice_status
 ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id,
 		     u8 *hw_prof);
 
-- 
2.25.1


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

* [dpdk-dev] [PATCH v10 3/4] app/testpmd: update Max RAW pattern size to 512
  2021-11-03  4:39                                   ` [dpdk-dev] [PATCH v10 0/4] " Junfeng Guo
  2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
  2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
@ 2021-11-03  4:40                                     ` Junfeng Guo
  2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
  2021-11-03 12:34                                     ` [dpdk-dev] [PATCH v10 0/4] " Zhang, Qi Z
  4 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-03  4:40 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Update max size for pattern in struct rte_flow_item_raw to enable
protocol agnostic flow offloading.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
Reviewed-by: Qi Zhang <qi.z.zhang@intel.com>
---
 app/test-pmd/cmdline_flow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 24b224e632..0a2205804e 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -495,7 +495,7 @@ enum index {
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
-#define ITEM_RAW_PATTERN_SIZE 40
+#define ITEM_RAW_PATTERN_SIZE 512
 
 /** Maximum size for GENEVE option data pattern in bytes. */
 #define ITEM_GENEVE_OPT_DATA_SIZE 124
-- 
2.25.1


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

* [dpdk-dev] [PATCH v10 4/4] net/ice: enable protocol agnostic flow offloading in FDIR
  2021-11-03  4:39                                   ` [dpdk-dev] [PATCH v10 0/4] " Junfeng Guo
                                                       ` (2 preceding siblings ...)
  2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
@ 2021-11-03  4:40                                     ` Junfeng Guo
  2021-11-03 12:34                                     ` [dpdk-dev] [PATCH v10 0/4] " Zhang, Qi Z
  4 siblings, 0 replies; 68+ messages in thread
From: Junfeng Guo @ 2021-11-03  4:40 UTC (permalink / raw)
  To: qi.z.zhang, jingjing.wu, beilei.xing
  Cc: dev, ferruh.yigit, ting.xu, junfeng.guo

Protocol agnostic flow offloading in Flow Director is enabled by this
patch based on the Parser Library, using existing rte_flow raw API.

Note that the raw flow requires:
1. byte string of raw target packet bits.
2. byte string of mask of target packet.

Here is an example:
FDIR matching ipv4 dst addr with 1.2.3.4 and redirect to queue 3:

flow create 0 ingress pattern raw \
pattern spec \
00000000000000000000000008004500001400004000401000000000000001020304 \
pattern mask \
000000000000000000000000000000000000000000000000000000000000ffffffff \
/ end actions queue index 3 / mark id 3 / end

Note that mask of some key bits (e.g., 0x0800 to indicate ipv4 proto)
is optional in our cases. To avoid redundancy, we just omit the mask
of 0x0800 (with 0xFFFF) in the mask byte string example. The prefix
'0x' for the spec and mask byte (hex) strings are also omitted here.

Also update the ice feature list with rte_flow item raw.

Signed-off-by: Junfeng Guo <junfeng.guo@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
---
 doc/guides/nics/features/ice.ini       |   1 +
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/ice/ice_ethdev.h           |  14 ++
 drivers/net/ice/ice_fdir_filter.c      | 237 +++++++++++++++++++++++++
 drivers/net/ice/ice_generic_flow.c     |   7 +
 drivers/net/ice/ice_generic_flow.h     |   3 +
 6 files changed, 263 insertions(+)

diff --git a/doc/guides/nics/features/ice.ini b/doc/guides/nics/features/ice.ini
index 9fd52fdd22..00ace32398 100644
--- a/doc/guides/nics/features/ice.ini
+++ b/doc/guides/nics/features/ice.ini
@@ -63,6 +63,7 @@ pfcp                 = Y
 pppoed               = Y
 pppoes               = Y
 pppoe_proto_id       = Y
+raw                  = Y
 sctp                 = Y
 tcp                  = Y
 udp                  = Y
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 98d50a160b..36fdee0a98 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -167,6 +167,7 @@ New Features
 
 * **Updated Intel ice driver.**
 
+  * Added protocol agnostic flow offloading support in Flow Director.
   * Added 1PPS out support by a devargs.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
   * Added DEV_RX_OFFLOAD_TIMESTAMP support.
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index 0e42c4c063..d021e7fd0b 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -318,6 +318,11 @@ struct ice_fdir_filter_conf {
 	uint64_t input_set_o; /* used for non-tunnel or tunnel outer fields */
 	uint64_t input_set_i; /* only for tunnel inner fields */
 	uint32_t mark_flag;
+
+	struct ice_parser_profile *prof;
+	bool parser_ena;
+	u8 *pkt_buf;
+	u8 pkt_len;
 };
 
 #define ICE_MAX_FDIR_FILTER_NUM		(1024 * 16)
@@ -487,6 +492,14 @@ struct ice_devargs {
 	uint8_t pps_out_ena;
 };
 
+/**
+ * Structure to store fdir fv entry.
+ */
+struct ice_fdir_prof_info {
+	struct ice_parser_profile prof;
+	u64 fdir_actived_cnt;
+};
+
 /**
  * Structure to store private data for each PF/VF instance.
  */
@@ -510,6 +523,7 @@ struct ice_adapter {
 	struct rte_timecounter tx_tstamp_tc;
 	bool ptp_ena;
 	uint64_t time_hw;
+	struct ice_fdir_prof_info fdir_prof_info[ICE_MAX_PTGS];
 #ifdef RTE_ARCH_X86
 	bool rx_use_avx2;
 	bool rx_use_avx512;
diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
index bd627e3aa8..13a2ac42df 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -107,6 +107,7 @@
 	ICE_INSET_NAT_T_ESP_SPI)
 
 static struct ice_pattern_match_item ice_fdir_pattern_list[] = {
+	{pattern_raw,					ICE_INSET_NONE,			ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_ethertype,				ICE_FDIR_INSET_ETH,		ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4,				ICE_FDIR_INSET_ETH_IPV4,	ICE_INSET_NONE,			ICE_INSET_NONE},
 	{pattern_eth_ipv4_udp,				ICE_FDIR_INSET_ETH_IPV4_UDP,	ICE_INSET_NONE,			ICE_INSET_NONE},
@@ -1188,6 +1189,24 @@ ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type)
 		return 0;
 }
 
+static int
+ice_fdir_add_del_raw(struct ice_pf *pf,
+		     struct ice_fdir_filter_conf *filter,
+		     bool add)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+	unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt;
+	rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len);
+
+	struct ice_fltr_desc desc;
+	memset(&desc, 0, sizeof(desc));
+	filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW;
+	ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add);
+
+	return ice_fdir_programming(pf, &desc);
+}
+
 static int
 ice_fdir_add_del_filter(struct ice_pf *pf,
 			struct ice_fdir_filter_conf *filter,
@@ -1303,6 +1322,68 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 	struct ice_fdir_fltr_pattern key;
 	bool is_tun;
 	int ret;
+	int i;
+
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+		bool fv_found = false;
+
+		struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg];
+		if (pi->fdir_actived_cnt != 0) {
+			for (i = 0; i < ICE_MAX_FV_WORDS; i++)
+				if (pi->prof.fv[i].proto_id !=
+				    filter->prof->fv[i].proto_id ||
+				    pi->prof.fv[i].offset !=
+				    filter->prof->fv[i].offset ||
+				    pi->prof.fv[i].msk !=
+				    filter->prof->fv[i].msk)
+					break;
+			if (i == ICE_MAX_FV_WORDS) {
+				fv_found = true;
+				pi->fdir_actived_cnt++;
+			}
+		}
+
+		if (!fv_found) {
+			ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi,
+						   filter->prof, ICE_BLK_FD);
+			if (ret)
+				goto error;
+		}
+
+		ret = ice_fdir_add_del_raw(pf, filter, true);
+		if (ret)
+			goto error;
+
+		if (!fv_found) {
+			for (i = 0; i < filter->prof->fv_num; i++) {
+				pi->prof.fv[i].proto_id =
+					filter->prof->fv[i].proto_id;
+				pi->prof.fv[i].offset =
+					filter->prof->fv[i].offset;
+				pi->prof.fv[i].msk = filter->prof->fv[i].msk;
+			}
+			pi->fdir_actived_cnt = 1;
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 1);
+
+		entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0);
+		if (!entry)
+			goto error;
+
+		rte_memcpy(entry, filter, sizeof(*filter));
+
+		flow->rule = entry;
+
+		return 0;
+	}
 
 	ice_fdir_extract_fltr_key(&key, filter);
 	node = ice_fdir_entry_lookup(fdir_info, &key);
@@ -1381,6 +1462,11 @@ ice_fdir_create_filter(struct ice_adapter *ad,
 free_entry:
 	rte_free(entry);
 	return -rte_errno;
+
+error:
+	rte_free(filter->prof);
+	rte_free(filter->pkt_buf);
+	return -rte_errno;
 }
 
 static int
@@ -1397,6 +1483,44 @@ ice_fdir_destroy_filter(struct ice_adapter *ad,
 
 	filter = (struct ice_fdir_filter_conf *)flow->rule;
 
+	if (filter->parser_ena) {
+		struct ice_hw *hw = ICE_PF_TO_HW(pf);
+
+		int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX);
+		int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id];
+		u16 ctrl_vsi = pf->fdir.fdir_vsi->idx;
+		u16 main_vsi = pf->main_vsi->idx;
+		enum ice_block blk = ICE_BLK_FD;
+		u16 vsi_num;
+
+		ret = ice_fdir_add_del_raw(pf, filter, false);
+		if (ret)
+			return -rte_errno;
+
+		struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg];
+		if (pi->fdir_actived_cnt != 0) {
+			pi->fdir_actived_cnt--;
+			if (!pi->fdir_actived_cnt) {
+				vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi);
+				ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+
+				vsi_num = ice_get_hw_vsi_num(hw, main_vsi);
+				ice_rem_prof_id_flow(hw, blk, vsi_num, id);
+			}
+		}
+
+		if (filter->mark_flag == 1)
+			ice_fdir_rx_parsing_enable(ad, 0);
+
+		flow->rule = NULL;
+
+		rte_free(filter->prof);
+		rte_free(filter->pkt_buf);
+		rte_free(filter);
+
+		return 0;
+	}
+
 	is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type);
 
 	if (filter->counter) {
@@ -1675,6 +1799,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
 	enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END;
 	enum ice_fdir_tunnel_type tunnel_type = ICE_FDIR_TUNNEL_TYPE_NONE;
+	const struct rte_flow_item_raw *raw_spec, *raw_mask;
 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
@@ -1702,6 +1827,9 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 	struct ice_fdir_extra *p_ext_data;
 	struct ice_fdir_v4 *p_v4 = NULL;
 	struct ice_fdir_v6 *p_v6 = NULL;
+	struct ice_parser_result rslt;
+	struct ice_parser *psr;
+	uint8_t item_num = 0;
 
 	for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
 		if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN)
@@ -1713,6 +1841,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 		    item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) {
 			is_outer = false;
 		}
+		item_num++;
 	}
 
 	/* This loop parse flow pattern and distinguish Non-tunnel and tunnel
@@ -1733,6 +1862,102 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 			    &input_set_i : &input_set_o;
 
 		switch (item_type) {
+		case RTE_FLOW_ITEM_TYPE_RAW: {
+			raw_spec = item->spec;
+			raw_mask = item->mask;
+
+			if (item_num != 1)
+				break;
+
+			/* convert raw spec & mask from byte string to int */
+			unsigned char *tmp_spec =
+				(uint8_t *)(uintptr_t)raw_spec->pattern;
+			unsigned char *tmp_mask =
+				(uint8_t *)(uintptr_t)raw_mask->pattern;
+			uint16_t udp_port = 0;
+			uint16_t tmp_val = 0;
+			uint8_t pkt_len = 0;
+			uint8_t tmp = 0;
+			int i, j;
+
+			pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern);
+			if (strlen((char *)(uintptr_t)raw_mask->pattern) !=
+				pkt_len)
+				return -rte_errno;
+
+			for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
+				tmp = tmp_spec[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_spec[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_spec[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_spec[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_spec[j] = tmp_val + tmp - '0';
+
+				tmp = tmp_mask[i];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_val = tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_val = tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_val = tmp - '0';
+
+				tmp_val *= 16;
+				tmp = tmp_mask[i + 1];
+				if (tmp >= 'a' && tmp <= 'f')
+					tmp_mask[j] = tmp_val + tmp - 'a' + 10;
+				if (tmp >= 'A' && tmp <= 'F')
+					tmp_mask[j] = tmp_val + tmp - 'A' + 10;
+				if (tmp >= '0' && tmp <= '9')
+					tmp_mask[j] = tmp_val + tmp - '0';
+			}
+
+			pkt_len /= 2;
+
+			if (ice_parser_create(&ad->hw, &psr))
+				return -rte_errno;
+			if (ice_get_open_tunnel_port(&ad->hw, TNL_VXLAN,
+						     &udp_port))
+				ice_parser_vxlan_tunnel_set(psr, udp_port,
+							    true);
+			if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt))
+				return -rte_errno;
+			ice_parser_destroy(psr);
+
+			if (!tmp_mask)
+				return -rte_errno;
+
+			filter->prof = (struct ice_parser_profile *)
+				ice_malloc(&ad->hw, sizeof(*filter->prof));
+			if (!filter->prof)
+				return -ENOMEM;
+
+			if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask,
+				pkt_len, ICE_BLK_FD, true, filter->prof))
+				return -rte_errno;
+
+			u8 *pkt_buf = (u8 *)ice_malloc(&ad->hw, pkt_len + 1);
+			if (!pkt_buf)
+				return -ENOMEM;
+			rte_memcpy(pkt_buf, tmp_spec, pkt_len);
+			filter->pkt_buf = pkt_buf;
+
+			filter->pkt_len = pkt_len;
+
+			filter->parser_ena = true;
+
+			break;
+		}
+
 		case RTE_FLOW_ITEM_TYPE_ETH:
 			flow_type = ICE_FLTR_PTYPE_NON_IP_L2;
 			eth_spec = item->spec;
@@ -2198,6 +2423,7 @@ ice_fdir_parse(struct ice_adapter *ad,
 	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
 	struct ice_pattern_match_item *item = NULL;
 	uint64_t input_set;
+	bool raw = false;
 	int ret;
 
 	memset(filter, 0, sizeof(*filter));
@@ -2213,7 +2439,13 @@ ice_fdir_parse(struct ice_adapter *ad,
 	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
 	if (ret)
 		goto error;
+
+	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
+		raw = true;
+
 	input_set = filter->input_set_o | filter->input_set_i;
+	input_set = raw ? ~input_set : input_set;
+
 	if (!input_set || filter->input_set_o &
 	    ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) ||
 	    filter->input_set_i & ~item->input_set_mask_i) {
@@ -2231,7 +2463,12 @@ ice_fdir_parse(struct ice_adapter *ad,
 
 	if (meta)
 		*meta = filter;
+
+	rte_free(item);
+	return ret;
 error:
+	rte_free(filter->prof);
+	rte_free(filter->pkt_buf);
 	rte_free(item);
 	return ret;
 }
diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 02f854666a..d3391c86c0 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -65,6 +65,12 @@ enum rte_flow_item_type pattern_empty[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* raw */
+enum rte_flow_item_type pattern_raw[] = {
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 /* L2 */
 enum rte_flow_item_type pattern_ethertype[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
@@ -2081,6 +2087,7 @@ struct ice_ptype_match {
 };
 
 static struct ice_ptype_match ice_ptype_map[] = {
+	{pattern_raw,					ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4,				ICE_PTYPE_IPV4_PAY},
 	{pattern_eth_ipv4_udp,				ICE_PTYPE_IPV4_UDP_PAY},
 	{pattern_eth_ipv4_tcp,				ICE_PTYPE_IPV4_TCP_PAY},
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index 8845a3e156..1b030c0466 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -124,6 +124,9 @@
 /* empty pattern */
 extern enum rte_flow_item_type pattern_empty[];
 
+/* raw pattern */
+extern enum rte_flow_item_type pattern_raw[];
+
 /* L2 */
 extern enum rte_flow_item_type pattern_ethertype[];
 extern enum rte_flow_item_type pattern_ethertype_vlan[];
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v10 0/4] enable protocol agnostic flow offloading in FDIR
  2021-11-03  4:39                                   ` [dpdk-dev] [PATCH v10 0/4] " Junfeng Guo
                                                       ` (3 preceding siblings ...)
  2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
@ 2021-11-03 12:34                                     ` Zhang, Qi Z
  4 siblings, 0 replies; 68+ messages in thread
From: Zhang, Qi Z @ 2021-11-03 12:34 UTC (permalink / raw)
  To: Guo, Junfeng, Wu, Jingjing, Xing, Beilei; +Cc: dev, Yigit, Ferruh, Xu, Ting



> -----Original Message-----
> From: Guo, Junfeng <junfeng.guo@intel.com>
> Sent: Wednesday, November 3, 2021 12:40 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Xu, Ting
> <ting.xu@intel.com>; Guo, Junfeng <junfeng.guo@intel.com>
> Subject: [PATCH v10 0/4] enable protocol agnostic flow offloading in FDIR
> 
> Protocol agnostic flow offloading in Flow Director is enabled by this patch set
> based on the Parser Library using existing rte_flow raw API.
> 
> [PATCH v10 1/4] net/ice/base: add method to disable FDIR SWAP option.
> [PATCH v10 2/4] net/ice/base: add function to set HW profile for raw flow.
> [PATCH v10 3/4] app/testpmd: update Max RAW pattern size to 512.
> [PATCH v10 4/4] net/ice: enable protocol agnostic flow offloading in FDIR.
> 
> Junfeng Guo (4):
>   net/ice/base: add method to disable FDIR SWAP option
>   net/ice/base: add function to set HW profile for raw flow
>   app/testpmd: update Max RAW pattern size to 512
>   net/ice: enable protocol agnostic flow offloading in FDIR
> 
> * v10:
> Fixed ICC build issue.
> 
> * v9:
> Added memory free logic.
> 
> * v8:
> Replaced profile info list with a table.
> 
> * v7:
> Fixed LIST_FOR_EACH_ENTRY logic.
> 
> * v6:
> Removed redundant code.
> 
> * v5:
> Optimized some code logic.
> 
> * v4:
> Added list to check inputset conflict.
> 
> * v3:
> Added necessary base code for raw flow in FDIR.
> 
> * v2:
> Enabled vxlan port add for raw flow and updated commit message
> 
>  app/test-pmd/cmdline_flow.c            |   2 +-
>  doc/guides/nics/features/ice.ini       |   1 +
>  doc/guides/rel_notes/release_21_11.rst |   1 +
>  drivers/net/ice/base/README            |   2 +-
>  drivers/net/ice/base/ice_flex_pipe.c   |  93 +++++++++-
>  drivers/net/ice/base/ice_flex_pipe.h   |   6 +-
>  drivers/net/ice/base/ice_flow.c        |  86 ++++++++-
>  drivers/net/ice/base/ice_flow.h        |   4 +
>  drivers/net/ice/ice_ethdev.h           |  14 ++
>  drivers/net/ice/ice_fdir_filter.c      | 237 +++++++++++++++++++++++++
>  drivers/net/ice/ice_generic_flow.c     |   7 +
>  drivers/net/ice/ice_generic_flow.h     |   3 +
>  12 files changed, 450 insertions(+), 6 deletions(-)
> 
> --
> 2.25.1

Applied to dpdk-next-net-intel.

Thanks
Qi


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

end of thread, other threads:[~2021-11-03 12:35 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-24 16:22 [dpdk-dev] [PATCH 0/3] enable protocol agnostic flow offloading in FDIR Junfeng Guo
2021-09-24 16:22 ` [dpdk-dev] [PATCH 1/3] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
2021-09-28 10:18   ` [dpdk-dev] [PATCH v2 0/3] enable protocol agnostic flow offloading in FDIR Junfeng Guo
2021-09-28 10:18     ` [dpdk-dev] [PATCH v2 1/3] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
2021-09-28 10:18     ` [dpdk-dev] [PATCH v2 2/3] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
2021-09-28 10:18     ` [dpdk-dev] [PATCH v2 3/3] doc: enable protocol agnostic flow " Junfeng Guo
2021-10-14 15:37       ` [dpdk-dev] [PATCH v3 0/5] enable protocol agnostic flow offloading " Junfeng Guo
2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 1/5] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 2/5] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 3/5] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 4/5] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
2021-10-14 15:37         ` [dpdk-dev] [PATCH v3 5/5] doc: enable protocol agnostic flow " Junfeng Guo
2021-10-26 12:00           ` [dpdk-dev] [PATCH v4 0/4] enable protocol agnostic flow offloading " Junfeng Guo
2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
2021-10-27  0:58               ` Zhang, Qi Z
2021-10-27  1:58                 ` Guo, Junfeng
2021-10-27  2:17                   ` Zhang, Qi Z
2021-10-27  2:51                     ` Guo, Junfeng
2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
2021-10-27  2:52               ` [dpdk-dev] [PATCH v5 0/4] enable protocol agnostic flow offloading in FDIR Junfeng Guo
2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
2021-10-27  2:52                 ` [dpdk-dev] [PATCH v5 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
2021-10-28  8:34                   ` [dpdk-dev] [PATCH v6 0/4] " Junfeng Guo
2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
2021-10-28  8:34                     ` [dpdk-dev] [PATCH v6 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
2021-10-28  9:13                       ` [dpdk-dev] [PATCH v7 0/4] " Junfeng Guo
2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
2021-10-28 11:26                           ` Zhang, Qi Z
2021-10-28 15:09                           ` Ferruh Yigit
2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
2021-10-28 11:28                           ` Zhang, Qi Z
2021-10-28 15:13                           ` Ferruh Yigit
2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
2021-10-28 11:46                           ` Zhang, Qi Z
2021-10-28  9:13                         ` [dpdk-dev] [PATCH v7 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
2021-10-28 11:10                           ` Zhang, Qi Z
2021-11-01  8:36                           ` [dpdk-dev] [PATCH v8 0/4] " Junfeng Guo
2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
2021-11-01  8:36                             ` [dpdk-dev] [PATCH v8 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
2021-11-01 23:56                               ` Zhang, Qi Z
2021-11-02  2:44                                 ` Guo, Junfeng
2021-11-02  5:39                               ` [dpdk-dev] [PATCH v9 0/4] " Junfeng Guo
2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
2021-11-02  5:39                                 ` [dpdk-dev] [PATCH v9 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
2021-11-02 16:22                                   ` Ferruh Yigit
2021-11-03  2:26                                     ` Guo, Junfeng
2021-11-03  4:39                                   ` [dpdk-dev] [PATCH v10 0/4] " Junfeng Guo
2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 1/4] net/ice/base: add method to disable FDIR SWAP option Junfeng Guo
2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 2/4] net/ice/base: add function to set HW profile for raw flow Junfeng Guo
2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 3/4] app/testpmd: update Max RAW pattern size to 512 Junfeng Guo
2021-11-03  4:40                                     ` [dpdk-dev] [PATCH v10 4/4] net/ice: enable protocol agnostic flow offloading in FDIR Junfeng Guo
2021-11-03 12:34                                     ` [dpdk-dev] [PATCH v10 0/4] " Zhang, Qi Z
2021-11-02  5:58                                 ` [dpdk-dev] [PATCH v9 " Zhang, Qi Z
2021-11-02 16:29                                 ` Ferruh Yigit
2021-11-03  3:16                                   ` Guo, Junfeng
2021-10-26 12:00             ` [dpdk-dev] [PATCH v4 4/4] net/ice: " Junfeng Guo
2021-09-24 16:22 ` [dpdk-dev] [PATCH 2/3] " Junfeng Guo
2021-09-24  8:45   ` Van Haaren, Harry
2021-09-24 16:22 ` [dpdk-dev] [PATCH 3/3] doc: enable protocol agnostic flow " Junfeng Guo

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.