xref: /dpdk/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c (revision 03ab51eafda992874a48c392ca66ffb577fe2b71)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2021 Broadcom
3  * All rights reserved.
4  */
5 
6 #include "bnxt.h"
7 #include "ulp_template_db_enum.h"
8 #include "ulp_template_struct.h"
9 #include "bnxt_ulp.h"
10 #include "bnxt_tf_common.h"
11 #include "bnxt_tf_pmd_shim.h"
12 #include "ulp_rte_parser.h"
13 #include "ulp_matcher.h"
14 #include "ulp_utils.h"
15 #include "tfp.h"
16 #include "ulp_port_db.h"
17 #include "ulp_flow_db.h"
18 #include "ulp_mapper.h"
19 #include "ulp_tun.h"
20 #include "ulp_template_db_tbl.h"
21 
22 /* Local defines for the parsing functions */
23 #define ULP_VLAN_PRIORITY_SHIFT		13 /* First 3 bits */
24 #define ULP_VLAN_PRIORITY_MASK		0x700
25 #define ULP_VLAN_TAG_MASK		0xFFF /* Last 12 bits*/
26 #define ULP_UDP_PORT_VXLAN		4789
27 
28 /* Utility function to skip the void items. */
29 static inline int32_t
30 ulp_rte_item_skip_void(const struct rte_flow_item **item, uint32_t increment)
31 {
32 	if (!*item)
33 		return 0;
34 	if (increment)
35 		(*item)++;
36 	while ((*item) && (*item)->type == RTE_FLOW_ITEM_TYPE_VOID)
37 		(*item)++;
38 	if (*item)
39 		return 1;
40 	return 0;
41 }
42 
43 /* Utility function to copy field spec items */
44 static struct ulp_rte_hdr_field *
45 ulp_rte_parser_fld_copy(struct ulp_rte_hdr_field *field,
46 			const void *buffer,
47 			uint32_t size)
48 {
49 	field->size = size;
50 	memcpy(field->spec, buffer, field->size);
51 	field++;
52 	return field;
53 }
54 
55 /* Utility function to update the field_bitmap */
56 static void
57 ulp_rte_parser_field_bitmap_update(struct ulp_rte_parser_params *params,
58 				   uint32_t idx,
59 				   enum bnxt_ulp_prsr_action prsr_act)
60 {
61 	struct ulp_rte_hdr_field *field;
62 
63 	field = &params->hdr_field[idx];
64 	if (ulp_bitmap_notzero(field->mask, field->size)) {
65 		ULP_INDEX_BITMAP_SET(params->fld_bitmap.bits, idx);
66 		if (!(prsr_act & ULP_PRSR_ACT_MATCH_IGNORE))
67 			ULP_INDEX_BITMAP_SET(params->fld_s_bitmap.bits, idx);
68 		/* Not exact match */
69 		if (!ulp_bitmap_is_ones(field->mask, field->size))
70 			ULP_COMP_FLD_IDX_WR(params,
71 					    BNXT_ULP_CF_IDX_WC_MATCH, 1);
72 	} else {
73 		ULP_INDEX_BITMAP_RESET(params->fld_bitmap.bits, idx);
74 	}
75 }
76 
77 #define ulp_deference_struct(x, y) ((x) ? &((x)->y) : NULL)
78 /* Utility function to copy field spec and masks items */
79 static void
80 ulp_rte_prsr_fld_mask(struct ulp_rte_parser_params *params,
81 		      uint32_t *idx,
82 		      uint32_t size,
83 		      const void *spec_buff,
84 		      const void *mask_buff,
85 		      enum bnxt_ulp_prsr_action prsr_act)
86 {
87 	struct ulp_rte_hdr_field *field = &params->hdr_field[*idx];
88 
89 	/* update the field size */
90 	field->size = size;
91 
92 	/* copy the mask specifications only if mask is not null */
93 	if (!(prsr_act & ULP_PRSR_ACT_MASK_IGNORE) && mask_buff) {
94 		memcpy(field->mask, mask_buff, size);
95 		ulp_rte_parser_field_bitmap_update(params, *idx, prsr_act);
96 	}
97 
98 	/* copy the protocol specifications only if mask is not null*/
99 	if (spec_buff && mask_buff && ulp_bitmap_notzero(mask_buff, size))
100 		memcpy(field->spec, spec_buff, size);
101 
102 	/* Increment the index */
103 	*idx = *idx + 1;
104 }
105 
106 /* Utility function to copy field spec and masks items */
107 static int32_t
108 ulp_rte_prsr_fld_size_validate(struct ulp_rte_parser_params *params,
109 			       uint32_t *idx,
110 			       uint32_t size)
111 {
112 	if (params->field_idx + size >= BNXT_ULP_PROTO_HDR_MAX) {
113 		BNXT_TF_DBG(ERR, "OOB for field processing %u\n", *idx);
114 		return -EINVAL;
115 	}
116 	*idx = params->field_idx;
117 	params->field_idx += size;
118 	return 0;
119 }
120 
121 /*
122  * Function to handle the parsing of RTE Flows and placing
123  * the RTE flow items into the ulp structures.
124  */
125 int32_t
126 bnxt_ulp_rte_parser_hdr_parse(const struct rte_flow_item pattern[],
127 			      struct ulp_rte_parser_params *params)
128 {
129 	const struct rte_flow_item *item = pattern;
130 	struct bnxt_ulp_rte_hdr_info *hdr_info;
131 
132 	params->field_idx = BNXT_ULP_PROTO_HDR_SVIF_NUM;
133 
134 	/* Set the computed flags for no vlan tags before parsing */
135 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_NO_VTAG, 1);
136 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_NO_VTAG, 1);
137 
138 	/* Parse all the items in the pattern */
139 	while (item && item->type != RTE_FLOW_ITEM_TYPE_END) {
140 		if (item->type >= (uint32_t)
141 		    BNXT_RTE_FLOW_ITEM_TYPE_END) {
142 			if (item->type >=
143 			    (uint32_t)BNXT_RTE_FLOW_ITEM_TYPE_LAST)
144 				goto hdr_parser_error;
145 			/* get the header information */
146 			hdr_info = &ulp_vendor_hdr_info[item->type -
147 				BNXT_RTE_FLOW_ITEM_TYPE_END];
148 		} else {
149 			if (item->type > RTE_FLOW_ITEM_TYPE_HIGIG2)
150 				goto hdr_parser_error;
151 			hdr_info = &ulp_hdr_info[item->type];
152 		}
153 		if (hdr_info->hdr_type == BNXT_ULP_HDR_TYPE_NOT_SUPPORTED) {
154 			goto hdr_parser_error;
155 		} else if (hdr_info->hdr_type == BNXT_ULP_HDR_TYPE_SUPPORTED) {
156 			/* call the registered callback handler */
157 			if (hdr_info->proto_hdr_func) {
158 				if (hdr_info->proto_hdr_func(item, params) !=
159 				    BNXT_TF_RC_SUCCESS) {
160 					return BNXT_TF_RC_ERROR;
161 				}
162 			}
163 		}
164 		item++;
165 	}
166 	/* update the implied SVIF */
167 	return ulp_rte_parser_implicit_match_port_process(params);
168 
169 hdr_parser_error:
170 	BNXT_TF_DBG(ERR, "Truflow parser does not support type %d\n",
171 		    item->type);
172 	return BNXT_TF_RC_PARSE_ERR;
173 }
174 
175 /*
176  * Function to handle the parsing of RTE Flows and placing
177  * the RTE flow actions into the ulp structures.
178  */
179 int32_t
180 bnxt_ulp_rte_parser_act_parse(const struct rte_flow_action actions[],
181 			      struct ulp_rte_parser_params *params)
182 {
183 	const struct rte_flow_action *action_item = actions;
184 	struct bnxt_ulp_rte_act_info *hdr_info;
185 
186 	/* Parse all the items in the pattern */
187 	while (action_item && action_item->type != RTE_FLOW_ACTION_TYPE_END) {
188 		if (action_item->type >=
189 		    (uint32_t)BNXT_RTE_FLOW_ACTION_TYPE_END) {
190 			if (action_item->type >=
191 			    (uint32_t)BNXT_RTE_FLOW_ACTION_TYPE_LAST)
192 				goto act_parser_error;
193 			/* get the header information from bnxt actinfo table */
194 			hdr_info = &ulp_vendor_act_info[action_item->type -
195 				BNXT_RTE_FLOW_ACTION_TYPE_END];
196 		} else {
197 			if (action_item->type > RTE_FLOW_ACTION_TYPE_SHARED)
198 				goto act_parser_error;
199 			/* get the header information from the act info table */
200 			hdr_info = &ulp_act_info[action_item->type];
201 		}
202 		if (hdr_info->act_type == BNXT_ULP_ACT_TYPE_NOT_SUPPORTED) {
203 			goto act_parser_error;
204 		} else if (hdr_info->act_type == BNXT_ULP_ACT_TYPE_SUPPORTED) {
205 			/* call the registered callback handler */
206 			if (hdr_info->proto_act_func) {
207 				if (hdr_info->proto_act_func(action_item,
208 							     params) !=
209 				    BNXT_TF_RC_SUCCESS) {
210 					return BNXT_TF_RC_ERROR;
211 				}
212 			}
213 		}
214 		action_item++;
215 	}
216 	/* update the implied port details */
217 	ulp_rte_parser_implicit_act_port_process(params);
218 	return BNXT_TF_RC_SUCCESS;
219 
220 act_parser_error:
221 	BNXT_TF_DBG(ERR, "Truflow parser does not support act %u\n",
222 		    action_item->type);
223 	return BNXT_TF_RC_ERROR;
224 }
225 
226 /*
227  * Function to handle the post processing of the computed
228  * fields for the interface.
229  */
230 static void
231 bnxt_ulp_comp_fld_intf_update(struct ulp_rte_parser_params *params)
232 {
233 	uint32_t ifindex;
234 	uint16_t port_id, parif;
235 	uint32_t mtype;
236 	enum bnxt_ulp_direction_type dir;
237 
238 	/* get the direction details */
239 	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
240 
241 	/* read the port id details */
242 	port_id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
243 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
244 					      port_id,
245 					      &ifindex)) {
246 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
247 		return;
248 	}
249 
250 	if (dir == BNXT_ULP_DIR_INGRESS) {
251 		/* Set port PARIF */
252 		if (ulp_port_db_parif_get(params->ulp_ctx, ifindex,
253 					  BNXT_ULP_PHY_PORT_PARIF, &parif)) {
254 			BNXT_TF_DBG(ERR, "ParseErr:ifindex is not valid\n");
255 			return;
256 		}
257 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_PHY_PORT_PARIF,
258 				    parif);
259 	} else {
260 		/* Get the match port type */
261 		mtype = ULP_COMP_FLD_IDX_RD(params,
262 					    BNXT_ULP_CF_IDX_MATCH_PORT_TYPE);
263 		if (mtype == BNXT_ULP_INTF_TYPE_VF_REP) {
264 			ULP_COMP_FLD_IDX_WR(params,
265 					    BNXT_ULP_CF_IDX_MATCH_PORT_IS_VFREP,
266 					    1);
267 			/* Set VF func PARIF */
268 			if (ulp_port_db_parif_get(params->ulp_ctx, ifindex,
269 						  BNXT_ULP_VF_FUNC_PARIF,
270 						  &parif)) {
271 				BNXT_TF_DBG(ERR,
272 					    "ParseErr:ifindex is not valid\n");
273 				return;
274 			}
275 			ULP_COMP_FLD_IDX_WR(params,
276 					    BNXT_ULP_CF_IDX_VF_FUNC_PARIF,
277 					    parif);
278 
279 		} else {
280 			/* Set DRV func PARIF */
281 			if (ulp_port_db_parif_get(params->ulp_ctx, ifindex,
282 						  BNXT_ULP_DRV_FUNC_PARIF,
283 						  &parif)) {
284 				BNXT_TF_DBG(ERR,
285 					    "ParseErr:ifindex is not valid\n");
286 				return;
287 			}
288 			ULP_COMP_FLD_IDX_WR(params,
289 					    BNXT_ULP_CF_IDX_DRV_FUNC_PARIF,
290 					    parif);
291 		}
292 		if (mtype == BNXT_ULP_INTF_TYPE_PF) {
293 			ULP_COMP_FLD_IDX_WR(params,
294 					    BNXT_ULP_CF_IDX_MATCH_PORT_IS_PF,
295 					    1);
296 		}
297 	}
298 }
299 
300 static int32_t
301 ulp_post_process_normal_flow(struct ulp_rte_parser_params *params)
302 {
303 	enum bnxt_ulp_intf_type match_port_type, act_port_type;
304 	enum bnxt_ulp_direction_type dir;
305 	uint32_t act_port_set;
306 
307 	/* Get the computed details */
308 	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
309 	match_port_type = ULP_COMP_FLD_IDX_RD(params,
310 					      BNXT_ULP_CF_IDX_MATCH_PORT_TYPE);
311 	act_port_type = ULP_COMP_FLD_IDX_RD(params,
312 					    BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
313 	act_port_set = ULP_COMP_FLD_IDX_RD(params,
314 					   BNXT_ULP_CF_IDX_ACT_PORT_IS_SET);
315 
316 	/* set the flow direction in the proto and action header */
317 	if (dir == BNXT_ULP_DIR_EGRESS) {
318 		ULP_BITMAP_SET(params->hdr_bitmap.bits,
319 			       BNXT_ULP_FLOW_DIR_BITMASK_EGR);
320 		ULP_BITMAP_SET(params->act_bitmap.bits,
321 			       BNXT_ULP_FLOW_DIR_BITMASK_EGR);
322 	}
323 
324 	/* calculate the VF to VF flag */
325 	if (act_port_set && act_port_type == BNXT_ULP_INTF_TYPE_VF_REP &&
326 	    match_port_type == BNXT_ULP_INTF_TYPE_VF_REP)
327 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_VF_TO_VF, 1);
328 
329 	/* Update the decrement ttl computational fields */
330 	if (ULP_BITMAP_ISSET(params->act_bitmap.bits,
331 			     BNXT_ULP_ACT_BIT_DEC_TTL)) {
332 		/*
333 		 * Check that vxlan proto is included and vxlan decap
334 		 * action is not set then decrement tunnel ttl.
335 		 * Similarly add GRE and NVGRE in future.
336 		 */
337 		if ((ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
338 				      BNXT_ULP_HDR_BIT_T_VXLAN) &&
339 		    !ULP_BITMAP_ISSET(params->act_bitmap.bits,
340 				      BNXT_ULP_ACT_BIT_VXLAN_DECAP))) {
341 			ULP_COMP_FLD_IDX_WR(params,
342 					    BNXT_ULP_CF_IDX_ACT_T_DEC_TTL, 1);
343 		} else {
344 			ULP_COMP_FLD_IDX_WR(params,
345 					    BNXT_ULP_CF_IDX_ACT_DEC_TTL, 1);
346 		}
347 	}
348 
349 	/* Merge the hdr_fp_bit into the proto header bit */
350 	params->hdr_bitmap.bits |= params->hdr_fp_bit.bits;
351 
352 	/* Update the comp fld fid */
353 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_FID, params->fid);
354 
355 	/* Update the computed interface parameters */
356 	bnxt_ulp_comp_fld_intf_update(params);
357 
358 	/* TBD: Handle the flow rejection scenarios */
359 	return 0;
360 }
361 
362 /*
363  * Function to handle the post processing of the parsing details
364  */
365 void
366 bnxt_ulp_rte_parser_post_process(struct ulp_rte_parser_params *params)
367 {
368 	ulp_post_process_normal_flow(params);
369 }
370 
371 /*
372  * Function to compute the flow direction based on the match port details
373  */
374 static void
375 bnxt_ulp_rte_parser_direction_compute(struct ulp_rte_parser_params *params)
376 {
377 	enum bnxt_ulp_intf_type match_port_type;
378 
379 	/* Get the match port type */
380 	match_port_type = ULP_COMP_FLD_IDX_RD(params,
381 					      BNXT_ULP_CF_IDX_MATCH_PORT_TYPE);
382 
383 	/* If ingress flow and matchport is vf rep then dir is egress*/
384 	if ((params->dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS) &&
385 	    match_port_type == BNXT_ULP_INTF_TYPE_VF_REP) {
386 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_DIRECTION,
387 				    BNXT_ULP_DIR_EGRESS);
388 	} else {
389 		/* Assign the input direction */
390 		if (params->dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS)
391 			ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_DIRECTION,
392 					    BNXT_ULP_DIR_INGRESS);
393 		else
394 			ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_DIRECTION,
395 					    BNXT_ULP_DIR_EGRESS);
396 	}
397 }
398 
399 /* Function to handle the parsing of RTE Flow item PF Header. */
400 static int32_t
401 ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,
402 			uint32_t ifindex,
403 			uint16_t mask)
404 {
405 	uint16_t svif;
406 	enum bnxt_ulp_direction_type dir;
407 	struct ulp_rte_hdr_field *hdr_field;
408 	enum bnxt_ulp_svif_type svif_type;
409 	enum bnxt_ulp_intf_type port_type;
410 
411 	if (ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_SVIF_FLAG) !=
412 	    BNXT_ULP_INVALID_SVIF_VAL) {
413 		BNXT_TF_DBG(ERR,
414 			    "SVIF already set,multiple source not support'd\n");
415 		return BNXT_TF_RC_ERROR;
416 	}
417 
418 	/* Get port type details */
419 	port_type = ulp_port_db_port_type_get(params->ulp_ctx, ifindex);
420 	if (port_type == BNXT_ULP_INTF_TYPE_INVALID) {
421 		BNXT_TF_DBG(ERR, "Invalid port type\n");
422 		return BNXT_TF_RC_ERROR;
423 	}
424 
425 	/* Update the match port type */
426 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_MATCH_PORT_TYPE, port_type);
427 
428 	/* compute the direction */
429 	bnxt_ulp_rte_parser_direction_compute(params);
430 
431 	/* Get the computed direction */
432 	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
433 	if (dir == BNXT_ULP_DIR_INGRESS) {
434 		svif_type = BNXT_ULP_PHY_PORT_SVIF;
435 	} else {
436 		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
437 			svif_type = BNXT_ULP_VF_FUNC_SVIF;
438 		else
439 			svif_type = BNXT_ULP_DRV_FUNC_SVIF;
440 	}
441 	ulp_port_db_svif_get(params->ulp_ctx, ifindex, svif_type,
442 			     &svif);
443 	svif = rte_cpu_to_be_16(svif);
444 	hdr_field = &params->hdr_field[BNXT_ULP_PROTO_HDR_FIELD_SVIF_IDX];
445 	memcpy(hdr_field->spec, &svif, sizeof(svif));
446 	memcpy(hdr_field->mask, &mask, sizeof(mask));
447 	hdr_field->size = sizeof(svif);
448 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_SVIF_FLAG,
449 			    rte_be_to_cpu_16(svif));
450 	return BNXT_TF_RC_SUCCESS;
451 }
452 
453 /* Function to handle the parsing of the RTE port id */
454 int32_t
455 ulp_rte_parser_implicit_match_port_process(struct ulp_rte_parser_params *params)
456 {
457 	uint16_t port_id = 0;
458 	uint16_t svif_mask = 0xFFFF;
459 	uint32_t ifindex;
460 	int32_t rc = BNXT_TF_RC_ERROR;
461 
462 	if (ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_SVIF_FLAG) !=
463 	    BNXT_ULP_INVALID_SVIF_VAL)
464 		return BNXT_TF_RC_SUCCESS;
465 
466 	/* SVIF not set. So get the port id */
467 	port_id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
468 
469 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
470 					      port_id,
471 					      &ifindex)) {
472 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
473 		return rc;
474 	}
475 
476 	/* Update the SVIF details */
477 	rc = ulp_rte_parser_svif_set(params, ifindex, svif_mask);
478 	return rc;
479 }
480 
481 /* Function to handle the implicit action port id */
482 int32_t
483 ulp_rte_parser_implicit_act_port_process(struct ulp_rte_parser_params *params)
484 {
485 	struct rte_flow_action action_item = {0};
486 	struct rte_flow_action_port_id port_id = {0};
487 
488 	/* Read the action port set bit */
489 	if (ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET)) {
490 		/* Already set, so just exit */
491 		return BNXT_TF_RC_SUCCESS;
492 	}
493 	port_id.id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
494 	action_item.conf = &port_id;
495 
496 	/* Update the action port based on incoming port */
497 	ulp_rte_port_id_act_handler(&action_item, params);
498 
499 	/* Reset the action port set bit */
500 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET, 0);
501 	return BNXT_TF_RC_SUCCESS;
502 }
503 
504 /* Function to handle the parsing of RTE Flow item PF Header. */
505 int32_t
506 ulp_rte_pf_hdr_handler(const struct rte_flow_item *item __rte_unused,
507 		       struct ulp_rte_parser_params *params)
508 {
509 	uint16_t port_id = 0;
510 	uint16_t svif_mask = 0xFFFF;
511 	uint32_t ifindex;
512 
513 	/* Get the implicit port id */
514 	port_id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
515 
516 	/* perform the conversion from dpdk port to bnxt ifindex */
517 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
518 					      port_id,
519 					      &ifindex)) {
520 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
521 		return BNXT_TF_RC_ERROR;
522 	}
523 
524 	/* Update the SVIF details */
525 	return  ulp_rte_parser_svif_set(params, ifindex, svif_mask);
526 }
527 
528 /* Function to handle the parsing of RTE Flow item VF Header. */
529 int32_t
530 ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,
531 		       struct ulp_rte_parser_params *params)
532 {
533 	const struct rte_flow_item_vf *vf_spec = item->spec;
534 	const struct rte_flow_item_vf *vf_mask = item->mask;
535 	uint16_t mask = 0;
536 	uint32_t ifindex;
537 	int32_t rc = BNXT_TF_RC_PARSE_ERR;
538 
539 	/* Get VF rte_flow_item for Port details */
540 	if (!vf_spec) {
541 		BNXT_TF_DBG(ERR, "ParseErr:VF id is not valid\n");
542 		return rc;
543 	}
544 	if (!vf_mask) {
545 		BNXT_TF_DBG(ERR, "ParseErr:VF mask is not valid\n");
546 		return rc;
547 	}
548 	mask = vf_mask->id;
549 
550 	/* perform the conversion from VF Func id to bnxt ifindex */
551 	if (ulp_port_db_dev_func_id_to_ulp_index(params->ulp_ctx,
552 						 vf_spec->id,
553 						 &ifindex)) {
554 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
555 		return rc;
556 	}
557 	/* Update the SVIF details */
558 	return ulp_rte_parser_svif_set(params, ifindex, mask);
559 }
560 
561 /* Function to handle the parsing of RTE Flow item port id  Header. */
562 int32_t
563 ulp_rte_port_id_hdr_handler(const struct rte_flow_item *item,
564 			    struct ulp_rte_parser_params *params)
565 {
566 	const struct rte_flow_item_port_id *port_spec = item->spec;
567 	const struct rte_flow_item_port_id *port_mask = item->mask;
568 	uint16_t mask = 0;
569 	int32_t rc = BNXT_TF_RC_PARSE_ERR;
570 	uint32_t ifindex;
571 
572 	if (!port_spec) {
573 		BNXT_TF_DBG(ERR, "ParseErr:Port id is not valid\n");
574 		return rc;
575 	}
576 	if (!port_mask) {
577 		BNXT_TF_DBG(ERR, "ParseErr:Phy Port mask is not valid\n");
578 		return rc;
579 	}
580 	mask = port_mask->id;
581 
582 	/* perform the conversion from dpdk port to bnxt ifindex */
583 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
584 					      port_spec->id,
585 					      &ifindex)) {
586 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
587 		return rc;
588 	}
589 	/* Update the SVIF details */
590 	return ulp_rte_parser_svif_set(params, ifindex, mask);
591 }
592 
593 /* Function to handle the parsing of RTE Flow item phy port Header. */
594 int32_t
595 ulp_rte_phy_port_hdr_handler(const struct rte_flow_item *item,
596 			     struct ulp_rte_parser_params *params)
597 {
598 	const struct rte_flow_item_phy_port *port_spec = item->spec;
599 	const struct rte_flow_item_phy_port *port_mask = item->mask;
600 	uint16_t mask = 0;
601 	int32_t rc = BNXT_TF_RC_ERROR;
602 	uint16_t svif;
603 	enum bnxt_ulp_direction_type dir;
604 	struct ulp_rte_hdr_field *hdr_field;
605 
606 	/* Copy the rte_flow_item for phy port into hdr_field */
607 	if (!port_spec) {
608 		BNXT_TF_DBG(ERR, "ParseErr:Phy Port id is not valid\n");
609 		return rc;
610 	}
611 	if (!port_mask) {
612 		BNXT_TF_DBG(ERR, "ParseErr:Phy Port mask is not valid\n");
613 		return rc;
614 	}
615 	mask = port_mask->index;
616 
617 	/* Update the match port type */
618 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_MATCH_PORT_TYPE,
619 			    BNXT_ULP_INTF_TYPE_PHY_PORT);
620 
621 	/* Compute the Hw direction */
622 	bnxt_ulp_rte_parser_direction_compute(params);
623 
624 	/* Direction validation */
625 	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
626 	if (dir == BNXT_ULP_DIR_EGRESS) {
627 		BNXT_TF_DBG(ERR,
628 			    "Parse Err:Phy ports are valid only for ingress\n");
629 		return BNXT_TF_RC_PARSE_ERR;
630 	}
631 
632 	/* Get the physical port details from port db */
633 	rc = ulp_port_db_phy_port_svif_get(params->ulp_ctx, port_spec->index,
634 					   &svif);
635 	if (rc) {
636 		BNXT_TF_DBG(ERR, "Failed to get port details\n");
637 		return BNXT_TF_RC_PARSE_ERR;
638 	}
639 
640 	/* Update the SVIF details */
641 	svif = rte_cpu_to_be_16(svif);
642 	hdr_field = &params->hdr_field[BNXT_ULP_PROTO_HDR_FIELD_SVIF_IDX];
643 	memcpy(hdr_field->spec, &svif, sizeof(svif));
644 	memcpy(hdr_field->mask, &mask, sizeof(mask));
645 	hdr_field->size = sizeof(svif);
646 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_SVIF_FLAG,
647 			    rte_be_to_cpu_16(svif));
648 	return BNXT_TF_RC_SUCCESS;
649 }
650 
651 /* Function to handle the update of proto header based on field values */
652 static void
653 ulp_rte_l2_proto_type_update(struct ulp_rte_parser_params *param,
654 			     uint16_t type, uint32_t in_flag)
655 {
656 	if (type == tfp_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {
657 		if (in_flag) {
658 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
659 				       BNXT_ULP_HDR_BIT_I_IPV4);
660 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_I_L3, 1);
661 		} else {
662 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
663 				       BNXT_ULP_HDR_BIT_O_IPV4);
664 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_O_L3, 1);
665 		}
666 	} else if (type == tfp_cpu_to_be_16(RTE_ETHER_TYPE_IPV6))  {
667 		if (in_flag) {
668 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
669 				       BNXT_ULP_HDR_BIT_I_IPV6);
670 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_I_L3, 1);
671 		} else {
672 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
673 				       BNXT_ULP_HDR_BIT_O_IPV6);
674 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_O_L3, 1);
675 		}
676 	}
677 }
678 
679 /* Internal Function to identify broadcast or multicast packets */
680 static int32_t
681 ulp_rte_parser_is_bcmc_addr(const struct rte_ether_addr *eth_addr)
682 {
683 	if (rte_is_multicast_ether_addr(eth_addr) ||
684 	    rte_is_broadcast_ether_addr(eth_addr)) {
685 		BNXT_TF_DBG(DEBUG,
686 			    "No support for bcast or mcast addr offload\n");
687 		return 1;
688 	}
689 	return 0;
690 }
691 
692 /* Function to handle the parsing of RTE Flow item Ethernet Header. */
693 int32_t
694 ulp_rte_eth_hdr_handler(const struct rte_flow_item *item,
695 			struct ulp_rte_parser_params *params)
696 {
697 	const struct rte_flow_item_eth *eth_spec = item->spec;
698 	const struct rte_flow_item_eth *eth_mask = item->mask;
699 	uint32_t idx = 0, dmac_idx = 0;
700 	uint32_t size;
701 	uint16_t eth_type = 0;
702 	uint32_t inner_flag = 0;
703 
704 	/* Perform validations */
705 	if (eth_spec) {
706 		/* Todo: work around to avoid multicast and broadcast addr */
707 		if (ulp_rte_parser_is_bcmc_addr(&eth_spec->dst))
708 			return BNXT_TF_RC_PARSE_ERR;
709 
710 		if (ulp_rte_parser_is_bcmc_addr(&eth_spec->src))
711 			return BNXT_TF_RC_PARSE_ERR;
712 
713 		eth_type = eth_spec->type;
714 	}
715 
716 	if (ulp_rte_prsr_fld_size_validate(params, &idx,
717 					   BNXT_ULP_PROTO_HDR_ETH_NUM)) {
718 		BNXT_TF_DBG(ERR, "Error parsing protocol header\n");
719 		return BNXT_TF_RC_ERROR;
720 	}
721 	/*
722 	 * Copy the rte_flow_item for eth into hdr_field using ethernet
723 	 * header fields
724 	 */
725 	dmac_idx = idx;
726 	size = sizeof(((struct rte_flow_item_eth *)NULL)->dst.addr_bytes);
727 	ulp_rte_prsr_fld_mask(params, &idx, size,
728 			      ulp_deference_struct(eth_spec, dst.addr_bytes),
729 			      ulp_deference_struct(eth_mask, dst.addr_bytes),
730 			      ULP_PRSR_ACT_DEFAULT);
731 
732 	size = sizeof(((struct rte_flow_item_eth *)NULL)->src.addr_bytes);
733 	ulp_rte_prsr_fld_mask(params, &idx, size,
734 			      ulp_deference_struct(eth_spec, src.addr_bytes),
735 			      ulp_deference_struct(eth_mask, src.addr_bytes),
736 			      ULP_PRSR_ACT_DEFAULT);
737 
738 	size = sizeof(((struct rte_flow_item_eth *)NULL)->type);
739 	ulp_rte_prsr_fld_mask(params, &idx, size,
740 			      ulp_deference_struct(eth_spec, type),
741 			      ulp_deference_struct(eth_mask, type),
742 			      ULP_PRSR_ACT_MATCH_IGNORE);
743 
744 	/* Update the protocol hdr bitmap */
745 	if (ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
746 			     BNXT_ULP_HDR_BIT_O_ETH) ||
747 	    ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
748 			     BNXT_ULP_HDR_BIT_O_IPV4) ||
749 	    ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
750 			     BNXT_ULP_HDR_BIT_O_IPV6) ||
751 	    ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
752 			     BNXT_ULP_HDR_BIT_O_UDP) ||
753 	    ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
754 			     BNXT_ULP_HDR_BIT_O_TCP)) {
755 		ULP_BITMAP_SET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_I_ETH);
756 		inner_flag = 1;
757 	} else {
758 		ULP_BITMAP_SET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_O_ETH);
759 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_TUN_OFF_DMAC_ID,
760 				    dmac_idx);
761 	}
762 	/* Update the field protocol hdr bitmap */
763 	ulp_rte_l2_proto_type_update(params, eth_type, inner_flag);
764 
765 	return BNXT_TF_RC_SUCCESS;
766 }
767 
768 /* Function to handle the parsing of RTE Flow item Vlan Header. */
769 int32_t
770 ulp_rte_vlan_hdr_handler(const struct rte_flow_item *item,
771 			 struct ulp_rte_parser_params *params)
772 {
773 	const struct rte_flow_item_vlan *vlan_spec = item->spec;
774 	const struct rte_flow_item_vlan *vlan_mask = item->mask;
775 	struct ulp_rte_hdr_bitmap	*hdr_bit;
776 	uint32_t idx = 0;
777 	uint16_t vlan_tag = 0, priority = 0;
778 	uint16_t vlan_tag_mask = 0, priority_mask = 0;
779 	uint32_t outer_vtag_num;
780 	uint32_t inner_vtag_num;
781 	uint16_t eth_type = 0;
782 	uint32_t inner_flag = 0;
783 	uint32_t size;
784 
785 	if (vlan_spec) {
786 		vlan_tag = ntohs(vlan_spec->tci);
787 		priority = htons(vlan_tag >> ULP_VLAN_PRIORITY_SHIFT);
788 		vlan_tag &= ULP_VLAN_TAG_MASK;
789 		vlan_tag = htons(vlan_tag);
790 		eth_type = vlan_spec->inner_type;
791 	}
792 
793 	if (vlan_mask) {
794 		vlan_tag_mask = ntohs(vlan_mask->tci);
795 		priority_mask = htons(vlan_tag_mask >> ULP_VLAN_PRIORITY_SHIFT);
796 		vlan_tag_mask &= 0xfff;
797 
798 		/*
799 		 * the storage for priority and vlan tag is 2 bytes
800 		 * The mask of priority which is 3 bits if it is all 1's
801 		 * then make the rest bits 13 bits as 1's
802 		 * so that it is matched as exact match.
803 		 */
804 		if (priority_mask == ULP_VLAN_PRIORITY_MASK)
805 			priority_mask |= ~ULP_VLAN_PRIORITY_MASK;
806 		if (vlan_tag_mask == ULP_VLAN_TAG_MASK)
807 			vlan_tag_mask |= ~ULP_VLAN_TAG_MASK;
808 		vlan_tag_mask = htons(vlan_tag_mask);
809 	}
810 
811 	if (ulp_rte_prsr_fld_size_validate(params, &idx,
812 					   BNXT_ULP_PROTO_HDR_S_VLAN_NUM)) {
813 		BNXT_TF_DBG(ERR, "Error parsing protocol header\n");
814 		return BNXT_TF_RC_ERROR;
815 	}
816 
817 	/*
818 	 * Copy the rte_flow_item for vlan into hdr_field using Vlan
819 	 * header fields
820 	 */
821 	size = sizeof(((struct rte_flow_item_vlan *)NULL)->tci);
822 	/*
823 	 * The priority field is ignored since OVS is setting it as
824 	 * wild card match and it is not supported. This is a work
825 	 * around and shall be addressed in the future.
826 	 */
827 	ulp_rte_prsr_fld_mask(params, &idx, size,
828 			      &priority,
829 			      (vlan_mask) ? &priority_mask : NULL,
830 			      ULP_PRSR_ACT_MASK_IGNORE);
831 
832 	ulp_rte_prsr_fld_mask(params, &idx, size,
833 			      &vlan_tag,
834 			      (vlan_mask) ? &vlan_tag_mask : NULL,
835 			      ULP_PRSR_ACT_DEFAULT);
836 
837 	size = sizeof(((struct rte_flow_item_vlan *)NULL)->inner_type);
838 	ulp_rte_prsr_fld_mask(params, &idx, size,
839 			      ulp_deference_struct(vlan_spec, inner_type),
840 			      ulp_deference_struct(vlan_mask, inner_type),
841 			      ULP_PRSR_ACT_MATCH_IGNORE);
842 
843 	/* Get the outer tag and inner tag counts */
844 	outer_vtag_num = ULP_COMP_FLD_IDX_RD(params,
845 					     BNXT_ULP_CF_IDX_O_VTAG_NUM);
846 	inner_vtag_num = ULP_COMP_FLD_IDX_RD(params,
847 					     BNXT_ULP_CF_IDX_I_VTAG_NUM);
848 
849 	/* Update the hdr_bitmap of the vlans */
850 	hdr_bit = &params->hdr_bitmap;
851 	if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
852 	    !ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_I_ETH) &&
853 	    !outer_vtag_num) {
854 		/* Update the vlan tag num */
855 		outer_vtag_num++;
856 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_VTAG_NUM,
857 				    outer_vtag_num);
858 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_NO_VTAG, 0);
859 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_ONE_VTAG, 1);
860 		ULP_BITMAP_SET(params->hdr_bitmap.bits,
861 			       BNXT_ULP_HDR_BIT_OO_VLAN);
862 		if (vlan_mask && vlan_tag_mask)
863 			ULP_COMP_FLD_IDX_WR(params,
864 					    BNXT_ULP_CF_IDX_OO_VLAN_FB_VID, 1);
865 
866 	} else if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
867 		   !ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_I_ETH) &&
868 		   outer_vtag_num == 1) {
869 		/* update the vlan tag num */
870 		outer_vtag_num++;
871 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_VTAG_NUM,
872 				    outer_vtag_num);
873 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_TWO_VTAGS, 1);
874 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_ONE_VTAG, 0);
875 		ULP_BITMAP_SET(params->hdr_bitmap.bits,
876 			       BNXT_ULP_HDR_BIT_OI_VLAN);
877 		if (vlan_mask && vlan_tag_mask)
878 			ULP_COMP_FLD_IDX_WR(params,
879 					    BNXT_ULP_CF_IDX_OI_VLAN_FB_VID, 1);
880 
881 	} else if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
882 		   ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_I_ETH) &&
883 		   !inner_vtag_num) {
884 		/* update the vlan tag num */
885 		inner_vtag_num++;
886 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_VTAG_NUM,
887 				    inner_vtag_num);
888 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_NO_VTAG, 0);
889 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_ONE_VTAG, 1);
890 		ULP_BITMAP_SET(params->hdr_bitmap.bits,
891 			       BNXT_ULP_HDR_BIT_IO_VLAN);
892 		if (vlan_mask && vlan_tag_mask)
893 			ULP_COMP_FLD_IDX_WR(params,
894 					    BNXT_ULP_CF_IDX_IO_VLAN_FB_VID, 1);
895 		inner_flag = 1;
896 	} else if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
897 		   ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_I_ETH) &&
898 		   inner_vtag_num == 1) {
899 		/* update the vlan tag num */
900 		inner_vtag_num++;
901 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_VTAG_NUM,
902 				    inner_vtag_num);
903 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_TWO_VTAGS, 1);
904 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_ONE_VTAG, 0);
905 		ULP_BITMAP_SET(params->hdr_bitmap.bits,
906 			       BNXT_ULP_HDR_BIT_II_VLAN);
907 		if (vlan_mask && vlan_tag_mask)
908 			ULP_COMP_FLD_IDX_WR(params,
909 					    BNXT_ULP_CF_IDX_II_VLAN_FB_VID, 1);
910 		inner_flag = 1;
911 	} else {
912 		BNXT_TF_DBG(ERR, "Error Parsing:Vlan hdr found without eth\n");
913 		return BNXT_TF_RC_ERROR;
914 	}
915 	/* Update the field protocol hdr bitmap */
916 	ulp_rte_l2_proto_type_update(params, eth_type, inner_flag);
917 	return BNXT_TF_RC_SUCCESS;
918 }
919 
920 /* Function to handle the update of proto header based on field values */
921 static void
922 ulp_rte_l3_proto_type_update(struct ulp_rte_parser_params *param,
923 			     uint8_t proto, uint32_t in_flag)
924 {
925 	if (proto == IPPROTO_UDP) {
926 		if (in_flag) {
927 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
928 				       BNXT_ULP_HDR_BIT_I_UDP);
929 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_I_L4, 1);
930 		} else {
931 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
932 				       BNXT_ULP_HDR_BIT_O_UDP);
933 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_O_L4, 1);
934 		}
935 	} else if (proto == IPPROTO_TCP) {
936 		if (in_flag) {
937 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
938 				       BNXT_ULP_HDR_BIT_I_TCP);
939 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_I_L4, 1);
940 		} else {
941 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
942 				       BNXT_ULP_HDR_BIT_O_TCP);
943 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_O_L4, 1);
944 		}
945 	} else if (proto == IPPROTO_GRE) {
946 		ULP_BITMAP_SET(param->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_T_GRE);
947 	} else if (proto == IPPROTO_ICMP) {
948 		if (ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_L3_TUN))
949 			ULP_BITMAP_SET(param->hdr_bitmap.bits,
950 				       BNXT_ULP_HDR_BIT_I_ICMP);
951 		else
952 			ULP_BITMAP_SET(param->hdr_bitmap.bits,
953 				       BNXT_ULP_HDR_BIT_O_ICMP);
954 	}
955 	if (proto) {
956 		if (in_flag) {
957 			ULP_COMP_FLD_IDX_WR(param,
958 					    BNXT_ULP_CF_IDX_I_L3_FB_PROTO_ID,
959 					    1);
960 			ULP_COMP_FLD_IDX_WR(param,
961 					    BNXT_ULP_CF_IDX_I_L3_PROTO_ID,
962 					    proto);
963 		} else {
964 			ULP_COMP_FLD_IDX_WR(param,
965 					    BNXT_ULP_CF_IDX_O_L3_FB_PROTO_ID,
966 					    1);
967 			ULP_COMP_FLD_IDX_WR(param,
968 					    BNXT_ULP_CF_IDX_O_L3_PROTO_ID,
969 					    proto);
970 		}
971 	}
972 }
973 
974 /* Function to handle the parsing of RTE Flow item IPV4 Header. */
975 int32_t
976 ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,
977 			 struct ulp_rte_parser_params *params)
978 {
979 	const struct rte_flow_item_ipv4 *ipv4_spec = item->spec;
980 	const struct rte_flow_item_ipv4 *ipv4_mask = item->mask;
981 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
982 	uint32_t idx = 0, dip_idx = 0;
983 	uint32_t size;
984 	uint8_t proto = 0;
985 	uint32_t inner_flag = 0;
986 	uint32_t cnt;
987 
988 	/* validate there are no 3rd L3 header */
989 	cnt = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L3_HDR_CNT);
990 	if (cnt == 2) {
991 		BNXT_TF_DBG(ERR, "Parse Err:Third L3 header not supported\n");
992 		return BNXT_TF_RC_ERROR;
993 	}
994 
995 	if (ulp_rte_prsr_fld_size_validate(params, &idx,
996 					   BNXT_ULP_PROTO_HDR_IPV4_NUM)) {
997 		BNXT_TF_DBG(ERR, "Error parsing protocol header\n");
998 		return BNXT_TF_RC_ERROR;
999 	}
1000 
1001 	/*
1002 	 * Copy the rte_flow_item for ipv4 into hdr_field using ipv4
1003 	 * header fields
1004 	 */
1005 	size = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.version_ihl);
1006 	ulp_rte_prsr_fld_mask(params, &idx, size,
1007 			      ulp_deference_struct(ipv4_spec, hdr.version_ihl),
1008 			      ulp_deference_struct(ipv4_mask, hdr.version_ihl),
1009 			      ULP_PRSR_ACT_DEFAULT);
1010 
1011 	/*
1012 	 * The tos field is ignored since OVS is setting it as wild card
1013 	 * match and it is not supported. This is a work around and
1014 	 * shall be addressed in the future.
1015 	 */
1016 	size = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.type_of_service);
1017 	ulp_rte_prsr_fld_mask(params, &idx, size,
1018 			      ulp_deference_struct(ipv4_spec,
1019 						   hdr.type_of_service),
1020 			      ulp_deference_struct(ipv4_mask,
1021 						   hdr.type_of_service),
1022 			      ULP_PRSR_ACT_MASK_IGNORE);
1023 
1024 	size = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.total_length);
1025 	ulp_rte_prsr_fld_mask(params, &idx, size,
1026 			      ulp_deference_struct(ipv4_spec, hdr.total_length),
1027 			      ulp_deference_struct(ipv4_mask, hdr.total_length),
1028 			      ULP_PRSR_ACT_DEFAULT);
1029 
1030 	size = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.packet_id);
1031 	ulp_rte_prsr_fld_mask(params, &idx, size,
1032 			      ulp_deference_struct(ipv4_spec, hdr.packet_id),
1033 			      ulp_deference_struct(ipv4_mask, hdr.packet_id),
1034 			      ULP_PRSR_ACT_DEFAULT);
1035 
1036 	size = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.fragment_offset);
1037 	ulp_rte_prsr_fld_mask(params, &idx, size,
1038 			      ulp_deference_struct(ipv4_spec,
1039 						   hdr.fragment_offset),
1040 			      ulp_deference_struct(ipv4_mask,
1041 						   hdr.fragment_offset),
1042 			      ULP_PRSR_ACT_DEFAULT);
1043 
1044 	size = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.time_to_live);
1045 	ulp_rte_prsr_fld_mask(params, &idx, size,
1046 			      ulp_deference_struct(ipv4_spec, hdr.time_to_live),
1047 			      ulp_deference_struct(ipv4_mask, hdr.time_to_live),
1048 			      ULP_PRSR_ACT_DEFAULT);
1049 
1050 	/* Ignore proto for matching templates */
1051 	size = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.next_proto_id);
1052 	ulp_rte_prsr_fld_mask(params, &idx, size,
1053 			      ulp_deference_struct(ipv4_spec,
1054 						   hdr.next_proto_id),
1055 			      ulp_deference_struct(ipv4_mask,
1056 						   hdr.next_proto_id),
1057 			      ULP_PRSR_ACT_MATCH_IGNORE);
1058 	if (ipv4_spec)
1059 		proto = ipv4_spec->hdr.next_proto_id;
1060 
1061 	size = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.hdr_checksum);
1062 	ulp_rte_prsr_fld_mask(params, &idx, size,
1063 			      ulp_deference_struct(ipv4_spec, hdr.hdr_checksum),
1064 			      ulp_deference_struct(ipv4_mask, hdr.hdr_checksum),
1065 			      ULP_PRSR_ACT_DEFAULT);
1066 
1067 	size = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.src_addr);
1068 	ulp_rte_prsr_fld_mask(params, &idx, size,
1069 			      ulp_deference_struct(ipv4_spec, hdr.src_addr),
1070 			      ulp_deference_struct(ipv4_mask, hdr.src_addr),
1071 			      ULP_PRSR_ACT_DEFAULT);
1072 
1073 	dip_idx = idx;
1074 	size = sizeof(((struct rte_flow_item_ipv4 *)NULL)->hdr.dst_addr);
1075 	ulp_rte_prsr_fld_mask(params, &idx, size,
1076 			      ulp_deference_struct(ipv4_spec, hdr.dst_addr),
1077 			      ulp_deference_struct(ipv4_mask, hdr.dst_addr),
1078 			      ULP_PRSR_ACT_DEFAULT);
1079 
1080 	/* Set the ipv4 header bitmap and computed l3 header bitmaps */
1081 	if (ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV4) ||
1082 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV6)) {
1083 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_IPV4);
1084 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L3, 1);
1085 		inner_flag = 1;
1086 	} else {
1087 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV4);
1088 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L3, 1);
1089 		/* Update the tunnel offload dest ip offset */
1090 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_TUN_OFF_DIP_ID,
1091 				    dip_idx);
1092 	}
1093 
1094 	/* Some of the PMD applications may set the protocol field
1095 	 * in the IPv4 spec but don't set the mask. So, consider
1096 	 * the mask in the proto value calculation.
1097 	 */
1098 	if (ipv4_mask)
1099 		proto &= ipv4_mask->hdr.next_proto_id;
1100 
1101 	/* Update the field protocol hdr bitmap */
1102 	ulp_rte_l3_proto_type_update(params, proto, inner_flag);
1103 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_HDR_CNT, ++cnt);
1104 	return BNXT_TF_RC_SUCCESS;
1105 }
1106 
1107 /* Function to handle the parsing of RTE Flow item IPV6 Header */
1108 int32_t
1109 ulp_rte_ipv6_hdr_handler(const struct rte_flow_item *item,
1110 			 struct ulp_rte_parser_params *params)
1111 {
1112 	const struct rte_flow_item_ipv6	*ipv6_spec = item->spec;
1113 	const struct rte_flow_item_ipv6	*ipv6_mask = item->mask;
1114 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
1115 	uint32_t idx = 0, dip_idx = 0;
1116 	uint32_t size;
1117 	uint32_t ver_spec = 0, ver_mask = 0;
1118 	uint32_t tc_spec = 0, tc_mask = 0;
1119 	uint32_t lab_spec = 0, lab_mask = 0;
1120 	uint8_t proto = 0;
1121 	uint32_t inner_flag = 0;
1122 	uint32_t cnt;
1123 
1124 	/* validate there are no 3rd L3 header */
1125 	cnt = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L3_HDR_CNT);
1126 	if (cnt == 2) {
1127 		BNXT_TF_DBG(ERR, "Parse Err:Third L3 header not supported\n");
1128 		return BNXT_TF_RC_ERROR;
1129 	}
1130 
1131 	if (ulp_rte_prsr_fld_size_validate(params, &idx,
1132 					   BNXT_ULP_PROTO_HDR_IPV6_NUM)) {
1133 		BNXT_TF_DBG(ERR, "Error parsing protocol header\n");
1134 		return BNXT_TF_RC_ERROR;
1135 	}
1136 
1137 	/*
1138 	 * Copy the rte_flow_item for ipv6 into hdr_field using ipv6
1139 	 * header fields
1140 	 */
1141 	if (ipv6_spec) {
1142 		ver_spec = BNXT_ULP_GET_IPV6_VER(ipv6_spec->hdr.vtc_flow);
1143 		tc_spec = BNXT_ULP_GET_IPV6_TC(ipv6_spec->hdr.vtc_flow);
1144 		lab_spec = BNXT_ULP_GET_IPV6_FLOWLABEL(ipv6_spec->hdr.vtc_flow);
1145 		proto = ipv6_spec->hdr.proto;
1146 	}
1147 
1148 	if (ipv6_mask) {
1149 		ver_mask = BNXT_ULP_GET_IPV6_VER(ipv6_mask->hdr.vtc_flow);
1150 		tc_mask = BNXT_ULP_GET_IPV6_TC(ipv6_mask->hdr.vtc_flow);
1151 		lab_mask = BNXT_ULP_GET_IPV6_FLOWLABEL(ipv6_mask->hdr.vtc_flow);
1152 
1153 		/* Some of the PMD applications may set the protocol field
1154 		 * in the IPv6 spec but don't set the mask. So, consider
1155 		 * the mask in proto value calculation.
1156 		 */
1157 		proto &= ipv6_mask->hdr.proto;
1158 	}
1159 
1160 	size = sizeof(((struct rte_flow_item_ipv6 *)NULL)->hdr.vtc_flow);
1161 	ulp_rte_prsr_fld_mask(params, &idx, size, &ver_spec, &ver_mask,
1162 			      ULP_PRSR_ACT_DEFAULT);
1163 	/*
1164 	 * The TC and flow label field are ignored since OVS is
1165 	 * setting it for match and it is not supported.
1166 	 * This is a work around and
1167 	 * shall be addressed in the future.
1168 	 */
1169 	ulp_rte_prsr_fld_mask(params, &idx, size, &tc_spec, &tc_mask,
1170 			      ULP_PRSR_ACT_MASK_IGNORE);
1171 	ulp_rte_prsr_fld_mask(params, &idx, size, &lab_spec, &lab_mask,
1172 			      ULP_PRSR_ACT_MASK_IGNORE);
1173 
1174 	size = sizeof(((struct rte_flow_item_ipv6 *)NULL)->hdr.payload_len);
1175 	ulp_rte_prsr_fld_mask(params, &idx, size,
1176 			      ulp_deference_struct(ipv6_spec, hdr.payload_len),
1177 			      ulp_deference_struct(ipv6_mask, hdr.payload_len),
1178 			      ULP_PRSR_ACT_DEFAULT);
1179 
1180 	/* Ignore proto for template matching */
1181 	size = sizeof(((struct rte_flow_item_ipv6 *)NULL)->hdr.proto);
1182 	ulp_rte_prsr_fld_mask(params, &idx, size,
1183 			      ulp_deference_struct(ipv6_spec, hdr.proto),
1184 			      ulp_deference_struct(ipv6_mask, hdr.proto),
1185 			      ULP_PRSR_ACT_MATCH_IGNORE);
1186 
1187 	size = sizeof(((struct rte_flow_item_ipv6 *)NULL)->hdr.hop_limits);
1188 	ulp_rte_prsr_fld_mask(params, &idx, size,
1189 			      ulp_deference_struct(ipv6_spec, hdr.hop_limits),
1190 			      ulp_deference_struct(ipv6_mask, hdr.hop_limits),
1191 			      ULP_PRSR_ACT_DEFAULT);
1192 
1193 	size = sizeof(((struct rte_flow_item_ipv6 *)NULL)->hdr.src_addr);
1194 	ulp_rte_prsr_fld_mask(params, &idx, size,
1195 			      ulp_deference_struct(ipv6_spec, hdr.src_addr),
1196 			      ulp_deference_struct(ipv6_mask, hdr.src_addr),
1197 			      ULP_PRSR_ACT_DEFAULT);
1198 
1199 	dip_idx =  idx;
1200 	size = sizeof(((struct rte_flow_item_ipv6 *)NULL)->hdr.dst_addr);
1201 	ulp_rte_prsr_fld_mask(params, &idx, size,
1202 			      ulp_deference_struct(ipv6_spec, hdr.dst_addr),
1203 			      ulp_deference_struct(ipv6_mask, hdr.dst_addr),
1204 			      ULP_PRSR_ACT_DEFAULT);
1205 
1206 	/* Set the ipv6 header bitmap and computed l3 header bitmaps */
1207 	if (ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV4) ||
1208 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV6)) {
1209 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_IPV6);
1210 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L3, 1);
1211 		inner_flag = 1;
1212 	} else {
1213 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV6);
1214 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L3, 1);
1215 		/* Update the tunnel offload dest ip offset */
1216 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_TUN_OFF_DIP_ID,
1217 				    dip_idx);
1218 	}
1219 
1220 	/* Update the field protocol hdr bitmap */
1221 	ulp_rte_l3_proto_type_update(params, proto, inner_flag);
1222 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_HDR_CNT, ++cnt);
1223 
1224 	return BNXT_TF_RC_SUCCESS;
1225 }
1226 
1227 /* Function to handle the update of proto header based on field values */
1228 static void
1229 ulp_rte_l4_proto_type_update(struct ulp_rte_parser_params *params,
1230 			     uint16_t src_port, uint16_t src_mask,
1231 			     uint16_t dst_port, uint16_t dst_mask,
1232 			     enum bnxt_ulp_hdr_bit hdr_bit)
1233 {
1234 	switch (hdr_bit) {
1235 	case BNXT_ULP_HDR_BIT_I_UDP:
1236 	case BNXT_ULP_HDR_BIT_I_TCP:
1237 		ULP_BITMAP_SET(params->hdr_bitmap.bits, hdr_bit);
1238 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L4, 1);
1239 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L4_SRC_PORT,
1240 				    (uint64_t)rte_be_to_cpu_16(src_port));
1241 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L4_DST_PORT,
1242 				    (uint64_t)rte_be_to_cpu_16(dst_port));
1243 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L4_SRC_PORT_MASK,
1244 				    (uint64_t)rte_be_to_cpu_16(src_mask));
1245 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L4_DST_PORT_MASK,
1246 				    (uint64_t)rte_be_to_cpu_16(dst_mask));
1247 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L3_FB_PROTO_ID,
1248 				    1);
1249 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L4_FB_SRC_PORT,
1250 				    !!(src_port & src_mask));
1251 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L4_FB_DST_PORT,
1252 				    !!(dst_port & dst_mask));
1253 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L3_PROTO_ID,
1254 				    (hdr_bit == BNXT_ULP_HDR_BIT_I_UDP) ?
1255 				    IPPROTO_UDP : IPPROTO_TCP);
1256 		break;
1257 	case BNXT_ULP_HDR_BIT_O_UDP:
1258 	case BNXT_ULP_HDR_BIT_O_TCP:
1259 		ULP_BITMAP_SET(params->hdr_bitmap.bits, hdr_bit);
1260 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4, 1);
1261 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4_SRC_PORT,
1262 				    (uint64_t)rte_be_to_cpu_16(src_port));
1263 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4_DST_PORT,
1264 				    (uint64_t)rte_be_to_cpu_16(dst_port));
1265 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4_SRC_PORT_MASK,
1266 				    (uint64_t)rte_be_to_cpu_16(src_mask));
1267 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4_DST_PORT_MASK,
1268 				    (uint64_t)rte_be_to_cpu_16(dst_mask));
1269 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L3_FB_PROTO_ID,
1270 				    1);
1271 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4_FB_SRC_PORT,
1272 				    !!(src_port & src_mask));
1273 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4_FB_DST_PORT,
1274 				    !!(dst_port & dst_mask));
1275 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L3_PROTO_ID,
1276 				    (hdr_bit == BNXT_ULP_HDR_BIT_O_UDP) ?
1277 				    IPPROTO_UDP : IPPROTO_TCP);
1278 		break;
1279 	default:
1280 		break;
1281 	}
1282 
1283 	if (hdr_bit == BNXT_ULP_HDR_BIT_O_UDP && dst_port ==
1284 	    tfp_cpu_to_be_16(ULP_UDP_PORT_VXLAN)) {
1285 		ULP_BITMAP_SET(params->hdr_fp_bit.bits,
1286 			       BNXT_ULP_HDR_BIT_T_VXLAN);
1287 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_TUN, 1);
1288 	}
1289 }
1290 
1291 /* Function to handle the parsing of RTE Flow item UDP Header. */
1292 int32_t
1293 ulp_rte_udp_hdr_handler(const struct rte_flow_item *item,
1294 			struct ulp_rte_parser_params *params)
1295 {
1296 	const struct rte_flow_item_udp *udp_spec = item->spec;
1297 	const struct rte_flow_item_udp *udp_mask = item->mask;
1298 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
1299 	uint32_t idx = 0;
1300 	uint32_t size;
1301 	uint16_t dport = 0, sport = 0;
1302 	uint16_t dport_mask = 0, sport_mask = 0;
1303 	uint32_t cnt;
1304 	enum bnxt_ulp_hdr_bit out_l4 = BNXT_ULP_HDR_BIT_O_UDP;
1305 
1306 	cnt = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L4_HDR_CNT);
1307 	if (cnt == 2) {
1308 		BNXT_TF_DBG(ERR, "Parse Err:Third L4 header not supported\n");
1309 		return BNXT_TF_RC_ERROR;
1310 	}
1311 
1312 	if (udp_spec) {
1313 		sport = udp_spec->hdr.src_port;
1314 		dport = udp_spec->hdr.dst_port;
1315 	}
1316 	if (udp_mask) {
1317 		sport_mask = udp_mask->hdr.src_port;
1318 		dport_mask = udp_mask->hdr.dst_port;
1319 	}
1320 
1321 	if (ulp_rte_prsr_fld_size_validate(params, &idx,
1322 					   BNXT_ULP_PROTO_HDR_UDP_NUM)) {
1323 		BNXT_TF_DBG(ERR, "Error parsing protocol header\n");
1324 		return BNXT_TF_RC_ERROR;
1325 	}
1326 
1327 	/*
1328 	 * Copy the rte_flow_item for ipv4 into hdr_field using ipv4
1329 	 * header fields
1330 	 */
1331 	size = sizeof(((struct rte_flow_item_udp *)NULL)->hdr.src_port);
1332 	ulp_rte_prsr_fld_mask(params, &idx, size,
1333 			      ulp_deference_struct(udp_spec, hdr.src_port),
1334 			      ulp_deference_struct(udp_mask, hdr.src_port),
1335 			      ULP_PRSR_ACT_DEFAULT);
1336 
1337 	size = sizeof(((struct rte_flow_item_udp *)NULL)->hdr.dst_port);
1338 	ulp_rte_prsr_fld_mask(params, &idx, size,
1339 			      ulp_deference_struct(udp_spec, hdr.dst_port),
1340 			      ulp_deference_struct(udp_mask, hdr.dst_port),
1341 			      ULP_PRSR_ACT_DEFAULT);
1342 
1343 	size = sizeof(((struct rte_flow_item_udp *)NULL)->hdr.dgram_len);
1344 	ulp_rte_prsr_fld_mask(params, &idx, size,
1345 			      ulp_deference_struct(udp_spec, hdr.dgram_len),
1346 			      ulp_deference_struct(udp_mask, hdr.dgram_len),
1347 			      ULP_PRSR_ACT_DEFAULT);
1348 
1349 	size = sizeof(((struct rte_flow_item_udp *)NULL)->hdr.dgram_cksum);
1350 	ulp_rte_prsr_fld_mask(params, &idx, size,
1351 			      ulp_deference_struct(udp_spec, hdr.dgram_cksum),
1352 			      ulp_deference_struct(udp_mask, hdr.dgram_cksum),
1353 			      ULP_PRSR_ACT_DEFAULT);
1354 
1355 	/* Set the udp header bitmap and computed l4 header bitmaps */
1356 	if (ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_UDP) ||
1357 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP))
1358 		out_l4 = BNXT_ULP_HDR_BIT_I_UDP;
1359 
1360 	ulp_rte_l4_proto_type_update(params, sport, sport_mask, dport,
1361 				     dport_mask, out_l4);
1362 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L4_HDR_CNT, ++cnt);
1363 	return BNXT_TF_RC_SUCCESS;
1364 }
1365 
1366 /* Function to handle the parsing of RTE Flow item TCP Header. */
1367 int32_t
1368 ulp_rte_tcp_hdr_handler(const struct rte_flow_item *item,
1369 			struct ulp_rte_parser_params *params)
1370 {
1371 	const struct rte_flow_item_tcp *tcp_spec = item->spec;
1372 	const struct rte_flow_item_tcp *tcp_mask = item->mask;
1373 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
1374 	uint32_t idx = 0;
1375 	uint16_t dport = 0, sport = 0;
1376 	uint16_t dport_mask = 0, sport_mask = 0;
1377 	uint32_t size;
1378 	uint32_t cnt;
1379 	enum bnxt_ulp_hdr_bit out_l4 = BNXT_ULP_HDR_BIT_O_TCP;
1380 
1381 	cnt = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L4_HDR_CNT);
1382 	if (cnt == 2) {
1383 		BNXT_TF_DBG(ERR, "Parse Err:Third L4 header not supported\n");
1384 		return BNXT_TF_RC_ERROR;
1385 	}
1386 
1387 	if (tcp_spec) {
1388 		sport = tcp_spec->hdr.src_port;
1389 		dport = tcp_spec->hdr.dst_port;
1390 	}
1391 	if (tcp_mask) {
1392 		sport_mask = tcp_mask->hdr.src_port;
1393 		dport_mask = tcp_mask->hdr.dst_port;
1394 	}
1395 
1396 	if (ulp_rte_prsr_fld_size_validate(params, &idx,
1397 					   BNXT_ULP_PROTO_HDR_TCP_NUM)) {
1398 		BNXT_TF_DBG(ERR, "Error parsing protocol header\n");
1399 		return BNXT_TF_RC_ERROR;
1400 	}
1401 
1402 	/*
1403 	 * Copy the rte_flow_item for ipv4 into hdr_field using ipv4
1404 	 * header fields
1405 	 */
1406 	size = sizeof(((struct rte_flow_item_tcp *)NULL)->hdr.src_port);
1407 	ulp_rte_prsr_fld_mask(params, &idx, size,
1408 			      ulp_deference_struct(tcp_spec, hdr.src_port),
1409 			      ulp_deference_struct(tcp_mask, hdr.src_port),
1410 			      ULP_PRSR_ACT_DEFAULT);
1411 
1412 	size = sizeof(((struct rte_flow_item_tcp *)NULL)->hdr.dst_port);
1413 	ulp_rte_prsr_fld_mask(params, &idx, size,
1414 			      ulp_deference_struct(tcp_spec, hdr.dst_port),
1415 			      ulp_deference_struct(tcp_mask, hdr.dst_port),
1416 			      ULP_PRSR_ACT_DEFAULT);
1417 
1418 	size = sizeof(((struct rte_flow_item_tcp *)NULL)->hdr.sent_seq);
1419 	ulp_rte_prsr_fld_mask(params, &idx, size,
1420 			      ulp_deference_struct(tcp_spec, hdr.sent_seq),
1421 			      ulp_deference_struct(tcp_mask, hdr.sent_seq),
1422 			      ULP_PRSR_ACT_DEFAULT);
1423 
1424 	size = sizeof(((struct rte_flow_item_tcp *)NULL)->hdr.recv_ack);
1425 	ulp_rte_prsr_fld_mask(params, &idx, size,
1426 			      ulp_deference_struct(tcp_spec, hdr.recv_ack),
1427 			      ulp_deference_struct(tcp_mask, hdr.recv_ack),
1428 			      ULP_PRSR_ACT_DEFAULT);
1429 
1430 	size = sizeof(((struct rte_flow_item_tcp *)NULL)->hdr.data_off);
1431 	ulp_rte_prsr_fld_mask(params, &idx, size,
1432 			      ulp_deference_struct(tcp_spec, hdr.data_off),
1433 			      ulp_deference_struct(tcp_mask, hdr.data_off),
1434 			      ULP_PRSR_ACT_DEFAULT);
1435 
1436 	size = sizeof(((struct rte_flow_item_tcp *)NULL)->hdr.tcp_flags);
1437 	ulp_rte_prsr_fld_mask(params, &idx, size,
1438 			      ulp_deference_struct(tcp_spec, hdr.tcp_flags),
1439 			      ulp_deference_struct(tcp_mask, hdr.tcp_flags),
1440 			      ULP_PRSR_ACT_DEFAULT);
1441 
1442 	size = sizeof(((struct rte_flow_item_tcp *)NULL)->hdr.rx_win);
1443 	ulp_rte_prsr_fld_mask(params, &idx, size,
1444 			      ulp_deference_struct(tcp_spec, hdr.rx_win),
1445 			      ulp_deference_struct(tcp_mask, hdr.rx_win),
1446 			      ULP_PRSR_ACT_DEFAULT);
1447 
1448 	size = sizeof(((struct rte_flow_item_tcp *)NULL)->hdr.cksum);
1449 	ulp_rte_prsr_fld_mask(params, &idx, size,
1450 			      ulp_deference_struct(tcp_spec, hdr.cksum),
1451 			      ulp_deference_struct(tcp_mask, hdr.cksum),
1452 			      ULP_PRSR_ACT_DEFAULT);
1453 
1454 	size = sizeof(((struct rte_flow_item_tcp *)NULL)->hdr.tcp_urp);
1455 	ulp_rte_prsr_fld_mask(params, &idx, size,
1456 			      ulp_deference_struct(tcp_spec, hdr.tcp_urp),
1457 			      ulp_deference_struct(tcp_mask, hdr.tcp_urp),
1458 			      ULP_PRSR_ACT_DEFAULT);
1459 
1460 	/* Set the udp header bitmap and computed l4 header bitmaps */
1461 	if (ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_UDP) ||
1462 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP))
1463 		out_l4 = BNXT_ULP_HDR_BIT_I_TCP;
1464 
1465 	ulp_rte_l4_proto_type_update(params, sport, sport_mask, dport,
1466 				     dport_mask, out_l4);
1467 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L4_HDR_CNT, ++cnt);
1468 	return BNXT_TF_RC_SUCCESS;
1469 }
1470 
1471 /* Function to handle the parsing of RTE Flow item Vxlan Header. */
1472 int32_t
1473 ulp_rte_vxlan_hdr_handler(const struct rte_flow_item *item,
1474 			  struct ulp_rte_parser_params *params)
1475 {
1476 	const struct rte_flow_item_vxlan *vxlan_spec = item->spec;
1477 	const struct rte_flow_item_vxlan *vxlan_mask = item->mask;
1478 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
1479 	uint32_t idx = 0;
1480 	uint32_t size;
1481 
1482 	if (ulp_rte_prsr_fld_size_validate(params, &idx,
1483 					   BNXT_ULP_PROTO_HDR_VXLAN_NUM)) {
1484 		BNXT_TF_DBG(ERR, "Error parsing protocol header\n");
1485 		return BNXT_TF_RC_ERROR;
1486 	}
1487 
1488 	/*
1489 	 * Copy the rte_flow_item for vxlan into hdr_field using vxlan
1490 	 * header fields
1491 	 */
1492 	size = sizeof(((struct rte_flow_item_vxlan *)NULL)->flags);
1493 	ulp_rte_prsr_fld_mask(params, &idx, size,
1494 			      ulp_deference_struct(vxlan_spec, flags),
1495 			      ulp_deference_struct(vxlan_mask, flags),
1496 			      ULP_PRSR_ACT_DEFAULT);
1497 
1498 	size = sizeof(((struct rte_flow_item_vxlan *)NULL)->rsvd0);
1499 	ulp_rte_prsr_fld_mask(params, &idx, size,
1500 			      ulp_deference_struct(vxlan_spec, rsvd0),
1501 			      ulp_deference_struct(vxlan_mask, rsvd0),
1502 			      ULP_PRSR_ACT_DEFAULT);
1503 
1504 	size = sizeof(((struct rte_flow_item_vxlan *)NULL)->vni);
1505 	ulp_rte_prsr_fld_mask(params, &idx, size,
1506 			      ulp_deference_struct(vxlan_spec, vni),
1507 			      ulp_deference_struct(vxlan_mask, vni),
1508 			      ULP_PRSR_ACT_DEFAULT);
1509 
1510 	size = sizeof(((struct rte_flow_item_vxlan *)NULL)->rsvd1);
1511 	ulp_rte_prsr_fld_mask(params, &idx, size,
1512 			      ulp_deference_struct(vxlan_spec, rsvd1),
1513 			      ulp_deference_struct(vxlan_mask, rsvd1),
1514 			      ULP_PRSR_ACT_DEFAULT);
1515 
1516 	/* Update the hdr_bitmap with vxlan */
1517 	ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_T_VXLAN);
1518 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_TUN, 1);
1519 	return BNXT_TF_RC_SUCCESS;
1520 }
1521 
1522 /* Function to handle the parsing of RTE Flow item GRE Header. */
1523 int32_t
1524 ulp_rte_gre_hdr_handler(const struct rte_flow_item *item,
1525 			struct ulp_rte_parser_params *params)
1526 {
1527 	const struct rte_flow_item_gre *gre_spec = item->spec;
1528 	const struct rte_flow_item_gre *gre_mask = item->mask;
1529 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
1530 	uint32_t idx = 0;
1531 	uint32_t size;
1532 
1533 	if (ulp_rte_prsr_fld_size_validate(params, &idx,
1534 					   BNXT_ULP_PROTO_HDR_GRE_NUM)) {
1535 		BNXT_TF_DBG(ERR, "Error parsing protocol header\n");
1536 		return BNXT_TF_RC_ERROR;
1537 	}
1538 
1539 	size = sizeof(((struct rte_flow_item_gre *)NULL)->c_rsvd0_ver);
1540 	ulp_rte_prsr_fld_mask(params, &idx, size,
1541 			      ulp_deference_struct(gre_spec, c_rsvd0_ver),
1542 			      ulp_deference_struct(gre_mask, c_rsvd0_ver),
1543 			      ULP_PRSR_ACT_DEFAULT);
1544 
1545 	size = sizeof(((struct rte_flow_item_gre *)NULL)->protocol);
1546 	ulp_rte_prsr_fld_mask(params, &idx, size,
1547 			      ulp_deference_struct(gre_spec, protocol),
1548 			      ulp_deference_struct(gre_mask, protocol),
1549 			      ULP_PRSR_ACT_DEFAULT);
1550 
1551 	/* Update the hdr_bitmap with GRE */
1552 	ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_T_GRE);
1553 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_TUN, 1);
1554 	return BNXT_TF_RC_SUCCESS;
1555 }
1556 
1557 /* Function to handle the parsing of RTE Flow item ANY. */
1558 int32_t
1559 ulp_rte_item_any_handler(const struct rte_flow_item *item __rte_unused,
1560 			 struct ulp_rte_parser_params *params __rte_unused)
1561 {
1562 	return BNXT_TF_RC_SUCCESS;
1563 }
1564 
1565 /* Function to handle the parsing of RTE Flow item ICMP Header. */
1566 int32_t
1567 ulp_rte_icmp_hdr_handler(const struct rte_flow_item *item,
1568 			 struct ulp_rte_parser_params *params)
1569 {
1570 	const struct rte_flow_item_icmp *icmp_spec = item->spec;
1571 	const struct rte_flow_item_icmp *icmp_mask = item->mask;
1572 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
1573 	uint32_t idx = 0;
1574 	uint32_t size;
1575 
1576 	if (ulp_rte_prsr_fld_size_validate(params, &idx,
1577 					   BNXT_ULP_PROTO_HDR_ICMP_NUM)) {
1578 		BNXT_TF_DBG(ERR, "Error parsing protocol header\n");
1579 		return BNXT_TF_RC_ERROR;
1580 	}
1581 
1582 	size = sizeof(((struct rte_flow_item_icmp *)NULL)->hdr.icmp_type);
1583 	ulp_rte_prsr_fld_mask(params, &idx, size,
1584 			      ulp_deference_struct(icmp_spec, hdr.icmp_type),
1585 			      ulp_deference_struct(icmp_mask, hdr.icmp_type),
1586 			      ULP_PRSR_ACT_DEFAULT);
1587 
1588 	size = sizeof(((struct rte_flow_item_icmp *)NULL)->hdr.icmp_code);
1589 	ulp_rte_prsr_fld_mask(params, &idx, size,
1590 			      ulp_deference_struct(icmp_spec, hdr.icmp_code),
1591 			      ulp_deference_struct(icmp_mask, hdr.icmp_code),
1592 			      ULP_PRSR_ACT_DEFAULT);
1593 
1594 	size = sizeof(((struct rte_flow_item_icmp *)NULL)->hdr.icmp_cksum);
1595 	ulp_rte_prsr_fld_mask(params, &idx, size,
1596 			      ulp_deference_struct(icmp_spec, hdr.icmp_cksum),
1597 			      ulp_deference_struct(icmp_mask, hdr.icmp_cksum),
1598 			      ULP_PRSR_ACT_DEFAULT);
1599 
1600 	size = sizeof(((struct rte_flow_item_icmp *)NULL)->hdr.icmp_ident);
1601 	ulp_rte_prsr_fld_mask(params, &idx, size,
1602 			      ulp_deference_struct(icmp_spec, hdr.icmp_ident),
1603 			      ulp_deference_struct(icmp_mask, hdr.icmp_ident),
1604 			      ULP_PRSR_ACT_DEFAULT);
1605 
1606 	size = sizeof(((struct rte_flow_item_icmp *)NULL)->hdr.icmp_seq_nb);
1607 	ulp_rte_prsr_fld_mask(params, &idx, size,
1608 			      ulp_deference_struct(icmp_spec, hdr.icmp_seq_nb),
1609 			      ulp_deference_struct(icmp_mask, hdr.icmp_seq_nb),
1610 			      ULP_PRSR_ACT_DEFAULT);
1611 
1612 	/* Update the hdr_bitmap with ICMP */
1613 	if (ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L3_TUN))
1614 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_ICMP);
1615 	else
1616 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_ICMP);
1617 	return BNXT_TF_RC_SUCCESS;
1618 }
1619 
1620 /* Function to handle the parsing of RTE Flow item ICMP6 Header. */
1621 int32_t
1622 ulp_rte_icmp6_hdr_handler(const struct rte_flow_item *item,
1623 			  struct ulp_rte_parser_params *params)
1624 {
1625 	const struct rte_flow_item_icmp6 *icmp_spec = item->spec;
1626 	const struct rte_flow_item_icmp6 *icmp_mask = item->mask;
1627 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
1628 	uint32_t idx = 0;
1629 	uint32_t size;
1630 
1631 	if (ulp_rte_prsr_fld_size_validate(params, &idx,
1632 					   BNXT_ULP_PROTO_HDR_ICMP_NUM)) {
1633 		BNXT_TF_DBG(ERR, "Error parsing protocol header\n");
1634 		return BNXT_TF_RC_ERROR;
1635 	}
1636 
1637 	size = sizeof(((struct rte_flow_item_icmp6 *)NULL)->type);
1638 	ulp_rte_prsr_fld_mask(params, &idx, size,
1639 			      ulp_deference_struct(icmp_spec, type),
1640 			      ulp_deference_struct(icmp_mask, type),
1641 			      ULP_PRSR_ACT_DEFAULT);
1642 
1643 	size = sizeof(((struct rte_flow_item_icmp6 *)NULL)->code);
1644 	ulp_rte_prsr_fld_mask(params, &idx, size,
1645 			      ulp_deference_struct(icmp_spec, code),
1646 			      ulp_deference_struct(icmp_mask, code),
1647 			      ULP_PRSR_ACT_DEFAULT);
1648 
1649 	size = sizeof(((struct rte_flow_item_icmp6 *)NULL)->checksum);
1650 	ulp_rte_prsr_fld_mask(params, &idx, size,
1651 			      ulp_deference_struct(icmp_spec, checksum),
1652 			      ulp_deference_struct(icmp_mask, checksum),
1653 			      ULP_PRSR_ACT_DEFAULT);
1654 
1655 	if (ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV4)) {
1656 		BNXT_TF_DBG(ERR, "Error: incorrect icmp version\n");
1657 		return BNXT_TF_RC_ERROR;
1658 	}
1659 
1660 	/* Update the hdr_bitmap with ICMP */
1661 	if (ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L3_TUN))
1662 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_ICMP);
1663 	else
1664 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_ICMP);
1665 	return BNXT_TF_RC_SUCCESS;
1666 }
1667 
1668 /* Function to handle the parsing of RTE Flow item void Header */
1669 int32_t
1670 ulp_rte_void_hdr_handler(const struct rte_flow_item *item __rte_unused,
1671 			 struct ulp_rte_parser_params *params __rte_unused)
1672 {
1673 	return BNXT_TF_RC_SUCCESS;
1674 }
1675 
1676 /* Function to handle the parsing of RTE Flow action void Header. */
1677 int32_t
1678 ulp_rte_void_act_handler(const struct rte_flow_action *action_item __rte_unused,
1679 			 struct ulp_rte_parser_params *params __rte_unused)
1680 {
1681 	return BNXT_TF_RC_SUCCESS;
1682 }
1683 
1684 /* Function to handle the parsing of RTE Flow action Mark Header. */
1685 int32_t
1686 ulp_rte_mark_act_handler(const struct rte_flow_action *action_item,
1687 			 struct ulp_rte_parser_params *param)
1688 {
1689 	const struct rte_flow_action_mark *mark;
1690 	struct ulp_rte_act_bitmap *act = &param->act_bitmap;
1691 	uint32_t mark_id;
1692 
1693 	mark = action_item->conf;
1694 	if (mark) {
1695 		mark_id = tfp_cpu_to_be_32(mark->id);
1696 		memcpy(&param->act_prop.act_details[BNXT_ULP_ACT_PROP_IDX_MARK],
1697 		       &mark_id, BNXT_ULP_ACT_PROP_SZ_MARK);
1698 
1699 		/* Update the hdr_bitmap with vxlan */
1700 		ULP_BITMAP_SET(act->bits, BNXT_ULP_ACT_BIT_MARK);
1701 		return BNXT_TF_RC_SUCCESS;
1702 	}
1703 	BNXT_TF_DBG(ERR, "Parse Error: Mark arg is invalid\n");
1704 	return BNXT_TF_RC_ERROR;
1705 }
1706 
1707 /* Function to handle the parsing of RTE Flow action RSS Header. */
1708 int32_t
1709 ulp_rte_rss_act_handler(const struct rte_flow_action *action_item,
1710 			struct ulp_rte_parser_params *param)
1711 {
1712 	const struct rte_flow_action_rss *rss;
1713 	struct ulp_rte_act_prop *ap = &param->act_prop;
1714 
1715 	if (action_item == NULL || action_item->conf == NULL) {
1716 		BNXT_TF_DBG(ERR, "Parse Err: invalid rss configuration\n");
1717 		return BNXT_TF_RC_ERROR;
1718 	}
1719 
1720 	rss = action_item->conf;
1721 	/* Copy the rss into the specific action properties */
1722 	memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_TYPES], &rss->types,
1723 	       BNXT_ULP_ACT_PROP_SZ_RSS_TYPES);
1724 	memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_LEVEL], &rss->level,
1725 	       BNXT_ULP_ACT_PROP_SZ_RSS_LEVEL);
1726 	memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY_LEN],
1727 	       &rss->key_len, BNXT_ULP_ACT_PROP_SZ_RSS_KEY_LEN);
1728 
1729 	if (rss->key_len > BNXT_ULP_ACT_PROP_SZ_RSS_KEY) {
1730 		BNXT_TF_DBG(ERR, "Parse Err: RSS key too big\n");
1731 		return BNXT_TF_RC_ERROR;
1732 	}
1733 	memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_RSS_KEY], rss->key,
1734 	       rss->key_len);
1735 
1736 	/* set the RSS action header bit */
1737 	ULP_BITMAP_SET(param->act_bitmap.bits, BNXT_ULP_ACT_BIT_RSS);
1738 
1739 	return BNXT_TF_RC_SUCCESS;
1740 }
1741 
1742 /* Function to handle the parsing of RTE Flow item eth Header. */
1743 static void
1744 ulp_rte_enc_eth_hdr_handler(struct ulp_rte_parser_params *params,
1745 			    const struct rte_flow_item_eth *eth_spec)
1746 {
1747 	struct ulp_rte_hdr_field *field;
1748 	uint32_t size;
1749 
1750 	field = &params->enc_field[BNXT_ULP_ENC_FIELD_ETH_DMAC];
1751 	size = sizeof(eth_spec->dst.addr_bytes);
1752 	field = ulp_rte_parser_fld_copy(field, eth_spec->dst.addr_bytes, size);
1753 
1754 	size = sizeof(eth_spec->src.addr_bytes);
1755 	field = ulp_rte_parser_fld_copy(field, eth_spec->src.addr_bytes, size);
1756 
1757 	size = sizeof(eth_spec->type);
1758 	field = ulp_rte_parser_fld_copy(field, &eth_spec->type, size);
1759 
1760 	ULP_BITMAP_SET(params->enc_hdr_bitmap.bits, BNXT_ULP_HDR_BIT_O_ETH);
1761 }
1762 
1763 /* Function to handle the parsing of RTE Flow item vlan Header. */
1764 static void
1765 ulp_rte_enc_vlan_hdr_handler(struct ulp_rte_parser_params *params,
1766 			     const struct rte_flow_item_vlan *vlan_spec,
1767 			     uint32_t inner)
1768 {
1769 	struct ulp_rte_hdr_field *field;
1770 	uint32_t size;
1771 
1772 	if (!inner) {
1773 		field = &params->enc_field[BNXT_ULP_ENC_FIELD_O_VLAN_TCI];
1774 		ULP_BITMAP_SET(params->enc_hdr_bitmap.bits,
1775 			       BNXT_ULP_HDR_BIT_OO_VLAN);
1776 	} else {
1777 		field = &params->enc_field[BNXT_ULP_ENC_FIELD_I_VLAN_TCI];
1778 		ULP_BITMAP_SET(params->enc_hdr_bitmap.bits,
1779 			       BNXT_ULP_HDR_BIT_OI_VLAN);
1780 	}
1781 
1782 	size = sizeof(vlan_spec->tci);
1783 	field = ulp_rte_parser_fld_copy(field, &vlan_spec->tci, size);
1784 
1785 	size = sizeof(vlan_spec->inner_type);
1786 	field = ulp_rte_parser_fld_copy(field, &vlan_spec->inner_type, size);
1787 }
1788 
1789 /* Function to handle the parsing of RTE Flow item ipv4 Header. */
1790 static void
1791 ulp_rte_enc_ipv4_hdr_handler(struct ulp_rte_parser_params *params,
1792 			     const struct rte_flow_item_ipv4 *ip)
1793 {
1794 	struct ulp_rte_hdr_field *field;
1795 	uint32_t size;
1796 	uint8_t val8;
1797 
1798 	field = &params->enc_field[BNXT_ULP_ENC_FIELD_IPV4_IHL];
1799 	size = sizeof(ip->hdr.version_ihl);
1800 	if (!ip->hdr.version_ihl)
1801 		val8 = RTE_IPV4_VHL_DEF;
1802 	else
1803 		val8 = ip->hdr.version_ihl;
1804 	field = ulp_rte_parser_fld_copy(field, &val8, size);
1805 
1806 	size = sizeof(ip->hdr.type_of_service);
1807 	field = ulp_rte_parser_fld_copy(field, &ip->hdr.type_of_service, size);
1808 
1809 	size = sizeof(ip->hdr.packet_id);
1810 	field = ulp_rte_parser_fld_copy(field, &ip->hdr.packet_id, size);
1811 
1812 	size = sizeof(ip->hdr.fragment_offset);
1813 	field = ulp_rte_parser_fld_copy(field, &ip->hdr.fragment_offset, size);
1814 
1815 	size = sizeof(ip->hdr.time_to_live);
1816 	if (!ip->hdr.time_to_live)
1817 		val8 = BNXT_ULP_DEFAULT_TTL;
1818 	else
1819 		val8 = ip->hdr.time_to_live;
1820 	field = ulp_rte_parser_fld_copy(field, &val8, size);
1821 
1822 	size = sizeof(ip->hdr.next_proto_id);
1823 	field = ulp_rte_parser_fld_copy(field, &ip->hdr.next_proto_id, size);
1824 
1825 	size = sizeof(ip->hdr.src_addr);
1826 	field = ulp_rte_parser_fld_copy(field, &ip->hdr.src_addr, size);
1827 
1828 	size = sizeof(ip->hdr.dst_addr);
1829 	field = ulp_rte_parser_fld_copy(field, &ip->hdr.dst_addr, size);
1830 
1831 	ULP_BITMAP_SET(params->enc_hdr_bitmap.bits, BNXT_ULP_HDR_BIT_O_IPV4);
1832 }
1833 
1834 /* Function to handle the parsing of RTE Flow item ipv6 Header. */
1835 static void
1836 ulp_rte_enc_ipv6_hdr_handler(struct ulp_rte_parser_params *params,
1837 			     const struct rte_flow_item_ipv6 *ip)
1838 {
1839 	struct ulp_rte_hdr_field *field;
1840 	uint32_t size;
1841 	uint32_t val32;
1842 	uint8_t val8;
1843 
1844 	field = &params->enc_field[BNXT_ULP_ENC_FIELD_IPV6_VTC_FLOW];
1845 	size = sizeof(ip->hdr.vtc_flow);
1846 	if (!ip->hdr.vtc_flow)
1847 		val32 = rte_cpu_to_be_32(BNXT_ULP_IPV6_DFLT_VER);
1848 	else
1849 		val32 = ip->hdr.vtc_flow;
1850 	field = ulp_rte_parser_fld_copy(field, &val32, size);
1851 
1852 	size = sizeof(ip->hdr.proto);
1853 	field = ulp_rte_parser_fld_copy(field, &ip->hdr.proto, size);
1854 
1855 	size = sizeof(ip->hdr.hop_limits);
1856 	if (!ip->hdr.hop_limits)
1857 		val8 = BNXT_ULP_DEFAULT_TTL;
1858 	else
1859 		val8 = ip->hdr.hop_limits;
1860 	field = ulp_rte_parser_fld_copy(field, &val8, size);
1861 
1862 	size = sizeof(ip->hdr.src_addr);
1863 	field = ulp_rte_parser_fld_copy(field, &ip->hdr.src_addr, size);
1864 
1865 	size = sizeof(ip->hdr.dst_addr);
1866 	field = ulp_rte_parser_fld_copy(field, &ip->hdr.dst_addr, size);
1867 
1868 	ULP_BITMAP_SET(params->enc_hdr_bitmap.bits, BNXT_ULP_HDR_BIT_O_IPV6);
1869 }
1870 
1871 /* Function to handle the parsing of RTE Flow item UDP Header. */
1872 static void
1873 ulp_rte_enc_udp_hdr_handler(struct ulp_rte_parser_params *params,
1874 			    const struct rte_flow_item_udp *udp_spec)
1875 {
1876 	struct ulp_rte_hdr_field *field;
1877 	uint32_t size;
1878 	uint8_t type = IPPROTO_UDP;
1879 
1880 	field = &params->enc_field[BNXT_ULP_ENC_FIELD_UDP_SPORT];
1881 	size = sizeof(udp_spec->hdr.src_port);
1882 	field = ulp_rte_parser_fld_copy(field, &udp_spec->hdr.src_port, size);
1883 
1884 	size = sizeof(udp_spec->hdr.dst_port);
1885 	field = ulp_rte_parser_fld_copy(field, &udp_spec->hdr.dst_port, size);
1886 
1887 	ULP_BITMAP_SET(params->enc_hdr_bitmap.bits, BNXT_ULP_HDR_BIT_O_UDP);
1888 
1889 	/* Update thhe ip header protocol */
1890 	field = &params->enc_field[BNXT_ULP_ENC_FIELD_IPV4_PROTO];
1891 	ulp_rte_parser_fld_copy(field, &type, sizeof(type));
1892 	field = &params->enc_field[BNXT_ULP_ENC_FIELD_IPV6_PROTO];
1893 	ulp_rte_parser_fld_copy(field, &type, sizeof(type));
1894 }
1895 
1896 /* Function to handle the parsing of RTE Flow item vxlan Header. */
1897 static void
1898 ulp_rte_enc_vxlan_hdr_handler(struct ulp_rte_parser_params *params,
1899 			      struct rte_flow_item_vxlan *vxlan_spec)
1900 {
1901 	struct ulp_rte_hdr_field *field;
1902 	uint32_t size;
1903 
1904 	field = &params->enc_field[BNXT_ULP_ENC_FIELD_VXLAN_FLAGS];
1905 	size = sizeof(vxlan_spec->flags);
1906 	field = ulp_rte_parser_fld_copy(field, &vxlan_spec->flags, size);
1907 
1908 	size = sizeof(vxlan_spec->rsvd0);
1909 	field = ulp_rte_parser_fld_copy(field, &vxlan_spec->rsvd0, size);
1910 
1911 	size = sizeof(vxlan_spec->vni);
1912 	field = ulp_rte_parser_fld_copy(field, &vxlan_spec->vni, size);
1913 
1914 	size = sizeof(vxlan_spec->rsvd1);
1915 	field = ulp_rte_parser_fld_copy(field, &vxlan_spec->rsvd1, size);
1916 
1917 	ULP_BITMAP_SET(params->enc_hdr_bitmap.bits, BNXT_ULP_HDR_BIT_T_VXLAN);
1918 }
1919 
1920 /* Function to handle the parsing of RTE Flow action vxlan_encap Header. */
1921 int32_t
1922 ulp_rte_vxlan_encap_act_handler(const struct rte_flow_action *action_item,
1923 				struct ulp_rte_parser_params *params)
1924 {
1925 	const struct rte_flow_action_vxlan_encap *vxlan_encap;
1926 	const struct rte_flow_item *item;
1927 	const struct rte_flow_item_ipv4 *ipv4_spec;
1928 	const struct rte_flow_item_ipv6 *ipv6_spec;
1929 	struct rte_flow_item_vxlan vxlan_spec;
1930 	uint32_t vlan_num = 0, vlan_size = 0;
1931 	uint32_t ip_size = 0, ip_type = 0;
1932 	uint32_t vxlan_size = 0;
1933 	struct ulp_rte_act_bitmap *act = &params->act_bitmap;
1934 	struct ulp_rte_act_prop *ap = &params->act_prop;
1935 
1936 	vxlan_encap = action_item->conf;
1937 	if (!vxlan_encap) {
1938 		BNXT_TF_DBG(ERR, "Parse Error: Vxlan_encap arg is invalid\n");
1939 		return BNXT_TF_RC_ERROR;
1940 	}
1941 
1942 	item = vxlan_encap->definition;
1943 	if (!item) {
1944 		BNXT_TF_DBG(ERR, "Parse Error: definition arg is invalid\n");
1945 		return BNXT_TF_RC_ERROR;
1946 	}
1947 
1948 	if (!ulp_rte_item_skip_void(&item, 0))
1949 		return BNXT_TF_RC_ERROR;
1950 
1951 	/* must have ethernet header */
1952 	if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
1953 		BNXT_TF_DBG(ERR, "Parse Error:vxlan encap does not have eth\n");
1954 		return BNXT_TF_RC_ERROR;
1955 	}
1956 
1957 	/* Parse the ethernet header */
1958 	if (item->spec)
1959 		ulp_rte_enc_eth_hdr_handler(params, item->spec);
1960 
1961 	/* Goto the next item */
1962 	if (!ulp_rte_item_skip_void(&item, 1))
1963 		return BNXT_TF_RC_ERROR;
1964 
1965 	/* May have vlan header */
1966 	if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
1967 		vlan_num++;
1968 		if (item->spec)
1969 			ulp_rte_enc_vlan_hdr_handler(params, item->spec, 0);
1970 
1971 		if (!ulp_rte_item_skip_void(&item, 1))
1972 			return BNXT_TF_RC_ERROR;
1973 	}
1974 
1975 	/* may have two vlan headers */
1976 	if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
1977 		vlan_num++;
1978 		if (item->spec)
1979 			ulp_rte_enc_vlan_hdr_handler(params, item->spec, 1);
1980 
1981 		if (!ulp_rte_item_skip_void(&item, 1))
1982 			return BNXT_TF_RC_ERROR;
1983 	}
1984 
1985 	/* Update the vlan count and size of more than one */
1986 	if (vlan_num) {
1987 		vlan_size = vlan_num * sizeof(struct rte_flow_item_vlan);
1988 		vlan_num = tfp_cpu_to_be_32(vlan_num);
1989 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG_NUM],
1990 		       &vlan_num,
1991 		       sizeof(uint32_t));
1992 		vlan_size = tfp_cpu_to_be_32(vlan_size);
1993 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG_SZ],
1994 		       &vlan_size,
1995 		       sizeof(uint32_t));
1996 	}
1997 
1998 	/* L3 must be IPv4, IPv6 */
1999 	if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) {
2000 		ipv4_spec = item->spec;
2001 		ip_size = BNXT_ULP_ENCAP_IPV4_SIZE;
2002 
2003 		/* Update the ip size details */
2004 		ip_size = tfp_cpu_to_be_32(ip_size);
2005 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP_SZ],
2006 		       &ip_size, sizeof(uint32_t));
2007 
2008 		/* update the ip type */
2009 		ip_type = rte_cpu_to_be_32(BNXT_ULP_ETH_IPV4);
2010 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_L3_TYPE],
2011 		       &ip_type, sizeof(uint32_t));
2012 
2013 		/* update the computed field to notify it is ipv4 header */
2014 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_ENCAP_IPV4_FLAG,
2015 				    1);
2016 		if (ipv4_spec)
2017 			ulp_rte_enc_ipv4_hdr_handler(params, ipv4_spec);
2018 
2019 		if (!ulp_rte_item_skip_void(&item, 1))
2020 			return BNXT_TF_RC_ERROR;
2021 	} else if (item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
2022 		ipv6_spec = item->spec;
2023 		ip_size = BNXT_ULP_ENCAP_IPV6_SIZE;
2024 
2025 		/* Update the ip size details */
2026 		ip_size = tfp_cpu_to_be_32(ip_size);
2027 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP_SZ],
2028 		       &ip_size, sizeof(uint32_t));
2029 
2030 		 /* update the ip type */
2031 		ip_type = rte_cpu_to_be_32(BNXT_ULP_ETH_IPV6);
2032 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_L3_TYPE],
2033 		       &ip_type, sizeof(uint32_t));
2034 
2035 		/* update the computed field to notify it is ipv6 header */
2036 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_ENCAP_IPV6_FLAG,
2037 				    1);
2038 		if (ipv6_spec)
2039 			ulp_rte_enc_ipv6_hdr_handler(params, ipv6_spec);
2040 
2041 		if (!ulp_rte_item_skip_void(&item, 1))
2042 			return BNXT_TF_RC_ERROR;
2043 	} else {
2044 		BNXT_TF_DBG(ERR, "Parse Error: Vxlan Encap expects L3 hdr\n");
2045 		return BNXT_TF_RC_ERROR;
2046 	}
2047 
2048 	/* L4 is UDP */
2049 	if (item->type != RTE_FLOW_ITEM_TYPE_UDP) {
2050 		BNXT_TF_DBG(ERR, "vxlan encap does not have udp\n");
2051 		return BNXT_TF_RC_ERROR;
2052 	}
2053 	if (item->spec)
2054 		ulp_rte_enc_udp_hdr_handler(params, item->spec);
2055 
2056 	if (!ulp_rte_item_skip_void(&item, 1))
2057 		return BNXT_TF_RC_ERROR;
2058 
2059 	/* Finally VXLAN */
2060 	if (item->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
2061 		BNXT_TF_DBG(ERR, "vxlan encap does not have vni\n");
2062 		return BNXT_TF_RC_ERROR;
2063 	}
2064 	vxlan_size = sizeof(struct rte_flow_item_vxlan);
2065 	/* copy the vxlan details */
2066 	memcpy(&vxlan_spec, item->spec, vxlan_size);
2067 	vxlan_spec.flags = 0x08;
2068 	vxlan_size = tfp_cpu_to_be_32(vxlan_size);
2069 	memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_TUN_SZ],
2070 	       &vxlan_size, sizeof(uint32_t));
2071 
2072 	ulp_rte_enc_vxlan_hdr_handler(params, &vxlan_spec);
2073 
2074 	/* update the hdr_bitmap with vxlan */
2075 	ULP_BITMAP_SET(act->bits, BNXT_ULP_ACT_BIT_VXLAN_ENCAP);
2076 	return BNXT_TF_RC_SUCCESS;
2077 }
2078 
2079 /* Function to handle the parsing of RTE Flow action vxlan_encap Header */
2080 int32_t
2081 ulp_rte_vxlan_decap_act_handler(const struct rte_flow_action *action_item
2082 				__rte_unused,
2083 				struct ulp_rte_parser_params *params)
2084 {
2085 	/* update the hdr_bitmap with vxlan */
2086 	ULP_BITMAP_SET(params->act_bitmap.bits,
2087 		       BNXT_ULP_ACT_BIT_VXLAN_DECAP);
2088 	/* Update computational field with tunnel decap info */
2089 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_TUN_DECAP, 1);
2090 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_TUN, 1);
2091 	return BNXT_TF_RC_SUCCESS;
2092 }
2093 
2094 /* Function to handle the parsing of RTE Flow action drop Header. */
2095 int32_t
2096 ulp_rte_drop_act_handler(const struct rte_flow_action *action_item __rte_unused,
2097 			 struct ulp_rte_parser_params *params)
2098 {
2099 	/* Update the hdr_bitmap with drop */
2100 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACT_BIT_DROP);
2101 	return BNXT_TF_RC_SUCCESS;
2102 }
2103 
2104 /* Function to handle the parsing of RTE Flow action count. */
2105 int32_t
2106 ulp_rte_count_act_handler(const struct rte_flow_action *action_item,
2107 			  struct ulp_rte_parser_params *params)
2108 {
2109 	const struct rte_flow_action_count *act_count;
2110 	struct ulp_rte_act_prop *act_prop = &params->act_prop;
2111 
2112 	act_count = action_item->conf;
2113 	if (act_count) {
2114 		if (act_count->shared) {
2115 			BNXT_TF_DBG(ERR,
2116 				    "Parse Error:Shared count not supported\n");
2117 			return BNXT_TF_RC_PARSE_ERR;
2118 		}
2119 		memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_COUNT],
2120 		       &act_count->id,
2121 		       BNXT_ULP_ACT_PROP_SZ_COUNT);
2122 	}
2123 
2124 	/* Update the hdr_bitmap with count */
2125 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACT_BIT_COUNT);
2126 	return BNXT_TF_RC_SUCCESS;
2127 }
2128 
2129 /* Function to handle the parsing of action ports. */
2130 static int32_t
2131 ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
2132 			    uint32_t ifindex)
2133 {
2134 	enum bnxt_ulp_direction_type dir;
2135 	uint16_t pid_s;
2136 	uint32_t pid;
2137 	struct ulp_rte_act_prop *act = &param->act_prop;
2138 	enum bnxt_ulp_intf_type port_type;
2139 	uint32_t vnic_type;
2140 
2141 	/* Get the direction */
2142 	dir = ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_DIRECTION);
2143 	if (dir == BNXT_ULP_DIR_EGRESS) {
2144 		/* For egress direction, fill vport */
2145 		if (ulp_port_db_vport_get(param->ulp_ctx, ifindex, &pid_s))
2146 			return BNXT_TF_RC_ERROR;
2147 
2148 		pid = pid_s;
2149 		pid = rte_cpu_to_be_32(pid);
2150 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_VPORT],
2151 		       &pid, BNXT_ULP_ACT_PROP_SZ_VPORT);
2152 	} else {
2153 		/* For ingress direction, fill vnic */
2154 		port_type = ULP_COMP_FLD_IDX_RD(param,
2155 						BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
2156 		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
2157 			vnic_type = BNXT_ULP_VF_FUNC_VNIC;
2158 		else
2159 			vnic_type = BNXT_ULP_DRV_FUNC_VNIC;
2160 
2161 		if (ulp_port_db_default_vnic_get(param->ulp_ctx, ifindex,
2162 						 vnic_type, &pid_s))
2163 			return BNXT_TF_RC_ERROR;
2164 
2165 		pid = pid_s;
2166 		pid = rte_cpu_to_be_32(pid);
2167 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_VNIC],
2168 		       &pid, BNXT_ULP_ACT_PROP_SZ_VNIC);
2169 	}
2170 
2171 	/* Update the action port set bit */
2172 	ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET, 1);
2173 	return BNXT_TF_RC_SUCCESS;
2174 }
2175 
2176 /* Function to handle the parsing of RTE Flow action PF. */
2177 int32_t
2178 ulp_rte_pf_act_handler(const struct rte_flow_action *action_item __rte_unused,
2179 		       struct ulp_rte_parser_params *params)
2180 {
2181 	uint32_t port_id;
2182 	uint32_t ifindex;
2183 	enum bnxt_ulp_intf_type intf_type;
2184 
2185 	/* Get the port id of the current device */
2186 	port_id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
2187 
2188 	/* Get the port db ifindex */
2189 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx, port_id,
2190 					      &ifindex)) {
2191 		BNXT_TF_DBG(ERR, "Invalid port id\n");
2192 		return BNXT_TF_RC_ERROR;
2193 	}
2194 
2195 	/* Check the port is PF port */
2196 	intf_type = ulp_port_db_port_type_get(params->ulp_ctx, ifindex);
2197 	if (intf_type != BNXT_ULP_INTF_TYPE_PF) {
2198 		BNXT_TF_DBG(ERR, "Port is not a PF port\n");
2199 		return BNXT_TF_RC_ERROR;
2200 	}
2201 	/* Update the action properties */
2202 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
2203 	return ulp_rte_parser_act_port_set(params, ifindex);
2204 }
2205 
2206 /* Function to handle the parsing of RTE Flow action VF. */
2207 int32_t
2208 ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
2209 		       struct ulp_rte_parser_params *params)
2210 {
2211 	const struct rte_flow_action_vf *vf_action;
2212 	enum bnxt_ulp_intf_type intf_type;
2213 	uint32_t ifindex;
2214 	struct bnxt *bp;
2215 
2216 	vf_action = action_item->conf;
2217 	if (!vf_action) {
2218 		BNXT_TF_DBG(ERR, "ParseErr: Invalid Argument\n");
2219 		return BNXT_TF_RC_PARSE_ERR;
2220 	}
2221 
2222 	if (vf_action->original) {
2223 		BNXT_TF_DBG(ERR, "ParseErr:VF Original not supported\n");
2224 		return BNXT_TF_RC_PARSE_ERR;
2225 	}
2226 
2227 	bp = bnxt_pmd_get_bp(params->port_id);
2228 	if (bp == NULL) {
2229 		BNXT_TF_DBG(ERR, "Invalid bp\n");
2230 		return BNXT_TF_RC_ERROR;
2231 	}
2232 
2233 	/* vf_action->id is a logical number which in this case is an
2234 	 * offset from the first VF. So, to get the absolute VF id, the
2235 	 * offset must be added to the absolute first vf id of that port.
2236 	 */
2237 	if (ulp_port_db_dev_func_id_to_ulp_index(params->ulp_ctx,
2238 						 bp->first_vf_id +
2239 						 vf_action->id,
2240 						 &ifindex)) {
2241 		BNXT_TF_DBG(ERR, "VF is not valid interface\n");
2242 		return BNXT_TF_RC_ERROR;
2243 	}
2244 	/* Check the port is VF port */
2245 	intf_type = ulp_port_db_port_type_get(params->ulp_ctx, ifindex);
2246 	if (intf_type != BNXT_ULP_INTF_TYPE_VF &&
2247 	    intf_type != BNXT_ULP_INTF_TYPE_TRUSTED_VF) {
2248 		BNXT_TF_DBG(ERR, "Port is not a VF port\n");
2249 		return BNXT_TF_RC_ERROR;
2250 	}
2251 
2252 	/* Update the action properties */
2253 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
2254 	return ulp_rte_parser_act_port_set(params, ifindex);
2255 }
2256 
2257 /* Function to handle the parsing of RTE Flow action port_id. */
2258 int32_t
2259 ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
2260 			    struct ulp_rte_parser_params *param)
2261 {
2262 	const struct rte_flow_action_port_id *port_id = act_item->conf;
2263 	uint32_t ifindex;
2264 	enum bnxt_ulp_intf_type intf_type;
2265 
2266 	if (!port_id) {
2267 		BNXT_TF_DBG(ERR,
2268 			    "ParseErr: Invalid Argument\n");
2269 		return BNXT_TF_RC_PARSE_ERR;
2270 	}
2271 	if (port_id->original) {
2272 		BNXT_TF_DBG(ERR,
2273 			    "ParseErr:Portid Original not supported\n");
2274 		return BNXT_TF_RC_PARSE_ERR;
2275 	}
2276 
2277 	/* Get the port db ifindex */
2278 	if (ulp_port_db_dev_port_to_ulp_index(param->ulp_ctx, port_id->id,
2279 					      &ifindex)) {
2280 		BNXT_TF_DBG(ERR, "Invalid port id\n");
2281 		return BNXT_TF_RC_ERROR;
2282 	}
2283 
2284 	/* Get the intf type */
2285 	intf_type = ulp_port_db_port_type_get(param->ulp_ctx, ifindex);
2286 	if (!intf_type) {
2287 		BNXT_TF_DBG(ERR, "Invalid port type\n");
2288 		return BNXT_TF_RC_ERROR;
2289 	}
2290 
2291 	/* Set the action port */
2292 	ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
2293 	return ulp_rte_parser_act_port_set(param, ifindex);
2294 }
2295 
2296 /* Function to handle the parsing of RTE Flow action phy_port. */
2297 int32_t
2298 ulp_rte_phy_port_act_handler(const struct rte_flow_action *action_item,
2299 			     struct ulp_rte_parser_params *prm)
2300 {
2301 	const struct rte_flow_action_phy_port *phy_port;
2302 	uint32_t pid;
2303 	int32_t rc;
2304 	uint16_t pid_s;
2305 	enum bnxt_ulp_direction_type dir;
2306 
2307 	phy_port = action_item->conf;
2308 	if (!phy_port) {
2309 		BNXT_TF_DBG(ERR,
2310 			    "ParseErr: Invalid Argument\n");
2311 		return BNXT_TF_RC_PARSE_ERR;
2312 	}
2313 
2314 	if (phy_port->original) {
2315 		BNXT_TF_DBG(ERR,
2316 			    "Parse Err:Port Original not supported\n");
2317 		return BNXT_TF_RC_PARSE_ERR;
2318 	}
2319 	dir = ULP_COMP_FLD_IDX_RD(prm, BNXT_ULP_CF_IDX_DIRECTION);
2320 	if (dir != BNXT_ULP_DIR_EGRESS) {
2321 		BNXT_TF_DBG(ERR,
2322 			    "Parse Err:Phy ports are valid only for egress\n");
2323 		return BNXT_TF_RC_PARSE_ERR;
2324 	}
2325 	/* Get the physical port details from port db */
2326 	rc = ulp_port_db_phy_port_vport_get(prm->ulp_ctx, phy_port->index,
2327 					    &pid_s);
2328 	if (rc) {
2329 		BNXT_TF_DBG(ERR, "Failed to get port details\n");
2330 		return -EINVAL;
2331 	}
2332 
2333 	pid = pid_s;
2334 	pid = rte_cpu_to_be_32(pid);
2335 	memcpy(&prm->act_prop.act_details[BNXT_ULP_ACT_PROP_IDX_VPORT],
2336 	       &pid, BNXT_ULP_ACT_PROP_SZ_VPORT);
2337 
2338 	/* Update the action port set bit */
2339 	ULP_COMP_FLD_IDX_WR(prm, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET, 1);
2340 	ULP_COMP_FLD_IDX_WR(prm, BNXT_ULP_CF_IDX_ACT_PORT_TYPE,
2341 			    BNXT_ULP_INTF_TYPE_PHY_PORT);
2342 	return BNXT_TF_RC_SUCCESS;
2343 }
2344 
2345 /* Function to handle the parsing of RTE Flow action pop vlan. */
2346 int32_t
2347 ulp_rte_of_pop_vlan_act_handler(const struct rte_flow_action *a __rte_unused,
2348 				struct ulp_rte_parser_params *params)
2349 {
2350 	/* Update the act_bitmap with pop */
2351 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACT_BIT_POP_VLAN);
2352 	return BNXT_TF_RC_SUCCESS;
2353 }
2354 
2355 /* Function to handle the parsing of RTE Flow action push vlan. */
2356 int32_t
2357 ulp_rte_of_push_vlan_act_handler(const struct rte_flow_action *action_item,
2358 				 struct ulp_rte_parser_params *params)
2359 {
2360 	const struct rte_flow_action_of_push_vlan *push_vlan;
2361 	uint16_t ethertype;
2362 	struct ulp_rte_act_prop *act = &params->act_prop;
2363 
2364 	push_vlan = action_item->conf;
2365 	if (push_vlan) {
2366 		ethertype = push_vlan->ethertype;
2367 		if (tfp_cpu_to_be_16(ethertype) != RTE_ETHER_TYPE_VLAN) {
2368 			BNXT_TF_DBG(ERR,
2369 				    "Parse Err: Ethertype not supported\n");
2370 			return BNXT_TF_RC_PARSE_ERR;
2371 		}
2372 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_PUSH_VLAN],
2373 		       &ethertype, BNXT_ULP_ACT_PROP_SZ_PUSH_VLAN);
2374 		/* Update the hdr_bitmap with push vlan */
2375 		ULP_BITMAP_SET(params->act_bitmap.bits,
2376 			       BNXT_ULP_ACT_BIT_PUSH_VLAN);
2377 		return BNXT_TF_RC_SUCCESS;
2378 	}
2379 	BNXT_TF_DBG(ERR, "Parse Error: Push vlan arg is invalid\n");
2380 	return BNXT_TF_RC_ERROR;
2381 }
2382 
2383 /* Function to handle the parsing of RTE Flow action set vlan id. */
2384 int32_t
2385 ulp_rte_of_set_vlan_vid_act_handler(const struct rte_flow_action *action_item,
2386 				    struct ulp_rte_parser_params *params)
2387 {
2388 	const struct rte_flow_action_of_set_vlan_vid *vlan_vid;
2389 	uint32_t vid;
2390 	struct ulp_rte_act_prop *act = &params->act_prop;
2391 
2392 	vlan_vid = action_item->conf;
2393 	if (vlan_vid && vlan_vid->vlan_vid) {
2394 		vid = vlan_vid->vlan_vid;
2395 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_VLAN_VID],
2396 		       &vid, BNXT_ULP_ACT_PROP_SZ_SET_VLAN_VID);
2397 		/* Update the hdr_bitmap with vlan vid */
2398 		ULP_BITMAP_SET(params->act_bitmap.bits,
2399 			       BNXT_ULP_ACT_BIT_SET_VLAN_VID);
2400 		return BNXT_TF_RC_SUCCESS;
2401 	}
2402 	BNXT_TF_DBG(ERR, "Parse Error: Vlan vid arg is invalid\n");
2403 	return BNXT_TF_RC_ERROR;
2404 }
2405 
2406 /* Function to handle the parsing of RTE Flow action set vlan pcp. */
2407 int32_t
2408 ulp_rte_of_set_vlan_pcp_act_handler(const struct rte_flow_action *action_item,
2409 				    struct ulp_rte_parser_params *params)
2410 {
2411 	const struct rte_flow_action_of_set_vlan_pcp *vlan_pcp;
2412 	uint8_t pcp;
2413 	struct ulp_rte_act_prop *act = &params->act_prop;
2414 
2415 	vlan_pcp = action_item->conf;
2416 	if (vlan_pcp) {
2417 		pcp = vlan_pcp->vlan_pcp;
2418 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_VLAN_PCP],
2419 		       &pcp, BNXT_ULP_ACT_PROP_SZ_SET_VLAN_PCP);
2420 		/* Update the hdr_bitmap with vlan vid */
2421 		ULP_BITMAP_SET(params->act_bitmap.bits,
2422 			       BNXT_ULP_ACT_BIT_SET_VLAN_PCP);
2423 		return BNXT_TF_RC_SUCCESS;
2424 	}
2425 	BNXT_TF_DBG(ERR, "Parse Error: Vlan pcp arg is invalid\n");
2426 	return BNXT_TF_RC_ERROR;
2427 }
2428 
2429 /* Function to handle the parsing of RTE Flow action set ipv4 src.*/
2430 int32_t
2431 ulp_rte_set_ipv4_src_act_handler(const struct rte_flow_action *action_item,
2432 				 struct ulp_rte_parser_params *params)
2433 {
2434 	const struct rte_flow_action_set_ipv4 *set_ipv4;
2435 	struct ulp_rte_act_prop *act = &params->act_prop;
2436 
2437 	set_ipv4 = action_item->conf;
2438 	if (set_ipv4) {
2439 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_IPV4_SRC],
2440 		       &set_ipv4->ipv4_addr, BNXT_ULP_ACT_PROP_SZ_SET_IPV4_SRC);
2441 		/* Update the hdr_bitmap with set ipv4 src */
2442 		ULP_BITMAP_SET(params->act_bitmap.bits,
2443 			       BNXT_ULP_ACT_BIT_SET_IPV4_SRC);
2444 		return BNXT_TF_RC_SUCCESS;
2445 	}
2446 	BNXT_TF_DBG(ERR, "Parse Error: set ipv4 src arg is invalid\n");
2447 	return BNXT_TF_RC_ERROR;
2448 }
2449 
2450 /* Function to handle the parsing of RTE Flow action set ipv4 dst.*/
2451 int32_t
2452 ulp_rte_set_ipv4_dst_act_handler(const struct rte_flow_action *action_item,
2453 				 struct ulp_rte_parser_params *params)
2454 {
2455 	const struct rte_flow_action_set_ipv4 *set_ipv4;
2456 	struct ulp_rte_act_prop *act = &params->act_prop;
2457 
2458 	set_ipv4 = action_item->conf;
2459 	if (set_ipv4) {
2460 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_IPV4_DST],
2461 		       &set_ipv4->ipv4_addr, BNXT_ULP_ACT_PROP_SZ_SET_IPV4_DST);
2462 		/* Update the hdr_bitmap with set ipv4 dst */
2463 		ULP_BITMAP_SET(params->act_bitmap.bits,
2464 			       BNXT_ULP_ACT_BIT_SET_IPV4_DST);
2465 		return BNXT_TF_RC_SUCCESS;
2466 	}
2467 	BNXT_TF_DBG(ERR, "Parse Error: set ipv4 dst arg is invalid\n");
2468 	return BNXT_TF_RC_ERROR;
2469 }
2470 
2471 /* Function to handle the parsing of RTE Flow action set tp src.*/
2472 int32_t
2473 ulp_rte_set_tp_src_act_handler(const struct rte_flow_action *action_item,
2474 			       struct ulp_rte_parser_params *params)
2475 {
2476 	const struct rte_flow_action_set_tp *set_tp;
2477 	struct ulp_rte_act_prop *act = &params->act_prop;
2478 
2479 	set_tp = action_item->conf;
2480 	if (set_tp) {
2481 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_TP_SRC],
2482 		       &set_tp->port, BNXT_ULP_ACT_PROP_SZ_SET_TP_SRC);
2483 		/* Update the hdr_bitmap with set tp src */
2484 		ULP_BITMAP_SET(params->act_bitmap.bits,
2485 			       BNXT_ULP_ACT_BIT_SET_TP_SRC);
2486 		return BNXT_TF_RC_SUCCESS;
2487 	}
2488 
2489 	BNXT_TF_DBG(ERR, "Parse Error: set tp src arg is invalid\n");
2490 	return BNXT_TF_RC_ERROR;
2491 }
2492 
2493 /* Function to handle the parsing of RTE Flow action set tp dst.*/
2494 int32_t
2495 ulp_rte_set_tp_dst_act_handler(const struct rte_flow_action *action_item,
2496 			       struct ulp_rte_parser_params *params)
2497 {
2498 	const struct rte_flow_action_set_tp *set_tp;
2499 	struct ulp_rte_act_prop *act = &params->act_prop;
2500 
2501 	set_tp = action_item->conf;
2502 	if (set_tp) {
2503 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_TP_DST],
2504 		       &set_tp->port, BNXT_ULP_ACT_PROP_SZ_SET_TP_DST);
2505 		/* Update the hdr_bitmap with set tp dst */
2506 		ULP_BITMAP_SET(params->act_bitmap.bits,
2507 			       BNXT_ULP_ACT_BIT_SET_TP_DST);
2508 		return BNXT_TF_RC_SUCCESS;
2509 	}
2510 
2511 	BNXT_TF_DBG(ERR, "Parse Error: set tp src arg is invalid\n");
2512 	return BNXT_TF_RC_ERROR;
2513 }
2514 
2515 /* Function to handle the parsing of RTE Flow action dec ttl.*/
2516 int32_t
2517 ulp_rte_dec_ttl_act_handler(const struct rte_flow_action *act __rte_unused,
2518 			    struct ulp_rte_parser_params *params)
2519 {
2520 	/* Update the act_bitmap with dec ttl */
2521 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACT_BIT_DEC_TTL);
2522 	return BNXT_TF_RC_SUCCESS;
2523 }
2524 
2525 /* Function to handle the parsing of RTE Flow action JUMP */
2526 int32_t
2527 ulp_rte_jump_act_handler(const struct rte_flow_action *action_item __rte_unused,
2528 			 struct ulp_rte_parser_params *params)
2529 {
2530 	/* Update the act_bitmap with dec ttl */
2531 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACT_BIT_JUMP);
2532 	return BNXT_TF_RC_SUCCESS;
2533 }
2534 
2535 int32_t
2536 ulp_rte_sample_act_handler(const struct rte_flow_action *action_item,
2537 			   struct ulp_rte_parser_params *params)
2538 {
2539 	const struct rte_flow_action_sample *sample;
2540 	int ret;
2541 
2542 	sample = action_item->conf;
2543 
2544 	/* if SAMPLE bit is set it means this sample action is nested within the
2545 	 * actions of another sample action; this is not allowed
2546 	 */
2547 	if (ULP_BITMAP_ISSET(params->act_bitmap.bits,
2548 			     BNXT_ULP_ACT_BIT_SAMPLE))
2549 		return BNXT_TF_RC_ERROR;
2550 
2551 	/* a sample action is only allowed as a shared action */
2552 	if (!ULP_BITMAP_ISSET(params->act_bitmap.bits,
2553 			      BNXT_ULP_ACT_BIT_SHARED))
2554 		return BNXT_TF_RC_ERROR;
2555 
2556 	/* only a ratio of 1 i.e. 100% is supported */
2557 	if (sample->ratio != 1)
2558 		return BNXT_TF_RC_ERROR;
2559 
2560 	if (!sample->actions)
2561 		return BNXT_TF_RC_ERROR;
2562 
2563 	/* parse the nested actions for a sample action */
2564 	ret = bnxt_ulp_rte_parser_act_parse(sample->actions, params);
2565 	if (ret == BNXT_TF_RC_SUCCESS)
2566 		/* Update the act_bitmap with sample */
2567 		ULP_BITMAP_SET(params->act_bitmap.bits,
2568 			       BNXT_ULP_ACT_BIT_SAMPLE);
2569 
2570 	return ret;
2571 }
2572 
2573 /* Function to handle the parsing of bnxt vendor Flow action vxlan Header. */
2574 int32_t
2575 ulp_vendor_vxlan_decap_act_handler(const struct rte_flow_action *action_item,
2576 				   struct ulp_rte_parser_params *params)
2577 {
2578 	/* Set the F1 flow header bit */
2579 	ULP_BITMAP_SET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_F1);
2580 	return ulp_rte_vxlan_decap_act_handler(action_item, params);
2581 }
2582 
2583 /* Function to handle the parsing of bnxt vendor Flow item vxlan Header. */
2584 int32_t
2585 ulp_rte_vendor_vxlan_decap_hdr_handler(const struct rte_flow_item *item,
2586 				       struct ulp_rte_parser_params *params)
2587 {
2588 	RTE_SET_USED(item);
2589 	/* Set the F2 flow header bit */
2590 	ULP_BITMAP_SET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_F2);
2591 	return ulp_rte_vxlan_decap_act_handler(NULL, params);
2592 }
2593