xref: /dpdk/drivers/net/dpaa2/dpaa2_flow.c (revision e6bf3256b95c77ee4d0b2874e1896d01c41c2d7c)
15f176728SJun Yang /* SPDX-License-Identifier: BSD-3-Clause
256c1817dSJun Yang  * Copyright 2018-2022 NXP
3fe2b986aSSunil Kumar Kori  */
4fe2b986aSSunil Kumar Kori 
5fe2b986aSSunil Kumar Kori #include <sys/queue.h>
6fe2b986aSSunil Kumar Kori #include <stdio.h>
7fe2b986aSSunil Kumar Kori #include <errno.h>
8fe2b986aSSunil Kumar Kori #include <stdint.h>
9fe2b986aSSunil Kumar Kori #include <string.h>
10fe2b986aSSunil Kumar Kori #include <unistd.h>
11fe2b986aSSunil Kumar Kori #include <stdarg.h>
1299400780SJun Yang #include <sys/mman.h>
13fe2b986aSSunil Kumar Kori 
14fe2b986aSSunil Kumar Kori #include <rte_ethdev.h>
15fe2b986aSSunil Kumar Kori #include <rte_log.h>
16fe2b986aSSunil Kumar Kori #include <rte_malloc.h>
17fe2b986aSSunil Kumar Kori #include <rte_flow_driver.h>
18fe2b986aSSunil Kumar Kori #include <rte_tailq.h>
19fe2b986aSSunil Kumar Kori 
20fe2b986aSSunil Kumar Kori #include <fsl_dpni.h>
21fe2b986aSSunil Kumar Kori #include <fsl_dpkg.h>
22fe2b986aSSunil Kumar Kori 
23fe2b986aSSunil Kumar Kori #include <dpaa2_ethdev.h>
24fe2b986aSSunil Kumar Kori #include <dpaa2_pmd_logs.h>
25fe2b986aSSunil Kumar Kori 
26f5ed2ea0SJun Yang static char *dpaa2_flow_control_log;
27068be45fSRohit Raj static uint16_t dpaa2_flow_miss_flow_id; /* Default miss flow id is 0. */
2899400780SJun Yang static int dpaa2_sp_loaded = -1;
29f5ed2ea0SJun Yang 
3056c1817dSJun Yang enum dpaa2_flow_entry_size {
3156c1817dSJun Yang 	DPAA2_FLOW_ENTRY_MIN_SIZE = (DPNI_MAX_KEY_SIZE / 2),
3256c1817dSJun Yang 	DPAA2_FLOW_ENTRY_MAX_SIZE = DPNI_MAX_KEY_SIZE
335f176728SJun Yang };
345f176728SJun Yang 
3556c1817dSJun Yang enum dpaa2_flow_dist_type {
3656c1817dSJun Yang 	DPAA2_FLOW_QOS_TYPE = 1 << 0,
3756c1817dSJun Yang 	DPAA2_FLOW_FS_TYPE = 1 << 1
385f176728SJun Yang };
395f176728SJun Yang 
4056c1817dSJun Yang #define DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT	16
4156c1817dSJun Yang #define DPAA2_FLOW_MAX_KEY_SIZE			16
42146c745eSJun Yang #define DPAA2_PROT_FIELD_STRING_SIZE		16
4339c8044fSJun Yang #define VXLAN_HF_VNI 0x08
4439c8044fSJun Yang 
4556c1817dSJun Yang struct dpaa2_dev_flow {
4656c1817dSJun Yang 	LIST_ENTRY(dpaa2_dev_flow) next;
475f176728SJun Yang 	struct dpni_rule_cfg qos_rule;
4856c1817dSJun Yang 	uint8_t *qos_key_addr;
4956c1817dSJun Yang 	uint8_t *qos_mask_addr;
5056c1817dSJun Yang 	uint16_t qos_rule_size;
515f176728SJun Yang 	struct dpni_rule_cfg fs_rule;
52d0a77dc3SJun Yang 	uint8_t qos_real_key_size;
53d0a77dc3SJun Yang 	uint8_t fs_real_key_size;
5456c1817dSJun Yang 	uint8_t *fs_key_addr;
5556c1817dSJun Yang 	uint8_t *fs_mask_addr;
5656c1817dSJun Yang 	uint16_t fs_rule_size;
575f176728SJun Yang 	uint8_t tc_id; /** Traffic Class ID. */
585f176728SJun Yang 	uint8_t tc_index; /** index within this Traffic Class. */
5956c1817dSJun Yang 	enum rte_flow_action_type action_type;
6056c1817dSJun Yang 	struct dpni_fs_action_cfg fs_action_cfg;
61fe2b986aSSunil Kumar Kori };
62fe2b986aSSunil Kumar Kori 
639ec29343SJun Yang struct rte_dpaa2_flow_item {
649ec29343SJun Yang 	struct rte_flow_item generic_item;
659ec29343SJun Yang 	int in_tunnel;
669ec29343SJun Yang };
679ec29343SJun Yang 
68fe2b986aSSunil Kumar Kori static const
691cf6d181SJun Yang enum rte_flow_item_type dpaa2_hp_supported_pattern_type[] = {
70fe2b986aSSunil Kumar Kori 	RTE_FLOW_ITEM_TYPE_END,
71fe2b986aSSunil Kumar Kori 	RTE_FLOW_ITEM_TYPE_ETH,
72fe2b986aSSunil Kumar Kori 	RTE_FLOW_ITEM_TYPE_VLAN,
73fe2b986aSSunil Kumar Kori 	RTE_FLOW_ITEM_TYPE_IPV4,
74fe2b986aSSunil Kumar Kori 	RTE_FLOW_ITEM_TYPE_IPV6,
75fe2b986aSSunil Kumar Kori 	RTE_FLOW_ITEM_TYPE_ICMP,
76fe2b986aSSunil Kumar Kori 	RTE_FLOW_ITEM_TYPE_UDP,
77fe2b986aSSunil Kumar Kori 	RTE_FLOW_ITEM_TYPE_TCP,
78fe2b986aSSunil Kumar Kori 	RTE_FLOW_ITEM_TYPE_SCTP,
79fe2b986aSSunil Kumar Kori 	RTE_FLOW_ITEM_TYPE_GRE,
801cf6d181SJun Yang 	RTE_FLOW_ITEM_TYPE_GTP,
814cc5cf4aSJun Yang 	RTE_FLOW_ITEM_TYPE_ESP,
824cc5cf4aSJun Yang 	RTE_FLOW_ITEM_TYPE_AH,
831cf6d181SJun Yang 	RTE_FLOW_ITEM_TYPE_RAW
841cf6d181SJun Yang };
851cf6d181SJun Yang 
861cf6d181SJun Yang static const
871cf6d181SJun Yang enum rte_flow_item_type dpaa2_sp_supported_pattern_type[] = {
881cf6d181SJun Yang 	RTE_FLOW_ITEM_TYPE_VXLAN,
891cf6d181SJun Yang 	RTE_FLOW_ITEM_TYPE_ECPRI
90fe2b986aSSunil Kumar Kori };
91fe2b986aSSunil Kumar Kori 
92fe2b986aSSunil Kumar Kori static const
93fe2b986aSSunil Kumar Kori enum rte_flow_action_type dpaa2_supported_action_type[] = {
94fe2b986aSSunil Kumar Kori 	RTE_FLOW_ACTION_TYPE_END,
95fe2b986aSSunil Kumar Kori 	RTE_FLOW_ACTION_TYPE_QUEUE,
96028d1dfdSJun Yang 	RTE_FLOW_ACTION_TYPE_PORT_ID,
97b1e15294SIvan Malov 	RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT,
98fe2b986aSSunil Kumar Kori 	RTE_FLOW_ACTION_TYPE_RSS
99fe2b986aSSunil Kumar Kori };
100fe2b986aSSunil Kumar Kori 
101926c1279SJun Yang #ifndef __cplusplus
102926c1279SJun Yang static const struct rte_flow_item_eth dpaa2_flow_item_eth_mask = {
103e0d947a1SFerruh Yigit 	.hdr.dst_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
104e0d947a1SFerruh Yigit 	.hdr.src_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
1058275d5fcSThomas Monjalon 	.hdr.ether_type = RTE_BE16(0xffff),
106926c1279SJun Yang };
107926c1279SJun Yang 
108926c1279SJun Yang static const struct rte_flow_item_vlan dpaa2_flow_item_vlan_mask = {
1098275d5fcSThomas Monjalon 	.hdr.vlan_tci = RTE_BE16(0xffff),
110926c1279SJun Yang };
111926c1279SJun Yang 
112926c1279SJun Yang static const struct rte_flow_item_ipv4 dpaa2_flow_item_ipv4_mask = {
113926c1279SJun Yang 	.hdr.src_addr = RTE_BE32(0xffffffff),
114926c1279SJun Yang 	.hdr.dst_addr = RTE_BE32(0xffffffff),
115926c1279SJun Yang 	.hdr.next_proto_id = 0xff,
116926c1279SJun Yang };
117926c1279SJun Yang 
118926c1279SJun Yang static const struct rte_flow_item_ipv6 dpaa2_flow_item_ipv6_mask = {
119926c1279SJun Yang 	.hdr = {
12089b5642dSRobin Jarry 		.src_addr = RTE_IPV6_MASK_FULL,
12189b5642dSRobin Jarry 		.dst_addr = RTE_IPV6_MASK_FULL,
122926c1279SJun Yang 		.proto = 0xff
123926c1279SJun Yang 	},
124926c1279SJun Yang };
125926c1279SJun Yang 
126926c1279SJun Yang static const struct rte_flow_item_icmp dpaa2_flow_item_icmp_mask = {
127926c1279SJun Yang 	.hdr.icmp_type = 0xff,
128926c1279SJun Yang 	.hdr.icmp_code = 0xff,
129926c1279SJun Yang };
130926c1279SJun Yang 
131926c1279SJun Yang static const struct rte_flow_item_udp dpaa2_flow_item_udp_mask = {
132926c1279SJun Yang 	.hdr = {
133926c1279SJun Yang 		.src_port = RTE_BE16(0xffff),
134926c1279SJun Yang 		.dst_port = RTE_BE16(0xffff),
135926c1279SJun Yang 	},
136926c1279SJun Yang };
137926c1279SJun Yang 
138926c1279SJun Yang static const struct rte_flow_item_tcp dpaa2_flow_item_tcp_mask = {
139926c1279SJun Yang 	.hdr = {
140926c1279SJun Yang 		.src_port = RTE_BE16(0xffff),
141926c1279SJun Yang 		.dst_port = RTE_BE16(0xffff),
142926c1279SJun Yang 	},
143926c1279SJun Yang };
144926c1279SJun Yang 
145926c1279SJun Yang static const struct rte_flow_item_sctp dpaa2_flow_item_sctp_mask = {
146926c1279SJun Yang 	.hdr = {
147926c1279SJun Yang 		.src_port = RTE_BE16(0xffff),
148926c1279SJun Yang 		.dst_port = RTE_BE16(0xffff),
149926c1279SJun Yang 	},
150926c1279SJun Yang };
151926c1279SJun Yang 
1524cc5cf4aSJun Yang static const struct rte_flow_item_esp dpaa2_flow_item_esp_mask = {
1534cc5cf4aSJun Yang 	.hdr = {
1544cc5cf4aSJun Yang 		.spi = RTE_BE32(0xffffffff),
1554cc5cf4aSJun Yang 		.seq = RTE_BE32(0xffffffff),
1564cc5cf4aSJun Yang 	},
1574cc5cf4aSJun Yang };
1584cc5cf4aSJun Yang 
1594cc5cf4aSJun Yang static const struct rte_flow_item_ah dpaa2_flow_item_ah_mask = {
1604cc5cf4aSJun Yang 	.spi = RTE_BE32(0xffffffff),
1614cc5cf4aSJun Yang };
1624cc5cf4aSJun Yang 
163926c1279SJun Yang static const struct rte_flow_item_gre dpaa2_flow_item_gre_mask = {
164926c1279SJun Yang 	.protocol = RTE_BE16(0xffff),
165926c1279SJun Yang };
16639c8044fSJun Yang 
16739c8044fSJun Yang static const struct rte_flow_item_vxlan dpaa2_flow_item_vxlan_mask = {
16839c8044fSJun Yang 	.flags = 0xff,
169*11f84bf4SStephen Hemminger 	.vni = { 0xff, 0xff, 0xff },
17039c8044fSJun Yang };
171a8a6b82eSJun Yang 
172a8a6b82eSJun Yang static const struct rte_flow_item_ecpri dpaa2_flow_item_ecpri_mask = {
173a8a6b82eSJun Yang 	.hdr.common.type = 0xff,
174a8a6b82eSJun Yang 	.hdr.dummy[0] = RTE_BE32(0xffffffff),
175a8a6b82eSJun Yang 	.hdr.dummy[1] = RTE_BE32(0xffffffff),
176a8a6b82eSJun Yang 	.hdr.dummy[2] = RTE_BE32(0xffffffff),
177a8a6b82eSJun Yang };
178146c745eSJun Yang 
179146c745eSJun Yang static const struct rte_flow_item_gtp dpaa2_flow_item_gtp_mask = {
180146c745eSJun Yang 	.teid = RTE_BE32(0xffffffff),
181146c745eSJun Yang };
182146c745eSJun Yang 
183926c1279SJun Yang #endif
184926c1279SJun Yang 
18556c1817dSJun Yang #define DPAA2_FLOW_DUMP printf
18656c1817dSJun Yang 
18756c1817dSJun Yang static inline void
18856c1817dSJun Yang dpaa2_prot_field_string(uint32_t prot, uint32_t field,
189f5ed2ea0SJun Yang 	char *string)
190f5ed2ea0SJun Yang {
191f5ed2ea0SJun Yang 	if (!dpaa2_flow_control_log)
192f5ed2ea0SJun Yang 		return;
193f5ed2ea0SJun Yang 
194f5ed2ea0SJun Yang 	if (prot == NET_PROT_ETH) {
195f5ed2ea0SJun Yang 		strcpy(string, "eth");
196f5ed2ea0SJun Yang 		if (field == NH_FLD_ETH_DA)
197f5ed2ea0SJun Yang 			strcat(string, ".dst");
198f5ed2ea0SJun Yang 		else if (field == NH_FLD_ETH_SA)
199f5ed2ea0SJun Yang 			strcat(string, ".src");
200f5ed2ea0SJun Yang 		else if (field == NH_FLD_ETH_TYPE)
201f5ed2ea0SJun Yang 			strcat(string, ".type");
202f5ed2ea0SJun Yang 		else
203f5ed2ea0SJun Yang 			strcat(string, ".unknown field");
204f5ed2ea0SJun Yang 	} else if (prot == NET_PROT_VLAN) {
205f5ed2ea0SJun Yang 		strcpy(string, "vlan");
206f5ed2ea0SJun Yang 		if (field == NH_FLD_VLAN_TCI)
207f5ed2ea0SJun Yang 			strcat(string, ".tci");
208f5ed2ea0SJun Yang 		else
209f5ed2ea0SJun Yang 			strcat(string, ".unknown field");
210f5ed2ea0SJun Yang 	} else if (prot == NET_PROT_IP) {
211f5ed2ea0SJun Yang 		strcpy(string, "ip");
212f5ed2ea0SJun Yang 		if (field == NH_FLD_IP_SRC)
213f5ed2ea0SJun Yang 			strcat(string, ".src");
214f5ed2ea0SJun Yang 		else if (field == NH_FLD_IP_DST)
215f5ed2ea0SJun Yang 			strcat(string, ".dst");
216f5ed2ea0SJun Yang 		else if (field == NH_FLD_IP_PROTO)
217f5ed2ea0SJun Yang 			strcat(string, ".proto");
218f5ed2ea0SJun Yang 		else
219f5ed2ea0SJun Yang 			strcat(string, ".unknown field");
220f5ed2ea0SJun Yang 	} else if (prot == NET_PROT_TCP) {
221f5ed2ea0SJun Yang 		strcpy(string, "tcp");
222f5ed2ea0SJun Yang 		if (field == NH_FLD_TCP_PORT_SRC)
223f5ed2ea0SJun Yang 			strcat(string, ".src");
224f5ed2ea0SJun Yang 		else if (field == NH_FLD_TCP_PORT_DST)
225f5ed2ea0SJun Yang 			strcat(string, ".dst");
226f5ed2ea0SJun Yang 		else
227f5ed2ea0SJun Yang 			strcat(string, ".unknown field");
228f5ed2ea0SJun Yang 	} else if (prot == NET_PROT_UDP) {
229f5ed2ea0SJun Yang 		strcpy(string, "udp");
230f5ed2ea0SJun Yang 		if (field == NH_FLD_UDP_PORT_SRC)
231f5ed2ea0SJun Yang 			strcat(string, ".src");
232f5ed2ea0SJun Yang 		else if (field == NH_FLD_UDP_PORT_DST)
233f5ed2ea0SJun Yang 			strcat(string, ".dst");
234f5ed2ea0SJun Yang 		else
235f5ed2ea0SJun Yang 			strcat(string, ".unknown field");
236f5ed2ea0SJun Yang 	} else if (prot == NET_PROT_ICMP) {
237f5ed2ea0SJun Yang 		strcpy(string, "icmp");
238f5ed2ea0SJun Yang 		if (field == NH_FLD_ICMP_TYPE)
239f5ed2ea0SJun Yang 			strcat(string, ".type");
240f5ed2ea0SJun Yang 		else if (field == NH_FLD_ICMP_CODE)
241f5ed2ea0SJun Yang 			strcat(string, ".code");
242f5ed2ea0SJun Yang 		else
243f5ed2ea0SJun Yang 			strcat(string, ".unknown field");
244f5ed2ea0SJun Yang 	} else if (prot == NET_PROT_SCTP) {
245f5ed2ea0SJun Yang 		strcpy(string, "sctp");
246f5ed2ea0SJun Yang 		if (field == NH_FLD_SCTP_PORT_SRC)
247f5ed2ea0SJun Yang 			strcat(string, ".src");
248f5ed2ea0SJun Yang 		else if (field == NH_FLD_SCTP_PORT_DST)
249f5ed2ea0SJun Yang 			strcat(string, ".dst");
250f5ed2ea0SJun Yang 		else
251f5ed2ea0SJun Yang 			strcat(string, ".unknown field");
252f5ed2ea0SJun Yang 	} else if (prot == NET_PROT_GRE) {
253f5ed2ea0SJun Yang 		strcpy(string, "gre");
254f5ed2ea0SJun Yang 		if (field == NH_FLD_GRE_TYPE)
255f5ed2ea0SJun Yang 			strcat(string, ".type");
256f5ed2ea0SJun Yang 		else
257f5ed2ea0SJun Yang 			strcat(string, ".unknown field");
258146c745eSJun Yang 	} else if (prot == NET_PROT_GTP) {
259146c745eSJun Yang 		rte_strscpy(string, "gtp", DPAA2_PROT_FIELD_STRING_SIZE);
260146c745eSJun Yang 		if (field == NH_FLD_GTP_TEID)
261146c745eSJun Yang 			strcat(string, ".teid");
262146c745eSJun Yang 		else
263146c745eSJun Yang 			strcat(string, ".unknown field");
2644cc5cf4aSJun Yang 	} else if (prot == NET_PROT_IPSEC_ESP) {
2654cc5cf4aSJun Yang 		rte_strscpy(string, "esp", DPAA2_PROT_FIELD_STRING_SIZE);
2664cc5cf4aSJun Yang 		if (field == NH_FLD_IPSEC_ESP_SPI)
2674cc5cf4aSJun Yang 			strcat(string, ".spi");
2684cc5cf4aSJun Yang 		else if (field == NH_FLD_IPSEC_ESP_SEQUENCE_NUM)
2694cc5cf4aSJun Yang 			strcat(string, ".seq");
2704cc5cf4aSJun Yang 		else
2714cc5cf4aSJun Yang 			strcat(string, ".unknown field");
272f5ed2ea0SJun Yang 	} else {
2734cc5cf4aSJun Yang 		sprintf(string, "unknown protocol(%d)", prot);
274f5ed2ea0SJun Yang 	}
275f5ed2ea0SJun Yang }
276f5ed2ea0SJun Yang 
27756c1817dSJun Yang static inline void
27856c1817dSJun Yang dpaa2_flow_qos_extracts_log(const struct dpaa2_dev_priv *priv)
279f5ed2ea0SJun Yang {
280f5ed2ea0SJun Yang 	int idx;
281f5ed2ea0SJun Yang 	char string[32];
28256c1817dSJun Yang 	const struct dpkg_profile_cfg *dpkg =
28356c1817dSJun Yang 		&priv->extract.qos_key_extract.dpkg;
28456c1817dSJun Yang 	const struct dpkg_extract *extract;
28556c1817dSJun Yang 	enum dpkg_extract_type type;
28656c1817dSJun Yang 	enum net_prot prot;
28756c1817dSJun Yang 	uint32_t field;
288f5ed2ea0SJun Yang 
289f5ed2ea0SJun Yang 	if (!dpaa2_flow_control_log)
290f5ed2ea0SJun Yang 		return;
291f5ed2ea0SJun Yang 
29256c1817dSJun Yang 	DPAA2_FLOW_DUMP("QoS table: %d extracts\r\n",
29356c1817dSJun Yang 		dpkg->num_extracts);
29456c1817dSJun Yang 	for (idx = 0; idx < dpkg->num_extracts; idx++) {
29556c1817dSJun Yang 		extract = &dpkg->extracts[idx];
29656c1817dSJun Yang 		type = extract->type;
29756c1817dSJun Yang 		if (type == DPKG_EXTRACT_FROM_HDR) {
29856c1817dSJun Yang 			prot = extract->extract.from_hdr.prot;
29956c1817dSJun Yang 			field = extract->extract.from_hdr.field;
30056c1817dSJun Yang 			dpaa2_prot_field_string(prot, field,
301f5ed2ea0SJun Yang 				string);
30256c1817dSJun Yang 		} else if (type == DPKG_EXTRACT_FROM_DATA) {
30356c1817dSJun Yang 			sprintf(string, "raw offset/len: %d/%d",
30456c1817dSJun Yang 				extract->extract.from_data.offset,
30556c1817dSJun Yang 				extract->extract.from_data.size);
306200a33e4SJun Yang 		} else if (type == DPKG_EXTRACT_FROM_PARSE) {
307200a33e4SJun Yang 			sprintf(string, "parse offset/len: %d/%d",
308200a33e4SJun Yang 				extract->extract.from_parse.offset,
309200a33e4SJun Yang 				extract->extract.from_parse.size);
310f5ed2ea0SJun Yang 		}
31156c1817dSJun Yang 		DPAA2_FLOW_DUMP("%s", string);
31256c1817dSJun Yang 		if ((idx + 1) < dpkg->num_extracts)
31356c1817dSJun Yang 			DPAA2_FLOW_DUMP(" / ");
31456c1817dSJun Yang 	}
31556c1817dSJun Yang 	DPAA2_FLOW_DUMP("\r\n");
316f5ed2ea0SJun Yang }
317f5ed2ea0SJun Yang 
31856c1817dSJun Yang static inline void
31956c1817dSJun Yang dpaa2_flow_fs_extracts_log(const struct dpaa2_dev_priv *priv,
32056c1817dSJun Yang 	int tc_id)
321f5ed2ea0SJun Yang {
322f5ed2ea0SJun Yang 	int idx;
323f5ed2ea0SJun Yang 	char string[32];
32456c1817dSJun Yang 	const struct dpkg_profile_cfg *dpkg =
32556c1817dSJun Yang 		&priv->extract.tc_key_extract[tc_id].dpkg;
32656c1817dSJun Yang 	const struct dpkg_extract *extract;
32756c1817dSJun Yang 	enum dpkg_extract_type type;
32856c1817dSJun Yang 	enum net_prot prot;
32956c1817dSJun Yang 	uint32_t field;
330f5ed2ea0SJun Yang 
331f5ed2ea0SJun Yang 	if (!dpaa2_flow_control_log)
332f5ed2ea0SJun Yang 		return;
333f5ed2ea0SJun Yang 
33456c1817dSJun Yang 	DPAA2_FLOW_DUMP("FS table: %d extracts in TC[%d]\r\n",
33556c1817dSJun Yang 		dpkg->num_extracts, tc_id);
33656c1817dSJun Yang 	for (idx = 0; idx < dpkg->num_extracts; idx++) {
33756c1817dSJun Yang 		extract = &dpkg->extracts[idx];
33856c1817dSJun Yang 		type = extract->type;
33956c1817dSJun Yang 		if (type == DPKG_EXTRACT_FROM_HDR) {
34056c1817dSJun Yang 			prot = extract->extract.from_hdr.prot;
34156c1817dSJun Yang 			field = extract->extract.from_hdr.field;
34256c1817dSJun Yang 			dpaa2_prot_field_string(prot, field,
343f5ed2ea0SJun Yang 				string);
34456c1817dSJun Yang 		} else if (type == DPKG_EXTRACT_FROM_DATA) {
34556c1817dSJun Yang 			sprintf(string, "raw offset/len: %d/%d",
34656c1817dSJun Yang 				extract->extract.from_data.offset,
34756c1817dSJun Yang 				extract->extract.from_data.size);
348200a33e4SJun Yang 		} else if (type == DPKG_EXTRACT_FROM_PARSE) {
349200a33e4SJun Yang 			sprintf(string, "parse offset/len: %d/%d",
350200a33e4SJun Yang 				extract->extract.from_parse.offset,
351200a33e4SJun Yang 				extract->extract.from_parse.size);
352f5ed2ea0SJun Yang 		}
35356c1817dSJun Yang 		DPAA2_FLOW_DUMP("%s", string);
35456c1817dSJun Yang 		if ((idx + 1) < dpkg->num_extracts)
35556c1817dSJun Yang 			DPAA2_FLOW_DUMP(" / ");
35656c1817dSJun Yang 	}
35756c1817dSJun Yang 	DPAA2_FLOW_DUMP("\r\n");
358f5ed2ea0SJun Yang }
359f5ed2ea0SJun Yang 
36056c1817dSJun Yang static inline void
36156c1817dSJun Yang dpaa2_flow_qos_entry_log(const char *log_info,
36256c1817dSJun Yang 	const struct dpaa2_dev_flow *flow, int qos_index)
363f5ed2ea0SJun Yang {
364f5ed2ea0SJun Yang 	int idx;
365f5ed2ea0SJun Yang 	uint8_t *key, *mask;
366f5ed2ea0SJun Yang 
367f5ed2ea0SJun Yang 	if (!dpaa2_flow_control_log)
368f5ed2ea0SJun Yang 		return;
369f5ed2ea0SJun Yang 
37056c1817dSJun Yang 	if (qos_index >= 0) {
37156c1817dSJun Yang 		DPAA2_FLOW_DUMP("%s QoS entry[%d](size %d/%d) for TC[%d]\r\n",
37256c1817dSJun Yang 			log_info, qos_index, flow->qos_rule_size,
37356c1817dSJun Yang 			flow->qos_rule.key_size,
37456c1817dSJun Yang 			flow->tc_id);
3755f176728SJun Yang 	} else {
37656c1817dSJun Yang 		DPAA2_FLOW_DUMP("%s QoS entry(size %d/%d) for TC[%d]\r\n",
37756c1817dSJun Yang 			log_info, flow->qos_rule_size,
37856c1817dSJun Yang 			flow->qos_rule.key_size,
37956c1817dSJun Yang 			flow->tc_id);
3805f176728SJun Yang 	}
3815f176728SJun Yang 
38256c1817dSJun Yang 	key = flow->qos_key_addr;
38356c1817dSJun Yang 	mask = flow->qos_mask_addr;
38456c1817dSJun Yang 
38556c1817dSJun Yang 	DPAA2_FLOW_DUMP("key:\r\n");
38656c1817dSJun Yang 	for (idx = 0; idx < flow->qos_rule_size; idx++)
38756c1817dSJun Yang 		DPAA2_FLOW_DUMP("%02x ", key[idx]);
38856c1817dSJun Yang 
38956c1817dSJun Yang 	DPAA2_FLOW_DUMP("\r\nmask:\r\n");
39056c1817dSJun Yang 	for (idx = 0; idx < flow->qos_rule_size; idx++)
39156c1817dSJun Yang 		DPAA2_FLOW_DUMP("%02x ", mask[idx]);
39256c1817dSJun Yang 	DPAA2_FLOW_DUMP("\r\n");
39356c1817dSJun Yang }
39456c1817dSJun Yang 
39556c1817dSJun Yang static inline void
39656c1817dSJun Yang dpaa2_flow_fs_entry_log(const char *log_info,
39756c1817dSJun Yang 	const struct dpaa2_dev_flow *flow)
3985f176728SJun Yang {
39956c1817dSJun Yang 	int idx;
40056c1817dSJun Yang 	uint8_t *key, *mask;
4015f176728SJun Yang 
40256c1817dSJun Yang 	if (!dpaa2_flow_control_log)
40356c1817dSJun Yang 		return;
40456c1817dSJun Yang 
40556c1817dSJun Yang 	DPAA2_FLOW_DUMP("%s FS/TC entry[%d](size %d/%d) of TC[%d]\r\n",
40656c1817dSJun Yang 		log_info, flow->tc_index,
40756c1817dSJun Yang 		flow->fs_rule_size, flow->fs_rule.key_size,
40856c1817dSJun Yang 		flow->tc_id);
40956c1817dSJun Yang 
41056c1817dSJun Yang 	key = flow->fs_key_addr;
41156c1817dSJun Yang 	mask = flow->fs_mask_addr;
41256c1817dSJun Yang 
41356c1817dSJun Yang 	DPAA2_FLOW_DUMP("key:\r\n");
41456c1817dSJun Yang 	for (idx = 0; idx < flow->fs_rule_size; idx++)
41556c1817dSJun Yang 		DPAA2_FLOW_DUMP("%02x ", key[idx]);
41656c1817dSJun Yang 
41756c1817dSJun Yang 	DPAA2_FLOW_DUMP("\r\nmask:\r\n");
41856c1817dSJun Yang 	for (idx = 0; idx < flow->fs_rule_size; idx++)
41956c1817dSJun Yang 		DPAA2_FLOW_DUMP("%02x ", mask[idx]);
42056c1817dSJun Yang 	DPAA2_FLOW_DUMP("\r\n");
4215f176728SJun Yang }
42256c1817dSJun Yang 
42399400780SJun Yang /** For LX2160A, LS2088A and LS1088A*/
42499400780SJun Yang #define WRIOP_CCSR_BASE 0x8b80000
42599400780SJun Yang #define WRIOP_CCSR_CTLU_OFFSET 0
42699400780SJun Yang #define WRIOP_CCSR_CTLU_PARSER_OFFSET 0
42799400780SJun Yang #define WRIOP_CCSR_CTLU_PARSER_INGRESS_OFFSET 0
42899400780SJun Yang 
42999400780SJun Yang #define WRIOP_INGRESS_PARSER_PHY \
43099400780SJun Yang 	(WRIOP_CCSR_BASE + WRIOP_CCSR_CTLU_OFFSET + \
43199400780SJun Yang 	WRIOP_CCSR_CTLU_PARSER_OFFSET + \
43299400780SJun Yang 	WRIOP_CCSR_CTLU_PARSER_INGRESS_OFFSET)
43399400780SJun Yang 
43499400780SJun Yang struct dpaa2_parser_ccsr {
43599400780SJun Yang 	uint32_t psr_cfg;
43699400780SJun Yang 	uint32_t psr_idle;
43799400780SJun Yang 	uint32_t psr_pclm;
43899400780SJun Yang 	uint8_t psr_ver_min;
43999400780SJun Yang 	uint8_t psr_ver_maj;
44099400780SJun Yang 	uint8_t psr_id1_l;
44199400780SJun Yang 	uint8_t psr_id1_h;
44299400780SJun Yang 	uint32_t psr_rev2;
44399400780SJun Yang 	uint8_t rsv[0x2c];
44499400780SJun Yang 	uint8_t sp_ins[4032];
44599400780SJun Yang };
44699400780SJun Yang 
44799400780SJun Yang int
44899400780SJun Yang dpaa2_soft_parser_loaded(void)
44999400780SJun Yang {
45099400780SJun Yang 	int fd, i, ret = 0;
45199400780SJun Yang 	struct dpaa2_parser_ccsr *parser_ccsr = NULL;
45299400780SJun Yang 
45399400780SJun Yang 	dpaa2_flow_control_log = getenv("DPAA2_FLOW_CONTROL_LOG");
45499400780SJun Yang 
45599400780SJun Yang 	if (dpaa2_sp_loaded >= 0)
45699400780SJun Yang 		return dpaa2_sp_loaded;
45799400780SJun Yang 
45899400780SJun Yang 	fd = open("/dev/mem", O_RDWR | O_SYNC);
45999400780SJun Yang 	if (fd < 0) {
46099400780SJun Yang 		DPAA2_PMD_ERR("open \"/dev/mem\" ERROR(%d)", fd);
46199400780SJun Yang 		ret = fd;
46299400780SJun Yang 		goto exit;
46399400780SJun Yang 	}
46499400780SJun Yang 
46599400780SJun Yang 	parser_ccsr = mmap(NULL, sizeof(struct dpaa2_parser_ccsr),
46699400780SJun Yang 		PROT_READ | PROT_WRITE, MAP_SHARED, fd,
46799400780SJun Yang 		WRIOP_INGRESS_PARSER_PHY);
46899400780SJun Yang 	if (!parser_ccsr) {
46999400780SJun Yang 		DPAA2_PMD_ERR("Map 0x%" PRIx64 "(size=0x%x) failed",
47099400780SJun Yang 			(uint64_t)WRIOP_INGRESS_PARSER_PHY,
47199400780SJun Yang 			(uint32_t)sizeof(struct dpaa2_parser_ccsr));
47299400780SJun Yang 		ret = -ENOBUFS;
47399400780SJun Yang 		goto exit;
47499400780SJun Yang 	}
47599400780SJun Yang 
47699400780SJun Yang 	DPAA2_PMD_INFO("Parser ID:0x%02x%02x, Rev:major(%02x), minor(%02x)",
47799400780SJun Yang 		parser_ccsr->psr_id1_h, parser_ccsr->psr_id1_l,
47899400780SJun Yang 		parser_ccsr->psr_ver_maj, parser_ccsr->psr_ver_min);
47999400780SJun Yang 
48099400780SJun Yang 	if (dpaa2_flow_control_log) {
48199400780SJun Yang 		for (i = 0; i < 64; i++) {
48299400780SJun Yang 			DPAA2_FLOW_DUMP("%02x ",
48399400780SJun Yang 				parser_ccsr->sp_ins[i]);
48499400780SJun Yang 			if (!((i + 1) % 16))
48599400780SJun Yang 				DPAA2_FLOW_DUMP("\r\n");
48699400780SJun Yang 		}
48799400780SJun Yang 	}
48899400780SJun Yang 
48999400780SJun Yang 	for (i = 0; i < 16; i++) {
49099400780SJun Yang 		if (parser_ccsr->sp_ins[i]) {
49199400780SJun Yang 			dpaa2_sp_loaded = 1;
49299400780SJun Yang 			break;
49399400780SJun Yang 		}
49499400780SJun Yang 	}
49599400780SJun Yang 	if (dpaa2_sp_loaded < 0)
49699400780SJun Yang 		dpaa2_sp_loaded = 0;
49799400780SJun Yang 
49899400780SJun Yang 	ret = dpaa2_sp_loaded;
49999400780SJun Yang 
50099400780SJun Yang exit:
50199400780SJun Yang 	if (parser_ccsr)
50299400780SJun Yang 		munmap(parser_ccsr, sizeof(struct dpaa2_parser_ccsr));
50399400780SJun Yang 	if (fd >= 0)
50499400780SJun Yang 		close(fd);
50599400780SJun Yang 
50699400780SJun Yang 	return ret;
50799400780SJun Yang }
50899400780SJun Yang 
50956c1817dSJun Yang static int
51056c1817dSJun Yang dpaa2_flow_ip_address_extract(enum net_prot prot,
51156c1817dSJun Yang 	uint32_t field)
51256c1817dSJun Yang {
51356c1817dSJun Yang 	if (prot == NET_PROT_IPV4 &&
51456c1817dSJun Yang 		(field == NH_FLD_IPV4_SRC_IP ||
51556c1817dSJun Yang 		field == NH_FLD_IPV4_DST_IP))
51656c1817dSJun Yang 		return true;
51756c1817dSJun Yang 	else if (prot == NET_PROT_IPV6 &&
51856c1817dSJun Yang 		(field == NH_FLD_IPV6_SRC_IP ||
51956c1817dSJun Yang 		field == NH_FLD_IPV6_DST_IP))
52056c1817dSJun Yang 		return true;
52156c1817dSJun Yang 	else if (prot == NET_PROT_IP &&
52256c1817dSJun Yang 		(field == NH_FLD_IP_SRC ||
52356c1817dSJun Yang 		field == NH_FLD_IP_DST))
52456c1817dSJun Yang 		return true;
52556c1817dSJun Yang 
52656c1817dSJun Yang 	return false;
52756c1817dSJun Yang }
52856c1817dSJun Yang 
52956c1817dSJun Yang static int
53056c1817dSJun Yang dpaa2_flow_l4_src_port_extract(enum net_prot prot,
53156c1817dSJun Yang 	uint32_t field)
53256c1817dSJun Yang {
53356c1817dSJun Yang 	if (prot == NET_PROT_TCP &&
53456c1817dSJun Yang 		field == NH_FLD_TCP_PORT_SRC)
53556c1817dSJun Yang 		return true;
53656c1817dSJun Yang 	else if (prot == NET_PROT_UDP &&
53756c1817dSJun Yang 		field == NH_FLD_UDP_PORT_SRC)
53856c1817dSJun Yang 		return true;
53956c1817dSJun Yang 	else if (prot == NET_PROT_SCTP &&
54056c1817dSJun Yang 		field == NH_FLD_SCTP_PORT_SRC)
54156c1817dSJun Yang 		return true;
54256c1817dSJun Yang 
54356c1817dSJun Yang 	return false;
54456c1817dSJun Yang }
54556c1817dSJun Yang 
54656c1817dSJun Yang static int
54756c1817dSJun Yang dpaa2_flow_l4_dst_port_extract(enum net_prot prot,
54856c1817dSJun Yang 	uint32_t field)
54956c1817dSJun Yang {
55056c1817dSJun Yang 	if (prot == NET_PROT_TCP &&
55156c1817dSJun Yang 		field == NH_FLD_TCP_PORT_DST)
55256c1817dSJun Yang 		return true;
55356c1817dSJun Yang 	else if (prot == NET_PROT_UDP &&
55456c1817dSJun Yang 		field == NH_FLD_UDP_PORT_DST)
55556c1817dSJun Yang 		return true;
55656c1817dSJun Yang 	else if (prot == NET_PROT_SCTP &&
55756c1817dSJun Yang 		field == NH_FLD_SCTP_PORT_DST)
55856c1817dSJun Yang 		return true;
55956c1817dSJun Yang 
56056c1817dSJun Yang 	return false;
56156c1817dSJun Yang }
56256c1817dSJun Yang 
56356c1817dSJun Yang static int
56456c1817dSJun Yang dpaa2_flow_add_qos_rule(struct dpaa2_dev_priv *priv,
56556c1817dSJun Yang 	struct dpaa2_dev_flow *flow)
56656c1817dSJun Yang {
56756c1817dSJun Yang 	uint16_t qos_index;
56856c1817dSJun Yang 	int ret;
56956c1817dSJun Yang 	struct fsl_mc_io *dpni = priv->hw;
57056c1817dSJun Yang 
57156c1817dSJun Yang 	if (priv->num_rx_tc <= 1 &&
57256c1817dSJun Yang 		flow->action_type != RTE_FLOW_ACTION_TYPE_RSS) {
57356c1817dSJun Yang 		DPAA2_PMD_WARN("No QoS Table for FS");
57456c1817dSJun Yang 		return -EINVAL;
57556c1817dSJun Yang 	}
57656c1817dSJun Yang 
57756c1817dSJun Yang 	/* QoS entry added is only effective for multiple TCs.*/
57856c1817dSJun Yang 	qos_index = flow->tc_id * priv->fs_entries + flow->tc_index;
57956c1817dSJun Yang 	if (qos_index >= priv->qos_entries) {
58056c1817dSJun Yang 		DPAA2_PMD_ERR("QoS table full(%d >= %d)",
58156c1817dSJun Yang 			qos_index, priv->qos_entries);
58256c1817dSJun Yang 		return -EINVAL;
58356c1817dSJun Yang 	}
58456c1817dSJun Yang 
58556c1817dSJun Yang 	dpaa2_flow_qos_entry_log("Start add", flow, qos_index);
58656c1817dSJun Yang 
58756c1817dSJun Yang 	ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW,
58856c1817dSJun Yang 			priv->token, &flow->qos_rule,
58956c1817dSJun Yang 			flow->tc_id, qos_index,
59056c1817dSJun Yang 			0, 0);
59156c1817dSJun Yang 	if (ret < 0) {
59256c1817dSJun Yang 		DPAA2_PMD_ERR("Add entry(%d) to table(%d) failed",
59356c1817dSJun Yang 			qos_index, flow->tc_id);
59456c1817dSJun Yang 		return ret;
59556c1817dSJun Yang 	}
59656c1817dSJun Yang 
59756c1817dSJun Yang 	return 0;
59856c1817dSJun Yang }
59956c1817dSJun Yang 
60056c1817dSJun Yang static int
60156c1817dSJun Yang dpaa2_flow_add_fs_rule(struct dpaa2_dev_priv *priv,
60256c1817dSJun Yang 	struct dpaa2_dev_flow *flow)
60356c1817dSJun Yang {
60456c1817dSJun Yang 	int ret;
60556c1817dSJun Yang 	struct fsl_mc_io *dpni = priv->hw;
60656c1817dSJun Yang 
60756c1817dSJun Yang 	if (flow->tc_index >= priv->fs_entries) {
60856c1817dSJun Yang 		DPAA2_PMD_ERR("FS table full(%d >= %d)",
60956c1817dSJun Yang 			flow->tc_index, priv->fs_entries);
61056c1817dSJun Yang 		return -EINVAL;
61156c1817dSJun Yang 	}
61256c1817dSJun Yang 
61356c1817dSJun Yang 	dpaa2_flow_fs_entry_log("Start add", flow);
61456c1817dSJun Yang 
61556c1817dSJun Yang 	ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW,
61656c1817dSJun Yang 			priv->token, flow->tc_id,
61756c1817dSJun Yang 			flow->tc_index, &flow->fs_rule,
61856c1817dSJun Yang 			&flow->fs_action_cfg);
61956c1817dSJun Yang 	if (ret < 0) {
62056c1817dSJun Yang 		DPAA2_PMD_ERR("Add rule(%d) to FS table(%d) failed",
62156c1817dSJun Yang 			flow->tc_index, flow->tc_id);
62256c1817dSJun Yang 		return ret;
62356c1817dSJun Yang 	}
62456c1817dSJun Yang 
62556c1817dSJun Yang 	return 0;
62656c1817dSJun Yang }
62756c1817dSJun Yang 
62856c1817dSJun Yang static int
62956c1817dSJun Yang dpaa2_flow_rule_insert_hole(struct dpaa2_dev_flow *flow,
63056c1817dSJun Yang 	int offset, int size,
63156c1817dSJun Yang 	enum dpaa2_flow_dist_type dist_type)
63256c1817dSJun Yang {
63356c1817dSJun Yang 	int end;
63456c1817dSJun Yang 
63556c1817dSJun Yang 	if (dist_type & DPAA2_FLOW_QOS_TYPE) {
63656c1817dSJun Yang 		end = flow->qos_rule_size;
63756c1817dSJun Yang 		if (end > offset) {
63856c1817dSJun Yang 			memmove(flow->qos_key_addr + offset + size,
63956c1817dSJun Yang 					flow->qos_key_addr + offset,
64056c1817dSJun Yang 					end - offset);
64156c1817dSJun Yang 			memset(flow->qos_key_addr + offset,
64256c1817dSJun Yang 					0, size);
64356c1817dSJun Yang 
64456c1817dSJun Yang 			memmove(flow->qos_mask_addr + offset + size,
64556c1817dSJun Yang 					flow->qos_mask_addr + offset,
64656c1817dSJun Yang 					end - offset);
64756c1817dSJun Yang 			memset(flow->qos_mask_addr + offset,
64856c1817dSJun Yang 					0, size);
64956c1817dSJun Yang 		}
65056c1817dSJun Yang 		flow->qos_rule_size += size;
65156c1817dSJun Yang 	}
65256c1817dSJun Yang 
65356c1817dSJun Yang 	if (dist_type & DPAA2_FLOW_FS_TYPE) {
65456c1817dSJun Yang 		end = flow->fs_rule_size;
65556c1817dSJun Yang 		if (end > offset) {
65656c1817dSJun Yang 			memmove(flow->fs_key_addr + offset + size,
65756c1817dSJun Yang 					flow->fs_key_addr + offset,
65856c1817dSJun Yang 					end - offset);
65956c1817dSJun Yang 			memset(flow->fs_key_addr + offset,
66056c1817dSJun Yang 					0, size);
66156c1817dSJun Yang 
66256c1817dSJun Yang 			memmove(flow->fs_mask_addr + offset + size,
66356c1817dSJun Yang 					flow->fs_mask_addr + offset,
66456c1817dSJun Yang 					end - offset);
66556c1817dSJun Yang 			memset(flow->fs_mask_addr + offset,
66656c1817dSJun Yang 					0, size);
66756c1817dSJun Yang 		}
66856c1817dSJun Yang 		flow->fs_rule_size += size;
66956c1817dSJun Yang 	}
67056c1817dSJun Yang 
67156c1817dSJun Yang 	return 0;
67256c1817dSJun Yang }
67356c1817dSJun Yang 
67456c1817dSJun Yang static int
67556c1817dSJun Yang dpaa2_flow_rule_add_all(struct dpaa2_dev_priv *priv,
67656c1817dSJun Yang 	enum dpaa2_flow_dist_type dist_type,
67756c1817dSJun Yang 	uint16_t entry_size, uint8_t tc_id)
67856c1817dSJun Yang {
67956c1817dSJun Yang 	struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows);
68056c1817dSJun Yang 	int ret;
68156c1817dSJun Yang 
68256c1817dSJun Yang 	while (curr) {
68356c1817dSJun Yang 		if (dist_type & DPAA2_FLOW_QOS_TYPE) {
68456c1817dSJun Yang 			if (priv->num_rx_tc > 1 ||
68556c1817dSJun Yang 				curr->action_type ==
68656c1817dSJun Yang 				RTE_FLOW_ACTION_TYPE_RSS) {
68756c1817dSJun Yang 				curr->qos_rule.key_size = entry_size;
68856c1817dSJun Yang 				ret = dpaa2_flow_add_qos_rule(priv, curr);
68956c1817dSJun Yang 				if (ret)
69056c1817dSJun Yang 					return ret;
69156c1817dSJun Yang 			}
69256c1817dSJun Yang 		}
69356c1817dSJun Yang 		if (dist_type & DPAA2_FLOW_FS_TYPE &&
69456c1817dSJun Yang 			curr->tc_id == tc_id) {
69556c1817dSJun Yang 			curr->fs_rule.key_size = entry_size;
69656c1817dSJun Yang 			ret = dpaa2_flow_add_fs_rule(priv, curr);
69756c1817dSJun Yang 			if (ret)
69856c1817dSJun Yang 				return ret;
69956c1817dSJun Yang 		}
70056c1817dSJun Yang 		curr = LIST_NEXT(curr, next);
70156c1817dSJun Yang 	}
70256c1817dSJun Yang 
70356c1817dSJun Yang 	return 0;
70456c1817dSJun Yang }
70556c1817dSJun Yang 
70656c1817dSJun Yang static int
70756c1817dSJun Yang dpaa2_flow_qos_rule_insert_hole(struct dpaa2_dev_priv *priv,
70856c1817dSJun Yang 	int offset, int size)
70956c1817dSJun Yang {
71056c1817dSJun Yang 	struct dpaa2_dev_flow *curr;
71156c1817dSJun Yang 	int ret;
71256c1817dSJun Yang 
71356c1817dSJun Yang 	curr = priv->curr;
71456c1817dSJun Yang 	if (!curr) {
71556c1817dSJun Yang 		DPAA2_PMD_ERR("Current qos flow insert hole failed.");
71656c1817dSJun Yang 		return -EINVAL;
71756c1817dSJun Yang 	} else {
71856c1817dSJun Yang 		ret = dpaa2_flow_rule_insert_hole(curr, offset, size,
71956c1817dSJun Yang 				DPAA2_FLOW_QOS_TYPE);
72056c1817dSJun Yang 		if (ret)
72156c1817dSJun Yang 			return ret;
72256c1817dSJun Yang 	}
72356c1817dSJun Yang 
72456c1817dSJun Yang 	curr = LIST_FIRST(&priv->flows);
72556c1817dSJun Yang 	while (curr) {
72656c1817dSJun Yang 		ret = dpaa2_flow_rule_insert_hole(curr, offset, size,
72756c1817dSJun Yang 				DPAA2_FLOW_QOS_TYPE);
72856c1817dSJun Yang 		if (ret)
72956c1817dSJun Yang 			return ret;
73056c1817dSJun Yang 		curr = LIST_NEXT(curr, next);
73156c1817dSJun Yang 	}
73256c1817dSJun Yang 
73356c1817dSJun Yang 	return 0;
73456c1817dSJun Yang }
73556c1817dSJun Yang 
73656c1817dSJun Yang static int
73756c1817dSJun Yang dpaa2_flow_fs_rule_insert_hole(struct dpaa2_dev_priv *priv,
73856c1817dSJun Yang 	int offset, int size, int tc_id)
73956c1817dSJun Yang {
74056c1817dSJun Yang 	struct dpaa2_dev_flow *curr;
74156c1817dSJun Yang 	int ret;
74256c1817dSJun Yang 
74356c1817dSJun Yang 	curr = priv->curr;
74456c1817dSJun Yang 	if (!curr || curr->tc_id != tc_id) {
74556c1817dSJun Yang 		DPAA2_PMD_ERR("Current flow insert hole failed.");
74656c1817dSJun Yang 		return -EINVAL;
74756c1817dSJun Yang 	} else {
74856c1817dSJun Yang 		ret = dpaa2_flow_rule_insert_hole(curr, offset, size,
74956c1817dSJun Yang 				DPAA2_FLOW_FS_TYPE);
75056c1817dSJun Yang 		if (ret)
75156c1817dSJun Yang 			return ret;
75256c1817dSJun Yang 	}
75356c1817dSJun Yang 
75456c1817dSJun Yang 	curr = LIST_FIRST(&priv->flows);
75556c1817dSJun Yang 
75656c1817dSJun Yang 	while (curr) {
75756c1817dSJun Yang 		if (curr->tc_id != tc_id) {
75856c1817dSJun Yang 			curr = LIST_NEXT(curr, next);
75956c1817dSJun Yang 			continue;
76056c1817dSJun Yang 		}
76156c1817dSJun Yang 		ret = dpaa2_flow_rule_insert_hole(curr, offset, size,
76256c1817dSJun Yang 				DPAA2_FLOW_FS_TYPE);
76356c1817dSJun Yang 		if (ret)
76456c1817dSJun Yang 			return ret;
76556c1817dSJun Yang 		curr = LIST_NEXT(curr, next);
76656c1817dSJun Yang 	}
76756c1817dSJun Yang 
76856c1817dSJun Yang 	return 0;
76956c1817dSJun Yang }
77056c1817dSJun Yang 
771200a33e4SJun Yang static int
772200a33e4SJun Yang dpaa2_flow_faf_advance(struct dpaa2_dev_priv *priv,
773200a33e4SJun Yang 	int faf_byte, enum dpaa2_flow_dist_type dist_type, int tc_id,
774200a33e4SJun Yang 	int *insert_offset)
775200a33e4SJun Yang {
776200a33e4SJun Yang 	int offset, ret;
777200a33e4SJun Yang 	struct dpaa2_key_profile *key_profile;
778200a33e4SJun Yang 	int num, pos;
779200a33e4SJun Yang 
780200a33e4SJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE)
781200a33e4SJun Yang 		key_profile = &priv->extract.qos_key_extract.key_profile;
782200a33e4SJun Yang 	else
783200a33e4SJun Yang 		key_profile = &priv->extract.tc_key_extract[tc_id].key_profile;
784200a33e4SJun Yang 
785200a33e4SJun Yang 	num = key_profile->num;
786200a33e4SJun Yang 
787200a33e4SJun Yang 	if (num >= DPKG_MAX_NUM_OF_EXTRACTS) {
788200a33e4SJun Yang 		DPAA2_PMD_ERR("Number of extracts overflows");
789200a33e4SJun Yang 		return -EINVAL;
790200a33e4SJun Yang 	}
791200a33e4SJun Yang 
792200a33e4SJun Yang 	if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) {
793200a33e4SJun Yang 		offset = key_profile->ip_addr_extract_off;
794200a33e4SJun Yang 		pos = key_profile->ip_addr_extract_pos;
795200a33e4SJun Yang 		key_profile->ip_addr_extract_pos++;
796200a33e4SJun Yang 		key_profile->ip_addr_extract_off++;
797200a33e4SJun Yang 		if (dist_type == DPAA2_FLOW_QOS_TYPE) {
798200a33e4SJun Yang 			ret = dpaa2_flow_qos_rule_insert_hole(priv,
799200a33e4SJun Yang 					offset, 1);
800200a33e4SJun Yang 		} else {
801200a33e4SJun Yang 			ret = dpaa2_flow_fs_rule_insert_hole(priv,
802200a33e4SJun Yang 				offset, 1, tc_id);
803200a33e4SJun Yang 		}
804200a33e4SJun Yang 		if (ret)
805200a33e4SJun Yang 			return ret;
806200a33e4SJun Yang 	} else {
807200a33e4SJun Yang 		pos = num;
808200a33e4SJun Yang 	}
809200a33e4SJun Yang 
810200a33e4SJun Yang 	if (pos > 0) {
811200a33e4SJun Yang 		key_profile->key_offset[pos] =
812200a33e4SJun Yang 			key_profile->key_offset[pos - 1] +
813200a33e4SJun Yang 			key_profile->key_size[pos - 1];
814200a33e4SJun Yang 	} else {
815200a33e4SJun Yang 		key_profile->key_offset[pos] = 0;
816200a33e4SJun Yang 	}
817200a33e4SJun Yang 
818200a33e4SJun Yang 	key_profile->key_size[pos] = 1;
819200a33e4SJun Yang 	key_profile->prot_field[pos].type = DPAA2_FAF_KEY;
820200a33e4SJun Yang 	key_profile->prot_field[pos].key_field = faf_byte;
821200a33e4SJun Yang 	key_profile->num++;
822200a33e4SJun Yang 
823200a33e4SJun Yang 	if (insert_offset)
824200a33e4SJun Yang 		*insert_offset = key_profile->key_offset[pos];
825200a33e4SJun Yang 
826200a33e4SJun Yang 	key_profile->key_max_size++;
827200a33e4SJun Yang 
828200a33e4SJun Yang 	return pos;
829200a33e4SJun Yang }
830200a33e4SJun Yang 
83139c8044fSJun Yang static int
83239c8044fSJun Yang dpaa2_flow_pr_advance(struct dpaa2_dev_priv *priv,
83339c8044fSJun Yang 	uint32_t pr_offset, uint32_t pr_size,
83439c8044fSJun Yang 	enum dpaa2_flow_dist_type dist_type, int tc_id,
83539c8044fSJun Yang 	int *insert_offset)
83639c8044fSJun Yang {
83739c8044fSJun Yang 	int offset, ret;
83839c8044fSJun Yang 	struct dpaa2_key_profile *key_profile;
83939c8044fSJun Yang 	int num, pos;
84039c8044fSJun Yang 
84139c8044fSJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE)
84239c8044fSJun Yang 		key_profile = &priv->extract.qos_key_extract.key_profile;
84339c8044fSJun Yang 	else
84439c8044fSJun Yang 		key_profile = &priv->extract.tc_key_extract[tc_id].key_profile;
84539c8044fSJun Yang 
84639c8044fSJun Yang 	num = key_profile->num;
84739c8044fSJun Yang 
84839c8044fSJun Yang 	if (num >= DPKG_MAX_NUM_OF_EXTRACTS) {
84939c8044fSJun Yang 		DPAA2_PMD_ERR("Number of extracts overflows");
85039c8044fSJun Yang 		return -EINVAL;
85139c8044fSJun Yang 	}
85239c8044fSJun Yang 
85339c8044fSJun Yang 	if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) {
85439c8044fSJun Yang 		offset = key_profile->ip_addr_extract_off;
85539c8044fSJun Yang 		pos = key_profile->ip_addr_extract_pos;
85639c8044fSJun Yang 		key_profile->ip_addr_extract_pos++;
85739c8044fSJun Yang 		key_profile->ip_addr_extract_off += pr_size;
85839c8044fSJun Yang 		if (dist_type == DPAA2_FLOW_QOS_TYPE) {
85939c8044fSJun Yang 			ret = dpaa2_flow_qos_rule_insert_hole(priv,
86039c8044fSJun Yang 					offset, pr_size);
86139c8044fSJun Yang 		} else {
86239c8044fSJun Yang 			ret = dpaa2_flow_fs_rule_insert_hole(priv,
86339c8044fSJun Yang 				offset, pr_size, tc_id);
86439c8044fSJun Yang 		}
86539c8044fSJun Yang 		if (ret)
86639c8044fSJun Yang 			return ret;
86739c8044fSJun Yang 	} else {
86839c8044fSJun Yang 		pos = num;
86939c8044fSJun Yang 	}
87039c8044fSJun Yang 
87139c8044fSJun Yang 	if (pos > 0) {
87239c8044fSJun Yang 		key_profile->key_offset[pos] =
87339c8044fSJun Yang 			key_profile->key_offset[pos - 1] +
87439c8044fSJun Yang 			key_profile->key_size[pos - 1];
87539c8044fSJun Yang 	} else {
87639c8044fSJun Yang 		key_profile->key_offset[pos] = 0;
87739c8044fSJun Yang 	}
87839c8044fSJun Yang 
87939c8044fSJun Yang 	key_profile->key_size[pos] = pr_size;
88039c8044fSJun Yang 	key_profile->prot_field[pos].type = DPAA2_PR_KEY;
88139c8044fSJun Yang 	key_profile->prot_field[pos].key_field =
88239c8044fSJun Yang 		(pr_offset << 16) | pr_size;
88339c8044fSJun Yang 	key_profile->num++;
88439c8044fSJun Yang 
88539c8044fSJun Yang 	if (insert_offset)
88639c8044fSJun Yang 		*insert_offset = key_profile->key_offset[pos];
88739c8044fSJun Yang 
88839c8044fSJun Yang 	key_profile->key_max_size += pr_size;
88939c8044fSJun Yang 
89039c8044fSJun Yang 	return pos;
89139c8044fSJun Yang }
89239c8044fSJun Yang 
89356c1817dSJun Yang /* Move IPv4/IPv6 addresses to fill new extract previous IP address.
89456c1817dSJun Yang  * Current MC/WRIOP only support generic IP extract but IP address
89556c1817dSJun Yang  * is not fixed, so we have to put them at end of extracts, otherwise,
89656c1817dSJun Yang  * the extracts position following them can't be identified.
8975f176728SJun Yang  */
89856c1817dSJun Yang static int
89956c1817dSJun Yang dpaa2_flow_key_profile_advance(enum net_prot prot,
90056c1817dSJun Yang 	uint32_t field, uint8_t field_size,
90156c1817dSJun Yang 	struct dpaa2_dev_priv *priv,
90256c1817dSJun Yang 	enum dpaa2_flow_dist_type dist_type, int tc_id,
90356c1817dSJun Yang 	int *insert_offset)
90456c1817dSJun Yang {
90556c1817dSJun Yang 	int offset, ret;
90656c1817dSJun Yang 	struct dpaa2_key_profile *key_profile;
90756c1817dSJun Yang 	int num, pos;
90856c1817dSJun Yang 
90956c1817dSJun Yang 	if (dpaa2_flow_ip_address_extract(prot, field)) {
91056c1817dSJun Yang 		DPAA2_PMD_ERR("%s only for none IP address extract",
91156c1817dSJun Yang 			__func__);
91256c1817dSJun Yang 		return -EINVAL;
9135f176728SJun Yang 	}
9145f176728SJun Yang 
91556c1817dSJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE)
91656c1817dSJun Yang 		key_profile = &priv->extract.qos_key_extract.key_profile;
9175f176728SJun Yang 	else
91856c1817dSJun Yang 		key_profile = &priv->extract.tc_key_extract[tc_id].key_profile;
91956c1817dSJun Yang 
92056c1817dSJun Yang 	num = key_profile->num;
92156c1817dSJun Yang 
92256c1817dSJun Yang 	if (num >= DPKG_MAX_NUM_OF_EXTRACTS) {
92356c1817dSJun Yang 		DPAA2_PMD_ERR("Number of extracts overflows");
92456c1817dSJun Yang 		return -EINVAL;
9255f176728SJun Yang 	}
9265f176728SJun Yang 
92756c1817dSJun Yang 	if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) {
92856c1817dSJun Yang 		offset = key_profile->ip_addr_extract_off;
92956c1817dSJun Yang 		pos = key_profile->ip_addr_extract_pos;
93056c1817dSJun Yang 		key_profile->ip_addr_extract_pos++;
93156c1817dSJun Yang 		key_profile->ip_addr_extract_off += field_size;
93256c1817dSJun Yang 		if (dist_type == DPAA2_FLOW_QOS_TYPE) {
93356c1817dSJun Yang 			ret = dpaa2_flow_qos_rule_insert_hole(priv,
93456c1817dSJun Yang 					offset, field_size);
9355f176728SJun Yang 		} else {
93656c1817dSJun Yang 			ret = dpaa2_flow_fs_rule_insert_hole(priv,
93756c1817dSJun Yang 				offset, field_size, tc_id);
93856c1817dSJun Yang 		}
93956c1817dSJun Yang 		if (ret)
94056c1817dSJun Yang 			return ret;
94156c1817dSJun Yang 	} else {
94256c1817dSJun Yang 		pos = num;
9435f176728SJun Yang 	}
9445f176728SJun Yang 
94556c1817dSJun Yang 	if (pos > 0) {
94656c1817dSJun Yang 		key_profile->key_offset[pos] =
94756c1817dSJun Yang 			key_profile->key_offset[pos - 1] +
94856c1817dSJun Yang 			key_profile->key_size[pos - 1];
9495f176728SJun Yang 	} else {
95056c1817dSJun Yang 		key_profile->key_offset[pos] = 0;
9515f176728SJun Yang 	}
95256c1817dSJun Yang 
95356c1817dSJun Yang 	key_profile->key_size[pos] = field_size;
954200a33e4SJun Yang 	key_profile->prot_field[pos].type = DPAA2_NET_PROT_KEY;
95556c1817dSJun Yang 	key_profile->prot_field[pos].prot = prot;
95656c1817dSJun Yang 	key_profile->prot_field[pos].key_field = field;
95756c1817dSJun Yang 	key_profile->num++;
95856c1817dSJun Yang 
95956c1817dSJun Yang 	if (insert_offset)
96056c1817dSJun Yang 		*insert_offset = key_profile->key_offset[pos];
96156c1817dSJun Yang 
96256c1817dSJun Yang 	if (dpaa2_flow_l4_src_port_extract(prot, field)) {
96356c1817dSJun Yang 		key_profile->l4_src_port_present = 1;
96456c1817dSJun Yang 		key_profile->l4_src_port_pos = pos;
96556c1817dSJun Yang 		key_profile->l4_src_port_offset =
96656c1817dSJun Yang 			key_profile->key_offset[pos];
96756c1817dSJun Yang 	} else if (dpaa2_flow_l4_dst_port_extract(prot, field)) {
96856c1817dSJun Yang 		key_profile->l4_dst_port_present = 1;
96956c1817dSJun Yang 		key_profile->l4_dst_port_pos = pos;
97056c1817dSJun Yang 		key_profile->l4_dst_port_offset =
97156c1817dSJun Yang 			key_profile->key_offset[pos];
9725f176728SJun Yang 	}
97356c1817dSJun Yang 	key_profile->key_max_size += field_size;
97456c1817dSJun Yang 
97556c1817dSJun Yang 	return pos;
9765f176728SJun Yang }
97756c1817dSJun Yang 
97856c1817dSJun Yang static int
979200a33e4SJun Yang dpaa2_flow_faf_add_hdr(int faf_byte,
980200a33e4SJun Yang 	struct dpaa2_dev_priv *priv,
981200a33e4SJun Yang 	enum dpaa2_flow_dist_type dist_type, int tc_id,
982200a33e4SJun Yang 	int *insert_offset)
983200a33e4SJun Yang {
984200a33e4SJun Yang 	int pos, i, offset;
985200a33e4SJun Yang 	struct dpaa2_key_extract *key_extract;
986200a33e4SJun Yang 	struct dpkg_profile_cfg *dpkg;
987200a33e4SJun Yang 	struct dpkg_extract *extracts;
988200a33e4SJun Yang 
989200a33e4SJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE)
990200a33e4SJun Yang 		key_extract = &priv->extract.qos_key_extract;
991200a33e4SJun Yang 	else
992200a33e4SJun Yang 		key_extract = &priv->extract.tc_key_extract[tc_id];
993200a33e4SJun Yang 
994200a33e4SJun Yang 	dpkg = &key_extract->dpkg;
995200a33e4SJun Yang 	extracts = dpkg->extracts;
996200a33e4SJun Yang 
997200a33e4SJun Yang 	if (dpkg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) {
998200a33e4SJun Yang 		DPAA2_PMD_ERR("Number of extracts overflows");
999200a33e4SJun Yang 		return -EINVAL;
1000200a33e4SJun Yang 	}
1001200a33e4SJun Yang 
1002200a33e4SJun Yang 	pos = dpaa2_flow_faf_advance(priv,
1003200a33e4SJun Yang 			faf_byte, dist_type, tc_id,
1004200a33e4SJun Yang 			insert_offset);
1005200a33e4SJun Yang 	if (pos < 0)
1006200a33e4SJun Yang 		return pos;
1007200a33e4SJun Yang 
1008200a33e4SJun Yang 	if (pos != dpkg->num_extracts) {
1009200a33e4SJun Yang 		/* Not the last pos, must have IP address extract.*/
1010200a33e4SJun Yang 		for (i = dpkg->num_extracts - 1; i >= pos; i--) {
1011200a33e4SJun Yang 			memcpy(&extracts[i + 1],
1012200a33e4SJun Yang 				&extracts[i], sizeof(struct dpkg_extract));
1013200a33e4SJun Yang 		}
1014200a33e4SJun Yang 	}
1015200a33e4SJun Yang 
1016200a33e4SJun Yang 	offset = DPAA2_FAFE_PSR_OFFSET + faf_byte;
1017200a33e4SJun Yang 
1018200a33e4SJun Yang 	extracts[pos].type = DPKG_EXTRACT_FROM_PARSE;
1019200a33e4SJun Yang 	extracts[pos].extract.from_parse.offset = offset;
1020200a33e4SJun Yang 	extracts[pos].extract.from_parse.size = 1;
1021200a33e4SJun Yang 
1022200a33e4SJun Yang 	dpkg->num_extracts++;
1023200a33e4SJun Yang 
1024200a33e4SJun Yang 	return 0;
1025200a33e4SJun Yang }
1026200a33e4SJun Yang 
1027200a33e4SJun Yang static int
102839c8044fSJun Yang dpaa2_flow_pr_add_hdr(uint32_t pr_offset,
102939c8044fSJun Yang 	uint32_t pr_size, struct dpaa2_dev_priv *priv,
103039c8044fSJun Yang 	enum dpaa2_flow_dist_type dist_type, int tc_id,
103139c8044fSJun Yang 	int *insert_offset)
103239c8044fSJun Yang {
103339c8044fSJun Yang 	int pos, i;
103439c8044fSJun Yang 	struct dpaa2_key_extract *key_extract;
103539c8044fSJun Yang 	struct dpkg_profile_cfg *dpkg;
103639c8044fSJun Yang 	struct dpkg_extract *extracts;
103739c8044fSJun Yang 
103839c8044fSJun Yang 	if ((pr_offset + pr_size) > DPAA2_FAPR_SIZE) {
103939c8044fSJun Yang 		DPAA2_PMD_ERR("PR extracts(%d:%d) overflow",
104039c8044fSJun Yang 			pr_offset, pr_size);
104139c8044fSJun Yang 		return -EINVAL;
104239c8044fSJun Yang 	}
104339c8044fSJun Yang 
104439c8044fSJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE)
104539c8044fSJun Yang 		key_extract = &priv->extract.qos_key_extract;
104639c8044fSJun Yang 	else
104739c8044fSJun Yang 		key_extract = &priv->extract.tc_key_extract[tc_id];
104839c8044fSJun Yang 
104939c8044fSJun Yang 	dpkg = &key_extract->dpkg;
105039c8044fSJun Yang 	extracts = dpkg->extracts;
105139c8044fSJun Yang 
105239c8044fSJun Yang 	if (dpkg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) {
105339c8044fSJun Yang 		DPAA2_PMD_ERR("Number of extracts overflows");
105439c8044fSJun Yang 		return -EINVAL;
105539c8044fSJun Yang 	}
105639c8044fSJun Yang 
105739c8044fSJun Yang 	pos = dpaa2_flow_pr_advance(priv,
105839c8044fSJun Yang 			pr_offset, pr_size, dist_type, tc_id,
105939c8044fSJun Yang 			insert_offset);
106039c8044fSJun Yang 	if (pos < 0)
106139c8044fSJun Yang 		return pos;
106239c8044fSJun Yang 
106339c8044fSJun Yang 	if (pos != dpkg->num_extracts) {
106439c8044fSJun Yang 		/* Not the last pos, must have IP address extract.*/
106539c8044fSJun Yang 		for (i = dpkg->num_extracts - 1; i >= pos; i--) {
106639c8044fSJun Yang 			memcpy(&extracts[i + 1],
106739c8044fSJun Yang 				&extracts[i], sizeof(struct dpkg_extract));
106839c8044fSJun Yang 		}
106939c8044fSJun Yang 	}
107039c8044fSJun Yang 
107139c8044fSJun Yang 	extracts[pos].type = DPKG_EXTRACT_FROM_PARSE;
107239c8044fSJun Yang 	extracts[pos].extract.from_parse.offset = pr_offset;
107339c8044fSJun Yang 	extracts[pos].extract.from_parse.size = pr_size;
107439c8044fSJun Yang 
107539c8044fSJun Yang 	dpkg->num_extracts++;
107639c8044fSJun Yang 
107739c8044fSJun Yang 	return 0;
107839c8044fSJun Yang }
107939c8044fSJun Yang 
108039c8044fSJun Yang static int
108156c1817dSJun Yang dpaa2_flow_extract_add_hdr(enum net_prot prot,
108256c1817dSJun Yang 	uint32_t field, uint8_t field_size,
108356c1817dSJun Yang 	struct dpaa2_dev_priv *priv,
108456c1817dSJun Yang 	enum dpaa2_flow_dist_type dist_type, int tc_id,
108556c1817dSJun Yang 	int *insert_offset)
108656c1817dSJun Yang {
108756c1817dSJun Yang 	int pos, i;
108856c1817dSJun Yang 	struct dpaa2_key_extract *key_extract;
108956c1817dSJun Yang 	struct dpkg_profile_cfg *dpkg;
109056c1817dSJun Yang 	struct dpkg_extract *extracts;
109156c1817dSJun Yang 
109256c1817dSJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE)
109356c1817dSJun Yang 		key_extract = &priv->extract.qos_key_extract;
109456c1817dSJun Yang 	else
109556c1817dSJun Yang 		key_extract = &priv->extract.tc_key_extract[tc_id];
109656c1817dSJun Yang 
109756c1817dSJun Yang 	dpkg = &key_extract->dpkg;
109856c1817dSJun Yang 	extracts = dpkg->extracts;
109956c1817dSJun Yang 
110056c1817dSJun Yang 	if (dpaa2_flow_ip_address_extract(prot, field)) {
110156c1817dSJun Yang 		DPAA2_PMD_ERR("%s only for none IP address extract",
110256c1817dSJun Yang 			__func__);
110356c1817dSJun Yang 		return -EINVAL;
11045f176728SJun Yang 	}
110556c1817dSJun Yang 
110656c1817dSJun Yang 	if (dpkg->num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) {
110756c1817dSJun Yang 		DPAA2_PMD_ERR("Number of extracts overflows");
110856c1817dSJun Yang 		return -EINVAL;
110956c1817dSJun Yang 	}
111056c1817dSJun Yang 
111156c1817dSJun Yang 	pos = dpaa2_flow_key_profile_advance(prot,
111256c1817dSJun Yang 			field, field_size, priv,
111356c1817dSJun Yang 			dist_type, tc_id,
111456c1817dSJun Yang 			insert_offset);
111556c1817dSJun Yang 	if (pos < 0)
111656c1817dSJun Yang 		return pos;
111756c1817dSJun Yang 
111856c1817dSJun Yang 	if (pos != dpkg->num_extracts) {
111956c1817dSJun Yang 		/* Not the last pos, must have IP address extract.*/
112056c1817dSJun Yang 		for (i = dpkg->num_extracts - 1; i >= pos; i--) {
112156c1817dSJun Yang 			memcpy(&extracts[i + 1],
112256c1817dSJun Yang 				&extracts[i], sizeof(struct dpkg_extract));
11235f176728SJun Yang 		}
11245f176728SJun Yang 	}
11255f176728SJun Yang 
112656c1817dSJun Yang 	extracts[pos].type = DPKG_EXTRACT_FROM_HDR;
112756c1817dSJun Yang 	extracts[pos].extract.from_hdr.prot = prot;
112856c1817dSJun Yang 	extracts[pos].extract.from_hdr.type = DPKG_FULL_FIELD;
112956c1817dSJun Yang 	extracts[pos].extract.from_hdr.field = field;
11305f176728SJun Yang 
11315f176728SJun Yang 	dpkg->num_extracts++;
11325f176728SJun Yang 
11335f176728SJun Yang 	return 0;
11345f176728SJun Yang }
11355f176728SJun Yang 
113656c1817dSJun Yang static int
1137e21bff64SJun Yang dpaa2_flow_extract_new_raw(struct dpaa2_dev_priv *priv,
1138e21bff64SJun Yang 	int offset, int size,
1139e21bff64SJun Yang 	enum dpaa2_flow_dist_type dist_type, int tc_id)
11403f881f8dSNipun Gupta {
1141e21bff64SJun Yang 	struct dpaa2_key_extract *key_extract;
1142e21bff64SJun Yang 	struct dpkg_profile_cfg *dpkg;
1143e21bff64SJun Yang 	struct dpaa2_key_profile *key_profile;
1144e21bff64SJun Yang 	int last_extract_size, index, pos, item_size;
1145e21bff64SJun Yang 	uint8_t num_extracts;
1146e21bff64SJun Yang 	uint32_t field;
11473f881f8dSNipun Gupta 
1148e21bff64SJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE)
1149e21bff64SJun Yang 		key_extract = &priv->extract.qos_key_extract;
1150e21bff64SJun Yang 	else
1151e21bff64SJun Yang 		key_extract = &priv->extract.tc_key_extract[tc_id];
1152e21bff64SJun Yang 
1153e21bff64SJun Yang 	dpkg = &key_extract->dpkg;
1154e21bff64SJun Yang 	key_profile = &key_extract->key_profile;
1155e21bff64SJun Yang 
1156e21bff64SJun Yang 	key_profile->raw_region.raw_start = 0;
1157e21bff64SJun Yang 	key_profile->raw_region.raw_size = 0;
11583f881f8dSNipun Gupta 
11593f881f8dSNipun Gupta 	last_extract_size = (size % DPAA2_FLOW_MAX_KEY_SIZE);
1160e21bff64SJun Yang 	num_extracts = (size / DPAA2_FLOW_MAX_KEY_SIZE);
11613f881f8dSNipun Gupta 	if (last_extract_size)
1162e21bff64SJun Yang 		num_extracts++;
11633f881f8dSNipun Gupta 	else
11643f881f8dSNipun Gupta 		last_extract_size = DPAA2_FLOW_MAX_KEY_SIZE;
11653f881f8dSNipun Gupta 
1166e21bff64SJun Yang 	for (index = 0; index < num_extracts; index++) {
1167e21bff64SJun Yang 		if (index == num_extracts - 1)
1168e21bff64SJun Yang 			item_size = last_extract_size;
11693f881f8dSNipun Gupta 		else
1170e21bff64SJun Yang 			item_size = DPAA2_FLOW_MAX_KEY_SIZE;
1171e21bff64SJun Yang 		field = offset << DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT;
1172e21bff64SJun Yang 		field |= item_size;
1173e21bff64SJun Yang 
1174e21bff64SJun Yang 		pos = dpaa2_flow_key_profile_advance(NET_PROT_PAYLOAD,
1175e21bff64SJun Yang 				field, item_size, priv, dist_type,
1176e21bff64SJun Yang 				tc_id, NULL);
1177e21bff64SJun Yang 		if (pos < 0)
1178e21bff64SJun Yang 			return pos;
1179e21bff64SJun Yang 
1180e21bff64SJun Yang 		dpkg->extracts[pos].type = DPKG_EXTRACT_FROM_DATA;
1181e21bff64SJun Yang 		dpkg->extracts[pos].extract.from_data.size = item_size;
1182e21bff64SJun Yang 		dpkg->extracts[pos].extract.from_data.offset = offset;
1183e21bff64SJun Yang 
1184e21bff64SJun Yang 		if (index == 0) {
1185e21bff64SJun Yang 			key_profile->raw_extract_pos = pos;
1186e21bff64SJun Yang 			key_profile->raw_extract_off =
1187e21bff64SJun Yang 				key_profile->key_offset[pos];
1188e21bff64SJun Yang 			key_profile->raw_region.raw_start = offset;
1189e21bff64SJun Yang 		}
1190e21bff64SJun Yang 		key_profile->raw_extract_num++;
1191e21bff64SJun Yang 		key_profile->raw_region.raw_size +=
1192e21bff64SJun Yang 			key_profile->key_size[pos];
1193e21bff64SJun Yang 
1194e21bff64SJun Yang 		offset += item_size;
1195e21bff64SJun Yang 		dpkg->num_extracts++;
11963f881f8dSNipun Gupta 	}
11973f881f8dSNipun Gupta 
11983f881f8dSNipun Gupta 	return 0;
11993f881f8dSNipun Gupta }
12003f881f8dSNipun Gupta 
1201e21bff64SJun Yang static int
1202e21bff64SJun Yang dpaa2_flow_extract_add_raw(struct dpaa2_dev_priv *priv,
1203e21bff64SJun Yang 	int offset, int size, enum dpaa2_flow_dist_type dist_type,
1204e21bff64SJun Yang 	int tc_id, int *recfg)
1205e21bff64SJun Yang {
1206e21bff64SJun Yang 	struct dpaa2_key_profile *key_profile;
1207e21bff64SJun Yang 	struct dpaa2_raw_region *raw_region;
1208e21bff64SJun Yang 	int end = offset + size, ret = 0, extract_extended, sz_extend;
1209e21bff64SJun Yang 	int start_cmp, end_cmp, new_size, index, pos, end_pos;
1210e21bff64SJun Yang 	int last_extract_size, item_size, num_extracts, bk_num = 0;
1211e21bff64SJun Yang 	struct dpkg_extract extract_bk[DPKG_MAX_NUM_OF_EXTRACTS];
1212e21bff64SJun Yang 	uint8_t key_offset_bk[DPKG_MAX_NUM_OF_EXTRACTS];
1213e21bff64SJun Yang 	uint8_t key_size_bk[DPKG_MAX_NUM_OF_EXTRACTS];
1214e21bff64SJun Yang 	struct key_prot_field prot_field_bk[DPKG_MAX_NUM_OF_EXTRACTS];
1215e21bff64SJun Yang 	struct dpaa2_raw_region raw_hole;
1216e21bff64SJun Yang 	struct dpkg_profile_cfg *dpkg;
1217e21bff64SJun Yang 	enum net_prot prot;
1218e21bff64SJun Yang 	uint32_t field;
1219e21bff64SJun Yang 
1220e21bff64SJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE) {
1221e21bff64SJun Yang 		key_profile = &priv->extract.qos_key_extract.key_profile;
1222e21bff64SJun Yang 		dpkg = &priv->extract.qos_key_extract.dpkg;
1223e21bff64SJun Yang 	} else {
1224e21bff64SJun Yang 		key_profile = &priv->extract.tc_key_extract[tc_id].key_profile;
1225e21bff64SJun Yang 		dpkg = &priv->extract.tc_key_extract[tc_id].dpkg;
1226e21bff64SJun Yang 	}
1227e21bff64SJun Yang 
1228e21bff64SJun Yang 	raw_region = &key_profile->raw_region;
1229e21bff64SJun Yang 	if (!raw_region->raw_size) {
1230e21bff64SJun Yang 		/* New RAW region*/
1231e21bff64SJun Yang 		ret = dpaa2_flow_extract_new_raw(priv, offset, size,
1232e21bff64SJun Yang 			dist_type, tc_id);
1233e21bff64SJun Yang 		if (!ret && recfg)
1234e21bff64SJun Yang 			(*recfg) |= dist_type;
1235e21bff64SJun Yang 
1236e21bff64SJun Yang 		return ret;
1237e21bff64SJun Yang 	}
1238e21bff64SJun Yang 	start_cmp = raw_region->raw_start;
1239e21bff64SJun Yang 	end_cmp = raw_region->raw_start + raw_region->raw_size;
1240e21bff64SJun Yang 
1241e21bff64SJun Yang 	if (offset >= start_cmp && end <= end_cmp)
1242e21bff64SJun Yang 		return 0;
1243e21bff64SJun Yang 
1244e21bff64SJun Yang 	sz_extend = 0;
1245e21bff64SJun Yang 	new_size = raw_region->raw_size;
1246e21bff64SJun Yang 	if (offset < start_cmp) {
1247e21bff64SJun Yang 		sz_extend += start_cmp - offset;
1248e21bff64SJun Yang 		new_size += (start_cmp - offset);
1249e21bff64SJun Yang 	}
1250e21bff64SJun Yang 	if (end > end_cmp) {
1251e21bff64SJun Yang 		sz_extend += end - end_cmp;
1252e21bff64SJun Yang 		new_size += (end - end_cmp);
1253e21bff64SJun Yang 	}
1254e21bff64SJun Yang 
1255e21bff64SJun Yang 	last_extract_size = (new_size % DPAA2_FLOW_MAX_KEY_SIZE);
1256e21bff64SJun Yang 	num_extracts = (new_size / DPAA2_FLOW_MAX_KEY_SIZE);
1257e21bff64SJun Yang 	if (last_extract_size)
1258e21bff64SJun Yang 		num_extracts++;
1259e21bff64SJun Yang 	else
1260e21bff64SJun Yang 		last_extract_size = DPAA2_FLOW_MAX_KEY_SIZE;
1261e21bff64SJun Yang 
1262e21bff64SJun Yang 	if ((key_profile->num + num_extracts -
1263e21bff64SJun Yang 		key_profile->raw_extract_num) >=
1264e21bff64SJun Yang 		DPKG_MAX_NUM_OF_EXTRACTS) {
1265e21bff64SJun Yang 		DPAA2_PMD_ERR("%s Failed to expand raw extracts",
1266e21bff64SJun Yang 			__func__);
1267e21bff64SJun Yang 		return -EINVAL;
1268e21bff64SJun Yang 	}
1269e21bff64SJun Yang 
1270e21bff64SJun Yang 	if (offset < start_cmp) {
1271e21bff64SJun Yang 		raw_hole.raw_start = key_profile->raw_extract_off;
1272e21bff64SJun Yang 		raw_hole.raw_size = start_cmp - offset;
1273e21bff64SJun Yang 		raw_region->raw_start = offset;
1274e21bff64SJun Yang 		raw_region->raw_size += start_cmp - offset;
1275e21bff64SJun Yang 
1276e21bff64SJun Yang 		if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1277e21bff64SJun Yang 			ret = dpaa2_flow_qos_rule_insert_hole(priv,
1278e21bff64SJun Yang 					raw_hole.raw_start,
1279e21bff64SJun Yang 					raw_hole.raw_size);
1280e21bff64SJun Yang 			if (ret)
1281e21bff64SJun Yang 				return ret;
1282e21bff64SJun Yang 		}
1283e21bff64SJun Yang 		if (dist_type & DPAA2_FLOW_FS_TYPE) {
1284e21bff64SJun Yang 			ret = dpaa2_flow_fs_rule_insert_hole(priv,
1285e21bff64SJun Yang 					raw_hole.raw_start,
1286e21bff64SJun Yang 					raw_hole.raw_size, tc_id);
1287e21bff64SJun Yang 			if (ret)
1288e21bff64SJun Yang 				return ret;
1289e21bff64SJun Yang 		}
1290e21bff64SJun Yang 	}
1291e21bff64SJun Yang 
1292e21bff64SJun Yang 	if (end > end_cmp) {
1293e21bff64SJun Yang 		raw_hole.raw_start =
1294e21bff64SJun Yang 			key_profile->raw_extract_off +
1295e21bff64SJun Yang 			raw_region->raw_size;
1296e21bff64SJun Yang 		raw_hole.raw_size = end - end_cmp;
1297e21bff64SJun Yang 		raw_region->raw_size += end - end_cmp;
1298e21bff64SJun Yang 
1299e21bff64SJun Yang 		if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1300e21bff64SJun Yang 			ret = dpaa2_flow_qos_rule_insert_hole(priv,
1301e21bff64SJun Yang 					raw_hole.raw_start,
1302e21bff64SJun Yang 					raw_hole.raw_size);
1303e21bff64SJun Yang 			if (ret)
1304e21bff64SJun Yang 				return ret;
1305e21bff64SJun Yang 		}
1306e21bff64SJun Yang 		if (dist_type & DPAA2_FLOW_FS_TYPE) {
1307e21bff64SJun Yang 			ret = dpaa2_flow_fs_rule_insert_hole(priv,
1308e21bff64SJun Yang 					raw_hole.raw_start,
1309e21bff64SJun Yang 					raw_hole.raw_size, tc_id);
1310e21bff64SJun Yang 			if (ret)
1311e21bff64SJun Yang 				return ret;
1312e21bff64SJun Yang 		}
1313e21bff64SJun Yang 	}
1314e21bff64SJun Yang 
1315e21bff64SJun Yang 	end_pos = key_profile->raw_extract_pos +
1316e21bff64SJun Yang 		key_profile->raw_extract_num;
1317e21bff64SJun Yang 	if (key_profile->num > end_pos) {
1318e21bff64SJun Yang 		bk_num = key_profile->num - end_pos;
1319e21bff64SJun Yang 		memcpy(extract_bk, &dpkg->extracts[end_pos],
1320e21bff64SJun Yang 			bk_num * sizeof(struct dpkg_extract));
1321e21bff64SJun Yang 		memcpy(key_offset_bk, &key_profile->key_offset[end_pos],
1322e21bff64SJun Yang 			bk_num * sizeof(uint8_t));
1323e21bff64SJun Yang 		memcpy(key_size_bk, &key_profile->key_size[end_pos],
1324e21bff64SJun Yang 			bk_num * sizeof(uint8_t));
1325e21bff64SJun Yang 		memcpy(prot_field_bk, &key_profile->prot_field[end_pos],
1326e21bff64SJun Yang 			bk_num * sizeof(struct key_prot_field));
1327e21bff64SJun Yang 
1328e21bff64SJun Yang 		for (index = 0; index < bk_num; index++) {
1329e21bff64SJun Yang 			key_offset_bk[index] += sz_extend;
1330e21bff64SJun Yang 			prot = prot_field_bk[index].prot;
1331e21bff64SJun Yang 			field = prot_field_bk[index].key_field;
1332e21bff64SJun Yang 			if (dpaa2_flow_l4_src_port_extract(prot,
1333e21bff64SJun Yang 				field)) {
1334e21bff64SJun Yang 				key_profile->l4_src_port_present = 1;
1335e21bff64SJun Yang 				key_profile->l4_src_port_pos = end_pos + index;
1336e21bff64SJun Yang 				key_profile->l4_src_port_offset =
1337e21bff64SJun Yang 					key_offset_bk[index];
1338e21bff64SJun Yang 			} else if (dpaa2_flow_l4_dst_port_extract(prot,
1339e21bff64SJun Yang 				field)) {
1340e21bff64SJun Yang 				key_profile->l4_dst_port_present = 1;
1341e21bff64SJun Yang 				key_profile->l4_dst_port_pos = end_pos + index;
1342e21bff64SJun Yang 				key_profile->l4_dst_port_offset =
1343e21bff64SJun Yang 					key_offset_bk[index];
1344e21bff64SJun Yang 			}
1345e21bff64SJun Yang 		}
1346e21bff64SJun Yang 	}
1347e21bff64SJun Yang 
1348e21bff64SJun Yang 	pos = key_profile->raw_extract_pos;
1349e21bff64SJun Yang 
1350e21bff64SJun Yang 	for (index = 0; index < num_extracts; index++) {
1351e21bff64SJun Yang 		if (index == num_extracts - 1)
1352e21bff64SJun Yang 			item_size = last_extract_size;
1353e21bff64SJun Yang 		else
1354e21bff64SJun Yang 			item_size = DPAA2_FLOW_MAX_KEY_SIZE;
1355e21bff64SJun Yang 		field = offset << DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT;
1356e21bff64SJun Yang 		field |= item_size;
1357e21bff64SJun Yang 
1358e21bff64SJun Yang 		if (pos > 0) {
1359e21bff64SJun Yang 			key_profile->key_offset[pos] =
1360e21bff64SJun Yang 				key_profile->key_offset[pos - 1] +
1361e21bff64SJun Yang 				key_profile->key_size[pos - 1];
1362e21bff64SJun Yang 		} else {
1363e21bff64SJun Yang 			key_profile->key_offset[pos] = 0;
1364e21bff64SJun Yang 		}
1365e21bff64SJun Yang 		key_profile->key_size[pos] = item_size;
1366200a33e4SJun Yang 		key_profile->prot_field[pos].type = DPAA2_NET_PROT_KEY;
1367e21bff64SJun Yang 		key_profile->prot_field[pos].prot = NET_PROT_PAYLOAD;
1368e21bff64SJun Yang 		key_profile->prot_field[pos].key_field = field;
1369e21bff64SJun Yang 
1370e21bff64SJun Yang 		dpkg->extracts[pos].type = DPKG_EXTRACT_FROM_DATA;
1371e21bff64SJun Yang 		dpkg->extracts[pos].extract.from_data.size = item_size;
1372e21bff64SJun Yang 		dpkg->extracts[pos].extract.from_data.offset = offset;
1373e21bff64SJun Yang 		offset += item_size;
1374e21bff64SJun Yang 		pos++;
1375e21bff64SJun Yang 	}
1376e21bff64SJun Yang 
1377e21bff64SJun Yang 	if (bk_num) {
1378e21bff64SJun Yang 		memcpy(&dpkg->extracts[pos], extract_bk,
1379e21bff64SJun Yang 			bk_num * sizeof(struct dpkg_extract));
1380e21bff64SJun Yang 		memcpy(&key_profile->key_offset[end_pos],
1381e21bff64SJun Yang 			key_offset_bk, bk_num * sizeof(uint8_t));
1382e21bff64SJun Yang 		memcpy(&key_profile->key_size[end_pos],
1383e21bff64SJun Yang 			key_size_bk, bk_num * sizeof(uint8_t));
1384e21bff64SJun Yang 		memcpy(&key_profile->prot_field[end_pos],
1385e21bff64SJun Yang 			prot_field_bk, bk_num * sizeof(struct key_prot_field));
1386e21bff64SJun Yang 	}
1387e21bff64SJun Yang 
1388e21bff64SJun Yang 	extract_extended = num_extracts - key_profile->raw_extract_num;
1389e21bff64SJun Yang 	if (key_profile->ip_addr_type != IP_NONE_ADDR_EXTRACT) {
1390e21bff64SJun Yang 		key_profile->ip_addr_extract_pos += extract_extended;
1391e21bff64SJun Yang 		key_profile->ip_addr_extract_off += sz_extend;
1392e21bff64SJun Yang 	}
1393e21bff64SJun Yang 	key_profile->raw_extract_num = num_extracts;
1394e21bff64SJun Yang 	key_profile->num += extract_extended;
1395e21bff64SJun Yang 	key_profile->key_max_size += sz_extend;
1396e21bff64SJun Yang 
1397e21bff64SJun Yang 	dpkg->num_extracts += extract_extended;
1398e21bff64SJun Yang 	if (!ret && recfg)
1399e21bff64SJun Yang 		(*recfg) |= dist_type;
1400e21bff64SJun Yang 
1401e21bff64SJun Yang 	return ret;
1402e21bff64SJun Yang }
1403e21bff64SJun Yang 
14045f176728SJun Yang static inline int
140556c1817dSJun Yang dpaa2_flow_extract_search(struct dpaa2_key_profile *key_profile,
1406200a33e4SJun Yang 	enum key_prot_type type, enum net_prot prot, uint32_t key_field)
14075f176728SJun Yang {
140856c1817dSJun Yang 	int pos;
140956c1817dSJun Yang 	struct key_prot_field *prot_field;
141056c1817dSJun Yang 
141156c1817dSJun Yang 	if (dpaa2_flow_ip_address_extract(prot, key_field)) {
141256c1817dSJun Yang 		DPAA2_PMD_ERR("%s only for none IP address extract",
141356c1817dSJun Yang 			__func__);
141456c1817dSJun Yang 		return -EINVAL;
14155f176728SJun Yang 	}
14165f176728SJun Yang 
141756c1817dSJun Yang 	prot_field = key_profile->prot_field;
141856c1817dSJun Yang 	for (pos = 0; pos < key_profile->num; pos++) {
1419200a33e4SJun Yang 		if (type == DPAA2_NET_PROT_KEY &&
1420200a33e4SJun Yang 			prot_field[pos].prot == prot &&
1421200a33e4SJun Yang 			prot_field[pos].key_field == key_field &&
1422200a33e4SJun Yang 			prot_field[pos].type == type)
1423200a33e4SJun Yang 			return pos;
1424200a33e4SJun Yang 		else if (type == DPAA2_FAF_KEY &&
1425200a33e4SJun Yang 			prot_field[pos].key_field == key_field &&
1426200a33e4SJun Yang 			prot_field[pos].type == type)
142756c1817dSJun Yang 			return pos;
142839c8044fSJun Yang 		else if (type == DPAA2_PR_KEY &&
142939c8044fSJun Yang 			prot_field[pos].key_field == key_field &&
143039c8044fSJun Yang 			prot_field[pos].type == type)
143139c8044fSJun Yang 			return pos;
143256c1817dSJun Yang 	}
14335f176728SJun Yang 
1434200a33e4SJun Yang 	if (type == DPAA2_NET_PROT_KEY &&
1435200a33e4SJun Yang 		dpaa2_flow_l4_src_port_extract(prot, key_field)) {
143656c1817dSJun Yang 		if (key_profile->l4_src_port_present)
143756c1817dSJun Yang 			return key_profile->l4_src_port_pos;
1438200a33e4SJun Yang 	} else if (type == DPAA2_NET_PROT_KEY &&
1439200a33e4SJun Yang 		dpaa2_flow_l4_dst_port_extract(prot, key_field)) {
144056c1817dSJun Yang 		if (key_profile->l4_dst_port_present)
144156c1817dSJun Yang 			return key_profile->l4_dst_port_pos;
144256c1817dSJun Yang 	}
144356c1817dSJun Yang 
144456c1817dSJun Yang 	return -ENXIO;
144556c1817dSJun Yang }
144656c1817dSJun Yang 
144756c1817dSJun Yang static inline int
144856c1817dSJun Yang dpaa2_flow_extract_key_offset(struct dpaa2_key_profile *key_profile,
1449200a33e4SJun Yang 	enum key_prot_type type, enum net_prot prot, uint32_t key_field)
14505f176728SJun Yang {
14515f176728SJun Yang 	int i;
14525f176728SJun Yang 
1453200a33e4SJun Yang 	i = dpaa2_flow_extract_search(key_profile, type, prot, key_field);
145456c1817dSJun Yang 	if (i >= 0)
145556c1817dSJun Yang 		return key_profile->key_offset[i];
145656c1817dSJun Yang 	else
14575f176728SJun Yang 		return i;
14585f176728SJun Yang }
14595f176728SJun Yang 
14605f176728SJun Yang static int
1461200a33e4SJun Yang dpaa2_flow_faf_add_rule(struct dpaa2_dev_priv *priv,
146256c1817dSJun Yang 	struct dpaa2_dev_flow *flow,
1463200a33e4SJun Yang 	enum dpaa2_rx_faf_offset faf_bit_off,
146456c1817dSJun Yang 	int group,
146556c1817dSJun Yang 	enum dpaa2_flow_dist_type dist_type)
14665f176728SJun Yang {
14675f176728SJun Yang 	int offset;
146856c1817dSJun Yang 	uint8_t *key_addr;
146956c1817dSJun Yang 	uint8_t *mask_addr;
147056c1817dSJun Yang 	struct dpaa2_key_extract *key_extract;
147156c1817dSJun Yang 	struct dpaa2_key_profile *key_profile;
1472200a33e4SJun Yang 	uint8_t faf_byte = faf_bit_off / 8;
1473200a33e4SJun Yang 	uint8_t faf_bit_in_byte = faf_bit_off % 8;
14745f176728SJun Yang 
1475200a33e4SJun Yang 	faf_bit_in_byte = 7 - faf_bit_in_byte;
14765f176728SJun Yang 
147756c1817dSJun Yang 	if (dist_type & DPAA2_FLOW_QOS_TYPE) {
147856c1817dSJun Yang 		key_extract = &priv->extract.qos_key_extract;
147956c1817dSJun Yang 		key_profile = &key_extract->key_profile;
148056c1817dSJun Yang 
148156c1817dSJun Yang 		offset = dpaa2_flow_extract_key_offset(key_profile,
1482200a33e4SJun Yang 				DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte);
14835f176728SJun Yang 		if (offset < 0) {
148456c1817dSJun Yang 			DPAA2_PMD_ERR("%s QoS key extract failed", __func__);
148556c1817dSJun Yang 			return -EINVAL;
14865f176728SJun Yang 		}
148756c1817dSJun Yang 		key_addr = flow->qos_key_addr + offset;
148856c1817dSJun Yang 		mask_addr = flow->qos_mask_addr + offset;
1489200a33e4SJun Yang 
1490200a33e4SJun Yang 		if (!(*key_addr) &&
1491200a33e4SJun Yang 			key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT)
1492200a33e4SJun Yang 			flow->qos_rule_size++;
1493200a33e4SJun Yang 
1494200a33e4SJun Yang 		*key_addr |=  (1 << faf_bit_in_byte);
1495200a33e4SJun Yang 		*mask_addr |=  (1 << faf_bit_in_byte);
14965f176728SJun Yang 	}
14975f176728SJun Yang 
149856c1817dSJun Yang 	if (dist_type & DPAA2_FLOW_FS_TYPE) {
149956c1817dSJun Yang 		key_extract = &priv->extract.tc_key_extract[group];
150056c1817dSJun Yang 		key_profile = &key_extract->key_profile;
150156c1817dSJun Yang 
150256c1817dSJun Yang 		offset = dpaa2_flow_extract_key_offset(key_profile,
1503200a33e4SJun Yang 				DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte);
15045f176728SJun Yang 		if (offset < 0) {
150556c1817dSJun Yang 			DPAA2_PMD_ERR("%s TC[%d] key extract failed",
150656c1817dSJun Yang 				__func__, group);
150756c1817dSJun Yang 			return -EINVAL;
15085f176728SJun Yang 		}
150956c1817dSJun Yang 		key_addr = flow->fs_key_addr + offset;
151056c1817dSJun Yang 		mask_addr = flow->fs_mask_addr + offset;
15115f176728SJun Yang 
1512200a33e4SJun Yang 		if (!(*key_addr) &&
1513200a33e4SJun Yang 			key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT)
1514200a33e4SJun Yang 			flow->fs_rule_size++;
1515200a33e4SJun Yang 
1516200a33e4SJun Yang 		*key_addr |=  (1 << faf_bit_in_byte);
1517200a33e4SJun Yang 		*mask_addr |=  (1 << faf_bit_in_byte);
15185f176728SJun Yang 	}
15195f176728SJun Yang 
15205f176728SJun Yang 	return 0;
15215f176728SJun Yang }
15225f176728SJun Yang 
15235f176728SJun Yang static inline int
152439c8044fSJun Yang dpaa2_flow_pr_rule_data_set(struct dpaa2_dev_flow *flow,
152539c8044fSJun Yang 	struct dpaa2_key_profile *key_profile,
152639c8044fSJun Yang 	uint32_t pr_offset, uint32_t pr_size,
152739c8044fSJun Yang 	const void *key, const void *mask,
152839c8044fSJun Yang 	enum dpaa2_flow_dist_type dist_type)
152939c8044fSJun Yang {
153039c8044fSJun Yang 	int offset;
153139c8044fSJun Yang 	uint32_t pr_field = pr_offset << 16 | pr_size;
153239c8044fSJun Yang 
153339c8044fSJun Yang 	offset = dpaa2_flow_extract_key_offset(key_profile,
153439c8044fSJun Yang 			DPAA2_PR_KEY, NET_PROT_NONE, pr_field);
153539c8044fSJun Yang 	if (offset < 0) {
153639c8044fSJun Yang 		DPAA2_PMD_ERR("PR off(%d)/size(%d) does not exist!",
153739c8044fSJun Yang 			pr_offset, pr_size);
153839c8044fSJun Yang 		return -EINVAL;
153939c8044fSJun Yang 	}
154039c8044fSJun Yang 
154139c8044fSJun Yang 	if (dist_type & DPAA2_FLOW_QOS_TYPE) {
154239c8044fSJun Yang 		memcpy((flow->qos_key_addr + offset), key, pr_size);
154339c8044fSJun Yang 		memcpy((flow->qos_mask_addr + offset), mask, pr_size);
154439c8044fSJun Yang 		if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT)
154539c8044fSJun Yang 			flow->qos_rule_size = offset + pr_size;
154639c8044fSJun Yang 	}
154739c8044fSJun Yang 
154839c8044fSJun Yang 	if (dist_type & DPAA2_FLOW_FS_TYPE) {
154939c8044fSJun Yang 		memcpy((flow->fs_key_addr + offset), key, pr_size);
155039c8044fSJun Yang 		memcpy((flow->fs_mask_addr + offset), mask, pr_size);
155139c8044fSJun Yang 		if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT)
155239c8044fSJun Yang 			flow->fs_rule_size = offset + pr_size;
155339c8044fSJun Yang 	}
155439c8044fSJun Yang 
155539c8044fSJun Yang 	return 0;
155639c8044fSJun Yang }
155739c8044fSJun Yang 
155839c8044fSJun Yang static inline int
155956c1817dSJun Yang dpaa2_flow_hdr_rule_data_set(struct dpaa2_dev_flow *flow,
156056c1817dSJun Yang 	struct dpaa2_key_profile *key_profile,
156156c1817dSJun Yang 	enum net_prot prot, uint32_t field, int size,
156256c1817dSJun Yang 	const void *key, const void *mask,
156356c1817dSJun Yang 	enum dpaa2_flow_dist_type dist_type)
15645f176728SJun Yang {
156556c1817dSJun Yang 	int offset;
15665f176728SJun Yang 
156756c1817dSJun Yang 	if (dpaa2_flow_ip_address_extract(prot, field)) {
156856c1817dSJun Yang 		DPAA2_PMD_ERR("%s only for none IP address extract",
156956c1817dSJun Yang 			__func__);
157056c1817dSJun Yang 		return -EINVAL;
15715f176728SJun Yang 	}
1572d0a77dc3SJun Yang 
157356c1817dSJun Yang 	offset = dpaa2_flow_extract_key_offset(key_profile,
1574200a33e4SJun Yang 			DPAA2_NET_PROT_KEY, prot, field);
157556c1817dSJun Yang 	if (offset < 0) {
157656c1817dSJun Yang 		DPAA2_PMD_ERR("P(%d)/F(%d) does not exist!",
157756c1817dSJun Yang 			prot, field);
157856c1817dSJun Yang 		return -EINVAL;
157956c1817dSJun Yang 	}
158056c1817dSJun Yang 
158156c1817dSJun Yang 	if (dist_type & DPAA2_FLOW_QOS_TYPE) {
158256c1817dSJun Yang 		memcpy((flow->qos_key_addr + offset), key, size);
158356c1817dSJun Yang 		memcpy((flow->qos_mask_addr + offset), mask, size);
158456c1817dSJun Yang 		if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT)
158556c1817dSJun Yang 			flow->qos_rule_size = offset + size;
158656c1817dSJun Yang 	}
158756c1817dSJun Yang 
158856c1817dSJun Yang 	if (dist_type & DPAA2_FLOW_FS_TYPE) {
158956c1817dSJun Yang 		memcpy((flow->fs_key_addr + offset), key, size);
159056c1817dSJun Yang 		memcpy((flow->fs_mask_addr + offset), mask, size);
159156c1817dSJun Yang 		if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT)
159256c1817dSJun Yang 			flow->fs_rule_size = offset + size;
159356c1817dSJun Yang 	}
15945f176728SJun Yang 
15955f176728SJun Yang 	return 0;
15965f176728SJun Yang }
15975f176728SJun Yang 
15985f176728SJun Yang static inline int
1599e21bff64SJun Yang dpaa2_flow_raw_rule_data_set(struct dpaa2_dev_flow *flow,
1600e21bff64SJun Yang 	struct dpaa2_key_profile *key_profile,
1601e21bff64SJun Yang 	uint32_t extract_offset, int size,
1602e21bff64SJun Yang 	const void *key, const void *mask,
1603e21bff64SJun Yang 	enum dpaa2_flow_dist_type dist_type)
16043f881f8dSNipun Gupta {
1605e21bff64SJun Yang 	int extract_size = size > DPAA2_FLOW_MAX_KEY_SIZE ?
1606e21bff64SJun Yang 		DPAA2_FLOW_MAX_KEY_SIZE : size;
1607e21bff64SJun Yang 	int offset, field;
16083f881f8dSNipun Gupta 
1609e21bff64SJun Yang 	field = extract_offset << DPAA2_FLOW_RAW_OFFSET_FIELD_SHIFT;
1610e21bff64SJun Yang 	field |= extract_size;
1611e21bff64SJun Yang 	offset = dpaa2_flow_extract_key_offset(key_profile,
1612200a33e4SJun Yang 			DPAA2_NET_PROT_KEY, NET_PROT_PAYLOAD, field);
1613e21bff64SJun Yang 	if (offset < 0) {
1614e21bff64SJun Yang 		DPAA2_PMD_ERR("offset(%d)/size(%d) raw extract failed",
1615e21bff64SJun Yang 			extract_offset, size);
1616e21bff64SJun Yang 		return -EINVAL;
1617e21bff64SJun Yang 	}
1618e21bff64SJun Yang 
1619e21bff64SJun Yang 	if (dist_type & DPAA2_FLOW_QOS_TYPE) {
1620e21bff64SJun Yang 		memcpy((flow->qos_key_addr + offset), key, size);
1621e21bff64SJun Yang 		memcpy((flow->qos_mask_addr + offset), mask, size);
1622e21bff64SJun Yang 		flow->qos_rule_size = offset + size;
1623e21bff64SJun Yang 	}
1624e21bff64SJun Yang 
1625e21bff64SJun Yang 	if (dist_type & DPAA2_FLOW_FS_TYPE) {
1626e21bff64SJun Yang 		memcpy((flow->fs_key_addr + offset), key, size);
1627e21bff64SJun Yang 		memcpy((flow->fs_mask_addr + offset), mask, size);
1628e21bff64SJun Yang 		flow->fs_rule_size = offset + size;
1629e21bff64SJun Yang 	}
16303f881f8dSNipun Gupta 
16313f881f8dSNipun Gupta 	return 0;
16323f881f8dSNipun Gupta }
16333f881f8dSNipun Gupta 
1634fe2b986aSSunil Kumar Kori static int
163556c1817dSJun Yang dpaa2_flow_extract_support(const uint8_t *mask_src,
1636926c1279SJun Yang 	enum rte_flow_item_type type)
1637926c1279SJun Yang {
1638926c1279SJun Yang 	char mask[64];
1639926c1279SJun Yang 	int i, size = 0;
1640926c1279SJun Yang 	const char *mask_support = 0;
1641926c1279SJun Yang 
1642926c1279SJun Yang 	switch (type) {
1643926c1279SJun Yang 	case RTE_FLOW_ITEM_TYPE_ETH:
1644926c1279SJun Yang 		mask_support = (const char *)&dpaa2_flow_item_eth_mask;
1645926c1279SJun Yang 		size = sizeof(struct rte_flow_item_eth);
1646926c1279SJun Yang 		break;
1647926c1279SJun Yang 	case RTE_FLOW_ITEM_TYPE_VLAN:
1648926c1279SJun Yang 		mask_support = (const char *)&dpaa2_flow_item_vlan_mask;
1649926c1279SJun Yang 		size = sizeof(struct rte_flow_item_vlan);
1650926c1279SJun Yang 		break;
1651926c1279SJun Yang 	case RTE_FLOW_ITEM_TYPE_IPV4:
1652926c1279SJun Yang 		mask_support = (const char *)&dpaa2_flow_item_ipv4_mask;
1653926c1279SJun Yang 		size = sizeof(struct rte_flow_item_ipv4);
1654926c1279SJun Yang 		break;
1655926c1279SJun Yang 	case RTE_FLOW_ITEM_TYPE_IPV6:
1656926c1279SJun Yang 		mask_support = (const char *)&dpaa2_flow_item_ipv6_mask;
1657926c1279SJun Yang 		size = sizeof(struct rte_flow_item_ipv6);
1658926c1279SJun Yang 		break;
1659926c1279SJun Yang 	case RTE_FLOW_ITEM_TYPE_ICMP:
1660926c1279SJun Yang 		mask_support = (const char *)&dpaa2_flow_item_icmp_mask;
1661926c1279SJun Yang 		size = sizeof(struct rte_flow_item_icmp);
1662926c1279SJun Yang 		break;
1663926c1279SJun Yang 	case RTE_FLOW_ITEM_TYPE_UDP:
1664926c1279SJun Yang 		mask_support = (const char *)&dpaa2_flow_item_udp_mask;
1665926c1279SJun Yang 		size = sizeof(struct rte_flow_item_udp);
1666926c1279SJun Yang 		break;
1667926c1279SJun Yang 	case RTE_FLOW_ITEM_TYPE_TCP:
1668926c1279SJun Yang 		mask_support = (const char *)&dpaa2_flow_item_tcp_mask;
1669926c1279SJun Yang 		size = sizeof(struct rte_flow_item_tcp);
1670926c1279SJun Yang 		break;
16714cc5cf4aSJun Yang 	case RTE_FLOW_ITEM_TYPE_ESP:
16724cc5cf4aSJun Yang 		mask_support = (const char *)&dpaa2_flow_item_esp_mask;
16734cc5cf4aSJun Yang 		size = sizeof(struct rte_flow_item_esp);
16744cc5cf4aSJun Yang 		break;
16754cc5cf4aSJun Yang 	case RTE_FLOW_ITEM_TYPE_AH:
16764cc5cf4aSJun Yang 		mask_support = (const char *)&dpaa2_flow_item_ah_mask;
16774cc5cf4aSJun Yang 		size = sizeof(struct rte_flow_item_ah);
16784cc5cf4aSJun Yang 		break;
1679926c1279SJun Yang 	case RTE_FLOW_ITEM_TYPE_SCTP:
1680926c1279SJun Yang 		mask_support = (const char *)&dpaa2_flow_item_sctp_mask;
1681926c1279SJun Yang 		size = sizeof(struct rte_flow_item_sctp);
1682926c1279SJun Yang 		break;
1683926c1279SJun Yang 	case RTE_FLOW_ITEM_TYPE_GRE:
1684926c1279SJun Yang 		mask_support = (const char *)&dpaa2_flow_item_gre_mask;
1685926c1279SJun Yang 		size = sizeof(struct rte_flow_item_gre);
1686926c1279SJun Yang 		break;
168739c8044fSJun Yang 	case RTE_FLOW_ITEM_TYPE_VXLAN:
168839c8044fSJun Yang 		mask_support = (const char *)&dpaa2_flow_item_vxlan_mask;
168939c8044fSJun Yang 		size = sizeof(struct rte_flow_item_vxlan);
169039c8044fSJun Yang 		break;
1691a8a6b82eSJun Yang 	case RTE_FLOW_ITEM_TYPE_ECPRI:
1692a8a6b82eSJun Yang 		mask_support = (const char *)&dpaa2_flow_item_ecpri_mask;
1693a8a6b82eSJun Yang 		size = sizeof(struct rte_flow_item_ecpri);
1694a8a6b82eSJun Yang 		break;
1695146c745eSJun Yang 	case RTE_FLOW_ITEM_TYPE_GTP:
1696146c745eSJun Yang 		mask_support = (const char *)&dpaa2_flow_item_gtp_mask;
1697146c745eSJun Yang 		size = sizeof(struct rte_flow_item_gtp);
1698146c745eSJun Yang 		break;
1699926c1279SJun Yang 	default:
170056c1817dSJun Yang 		return -EINVAL;
1701926c1279SJun Yang 	}
1702926c1279SJun Yang 
1703926c1279SJun Yang 	memcpy(mask, mask_support, size);
1704926c1279SJun Yang 
1705926c1279SJun Yang 	for (i = 0; i < size; i++)
1706926c1279SJun Yang 		mask[i] = (mask[i] | mask_src[i]);
1707926c1279SJun Yang 
1708926c1279SJun Yang 	if (memcmp(mask, mask_support, size))
17094cc5cf4aSJun Yang 		return -ENOTSUP;
1710926c1279SJun Yang 
1711926c1279SJun Yang 	return 0;
1712926c1279SJun Yang }
1713926c1279SJun Yang 
1714926c1279SJun Yang static int
1715200a33e4SJun Yang dpaa2_flow_identify_by_faf(struct dpaa2_dev_priv *priv,
171656c1817dSJun Yang 	struct dpaa2_dev_flow *flow,
1717200a33e4SJun Yang 	enum dpaa2_rx_faf_offset faf_off,
171856c1817dSJun Yang 	enum dpaa2_flow_dist_type dist_type,
171956c1817dSJun Yang 	int group, int *recfg)
172056c1817dSJun Yang {
1721200a33e4SJun Yang 	int ret, index, local_cfg = 0;
172256c1817dSJun Yang 	struct dpaa2_key_extract *extract;
172356c1817dSJun Yang 	struct dpaa2_key_profile *key_profile;
1724200a33e4SJun Yang 	uint8_t faf_byte = faf_off / 8;
172556c1817dSJun Yang 
172656c1817dSJun Yang 	if (dist_type & DPAA2_FLOW_QOS_TYPE) {
172756c1817dSJun Yang 		extract = &priv->extract.qos_key_extract;
172856c1817dSJun Yang 		key_profile = &extract->key_profile;
172956c1817dSJun Yang 
173056c1817dSJun Yang 		index = dpaa2_flow_extract_search(key_profile,
1731200a33e4SJun Yang 				DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte);
173256c1817dSJun Yang 		if (index < 0) {
1733200a33e4SJun Yang 			ret = dpaa2_flow_faf_add_hdr(faf_byte,
1734200a33e4SJun Yang 					priv, DPAA2_FLOW_QOS_TYPE, group,
173556c1817dSJun Yang 					NULL);
173656c1817dSJun Yang 			if (ret) {
1737200a33e4SJun Yang 				DPAA2_PMD_ERR("QOS faf extract add failed");
173856c1817dSJun Yang 
173956c1817dSJun Yang 				return -EINVAL;
174056c1817dSJun Yang 			}
174156c1817dSJun Yang 			local_cfg |= DPAA2_FLOW_QOS_TYPE;
174256c1817dSJun Yang 		}
174356c1817dSJun Yang 
1744200a33e4SJun Yang 		ret = dpaa2_flow_faf_add_rule(priv, flow, faf_off, group,
174556c1817dSJun Yang 				DPAA2_FLOW_QOS_TYPE);
174656c1817dSJun Yang 		if (ret) {
1747200a33e4SJun Yang 			DPAA2_PMD_ERR("QoS faf rule set failed");
174856c1817dSJun Yang 			return -EINVAL;
174956c1817dSJun Yang 		}
175056c1817dSJun Yang 	}
175156c1817dSJun Yang 
175256c1817dSJun Yang 	if (dist_type & DPAA2_FLOW_FS_TYPE) {
175356c1817dSJun Yang 		extract = &priv->extract.tc_key_extract[group];
175456c1817dSJun Yang 		key_profile = &extract->key_profile;
175556c1817dSJun Yang 
175656c1817dSJun Yang 		index = dpaa2_flow_extract_search(key_profile,
1757200a33e4SJun Yang 				DPAA2_FAF_KEY, NET_PROT_NONE, faf_byte);
175856c1817dSJun Yang 		if (index < 0) {
1759200a33e4SJun Yang 			ret = dpaa2_flow_faf_add_hdr(faf_byte,
1760200a33e4SJun Yang 					priv, DPAA2_FLOW_FS_TYPE, group,
176156c1817dSJun Yang 					NULL);
176256c1817dSJun Yang 			if (ret) {
1763200a33e4SJun Yang 				DPAA2_PMD_ERR("FS[%d] faf extract add failed",
176456c1817dSJun Yang 					group);
176556c1817dSJun Yang 
176656c1817dSJun Yang 				return -EINVAL;
176756c1817dSJun Yang 			}
176856c1817dSJun Yang 			local_cfg |= DPAA2_FLOW_FS_TYPE;
176956c1817dSJun Yang 		}
177056c1817dSJun Yang 
1771200a33e4SJun Yang 		ret = dpaa2_flow_faf_add_rule(priv, flow, faf_off, group,
177256c1817dSJun Yang 				DPAA2_FLOW_FS_TYPE);
177356c1817dSJun Yang 		if (ret) {
1774200a33e4SJun Yang 			DPAA2_PMD_ERR("FS[%d] faf rule set failed",
177556c1817dSJun Yang 				group);
177656c1817dSJun Yang 			return -EINVAL;
177756c1817dSJun Yang 		}
177856c1817dSJun Yang 	}
177956c1817dSJun Yang 
178056c1817dSJun Yang 	if (recfg)
1781200a33e4SJun Yang 		*recfg |= local_cfg;
178256c1817dSJun Yang 
178356c1817dSJun Yang 	return 0;
178456c1817dSJun Yang }
178556c1817dSJun Yang 
178656c1817dSJun Yang static int
178739c8044fSJun Yang dpaa2_flow_add_pr_extract_rule(struct dpaa2_dev_flow *flow,
178839c8044fSJun Yang 	uint32_t pr_offset, uint32_t pr_size,
178939c8044fSJun Yang 	const void *key, const void *mask,
179039c8044fSJun Yang 	struct dpaa2_dev_priv *priv, int tc_id, int *recfg,
179139c8044fSJun Yang 	enum dpaa2_flow_dist_type dist_type)
179239c8044fSJun Yang {
179339c8044fSJun Yang 	int index, ret, local_cfg = 0;
179439c8044fSJun Yang 	struct dpaa2_key_extract *key_extract;
179539c8044fSJun Yang 	struct dpaa2_key_profile *key_profile;
179639c8044fSJun Yang 	uint32_t pr_field = pr_offset << 16 | pr_size;
179739c8044fSJun Yang 
179839c8044fSJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE)
179939c8044fSJun Yang 		key_extract = &priv->extract.qos_key_extract;
180039c8044fSJun Yang 	else
180139c8044fSJun Yang 		key_extract = &priv->extract.tc_key_extract[tc_id];
180239c8044fSJun Yang 
180339c8044fSJun Yang 	key_profile = &key_extract->key_profile;
180439c8044fSJun Yang 
180539c8044fSJun Yang 	index = dpaa2_flow_extract_search(key_profile,
180639c8044fSJun Yang 			DPAA2_PR_KEY, NET_PROT_NONE, pr_field);
180739c8044fSJun Yang 	if (index < 0) {
180839c8044fSJun Yang 		ret = dpaa2_flow_pr_add_hdr(pr_offset,
180939c8044fSJun Yang 				pr_size, priv,
181039c8044fSJun Yang 				dist_type, tc_id, NULL);
181139c8044fSJun Yang 		if (ret) {
181239c8044fSJun Yang 			DPAA2_PMD_ERR("PR add off(%d)/size(%d) failed",
181339c8044fSJun Yang 				pr_offset, pr_size);
181439c8044fSJun Yang 
181539c8044fSJun Yang 			return ret;
181639c8044fSJun Yang 		}
181739c8044fSJun Yang 		local_cfg |= dist_type;
181839c8044fSJun Yang 	}
181939c8044fSJun Yang 
182039c8044fSJun Yang 	ret = dpaa2_flow_pr_rule_data_set(flow, key_profile,
182139c8044fSJun Yang 			pr_offset, pr_size, key, mask, dist_type);
182239c8044fSJun Yang 	if (ret) {
182339c8044fSJun Yang 		DPAA2_PMD_ERR("PR off(%d)/size(%d) rule data set failed",
182439c8044fSJun Yang 			pr_offset, pr_size);
182539c8044fSJun Yang 
182639c8044fSJun Yang 		return ret;
182739c8044fSJun Yang 	}
182839c8044fSJun Yang 
182939c8044fSJun Yang 	if (recfg)
183039c8044fSJun Yang 		*recfg |= local_cfg;
183139c8044fSJun Yang 
183239c8044fSJun Yang 	return 0;
183339c8044fSJun Yang }
183439c8044fSJun Yang 
183539c8044fSJun Yang static int
183656c1817dSJun Yang dpaa2_flow_add_hdr_extract_rule(struct dpaa2_dev_flow *flow,
183756c1817dSJun Yang 	enum net_prot prot, uint32_t field,
183856c1817dSJun Yang 	const void *key, const void *mask, int size,
183956c1817dSJun Yang 	struct dpaa2_dev_priv *priv, int tc_id, int *recfg,
184056c1817dSJun Yang 	enum dpaa2_flow_dist_type dist_type)
184156c1817dSJun Yang {
184256c1817dSJun Yang 	int index, ret, local_cfg = 0;
184356c1817dSJun Yang 	struct dpaa2_key_extract *key_extract;
184456c1817dSJun Yang 	struct dpaa2_key_profile *key_profile;
184556c1817dSJun Yang 
184656c1817dSJun Yang 	if (dpaa2_flow_ip_address_extract(prot, field))
184756c1817dSJun Yang 		return -EINVAL;
184856c1817dSJun Yang 
184956c1817dSJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE)
185056c1817dSJun Yang 		key_extract = &priv->extract.qos_key_extract;
185156c1817dSJun Yang 	else
185256c1817dSJun Yang 		key_extract = &priv->extract.tc_key_extract[tc_id];
185356c1817dSJun Yang 
185456c1817dSJun Yang 	key_profile = &key_extract->key_profile;
185556c1817dSJun Yang 
185656c1817dSJun Yang 	index = dpaa2_flow_extract_search(key_profile,
1857200a33e4SJun Yang 			DPAA2_NET_PROT_KEY, prot, field);
185856c1817dSJun Yang 	if (index < 0) {
185956c1817dSJun Yang 		ret = dpaa2_flow_extract_add_hdr(prot,
186056c1817dSJun Yang 				field, size, priv,
186156c1817dSJun Yang 				dist_type, tc_id, NULL);
186256c1817dSJun Yang 		if (ret) {
186356c1817dSJun Yang 			DPAA2_PMD_ERR("QoS Extract P(%d)/F(%d) failed",
186456c1817dSJun Yang 				prot, field);
186556c1817dSJun Yang 
186656c1817dSJun Yang 			return ret;
186756c1817dSJun Yang 		}
186856c1817dSJun Yang 		local_cfg |= dist_type;
186956c1817dSJun Yang 	}
187056c1817dSJun Yang 
187156c1817dSJun Yang 	ret = dpaa2_flow_hdr_rule_data_set(flow, key_profile,
187256c1817dSJun Yang 			prot, field, size, key, mask, dist_type);
187356c1817dSJun Yang 	if (ret) {
187456c1817dSJun Yang 		DPAA2_PMD_ERR("QoS P(%d)/F(%d) rule data set failed",
187556c1817dSJun Yang 			prot, field);
187656c1817dSJun Yang 
187756c1817dSJun Yang 		return ret;
187856c1817dSJun Yang 	}
187956c1817dSJun Yang 
188056c1817dSJun Yang 	if (recfg)
188156c1817dSJun Yang 		*recfg |= local_cfg;
188256c1817dSJun Yang 
188356c1817dSJun Yang 	return 0;
188456c1817dSJun Yang }
188556c1817dSJun Yang 
188656c1817dSJun Yang static int
188756c1817dSJun Yang dpaa2_flow_add_ipaddr_extract_rule(struct dpaa2_dev_flow *flow,
188856c1817dSJun Yang 	enum net_prot prot, uint32_t field,
188956c1817dSJun Yang 	const void *key, const void *mask, int size,
189056c1817dSJun Yang 	struct dpaa2_dev_priv *priv, int tc_id, int *recfg,
189156c1817dSJun Yang 	enum dpaa2_flow_dist_type dist_type)
189256c1817dSJun Yang {
189356c1817dSJun Yang 	int local_cfg = 0, num, ipaddr_extract_len = 0;
189456c1817dSJun Yang 	struct dpaa2_key_extract *key_extract;
189556c1817dSJun Yang 	struct dpaa2_key_profile *key_profile;
189656c1817dSJun Yang 	struct dpkg_profile_cfg *dpkg;
189756c1817dSJun Yang 	uint8_t *key_addr, *mask_addr;
189856c1817dSJun Yang 	union ip_addr_extract_rule *ip_addr_data;
189956c1817dSJun Yang 	union ip_addr_extract_rule *ip_addr_mask;
190056c1817dSJun Yang 	enum net_prot orig_prot;
190156c1817dSJun Yang 	uint32_t orig_field;
190256c1817dSJun Yang 
190356c1817dSJun Yang 	if (prot != NET_PROT_IPV4 && prot != NET_PROT_IPV6)
190456c1817dSJun Yang 		return -EINVAL;
190556c1817dSJun Yang 
190656c1817dSJun Yang 	if (prot == NET_PROT_IPV4 && field != NH_FLD_IPV4_SRC_IP &&
190756c1817dSJun Yang 		field != NH_FLD_IPV4_DST_IP) {
190856c1817dSJun Yang 		return -EINVAL;
190956c1817dSJun Yang 	}
191056c1817dSJun Yang 
191156c1817dSJun Yang 	if (prot == NET_PROT_IPV6 && field != NH_FLD_IPV6_SRC_IP &&
191256c1817dSJun Yang 		field != NH_FLD_IPV6_DST_IP) {
191356c1817dSJun Yang 		return -EINVAL;
191456c1817dSJun Yang 	}
191556c1817dSJun Yang 
191656c1817dSJun Yang 	orig_prot = prot;
191756c1817dSJun Yang 	orig_field = field;
191856c1817dSJun Yang 
191956c1817dSJun Yang 	if (prot == NET_PROT_IPV4 &&
192056c1817dSJun Yang 		field == NH_FLD_IPV4_SRC_IP) {
192156c1817dSJun Yang 		prot = NET_PROT_IP;
192256c1817dSJun Yang 		field = NH_FLD_IP_SRC;
192356c1817dSJun Yang 	} else if (prot == NET_PROT_IPV4 &&
192456c1817dSJun Yang 		field == NH_FLD_IPV4_DST_IP) {
192556c1817dSJun Yang 		prot = NET_PROT_IP;
192656c1817dSJun Yang 		field = NH_FLD_IP_DST;
192756c1817dSJun Yang 	} else if (prot == NET_PROT_IPV6 &&
192856c1817dSJun Yang 		field == NH_FLD_IPV6_SRC_IP) {
192956c1817dSJun Yang 		prot = NET_PROT_IP;
193056c1817dSJun Yang 		field = NH_FLD_IP_SRC;
193156c1817dSJun Yang 	} else if (prot == NET_PROT_IPV6 &&
193256c1817dSJun Yang 		field == NH_FLD_IPV6_DST_IP) {
193356c1817dSJun Yang 		prot = NET_PROT_IP;
193456c1817dSJun Yang 		field = NH_FLD_IP_DST;
193556c1817dSJun Yang 	} else {
193656c1817dSJun Yang 		DPAA2_PMD_ERR("Inval P(%d)/F(%d) to extract ip address",
193756c1817dSJun Yang 			prot, field);
193856c1817dSJun Yang 		return -EINVAL;
193956c1817dSJun Yang 	}
194056c1817dSJun Yang 
194156c1817dSJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE) {
194256c1817dSJun Yang 		key_extract = &priv->extract.qos_key_extract;
194356c1817dSJun Yang 		key_profile = &key_extract->key_profile;
194456c1817dSJun Yang 		dpkg = &key_extract->dpkg;
194556c1817dSJun Yang 		num = key_profile->num;
194656c1817dSJun Yang 		key_addr = flow->qos_key_addr;
194756c1817dSJun Yang 		mask_addr = flow->qos_mask_addr;
194856c1817dSJun Yang 	} else {
194956c1817dSJun Yang 		key_extract = &priv->extract.tc_key_extract[tc_id];
195056c1817dSJun Yang 		key_profile = &key_extract->key_profile;
195156c1817dSJun Yang 		dpkg = &key_extract->dpkg;
195256c1817dSJun Yang 		num = key_profile->num;
195356c1817dSJun Yang 		key_addr = flow->fs_key_addr;
195456c1817dSJun Yang 		mask_addr = flow->fs_mask_addr;
195556c1817dSJun Yang 	}
195656c1817dSJun Yang 
195756c1817dSJun Yang 	if (num >= DPKG_MAX_NUM_OF_EXTRACTS) {
195856c1817dSJun Yang 		DPAA2_PMD_ERR("Number of extracts overflows");
195956c1817dSJun Yang 		return -EINVAL;
196056c1817dSJun Yang 	}
196156c1817dSJun Yang 
196256c1817dSJun Yang 	if (key_profile->ip_addr_type == IP_NONE_ADDR_EXTRACT) {
196356c1817dSJun Yang 		if (field == NH_FLD_IP_SRC)
196456c1817dSJun Yang 			key_profile->ip_addr_type = IP_SRC_EXTRACT;
196556c1817dSJun Yang 		else
196656c1817dSJun Yang 			key_profile->ip_addr_type = IP_DST_EXTRACT;
196756c1817dSJun Yang 		ipaddr_extract_len = size;
196856c1817dSJun Yang 
196956c1817dSJun Yang 		key_profile->ip_addr_extract_pos = num;
197056c1817dSJun Yang 		if (num > 0) {
197156c1817dSJun Yang 			key_profile->ip_addr_extract_off =
197256c1817dSJun Yang 				key_profile->key_offset[num - 1] +
197356c1817dSJun Yang 				key_profile->key_size[num - 1];
197456c1817dSJun Yang 		} else {
197556c1817dSJun Yang 			key_profile->ip_addr_extract_off = 0;
197656c1817dSJun Yang 		}
197756c1817dSJun Yang 		key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE;
197856c1817dSJun Yang 	} else if (key_profile->ip_addr_type == IP_SRC_EXTRACT) {
197956c1817dSJun Yang 		if (field == NH_FLD_IP_SRC) {
198056c1817dSJun Yang 			ipaddr_extract_len = size;
198156c1817dSJun Yang 			goto rule_configure;
198256c1817dSJun Yang 		}
198356c1817dSJun Yang 		key_profile->ip_addr_type = IP_SRC_DST_EXTRACT;
198456c1817dSJun Yang 		ipaddr_extract_len = size * 2;
198556c1817dSJun Yang 		key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE;
198656c1817dSJun Yang 	} else if (key_profile->ip_addr_type == IP_DST_EXTRACT) {
198756c1817dSJun Yang 		if (field == NH_FLD_IP_DST) {
198856c1817dSJun Yang 			ipaddr_extract_len = size;
198956c1817dSJun Yang 			goto rule_configure;
199056c1817dSJun Yang 		}
199156c1817dSJun Yang 		key_profile->ip_addr_type = IP_DST_SRC_EXTRACT;
199256c1817dSJun Yang 		ipaddr_extract_len = size * 2;
199356c1817dSJun Yang 		key_profile->key_max_size += NH_FLD_IPV6_ADDR_SIZE;
199456c1817dSJun Yang 	}
199556c1817dSJun Yang 	key_profile->num++;
1996200a33e4SJun Yang 	key_profile->prot_field[num].type = DPAA2_NET_PROT_KEY;
199756c1817dSJun Yang 
199856c1817dSJun Yang 	dpkg->extracts[num].extract.from_hdr.prot = prot;
199956c1817dSJun Yang 	dpkg->extracts[num].extract.from_hdr.field = field;
200056c1817dSJun Yang 	dpkg->extracts[num].extract.from_hdr.type = DPKG_FULL_FIELD;
200156c1817dSJun Yang 	dpkg->num_extracts++;
200256c1817dSJun Yang 
200356c1817dSJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE)
200456c1817dSJun Yang 		local_cfg = DPAA2_FLOW_QOS_TYPE;
200556c1817dSJun Yang 	else
200656c1817dSJun Yang 		local_cfg = DPAA2_FLOW_FS_TYPE;
200756c1817dSJun Yang 
200856c1817dSJun Yang rule_configure:
200956c1817dSJun Yang 	key_addr += key_profile->ip_addr_extract_off;
201056c1817dSJun Yang 	ip_addr_data = (union ip_addr_extract_rule *)key_addr;
201156c1817dSJun Yang 	mask_addr += key_profile->ip_addr_extract_off;
201256c1817dSJun Yang 	ip_addr_mask = (union ip_addr_extract_rule *)mask_addr;
201356c1817dSJun Yang 
201456c1817dSJun Yang 	if (orig_prot == NET_PROT_IPV4 &&
201556c1817dSJun Yang 		orig_field == NH_FLD_IPV4_SRC_IP) {
201656c1817dSJun Yang 		if (key_profile->ip_addr_type == IP_SRC_EXTRACT ||
201756c1817dSJun Yang 			key_profile->ip_addr_type == IP_SRC_DST_EXTRACT) {
201856c1817dSJun Yang 			memcpy(&ip_addr_data->ipv4_sd_addr.ipv4_src,
201956c1817dSJun Yang 				key, size);
202056c1817dSJun Yang 			memcpy(&ip_addr_mask->ipv4_sd_addr.ipv4_src,
202156c1817dSJun Yang 				mask, size);
202256c1817dSJun Yang 		} else {
202356c1817dSJun Yang 			memcpy(&ip_addr_data->ipv4_ds_addr.ipv4_src,
202456c1817dSJun Yang 				key, size);
202556c1817dSJun Yang 			memcpy(&ip_addr_mask->ipv4_ds_addr.ipv4_src,
202656c1817dSJun Yang 				mask, size);
202756c1817dSJun Yang 		}
202856c1817dSJun Yang 	} else if (orig_prot == NET_PROT_IPV4 &&
202956c1817dSJun Yang 		orig_field == NH_FLD_IPV4_DST_IP) {
203056c1817dSJun Yang 		if (key_profile->ip_addr_type == IP_DST_EXTRACT ||
203156c1817dSJun Yang 			key_profile->ip_addr_type == IP_DST_SRC_EXTRACT) {
203256c1817dSJun Yang 			memcpy(&ip_addr_data->ipv4_ds_addr.ipv4_dst,
203356c1817dSJun Yang 				key, size);
203456c1817dSJun Yang 			memcpy(&ip_addr_mask->ipv4_ds_addr.ipv4_dst,
203556c1817dSJun Yang 				mask, size);
203656c1817dSJun Yang 		} else {
203756c1817dSJun Yang 			memcpy(&ip_addr_data->ipv4_sd_addr.ipv4_dst,
203856c1817dSJun Yang 				key, size);
203956c1817dSJun Yang 			memcpy(&ip_addr_mask->ipv4_sd_addr.ipv4_dst,
204056c1817dSJun Yang 				mask, size);
204156c1817dSJun Yang 		}
204256c1817dSJun Yang 	} else if (orig_prot == NET_PROT_IPV6 &&
204356c1817dSJun Yang 		orig_field == NH_FLD_IPV6_SRC_IP) {
204456c1817dSJun Yang 		if (key_profile->ip_addr_type == IP_SRC_EXTRACT ||
204556c1817dSJun Yang 			key_profile->ip_addr_type == IP_SRC_DST_EXTRACT) {
204656c1817dSJun Yang 			memcpy(ip_addr_data->ipv6_sd_addr.ipv6_src,
204756c1817dSJun Yang 				key, size);
204856c1817dSJun Yang 			memcpy(ip_addr_mask->ipv6_sd_addr.ipv6_src,
204956c1817dSJun Yang 				mask, size);
205056c1817dSJun Yang 		} else {
205156c1817dSJun Yang 			memcpy(ip_addr_data->ipv6_ds_addr.ipv6_src,
205256c1817dSJun Yang 				key, size);
205356c1817dSJun Yang 			memcpy(ip_addr_mask->ipv6_ds_addr.ipv6_src,
205456c1817dSJun Yang 				mask, size);
205556c1817dSJun Yang 		}
205656c1817dSJun Yang 	} else if (orig_prot == NET_PROT_IPV6 &&
205756c1817dSJun Yang 		orig_field == NH_FLD_IPV6_DST_IP) {
205856c1817dSJun Yang 		if (key_profile->ip_addr_type == IP_DST_EXTRACT ||
205956c1817dSJun Yang 			key_profile->ip_addr_type == IP_DST_SRC_EXTRACT) {
206056c1817dSJun Yang 			memcpy(ip_addr_data->ipv6_ds_addr.ipv6_dst,
206156c1817dSJun Yang 				key, size);
206256c1817dSJun Yang 			memcpy(ip_addr_mask->ipv6_ds_addr.ipv6_dst,
206356c1817dSJun Yang 				mask, size);
206456c1817dSJun Yang 		} else {
206556c1817dSJun Yang 			memcpy(ip_addr_data->ipv6_sd_addr.ipv6_dst,
206656c1817dSJun Yang 				key, size);
206756c1817dSJun Yang 			memcpy(ip_addr_mask->ipv6_sd_addr.ipv6_dst,
206856c1817dSJun Yang 				mask, size);
206956c1817dSJun Yang 		}
207056c1817dSJun Yang 	}
207156c1817dSJun Yang 
207256c1817dSJun Yang 	if (dist_type == DPAA2_FLOW_QOS_TYPE) {
207356c1817dSJun Yang 		flow->qos_rule_size =
207456c1817dSJun Yang 			key_profile->ip_addr_extract_off + ipaddr_extract_len;
207556c1817dSJun Yang 	} else {
207656c1817dSJun Yang 		flow->fs_rule_size =
207756c1817dSJun Yang 			key_profile->ip_addr_extract_off + ipaddr_extract_len;
207856c1817dSJun Yang 	}
207956c1817dSJun Yang 
208056c1817dSJun Yang 	if (recfg)
208156c1817dSJun Yang 		*recfg |= local_cfg;
208256c1817dSJun Yang 
208356c1817dSJun Yang 	return 0;
208456c1817dSJun Yang }
208556c1817dSJun Yang 
208656c1817dSJun Yang static int
20879ec29343SJun Yang dpaa2_configure_flow_tunnel_eth(struct dpaa2_dev_flow *flow,
2088fe2b986aSSunil Kumar Kori 	struct rte_eth_dev *dev,
2089fe2b986aSSunil Kumar Kori 	const struct rte_flow_attr *attr,
2090fe2b986aSSunil Kumar Kori 	const struct rte_flow_item *pattern,
20919ec29343SJun Yang 	int *device_configured)
20929ec29343SJun Yang {
20939ec29343SJun Yang 	int ret, local_cfg = 0;
20949ec29343SJun Yang 	uint32_t group;
20959ec29343SJun Yang 	const struct rte_flow_item_eth *spec, *mask;
20969ec29343SJun Yang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
20979ec29343SJun Yang 	const char zero_cmp[RTE_ETHER_ADDR_LEN] = {0};
20989ec29343SJun Yang 
20999ec29343SJun Yang 	group = attr->group;
21009ec29343SJun Yang 
21019ec29343SJun Yang 	/* Parse pattern list to get the matching parameters */
21029ec29343SJun Yang 	spec = pattern->spec;
21039ec29343SJun Yang 	mask = pattern->mask ?
21049ec29343SJun Yang 			pattern->mask : &dpaa2_flow_item_eth_mask;
21059ec29343SJun Yang 
21069ec29343SJun Yang 	/* Get traffic class index and flow id to be configured */
21079ec29343SJun Yang 	flow->tc_id = group;
21089ec29343SJun Yang 	flow->tc_index = attr->priority;
21099ec29343SJun Yang 
21109ec29343SJun Yang 	if (!spec)
21119ec29343SJun Yang 		return 0;
21129ec29343SJun Yang 
21134cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
21144cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_ETH);
21154cc5cf4aSJun Yang 	if (ret) {
21169ec29343SJun Yang 		DPAA2_PMD_WARN("Extract field(s) of ethernet failed");
21179ec29343SJun Yang 
21184cc5cf4aSJun Yang 		return ret;
21199ec29343SJun Yang 	}
21209ec29343SJun Yang 
21219ec29343SJun Yang 	if (memcmp((const char *)&mask->src,
21229ec29343SJun Yang 		zero_cmp, RTE_ETHER_ADDR_LEN)) {
21239ec29343SJun Yang 		/*SRC[0:1]*/
21249ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
21259ec29343SJun Yang 			DPAA2_VXLAN_IN_SADDR0_OFFSET,
21269ec29343SJun Yang 			1, &spec->src.addr_bytes[0],
21279ec29343SJun Yang 			&mask->src.addr_bytes[0],
21289ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
21299ec29343SJun Yang 		if (ret)
21309ec29343SJun Yang 			return ret;
21319ec29343SJun Yang 		/*SRC[1:2]*/
21329ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
21339ec29343SJun Yang 			DPAA2_VXLAN_IN_SADDR1_OFFSET,
21349ec29343SJun Yang 			2, &spec->src.addr_bytes[1],
21359ec29343SJun Yang 			&mask->src.addr_bytes[1],
21369ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
21379ec29343SJun Yang 		if (ret)
21389ec29343SJun Yang 			return ret;
21399ec29343SJun Yang 		/*SRC[3:1]*/
21409ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
21419ec29343SJun Yang 			DPAA2_VXLAN_IN_SADDR3_OFFSET,
21429ec29343SJun Yang 			1, &spec->src.addr_bytes[3],
21439ec29343SJun Yang 			&mask->src.addr_bytes[3],
21449ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
21459ec29343SJun Yang 		if (ret)
21469ec29343SJun Yang 			return ret;
21479ec29343SJun Yang 		/*SRC[4:2]*/
21489ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
21499ec29343SJun Yang 			DPAA2_VXLAN_IN_SADDR4_OFFSET,
21509ec29343SJun Yang 			2, &spec->src.addr_bytes[4],
21519ec29343SJun Yang 			&mask->src.addr_bytes[4],
21529ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
21539ec29343SJun Yang 		if (ret)
21549ec29343SJun Yang 			return ret;
21559ec29343SJun Yang 
21569ec29343SJun Yang 		/*SRC[0:1]*/
21579ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
21589ec29343SJun Yang 			DPAA2_VXLAN_IN_SADDR0_OFFSET,
21599ec29343SJun Yang 			1, &spec->src.addr_bytes[0],
21609ec29343SJun Yang 			&mask->src.addr_bytes[0],
21619ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
21629ec29343SJun Yang 		if (ret)
21639ec29343SJun Yang 			return ret;
21649ec29343SJun Yang 		/*SRC[1:2]*/
21659ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
21669ec29343SJun Yang 			DPAA2_VXLAN_IN_SADDR1_OFFSET,
21679ec29343SJun Yang 			2, &spec->src.addr_bytes[1],
21689ec29343SJun Yang 			&mask->src.addr_bytes[1],
21699ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
21709ec29343SJun Yang 		if (ret)
21719ec29343SJun Yang 			return ret;
21729ec29343SJun Yang 		/*SRC[3:1]*/
21739ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
21749ec29343SJun Yang 			DPAA2_VXLAN_IN_SADDR3_OFFSET,
21759ec29343SJun Yang 			1, &spec->src.addr_bytes[3],
21769ec29343SJun Yang 			&mask->src.addr_bytes[3],
21779ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
21789ec29343SJun Yang 		if (ret)
21799ec29343SJun Yang 			return ret;
21809ec29343SJun Yang 		/*SRC[4:2]*/
21819ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
21829ec29343SJun Yang 			DPAA2_VXLAN_IN_SADDR4_OFFSET,
21839ec29343SJun Yang 			2, &spec->src.addr_bytes[4],
21849ec29343SJun Yang 			&mask->src.addr_bytes[4],
21859ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
21869ec29343SJun Yang 		if (ret)
21879ec29343SJun Yang 			return ret;
21889ec29343SJun Yang 	}
21899ec29343SJun Yang 
21909ec29343SJun Yang 	if (memcmp((const char *)&mask->dst,
21919ec29343SJun Yang 		zero_cmp, RTE_ETHER_ADDR_LEN)) {
21929ec29343SJun Yang 		/*DST[0:1]*/
21939ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
21949ec29343SJun Yang 			DPAA2_VXLAN_IN_DADDR0_OFFSET,
21959ec29343SJun Yang 			1, &spec->dst.addr_bytes[0],
21969ec29343SJun Yang 			&mask->dst.addr_bytes[0],
21979ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
21989ec29343SJun Yang 		if (ret)
21999ec29343SJun Yang 			return ret;
22009ec29343SJun Yang 		/*DST[1:1]*/
22019ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
22029ec29343SJun Yang 			DPAA2_VXLAN_IN_DADDR1_OFFSET,
22039ec29343SJun Yang 			1, &spec->dst.addr_bytes[1],
22049ec29343SJun Yang 			&mask->dst.addr_bytes[1],
22059ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
22069ec29343SJun Yang 		if (ret)
22079ec29343SJun Yang 			return ret;
22089ec29343SJun Yang 		/*DST[2:3]*/
22099ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
22109ec29343SJun Yang 			DPAA2_VXLAN_IN_DADDR2_OFFSET,
22119ec29343SJun Yang 			3, &spec->dst.addr_bytes[2],
22129ec29343SJun Yang 			&mask->dst.addr_bytes[2],
22139ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
22149ec29343SJun Yang 		if (ret)
22159ec29343SJun Yang 			return ret;
22169ec29343SJun Yang 		/*DST[5:1]*/
22179ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
22189ec29343SJun Yang 			DPAA2_VXLAN_IN_DADDR5_OFFSET,
22199ec29343SJun Yang 			1, &spec->dst.addr_bytes[5],
22209ec29343SJun Yang 			&mask->dst.addr_bytes[5],
22219ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
22229ec29343SJun Yang 		if (ret)
22239ec29343SJun Yang 			return ret;
22249ec29343SJun Yang 
22259ec29343SJun Yang 		/*DST[0:1]*/
22269ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
22279ec29343SJun Yang 			DPAA2_VXLAN_IN_DADDR0_OFFSET,
22289ec29343SJun Yang 			1, &spec->dst.addr_bytes[0],
22299ec29343SJun Yang 			&mask->dst.addr_bytes[0],
22309ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
22319ec29343SJun Yang 		if (ret)
22329ec29343SJun Yang 			return ret;
22339ec29343SJun Yang 		/*DST[1:1]*/
22349ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
22359ec29343SJun Yang 			DPAA2_VXLAN_IN_DADDR1_OFFSET,
22369ec29343SJun Yang 			1, &spec->dst.addr_bytes[1],
22379ec29343SJun Yang 			&mask->dst.addr_bytes[1],
22389ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
22399ec29343SJun Yang 		if (ret)
22409ec29343SJun Yang 			return ret;
22419ec29343SJun Yang 		/*DST[2:3]*/
22429ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
22439ec29343SJun Yang 			DPAA2_VXLAN_IN_DADDR2_OFFSET,
22449ec29343SJun Yang 			3, &spec->dst.addr_bytes[2],
22459ec29343SJun Yang 			&mask->dst.addr_bytes[2],
22469ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
22479ec29343SJun Yang 		if (ret)
22489ec29343SJun Yang 			return ret;
22499ec29343SJun Yang 		/*DST[5:1]*/
22509ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
22519ec29343SJun Yang 			DPAA2_VXLAN_IN_DADDR5_OFFSET,
22529ec29343SJun Yang 			1, &spec->dst.addr_bytes[5],
22539ec29343SJun Yang 			&mask->dst.addr_bytes[5],
22549ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
22559ec29343SJun Yang 		if (ret)
22569ec29343SJun Yang 			return ret;
22579ec29343SJun Yang 	}
22589ec29343SJun Yang 
22599ec29343SJun Yang 	if (memcmp((const char *)&mask->type,
22609ec29343SJun Yang 		zero_cmp, sizeof(rte_be16_t))) {
22619ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
22629ec29343SJun Yang 			DPAA2_VXLAN_IN_TYPE_OFFSET,
22639ec29343SJun Yang 			sizeof(rte_be16_t), &spec->type, &mask->type,
22649ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
22659ec29343SJun Yang 		if (ret)
22669ec29343SJun Yang 			return ret;
22679ec29343SJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
22689ec29343SJun Yang 			DPAA2_VXLAN_IN_TYPE_OFFSET,
22699ec29343SJun Yang 			sizeof(rte_be16_t), &spec->type, &mask->type,
22709ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
22719ec29343SJun Yang 		if (ret)
22729ec29343SJun Yang 			return ret;
22739ec29343SJun Yang 	}
22749ec29343SJun Yang 
22759ec29343SJun Yang 	(*device_configured) |= local_cfg;
22769ec29343SJun Yang 
22779ec29343SJun Yang 	return 0;
22789ec29343SJun Yang }
22799ec29343SJun Yang 
22809ec29343SJun Yang static int
22819ec29343SJun Yang dpaa2_configure_flow_eth(struct dpaa2_dev_flow *flow,
22829ec29343SJun Yang 	struct rte_eth_dev *dev,
22839ec29343SJun Yang 	const struct rte_flow_attr *attr,
22849ec29343SJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
2285fe2b986aSSunil Kumar Kori 	const struct rte_flow_action actions[] __rte_unused,
22865f176728SJun Yang 	struct rte_flow_error *error __rte_unused,
22875f176728SJun Yang 	int *device_configured)
2288fe2b986aSSunil Kumar Kori {
228956c1817dSJun Yang 	int ret, local_cfg = 0;
2290fe2b986aSSunil Kumar Kori 	uint32_t group;
2291fe2b986aSSunil Kumar Kori 	const struct rte_flow_item_eth *spec, *mask;
2292fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
22935f176728SJun Yang 	const char zero_cmp[RTE_ETHER_ADDR_LEN] = {0};
22949ec29343SJun Yang 	const struct rte_flow_item *pattern =
22959ec29343SJun Yang 		&dpaa2_pattern->generic_item;
22969ec29343SJun Yang 
22979ec29343SJun Yang 	if (dpaa2_pattern->in_tunnel) {
22989ec29343SJun Yang 		return dpaa2_configure_flow_tunnel_eth(flow,
22999ec29343SJun Yang 				dev, attr, pattern, device_configured);
23009ec29343SJun Yang 	}
2301fe2b986aSSunil Kumar Kori 
2302fe2b986aSSunil Kumar Kori 	group = attr->group;
2303fe2b986aSSunil Kumar Kori 
2304fe2b986aSSunil Kumar Kori 	/* Parse pattern list to get the matching parameters */
230556c1817dSJun Yang 	spec = pattern->spec;
230656c1817dSJun Yang 	mask = pattern->mask ?
230756c1817dSJun Yang 			pattern->mask : &dpaa2_flow_item_eth_mask;
2308fe2b986aSSunil Kumar Kori 
23095f176728SJun Yang 	/* Get traffic class index and flow id to be configured */
23105f176728SJun Yang 	flow->tc_id = group;
23115f176728SJun Yang 	flow->tc_index = attr->priority;
23125f176728SJun Yang 
2313200a33e4SJun Yang 	if (!spec) {
2314200a33e4SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
2315200a33e4SJun Yang 				FAF_ETH_FRAM, DPAA2_FLOW_QOS_TYPE,
2316200a33e4SJun Yang 				group, &local_cfg);
2317200a33e4SJun Yang 		if (ret)
2318200a33e4SJun Yang 			return ret;
2319200a33e4SJun Yang 
2320200a33e4SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
2321200a33e4SJun Yang 				FAF_ETH_FRAM, DPAA2_FLOW_FS_TYPE,
2322200a33e4SJun Yang 				group, &local_cfg);
2323200a33e4SJun Yang 		if (ret)
2324200a33e4SJun Yang 			return ret;
2325200a33e4SJun Yang 
2326200a33e4SJun Yang 		(*device_configured) |= local_cfg;
2327200a33e4SJun Yang 		return 0;
2328200a33e4SJun Yang 	}
2329200a33e4SJun Yang 
23304cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
23314cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_ETH);
23324cc5cf4aSJun Yang 	if (ret) {
233356c1817dSJun Yang 		DPAA2_PMD_WARN("Extract field(s) of ethernet failed");
2334926c1279SJun Yang 
23354cc5cf4aSJun Yang 		return ret;
2336926c1279SJun Yang 	}
2337926c1279SJun Yang 
233856c1817dSJun Yang 	if (memcmp((const char *)&mask->src,
233956c1817dSJun Yang 		zero_cmp, RTE_ETHER_ADDR_LEN)) {
234056c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
234156c1817dSJun Yang 			NH_FLD_ETH_SA, &spec->src.addr_bytes,
234256c1817dSJun Yang 			&mask->src.addr_bytes, RTE_ETHER_ADDR_LEN,
234356c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
234456c1817dSJun Yang 		if (ret)
234556c1817dSJun Yang 			return ret;
23465f176728SJun Yang 
234756c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
234856c1817dSJun Yang 			NH_FLD_ETH_SA, &spec->src.addr_bytes,
234956c1817dSJun Yang 			&mask->src.addr_bytes, RTE_ETHER_ADDR_LEN,
235056c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
235156c1817dSJun Yang 		if (ret)
235256c1817dSJun Yang 			return ret;
23535f176728SJun Yang 	}
23545f176728SJun Yang 
235556c1817dSJun Yang 	if (memcmp((const char *)&mask->dst,
235656c1817dSJun Yang 		zero_cmp, RTE_ETHER_ADDR_LEN)) {
235756c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
235856c1817dSJun Yang 			NH_FLD_ETH_DA, &spec->dst.addr_bytes,
235956c1817dSJun Yang 			&mask->dst.addr_bytes, RTE_ETHER_ADDR_LEN,
236056c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
236156c1817dSJun Yang 		if (ret)
236256c1817dSJun Yang 			return ret;
236356c1817dSJun Yang 
236456c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
236556c1817dSJun Yang 			NH_FLD_ETH_DA, &spec->dst.addr_bytes,
236656c1817dSJun Yang 			&mask->dst.addr_bytes, RTE_ETHER_ADDR_LEN,
236756c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
236856c1817dSJun Yang 		if (ret)
236956c1817dSJun Yang 			return ret;
23705f176728SJun Yang 	}
23715f176728SJun Yang 
237256c1817dSJun Yang 	if (memcmp((const char *)&mask->type,
237356c1817dSJun Yang 		zero_cmp, sizeof(rte_be16_t))) {
237456c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
237556c1817dSJun Yang 			NH_FLD_ETH_TYPE, &spec->type,
237656c1817dSJun Yang 			&mask->type, sizeof(rte_be16_t),
237756c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
237856c1817dSJun Yang 		if (ret)
237956c1817dSJun Yang 			return ret;
23805f176728SJun Yang 
238156c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ETH,
238256c1817dSJun Yang 			NH_FLD_ETH_TYPE, &spec->type,
238356c1817dSJun Yang 			&mask->type, sizeof(rte_be16_t),
238456c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
238556c1817dSJun Yang 		if (ret)
238656c1817dSJun Yang 			return ret;
23875f176728SJun Yang 	}
2388fe2b986aSSunil Kumar Kori 
23895f176728SJun Yang 	(*device_configured) |= local_cfg;
23904e445633SJun Yang 
23915f176728SJun Yang 	return 0;
2392fe2b986aSSunil Kumar Kori }
2393fe2b986aSSunil Kumar Kori 
2394fe2b986aSSunil Kumar Kori static int
23959ec29343SJun Yang dpaa2_configure_flow_tunnel_vlan(struct dpaa2_dev_flow *flow,
2396fe2b986aSSunil Kumar Kori 	struct rte_eth_dev *dev,
2397fe2b986aSSunil Kumar Kori 	const struct rte_flow_attr *attr,
2398fe2b986aSSunil Kumar Kori 	const struct rte_flow_item *pattern,
23999ec29343SJun Yang 	int *device_configured)
24009ec29343SJun Yang {
24019ec29343SJun Yang 	int ret, local_cfg = 0;
24029ec29343SJun Yang 	uint32_t group;
24039ec29343SJun Yang 	const struct rte_flow_item_vlan *spec, *mask;
24049ec29343SJun Yang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
24059ec29343SJun Yang 
24069ec29343SJun Yang 	group = attr->group;
24079ec29343SJun Yang 
24089ec29343SJun Yang 	/* Parse pattern list to get the matching parameters */
24099ec29343SJun Yang 	spec = pattern->spec;
24109ec29343SJun Yang 	mask = pattern->mask ?
24119ec29343SJun Yang 		pattern->mask : &dpaa2_flow_item_vlan_mask;
24129ec29343SJun Yang 
24139ec29343SJun Yang 	/* Get traffic class index and flow id to be configured */
24149ec29343SJun Yang 	flow->tc_id = group;
24159ec29343SJun Yang 	flow->tc_index = attr->priority;
24169ec29343SJun Yang 
24179ec29343SJun Yang 	if (!spec) {
24189ec29343SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
24199ec29343SJun Yang 				FAFE_VXLAN_IN_VLAN_FRAM,
24209ec29343SJun Yang 				DPAA2_FLOW_QOS_TYPE,
24219ec29343SJun Yang 				group, &local_cfg);
24229ec29343SJun Yang 		if (ret)
24239ec29343SJun Yang 			return ret;
24249ec29343SJun Yang 
24259ec29343SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
24269ec29343SJun Yang 				FAFE_VXLAN_IN_VLAN_FRAM,
24279ec29343SJun Yang 				DPAA2_FLOW_FS_TYPE,
24289ec29343SJun Yang 				group, &local_cfg);
24299ec29343SJun Yang 		if (ret)
24309ec29343SJun Yang 			return ret;
24319ec29343SJun Yang 
24329ec29343SJun Yang 		(*device_configured) |= local_cfg;
24339ec29343SJun Yang 		return 0;
24349ec29343SJun Yang 	}
24359ec29343SJun Yang 
24364cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
24374cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_VLAN);
24384cc5cf4aSJun Yang 	if (ret) {
24399ec29343SJun Yang 		DPAA2_PMD_WARN("Extract field(s) of vlan not support.");
24409ec29343SJun Yang 
24414cc5cf4aSJun Yang 		return ret;
24429ec29343SJun Yang 	}
24439ec29343SJun Yang 
24449ec29343SJun Yang 	if (!mask->tci)
24459ec29343SJun Yang 		return 0;
24469ec29343SJun Yang 
24479ec29343SJun Yang 	ret = dpaa2_flow_add_pr_extract_rule(flow,
24489ec29343SJun Yang 			DPAA2_VXLAN_IN_TCI_OFFSET,
24499ec29343SJun Yang 			sizeof(rte_be16_t), &spec->tci, &mask->tci,
24509ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
24519ec29343SJun Yang 	if (ret)
24529ec29343SJun Yang 		return ret;
24539ec29343SJun Yang 
24549ec29343SJun Yang 	ret = dpaa2_flow_add_pr_extract_rule(flow,
24559ec29343SJun Yang 			DPAA2_VXLAN_IN_TCI_OFFSET,
24569ec29343SJun Yang 			sizeof(rte_be16_t), &spec->tci, &mask->tci,
24579ec29343SJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
24589ec29343SJun Yang 	if (ret)
24599ec29343SJun Yang 		return ret;
24609ec29343SJun Yang 
24619ec29343SJun Yang 	(*device_configured) |= local_cfg;
24629ec29343SJun Yang 
24639ec29343SJun Yang 	return 0;
24649ec29343SJun Yang }
24659ec29343SJun Yang 
24669ec29343SJun Yang static int
24679ec29343SJun Yang dpaa2_configure_flow_vlan(struct dpaa2_dev_flow *flow,
24689ec29343SJun Yang 	struct rte_eth_dev *dev,
24699ec29343SJun Yang 	const struct rte_flow_attr *attr,
24709ec29343SJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
2471fe2b986aSSunil Kumar Kori 	const struct rte_flow_action actions[] __rte_unused,
24725f176728SJun Yang 	struct rte_flow_error *error __rte_unused,
24735f176728SJun Yang 	int *device_configured)
2474fe2b986aSSunil Kumar Kori {
247556c1817dSJun Yang 	int ret, local_cfg = 0;
2476fe2b986aSSunil Kumar Kori 	uint32_t group;
2477fe2b986aSSunil Kumar Kori 	const struct rte_flow_item_vlan *spec, *mask;
2478fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
24799ec29343SJun Yang 	const struct rte_flow_item *pattern =
24809ec29343SJun Yang 		&dpaa2_pattern->generic_item;
24819ec29343SJun Yang 
24829ec29343SJun Yang 	if (dpaa2_pattern->in_tunnel) {
24839ec29343SJun Yang 		return dpaa2_configure_flow_tunnel_vlan(flow,
24849ec29343SJun Yang 				dev, attr, pattern, device_configured);
24859ec29343SJun Yang 	}
2486fe2b986aSSunil Kumar Kori 
2487fe2b986aSSunil Kumar Kori 	group = attr->group;
2488fe2b986aSSunil Kumar Kori 
2489fe2b986aSSunil Kumar Kori 	/* Parse pattern list to get the matching parameters */
249056c1817dSJun Yang 	spec = pattern->spec;
249156c1817dSJun Yang 	mask = pattern->mask ? pattern->mask : &dpaa2_flow_item_vlan_mask;
2492fe2b986aSSunil Kumar Kori 
24935f176728SJun Yang 	/* Get traffic class index and flow id to be configured */
24945f176728SJun Yang 	flow->tc_id = group;
24955f176728SJun Yang 	flow->tc_index = attr->priority;
2496fe2b986aSSunil Kumar Kori 
24975f176728SJun Yang 	if (!spec) {
2498200a33e4SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_VLAN_FRAM,
2499200a33e4SJun Yang 				DPAA2_FLOW_QOS_TYPE, group,
2500200a33e4SJun Yang 				&local_cfg);
250156c1817dSJun Yang 		if (ret)
250256c1817dSJun Yang 			return ret;
2503200a33e4SJun Yang 
2504200a33e4SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_VLAN_FRAM,
2505200a33e4SJun Yang 				DPAA2_FLOW_FS_TYPE, group,
2506200a33e4SJun Yang 				&local_cfg);
2507200a33e4SJun Yang 		if (ret)
2508200a33e4SJun Yang 			return ret;
2509200a33e4SJun Yang 
25105f176728SJun Yang 		(*device_configured) |= local_cfg;
25115f176728SJun Yang 		return 0;
25125f176728SJun Yang 	}
25135f176728SJun Yang 
25144cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
25154cc5cf4aSJun Yang 			RTE_FLOW_ITEM_TYPE_VLAN);
25164cc5cf4aSJun Yang 	if (ret) {
2517926c1279SJun Yang 		DPAA2_PMD_WARN("Extract field(s) of vlan not support.");
25184cc5cf4aSJun Yang 		return ret;
2519926c1279SJun Yang 	}
2520926c1279SJun Yang 
252156c1817dSJun Yang 	if (!mask->tci)
25225f176728SJun Yang 		return 0;
25235f176728SJun Yang 
252456c1817dSJun Yang 	ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_VLAN,
252556c1817dSJun Yang 			NH_FLD_VLAN_TCI, &spec->tci,
252656c1817dSJun Yang 			&mask->tci, sizeof(rte_be16_t),
252756c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
252856c1817dSJun Yang 	if (ret)
252956c1817dSJun Yang 		return ret;
25305f176728SJun Yang 
253156c1817dSJun Yang 	ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_VLAN,
253256c1817dSJun Yang 			NH_FLD_VLAN_TCI, &spec->tci,
253356c1817dSJun Yang 			&mask->tci, sizeof(rte_be16_t),
253456c1817dSJun Yang 			priv, group, &local_cfg,
253556c1817dSJun Yang 			DPAA2_FLOW_FS_TYPE);
253656c1817dSJun Yang 	if (ret)
253756c1817dSJun Yang 		return ret;
25385f176728SJun Yang 
25395f176728SJun Yang 	(*device_configured) |= local_cfg;
25405f176728SJun Yang 	return 0;
2541fe2b986aSSunil Kumar Kori }
2542fe2b986aSSunil Kumar Kori 
2543fe2b986aSSunil Kumar Kori static int
25444cc5cf4aSJun Yang dpaa2_configure_flow_ipv4(struct dpaa2_dev_flow *flow,
25454cc5cf4aSJun Yang 	struct rte_eth_dev *dev,
2546fe2b986aSSunil Kumar Kori 	const struct rte_flow_attr *attr,
25479ec29343SJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
2548fe2b986aSSunil Kumar Kori 	const struct rte_flow_action actions[] __rte_unused,
25495f176728SJun Yang 	struct rte_flow_error *error __rte_unused,
25505f176728SJun Yang 	int *device_configured)
2551fe2b986aSSunil Kumar Kori {
255256c1817dSJun Yang 	int ret, local_cfg = 0;
2553fe2b986aSSunil Kumar Kori 	uint32_t group;
255456c1817dSJun Yang 	const struct rte_flow_item_ipv4 *spec_ipv4 = 0, *mask_ipv4 = 0;
25555f176728SJun Yang 	const void *key, *mask;
2556fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
25575f176728SJun Yang 	int size;
25589ec29343SJun Yang 	const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
2559fe2b986aSSunil Kumar Kori 
2560fe2b986aSSunil Kumar Kori 	group = attr->group;
2561fe2b986aSSunil Kumar Kori 
25625f176728SJun Yang 	/* Parse pattern list to get the matching parameters */
256356c1817dSJun Yang 	spec_ipv4 = pattern->spec;
256456c1817dSJun Yang 	mask_ipv4 = pattern->mask ?
256556c1817dSJun Yang 		    pattern->mask : &dpaa2_flow_item_ipv4_mask;
2566fe2b986aSSunil Kumar Kori 
25679ec29343SJun Yang 	if (dpaa2_pattern->in_tunnel) {
25689ec29343SJun Yang 		if (spec_ipv4) {
25699ec29343SJun Yang 			DPAA2_PMD_ERR("Tunnel-IPv4 distribution not support");
25709ec29343SJun Yang 			return -ENOTSUP;
25719ec29343SJun Yang 		}
25729ec29343SJun Yang 
25739ec29343SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
25749ec29343SJun Yang 				FAFE_VXLAN_IN_IPV4_FRAM,
25759ec29343SJun Yang 				DPAA2_FLOW_QOS_TYPE, group,
25769ec29343SJun Yang 				&local_cfg);
25779ec29343SJun Yang 		if (ret)
25789ec29343SJun Yang 			return ret;
25799ec29343SJun Yang 
25809ec29343SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
25819ec29343SJun Yang 				FAFE_VXLAN_IN_IPV4_FRAM,
25829ec29343SJun Yang 				DPAA2_FLOW_FS_TYPE, group,
25839ec29343SJun Yang 				&local_cfg);
25849ec29343SJun Yang 		return ret;
25859ec29343SJun Yang 	}
25869ec29343SJun Yang 
2587fe2b986aSSunil Kumar Kori 	/* Get traffic class index and flow id to be configured */
2588fe2b986aSSunil Kumar Kori 	flow->tc_id = group;
25895f176728SJun Yang 	flow->tc_index = attr->priority;
2590fe2b986aSSunil Kumar Kori 
2591200a33e4SJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV4_FRAM,
2592200a33e4SJun Yang 			DPAA2_FLOW_QOS_TYPE, group,
259356c1817dSJun Yang 			&local_cfg);
2594200a33e4SJun Yang 	if (ret)
259556c1817dSJun Yang 		return ret;
2596fe2b986aSSunil Kumar Kori 
2597200a33e4SJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV4_FRAM,
2598200a33e4SJun Yang 			DPAA2_FLOW_FS_TYPE, group, &local_cfg);
2599200a33e4SJun Yang 	if (ret)
2600200a33e4SJun Yang 		return ret;
2601200a33e4SJun Yang 
2602200a33e4SJun Yang 	if (!spec_ipv4) {
2603200a33e4SJun Yang 		(*device_configured) |= local_cfg;
26045f176728SJun Yang 		return 0;
2605200a33e4SJun Yang 	}
2606fe2b986aSSunil Kumar Kori 
26074cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask_ipv4,
26084cc5cf4aSJun Yang 			RTE_FLOW_ITEM_TYPE_IPV4);
26094cc5cf4aSJun Yang 	if (ret) {
2610926c1279SJun Yang 		DPAA2_PMD_WARN("Extract field(s) of IPv4 not support.");
26114cc5cf4aSJun Yang 		return ret;
2612926c1279SJun Yang 	}
2613926c1279SJun Yang 
261456c1817dSJun Yang 	if (mask_ipv4->hdr.src_addr) {
26155f176728SJun Yang 		key = &spec_ipv4->hdr.src_addr;
26165f176728SJun Yang 		mask = &mask_ipv4->hdr.src_addr;
261756c1817dSJun Yang 		size = sizeof(rte_be32_t);
261856c1817dSJun Yang 
261956c1817dSJun Yang 		ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
262056c1817dSJun Yang 				NH_FLD_IPV4_SRC_IP,
262156c1817dSJun Yang 				key, mask, size, priv,
262256c1817dSJun Yang 				group, &local_cfg,
262356c1817dSJun Yang 				DPAA2_FLOW_QOS_TYPE);
262456c1817dSJun Yang 		if (ret)
262556c1817dSJun Yang 			return ret;
262656c1817dSJun Yang 
262756c1817dSJun Yang 		ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
262856c1817dSJun Yang 				NH_FLD_IPV4_SRC_IP,
262956c1817dSJun Yang 				key, mask, size, priv,
263056c1817dSJun Yang 				group, &local_cfg,
263156c1817dSJun Yang 				DPAA2_FLOW_FS_TYPE);
263256c1817dSJun Yang 		if (ret)
263356c1817dSJun Yang 			return ret;
2634fe2b986aSSunil Kumar Kori 	}
2635fe2b986aSSunil Kumar Kori 
263656c1817dSJun Yang 	if (mask_ipv4->hdr.dst_addr) {
26375f176728SJun Yang 		key = &spec_ipv4->hdr.dst_addr;
26385f176728SJun Yang 		mask = &mask_ipv4->hdr.dst_addr;
263956c1817dSJun Yang 		size = sizeof(rte_be32_t);
264056c1817dSJun Yang 
264156c1817dSJun Yang 		ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
264256c1817dSJun Yang 				NH_FLD_IPV4_DST_IP,
264356c1817dSJun Yang 				key, mask, size, priv,
264456c1817dSJun Yang 				group, &local_cfg,
264556c1817dSJun Yang 				DPAA2_FLOW_QOS_TYPE);
264656c1817dSJun Yang 		if (ret)
264756c1817dSJun Yang 			return ret;
264856c1817dSJun Yang 		ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV4,
264956c1817dSJun Yang 				NH_FLD_IPV4_DST_IP,
265056c1817dSJun Yang 				key, mask, size, priv,
265156c1817dSJun Yang 				group, &local_cfg,
265256c1817dSJun Yang 				DPAA2_FLOW_FS_TYPE);
265356c1817dSJun Yang 		if (ret)
265456c1817dSJun Yang 			return ret;
26555f176728SJun Yang 	}
26565f176728SJun Yang 
265756c1817dSJun Yang 	if (mask_ipv4->hdr.next_proto_id) {
26585f176728SJun Yang 		key = &spec_ipv4->hdr.next_proto_id;
26595f176728SJun Yang 		mask = &mask_ipv4->hdr.next_proto_id;
266056c1817dSJun Yang 		size = sizeof(uint8_t);
26615f176728SJun Yang 
266256c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
266356c1817dSJun Yang 				NH_FLD_IP_PROTO, key,
266456c1817dSJun Yang 				mask, size, priv, group,
266556c1817dSJun Yang 				&local_cfg,
266656c1817dSJun Yang 				DPAA2_FLOW_QOS_TYPE);
266756c1817dSJun Yang 		if (ret)
266856c1817dSJun Yang 			return ret;
26695f176728SJun Yang 
267056c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
267156c1817dSJun Yang 				NH_FLD_IP_PROTO, key,
267256c1817dSJun Yang 				mask, size, priv, group,
267356c1817dSJun Yang 				&local_cfg,
267456c1817dSJun Yang 				DPAA2_FLOW_FS_TYPE);
267556c1817dSJun Yang 		if (ret)
267656c1817dSJun Yang 			return ret;
2677fe2b986aSSunil Kumar Kori 	}
2678fe2b986aSSunil Kumar Kori 
26795f176728SJun Yang 	(*device_configured) |= local_cfg;
26805f176728SJun Yang 	return 0;
2681fe2b986aSSunil Kumar Kori }
2682fe2b986aSSunil Kumar Kori 
2683fe2b986aSSunil Kumar Kori static int
26844cc5cf4aSJun Yang dpaa2_configure_flow_ipv6(struct dpaa2_dev_flow *flow,
26854cc5cf4aSJun Yang 	struct rte_eth_dev *dev,
268656c1817dSJun Yang 	const struct rte_flow_attr *attr,
26879ec29343SJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
268856c1817dSJun Yang 	const struct rte_flow_action actions[] __rte_unused,
268956c1817dSJun Yang 	struct rte_flow_error *error __rte_unused,
269056c1817dSJun Yang 	int *device_configured)
269156c1817dSJun Yang {
269256c1817dSJun Yang 	int ret, local_cfg = 0;
269356c1817dSJun Yang 	uint32_t group;
269456c1817dSJun Yang 	const struct rte_flow_item_ipv6 *spec_ipv6 = 0, *mask_ipv6 = 0;
269556c1817dSJun Yang 	const void *key, *mask;
269656c1817dSJun Yang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
269756c1817dSJun Yang 	const char zero_cmp[NH_FLD_IPV6_ADDR_SIZE] = {0};
269856c1817dSJun Yang 	int size;
26999ec29343SJun Yang 	const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
270056c1817dSJun Yang 
270156c1817dSJun Yang 	group = attr->group;
270256c1817dSJun Yang 
270356c1817dSJun Yang 	/* Parse pattern list to get the matching parameters */
270456c1817dSJun Yang 	spec_ipv6 = pattern->spec;
270556c1817dSJun Yang 	mask_ipv6 = pattern->mask ? pattern->mask : &dpaa2_flow_item_ipv6_mask;
270656c1817dSJun Yang 
270756c1817dSJun Yang 	/* Get traffic class index and flow id to be configured */
270856c1817dSJun Yang 	flow->tc_id = group;
270956c1817dSJun Yang 	flow->tc_index = attr->priority;
271056c1817dSJun Yang 
27119ec29343SJun Yang 	if (dpaa2_pattern->in_tunnel) {
27129ec29343SJun Yang 		if (spec_ipv6) {
27139ec29343SJun Yang 			DPAA2_PMD_ERR("Tunnel-IPv6 distribution not support");
27149ec29343SJun Yang 			return -ENOTSUP;
27159ec29343SJun Yang 		}
27169ec29343SJun Yang 
27179ec29343SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
27189ec29343SJun Yang 				FAFE_VXLAN_IN_IPV6_FRAM,
27199ec29343SJun Yang 				DPAA2_FLOW_QOS_TYPE, group,
27209ec29343SJun Yang 				&local_cfg);
27219ec29343SJun Yang 		if (ret)
27229ec29343SJun Yang 			return ret;
27239ec29343SJun Yang 
27249ec29343SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
27259ec29343SJun Yang 				FAFE_VXLAN_IN_IPV6_FRAM,
27269ec29343SJun Yang 				DPAA2_FLOW_FS_TYPE, group,
27279ec29343SJun Yang 				&local_cfg);
27289ec29343SJun Yang 		return ret;
27299ec29343SJun Yang 	}
27309ec29343SJun Yang 
2731200a33e4SJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV6_FRAM,
2732200a33e4SJun Yang 			DPAA2_FLOW_QOS_TYPE, group,
2733200a33e4SJun Yang 			&local_cfg);
2734200a33e4SJun Yang 	if (ret)
273556c1817dSJun Yang 		return ret;
273656c1817dSJun Yang 
2737200a33e4SJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow, FAF_IPV6_FRAM,
2738200a33e4SJun Yang 			DPAA2_FLOW_FS_TYPE, group, &local_cfg);
2739200a33e4SJun Yang 	if (ret)
2740200a33e4SJun Yang 		return ret;
2741200a33e4SJun Yang 
2742200a33e4SJun Yang 	if (!spec_ipv6) {
2743200a33e4SJun Yang 		(*device_configured) |= local_cfg;
274456c1817dSJun Yang 		return 0;
2745200a33e4SJun Yang 	}
274656c1817dSJun Yang 
27474cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask_ipv6,
27484cc5cf4aSJun Yang 			RTE_FLOW_ITEM_TYPE_IPV6);
27494cc5cf4aSJun Yang 	if (ret) {
275056c1817dSJun Yang 		DPAA2_PMD_WARN("Extract field(s) of IPv6 not support.");
27514cc5cf4aSJun Yang 		return ret;
275256c1817dSJun Yang 	}
275356c1817dSJun Yang 
275456c1817dSJun Yang 	if (memcmp((const char *)&mask_ipv6->hdr.src_addr, zero_cmp, NH_FLD_IPV6_ADDR_SIZE)) {
275556c1817dSJun Yang 		key = &spec_ipv6->hdr.src_addr;
275656c1817dSJun Yang 		mask = &mask_ipv6->hdr.src_addr;
275756c1817dSJun Yang 		size = NH_FLD_IPV6_ADDR_SIZE;
275856c1817dSJun Yang 
275956c1817dSJun Yang 		ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
276056c1817dSJun Yang 				NH_FLD_IPV6_SRC_IP,
276156c1817dSJun Yang 				key, mask, size, priv,
276256c1817dSJun Yang 				group, &local_cfg,
276356c1817dSJun Yang 				DPAA2_FLOW_QOS_TYPE);
276456c1817dSJun Yang 		if (ret)
276556c1817dSJun Yang 			return ret;
276656c1817dSJun Yang 
276756c1817dSJun Yang 		ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
276856c1817dSJun Yang 				NH_FLD_IPV6_SRC_IP,
276956c1817dSJun Yang 				key, mask, size, priv,
277056c1817dSJun Yang 				group, &local_cfg,
277156c1817dSJun Yang 				DPAA2_FLOW_FS_TYPE);
277256c1817dSJun Yang 		if (ret)
277356c1817dSJun Yang 			return ret;
277456c1817dSJun Yang 	}
277556c1817dSJun Yang 
277656c1817dSJun Yang 	if (memcmp((const char *)&mask_ipv6->hdr.dst_addr, zero_cmp, NH_FLD_IPV6_ADDR_SIZE)) {
277756c1817dSJun Yang 		key = &spec_ipv6->hdr.dst_addr;
277856c1817dSJun Yang 		mask = &mask_ipv6->hdr.dst_addr;
277956c1817dSJun Yang 		size = NH_FLD_IPV6_ADDR_SIZE;
278056c1817dSJun Yang 
278156c1817dSJun Yang 		ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
278256c1817dSJun Yang 				NH_FLD_IPV6_DST_IP,
278356c1817dSJun Yang 				key, mask, size, priv,
278456c1817dSJun Yang 				group, &local_cfg,
278556c1817dSJun Yang 				DPAA2_FLOW_QOS_TYPE);
278656c1817dSJun Yang 		if (ret)
278756c1817dSJun Yang 			return ret;
278856c1817dSJun Yang 
278956c1817dSJun Yang 		ret = dpaa2_flow_add_ipaddr_extract_rule(flow, NET_PROT_IPV6,
279056c1817dSJun Yang 				NH_FLD_IPV6_DST_IP,
279156c1817dSJun Yang 				key, mask, size, priv,
279256c1817dSJun Yang 				group, &local_cfg,
279356c1817dSJun Yang 				DPAA2_FLOW_FS_TYPE);
279456c1817dSJun Yang 		if (ret)
279556c1817dSJun Yang 			return ret;
279656c1817dSJun Yang 	}
279756c1817dSJun Yang 
279856c1817dSJun Yang 	if (mask_ipv6->hdr.proto) {
279956c1817dSJun Yang 		key = &spec_ipv6->hdr.proto;
280056c1817dSJun Yang 		mask = &mask_ipv6->hdr.proto;
280156c1817dSJun Yang 		size = sizeof(uint8_t);
280256c1817dSJun Yang 
280356c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
280456c1817dSJun Yang 				NH_FLD_IP_PROTO, key,
280556c1817dSJun Yang 				mask, size, priv, group,
280656c1817dSJun Yang 				&local_cfg,
280756c1817dSJun Yang 				DPAA2_FLOW_QOS_TYPE);
280856c1817dSJun Yang 		if (ret)
280956c1817dSJun Yang 			return ret;
281056c1817dSJun Yang 
281156c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IP,
281256c1817dSJun Yang 				NH_FLD_IP_PROTO, key,
281356c1817dSJun Yang 				mask, size, priv, group,
281456c1817dSJun Yang 				&local_cfg,
281556c1817dSJun Yang 				DPAA2_FLOW_FS_TYPE);
281656c1817dSJun Yang 		if (ret)
281756c1817dSJun Yang 			return ret;
281856c1817dSJun Yang 	}
281956c1817dSJun Yang 
282056c1817dSJun Yang 	(*device_configured) |= local_cfg;
282156c1817dSJun Yang 	return 0;
282256c1817dSJun Yang }
282356c1817dSJun Yang 
282456c1817dSJun Yang static int
282556c1817dSJun Yang dpaa2_configure_flow_icmp(struct dpaa2_dev_flow *flow,
2826fe2b986aSSunil Kumar Kori 	struct rte_eth_dev *dev,
2827fe2b986aSSunil Kumar Kori 	const struct rte_flow_attr *attr,
28289ec29343SJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
2829fe2b986aSSunil Kumar Kori 	const struct rte_flow_action actions[] __rte_unused,
28305f176728SJun Yang 	struct rte_flow_error *error __rte_unused,
28315f176728SJun Yang 	int *device_configured)
2832fe2b986aSSunil Kumar Kori {
283356c1817dSJun Yang 	int ret, local_cfg = 0;
2834fe2b986aSSunil Kumar Kori 	uint32_t group;
2835fe2b986aSSunil Kumar Kori 	const struct rte_flow_item_icmp *spec, *mask;
2836fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
28379ec29343SJun Yang 	const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
2838fe2b986aSSunil Kumar Kori 
2839fe2b986aSSunil Kumar Kori 	group = attr->group;
2840fe2b986aSSunil Kumar Kori 
2841fe2b986aSSunil Kumar Kori 	/* Parse pattern list to get the matching parameters */
284256c1817dSJun Yang 	spec = pattern->spec;
284356c1817dSJun Yang 	mask = pattern->mask ?
284456c1817dSJun Yang 		pattern->mask : &dpaa2_flow_item_icmp_mask;
2845fe2b986aSSunil Kumar Kori 
28465f176728SJun Yang 	/* Get traffic class index and flow id to be configured */
28475f176728SJun Yang 	flow->tc_id = group;
28485f176728SJun Yang 	flow->tc_index = attr->priority;
2849fe2b986aSSunil Kumar Kori 
28509ec29343SJun Yang 	if (dpaa2_pattern->in_tunnel) {
28519ec29343SJun Yang 		DPAA2_PMD_ERR("Tunnel-ICMP distribution not support");
28529ec29343SJun Yang 		return -ENOTSUP;
28539ec29343SJun Yang 	}
28549ec29343SJun Yang 
28555f176728SJun Yang 	if (!spec) {
2856200a33e4SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
2857200a33e4SJun Yang 				FAF_ICMP_FRAM, DPAA2_FLOW_QOS_TYPE,
2858200a33e4SJun Yang 				group, &local_cfg);
2859200a33e4SJun Yang 		if (ret)
2860200a33e4SJun Yang 			return ret;
2861fe2b986aSSunil Kumar Kori 
2862200a33e4SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
2863200a33e4SJun Yang 				FAF_ICMP_FRAM, DPAA2_FLOW_FS_TYPE,
286456c1817dSJun Yang 				group, &local_cfg);
286556c1817dSJun Yang 		if (ret)
286656c1817dSJun Yang 			return ret;
28675f176728SJun Yang 
28685f176728SJun Yang 		(*device_configured) |= local_cfg;
28695f176728SJun Yang 		return 0;
28705f176728SJun Yang 	}
28715f176728SJun Yang 
28724cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
28734cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_ICMP);
28744cc5cf4aSJun Yang 	if (ret) {
2875926c1279SJun Yang 		DPAA2_PMD_WARN("Extract field(s) of ICMP not support.");
2876926c1279SJun Yang 
28774cc5cf4aSJun Yang 		return ret;
2878926c1279SJun Yang 	}
2879926c1279SJun Yang 
28805f176728SJun Yang 	if (mask->hdr.icmp_type) {
288156c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
288256c1817dSJun Yang 			NH_FLD_ICMP_TYPE, &spec->hdr.icmp_type,
288356c1817dSJun Yang 			&mask->hdr.icmp_type, sizeof(uint8_t),
288456c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
288556c1817dSJun Yang 		if (ret)
288656c1817dSJun Yang 			return ret;
28875f176728SJun Yang 
288856c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
288956c1817dSJun Yang 			NH_FLD_ICMP_TYPE, &spec->hdr.icmp_type,
289056c1817dSJun Yang 			&mask->hdr.icmp_type, sizeof(uint8_t),
289156c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
289256c1817dSJun Yang 		if (ret)
289356c1817dSJun Yang 			return ret;
28945f176728SJun Yang 	}
28955f176728SJun Yang 
28965f176728SJun Yang 	if (mask->hdr.icmp_code) {
289756c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
289856c1817dSJun Yang 			NH_FLD_ICMP_CODE, &spec->hdr.icmp_code,
289956c1817dSJun Yang 			&mask->hdr.icmp_code, sizeof(uint8_t),
290056c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
290156c1817dSJun Yang 		if (ret)
290256c1817dSJun Yang 			return ret;
29035f176728SJun Yang 
290456c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_ICMP,
290556c1817dSJun Yang 			NH_FLD_ICMP_CODE, &spec->hdr.icmp_code,
290656c1817dSJun Yang 			&mask->hdr.icmp_code, sizeof(uint8_t),
290756c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
290856c1817dSJun Yang 		if (ret)
290956c1817dSJun Yang 			return ret;
29105f176728SJun Yang 	}
29115f176728SJun Yang 
29125f176728SJun Yang 	(*device_configured) |= local_cfg;
29135f176728SJun Yang 
29145f176728SJun Yang 	return 0;
2915fe2b986aSSunil Kumar Kori }
2916fe2b986aSSunil Kumar Kori 
2917fe2b986aSSunil Kumar Kori static int
291856c1817dSJun Yang dpaa2_configure_flow_udp(struct dpaa2_dev_flow *flow,
2919fe2b986aSSunil Kumar Kori 	struct rte_eth_dev *dev,
2920fe2b986aSSunil Kumar Kori 	const struct rte_flow_attr *attr,
29219ec29343SJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
2922fe2b986aSSunil Kumar Kori 	const struct rte_flow_action actions[] __rte_unused,
29235f176728SJun Yang 	struct rte_flow_error *error __rte_unused,
29245f176728SJun Yang 	int *device_configured)
2925fe2b986aSSunil Kumar Kori {
292656c1817dSJun Yang 	int ret, local_cfg = 0;
2927fe2b986aSSunil Kumar Kori 	uint32_t group;
2928fe2b986aSSunil Kumar Kori 	const struct rte_flow_item_udp *spec, *mask;
2929fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
29309ec29343SJun Yang 	const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
2931fe2b986aSSunil Kumar Kori 
2932fe2b986aSSunil Kumar Kori 	group = attr->group;
2933fe2b986aSSunil Kumar Kori 
2934fe2b986aSSunil Kumar Kori 	/* Parse pattern list to get the matching parameters */
293556c1817dSJun Yang 	spec = pattern->spec;
293656c1817dSJun Yang 	mask = pattern->mask ?
293756c1817dSJun Yang 		pattern->mask : &dpaa2_flow_item_udp_mask;
2938fe2b986aSSunil Kumar Kori 
29395f176728SJun Yang 	/* Get traffic class index and flow id to be configured */
29405f176728SJun Yang 	flow->tc_id = group;
29415f176728SJun Yang 	flow->tc_index = attr->priority;
2942fe2b986aSSunil Kumar Kori 
29439ec29343SJun Yang 	if (dpaa2_pattern->in_tunnel) {
29449ec29343SJun Yang 		if (spec) {
29459ec29343SJun Yang 			DPAA2_PMD_ERR("Tunnel-UDP distribution not support");
29469ec29343SJun Yang 			return -ENOTSUP;
29479ec29343SJun Yang 		}
29489ec29343SJun Yang 
29499ec29343SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
29509ec29343SJun Yang 				FAFE_VXLAN_IN_UDP_FRAM,
29519ec29343SJun Yang 				DPAA2_FLOW_QOS_TYPE, group,
29529ec29343SJun Yang 				&local_cfg);
29539ec29343SJun Yang 		if (ret)
29549ec29343SJun Yang 			return ret;
29559ec29343SJun Yang 
29569ec29343SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
29579ec29343SJun Yang 				FAFE_VXLAN_IN_UDP_FRAM,
29589ec29343SJun Yang 				DPAA2_FLOW_FS_TYPE, group,
29599ec29343SJun Yang 				&local_cfg);
29609ec29343SJun Yang 		return ret;
29619ec29343SJun Yang 	}
29629ec29343SJun Yang 
2963200a33e4SJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow,
2964200a33e4SJun Yang 			FAF_UDP_FRAM, DPAA2_FLOW_QOS_TYPE,
296556c1817dSJun Yang 			group, &local_cfg);
296656c1817dSJun Yang 	if (ret)
296756c1817dSJun Yang 		return ret;
29685f176728SJun Yang 
2969200a33e4SJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow,
2970200a33e4SJun Yang 			FAF_UDP_FRAM, DPAA2_FLOW_FS_TYPE,
2971200a33e4SJun Yang 			group, &local_cfg);
2972200a33e4SJun Yang 	if (ret)
2973200a33e4SJun Yang 		return ret;
29745f176728SJun Yang 
2975200a33e4SJun Yang 	if (!spec) {
2976200a33e4SJun Yang 		(*device_configured) |= local_cfg;
29775f176728SJun Yang 		return 0;
29785f176728SJun Yang 	}
29795f176728SJun Yang 
29804cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
29814cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_UDP);
29824cc5cf4aSJun Yang 	if (ret) {
2983926c1279SJun Yang 		DPAA2_PMD_WARN("Extract field(s) of UDP not support.");
2984926c1279SJun Yang 
29854cc5cf4aSJun Yang 		return ret;
2986926c1279SJun Yang 	}
2987926c1279SJun Yang 
29885f176728SJun Yang 	if (mask->hdr.src_port) {
298956c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
299056c1817dSJun Yang 			NH_FLD_UDP_PORT_SRC, &spec->hdr.src_port,
299156c1817dSJun Yang 			&mask->hdr.src_port, sizeof(rte_be16_t),
299256c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
299356c1817dSJun Yang 		if (ret)
299456c1817dSJun Yang 			return ret;
29955f176728SJun Yang 
299656c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
299756c1817dSJun Yang 			NH_FLD_UDP_PORT_SRC, &spec->hdr.src_port,
299856c1817dSJun Yang 			&mask->hdr.src_port, sizeof(rte_be16_t),
299956c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
300056c1817dSJun Yang 		if (ret)
300156c1817dSJun Yang 			return ret;
30025f176728SJun Yang 	}
30035f176728SJun Yang 
30045f176728SJun Yang 	if (mask->hdr.dst_port) {
300556c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
300656c1817dSJun Yang 			NH_FLD_UDP_PORT_DST, &spec->hdr.dst_port,
300756c1817dSJun Yang 			&mask->hdr.dst_port, sizeof(rte_be16_t),
300856c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
300956c1817dSJun Yang 		if (ret)
301056c1817dSJun Yang 			return ret;
30115f176728SJun Yang 
301256c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_UDP,
301356c1817dSJun Yang 			NH_FLD_UDP_PORT_DST, &spec->hdr.dst_port,
301456c1817dSJun Yang 			&mask->hdr.dst_port, sizeof(rte_be16_t),
301556c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
301656c1817dSJun Yang 		if (ret)
301756c1817dSJun Yang 			return ret;
30185f176728SJun Yang 	}
30195f176728SJun Yang 
30205f176728SJun Yang 	(*device_configured) |= local_cfg;
30215f176728SJun Yang 
30225f176728SJun Yang 	return 0;
3023fe2b986aSSunil Kumar Kori }
3024fe2b986aSSunil Kumar Kori 
3025fe2b986aSSunil Kumar Kori static int
302656c1817dSJun Yang dpaa2_configure_flow_tcp(struct dpaa2_dev_flow *flow,
3027fe2b986aSSunil Kumar Kori 	struct rte_eth_dev *dev,
3028fe2b986aSSunil Kumar Kori 	const struct rte_flow_attr *attr,
30299ec29343SJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
3030fe2b986aSSunil Kumar Kori 	const struct rte_flow_action actions[] __rte_unused,
30315f176728SJun Yang 	struct rte_flow_error *error __rte_unused,
30325f176728SJun Yang 	int *device_configured)
3033fe2b986aSSunil Kumar Kori {
303456c1817dSJun Yang 	int ret, local_cfg = 0;
3035fe2b986aSSunil Kumar Kori 	uint32_t group;
3036fe2b986aSSunil Kumar Kori 	const struct rte_flow_item_tcp *spec, *mask;
3037fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
30389ec29343SJun Yang 	const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3039fe2b986aSSunil Kumar Kori 
3040fe2b986aSSunil Kumar Kori 	group = attr->group;
3041fe2b986aSSunil Kumar Kori 
3042fe2b986aSSunil Kumar Kori 	/* Parse pattern list to get the matching parameters */
304356c1817dSJun Yang 	spec = pattern->spec;
304456c1817dSJun Yang 	mask = pattern->mask ?
304556c1817dSJun Yang 		pattern->mask : &dpaa2_flow_item_tcp_mask;
3046fe2b986aSSunil Kumar Kori 
30475f176728SJun Yang 	/* Get traffic class index and flow id to be configured */
30485f176728SJun Yang 	flow->tc_id = group;
30495f176728SJun Yang 	flow->tc_index = attr->priority;
3050fe2b986aSSunil Kumar Kori 
30519ec29343SJun Yang 	if (dpaa2_pattern->in_tunnel) {
30529ec29343SJun Yang 		if (spec) {
30539ec29343SJun Yang 			DPAA2_PMD_ERR("Tunnel-TCP distribution not support");
30549ec29343SJun Yang 			return -ENOTSUP;
30559ec29343SJun Yang 		}
30569ec29343SJun Yang 
30579ec29343SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
30589ec29343SJun Yang 				FAFE_VXLAN_IN_TCP_FRAM,
30599ec29343SJun Yang 				DPAA2_FLOW_QOS_TYPE, group,
30609ec29343SJun Yang 				&local_cfg);
30619ec29343SJun Yang 		if (ret)
30629ec29343SJun Yang 			return ret;
30639ec29343SJun Yang 
30649ec29343SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
30659ec29343SJun Yang 						 FAFE_VXLAN_IN_TCP_FRAM,
30669ec29343SJun Yang 						 DPAA2_FLOW_FS_TYPE, group,
30679ec29343SJun Yang 						 &local_cfg);
30689ec29343SJun Yang 		return ret;
30699ec29343SJun Yang 	}
30709ec29343SJun Yang 
3071200a33e4SJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow,
3072200a33e4SJun Yang 			FAF_TCP_FRAM, DPAA2_FLOW_QOS_TYPE,
307356c1817dSJun Yang 			group, &local_cfg);
307456c1817dSJun Yang 	if (ret)
307556c1817dSJun Yang 		return ret;
30765f176728SJun Yang 
3077200a33e4SJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow,
3078200a33e4SJun Yang 			FAF_TCP_FRAM, DPAA2_FLOW_FS_TYPE,
3079200a33e4SJun Yang 			group, &local_cfg);
3080200a33e4SJun Yang 	if (ret)
3081200a33e4SJun Yang 		return ret;
30825f176728SJun Yang 
3083200a33e4SJun Yang 	if (!spec) {
3084200a33e4SJun Yang 		(*device_configured) |= local_cfg;
30855f176728SJun Yang 		return 0;
30865f176728SJun Yang 	}
30875f176728SJun Yang 
30884cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
30894cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_TCP);
30904cc5cf4aSJun Yang 	if (ret) {
3091926c1279SJun Yang 		DPAA2_PMD_WARN("Extract field(s) of TCP not support.");
3092926c1279SJun Yang 
30934cc5cf4aSJun Yang 		return ret;
3094926c1279SJun Yang 	}
3095926c1279SJun Yang 
30965f176728SJun Yang 	if (mask->hdr.src_port) {
309756c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
309856c1817dSJun Yang 			NH_FLD_TCP_PORT_SRC, &spec->hdr.src_port,
309956c1817dSJun Yang 			&mask->hdr.src_port, sizeof(rte_be16_t),
310056c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
310156c1817dSJun Yang 		if (ret)
310256c1817dSJun Yang 			return ret;
31035f176728SJun Yang 
310456c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
310556c1817dSJun Yang 			NH_FLD_TCP_PORT_SRC, &spec->hdr.src_port,
310656c1817dSJun Yang 			&mask->hdr.src_port, sizeof(rte_be16_t),
310756c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
310856c1817dSJun Yang 		if (ret)
310956c1817dSJun Yang 			return ret;
31105f176728SJun Yang 	}
31115f176728SJun Yang 
31125f176728SJun Yang 	if (mask->hdr.dst_port) {
311356c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
311456c1817dSJun Yang 			NH_FLD_TCP_PORT_DST, &spec->hdr.dst_port,
311556c1817dSJun Yang 			&mask->hdr.dst_port, sizeof(rte_be16_t),
311656c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
311756c1817dSJun Yang 		if (ret)
311856c1817dSJun Yang 			return ret;
31195f176728SJun Yang 
312056c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_TCP,
312156c1817dSJun Yang 			NH_FLD_TCP_PORT_DST, &spec->hdr.dst_port,
312256c1817dSJun Yang 			&mask->hdr.dst_port, sizeof(rte_be16_t),
312356c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
312456c1817dSJun Yang 		if (ret)
312556c1817dSJun Yang 			return ret;
31265f176728SJun Yang 	}
31275f176728SJun Yang 
31285f176728SJun Yang 	(*device_configured) |= local_cfg;
31295f176728SJun Yang 
31305f176728SJun Yang 	return 0;
3131fe2b986aSSunil Kumar Kori }
3132fe2b986aSSunil Kumar Kori 
3133fe2b986aSSunil Kumar Kori static int
31344cc5cf4aSJun Yang dpaa2_configure_flow_esp(struct dpaa2_dev_flow *flow,
31354cc5cf4aSJun Yang 	struct rte_eth_dev *dev,
31364cc5cf4aSJun Yang 	const struct rte_flow_attr *attr,
31374cc5cf4aSJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
31384cc5cf4aSJun Yang 	const struct rte_flow_action actions[] __rte_unused,
31394cc5cf4aSJun Yang 	struct rte_flow_error *error __rte_unused,
31404cc5cf4aSJun Yang 	int *device_configured)
31414cc5cf4aSJun Yang {
31424cc5cf4aSJun Yang 	int ret, local_cfg = 0;
31434cc5cf4aSJun Yang 	uint32_t group;
31444cc5cf4aSJun Yang 	const struct rte_flow_item_esp *spec, *mask;
31454cc5cf4aSJun Yang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
31464cc5cf4aSJun Yang 	const struct rte_flow_item *pattern =
31474cc5cf4aSJun Yang 		&dpaa2_pattern->generic_item;
31484cc5cf4aSJun Yang 
31494cc5cf4aSJun Yang 	group = attr->group;
31504cc5cf4aSJun Yang 
31514cc5cf4aSJun Yang 	/* Parse pattern list to get the matching parameters */
31524cc5cf4aSJun Yang 	spec = pattern->spec;
31534cc5cf4aSJun Yang 	mask = pattern->mask ?
31544cc5cf4aSJun Yang 		pattern->mask : &dpaa2_flow_item_esp_mask;
31554cc5cf4aSJun Yang 
31564cc5cf4aSJun Yang 	/* Get traffic class index and flow id to be configured */
31574cc5cf4aSJun Yang 	flow->tc_id = group;
31584cc5cf4aSJun Yang 	flow->tc_index = attr->priority;
31594cc5cf4aSJun Yang 
31604cc5cf4aSJun Yang 	if (dpaa2_pattern->in_tunnel) {
31614cc5cf4aSJun Yang 		DPAA2_PMD_ERR("Tunnel-ESP distribution not support");
31624cc5cf4aSJun Yang 		return -ENOTSUP;
31634cc5cf4aSJun Yang 	}
31644cc5cf4aSJun Yang 
31654cc5cf4aSJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow,
31664cc5cf4aSJun Yang 			FAF_IPSEC_ESP_FRAM, DPAA2_FLOW_QOS_TYPE,
31674cc5cf4aSJun Yang 			group, &local_cfg);
31684cc5cf4aSJun Yang 	if (ret)
31694cc5cf4aSJun Yang 		return ret;
31704cc5cf4aSJun Yang 
31714cc5cf4aSJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow,
31724cc5cf4aSJun Yang 			FAF_IPSEC_ESP_FRAM, DPAA2_FLOW_FS_TYPE,
31734cc5cf4aSJun Yang 			group, &local_cfg);
31744cc5cf4aSJun Yang 	if (ret)
31754cc5cf4aSJun Yang 		return ret;
31764cc5cf4aSJun Yang 
31774cc5cf4aSJun Yang 	if (!spec) {
31784cc5cf4aSJun Yang 		(*device_configured) |= local_cfg;
31794cc5cf4aSJun Yang 		return 0;
31804cc5cf4aSJun Yang 	}
31814cc5cf4aSJun Yang 
31824cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
31834cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_ESP);
31844cc5cf4aSJun Yang 	if (ret) {
31854cc5cf4aSJun Yang 		DPAA2_PMD_WARN("Extract field(s) of ESP not support.");
31864cc5cf4aSJun Yang 
31874cc5cf4aSJun Yang 		return ret;
31884cc5cf4aSJun Yang 	}
31894cc5cf4aSJun Yang 
31904cc5cf4aSJun Yang 	if (mask->hdr.spi) {
31914cc5cf4aSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
31924cc5cf4aSJun Yang 			NH_FLD_IPSEC_ESP_SPI, &spec->hdr.spi,
31934cc5cf4aSJun Yang 			&mask->hdr.spi, sizeof(rte_be32_t),
31944cc5cf4aSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
31954cc5cf4aSJun Yang 		if (ret)
31964cc5cf4aSJun Yang 			return ret;
31974cc5cf4aSJun Yang 
31984cc5cf4aSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
31994cc5cf4aSJun Yang 			NH_FLD_IPSEC_ESP_SPI, &spec->hdr.spi,
32004cc5cf4aSJun Yang 			&mask->hdr.spi, sizeof(rte_be32_t),
32014cc5cf4aSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
32024cc5cf4aSJun Yang 		if (ret)
32034cc5cf4aSJun Yang 			return ret;
32044cc5cf4aSJun Yang 	}
32054cc5cf4aSJun Yang 
32064cc5cf4aSJun Yang 	if (mask->hdr.seq) {
32074cc5cf4aSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
32084cc5cf4aSJun Yang 			NH_FLD_IPSEC_ESP_SEQUENCE_NUM, &spec->hdr.seq,
32094cc5cf4aSJun Yang 			&mask->hdr.seq, sizeof(rte_be32_t),
32104cc5cf4aSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
32114cc5cf4aSJun Yang 		if (ret)
32124cc5cf4aSJun Yang 			return ret;
32134cc5cf4aSJun Yang 
32144cc5cf4aSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_ESP,
32154cc5cf4aSJun Yang 			NH_FLD_IPSEC_ESP_SEQUENCE_NUM, &spec->hdr.seq,
32164cc5cf4aSJun Yang 			&mask->hdr.seq, sizeof(rte_be32_t),
32174cc5cf4aSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
32184cc5cf4aSJun Yang 		if (ret)
32194cc5cf4aSJun Yang 			return ret;
32204cc5cf4aSJun Yang 	}
32214cc5cf4aSJun Yang 
32224cc5cf4aSJun Yang 	(*device_configured) |= local_cfg;
32234cc5cf4aSJun Yang 
32244cc5cf4aSJun Yang 	return 0;
32254cc5cf4aSJun Yang }
32264cc5cf4aSJun Yang 
32274cc5cf4aSJun Yang static int
32284cc5cf4aSJun Yang dpaa2_configure_flow_ah(struct dpaa2_dev_flow *flow,
32294cc5cf4aSJun Yang 	struct rte_eth_dev *dev,
32304cc5cf4aSJun Yang 	const struct rte_flow_attr *attr,
32314cc5cf4aSJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
32324cc5cf4aSJun Yang 	const struct rte_flow_action actions[] __rte_unused,
32334cc5cf4aSJun Yang 	struct rte_flow_error *error __rte_unused,
32344cc5cf4aSJun Yang 	int *device_configured)
32354cc5cf4aSJun Yang {
32364cc5cf4aSJun Yang 	int ret, local_cfg = 0;
32374cc5cf4aSJun Yang 	uint32_t group;
32384cc5cf4aSJun Yang 	const struct rte_flow_item_ah *spec, *mask;
32394cc5cf4aSJun Yang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
32404cc5cf4aSJun Yang 	const struct rte_flow_item *pattern =
32414cc5cf4aSJun Yang 		&dpaa2_pattern->generic_item;
32424cc5cf4aSJun Yang 
32434cc5cf4aSJun Yang 	group = attr->group;
32444cc5cf4aSJun Yang 
32454cc5cf4aSJun Yang 	/* Parse pattern list to get the matching parameters */
32464cc5cf4aSJun Yang 	spec = pattern->spec;
32474cc5cf4aSJun Yang 	mask = pattern->mask ?
32484cc5cf4aSJun Yang 		pattern->mask : &dpaa2_flow_item_ah_mask;
32494cc5cf4aSJun Yang 
32504cc5cf4aSJun Yang 	/* Get traffic class index and flow id to be configured */
32514cc5cf4aSJun Yang 	flow->tc_id = group;
32524cc5cf4aSJun Yang 	flow->tc_index = attr->priority;
32534cc5cf4aSJun Yang 
32544cc5cf4aSJun Yang 	if (dpaa2_pattern->in_tunnel) {
32554cc5cf4aSJun Yang 		DPAA2_PMD_ERR("Tunnel-AH distribution not support");
32564cc5cf4aSJun Yang 		return -ENOTSUP;
32574cc5cf4aSJun Yang 	}
32584cc5cf4aSJun Yang 
32594cc5cf4aSJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow,
32604cc5cf4aSJun Yang 			FAF_IPSEC_AH_FRAM, DPAA2_FLOW_QOS_TYPE,
32614cc5cf4aSJun Yang 			group, &local_cfg);
32624cc5cf4aSJun Yang 	if (ret)
32634cc5cf4aSJun Yang 		return ret;
32644cc5cf4aSJun Yang 
32654cc5cf4aSJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow,
32664cc5cf4aSJun Yang 			FAF_IPSEC_AH_FRAM, DPAA2_FLOW_FS_TYPE,
32674cc5cf4aSJun Yang 			group, &local_cfg);
32684cc5cf4aSJun Yang 	if (ret)
32694cc5cf4aSJun Yang 		return ret;
32704cc5cf4aSJun Yang 
32714cc5cf4aSJun Yang 	if (!spec) {
32724cc5cf4aSJun Yang 		(*device_configured) |= local_cfg;
32734cc5cf4aSJun Yang 		return 0;
32744cc5cf4aSJun Yang 	}
32754cc5cf4aSJun Yang 
32764cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
32774cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_AH);
32784cc5cf4aSJun Yang 	if (ret) {
32794cc5cf4aSJun Yang 		DPAA2_PMD_WARN("Extract field(s) of AH not support.");
32804cc5cf4aSJun Yang 
32814cc5cf4aSJun Yang 		return ret;
32824cc5cf4aSJun Yang 	}
32834cc5cf4aSJun Yang 
32844cc5cf4aSJun Yang 	if (mask->spi) {
32854cc5cf4aSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_AH,
32864cc5cf4aSJun Yang 			NH_FLD_IPSEC_AH_SPI, &spec->spi,
32874cc5cf4aSJun Yang 			&mask->spi, sizeof(rte_be32_t),
32884cc5cf4aSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
32894cc5cf4aSJun Yang 		if (ret)
32904cc5cf4aSJun Yang 			return ret;
32914cc5cf4aSJun Yang 
32924cc5cf4aSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_IPSEC_AH,
32934cc5cf4aSJun Yang 			NH_FLD_IPSEC_AH_SPI, &spec->spi,
32944cc5cf4aSJun Yang 			&mask->spi, sizeof(rte_be32_t),
32954cc5cf4aSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
32964cc5cf4aSJun Yang 		if (ret)
32974cc5cf4aSJun Yang 			return ret;
32984cc5cf4aSJun Yang 	}
32994cc5cf4aSJun Yang 
33004cc5cf4aSJun Yang 	if (mask->seq_num) {
33014cc5cf4aSJun Yang 		DPAA2_PMD_ERR("AH seq distribution not support");
33024cc5cf4aSJun Yang 		return -ENOTSUP;
33034cc5cf4aSJun Yang 	}
33044cc5cf4aSJun Yang 
33054cc5cf4aSJun Yang 	(*device_configured) |= local_cfg;
33064cc5cf4aSJun Yang 
33074cc5cf4aSJun Yang 	return 0;
33084cc5cf4aSJun Yang }
33094cc5cf4aSJun Yang 
33104cc5cf4aSJun Yang static int
331156c1817dSJun Yang dpaa2_configure_flow_sctp(struct dpaa2_dev_flow *flow,
3312fe2b986aSSunil Kumar Kori 	struct rte_eth_dev *dev,
3313fe2b986aSSunil Kumar Kori 	const struct rte_flow_attr *attr,
33149ec29343SJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
3315fe2b986aSSunil Kumar Kori 	const struct rte_flow_action actions[] __rte_unused,
33165f176728SJun Yang 	struct rte_flow_error *error __rte_unused,
33175f176728SJun Yang 	int *device_configured)
3318fe2b986aSSunil Kumar Kori {
331956c1817dSJun Yang 	int ret, local_cfg = 0;
3320fe2b986aSSunil Kumar Kori 	uint32_t group;
3321fe2b986aSSunil Kumar Kori 	const struct rte_flow_item_sctp *spec, *mask;
3322fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
33239ec29343SJun Yang 	const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3324fe2b986aSSunil Kumar Kori 
3325fe2b986aSSunil Kumar Kori 	group = attr->group;
3326fe2b986aSSunil Kumar Kori 
3327fe2b986aSSunil Kumar Kori 	/* Parse pattern list to get the matching parameters */
332856c1817dSJun Yang 	spec = pattern->spec;
332956c1817dSJun Yang 	mask = pattern->mask ?
333056c1817dSJun Yang 		pattern->mask : &dpaa2_flow_item_sctp_mask;
3331fe2b986aSSunil Kumar Kori 
33325f176728SJun Yang 	/* Get traffic class index and flow id to be configured */
33335f176728SJun Yang 	flow->tc_id = group;
33345f176728SJun Yang 	flow->tc_index = attr->priority;
3335fe2b986aSSunil Kumar Kori 
33369ec29343SJun Yang 	if (dpaa2_pattern->in_tunnel) {
33379ec29343SJun Yang 		DPAA2_PMD_ERR("Tunnel-SCTP distribution not support");
33389ec29343SJun Yang 		return -ENOTSUP;
33399ec29343SJun Yang 	}
33409ec29343SJun Yang 
3341200a33e4SJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow,
3342200a33e4SJun Yang 			FAF_SCTP_FRAM, DPAA2_FLOW_QOS_TYPE,
334356c1817dSJun Yang 			group, &local_cfg);
334456c1817dSJun Yang 	if (ret)
334556c1817dSJun Yang 		return ret;
33465f176728SJun Yang 
3347200a33e4SJun Yang 	ret = dpaa2_flow_identify_by_faf(priv, flow,
3348200a33e4SJun Yang 			FAF_SCTP_FRAM, DPAA2_FLOW_FS_TYPE,
3349200a33e4SJun Yang 			group, &local_cfg);
3350200a33e4SJun Yang 	if (ret)
3351200a33e4SJun Yang 		return ret;
33525f176728SJun Yang 
3353200a33e4SJun Yang 	if (!spec) {
3354200a33e4SJun Yang 		(*device_configured) |= local_cfg;
33555f176728SJun Yang 		return 0;
33565f176728SJun Yang 	}
33575f176728SJun Yang 
33584cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
33594cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_SCTP);
33604cc5cf4aSJun Yang 	if (ret) {
3361926c1279SJun Yang 		DPAA2_PMD_WARN("Extract field(s) of SCTP not support.");
3362926c1279SJun Yang 
33634cc5cf4aSJun Yang 		return ret;
3364926c1279SJun Yang 	}
3365926c1279SJun Yang 
33665f176728SJun Yang 	if (mask->hdr.src_port) {
336756c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
336856c1817dSJun Yang 			NH_FLD_SCTP_PORT_SRC, &spec->hdr.src_port,
336956c1817dSJun Yang 			&mask->hdr.src_port, sizeof(rte_be16_t),
337056c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
337156c1817dSJun Yang 		if (ret)
337256c1817dSJun Yang 			return ret;
33735f176728SJun Yang 
337456c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
337556c1817dSJun Yang 			NH_FLD_SCTP_PORT_SRC, &spec->hdr.src_port,
337656c1817dSJun Yang 			&mask->hdr.src_port, sizeof(rte_be16_t),
337756c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
337856c1817dSJun Yang 		if (ret)
337956c1817dSJun Yang 			return ret;
33805f176728SJun Yang 	}
33815f176728SJun Yang 
33825f176728SJun Yang 	if (mask->hdr.dst_port) {
338356c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
338456c1817dSJun Yang 			NH_FLD_SCTP_PORT_DST, &spec->hdr.dst_port,
338556c1817dSJun Yang 			&mask->hdr.dst_port, sizeof(rte_be16_t),
338656c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
338756c1817dSJun Yang 		if (ret)
338856c1817dSJun Yang 			return ret;
33895f176728SJun Yang 
339056c1817dSJun Yang 		ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_SCTP,
339156c1817dSJun Yang 			NH_FLD_SCTP_PORT_DST, &spec->hdr.dst_port,
339256c1817dSJun Yang 			&mask->hdr.dst_port, sizeof(rte_be16_t),
339356c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
339456c1817dSJun Yang 		if (ret)
339556c1817dSJun Yang 			return ret;
33965f176728SJun Yang 	}
33975f176728SJun Yang 
33985f176728SJun Yang 	(*device_configured) |= local_cfg;
33995f176728SJun Yang 
34005f176728SJun Yang 	return 0;
3401fe2b986aSSunil Kumar Kori }
3402fe2b986aSSunil Kumar Kori 
3403fe2b986aSSunil Kumar Kori static int
340456c1817dSJun Yang dpaa2_configure_flow_gre(struct dpaa2_dev_flow *flow,
3405fe2b986aSSunil Kumar Kori 	struct rte_eth_dev *dev,
3406fe2b986aSSunil Kumar Kori 	const struct rte_flow_attr *attr,
34079ec29343SJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
3408fe2b986aSSunil Kumar Kori 	const struct rte_flow_action actions[] __rte_unused,
34095f176728SJun Yang 	struct rte_flow_error *error __rte_unused,
34105f176728SJun Yang 	int *device_configured)
3411fe2b986aSSunil Kumar Kori {
341256c1817dSJun Yang 	int ret, local_cfg = 0;
3413fe2b986aSSunil Kumar Kori 	uint32_t group;
3414fe2b986aSSunil Kumar Kori 	const struct rte_flow_item_gre *spec, *mask;
3415fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
34169ec29343SJun Yang 	const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
3417fe2b986aSSunil Kumar Kori 
3418fe2b986aSSunil Kumar Kori 	group = attr->group;
3419fe2b986aSSunil Kumar Kori 
3420fe2b986aSSunil Kumar Kori 	/* Parse pattern list to get the matching parameters */
342156c1817dSJun Yang 	spec = pattern->spec;
342256c1817dSJun Yang 	mask = pattern->mask ?
342356c1817dSJun Yang 		pattern->mask : &dpaa2_flow_item_gre_mask;
3424fe2b986aSSunil Kumar Kori 
34255f176728SJun Yang 	/* Get traffic class index and flow id to be configured */
34265f176728SJun Yang 	flow->tc_id = group;
34275f176728SJun Yang 	flow->tc_index = attr->priority;
34285f176728SJun Yang 
34299ec29343SJun Yang 	if (dpaa2_pattern->in_tunnel) {
34309ec29343SJun Yang 		DPAA2_PMD_ERR("Tunnel-GRE distribution not support");
34319ec29343SJun Yang 		return -ENOTSUP;
34329ec29343SJun Yang 	}
34339ec29343SJun Yang 
34345f176728SJun Yang 	if (!spec) {
3435200a33e4SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
3436200a33e4SJun Yang 				FAF_GRE_FRAM, DPAA2_FLOW_QOS_TYPE,
3437200a33e4SJun Yang 				group, &local_cfg);
3438200a33e4SJun Yang 		if (ret)
3439200a33e4SJun Yang 			return ret;
34405f176728SJun Yang 
3441200a33e4SJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
3442200a33e4SJun Yang 				FAF_GRE_FRAM, DPAA2_FLOW_FS_TYPE,
344356c1817dSJun Yang 				group, &local_cfg);
344456c1817dSJun Yang 		if (ret)
344556c1817dSJun Yang 			return ret;
34465f176728SJun Yang 
34475f176728SJun Yang 		(*device_configured) |= local_cfg;
34485f176728SJun Yang 		return 0;
34495f176728SJun Yang 	}
34505f176728SJun Yang 
34514cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
34524cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_GRE);
34534cc5cf4aSJun Yang 	if (ret) {
3454926c1279SJun Yang 		DPAA2_PMD_WARN("Extract field(s) of GRE not support.");
3455926c1279SJun Yang 
34564cc5cf4aSJun Yang 		return ret;
3457926c1279SJun Yang 	}
3458926c1279SJun Yang 
34595f176728SJun Yang 	if (!mask->protocol)
34605f176728SJun Yang 		return 0;
34615f176728SJun Yang 
346256c1817dSJun Yang 	ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GRE,
346356c1817dSJun Yang 			NH_FLD_GRE_TYPE, &spec->protocol,
346456c1817dSJun Yang 			&mask->protocol, sizeof(rte_be16_t),
346556c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
346656c1817dSJun Yang 	if (ret)
346756c1817dSJun Yang 		return ret;
3468fe2b986aSSunil Kumar Kori 
346956c1817dSJun Yang 	ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GRE,
347056c1817dSJun Yang 			NH_FLD_GRE_TYPE, &spec->protocol,
347156c1817dSJun Yang 			&mask->protocol, sizeof(rte_be16_t),
347256c1817dSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
347356c1817dSJun Yang 	if (ret)
347456c1817dSJun Yang 		return ret;
34755f176728SJun Yang 
34765f176728SJun Yang 	(*device_configured) |= local_cfg;
34775f176728SJun Yang 
34785f176728SJun Yang 	return 0;
34795f176728SJun Yang }
34805f176728SJun Yang 
34813f881f8dSNipun Gupta static int
348239c8044fSJun Yang dpaa2_configure_flow_vxlan(struct dpaa2_dev_flow *flow,
348339c8044fSJun Yang 	struct rte_eth_dev *dev,
348439c8044fSJun Yang 	const struct rte_flow_attr *attr,
34859ec29343SJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
348639c8044fSJun Yang 	const struct rte_flow_action actions[] __rte_unused,
348739c8044fSJun Yang 	struct rte_flow_error *error __rte_unused,
348839c8044fSJun Yang 	int *device_configured)
348939c8044fSJun Yang {
349039c8044fSJun Yang 	int ret, local_cfg = 0;
349139c8044fSJun Yang 	uint32_t group;
349239c8044fSJun Yang 	const struct rte_flow_item_vxlan *spec, *mask;
349339c8044fSJun Yang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
34949ec29343SJun Yang 	const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
349539c8044fSJun Yang 
349639c8044fSJun Yang 	group = attr->group;
349739c8044fSJun Yang 
349839c8044fSJun Yang 	/* Parse pattern list to get the matching parameters */
349939c8044fSJun Yang 	spec = pattern->spec;
350039c8044fSJun Yang 	mask = pattern->mask ?
350139c8044fSJun Yang 		pattern->mask : &dpaa2_flow_item_vxlan_mask;
350239c8044fSJun Yang 
350339c8044fSJun Yang 	/* Get traffic class index and flow id to be configured */
350439c8044fSJun Yang 	flow->tc_id = group;
350539c8044fSJun Yang 	flow->tc_index = attr->priority;
350639c8044fSJun Yang 
35079ec29343SJun Yang 	if (dpaa2_pattern->in_tunnel) {
35089ec29343SJun Yang 		DPAA2_PMD_ERR("Tunnel-VXLAN distribution not support");
35099ec29343SJun Yang 		return -ENOTSUP;
35109ec29343SJun Yang 	}
35119ec29343SJun Yang 
351239c8044fSJun Yang 	if (!spec) {
351339c8044fSJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
351439c8044fSJun Yang 				FAF_VXLAN_FRAM, DPAA2_FLOW_QOS_TYPE,
351539c8044fSJun Yang 				group, &local_cfg);
351639c8044fSJun Yang 		if (ret)
351739c8044fSJun Yang 			return ret;
351839c8044fSJun Yang 
351939c8044fSJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
352039c8044fSJun Yang 				FAF_VXLAN_FRAM, DPAA2_FLOW_FS_TYPE,
352139c8044fSJun Yang 				group, &local_cfg);
352239c8044fSJun Yang 		if (ret)
352339c8044fSJun Yang 			return ret;
352439c8044fSJun Yang 
352539c8044fSJun Yang 		(*device_configured) |= local_cfg;
352639c8044fSJun Yang 		return 0;
352739c8044fSJun Yang 	}
352839c8044fSJun Yang 
35294cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
35304cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_VXLAN);
35314cc5cf4aSJun Yang 	if (ret) {
353239c8044fSJun Yang 		DPAA2_PMD_WARN("Extract field(s) of VXLAN not support.");
353339c8044fSJun Yang 
35344cc5cf4aSJun Yang 		return ret;
353539c8044fSJun Yang 	}
353639c8044fSJun Yang 
353739c8044fSJun Yang 	if (mask->flags) {
353839c8044fSJun Yang 		if (spec->flags != VXLAN_HF_VNI) {
353939c8044fSJun Yang 			DPAA2_PMD_ERR("vxlan flag(0x%02x) must be 0x%02x.",
354039c8044fSJun Yang 				spec->flags, VXLAN_HF_VNI);
354139c8044fSJun Yang 			return -EINVAL;
354239c8044fSJun Yang 		}
354339c8044fSJun Yang 		if (mask->flags != 0xff) {
354439c8044fSJun Yang 			DPAA2_PMD_ERR("Not support to extract vxlan flag.");
354539c8044fSJun Yang 			return -EINVAL;
354639c8044fSJun Yang 		}
354739c8044fSJun Yang 	}
354839c8044fSJun Yang 
354939c8044fSJun Yang 	if (mask->vni[0] || mask->vni[1] || mask->vni[2]) {
355039c8044fSJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
355139c8044fSJun Yang 			DPAA2_VXLAN_VNI_OFFSET,
355239c8044fSJun Yang 			sizeof(mask->vni), spec->vni,
355339c8044fSJun Yang 			mask->vni,
355439c8044fSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
355539c8044fSJun Yang 		if (ret)
355639c8044fSJun Yang 			return ret;
355739c8044fSJun Yang 
355839c8044fSJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
355939c8044fSJun Yang 			DPAA2_VXLAN_VNI_OFFSET,
356039c8044fSJun Yang 			sizeof(mask->vni), spec->vni,
356139c8044fSJun Yang 			mask->vni,
356239c8044fSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
356339c8044fSJun Yang 		if (ret)
356439c8044fSJun Yang 			return ret;
356539c8044fSJun Yang 	}
356639c8044fSJun Yang 
356739c8044fSJun Yang 	(*device_configured) |= local_cfg;
356839c8044fSJun Yang 
356939c8044fSJun Yang 	return 0;
357039c8044fSJun Yang }
357139c8044fSJun Yang 
357239c8044fSJun Yang static int
3573a8a6b82eSJun Yang dpaa2_configure_flow_ecpri(struct dpaa2_dev_flow *flow,
3574a8a6b82eSJun Yang 	struct rte_eth_dev *dev,
3575a8a6b82eSJun Yang 	const struct rte_flow_attr *attr,
3576a8a6b82eSJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
3577a8a6b82eSJun Yang 	const struct rte_flow_action actions[] __rte_unused,
3578a8a6b82eSJun Yang 	struct rte_flow_error *error __rte_unused,
3579a8a6b82eSJun Yang 	int *device_configured)
3580a8a6b82eSJun Yang {
3581a8a6b82eSJun Yang 	int ret, local_cfg = 0;
3582a8a6b82eSJun Yang 	uint32_t group;
3583a8a6b82eSJun Yang 	const struct rte_flow_item_ecpri *spec, *mask;
3584a8a6b82eSJun Yang 	struct rte_flow_item_ecpri local_mask;
3585a8a6b82eSJun Yang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
3586a8a6b82eSJun Yang 	const struct rte_flow_item *pattern =
3587a8a6b82eSJun Yang 		&dpaa2_pattern->generic_item;
3588a8a6b82eSJun Yang 	uint8_t extract_nb = 0, i;
3589a8a6b82eSJun Yang 	uint64_t rule_data[DPAA2_ECPRI_MAX_EXTRACT_NB];
3590a8a6b82eSJun Yang 	uint64_t mask_data[DPAA2_ECPRI_MAX_EXTRACT_NB];
3591a8a6b82eSJun Yang 	uint8_t extract_size[DPAA2_ECPRI_MAX_EXTRACT_NB];
3592a8a6b82eSJun Yang 	uint8_t extract_off[DPAA2_ECPRI_MAX_EXTRACT_NB];
3593a8a6b82eSJun Yang 
3594a8a6b82eSJun Yang 	group = attr->group;
3595a8a6b82eSJun Yang 
3596a8a6b82eSJun Yang 	/* Parse pattern list to get the matching parameters */
3597a8a6b82eSJun Yang 	spec = pattern->spec;
3598a8a6b82eSJun Yang 	if (pattern->mask) {
3599a8a6b82eSJun Yang 		memcpy(&local_mask, pattern->mask,
3600a8a6b82eSJun Yang 			sizeof(struct rte_flow_item_ecpri));
3601a8a6b82eSJun Yang 		local_mask.hdr.common.u32 =
3602a8a6b82eSJun Yang 			rte_be_to_cpu_32(local_mask.hdr.common.u32);
3603a8a6b82eSJun Yang 		mask = &local_mask;
3604a8a6b82eSJun Yang 	} else {
3605a8a6b82eSJun Yang 		mask = &dpaa2_flow_item_ecpri_mask;
3606a8a6b82eSJun Yang 	}
3607a8a6b82eSJun Yang 
3608a8a6b82eSJun Yang 	/* Get traffic class index and flow id to be configured */
3609a8a6b82eSJun Yang 	flow->tc_id = group;
3610a8a6b82eSJun Yang 	flow->tc_index = attr->priority;
3611a8a6b82eSJun Yang 
3612a8a6b82eSJun Yang 	if (dpaa2_pattern->in_tunnel) {
3613a8a6b82eSJun Yang 		DPAA2_PMD_ERR("Tunnel-ECPRI distribution not support");
3614a8a6b82eSJun Yang 		return -ENOTSUP;
3615a8a6b82eSJun Yang 	}
3616a8a6b82eSJun Yang 
3617a8a6b82eSJun Yang 	if (!spec) {
3618a8a6b82eSJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
3619a8a6b82eSJun Yang 			FAFE_ECPRI_FRAM, DPAA2_FLOW_QOS_TYPE,
3620a8a6b82eSJun Yang 			group, &local_cfg);
3621a8a6b82eSJun Yang 		if (ret)
3622a8a6b82eSJun Yang 			return ret;
3623a8a6b82eSJun Yang 
3624a8a6b82eSJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
3625a8a6b82eSJun Yang 			FAFE_ECPRI_FRAM, DPAA2_FLOW_FS_TYPE,
3626a8a6b82eSJun Yang 			group, &local_cfg);
3627a8a6b82eSJun Yang 		if (ret)
3628a8a6b82eSJun Yang 			return ret;
3629a8a6b82eSJun Yang 
3630a8a6b82eSJun Yang 		(*device_configured) |= local_cfg;
3631a8a6b82eSJun Yang 		return 0;
3632a8a6b82eSJun Yang 	}
3633a8a6b82eSJun Yang 
36344cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
36354cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_ECPRI);
36364cc5cf4aSJun Yang 	if (ret) {
3637a8a6b82eSJun Yang 		DPAA2_PMD_WARN("Extract field(s) of ECPRI not support.");
3638a8a6b82eSJun Yang 
36394cc5cf4aSJun Yang 		return ret;
3640a8a6b82eSJun Yang 	}
3641a8a6b82eSJun Yang 
3642a8a6b82eSJun Yang 	if (mask->hdr.common.type != 0xff) {
3643a8a6b82eSJun Yang 		DPAA2_PMD_WARN("ECPRI header type not specified.");
3644a8a6b82eSJun Yang 
36454cc5cf4aSJun Yang 		return -EINVAL;
3646a8a6b82eSJun Yang 	}
3647a8a6b82eSJun Yang 
3648a8a6b82eSJun Yang 	if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_IQ_DATA) {
3649a8a6b82eSJun Yang 		rule_data[extract_nb] = ECPRI_FAFE_TYPE_0;
3650a8a6b82eSJun Yang 		mask_data[extract_nb] = 0xff;
3651a8a6b82eSJun Yang 		extract_size[extract_nb] = sizeof(uint8_t);
3652a8a6b82eSJun Yang 		extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3653a8a6b82eSJun Yang 		extract_nb++;
3654a8a6b82eSJun Yang 
3655a8a6b82eSJun Yang 		if (mask->hdr.type0.pc_id) {
3656a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type0.pc_id;
3657a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type0.pc_id;
3658a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(rte_be16_t);
3659a8a6b82eSJun Yang 			extract_off[extract_nb] =
3660a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3661a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_iq_data, pc_id);
3662a8a6b82eSJun Yang 			extract_nb++;
3663a8a6b82eSJun Yang 		}
3664a8a6b82eSJun Yang 		if (mask->hdr.type0.seq_id) {
3665a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type0.seq_id;
3666a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type0.seq_id;
3667a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(rte_be16_t);
3668a8a6b82eSJun Yang 			extract_off[extract_nb] =
3669a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3670a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_iq_data, seq_id);
3671a8a6b82eSJun Yang 			extract_nb++;
3672a8a6b82eSJun Yang 		}
3673a8a6b82eSJun Yang 	} else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_BIT_SEQ) {
3674a8a6b82eSJun Yang 		rule_data[extract_nb] = ECPRI_FAFE_TYPE_1;
3675a8a6b82eSJun Yang 		mask_data[extract_nb] = 0xff;
3676a8a6b82eSJun Yang 		extract_size[extract_nb] = sizeof(uint8_t);
3677a8a6b82eSJun Yang 		extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3678a8a6b82eSJun Yang 		extract_nb++;
3679a8a6b82eSJun Yang 
3680a8a6b82eSJun Yang 		if (mask->hdr.type1.pc_id) {
3681a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type1.pc_id;
3682a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type1.pc_id;
3683a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(rte_be16_t);
3684a8a6b82eSJun Yang 			extract_off[extract_nb] =
3685a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3686a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_bit_seq, pc_id);
3687a8a6b82eSJun Yang 			extract_nb++;
3688a8a6b82eSJun Yang 		}
3689a8a6b82eSJun Yang 		if (mask->hdr.type1.seq_id) {
3690a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type1.seq_id;
3691a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type1.seq_id;
3692a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(rte_be16_t);
3693a8a6b82eSJun Yang 			extract_off[extract_nb] =
3694a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3695a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_bit_seq, seq_id);
3696a8a6b82eSJun Yang 			extract_nb++;
3697a8a6b82eSJun Yang 		}
3698a8a6b82eSJun Yang 	} else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RTC_CTRL) {
3699a8a6b82eSJun Yang 		rule_data[extract_nb] = ECPRI_FAFE_TYPE_2;
3700a8a6b82eSJun Yang 		mask_data[extract_nb] = 0xff;
3701a8a6b82eSJun Yang 		extract_size[extract_nb] = sizeof(uint8_t);
3702a8a6b82eSJun Yang 		extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3703a8a6b82eSJun Yang 		extract_nb++;
3704a8a6b82eSJun Yang 
3705a8a6b82eSJun Yang 		if (mask->hdr.type2.rtc_id) {
3706a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type2.rtc_id;
3707a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type2.rtc_id;
3708a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(rte_be16_t);
3709a8a6b82eSJun Yang 			extract_off[extract_nb] =
3710a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3711a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_rtc_ctrl, rtc_id);
3712a8a6b82eSJun Yang 			extract_nb++;
3713a8a6b82eSJun Yang 		}
3714a8a6b82eSJun Yang 		if (mask->hdr.type2.seq_id) {
3715a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type2.seq_id;
3716a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type2.seq_id;
3717a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(rte_be16_t);
3718a8a6b82eSJun Yang 			extract_off[extract_nb] =
3719a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3720a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_rtc_ctrl, seq_id);
3721a8a6b82eSJun Yang 			extract_nb++;
3722a8a6b82eSJun Yang 		}
3723a8a6b82eSJun Yang 	} else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_GEN_DATA) {
3724a8a6b82eSJun Yang 		rule_data[extract_nb] = ECPRI_FAFE_TYPE_3;
3725a8a6b82eSJun Yang 		mask_data[extract_nb] = 0xff;
3726a8a6b82eSJun Yang 		extract_size[extract_nb] = sizeof(uint8_t);
3727a8a6b82eSJun Yang 		extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3728a8a6b82eSJun Yang 		extract_nb++;
3729a8a6b82eSJun Yang 
3730a8a6b82eSJun Yang 		if (mask->hdr.type3.pc_id || mask->hdr.type3.seq_id)
3731a8a6b82eSJun Yang 			DPAA2_PMD_WARN("Extract type3 msg not support.");
3732a8a6b82eSJun Yang 	} else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RM_ACC) {
3733a8a6b82eSJun Yang 		rule_data[extract_nb] = ECPRI_FAFE_TYPE_4;
3734a8a6b82eSJun Yang 		mask_data[extract_nb] = 0xff;
3735a8a6b82eSJun Yang 		extract_size[extract_nb] = sizeof(uint8_t);
3736a8a6b82eSJun Yang 		extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3737a8a6b82eSJun Yang 		extract_nb++;
3738a8a6b82eSJun Yang 
3739a8a6b82eSJun Yang 		if (mask->hdr.type4.rma_id) {
3740a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type4.rma_id;
3741a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type4.rma_id;
3742a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(uint8_t);
3743a8a6b82eSJun Yang 			extract_off[extract_nb] =
3744a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET + 0;
3745a8a6b82eSJun Yang 				/** Compiler not support to take address
3746a8a6b82eSJun Yang 				 * of bit-field
3747a8a6b82eSJun Yang 				 * offsetof(struct rte_ecpri_msg_rm_access,
3748a8a6b82eSJun Yang 				 * rma_id);
3749a8a6b82eSJun Yang 				 */
3750a8a6b82eSJun Yang 			extract_nb++;
3751a8a6b82eSJun Yang 		}
3752a8a6b82eSJun Yang 		if (mask->hdr.type4.ele_id) {
3753a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type4.ele_id;
3754a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type4.ele_id;
3755a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(rte_be16_t);
3756a8a6b82eSJun Yang 			extract_off[extract_nb] =
3757a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET + 2;
3758a8a6b82eSJun Yang 				/** Compiler not support to take address
3759a8a6b82eSJun Yang 				 * of bit-field
3760a8a6b82eSJun Yang 				 * offsetof(struct rte_ecpri_msg_rm_access,
3761a8a6b82eSJun Yang 				 * ele_id);
3762a8a6b82eSJun Yang 				 */
3763a8a6b82eSJun Yang 			extract_nb++;
3764a8a6b82eSJun Yang 		}
3765a8a6b82eSJun Yang 	} else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_DLY_MSR) {
3766a8a6b82eSJun Yang 		rule_data[extract_nb] = ECPRI_FAFE_TYPE_5;
3767a8a6b82eSJun Yang 		mask_data[extract_nb] = 0xff;
3768a8a6b82eSJun Yang 		extract_size[extract_nb] = sizeof(uint8_t);
3769a8a6b82eSJun Yang 		extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3770a8a6b82eSJun Yang 		extract_nb++;
3771a8a6b82eSJun Yang 
3772a8a6b82eSJun Yang 		if (mask->hdr.type5.msr_id) {
3773a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type5.msr_id;
3774a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type5.msr_id;
3775a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(uint8_t);
3776a8a6b82eSJun Yang 			extract_off[extract_nb] =
3777a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3778a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_delay_measure,
3779a8a6b82eSJun Yang 					msr_id);
3780a8a6b82eSJun Yang 			extract_nb++;
3781a8a6b82eSJun Yang 		}
3782a8a6b82eSJun Yang 		if (mask->hdr.type5.act_type) {
3783a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type5.act_type;
3784a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type5.act_type;
3785a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(uint8_t);
3786a8a6b82eSJun Yang 			extract_off[extract_nb] =
3787a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3788a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_delay_measure,
3789a8a6b82eSJun Yang 					act_type);
3790a8a6b82eSJun Yang 			extract_nb++;
3791a8a6b82eSJun Yang 		}
3792a8a6b82eSJun Yang 	} else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_RMT_RST) {
3793a8a6b82eSJun Yang 		rule_data[extract_nb] = ECPRI_FAFE_TYPE_6;
3794a8a6b82eSJun Yang 		mask_data[extract_nb] = 0xff;
3795a8a6b82eSJun Yang 		extract_size[extract_nb] = sizeof(uint8_t);
3796a8a6b82eSJun Yang 		extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3797a8a6b82eSJun Yang 		extract_nb++;
3798a8a6b82eSJun Yang 
3799a8a6b82eSJun Yang 		if (mask->hdr.type6.rst_id) {
3800a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type6.rst_id;
3801a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type6.rst_id;
3802a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(rte_be16_t);
3803a8a6b82eSJun Yang 			extract_off[extract_nb] =
3804a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3805a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_remote_reset,
3806a8a6b82eSJun Yang 					rst_id);
3807a8a6b82eSJun Yang 			extract_nb++;
3808a8a6b82eSJun Yang 		}
3809a8a6b82eSJun Yang 		if (mask->hdr.type6.rst_op) {
3810a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type6.rst_op;
3811a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type6.rst_op;
3812a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(uint8_t);
3813a8a6b82eSJun Yang 			extract_off[extract_nb] =
3814a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3815a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_remote_reset,
3816a8a6b82eSJun Yang 					rst_op);
3817a8a6b82eSJun Yang 			extract_nb++;
3818a8a6b82eSJun Yang 		}
3819a8a6b82eSJun Yang 	} else if (spec->hdr.common.type == RTE_ECPRI_MSG_TYPE_EVT_IND) {
3820a8a6b82eSJun Yang 		rule_data[extract_nb] = ECPRI_FAFE_TYPE_7;
3821a8a6b82eSJun Yang 		mask_data[extract_nb] = 0xff;
3822a8a6b82eSJun Yang 		extract_size[extract_nb] = sizeof(uint8_t);
3823a8a6b82eSJun Yang 		extract_off[extract_nb] = DPAA2_FAFE_PSR_OFFSET;
3824a8a6b82eSJun Yang 		extract_nb++;
3825a8a6b82eSJun Yang 
3826a8a6b82eSJun Yang 		if (mask->hdr.type7.evt_id) {
3827a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type7.evt_id;
3828a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type7.evt_id;
3829a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(uint8_t);
3830a8a6b82eSJun Yang 			extract_off[extract_nb] =
3831a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3832a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_event_ind,
3833a8a6b82eSJun Yang 					evt_id);
3834a8a6b82eSJun Yang 			extract_nb++;
3835a8a6b82eSJun Yang 		}
3836a8a6b82eSJun Yang 		if (mask->hdr.type7.evt_type) {
3837a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type7.evt_type;
3838a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type7.evt_type;
3839a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(uint8_t);
3840a8a6b82eSJun Yang 			extract_off[extract_nb] =
3841a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3842a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_event_ind,
3843a8a6b82eSJun Yang 					evt_type);
3844a8a6b82eSJun Yang 			extract_nb++;
3845a8a6b82eSJun Yang 		}
3846a8a6b82eSJun Yang 		if (mask->hdr.type7.seq) {
3847a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type7.seq;
3848a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type7.seq;
3849a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(uint8_t);
3850a8a6b82eSJun Yang 			extract_off[extract_nb] =
3851a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3852a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_event_ind,
3853a8a6b82eSJun Yang 					seq);
3854a8a6b82eSJun Yang 			extract_nb++;
3855a8a6b82eSJun Yang 		}
3856a8a6b82eSJun Yang 		if (mask->hdr.type7.number) {
3857a8a6b82eSJun Yang 			rule_data[extract_nb] = spec->hdr.type7.number;
3858a8a6b82eSJun Yang 			mask_data[extract_nb] = mask->hdr.type7.number;
3859a8a6b82eSJun Yang 			extract_size[extract_nb] = sizeof(uint8_t);
3860a8a6b82eSJun Yang 			extract_off[extract_nb] =
3861a8a6b82eSJun Yang 				DPAA2_ECPRI_MSG_OFFSET +
3862a8a6b82eSJun Yang 				offsetof(struct rte_ecpri_msg_event_ind,
3863a8a6b82eSJun Yang 					number);
3864a8a6b82eSJun Yang 			extract_nb++;
3865a8a6b82eSJun Yang 		}
3866a8a6b82eSJun Yang 	} else {
3867a8a6b82eSJun Yang 		DPAA2_PMD_ERR("Invalid ecpri header type(%d)",
3868a8a6b82eSJun Yang 				spec->hdr.common.type);
3869a8a6b82eSJun Yang 		return -EINVAL;
3870a8a6b82eSJun Yang 	}
3871a8a6b82eSJun Yang 
3872a8a6b82eSJun Yang 	for (i = 0; i < extract_nb; i++) {
3873a8a6b82eSJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
3874a8a6b82eSJun Yang 			extract_off[i],
3875a8a6b82eSJun Yang 			extract_size[i], &rule_data[i], &mask_data[i],
3876a8a6b82eSJun Yang 			priv, group,
3877a8a6b82eSJun Yang 			device_configured,
3878a8a6b82eSJun Yang 			DPAA2_FLOW_QOS_TYPE);
3879a8a6b82eSJun Yang 		if (ret)
3880a8a6b82eSJun Yang 			return ret;
3881a8a6b82eSJun Yang 
3882a8a6b82eSJun Yang 		ret = dpaa2_flow_add_pr_extract_rule(flow,
3883a8a6b82eSJun Yang 			extract_off[i],
3884a8a6b82eSJun Yang 			extract_size[i], &rule_data[i], &mask_data[i],
3885a8a6b82eSJun Yang 			priv, group,
3886a8a6b82eSJun Yang 			device_configured,
3887a8a6b82eSJun Yang 			DPAA2_FLOW_FS_TYPE);
3888a8a6b82eSJun Yang 		if (ret)
3889a8a6b82eSJun Yang 			return ret;
3890a8a6b82eSJun Yang 	}
3891a8a6b82eSJun Yang 
3892a8a6b82eSJun Yang 	(*device_configured) |= local_cfg;
3893a8a6b82eSJun Yang 
3894a8a6b82eSJun Yang 	return 0;
3895a8a6b82eSJun Yang }
3896a8a6b82eSJun Yang 
3897a8a6b82eSJun Yang static int
3898146c745eSJun Yang dpaa2_configure_flow_gtp(struct dpaa2_dev_flow *flow,
3899146c745eSJun Yang 	struct rte_eth_dev *dev,
3900146c745eSJun Yang 	const struct rte_flow_attr *attr,
3901146c745eSJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
3902146c745eSJun Yang 	const struct rte_flow_action actions[] __rte_unused,
3903146c745eSJun Yang 	struct rte_flow_error *error __rte_unused,
3904146c745eSJun Yang 	int *device_configured)
3905146c745eSJun Yang {
3906146c745eSJun Yang 	int ret, local_cfg = 0;
3907146c745eSJun Yang 	uint32_t group;
3908146c745eSJun Yang 	const struct rte_flow_item_gtp *spec, *mask;
3909146c745eSJun Yang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
3910146c745eSJun Yang 	const struct rte_flow_item *pattern =
3911146c745eSJun Yang 		&dpaa2_pattern->generic_item;
3912146c745eSJun Yang 
3913146c745eSJun Yang 	group = attr->group;
3914146c745eSJun Yang 
3915146c745eSJun Yang 	/* Parse pattern list to get the matching parameters */
3916146c745eSJun Yang 	spec = pattern->spec;
3917146c745eSJun Yang 	mask = pattern->mask ?
3918146c745eSJun Yang 		pattern->mask : &dpaa2_flow_item_gtp_mask;
3919146c745eSJun Yang 
3920146c745eSJun Yang 	/* Get traffic class index and flow id to be configured */
3921146c745eSJun Yang 	flow->tc_id = group;
3922146c745eSJun Yang 	flow->tc_index = attr->priority;
3923146c745eSJun Yang 
3924146c745eSJun Yang 	if (dpaa2_pattern->in_tunnel) {
3925146c745eSJun Yang 		DPAA2_PMD_ERR("Tunnel-GTP distribution not support");
3926146c745eSJun Yang 		return -ENOTSUP;
3927146c745eSJun Yang 	}
3928146c745eSJun Yang 
3929146c745eSJun Yang 	if (!spec) {
3930146c745eSJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
3931146c745eSJun Yang 				FAF_GTP_FRAM, DPAA2_FLOW_QOS_TYPE,
3932146c745eSJun Yang 				group, &local_cfg);
3933146c745eSJun Yang 		if (ret)
3934146c745eSJun Yang 			return ret;
3935146c745eSJun Yang 
3936146c745eSJun Yang 		ret = dpaa2_flow_identify_by_faf(priv, flow,
3937146c745eSJun Yang 				FAF_GTP_FRAM, DPAA2_FLOW_FS_TYPE,
3938146c745eSJun Yang 				group, &local_cfg);
3939146c745eSJun Yang 		if (ret)
3940146c745eSJun Yang 			return ret;
3941146c745eSJun Yang 
3942146c745eSJun Yang 		(*device_configured) |= local_cfg;
3943146c745eSJun Yang 		return 0;
3944146c745eSJun Yang 	}
3945146c745eSJun Yang 
39464cc5cf4aSJun Yang 	ret = dpaa2_flow_extract_support((const uint8_t *)mask,
39474cc5cf4aSJun Yang 		RTE_FLOW_ITEM_TYPE_GTP);
39484cc5cf4aSJun Yang 	if (ret) {
3949146c745eSJun Yang 		DPAA2_PMD_WARN("Extract field(s) of GTP not support.");
3950146c745eSJun Yang 
39514cc5cf4aSJun Yang 		return ret;
3952146c745eSJun Yang 	}
3953146c745eSJun Yang 
3954146c745eSJun Yang 	if (!mask->teid)
3955146c745eSJun Yang 		return 0;
3956146c745eSJun Yang 
3957146c745eSJun Yang 	ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GTP,
3958146c745eSJun Yang 			NH_FLD_GTP_TEID, &spec->teid,
3959146c745eSJun Yang 			&mask->teid, sizeof(rte_be32_t),
3960146c745eSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE);
3961146c745eSJun Yang 	if (ret)
3962146c745eSJun Yang 		return ret;
3963146c745eSJun Yang 
3964146c745eSJun Yang 	ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_GTP,
3965146c745eSJun Yang 			NH_FLD_GTP_TEID, &spec->teid,
3966146c745eSJun Yang 			&mask->teid, sizeof(rte_be32_t),
3967146c745eSJun Yang 			priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE);
3968146c745eSJun Yang 	if (ret)
3969146c745eSJun Yang 		return ret;
3970146c745eSJun Yang 
3971146c745eSJun Yang 	(*device_configured) |= local_cfg;
3972146c745eSJun Yang 
3973146c745eSJun Yang 	return 0;
3974146c745eSJun Yang }
3975146c745eSJun Yang 
3976146c745eSJun Yang static int
397756c1817dSJun Yang dpaa2_configure_flow_raw(struct dpaa2_dev_flow *flow,
39783f881f8dSNipun Gupta 	struct rte_eth_dev *dev,
39793f881f8dSNipun Gupta 	const struct rte_flow_attr *attr,
39809ec29343SJun Yang 	const struct rte_dpaa2_flow_item *dpaa2_pattern,
39813f881f8dSNipun Gupta 	const struct rte_flow_action actions[] __rte_unused,
39823f881f8dSNipun Gupta 	struct rte_flow_error *error __rte_unused,
39833f881f8dSNipun Gupta 	int *device_configured)
39843f881f8dSNipun Gupta {
39853f881f8dSNipun Gupta 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
39863f881f8dSNipun Gupta 	int local_cfg = 0, ret;
39873f881f8dSNipun Gupta 	uint32_t group;
3988e21bff64SJun Yang 	struct dpaa2_key_extract *qos_key_extract;
3989e21bff64SJun Yang 	struct dpaa2_key_extract *tc_key_extract;
39909ec29343SJun Yang 	const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
39919ec29343SJun Yang 	const struct rte_flow_item_raw *spec = pattern->spec;
39929ec29343SJun Yang 	const struct rte_flow_item_raw *mask = pattern->mask;
39933f881f8dSNipun Gupta 
39943f881f8dSNipun Gupta 	/* Need both spec and mask */
39953f881f8dSNipun Gupta 	if (!spec || !mask) {
39963f881f8dSNipun Gupta 		DPAA2_PMD_ERR("spec or mask not present.");
39973f881f8dSNipun Gupta 		return -EINVAL;
39983f881f8dSNipun Gupta 	}
3999e21bff64SJun Yang 
4000e21bff64SJun Yang 	if (spec->relative) {
4001e21bff64SJun Yang 		/* TBD: relative offset support.
4002e21bff64SJun Yang 		 * To support relative offset of previous L3 protocol item,
4003e21bff64SJun Yang 		 * extracts should be expanded to identify if the frame is:
4004e21bff64SJun Yang 		 * vlan or none-vlan.
4005e21bff64SJun Yang 		 *
4006e21bff64SJun Yang 		 * To support relative offset of previous L4 protocol item,
4007e21bff64SJun Yang 		 * extracts should be expanded to identify if the frame is:
4008e21bff64SJun Yang 		 * vlan/IPv4 or vlan/IPv6 or none-vlan/IPv4 or none-vlan/IPv6.
4009e21bff64SJun Yang 		 */
4010e21bff64SJun Yang 		DPAA2_PMD_ERR("relative not supported.");
40113f881f8dSNipun Gupta 		return -EINVAL;
40123f881f8dSNipun Gupta 	}
4013e21bff64SJun Yang 
4014e21bff64SJun Yang 	if (spec->search) {
4015e21bff64SJun Yang 		DPAA2_PMD_ERR("search not supported.");
4016e21bff64SJun Yang 		return -EINVAL;
4017e21bff64SJun Yang 	}
4018e21bff64SJun Yang 
40193f881f8dSNipun Gupta 	/* Spec len and mask len should be same */
40203f881f8dSNipun Gupta 	if (spec->length != mask->length) {
40213f881f8dSNipun Gupta 		DPAA2_PMD_ERR("Spec len and mask len mismatch.");
40223f881f8dSNipun Gupta 		return -EINVAL;
40233f881f8dSNipun Gupta 	}
40243f881f8dSNipun Gupta 
40253f881f8dSNipun Gupta 	/* Get traffic class index and flow id to be configured */
40263f881f8dSNipun Gupta 	group = attr->group;
40273f881f8dSNipun Gupta 	flow->tc_id = group;
40283f881f8dSNipun Gupta 	flow->tc_index = attr->priority;
40293f881f8dSNipun Gupta 
4030e21bff64SJun Yang 	qos_key_extract = &priv->extract.qos_key_extract;
4031e21bff64SJun Yang 	tc_key_extract = &priv->extract.tc_key_extract[group];
4032e21bff64SJun Yang 
4033e21bff64SJun Yang 	ret = dpaa2_flow_extract_add_raw(priv,
4034e21bff64SJun Yang 			spec->offset, spec->length,
4035e21bff64SJun Yang 			DPAA2_FLOW_QOS_TYPE, 0, &local_cfg);
40363f881f8dSNipun Gupta 	if (ret) {
40373f881f8dSNipun Gupta 		DPAA2_PMD_ERR("QoS Extract RAW add failed.");
4038e21bff64SJun Yang 		return -EINVAL;
40393f881f8dSNipun Gupta 	}
40403f881f8dSNipun Gupta 
4041e21bff64SJun Yang 	ret = dpaa2_flow_extract_add_raw(priv,
4042e21bff64SJun Yang 			spec->offset, spec->length,
4043e21bff64SJun Yang 			DPAA2_FLOW_FS_TYPE, group, &local_cfg);
40443f881f8dSNipun Gupta 	if (ret) {
4045e21bff64SJun Yang 		DPAA2_PMD_ERR("FS[%d] Extract RAW add failed.",
4046e21bff64SJun Yang 			group);
4047e21bff64SJun Yang 		return -EINVAL;
40483f881f8dSNipun Gupta 	}
40493f881f8dSNipun Gupta 
4050e21bff64SJun Yang 	ret = dpaa2_flow_raw_rule_data_set(flow,
4051e21bff64SJun Yang 			&qos_key_extract->key_profile,
4052e21bff64SJun Yang 			spec->offset, spec->length,
4053e21bff64SJun Yang 			spec->pattern, mask->pattern,
4054e21bff64SJun Yang 			DPAA2_FLOW_QOS_TYPE);
40553f881f8dSNipun Gupta 	if (ret) {
40563f881f8dSNipun Gupta 		DPAA2_PMD_ERR("QoS RAW rule data set failed");
4057e21bff64SJun Yang 		return -EINVAL;
40583f881f8dSNipun Gupta 	}
40593f881f8dSNipun Gupta 
4060e21bff64SJun Yang 	ret = dpaa2_flow_raw_rule_data_set(flow,
4061e21bff64SJun Yang 			&tc_key_extract->key_profile,
4062e21bff64SJun Yang 			spec->offset, spec->length,
4063e21bff64SJun Yang 			spec->pattern, mask->pattern,
4064e21bff64SJun Yang 			DPAA2_FLOW_FS_TYPE);
40653f881f8dSNipun Gupta 	if (ret) {
40663f881f8dSNipun Gupta 		DPAA2_PMD_ERR("FS RAW rule data set failed");
4067e21bff64SJun Yang 		return -EINVAL;
40683f881f8dSNipun Gupta 	}
40693f881f8dSNipun Gupta 
40703f881f8dSNipun Gupta 	(*device_configured) |= local_cfg;
40713f881f8dSNipun Gupta 
40723f881f8dSNipun Gupta 	return 0;
40733f881f8dSNipun Gupta }
40743f881f8dSNipun Gupta 
4075028d1dfdSJun Yang static inline int
407656c1817dSJun Yang dpaa2_flow_verify_attr(struct dpaa2_dev_priv *priv,
40774ce58f8aSJun Yang 	const struct rte_flow_attr *attr)
40784ce58f8aSJun Yang {
407956c1817dSJun Yang 	struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows);
40804ce58f8aSJun Yang 
40814ce58f8aSJun Yang 	while (curr) {
40824ce58f8aSJun Yang 		if (curr->tc_id == attr->group &&
40834ce58f8aSJun Yang 			curr->tc_index == attr->priority) {
408456c1817dSJun Yang 			DPAA2_PMD_ERR("Flow(TC[%d].entry[%d] exists",
40854ce58f8aSJun Yang 				attr->group, attr->priority);
40864ce58f8aSJun Yang 
408756c1817dSJun Yang 			return -EINVAL;
40884ce58f8aSJun Yang 		}
40894ce58f8aSJun Yang 		curr = LIST_NEXT(curr, next);
40904ce58f8aSJun Yang 	}
40914ce58f8aSJun Yang 
40924ce58f8aSJun Yang 	return 0;
40934ce58f8aSJun Yang }
40944ce58f8aSJun Yang 
4095028d1dfdSJun Yang static inline struct rte_eth_dev *
4096028d1dfdSJun Yang dpaa2_flow_redirect_dev(struct dpaa2_dev_priv *priv,
4097028d1dfdSJun Yang 	const struct rte_flow_action *action)
4098028d1dfdSJun Yang {
4099028d1dfdSJun Yang 	const struct rte_flow_action_port_id *port_id;
410056c1817dSJun Yang 	const struct rte_flow_action_ethdev *ethdev;
4101028d1dfdSJun Yang 	int idx = -1;
4102028d1dfdSJun Yang 	struct rte_eth_dev *dest_dev;
4103028d1dfdSJun Yang 
4104235558feSIvan Malov 	if (action->type == RTE_FLOW_ACTION_TYPE_PORT_ID) {
410556c1817dSJun Yang 		port_id = action->conf;
4106028d1dfdSJun Yang 		if (!port_id->original)
4107028d1dfdSJun Yang 			idx = port_id->id;
4108b1e15294SIvan Malov 	} else if (action->type == RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT) {
410956c1817dSJun Yang 		ethdev = action->conf;
4110b1e15294SIvan Malov 		idx = ethdev->port_id;
4111028d1dfdSJun Yang 	} else {
4112028d1dfdSJun Yang 		return NULL;
4113028d1dfdSJun Yang 	}
4114028d1dfdSJun Yang 
4115028d1dfdSJun Yang 	if (idx >= 0) {
4116028d1dfdSJun Yang 		if (!rte_eth_dev_is_valid_port(idx))
4117028d1dfdSJun Yang 			return NULL;
411872cd5a48SJun Yang 		if (!rte_pmd_dpaa2_dev_is_dpaa2(idx))
411972cd5a48SJun Yang 			return NULL;
4120028d1dfdSJun Yang 		dest_dev = &rte_eth_devices[idx];
4121028d1dfdSJun Yang 	} else {
4122028d1dfdSJun Yang 		dest_dev = priv->eth_dev;
4123028d1dfdSJun Yang 	}
4124028d1dfdSJun Yang 
4125028d1dfdSJun Yang 	return dest_dev;
4126028d1dfdSJun Yang }
4127028d1dfdSJun Yang 
4128bac4a296SJun Yang static inline int
412956c1817dSJun Yang dpaa2_flow_verify_action(struct dpaa2_dev_priv *priv,
4130bac4a296SJun Yang 	const struct rte_flow_attr *attr,
4131bac4a296SJun Yang 	const struct rte_flow_action actions[])
4132bac4a296SJun Yang {
4133bac4a296SJun Yang 	int end_of_list = 0, i, j = 0;
4134bac4a296SJun Yang 	const struct rte_flow_action_queue *dest_queue;
4135bac4a296SJun Yang 	const struct rte_flow_action_rss *rss_conf;
4136bac4a296SJun Yang 	struct dpaa2_queue *rxq;
4137bac4a296SJun Yang 
4138bac4a296SJun Yang 	while (!end_of_list) {
4139bac4a296SJun Yang 		switch (actions[j].type) {
4140bac4a296SJun Yang 		case RTE_FLOW_ACTION_TYPE_QUEUE:
414156c1817dSJun Yang 			dest_queue = actions[j].conf;
4142bac4a296SJun Yang 			rxq = priv->rx_vq[dest_queue->index];
4143bac4a296SJun Yang 			if (attr->group != rxq->tc_index) {
414456c1817dSJun Yang 				DPAA2_PMD_ERR("FSQ(%d.%d) not in TC[%d]",
414556c1817dSJun Yang 					rxq->tc_index, rxq->flow_id,
414656c1817dSJun Yang 					attr->group);
4147bac4a296SJun Yang 
414856c1817dSJun Yang 				return -ENOTSUP;
4149bac4a296SJun Yang 			}
4150bac4a296SJun Yang 			break;
4151b1e15294SIvan Malov 		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
4152028d1dfdSJun Yang 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
4153028d1dfdSJun Yang 			if (!dpaa2_flow_redirect_dev(priv, &actions[j])) {
4154028d1dfdSJun Yang 				DPAA2_PMD_ERR("Invalid port id of action");
4155028d1dfdSJun Yang 				return -ENOTSUP;
4156028d1dfdSJun Yang 			}
4157028d1dfdSJun Yang 			break;
4158bac4a296SJun Yang 		case RTE_FLOW_ACTION_TYPE_RSS:
4159bac4a296SJun Yang 			rss_conf = (const struct rte_flow_action_rss *)
4160bac4a296SJun Yang 					(actions[j].conf);
4161bac4a296SJun Yang 			if (rss_conf->queue_num > priv->dist_queues) {
416256c1817dSJun Yang 				DPAA2_PMD_ERR("RSS number too large");
4163bac4a296SJun Yang 				return -ENOTSUP;
4164bac4a296SJun Yang 			}
4165bac4a296SJun Yang 			for (i = 0; i < (int)rss_conf->queue_num; i++) {
4166bac4a296SJun Yang 				if (rss_conf->queue[i] >= priv->nb_rx_queues) {
416756c1817dSJun Yang 					DPAA2_PMD_ERR("RSS queue not in range");
4168bac4a296SJun Yang 					return -ENOTSUP;
4169bac4a296SJun Yang 				}
4170bac4a296SJun Yang 				rxq = priv->rx_vq[rss_conf->queue[i]];
4171bac4a296SJun Yang 				if (rxq->tc_index != attr->group) {
417256c1817dSJun Yang 					DPAA2_PMD_ERR("RSS queue not in group");
4173bac4a296SJun Yang 					return -ENOTSUP;
4174bac4a296SJun Yang 				}
4175bac4a296SJun Yang 			}
4176bac4a296SJun Yang 
4177bac4a296SJun Yang 			break;
417839c8044fSJun Yang 		case RTE_FLOW_ACTION_TYPE_PF:
417939c8044fSJun Yang 			/* Skip this action, have to add for vxlan */
418039c8044fSJun Yang 			break;
4181bac4a296SJun Yang 		case RTE_FLOW_ACTION_TYPE_END:
4182bac4a296SJun Yang 			end_of_list = 1;
4183bac4a296SJun Yang 			break;
4184bac4a296SJun Yang 		default:
4185bac4a296SJun Yang 			DPAA2_PMD_ERR("Invalid action type");
4186bac4a296SJun Yang 			return -ENOTSUP;
4187bac4a296SJun Yang 		}
4188bac4a296SJun Yang 		j++;
4189bac4a296SJun Yang 	}
4190bac4a296SJun Yang 
4191bac4a296SJun Yang 	return 0;
4192bac4a296SJun Yang }
4193bac4a296SJun Yang 
4194fe2b986aSSunil Kumar Kori static int
419556c1817dSJun Yang dpaa2_configure_flow_fs_action(struct dpaa2_dev_priv *priv,
419656c1817dSJun Yang 	struct dpaa2_dev_flow *flow,
419756c1817dSJun Yang 	const struct rte_flow_action *rte_action)
419856c1817dSJun Yang {
419956c1817dSJun Yang 	struct rte_eth_dev *dest_dev;
420056c1817dSJun Yang 	struct dpaa2_dev_priv *dest_priv;
420156c1817dSJun Yang 	const struct rte_flow_action_queue *dest_queue;
420256c1817dSJun Yang 	struct dpaa2_queue *dest_q;
420356c1817dSJun Yang 
420456c1817dSJun Yang 	memset(&flow->fs_action_cfg, 0,
420556c1817dSJun Yang 		sizeof(struct dpni_fs_action_cfg));
420656c1817dSJun Yang 	flow->action_type = rte_action->type;
420756c1817dSJun Yang 
420856c1817dSJun Yang 	if (flow->action_type == RTE_FLOW_ACTION_TYPE_QUEUE) {
420956c1817dSJun Yang 		dest_queue = rte_action->conf;
421056c1817dSJun Yang 		dest_q = priv->rx_vq[dest_queue->index];
421156c1817dSJun Yang 		flow->fs_action_cfg.flow_id = dest_q->flow_id;
421256c1817dSJun Yang 	} else if (flow->action_type == RTE_FLOW_ACTION_TYPE_PORT_ID ||
421356c1817dSJun Yang 		   flow->action_type == RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT) {
421456c1817dSJun Yang 		dest_dev = dpaa2_flow_redirect_dev(priv, rte_action);
421556c1817dSJun Yang 		if (!dest_dev) {
421656c1817dSJun Yang 			DPAA2_PMD_ERR("Invalid device to redirect");
421756c1817dSJun Yang 			return -EINVAL;
421856c1817dSJun Yang 		}
421956c1817dSJun Yang 
422056c1817dSJun Yang 		dest_priv = dest_dev->data->dev_private;
422156c1817dSJun Yang 		dest_q = dest_priv->tx_vq[0];
422256c1817dSJun Yang 		flow->fs_action_cfg.options =
422356c1817dSJun Yang 			DPNI_FS_OPT_REDIRECT_TO_DPNI_TX;
422456c1817dSJun Yang 		flow->fs_action_cfg.redirect_obj_token =
422556c1817dSJun Yang 			dest_priv->token;
422656c1817dSJun Yang 		flow->fs_action_cfg.flow_id = dest_q->flow_id;
422756c1817dSJun Yang 	}
422856c1817dSJun Yang 
422956c1817dSJun Yang 	return 0;
423056c1817dSJun Yang }
423156c1817dSJun Yang 
423256c1817dSJun Yang static inline uint16_t
423356c1817dSJun Yang dpaa2_flow_entry_size(uint16_t key_max_size)
423456c1817dSJun Yang {
423556c1817dSJun Yang 	if (key_max_size > DPAA2_FLOW_ENTRY_MAX_SIZE) {
423656c1817dSJun Yang 		DPAA2_PMD_ERR("Key size(%d) > max(%d)",
423756c1817dSJun Yang 			key_max_size,
423856c1817dSJun Yang 			DPAA2_FLOW_ENTRY_MAX_SIZE);
423956c1817dSJun Yang 
424056c1817dSJun Yang 		return 0;
424156c1817dSJun Yang 	}
424256c1817dSJun Yang 
424356c1817dSJun Yang 	if (key_max_size > DPAA2_FLOW_ENTRY_MIN_SIZE)
424456c1817dSJun Yang 		return DPAA2_FLOW_ENTRY_MAX_SIZE;
424556c1817dSJun Yang 
424656c1817dSJun Yang 	/* Current MC only support fixed entry size(56)*/
424756c1817dSJun Yang 	return DPAA2_FLOW_ENTRY_MAX_SIZE;
424856c1817dSJun Yang }
424956c1817dSJun Yang 
425056c1817dSJun Yang static inline int
425156c1817dSJun Yang dpaa2_flow_clear_fs_table(struct dpaa2_dev_priv *priv,
425256c1817dSJun Yang 	uint8_t tc_id)
425356c1817dSJun Yang {
425456c1817dSJun Yang 	struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows);
425556c1817dSJun Yang 	int need_clear = 0, ret;
425656c1817dSJun Yang 	struct fsl_mc_io *dpni = priv->hw;
425756c1817dSJun Yang 
425856c1817dSJun Yang 	while (curr) {
425956c1817dSJun Yang 		if (curr->tc_id == tc_id) {
426056c1817dSJun Yang 			need_clear = 1;
426156c1817dSJun Yang 			break;
426256c1817dSJun Yang 		}
426356c1817dSJun Yang 		curr = LIST_NEXT(curr, next);
426456c1817dSJun Yang 	}
426556c1817dSJun Yang 
426656c1817dSJun Yang 	if (need_clear) {
426756c1817dSJun Yang 		ret = dpni_clear_fs_entries(dpni, CMD_PRI_LOW,
426856c1817dSJun Yang 				priv->token, tc_id);
426956c1817dSJun Yang 		if (ret) {
427056c1817dSJun Yang 			DPAA2_PMD_ERR("TC[%d] clear failed", tc_id);
427156c1817dSJun Yang 			return ret;
427256c1817dSJun Yang 		}
427356c1817dSJun Yang 	}
427456c1817dSJun Yang 
427556c1817dSJun Yang 	return 0;
427656c1817dSJun Yang }
427756c1817dSJun Yang 
427856c1817dSJun Yang static int
427956c1817dSJun Yang dpaa2_configure_fs_rss_table(struct dpaa2_dev_priv *priv,
428056c1817dSJun Yang 	uint8_t tc_id, uint16_t dist_size, int rss_dist)
428156c1817dSJun Yang {
428256c1817dSJun Yang 	struct dpaa2_key_extract *tc_extract;
428356c1817dSJun Yang 	uint8_t *key_cfg_buf;
428456c1817dSJun Yang 	uint64_t key_cfg_iova;
428556c1817dSJun Yang 	int ret;
428656c1817dSJun Yang 	struct dpni_rx_dist_cfg tc_cfg;
428756c1817dSJun Yang 	struct fsl_mc_io *dpni = priv->hw;
428856c1817dSJun Yang 	uint16_t entry_size;
428956c1817dSJun Yang 	uint16_t key_max_size;
429056c1817dSJun Yang 
429156c1817dSJun Yang 	ret = dpaa2_flow_clear_fs_table(priv, tc_id);
429256c1817dSJun Yang 	if (ret < 0) {
429356c1817dSJun Yang 		DPAA2_PMD_ERR("TC[%d] clear failed", tc_id);
429456c1817dSJun Yang 		return ret;
429556c1817dSJun Yang 	}
429656c1817dSJun Yang 
429756c1817dSJun Yang 	tc_extract = &priv->extract.tc_key_extract[tc_id];
429856c1817dSJun Yang 	key_cfg_buf = priv->extract.tc_extract_param[tc_id];
429925d0ae62SJun Yang 	key_cfg_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_cfg_buf,
430025d0ae62SJun Yang 		DPAA2_EXTRACT_PARAM_MAX_SIZE);
430125d0ae62SJun Yang 	if (key_cfg_iova == RTE_BAD_IOVA) {
430225d0ae62SJun Yang 		DPAA2_PMD_ERR("%s: No IOMMU map for key cfg(%p)",
430325d0ae62SJun Yang 			__func__, key_cfg_buf);
430425d0ae62SJun Yang 
430525d0ae62SJun Yang 		return -ENOBUFS;
430625d0ae62SJun Yang 	}
430756c1817dSJun Yang 
430856c1817dSJun Yang 	key_max_size = tc_extract->key_profile.key_max_size;
430956c1817dSJun Yang 	entry_size = dpaa2_flow_entry_size(key_max_size);
431056c1817dSJun Yang 
431156c1817dSJun Yang 	dpaa2_flow_fs_extracts_log(priv, tc_id);
431256c1817dSJun Yang 	ret = dpkg_prepare_key_cfg(&tc_extract->dpkg,
431356c1817dSJun Yang 			key_cfg_buf);
431456c1817dSJun Yang 	if (ret < 0) {
431556c1817dSJun Yang 		DPAA2_PMD_ERR("TC[%d] prepare key failed", tc_id);
431656c1817dSJun Yang 		return ret;
431756c1817dSJun Yang 	}
431856c1817dSJun Yang 
431956c1817dSJun Yang 	memset(&tc_cfg, 0, sizeof(struct dpni_rx_dist_cfg));
432056c1817dSJun Yang 	tc_cfg.dist_size = dist_size;
432156c1817dSJun Yang 	tc_cfg.key_cfg_iova = key_cfg_iova;
432256c1817dSJun Yang 	if (rss_dist)
432356c1817dSJun Yang 		tc_cfg.enable = true;
432456c1817dSJun Yang 	else
432556c1817dSJun Yang 		tc_cfg.enable = false;
432656c1817dSJun Yang 	tc_cfg.tc = tc_id;
432756c1817dSJun Yang 	ret = dpni_set_rx_hash_dist(dpni, CMD_PRI_LOW,
432856c1817dSJun Yang 			priv->token, &tc_cfg);
432956c1817dSJun Yang 	if (ret < 0) {
433056c1817dSJun Yang 		if (rss_dist) {
433156c1817dSJun Yang 			DPAA2_PMD_ERR("RSS TC[%d] set failed",
433256c1817dSJun Yang 				tc_id);
433356c1817dSJun Yang 		} else {
433456c1817dSJun Yang 			DPAA2_PMD_ERR("FS TC[%d] hash disable failed",
433556c1817dSJun Yang 				tc_id);
433656c1817dSJun Yang 		}
433756c1817dSJun Yang 
433856c1817dSJun Yang 		return ret;
433956c1817dSJun Yang 	}
434056c1817dSJun Yang 
434156c1817dSJun Yang 	if (rss_dist)
434256c1817dSJun Yang 		return 0;
434356c1817dSJun Yang 
434456c1817dSJun Yang 	tc_cfg.enable = true;
434556c1817dSJun Yang 	tc_cfg.fs_miss_flow_id = dpaa2_flow_miss_flow_id;
434656c1817dSJun Yang 	ret = dpni_set_rx_fs_dist(dpni, CMD_PRI_LOW,
434756c1817dSJun Yang 			priv->token, &tc_cfg);
434856c1817dSJun Yang 	if (ret < 0) {
434956c1817dSJun Yang 		DPAA2_PMD_ERR("TC[%d] FS configured failed", tc_id);
435056c1817dSJun Yang 		return ret;
435156c1817dSJun Yang 	}
435256c1817dSJun Yang 
435356c1817dSJun Yang 	ret = dpaa2_flow_rule_add_all(priv, DPAA2_FLOW_FS_TYPE,
435456c1817dSJun Yang 			entry_size, tc_id);
435556c1817dSJun Yang 	if (ret)
435656c1817dSJun Yang 		return ret;
435756c1817dSJun Yang 
435856c1817dSJun Yang 	return 0;
435956c1817dSJun Yang }
436056c1817dSJun Yang 
436156c1817dSJun Yang static int
436256c1817dSJun Yang dpaa2_configure_qos_table(struct dpaa2_dev_priv *priv,
436356c1817dSJun Yang 	int rss_dist)
436456c1817dSJun Yang {
436556c1817dSJun Yang 	struct dpaa2_key_extract *qos_extract;
436656c1817dSJun Yang 	uint8_t *key_cfg_buf;
436756c1817dSJun Yang 	uint64_t key_cfg_iova;
436856c1817dSJun Yang 	int ret;
436956c1817dSJun Yang 	struct dpni_qos_tbl_cfg qos_cfg;
437056c1817dSJun Yang 	struct fsl_mc_io *dpni = priv->hw;
437156c1817dSJun Yang 	uint16_t entry_size;
437256c1817dSJun Yang 	uint16_t key_max_size;
437356c1817dSJun Yang 
437456c1817dSJun Yang 	if (!rss_dist && priv->num_rx_tc <= 1) {
437556c1817dSJun Yang 		/* QoS table is effecitive for FS multiple TCs or RSS.*/
437656c1817dSJun Yang 		return 0;
437756c1817dSJun Yang 	}
437856c1817dSJun Yang 
437956c1817dSJun Yang 	if (LIST_FIRST(&priv->flows)) {
438056c1817dSJun Yang 		ret = dpni_clear_qos_table(dpni, CMD_PRI_LOW,
438156c1817dSJun Yang 				priv->token);
438256c1817dSJun Yang 		if (ret < 0) {
438356c1817dSJun Yang 			DPAA2_PMD_ERR("QoS table clear failed");
438456c1817dSJun Yang 			return ret;
438556c1817dSJun Yang 		}
438656c1817dSJun Yang 	}
438756c1817dSJun Yang 
438856c1817dSJun Yang 	qos_extract = &priv->extract.qos_key_extract;
438956c1817dSJun Yang 	key_cfg_buf = priv->extract.qos_extract_param;
439025d0ae62SJun Yang 	key_cfg_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_cfg_buf,
439125d0ae62SJun Yang 		DPAA2_EXTRACT_PARAM_MAX_SIZE);
439225d0ae62SJun Yang 	if (key_cfg_iova == RTE_BAD_IOVA) {
439325d0ae62SJun Yang 		DPAA2_PMD_ERR("%s: No IOMMU map for key cfg(%p)",
439425d0ae62SJun Yang 			__func__, key_cfg_buf);
439525d0ae62SJun Yang 
439625d0ae62SJun Yang 		return -ENOBUFS;
439725d0ae62SJun Yang 	}
439856c1817dSJun Yang 
439956c1817dSJun Yang 	key_max_size = qos_extract->key_profile.key_max_size;
440056c1817dSJun Yang 	entry_size = dpaa2_flow_entry_size(key_max_size);
440156c1817dSJun Yang 
440256c1817dSJun Yang 	dpaa2_flow_qos_extracts_log(priv);
440356c1817dSJun Yang 
440456c1817dSJun Yang 	ret = dpkg_prepare_key_cfg(&qos_extract->dpkg,
440556c1817dSJun Yang 			key_cfg_buf);
440656c1817dSJun Yang 	if (ret < 0) {
440756c1817dSJun Yang 		DPAA2_PMD_ERR("QoS prepare extract failed");
440856c1817dSJun Yang 		return ret;
440956c1817dSJun Yang 	}
441056c1817dSJun Yang 	memset(&qos_cfg, 0, sizeof(struct dpni_qos_tbl_cfg));
441156c1817dSJun Yang 	qos_cfg.keep_entries = true;
441256c1817dSJun Yang 	qos_cfg.key_cfg_iova = key_cfg_iova;
441356c1817dSJun Yang 	if (rss_dist) {
441456c1817dSJun Yang 		qos_cfg.discard_on_miss = true;
441556c1817dSJun Yang 	} else {
441656c1817dSJun Yang 		qos_cfg.discard_on_miss = false;
441756c1817dSJun Yang 		qos_cfg.default_tc = 0;
441856c1817dSJun Yang 	}
441956c1817dSJun Yang 
442056c1817dSJun Yang 	ret = dpni_set_qos_table(dpni, CMD_PRI_LOW,
442156c1817dSJun Yang 			priv->token, &qos_cfg);
442256c1817dSJun Yang 	if (ret < 0) {
442356c1817dSJun Yang 		DPAA2_PMD_ERR("QoS table set failed");
442456c1817dSJun Yang 		return ret;
442556c1817dSJun Yang 	}
442656c1817dSJun Yang 
442756c1817dSJun Yang 	ret = dpaa2_flow_rule_add_all(priv, DPAA2_FLOW_QOS_TYPE,
442856c1817dSJun Yang 			entry_size, 0);
442956c1817dSJun Yang 	if (ret)
443056c1817dSJun Yang 		return ret;
443156c1817dSJun Yang 
443256c1817dSJun Yang 	return 0;
443356c1817dSJun Yang }
443456c1817dSJun Yang 
443556c1817dSJun Yang static int
44369ec29343SJun Yang dpaa2_flow_item_convert(const struct rte_flow_item pattern[],
44379ec29343SJun Yang 			struct rte_dpaa2_flow_item **dpaa2_pattern)
44389ec29343SJun Yang {
44399ec29343SJun Yang 	struct rte_dpaa2_flow_item *new_pattern;
44409ec29343SJun Yang 	int num = 0, tunnel_start = 0;
44419ec29343SJun Yang 
44429ec29343SJun Yang 	while (1) {
44439ec29343SJun Yang 		num++;
44449ec29343SJun Yang 		if (pattern[num].type == RTE_FLOW_ITEM_TYPE_END)
44459ec29343SJun Yang 			break;
44469ec29343SJun Yang 	}
44479ec29343SJun Yang 
44489ec29343SJun Yang 	new_pattern = rte_malloc(NULL, sizeof(struct rte_dpaa2_flow_item) * num,
44499ec29343SJun Yang 				 RTE_CACHE_LINE_SIZE);
44509ec29343SJun Yang 	if (!new_pattern) {
44519ec29343SJun Yang 		DPAA2_PMD_ERR("Failed to alloc %d flow items", num);
44529ec29343SJun Yang 		return -ENOMEM;
44539ec29343SJun Yang 	}
44549ec29343SJun Yang 
44559ec29343SJun Yang 	num = 0;
44569ec29343SJun Yang 	while (pattern[num].type != RTE_FLOW_ITEM_TYPE_END) {
44579ec29343SJun Yang 		memcpy(&new_pattern[num].generic_item, &pattern[num],
44589ec29343SJun Yang 		       sizeof(struct rte_flow_item));
44599ec29343SJun Yang 		new_pattern[num].in_tunnel = 0;
44609ec29343SJun Yang 
44619ec29343SJun Yang 		if (pattern[num].type == RTE_FLOW_ITEM_TYPE_VXLAN)
44629ec29343SJun Yang 			tunnel_start = 1;
44639ec29343SJun Yang 		else if (tunnel_start)
44649ec29343SJun Yang 			new_pattern[num].in_tunnel = 1;
44659ec29343SJun Yang 		num++;
44669ec29343SJun Yang 	}
44679ec29343SJun Yang 
44689ec29343SJun Yang 	new_pattern[num].generic_item.type = RTE_FLOW_ITEM_TYPE_END;
44699ec29343SJun Yang 	*dpaa2_pattern = new_pattern;
44709ec29343SJun Yang 
44719ec29343SJun Yang 	return 0;
44729ec29343SJun Yang }
44739ec29343SJun Yang 
44749ec29343SJun Yang static int
447556c1817dSJun Yang dpaa2_generic_flow_set(struct dpaa2_dev_flow *flow,
4476fe2b986aSSunil Kumar Kori 	struct rte_eth_dev *dev,
4477fe2b986aSSunil Kumar Kori 	const struct rte_flow_attr *attr,
4478fe2b986aSSunil Kumar Kori 	const struct rte_flow_item pattern[],
4479fe2b986aSSunil Kumar Kori 	const struct rte_flow_action actions[],
4480fe2b986aSSunil Kumar Kori 	struct rte_flow_error *error)
4481fe2b986aSSunil Kumar Kori {
4482fe2b986aSSunil Kumar Kori 	const struct rte_flow_action_rss *rss_conf;
4483fe2b986aSSunil Kumar Kori 	int is_keycfg_configured = 0, end_of_list = 0;
4484fe2b986aSSunil Kumar Kori 	int ret = 0, i = 0, j = 0;
4485fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
448656c1817dSJun Yang 	struct dpaa2_dev_flow *curr = LIST_FIRST(&priv->flows);
448756c1817dSJun Yang 	uint16_t dist_size, key_size;
448856c1817dSJun Yang 	struct dpaa2_key_extract *qos_key_extract;
448956c1817dSJun Yang 	struct dpaa2_key_extract *tc_key_extract;
44909ec29343SJun Yang 	struct rte_dpaa2_flow_item *dpaa2_pattern = NULL;
44914ce58f8aSJun Yang 
44924ce58f8aSJun Yang 	ret = dpaa2_flow_verify_attr(priv, attr);
44934ce58f8aSJun Yang 	if (ret)
44944ce58f8aSJun Yang 		return ret;
4495fe2b986aSSunil Kumar Kori 
4496bac4a296SJun Yang 	ret = dpaa2_flow_verify_action(priv, attr, actions);
4497bac4a296SJun Yang 	if (ret)
4498bac4a296SJun Yang 		return ret;
4499bac4a296SJun Yang 
45009ec29343SJun Yang 	ret = dpaa2_flow_item_convert(pattern, &dpaa2_pattern);
45019ec29343SJun Yang 	if (ret)
45029ec29343SJun Yang 		return ret;
45039ec29343SJun Yang 
4504fe2b986aSSunil Kumar Kori 	/* Parse pattern list to get the matching parameters */
4505fe2b986aSSunil Kumar Kori 	while (!end_of_list) {
4506fe2b986aSSunil Kumar Kori 		switch (pattern[i].type) {
4507fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ITEM_TYPE_ETH:
45089ec29343SJun Yang 			ret = dpaa2_configure_flow_eth(flow, dev, attr,
45099ec29343SJun Yang 					&dpaa2_pattern[i],
45109ec29343SJun Yang 					actions, error,
45115f176728SJun Yang 					&is_keycfg_configured);
45125f176728SJun Yang 			if (ret) {
451356c1817dSJun Yang 				DPAA2_PMD_ERR("ETH flow config failed!");
45149ec29343SJun Yang 				goto end_flow_set;
45155f176728SJun Yang 			}
4516fe2b986aSSunil Kumar Kori 			break;
4517fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ITEM_TYPE_VLAN:
45189ec29343SJun Yang 			ret = dpaa2_configure_flow_vlan(flow, dev, attr,
45199ec29343SJun Yang 					&dpaa2_pattern[i],
45209ec29343SJun Yang 					actions, error,
45215f176728SJun Yang 					&is_keycfg_configured);
45225f176728SJun Yang 			if (ret) {
452356c1817dSJun Yang 				DPAA2_PMD_ERR("vLan flow config failed!");
45249ec29343SJun Yang 				goto end_flow_set;
45255f176728SJun Yang 			}
4526fe2b986aSSunil Kumar Kori 			break;
4527fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ITEM_TYPE_IPV4:
45289ec29343SJun Yang 			ret = dpaa2_configure_flow_ipv4(flow, dev, attr,
45299ec29343SJun Yang 					&dpaa2_pattern[i],
45309ec29343SJun Yang 					actions, error,
45315f176728SJun Yang 					&is_keycfg_configured);
45325f176728SJun Yang 			if (ret) {
453356c1817dSJun Yang 				DPAA2_PMD_ERR("IPV4 flow config failed!");
45349ec29343SJun Yang 				goto end_flow_set;
453556c1817dSJun Yang 			}
453656c1817dSJun Yang 			break;
453756c1817dSJun Yang 		case RTE_FLOW_ITEM_TYPE_IPV6:
45389ec29343SJun Yang 			ret = dpaa2_configure_flow_ipv6(flow, dev, attr,
45399ec29343SJun Yang 					&dpaa2_pattern[i],
45409ec29343SJun Yang 					actions, error,
454156c1817dSJun Yang 					&is_keycfg_configured);
454256c1817dSJun Yang 			if (ret) {
454356c1817dSJun Yang 				DPAA2_PMD_ERR("IPV6 flow config failed!");
45449ec29343SJun Yang 				goto end_flow_set;
45455f176728SJun Yang 			}
4546fe2b986aSSunil Kumar Kori 			break;
4547fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ITEM_TYPE_ICMP:
45489ec29343SJun Yang 			ret = dpaa2_configure_flow_icmp(flow, dev, attr,
45499ec29343SJun Yang 					&dpaa2_pattern[i],
45509ec29343SJun Yang 					actions, error,
45515f176728SJun Yang 					&is_keycfg_configured);
45525f176728SJun Yang 			if (ret) {
455356c1817dSJun Yang 				DPAA2_PMD_ERR("ICMP flow config failed!");
45549ec29343SJun Yang 				goto end_flow_set;
45555f176728SJun Yang 			}
4556fe2b986aSSunil Kumar Kori 			break;
4557fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ITEM_TYPE_UDP:
45589ec29343SJun Yang 			ret = dpaa2_configure_flow_udp(flow, dev, attr,
45599ec29343SJun Yang 					&dpaa2_pattern[i],
45609ec29343SJun Yang 					actions, error,
45615f176728SJun Yang 					&is_keycfg_configured);
45625f176728SJun Yang 			if (ret) {
456356c1817dSJun Yang 				DPAA2_PMD_ERR("UDP flow config failed!");
45649ec29343SJun Yang 				goto end_flow_set;
45655f176728SJun Yang 			}
4566fe2b986aSSunil Kumar Kori 			break;
4567fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ITEM_TYPE_TCP:
45689ec29343SJun Yang 			ret = dpaa2_configure_flow_tcp(flow, dev, attr,
45699ec29343SJun Yang 					&dpaa2_pattern[i],
45709ec29343SJun Yang 					actions, error,
45715f176728SJun Yang 					&is_keycfg_configured);
45725f176728SJun Yang 			if (ret) {
457356c1817dSJun Yang 				DPAA2_PMD_ERR("TCP flow config failed!");
45749ec29343SJun Yang 				goto end_flow_set;
45755f176728SJun Yang 			}
4576fe2b986aSSunil Kumar Kori 			break;
4577fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ITEM_TYPE_SCTP:
45789ec29343SJun Yang 			ret = dpaa2_configure_flow_sctp(flow, dev, attr,
45799ec29343SJun Yang 					&dpaa2_pattern[i],
45809ec29343SJun Yang 					actions, error,
45815f176728SJun Yang 					&is_keycfg_configured);
45825f176728SJun Yang 			if (ret) {
458356c1817dSJun Yang 				DPAA2_PMD_ERR("SCTP flow config failed!");
45849ec29343SJun Yang 				goto end_flow_set;
45855f176728SJun Yang 			}
4586fe2b986aSSunil Kumar Kori 			break;
45874cc5cf4aSJun Yang 		case RTE_FLOW_ITEM_TYPE_ESP:
45884cc5cf4aSJun Yang 			ret = dpaa2_configure_flow_esp(flow,
45894cc5cf4aSJun Yang 					dev, attr, &dpaa2_pattern[i],
45904cc5cf4aSJun Yang 					actions, error,
45914cc5cf4aSJun Yang 					&is_keycfg_configured);
45924cc5cf4aSJun Yang 			if (ret) {
45934cc5cf4aSJun Yang 				DPAA2_PMD_ERR("ESP flow config failed!");
45944cc5cf4aSJun Yang 				goto end_flow_set;
45954cc5cf4aSJun Yang 			}
45964cc5cf4aSJun Yang 			break;
45974cc5cf4aSJun Yang 		case RTE_FLOW_ITEM_TYPE_AH:
45984cc5cf4aSJun Yang 			ret = dpaa2_configure_flow_ah(flow,
45994cc5cf4aSJun Yang 					dev, attr, &dpaa2_pattern[i],
46004cc5cf4aSJun Yang 					actions, error,
46014cc5cf4aSJun Yang 					&is_keycfg_configured);
46024cc5cf4aSJun Yang 			if (ret) {
46034cc5cf4aSJun Yang 				DPAA2_PMD_ERR("AH flow config failed!");
46044cc5cf4aSJun Yang 				goto end_flow_set;
46054cc5cf4aSJun Yang 			}
46064cc5cf4aSJun Yang 			break;
4607fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ITEM_TYPE_GRE:
46089ec29343SJun Yang 			ret = dpaa2_configure_flow_gre(flow, dev, attr,
46099ec29343SJun Yang 					&dpaa2_pattern[i],
46109ec29343SJun Yang 					actions, error,
46115f176728SJun Yang 					&is_keycfg_configured);
46125f176728SJun Yang 			if (ret) {
461356c1817dSJun Yang 				DPAA2_PMD_ERR("GRE flow config failed!");
46149ec29343SJun Yang 				goto end_flow_set;
46155f176728SJun Yang 			}
4616fe2b986aSSunil Kumar Kori 			break;
461739c8044fSJun Yang 		case RTE_FLOW_ITEM_TYPE_VXLAN:
46189ec29343SJun Yang 			ret = dpaa2_configure_flow_vxlan(flow, dev, attr,
46199ec29343SJun Yang 					&dpaa2_pattern[i],
46209ec29343SJun Yang 					actions, error,
462139c8044fSJun Yang 					&is_keycfg_configured);
462239c8044fSJun Yang 			if (ret) {
462339c8044fSJun Yang 				DPAA2_PMD_ERR("VXLAN flow config failed!");
46249ec29343SJun Yang 				goto end_flow_set;
462539c8044fSJun Yang 			}
462639c8044fSJun Yang 			break;
4627a8a6b82eSJun Yang 		case RTE_FLOW_ITEM_TYPE_ECPRI:
4628a8a6b82eSJun Yang 			ret = dpaa2_configure_flow_ecpri(flow,
4629a8a6b82eSJun Yang 					dev, attr, &dpaa2_pattern[i],
4630a8a6b82eSJun Yang 					actions, error,
4631a8a6b82eSJun Yang 					&is_keycfg_configured);
4632a8a6b82eSJun Yang 			if (ret) {
4633a8a6b82eSJun Yang 				DPAA2_PMD_ERR("ECPRI flow config failed!");
4634a8a6b82eSJun Yang 				goto end_flow_set;
4635a8a6b82eSJun Yang 			}
4636a8a6b82eSJun Yang 			break;
4637146c745eSJun Yang 		case RTE_FLOW_ITEM_TYPE_GTP:
4638146c745eSJun Yang 			ret = dpaa2_configure_flow_gtp(flow,
4639146c745eSJun Yang 					dev, attr, &dpaa2_pattern[i],
4640146c745eSJun Yang 					actions, error,
4641146c745eSJun Yang 					&is_keycfg_configured);
4642146c745eSJun Yang 			if (ret) {
4643146c745eSJun Yang 				DPAA2_PMD_ERR("GTP flow config failed!");
4644146c745eSJun Yang 				goto end_flow_set;
4645146c745eSJun Yang 			}
4646146c745eSJun Yang 			break;
46473f881f8dSNipun Gupta 		case RTE_FLOW_ITEM_TYPE_RAW:
46489ec29343SJun Yang 			ret = dpaa2_configure_flow_raw(flow, dev, attr,
46499ec29343SJun Yang 					&dpaa2_pattern[i],
46503f881f8dSNipun Gupta 					actions, error,
46513f881f8dSNipun Gupta 					&is_keycfg_configured);
46523f881f8dSNipun Gupta 			if (ret) {
465356c1817dSJun Yang 				DPAA2_PMD_ERR("RAW flow config failed!");
46549ec29343SJun Yang 				goto end_flow_set;
46553f881f8dSNipun Gupta 			}
46563f881f8dSNipun Gupta 			break;
4657fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ITEM_TYPE_END:
4658fe2b986aSSunil Kumar Kori 			end_of_list = 1;
4659fe2b986aSSunil Kumar Kori 			break; /*End of List*/
4660fe2b986aSSunil Kumar Kori 		default:
4661a8a6b82eSJun Yang 			DPAA2_PMD_ERR("Invalid flow item[%d] type(%d)",
4662a8a6b82eSJun Yang 				i, pattern[i].type);
4663fe2b986aSSunil Kumar Kori 			ret = -ENOTSUP;
4664fe2b986aSSunil Kumar Kori 			break;
4665fe2b986aSSunil Kumar Kori 		}
4666fe2b986aSSunil Kumar Kori 		i++;
4667fe2b986aSSunil Kumar Kori 	}
4668fe2b986aSSunil Kumar Kori 
466956c1817dSJun Yang 	qos_key_extract = &priv->extract.qos_key_extract;
467056c1817dSJun Yang 	key_size = qos_key_extract->key_profile.key_max_size;
467156c1817dSJun Yang 	flow->qos_rule.key_size = dpaa2_flow_entry_size(key_size);
467256c1817dSJun Yang 
467356c1817dSJun Yang 	tc_key_extract = &priv->extract.tc_key_extract[flow->tc_id];
467456c1817dSJun Yang 	key_size = tc_key_extract->key_profile.key_max_size;
467556c1817dSJun Yang 	flow->fs_rule.key_size = dpaa2_flow_entry_size(key_size);
467656c1817dSJun Yang 
4677fe2b986aSSunil Kumar Kori 	/* Let's parse action on matching traffic */
4678fe2b986aSSunil Kumar Kori 	end_of_list = 0;
4679fe2b986aSSunil Kumar Kori 	while (!end_of_list) {
4680fe2b986aSSunil Kumar Kori 		switch (actions[j].type) {
4681fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ACTION_TYPE_QUEUE:
4682b1e15294SIvan Malov 		case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
4683028d1dfdSJun Yang 		case RTE_FLOW_ACTION_TYPE_PORT_ID:
468456c1817dSJun Yang 			ret = dpaa2_configure_flow_fs_action(priv, flow,
4685028d1dfdSJun Yang 							     &actions[j]);
468656c1817dSJun Yang 			if (ret)
46879ec29343SJun Yang 				goto end_flow_set;
4688fe2b986aSSunil Kumar Kori 
468959303cdfSJun Yang 			/* Configure FS table first*/
469056c1817dSJun Yang 			dist_size = priv->nb_rx_queues / priv->num_rx_tc;
469156c1817dSJun Yang 			if (is_keycfg_configured & DPAA2_FLOW_FS_TYPE) {
469256c1817dSJun Yang 				ret = dpaa2_configure_fs_rss_table(priv,
469356c1817dSJun Yang 								   flow->tc_id,
469456c1817dSJun Yang 								   dist_size,
469556c1817dSJun Yang 								   false);
469656c1817dSJun Yang 				if (ret)
46979ec29343SJun Yang 					goto end_flow_set;
4698fe2b986aSSunil Kumar Kori 			}
4699fe2b986aSSunil Kumar Kori 
470059303cdfSJun Yang 			/* Configure QoS table then.*/
470156c1817dSJun Yang 			if (is_keycfg_configured & DPAA2_FLOW_QOS_TYPE) {
470256c1817dSJun Yang 				ret = dpaa2_configure_qos_table(priv, false);
470356c1817dSJun Yang 				if (ret)
47049ec29343SJun Yang 					goto end_flow_set;
4705fe2b986aSSunil Kumar Kori 			}
470656c1817dSJun Yang 
470756c1817dSJun Yang 			if (priv->num_rx_tc > 1) {
470856c1817dSJun Yang 				ret = dpaa2_flow_add_qos_rule(priv, flow);
470956c1817dSJun Yang 				if (ret)
47109ec29343SJun Yang 					goto end_flow_set;
471159303cdfSJun Yang 			}
4712fe2b986aSSunil Kumar Kori 
47134ce58f8aSJun Yang 			if (flow->tc_index >= priv->fs_entries) {
47145f176728SJun Yang 				DPAA2_PMD_ERR("FS table with %d entries full",
47154ce58f8aSJun Yang 					priv->fs_entries);
47165f176728SJun Yang 				return -1;
47175f176728SJun Yang 			}
4718d0a77dc3SJun Yang 
471956c1817dSJun Yang 			ret = dpaa2_flow_add_fs_rule(priv, flow);
472056c1817dSJun Yang 			if (ret)
47219ec29343SJun Yang 				goto end_flow_set;
472256c1817dSJun Yang 
4723fe2b986aSSunil Kumar Kori 			break;
4724fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ACTION_TYPE_RSS:
472556c1817dSJun Yang 			rss_conf = actions[j].conf;
472656c1817dSJun Yang 			flow->action_type = RTE_FLOW_ACTION_TYPE_RSS;
4727fe2b986aSSunil Kumar Kori 
4728fe2b986aSSunil Kumar Kori 			ret = dpaa2_distset_to_dpkg_profile_cfg(rss_conf->types,
472956c1817dSJun Yang 					&tc_key_extract->dpkg);
4730fe2b986aSSunil Kumar Kori 			if (ret < 0) {
473156c1817dSJun Yang 				DPAA2_PMD_ERR("TC[%d] distset RSS failed",
473256c1817dSJun Yang 					      flow->tc_id);
47339ec29343SJun Yang 				goto end_flow_set;
4734fe2b986aSSunil Kumar Kori 			}
4735fe2b986aSSunil Kumar Kori 
473656c1817dSJun Yang 			dist_size = rss_conf->queue_num;
473756c1817dSJun Yang 			if (is_keycfg_configured & DPAA2_FLOW_FS_TYPE) {
473856c1817dSJun Yang 				ret = dpaa2_configure_fs_rss_table(priv,
473956c1817dSJun Yang 								   flow->tc_id,
474056c1817dSJun Yang 								   dist_size,
474156c1817dSJun Yang 								   true);
474256c1817dSJun Yang 				if (ret)
47439ec29343SJun Yang 					goto end_flow_set;
4744fe2b986aSSunil Kumar Kori 			}
474556c1817dSJun Yang 
474656c1817dSJun Yang 			if (is_keycfg_configured & DPAA2_FLOW_QOS_TYPE) {
474756c1817dSJun Yang 				ret = dpaa2_configure_qos_table(priv, true);
474856c1817dSJun Yang 				if (ret)
47499ec29343SJun Yang 					goto end_flow_set;
475056c1817dSJun Yang 			}
475156c1817dSJun Yang 
475256c1817dSJun Yang 			ret = dpaa2_flow_add_qos_rule(priv, flow);
475356c1817dSJun Yang 			if (ret)
47549ec29343SJun Yang 				goto end_flow_set;
475556c1817dSJun Yang 
475656c1817dSJun Yang 			ret = dpaa2_flow_add_fs_rule(priv, flow);
475756c1817dSJun Yang 			if (ret)
47589ec29343SJun Yang 				goto end_flow_set;
475956c1817dSJun Yang 
4760fe2b986aSSunil Kumar Kori 			break;
476139c8044fSJun Yang 		case RTE_FLOW_ACTION_TYPE_PF:
476239c8044fSJun Yang 			/* Skip this action, have to add for vxlan */
476339c8044fSJun Yang 			break;
4764fe2b986aSSunil Kumar Kori 		case RTE_FLOW_ACTION_TYPE_END:
4765fe2b986aSSunil Kumar Kori 			end_of_list = 1;
4766fe2b986aSSunil Kumar Kori 			break;
4767fe2b986aSSunil Kumar Kori 		default:
4768fe2b986aSSunil Kumar Kori 			DPAA2_PMD_ERR("Invalid action type");
4769fe2b986aSSunil Kumar Kori 			ret = -ENOTSUP;
4770fe2b986aSSunil Kumar Kori 			break;
4771fe2b986aSSunil Kumar Kori 		}
4772fe2b986aSSunil Kumar Kori 		j++;
4773fe2b986aSSunil Kumar Kori 	}
4774fe2b986aSSunil Kumar Kori 
47759ec29343SJun Yang end_flow_set:
47766a556bd6SHemant Agrawal 	if (!ret) {
47776a556bd6SHemant Agrawal 		/* New rules are inserted. */
47786a556bd6SHemant Agrawal 		if (!curr) {
47796a556bd6SHemant Agrawal 			LIST_INSERT_HEAD(&priv->flows, flow, next);
47806a556bd6SHemant Agrawal 		} else {
47816a556bd6SHemant Agrawal 			while (LIST_NEXT(curr, next))
47826a556bd6SHemant Agrawal 				curr = LIST_NEXT(curr, next);
47836a556bd6SHemant Agrawal 			LIST_INSERT_AFTER(curr, flow, next);
47846a556bd6SHemant Agrawal 		}
47856a556bd6SHemant Agrawal 	}
47869ec29343SJun Yang 
47879ec29343SJun Yang 	rte_free(dpaa2_pattern);
47889ec29343SJun Yang 
4789fe2b986aSSunil Kumar Kori 	return ret;
4790fe2b986aSSunil Kumar Kori }
4791fe2b986aSSunil Kumar Kori 
4792fe2b986aSSunil Kumar Kori static inline int
4793fe2b986aSSunil Kumar Kori dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr,
4794fe2b986aSSunil Kumar Kori 	const struct rte_flow_attr *attr)
4795fe2b986aSSunil Kumar Kori {
4796fe2b986aSSunil Kumar Kori 	int ret = 0;
4797fe2b986aSSunil Kumar Kori 
4798fe2b986aSSunil Kumar Kori 	if (unlikely(attr->group >= dpni_attr->num_rx_tcs)) {
47991cf6d181SJun Yang 		DPAA2_PMD_ERR("Group/TC(%d) is out of range(%d)",
48001cf6d181SJun Yang 			attr->group, dpni_attr->num_rx_tcs);
4801fe2b986aSSunil Kumar Kori 		ret = -ENOTSUP;
4802fe2b986aSSunil Kumar Kori 	}
4803fe2b986aSSunil Kumar Kori 	if (unlikely(attr->priority >= dpni_attr->fs_entries)) {
48041cf6d181SJun Yang 		DPAA2_PMD_ERR("Priority(%d) within group is out of range(%d)",
48051cf6d181SJun Yang 			attr->priority, dpni_attr->fs_entries);
4806fe2b986aSSunil Kumar Kori 		ret = -ENOTSUP;
4807fe2b986aSSunil Kumar Kori 	}
4808fe2b986aSSunil Kumar Kori 	if (unlikely(attr->egress)) {
48091cf6d181SJun Yang 		DPAA2_PMD_ERR("Egress flow configuration is not supported");
4810fe2b986aSSunil Kumar Kori 		ret = -ENOTSUP;
4811fe2b986aSSunil Kumar Kori 	}
4812fe2b986aSSunil Kumar Kori 	if (unlikely(!attr->ingress)) {
4813f665790aSDavid Marchand 		DPAA2_PMD_ERR("Ingress flag must be configured");
4814fe2b986aSSunil Kumar Kori 		ret = -EINVAL;
4815fe2b986aSSunil Kumar Kori 	}
4816fe2b986aSSunil Kumar Kori 	return ret;
4817fe2b986aSSunil Kumar Kori }
4818fe2b986aSSunil Kumar Kori 
4819fe2b986aSSunil Kumar Kori static inline int
48205f176728SJun Yang dpaa2_dev_verify_patterns(const struct rte_flow_item pattern[])
4821fe2b986aSSunil Kumar Kori {
48225f176728SJun Yang 	unsigned int i, j, is_found = 0;
4823fe2b986aSSunil Kumar Kori 	int ret = 0;
48241cf6d181SJun Yang 	const enum rte_flow_item_type *hp_supported;
48251cf6d181SJun Yang 	const enum rte_flow_item_type *sp_supported;
48261cf6d181SJun Yang 	uint64_t hp_supported_num, sp_supported_num;
48271cf6d181SJun Yang 
48281cf6d181SJun Yang 	hp_supported = dpaa2_hp_supported_pattern_type;
48291cf6d181SJun Yang 	hp_supported_num = RTE_DIM(dpaa2_hp_supported_pattern_type);
48301cf6d181SJun Yang 
48311cf6d181SJun Yang 	sp_supported = dpaa2_sp_supported_pattern_type;
48321cf6d181SJun Yang 	sp_supported_num = RTE_DIM(dpaa2_sp_supported_pattern_type);
4833fe2b986aSSunil Kumar Kori 
4834fe2b986aSSunil Kumar Kori 	for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) {
48351cf6d181SJun Yang 		is_found = 0;
48361cf6d181SJun Yang 		for (i = 0; i < hp_supported_num; i++) {
48371cf6d181SJun Yang 			if (hp_supported[i] == pattern[j].type) {
4838fe2b986aSSunil Kumar Kori 				is_found = 1;
4839fe2b986aSSunil Kumar Kori 				break;
4840fe2b986aSSunil Kumar Kori 			}
4841fe2b986aSSunil Kumar Kori 		}
48421cf6d181SJun Yang 		if (is_found)
48431cf6d181SJun Yang 			continue;
48441cf6d181SJun Yang 		if (dpaa2_sp_loaded > 0) {
48451cf6d181SJun Yang 			for (i = 0; i < sp_supported_num; i++) {
48461cf6d181SJun Yang 				if (sp_supported[i] == pattern[j].type) {
48471cf6d181SJun Yang 					is_found = 1;
4848fe2b986aSSunil Kumar Kori 					break;
4849fe2b986aSSunil Kumar Kori 				}
4850fe2b986aSSunil Kumar Kori 			}
48511cf6d181SJun Yang 		}
48521cf6d181SJun Yang 		if (!is_found) {
48531cf6d181SJun Yang 			DPAA2_PMD_WARN("Flow type(%d) not supported",
48541cf6d181SJun Yang 				pattern[j].type);
48551cf6d181SJun Yang 			ret = -ENOTSUP;
4856fe2b986aSSunil Kumar Kori 			break;
4857fe2b986aSSunil Kumar Kori 		}
4858fe2b986aSSunil Kumar Kori 	}
4859fe2b986aSSunil Kumar Kori 
4860fe2b986aSSunil Kumar Kori 	return ret;
4861fe2b986aSSunil Kumar Kori }
4862fe2b986aSSunil Kumar Kori 
4863fe2b986aSSunil Kumar Kori static inline int
4864fe2b986aSSunil Kumar Kori dpaa2_dev_verify_actions(const struct rte_flow_action actions[])
4865fe2b986aSSunil Kumar Kori {
4866fe2b986aSSunil Kumar Kori 	unsigned int i, j, is_found = 0;
4867fe2b986aSSunil Kumar Kori 	int ret = 0;
4868fe2b986aSSunil Kumar Kori 
4869fe2b986aSSunil Kumar Kori 	for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
4870fe2b986aSSunil Kumar Kori 		for (i = 0; i < RTE_DIM(dpaa2_supported_action_type); i++) {
4871fe2b986aSSunil Kumar Kori 			if (dpaa2_supported_action_type[i] == actions[j].type) {
4872fe2b986aSSunil Kumar Kori 				is_found = 1;
4873fe2b986aSSunil Kumar Kori 				break;
4874fe2b986aSSunil Kumar Kori 			}
4875fe2b986aSSunil Kumar Kori 		}
4876fe2b986aSSunil Kumar Kori 		if (!is_found) {
4877fe2b986aSSunil Kumar Kori 			ret = -ENOTSUP;
4878fe2b986aSSunil Kumar Kori 			break;
4879fe2b986aSSunil Kumar Kori 		}
4880fe2b986aSSunil Kumar Kori 	}
4881fe2b986aSSunil Kumar Kori 	for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) {
48825f176728SJun Yang 		if (actions[j].type != RTE_FLOW_ACTION_TYPE_DROP &&
48835f176728SJun Yang 		    !actions[j].conf)
4884fe2b986aSSunil Kumar Kori 			ret = -EINVAL;
4885fe2b986aSSunil Kumar Kori 	}
4886fe2b986aSSunil Kumar Kori 	return ret;
4887fe2b986aSSunil Kumar Kori }
4888fe2b986aSSunil Kumar Kori 
488956c1817dSJun Yang static int
489056c1817dSJun Yang dpaa2_flow_validate(struct rte_eth_dev *dev,
4891fe2b986aSSunil Kumar Kori 	const struct rte_flow_attr *flow_attr,
4892fe2b986aSSunil Kumar Kori 	const struct rte_flow_item pattern[],
4893fe2b986aSSunil Kumar Kori 	const struct rte_flow_action actions[],
48946a556bd6SHemant Agrawal 	struct rte_flow_error *error)
4895fe2b986aSSunil Kumar Kori {
4896fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
4897fe2b986aSSunil Kumar Kori 	struct dpni_attr dpni_attr;
4898fe2b986aSSunil Kumar Kori 	struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
4899fe2b986aSSunil Kumar Kori 	uint16_t token = priv->token;
4900fe2b986aSSunil Kumar Kori 	int ret = 0;
4901fe2b986aSSunil Kumar Kori 
4902fe2b986aSSunil Kumar Kori 	memset(&dpni_attr, 0, sizeof(struct dpni_attr));
4903fe2b986aSSunil Kumar Kori 	ret = dpni_get_attributes(dpni, CMD_PRI_LOW, token, &dpni_attr);
4904fe2b986aSSunil Kumar Kori 	if (ret < 0) {
49051cf6d181SJun Yang 		DPAA2_PMD_ERR("Get dpni@%d attribute failed(%d)",
49061cf6d181SJun Yang 			priv->hw_id, ret);
49076a556bd6SHemant Agrawal 		rte_flow_error_set(error, EPERM,
49086a556bd6SHemant Agrawal 			RTE_FLOW_ERROR_TYPE_ATTR,
49096a556bd6SHemant Agrawal 			flow_attr, "invalid");
4910fe2b986aSSunil Kumar Kori 		return ret;
4911fe2b986aSSunil Kumar Kori 	}
4912fe2b986aSSunil Kumar Kori 
4913fe2b986aSSunil Kumar Kori 	/* Verify input attributes */
4914fe2b986aSSunil Kumar Kori 	ret = dpaa2_dev_verify_attr(&dpni_attr, flow_attr);
4915fe2b986aSSunil Kumar Kori 	if (ret < 0) {
49161cf6d181SJun Yang 		DPAA2_PMD_ERR("Invalid attributes are given");
49176a556bd6SHemant Agrawal 		rte_flow_error_set(error, EPERM,
49186a556bd6SHemant Agrawal 			RTE_FLOW_ERROR_TYPE_ATTR,
49196a556bd6SHemant Agrawal 			flow_attr, "invalid");
4920fe2b986aSSunil Kumar Kori 		goto not_valid_params;
4921fe2b986aSSunil Kumar Kori 	}
4922fe2b986aSSunil Kumar Kori 	/* Verify input pattern list */
49235f176728SJun Yang 	ret = dpaa2_dev_verify_patterns(pattern);
4924fe2b986aSSunil Kumar Kori 	if (ret < 0) {
49251cf6d181SJun Yang 		DPAA2_PMD_ERR("Invalid pattern list is given");
49266a556bd6SHemant Agrawal 		rte_flow_error_set(error, EPERM,
49276a556bd6SHemant Agrawal 			RTE_FLOW_ERROR_TYPE_ITEM,
49286a556bd6SHemant Agrawal 			pattern, "invalid");
4929fe2b986aSSunil Kumar Kori 		goto not_valid_params;
4930fe2b986aSSunil Kumar Kori 	}
4931fe2b986aSSunil Kumar Kori 	/* Verify input action list */
4932fe2b986aSSunil Kumar Kori 	ret = dpaa2_dev_verify_actions(actions);
4933fe2b986aSSunil Kumar Kori 	if (ret < 0) {
49341cf6d181SJun Yang 		DPAA2_PMD_ERR("Invalid action list is given");
49356a556bd6SHemant Agrawal 		rte_flow_error_set(error, EPERM,
49366a556bd6SHemant Agrawal 			RTE_FLOW_ERROR_TYPE_ACTION,
49376a556bd6SHemant Agrawal 			actions, "invalid");
4938fe2b986aSSunil Kumar Kori 		goto not_valid_params;
4939fe2b986aSSunil Kumar Kori 	}
4940fe2b986aSSunil Kumar Kori not_valid_params:
4941fe2b986aSSunil Kumar Kori 	return ret;
4942fe2b986aSSunil Kumar Kori }
4943fe2b986aSSunil Kumar Kori 
494456c1817dSJun Yang static struct rte_flow *
494556c1817dSJun Yang dpaa2_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
4946fe2b986aSSunil Kumar Kori 		  const struct rte_flow_item pattern[],
4947fe2b986aSSunil Kumar Kori 		  const struct rte_flow_action actions[],
4948fe2b986aSSunil Kumar Kori 		  struct rte_flow_error *error)
4949fe2b986aSSunil Kumar Kori {
495056c1817dSJun Yang 	struct dpaa2_dev_flow *flow = NULL;
495156c1817dSJun Yang 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
4952fe2b986aSSunil Kumar Kori 	int ret;
495325d0ae62SJun Yang 	uint64_t iova;
4954fe2b986aSSunil Kumar Kori 
4955f5ed2ea0SJun Yang 	dpaa2_flow_control_log =
4956f5ed2ea0SJun Yang 		getenv("DPAA2_FLOW_CONTROL_LOG");
4957f5ed2ea0SJun Yang 
495840f84025SJun Yang 	if (getenv("DPAA2_FLOW_CONTROL_MISS_FLOW")) {
495940f84025SJun Yang 		dpaa2_flow_miss_flow_id =
4960068be45fSRohit Raj 			(uint16_t)atoi(getenv("DPAA2_FLOW_CONTROL_MISS_FLOW"));
496140f84025SJun Yang 		if (dpaa2_flow_miss_flow_id >= priv->dist_queues) {
496256c1817dSJun Yang 			DPAA2_PMD_ERR("Missed flow ID %d >= dist size(%d)",
496340f84025SJun Yang 				      dpaa2_flow_miss_flow_id,
496456c1817dSJun Yang 				      priv->dist_queues);
496540f84025SJun Yang 			return NULL;
496640f84025SJun Yang 		}
496740f84025SJun Yang 	}
496840f84025SJun Yang 
496956c1817dSJun Yang 	flow = rte_zmalloc(NULL, sizeof(struct dpaa2_dev_flow),
497056c1817dSJun Yang 			   RTE_CACHE_LINE_SIZE);
4971fe2b986aSSunil Kumar Kori 	if (!flow) {
4972fe2b986aSSunil Kumar Kori 		DPAA2_PMD_ERR("Failure to allocate memory for flow");
49736a556bd6SHemant Agrawal 		goto mem_failure;
4974fe2b986aSSunil Kumar Kori 	}
497556c1817dSJun Yang 
497656c1817dSJun Yang 	/* Allocate DMA'ble memory to write the qos rules */
497725d0ae62SJun Yang 	flow->qos_key_addr = rte_zmalloc(NULL,
497825d0ae62SJun Yang 		DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
497956c1817dSJun Yang 	if (!flow->qos_key_addr) {
498056c1817dSJun Yang 		DPAA2_PMD_ERR("Memory allocation failed");
49816a556bd6SHemant Agrawal 		goto mem_failure;
4982fe2b986aSSunil Kumar Kori 	}
498325d0ae62SJun Yang 	iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->qos_key_addr,
498425d0ae62SJun Yang 			DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
498525d0ae62SJun Yang 	if (iova == RTE_BAD_IOVA) {
498625d0ae62SJun Yang 		DPAA2_PMD_ERR("%s: No IOMMU map for qos key(%p)",
498725d0ae62SJun Yang 			__func__, flow->qos_key_addr);
498825d0ae62SJun Yang 		goto mem_failure;
498925d0ae62SJun Yang 	}
499025d0ae62SJun Yang 	flow->qos_rule.key_iova = iova;
499156c1817dSJun Yang 
499225d0ae62SJun Yang 	flow->qos_mask_addr = rte_zmalloc(NULL,
499325d0ae62SJun Yang 		DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
499456c1817dSJun Yang 	if (!flow->qos_mask_addr) {
499556c1817dSJun Yang 		DPAA2_PMD_ERR("Memory allocation failed");
49966a556bd6SHemant Agrawal 		goto mem_failure;
4997fe2b986aSSunil Kumar Kori 	}
499825d0ae62SJun Yang 	iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->qos_mask_addr,
499925d0ae62SJun Yang 			DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
500025d0ae62SJun Yang 	if (iova == RTE_BAD_IOVA) {
500125d0ae62SJun Yang 		DPAA2_PMD_ERR("%s: No IOMMU map for qos mask(%p)",
500225d0ae62SJun Yang 			__func__, flow->qos_mask_addr);
500325d0ae62SJun Yang 		goto mem_failure;
500425d0ae62SJun Yang 	}
500525d0ae62SJun Yang 	flow->qos_rule.mask_iova = iova;
5006fe2b986aSSunil Kumar Kori 
500756c1817dSJun Yang 	/* Allocate DMA'ble memory to write the FS rules */
500825d0ae62SJun Yang 	flow->fs_key_addr = rte_zmalloc(NULL,
500925d0ae62SJun Yang 		DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
501056c1817dSJun Yang 	if (!flow->fs_key_addr) {
501156c1817dSJun Yang 		DPAA2_PMD_ERR("Memory allocation failed");
50125f176728SJun Yang 		goto mem_failure;
50135f176728SJun Yang 	}
501425d0ae62SJun Yang 	iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->fs_key_addr,
501525d0ae62SJun Yang 			DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
501625d0ae62SJun Yang 	if (iova == RTE_BAD_IOVA) {
501725d0ae62SJun Yang 		DPAA2_PMD_ERR("%s: No IOMMU map for fs key(%p)",
501825d0ae62SJun Yang 			__func__, flow->fs_key_addr);
501925d0ae62SJun Yang 		goto mem_failure;
502025d0ae62SJun Yang 	}
502125d0ae62SJun Yang 	flow->fs_rule.key_iova = iova;
502256c1817dSJun Yang 
502325d0ae62SJun Yang 	flow->fs_mask_addr = rte_zmalloc(NULL,
502425d0ae62SJun Yang 		DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE, RTE_CACHE_LINE_SIZE);
502556c1817dSJun Yang 	if (!flow->fs_mask_addr) {
502656c1817dSJun Yang 		DPAA2_PMD_ERR("Memory allocation failed");
50275f176728SJun Yang 		goto mem_failure;
50285f176728SJun Yang 	}
502925d0ae62SJun Yang 	iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(flow->fs_mask_addr,
503025d0ae62SJun Yang 		DPAA2_EXTRACT_ALLOC_KEY_MAX_SIZE);
503125d0ae62SJun Yang 	if (iova == RTE_BAD_IOVA) {
503225d0ae62SJun Yang 		DPAA2_PMD_ERR("%s: No IOMMU map for fs mask(%p)",
503325d0ae62SJun Yang 			__func__, flow->fs_mask_addr);
503425d0ae62SJun Yang 		goto mem_failure;
503525d0ae62SJun Yang 	}
503625d0ae62SJun Yang 	flow->fs_rule.mask_iova = iova;
50375f176728SJun Yang 
503856c1817dSJun Yang 	priv->curr = flow;
50395f176728SJun Yang 
504056c1817dSJun Yang 	ret = dpaa2_generic_flow_set(flow, dev, attr, pattern, actions, error);
5041fe2b986aSSunil Kumar Kori 	if (ret < 0) {
5042028d1dfdSJun Yang 		if (error && error->type > RTE_FLOW_ERROR_TYPE_ACTION)
50436a556bd6SHemant Agrawal 			rte_flow_error_set(error, EPERM,
50446a556bd6SHemant Agrawal 					   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
50456a556bd6SHemant Agrawal 					   attr, "unknown");
504656c1817dSJun Yang 		DPAA2_PMD_ERR("Create flow failed (%d)", ret);
5047fe2b986aSSunil Kumar Kori 		goto creation_error;
5048fe2b986aSSunil Kumar Kori 	}
5049fe2b986aSSunil Kumar Kori 
505056c1817dSJun Yang 	priv->curr = NULL;
505156c1817dSJun Yang 	return (struct rte_flow *)flow;
505256c1817dSJun Yang 
50536a556bd6SHemant Agrawal mem_failure:
505456c1817dSJun Yang 	rte_flow_error_set(error, EPERM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
505556c1817dSJun Yang 			   "memory alloc");
505656c1817dSJun Yang 
5057fe2b986aSSunil Kumar Kori creation_error:
505856c1817dSJun Yang 	if (flow) {
505956c1817dSJun Yang 		rte_free(flow->qos_key_addr);
506056c1817dSJun Yang 		rte_free(flow->qos_mask_addr);
506156c1817dSJun Yang 		rte_free(flow->fs_key_addr);
506256c1817dSJun Yang 		rte_free(flow->fs_mask_addr);
506356c1817dSJun Yang 		rte_free(flow);
506456c1817dSJun Yang 	}
506556c1817dSJun Yang 	priv->curr = NULL;
50666a556bd6SHemant Agrawal 
5067fe2b986aSSunil Kumar Kori 	return NULL;
5068fe2b986aSSunil Kumar Kori }
5069fe2b986aSSunil Kumar Kori 
507056c1817dSJun Yang static int
507156c1817dSJun Yang dpaa2_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *_flow,
50726a556bd6SHemant Agrawal 		   struct rte_flow_error *error)
5073fe2b986aSSunil Kumar Kori {
5074fe2b986aSSunil Kumar Kori 	int ret = 0;
507556c1817dSJun Yang 	struct dpaa2_dev_flow *flow;
5076fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
507756c1817dSJun Yang 	struct fsl_mc_io *dpni = priv->hw;
5078fe2b986aSSunil Kumar Kori 
507956c1817dSJun Yang 	flow = (struct dpaa2_dev_flow *)_flow;
508056c1817dSJun Yang 
508156c1817dSJun Yang 	switch (flow->action_type) {
5082fe2b986aSSunil Kumar Kori 	case RTE_FLOW_ACTION_TYPE_QUEUE:
5083b1e15294SIvan Malov 	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
5084028d1dfdSJun Yang 	case RTE_FLOW_ACTION_TYPE_PORT_ID:
508559303cdfSJun Yang 		if (priv->num_rx_tc > 1) {
5086fe2b986aSSunil Kumar Kori 			/* Remove entry from QoS table first */
508756c1817dSJun Yang 			ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW,
508856c1817dSJun Yang 						    priv->token,
50895f176728SJun Yang 						    &flow->qos_rule);
5090fe2b986aSSunil Kumar Kori 			if (ret < 0) {
509156c1817dSJun Yang 				DPAA2_PMD_ERR("Remove FS QoS entry failed");
509256c1817dSJun Yang 				dpaa2_flow_qos_entry_log("Delete failed", flow,
509356c1817dSJun Yang 							 -1);
509456c1817dSJun Yang 				abort();
5095fe2b986aSSunil Kumar Kori 				goto error;
5096fe2b986aSSunil Kumar Kori 			}
509759303cdfSJun Yang 		}
5098fe2b986aSSunil Kumar Kori 
5099fe2b986aSSunil Kumar Kori 		/* Then remove entry from FS table */
5100fe2b986aSSunil Kumar Kori 		ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW, priv->token,
51015f176728SJun Yang 					   flow->tc_id, &flow->fs_rule);
5102fe2b986aSSunil Kumar Kori 		if (ret < 0) {
510356c1817dSJun Yang 			DPAA2_PMD_ERR("Remove entry from FS[%d] failed",
510456c1817dSJun Yang 				      flow->tc_id);
5105fe2b986aSSunil Kumar Kori 			goto error;
5106fe2b986aSSunil Kumar Kori 		}
5107fe2b986aSSunil Kumar Kori 		break;
5108fe2b986aSSunil Kumar Kori 	case RTE_FLOW_ACTION_TYPE_RSS:
510959303cdfSJun Yang 		if (priv->num_rx_tc > 1) {
511056c1817dSJun Yang 			ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW,
511156c1817dSJun Yang 						    priv->token,
51125f176728SJun Yang 						    &flow->qos_rule);
5113fe2b986aSSunil Kumar Kori 			if (ret < 0) {
511456c1817dSJun Yang 				DPAA2_PMD_ERR("Remove RSS QoS entry failed");
5115fe2b986aSSunil Kumar Kori 				goto error;
5116fe2b986aSSunil Kumar Kori 			}
511759303cdfSJun Yang 		}
5118fe2b986aSSunil Kumar Kori 		break;
5119fe2b986aSSunil Kumar Kori 	default:
512056c1817dSJun Yang 		DPAA2_PMD_ERR("Action(%d) not supported", flow->action_type);
5121fe2b986aSSunil Kumar Kori 		ret = -ENOTSUP;
5122fe2b986aSSunil Kumar Kori 		break;
5123fe2b986aSSunil Kumar Kori 	}
5124fe2b986aSSunil Kumar Kori 
51256a556bd6SHemant Agrawal 	LIST_REMOVE(flow, next);
512656c1817dSJun Yang 	rte_free(flow->qos_key_addr);
512756c1817dSJun Yang 	rte_free(flow->qos_mask_addr);
512856c1817dSJun Yang 	rte_free(flow->fs_key_addr);
512956c1817dSJun Yang 	rte_free(flow->fs_mask_addr);
5130fe2b986aSSunil Kumar Kori 	/* Now free the flow */
5131fe2b986aSSunil Kumar Kori 	rte_free(flow);
5132fe2b986aSSunil Kumar Kori 
5133fe2b986aSSunil Kumar Kori error:
51346a556bd6SHemant Agrawal 	if (ret)
51356a556bd6SHemant Agrawal 		rte_flow_error_set(error, EPERM,
51366a556bd6SHemant Agrawal 				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
51376a556bd6SHemant Agrawal 				   NULL, "unknown");
5138fe2b986aSSunil Kumar Kori 	return ret;
5139fe2b986aSSunil Kumar Kori }
5140fe2b986aSSunil Kumar Kori 
51416a556bd6SHemant Agrawal /**
51426a556bd6SHemant Agrawal  * Destroy user-configured flow rules.
51436a556bd6SHemant Agrawal  *
51446a556bd6SHemant Agrawal  * This function skips internal flows rules.
51456a556bd6SHemant Agrawal  *
51466a556bd6SHemant Agrawal  * @see rte_flow_flush()
51476a556bd6SHemant Agrawal  * @see rte_flow_ops
51486a556bd6SHemant Agrawal  */
5149fe2b986aSSunil Kumar Kori static int
5150fe2b986aSSunil Kumar Kori dpaa2_flow_flush(struct rte_eth_dev *dev,
51516a556bd6SHemant Agrawal 		struct rte_flow_error *error)
5152fe2b986aSSunil Kumar Kori {
5153fe2b986aSSunil Kumar Kori 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
515456c1817dSJun Yang 	struct dpaa2_dev_flow *flow = LIST_FIRST(&priv->flows);
5155fe2b986aSSunil Kumar Kori 
51566a556bd6SHemant Agrawal 	while (flow) {
515756c1817dSJun Yang 		struct dpaa2_dev_flow *next = LIST_NEXT(flow, next);
5158fe2b986aSSunil Kumar Kori 
515956c1817dSJun Yang 		dpaa2_flow_destroy(dev, (struct rte_flow *)flow, error);
51606a556bd6SHemant Agrawal 		flow = next;
5161fe2b986aSSunil Kumar Kori 	}
51626a556bd6SHemant Agrawal 	return 0;
5163fe2b986aSSunil Kumar Kori }
5164fe2b986aSSunil Kumar Kori 
5165fe2b986aSSunil Kumar Kori static int
5166fe2b986aSSunil Kumar Kori dpaa2_flow_query(struct rte_eth_dev *dev __rte_unused,
516756c1817dSJun Yang 	struct rte_flow *_flow __rte_unused,
5168fe2b986aSSunil Kumar Kori 	const struct rte_flow_action *actions __rte_unused,
5169fe2b986aSSunil Kumar Kori 	void *data __rte_unused,
5170fe2b986aSSunil Kumar Kori 	struct rte_flow_error *error __rte_unused)
5171fe2b986aSSunil Kumar Kori {
5172fe2b986aSSunil Kumar Kori 	return 0;
5173fe2b986aSSunil Kumar Kori }
5174fe2b986aSSunil Kumar Kori 
51756a556bd6SHemant Agrawal /**
51766a556bd6SHemant Agrawal  * Clean up all flow rules.
51776a556bd6SHemant Agrawal  *
51786a556bd6SHemant Agrawal  * Unlike dpaa2_flow_flush(), this function takes care of all remaining flow
51796a556bd6SHemant Agrawal  * rules regardless of whether they are internal or user-configured.
51806a556bd6SHemant Agrawal  *
51816a556bd6SHemant Agrawal  * @param priv
51826a556bd6SHemant Agrawal  *   Pointer to private structure.
51836a556bd6SHemant Agrawal  */
51846a556bd6SHemant Agrawal void
51856a556bd6SHemant Agrawal dpaa2_flow_clean(struct rte_eth_dev *dev)
51866a556bd6SHemant Agrawal {
518756c1817dSJun Yang 	struct dpaa2_dev_flow *flow;
51886a556bd6SHemant Agrawal 	struct dpaa2_dev_priv *priv = dev->data->dev_private;
51896a556bd6SHemant Agrawal 
51906a556bd6SHemant Agrawal 	while ((flow = LIST_FIRST(&priv->flows)))
519156c1817dSJun Yang 		dpaa2_flow_destroy(dev, (struct rte_flow *)flow, NULL);
51926a556bd6SHemant Agrawal }
51936a556bd6SHemant Agrawal 
5194fe2b986aSSunil Kumar Kori const struct rte_flow_ops dpaa2_flow_ops = {
5195fe2b986aSSunil Kumar Kori 	.create	= dpaa2_flow_create,
5196fe2b986aSSunil Kumar Kori 	.validate = dpaa2_flow_validate,
5197fe2b986aSSunil Kumar Kori 	.destroy = dpaa2_flow_destroy,
5198fe2b986aSSunil Kumar Kori 	.flush	= dpaa2_flow_flush,
5199fe2b986aSSunil Kumar Kori 	.query	= dpaa2_flow_query,
5200fe2b986aSSunil Kumar Kori };
5201