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