xref: /dpdk/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c (revision 10b71caecbe1cddcbb65c050ca775fba575e88db)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2020 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_tf_common.h"
10 #include "ulp_rte_parser.h"
11 #include "ulp_utils.h"
12 #include "tfp.h"
13 #include "ulp_port_db.h"
14 
15 /* Local defines for the parsing functions */
16 #define ULP_VLAN_PRIORITY_SHIFT		13 /* First 3 bits */
17 #define ULP_VLAN_PRIORITY_MASK		0x700
18 #define ULP_VLAN_TAG_MASK		0xFFF /* Last 12 bits*/
19 #define ULP_UDP_PORT_VXLAN		4789
20 
21 /* Utility function to skip the void items. */
22 static inline int32_t
23 ulp_rte_item_skip_void(const struct rte_flow_item **item, uint32_t increment)
24 {
25 	if (!*item)
26 		return 0;
27 	if (increment)
28 		(*item)++;
29 	while ((*item) && (*item)->type == RTE_FLOW_ITEM_TYPE_VOID)
30 		(*item)++;
31 	if (*item)
32 		return 1;
33 	return 0;
34 }
35 
36 /* Utility function to update the field_bitmap */
37 static void
38 ulp_rte_parser_field_bitmap_update(struct ulp_rte_parser_params *params,
39 				   uint32_t idx)
40 {
41 	struct ulp_rte_hdr_field *field;
42 
43 	field = &params->hdr_field[idx];
44 	if (ulp_bitmap_notzero(field->mask, field->size)) {
45 		ULP_INDEX_BITMAP_SET(params->fld_bitmap.bits, idx);
46 		/* Not exact match */
47 		if (!ulp_bitmap_is_ones(field->mask, field->size))
48 			ULP_BITMAP_SET(params->fld_bitmap.bits,
49 				       BNXT_ULP_MATCH_TYPE_BITMASK_WM);
50 	} else {
51 		ULP_INDEX_BITMAP_RESET(params->fld_bitmap.bits, idx);
52 	}
53 }
54 
55 /* Utility function to copy field spec items */
56 static struct ulp_rte_hdr_field *
57 ulp_rte_parser_fld_copy(struct ulp_rte_hdr_field *field,
58 			const void *buffer,
59 			uint32_t size)
60 {
61 	field->size = size;
62 	memcpy(field->spec, buffer, field->size);
63 	field++;
64 	return field;
65 }
66 
67 /* Utility function to copy field masks items */
68 static void
69 ulp_rte_prsr_mask_copy(struct ulp_rte_parser_params *params,
70 		       uint32_t *idx,
71 		       const void *buffer,
72 		       uint32_t size)
73 {
74 	struct ulp_rte_hdr_field *field = &params->hdr_field[*idx];
75 
76 	memcpy(field->mask, buffer, size);
77 	ulp_rte_parser_field_bitmap_update(params, *idx);
78 	*idx = *idx + 1;
79 }
80 
81 /*
82  * Function to handle the parsing of RTE Flows and placing
83  * the RTE flow items into the ulp structures.
84  */
85 int32_t
86 bnxt_ulp_rte_parser_hdr_parse(const struct rte_flow_item pattern[],
87 			      struct ulp_rte_parser_params *params)
88 {
89 	const struct rte_flow_item *item = pattern;
90 	struct bnxt_ulp_rte_hdr_info *hdr_info;
91 
92 	params->field_idx = BNXT_ULP_PROTO_HDR_SVIF_NUM;
93 
94 	/* Set the computed flags for no vlan tags before parsing */
95 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_NO_VTAG, 1);
96 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_NO_VTAG, 1);
97 
98 	/* Parse all the items in the pattern */
99 	while (item && item->type != RTE_FLOW_ITEM_TYPE_END) {
100 		/* get the header information from the flow_hdr_info table */
101 		hdr_info = &ulp_hdr_info[item->type];
102 		if (hdr_info->hdr_type == BNXT_ULP_HDR_TYPE_NOT_SUPPORTED) {
103 			BNXT_TF_DBG(ERR,
104 				    "Truflow parser does not support type %d\n",
105 				    item->type);
106 			return BNXT_TF_RC_PARSE_ERR;
107 		} else if (hdr_info->hdr_type == BNXT_ULP_HDR_TYPE_SUPPORTED) {
108 			/* call the registered callback handler */
109 			if (hdr_info->proto_hdr_func) {
110 				if (hdr_info->proto_hdr_func(item, params) !=
111 				    BNXT_TF_RC_SUCCESS) {
112 					return BNXT_TF_RC_ERROR;
113 				}
114 			}
115 		}
116 		item++;
117 	}
118 	/* update the implied SVIF */
119 	return ulp_rte_parser_implicit_match_port_process(params);
120 }
121 
122 /*
123  * Function to handle the parsing of RTE Flows and placing
124  * the RTE flow actions into the ulp structures.
125  */
126 int32_t
127 bnxt_ulp_rte_parser_act_parse(const struct rte_flow_action actions[],
128 			      struct ulp_rte_parser_params *params)
129 {
130 	const struct rte_flow_action *action_item = actions;
131 	struct bnxt_ulp_rte_act_info *hdr_info;
132 
133 	/* Parse all the items in the pattern */
134 	while (action_item && action_item->type != RTE_FLOW_ACTION_TYPE_END) {
135 		/* get the header information from the flow_hdr_info table */
136 		hdr_info = &ulp_act_info[action_item->type];
137 		if (hdr_info->act_type ==
138 		    BNXT_ULP_ACT_TYPE_NOT_SUPPORTED) {
139 			BNXT_TF_DBG(ERR,
140 				    "Truflow parser does not support act %u\n",
141 				    action_item->type);
142 			return BNXT_TF_RC_ERROR;
143 		} else if (hdr_info->act_type ==
144 		    BNXT_ULP_ACT_TYPE_SUPPORTED) {
145 			/* call the registered callback handler */
146 			if (hdr_info->proto_act_func) {
147 				if (hdr_info->proto_act_func(action_item,
148 							     params) !=
149 				    BNXT_TF_RC_SUCCESS) {
150 					return BNXT_TF_RC_ERROR;
151 				}
152 			}
153 		}
154 		action_item++;
155 	}
156 	/* update the implied port details */
157 	ulp_rte_parser_implicit_act_port_process(params);
158 	return BNXT_TF_RC_SUCCESS;
159 }
160 
161 /*
162  * Function to handle the post processing of the computed
163  * fields for the interface.
164  */
165 static void
166 bnxt_ulp_comp_fld_intf_update(struct ulp_rte_parser_params *params)
167 {
168 	uint32_t ifindex;
169 	uint16_t port_id, parif;
170 	uint32_t mtype;
171 	enum bnxt_ulp_direction_type dir;
172 
173 	/* get the direction details */
174 	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
175 
176 	/* read the port id details */
177 	port_id = ULP_COMP_FLD_IDX_RD(params,
178 				      BNXT_ULP_CF_IDX_INCOMING_IF);
179 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
180 					      port_id,
181 					      &ifindex)) {
182 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
183 		return;
184 	}
185 
186 	if (dir == BNXT_ULP_DIR_INGRESS) {
187 		/* Set port PARIF */
188 		if (ulp_port_db_parif_get(params->ulp_ctx, ifindex,
189 					  BNXT_ULP_PHY_PORT_PARIF, &parif)) {
190 			BNXT_TF_DBG(ERR, "ParseErr:ifindex is not valid\n");
191 			return;
192 		}
193 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_PHY_PORT_PARIF,
194 				    parif);
195 	} else {
196 		/* Get the match port type */
197 		mtype = ULP_COMP_FLD_IDX_RD(params,
198 					    BNXT_ULP_CF_IDX_MATCH_PORT_TYPE);
199 		if (mtype == BNXT_ULP_INTF_TYPE_VF_REP) {
200 			ULP_COMP_FLD_IDX_WR(params,
201 					    BNXT_ULP_CF_IDX_MATCH_PORT_IS_VFREP,
202 					    1);
203 			/* Set VF func PARIF */
204 			if (ulp_port_db_parif_get(params->ulp_ctx, ifindex,
205 						  BNXT_ULP_VF_FUNC_PARIF,
206 						  &parif)) {
207 				BNXT_TF_DBG(ERR,
208 					    "ParseErr:ifindex is not valid\n");
209 				return;
210 			}
211 			ULP_COMP_FLD_IDX_WR(params,
212 					    BNXT_ULP_CF_IDX_VF_FUNC_PARIF,
213 					    parif);
214 		} else {
215 			/* Set DRV func PARIF */
216 			if (ulp_port_db_parif_get(params->ulp_ctx, ifindex,
217 						  BNXT_ULP_DRV_FUNC_PARIF,
218 						  &parif)) {
219 				BNXT_TF_DBG(ERR,
220 					    "ParseErr:ifindex is not valid\n");
221 				return;
222 			}
223 			ULP_COMP_FLD_IDX_WR(params,
224 					    BNXT_ULP_CF_IDX_DRV_FUNC_PARIF,
225 					    parif);
226 		}
227 	}
228 }
229 
230 /*
231  * Function to handle the post processing of the parsing details
232  */
233 int32_t
234 bnxt_ulp_rte_parser_post_process(struct ulp_rte_parser_params *params)
235 {
236 	enum bnxt_ulp_direction_type dir;
237 	enum bnxt_ulp_intf_type match_port_type, act_port_type;
238 	uint32_t act_port_set;
239 
240 	/* Get the computed details */
241 	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
242 	match_port_type = ULP_COMP_FLD_IDX_RD(params,
243 					      BNXT_ULP_CF_IDX_MATCH_PORT_TYPE);
244 	act_port_type = ULP_COMP_FLD_IDX_RD(params,
245 					    BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
246 	act_port_set = ULP_COMP_FLD_IDX_RD(params,
247 					   BNXT_ULP_CF_IDX_ACT_PORT_IS_SET);
248 
249 	/* set the flow direction in the proto and action header */
250 	if (dir == BNXT_ULP_DIR_EGRESS) {
251 		ULP_BITMAP_SET(params->hdr_bitmap.bits,
252 			       BNXT_ULP_FLOW_DIR_BITMASK_EGR);
253 		ULP_BITMAP_SET(params->act_bitmap.bits,
254 			       BNXT_ULP_FLOW_DIR_BITMASK_EGR);
255 	}
256 
257 	/* calculate the VF to VF flag */
258 	if (act_port_set && act_port_type == BNXT_ULP_INTF_TYPE_VF_REP &&
259 	    match_port_type == BNXT_ULP_INTF_TYPE_VF_REP)
260 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_VF_TO_VF, 1);
261 
262 	/* Update the decrement ttl computational fields */
263 	if (ULP_BITMAP_ISSET(params->act_bitmap.bits,
264 			     BNXT_ULP_ACTION_BIT_DEC_TTL)) {
265 		/*
266 		 * Check that vxlan proto is included and vxlan decap
267 		 * action is not set then decrement tunnel ttl.
268 		 * Similarly add GRE and NVGRE in future.
269 		 */
270 		if ((ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
271 				      BNXT_ULP_HDR_BIT_T_VXLAN) &&
272 		    !ULP_BITMAP_ISSET(params->act_bitmap.bits,
273 				      BNXT_ULP_ACTION_BIT_VXLAN_DECAP))) {
274 			ULP_COMP_FLD_IDX_WR(params,
275 					    BNXT_ULP_CF_IDX_ACT_T_DEC_TTL, 1);
276 		} else {
277 			ULP_COMP_FLD_IDX_WR(params,
278 					    BNXT_ULP_CF_IDX_ACT_DEC_TTL, 1);
279 		}
280 	}
281 
282 	/* Merge the hdr_fp_bit into the proto header bit */
283 	params->hdr_bitmap.bits |= params->hdr_fp_bit.bits;
284 
285 	/* Update the computed interface parameters */
286 	bnxt_ulp_comp_fld_intf_update(params);
287 
288 	/* TBD: Handle the flow rejection scenarios */
289 	return 0;
290 }
291 
292 /*
293  * Function to compute the flow direction based on the match port details
294  */
295 static void
296 bnxt_ulp_rte_parser_direction_compute(struct ulp_rte_parser_params *params)
297 {
298 	enum bnxt_ulp_intf_type match_port_type;
299 
300 	/* Get the match port type */
301 	match_port_type = ULP_COMP_FLD_IDX_RD(params,
302 					      BNXT_ULP_CF_IDX_MATCH_PORT_TYPE);
303 
304 	/* If ingress flow and matchport is vf rep then dir is egress*/
305 	if ((params->dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS) &&
306 	    match_port_type == BNXT_ULP_INTF_TYPE_VF_REP) {
307 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_DIRECTION,
308 				    BNXT_ULP_DIR_EGRESS);
309 	} else {
310 		/* Assign the input direction */
311 		if (params->dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS)
312 			ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_DIRECTION,
313 					    BNXT_ULP_DIR_INGRESS);
314 		else
315 			ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_DIRECTION,
316 					    BNXT_ULP_DIR_EGRESS);
317 	}
318 }
319 
320 /* Function to handle the parsing of RTE Flow item PF Header. */
321 static int32_t
322 ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,
323 			uint32_t ifindex,
324 			uint16_t mask)
325 {
326 	uint16_t svif;
327 	enum bnxt_ulp_direction_type dir;
328 	struct ulp_rte_hdr_field *hdr_field;
329 	enum bnxt_ulp_svif_type svif_type;
330 	enum bnxt_ulp_intf_type port_type;
331 
332 	if (ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_SVIF_FLAG) !=
333 	    BNXT_ULP_INVALID_SVIF_VAL) {
334 		BNXT_TF_DBG(ERR,
335 			    "SVIF already set,multiple source not support'd\n");
336 		return BNXT_TF_RC_ERROR;
337 	}
338 
339 	/* Get port type details */
340 	port_type = ulp_port_db_port_type_get(params->ulp_ctx, ifindex);
341 	if (port_type == BNXT_ULP_INTF_TYPE_INVALID) {
342 		BNXT_TF_DBG(ERR, "Invalid port type\n");
343 		return BNXT_TF_RC_ERROR;
344 	}
345 
346 	/* Update the match port type */
347 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_MATCH_PORT_TYPE, port_type);
348 
349 	/* compute the direction */
350 	bnxt_ulp_rte_parser_direction_compute(params);
351 
352 	/* Get the computed direction */
353 	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
354 	if (dir == BNXT_ULP_DIR_INGRESS) {
355 		svif_type = BNXT_ULP_PHY_PORT_SVIF;
356 	} else {
357 		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
358 			svif_type = BNXT_ULP_VF_FUNC_SVIF;
359 		else
360 			svif_type = BNXT_ULP_DRV_FUNC_SVIF;
361 	}
362 	ulp_port_db_svif_get(params->ulp_ctx, ifindex, svif_type,
363 			     &svif);
364 	svif = rte_cpu_to_be_16(svif);
365 	hdr_field = &params->hdr_field[BNXT_ULP_PROTO_HDR_FIELD_SVIF_IDX];
366 	memcpy(hdr_field->spec, &svif, sizeof(svif));
367 	memcpy(hdr_field->mask, &mask, sizeof(mask));
368 	hdr_field->size = sizeof(svif);
369 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_SVIF_FLAG,
370 			    rte_be_to_cpu_16(svif));
371 	return BNXT_TF_RC_SUCCESS;
372 }
373 
374 /* Function to handle the parsing of the RTE port id */
375 int32_t
376 ulp_rte_parser_implicit_match_port_process(struct ulp_rte_parser_params *params)
377 {
378 	uint16_t port_id = 0;
379 	uint16_t svif_mask = 0xFFFF;
380 	uint32_t ifindex;
381 	int32_t rc = BNXT_TF_RC_ERROR;
382 
383 	if (ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_SVIF_FLAG) !=
384 	    BNXT_ULP_INVALID_SVIF_VAL)
385 		return BNXT_TF_RC_SUCCESS;
386 
387 	/* SVIF not set. So get the port id */
388 	port_id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
389 
390 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
391 					      port_id,
392 					      &ifindex)) {
393 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
394 		return rc;
395 	}
396 
397 	/* Update the SVIF details */
398 	rc = ulp_rte_parser_svif_set(params, ifindex, svif_mask);
399 	return rc;
400 }
401 
402 /* Function to handle the implicit action port id */
403 int32_t
404 ulp_rte_parser_implicit_act_port_process(struct ulp_rte_parser_params *params)
405 {
406 	struct rte_flow_action action_item = {0};
407 	struct rte_flow_action_port_id port_id = {0};
408 
409 	/* Read the action port set bit */
410 	if (ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET)) {
411 		/* Already set, so just exit */
412 		return BNXT_TF_RC_SUCCESS;
413 	}
414 	port_id.id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
415 	action_item.conf = &port_id;
416 
417 	/* Update the action port based on incoming port */
418 	ulp_rte_port_id_act_handler(&action_item, params);
419 
420 	/* Reset the action port set bit */
421 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET, 0);
422 	return BNXT_TF_RC_SUCCESS;
423 }
424 
425 /* Function to handle the parsing of RTE Flow item PF Header. */
426 int32_t
427 ulp_rte_pf_hdr_handler(const struct rte_flow_item *item __rte_unused,
428 		       struct ulp_rte_parser_params *params)
429 {
430 	uint16_t port_id = 0;
431 	uint16_t svif_mask = 0xFFFF;
432 	uint32_t ifindex;
433 
434 	/* Get the implicit port id */
435 	port_id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
436 
437 	/* perform the conversion from dpdk port to bnxt ifindex */
438 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
439 					      port_id,
440 					      &ifindex)) {
441 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
442 		return BNXT_TF_RC_ERROR;
443 	}
444 
445 	/* Update the SVIF details */
446 	return  ulp_rte_parser_svif_set(params, ifindex, svif_mask);
447 }
448 
449 /* Function to handle the parsing of RTE Flow item VF Header. */
450 int32_t
451 ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,
452 		       struct ulp_rte_parser_params *params)
453 {
454 	const struct rte_flow_item_vf *vf_spec = item->spec;
455 	const struct rte_flow_item_vf *vf_mask = item->mask;
456 	uint16_t mask = 0;
457 	uint32_t ifindex;
458 	int32_t rc = BNXT_TF_RC_PARSE_ERR;
459 
460 	/* Get VF rte_flow_item for Port details */
461 	if (!vf_spec) {
462 		BNXT_TF_DBG(ERR, "ParseErr:VF id is not valid\n");
463 		return rc;
464 	}
465 	if (!vf_mask) {
466 		BNXT_TF_DBG(ERR, "ParseErr:VF mask is not valid\n");
467 		return rc;
468 	}
469 	mask = vf_mask->id;
470 
471 	/* perform the conversion from VF Func id to bnxt ifindex */
472 	if (ulp_port_db_dev_func_id_to_ulp_index(params->ulp_ctx,
473 						 vf_spec->id,
474 						 &ifindex)) {
475 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
476 		return rc;
477 	}
478 	/* Update the SVIF details */
479 	return ulp_rte_parser_svif_set(params, ifindex, mask);
480 }
481 
482 /* Function to handle the parsing of RTE Flow item port id  Header. */
483 int32_t
484 ulp_rte_port_id_hdr_handler(const struct rte_flow_item *item,
485 			    struct ulp_rte_parser_params *params)
486 {
487 	const struct rte_flow_item_port_id *port_spec = item->spec;
488 	const struct rte_flow_item_port_id *port_mask = item->mask;
489 	uint16_t mask = 0;
490 	int32_t rc = BNXT_TF_RC_PARSE_ERR;
491 	uint32_t ifindex;
492 
493 	if (!port_spec) {
494 		BNXT_TF_DBG(ERR, "ParseErr:Port id is not valid\n");
495 		return rc;
496 	}
497 	if (!port_mask) {
498 		BNXT_TF_DBG(ERR, "ParseErr:Phy Port mask is not valid\n");
499 		return rc;
500 	}
501 	mask = port_mask->id;
502 
503 	/* perform the conversion from dpdk port to bnxt ifindex */
504 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
505 					      port_spec->id,
506 					      &ifindex)) {
507 		BNXT_TF_DBG(ERR, "ParseErr:Portid is not valid\n");
508 		return rc;
509 	}
510 	/* Update the SVIF details */
511 	return ulp_rte_parser_svif_set(params, ifindex, mask);
512 }
513 
514 /* Function to handle the parsing of RTE Flow item phy port Header. */
515 int32_t
516 ulp_rte_phy_port_hdr_handler(const struct rte_flow_item *item,
517 			     struct ulp_rte_parser_params *params)
518 {
519 	const struct rte_flow_item_phy_port *port_spec = item->spec;
520 	const struct rte_flow_item_phy_port *port_mask = item->mask;
521 	uint16_t mask = 0;
522 	int32_t rc = BNXT_TF_RC_ERROR;
523 	uint16_t svif;
524 	enum bnxt_ulp_direction_type dir;
525 	struct ulp_rte_hdr_field *hdr_field;
526 
527 	/* Copy the rte_flow_item for phy port into hdr_field */
528 	if (!port_spec) {
529 		BNXT_TF_DBG(ERR, "ParseErr:Phy Port id is not valid\n");
530 		return rc;
531 	}
532 	if (!port_mask) {
533 		BNXT_TF_DBG(ERR, "ParseErr:Phy Port mask is not valid\n");
534 		return rc;
535 	}
536 	mask = port_mask->index;
537 
538 	/* Update the match port type */
539 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_MATCH_PORT_TYPE,
540 			    BNXT_ULP_INTF_TYPE_PHY_PORT);
541 
542 	/* Compute the Hw direction */
543 	bnxt_ulp_rte_parser_direction_compute(params);
544 
545 	/* Direction validation */
546 	dir = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_DIRECTION);
547 	if (dir == BNXT_ULP_DIR_EGRESS) {
548 		BNXT_TF_DBG(ERR,
549 			    "Parse Err:Phy ports are valid only for ingress\n");
550 		return BNXT_TF_RC_PARSE_ERR;
551 	}
552 
553 	/* Get the physical port details from port db */
554 	rc = ulp_port_db_phy_port_svif_get(params->ulp_ctx, port_spec->index,
555 					   &svif);
556 	if (rc) {
557 		BNXT_TF_DBG(ERR, "Failed to get port details\n");
558 		return BNXT_TF_RC_PARSE_ERR;
559 	}
560 
561 	/* Update the SVIF details */
562 	svif = rte_cpu_to_be_16(svif);
563 	hdr_field = &params->hdr_field[BNXT_ULP_PROTO_HDR_FIELD_SVIF_IDX];
564 	memcpy(hdr_field->spec, &svif, sizeof(svif));
565 	memcpy(hdr_field->mask, &mask, sizeof(mask));
566 	hdr_field->size = sizeof(svif);
567 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_SVIF_FLAG,
568 			    rte_be_to_cpu_16(svif));
569 	return BNXT_TF_RC_SUCCESS;
570 }
571 
572 /* Function to handle the update of proto header based on field values */
573 static void
574 ulp_rte_l2_proto_type_update(struct ulp_rte_parser_params *param,
575 			     uint16_t type, uint32_t in_flag)
576 {
577 	if (type == tfp_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {
578 		if (in_flag) {
579 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
580 				       BNXT_ULP_HDR_BIT_I_IPV4);
581 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_I_L3, 1);
582 		} else {
583 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
584 				       BNXT_ULP_HDR_BIT_O_IPV4);
585 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_O_L3, 1);
586 		}
587 	} else if (type == tfp_cpu_to_be_16(RTE_ETHER_TYPE_IPV6))  {
588 		if (in_flag) {
589 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
590 				       BNXT_ULP_HDR_BIT_I_IPV6);
591 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_I_L3, 1);
592 		} else {
593 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
594 				       BNXT_ULP_HDR_BIT_O_IPV6);
595 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_O_L3, 1);
596 		}
597 	}
598 }
599 
600 /* Function to handle the parsing of RTE Flow item Ethernet Header. */
601 int32_t
602 ulp_rte_eth_hdr_handler(const struct rte_flow_item *item,
603 			struct ulp_rte_parser_params *params)
604 {
605 	const struct rte_flow_item_eth *eth_spec = item->spec;
606 	const struct rte_flow_item_eth *eth_mask = item->mask;
607 	struct ulp_rte_hdr_field *field;
608 	uint32_t idx = params->field_idx;
609 	uint32_t size;
610 	uint16_t eth_type = 0;
611 	uint32_t inner_flag = 0;
612 
613 	/*
614 	 * Copy the rte_flow_item for eth into hdr_field using ethernet
615 	 * header fields
616 	 */
617 	if (eth_spec) {
618 		size = sizeof(eth_spec->dst.addr_bytes);
619 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
620 						eth_spec->dst.addr_bytes,
621 						size);
622 		size = sizeof(eth_spec->src.addr_bytes);
623 		field = ulp_rte_parser_fld_copy(field,
624 						eth_spec->src.addr_bytes,
625 						size);
626 		field = ulp_rte_parser_fld_copy(field,
627 						&eth_spec->type,
628 						sizeof(eth_spec->type));
629 		eth_type = eth_spec->type;
630 	}
631 	if (eth_mask) {
632 		ulp_rte_prsr_mask_copy(params, &idx, eth_mask->dst.addr_bytes,
633 				       sizeof(eth_mask->dst.addr_bytes));
634 		ulp_rte_prsr_mask_copy(params, &idx, eth_mask->src.addr_bytes,
635 				       sizeof(eth_mask->src.addr_bytes));
636 		ulp_rte_prsr_mask_copy(params, &idx, &eth_mask->type,
637 				       sizeof(eth_mask->type));
638 	}
639 	/* Add number of vlan header elements */
640 	params->field_idx += BNXT_ULP_PROTO_HDR_ETH_NUM;
641 	params->vlan_idx = params->field_idx;
642 	params->field_idx += BNXT_ULP_PROTO_HDR_VLAN_NUM;
643 
644 	/* Update the protocol hdr bitmap */
645 	if (ULP_BITMAP_ISSET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_O_ETH)) {
646 		ULP_BITMAP_SET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_I_ETH);
647 		inner_flag = 1;
648 	} else {
649 		ULP_BITMAP_SET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_O_ETH);
650 	}
651 	/* Update the field protocol hdr bitmap */
652 	ulp_rte_l2_proto_type_update(params, eth_type, inner_flag);
653 
654 	return BNXT_TF_RC_SUCCESS;
655 }
656 
657 /* Function to handle the parsing of RTE Flow item Vlan Header. */
658 int32_t
659 ulp_rte_vlan_hdr_handler(const struct rte_flow_item *item,
660 			 struct ulp_rte_parser_params *params)
661 {
662 	const struct rte_flow_item_vlan *vlan_spec = item->spec;
663 	const struct rte_flow_item_vlan *vlan_mask = item->mask;
664 	struct ulp_rte_hdr_field *field;
665 	struct ulp_rte_hdr_bitmap	*hdr_bit;
666 	uint32_t idx = params->vlan_idx;
667 	uint16_t vlan_tag, priority;
668 	uint32_t outer_vtag_num;
669 	uint32_t inner_vtag_num;
670 	uint16_t eth_type = 0;
671 	uint32_t inner_flag = 0;
672 
673 	/*
674 	 * Copy the rte_flow_item for vlan into hdr_field using Vlan
675 	 * header fields
676 	 */
677 	if (vlan_spec) {
678 		vlan_tag = ntohs(vlan_spec->tci);
679 		priority = htons(vlan_tag >> ULP_VLAN_PRIORITY_SHIFT);
680 		vlan_tag &= ULP_VLAN_TAG_MASK;
681 		vlan_tag = htons(vlan_tag);
682 
683 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
684 						&priority,
685 						sizeof(priority));
686 		field = ulp_rte_parser_fld_copy(field,
687 						&vlan_tag,
688 						sizeof(vlan_tag));
689 		field = ulp_rte_parser_fld_copy(field,
690 						&vlan_spec->inner_type,
691 						sizeof(vlan_spec->inner_type));
692 		eth_type = vlan_spec->inner_type;
693 	}
694 
695 	if (vlan_mask) {
696 		vlan_tag = ntohs(vlan_mask->tci);
697 		priority = htons(vlan_tag >> ULP_VLAN_PRIORITY_SHIFT);
698 		vlan_tag &= 0xfff;
699 
700 		/*
701 		 * the storage for priority and vlan tag is 2 bytes
702 		 * The mask of priority which is 3 bits if it is all 1's
703 		 * then make the rest bits 13 bits as 1's
704 		 * so that it is matched as exact match.
705 		 */
706 		if (priority == ULP_VLAN_PRIORITY_MASK)
707 			priority |= ~ULP_VLAN_PRIORITY_MASK;
708 		if (vlan_tag == ULP_VLAN_TAG_MASK)
709 			vlan_tag |= ~ULP_VLAN_TAG_MASK;
710 		vlan_tag = htons(vlan_tag);
711 
712 		/*
713 		 * The priority field is ignored since OVS is setting it as
714 		 * wild card match and it is not supported. This is a work
715 		 * around and shall be addressed in the future.
716 		 */
717 		idx += 1;
718 
719 		ulp_rte_prsr_mask_copy(params, &idx, &vlan_tag,
720 				       sizeof(vlan_tag));
721 		ulp_rte_prsr_mask_copy(params, &idx, &vlan_mask->inner_type,
722 				       sizeof(vlan_mask->inner_type));
723 	}
724 	/* Set the vlan index to new incremented value */
725 	params->vlan_idx += BNXT_ULP_PROTO_HDR_S_VLAN_NUM;
726 
727 	/* Get the outer tag and inner tag counts */
728 	outer_vtag_num = ULP_COMP_FLD_IDX_RD(params,
729 					     BNXT_ULP_CF_IDX_O_VTAG_NUM);
730 	inner_vtag_num = ULP_COMP_FLD_IDX_RD(params,
731 					     BNXT_ULP_CF_IDX_I_VTAG_NUM);
732 
733 	/* Update the hdr_bitmap of the vlans */
734 	hdr_bit = &params->hdr_bitmap;
735 	if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
736 	    !ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_I_ETH) &&
737 	    !outer_vtag_num) {
738 		/* Update the vlan tag num */
739 		outer_vtag_num++;
740 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_VTAG_NUM,
741 				    outer_vtag_num);
742 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_NO_VTAG, 0);
743 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_ONE_VTAG, 1);
744 		ULP_BITMAP_SET(params->hdr_bitmap.bits,
745 			       BNXT_ULP_HDR_BIT_OO_VLAN);
746 	} else if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
747 		   !ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_I_ETH) &&
748 		   outer_vtag_num == 1) {
749 		/* update the vlan tag num */
750 		outer_vtag_num++;
751 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_VTAG_NUM,
752 				    outer_vtag_num);
753 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_TWO_VTAGS, 1);
754 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_ONE_VTAG, 0);
755 		ULP_BITMAP_SET(params->hdr_bitmap.bits,
756 			       BNXT_ULP_HDR_BIT_OI_VLAN);
757 	} else if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
758 		   ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_I_ETH) &&
759 		   !inner_vtag_num) {
760 		/* update the vlan tag num */
761 		inner_vtag_num++;
762 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_VTAG_NUM,
763 				    inner_vtag_num);
764 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_NO_VTAG, 0);
765 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_ONE_VTAG, 1);
766 		ULP_BITMAP_SET(params->hdr_bitmap.bits,
767 			       BNXT_ULP_HDR_BIT_IO_VLAN);
768 		inner_flag = 1;
769 	} else if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
770 		   ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_I_ETH) &&
771 		   inner_vtag_num == 1) {
772 		/* update the vlan tag num */
773 		inner_vtag_num++;
774 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_VTAG_NUM,
775 				    inner_vtag_num);
776 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_TWO_VTAGS, 1);
777 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_ONE_VTAG, 0);
778 		ULP_BITMAP_SET(params->hdr_bitmap.bits,
779 			       BNXT_ULP_HDR_BIT_II_VLAN);
780 		inner_flag = 1;
781 	} else {
782 		BNXT_TF_DBG(ERR, "Error Parsing:Vlan hdr found withtout eth\n");
783 		return BNXT_TF_RC_ERROR;
784 	}
785 	/* Update the field protocol hdr bitmap */
786 	ulp_rte_l2_proto_type_update(params, eth_type, inner_flag);
787 	return BNXT_TF_RC_SUCCESS;
788 }
789 
790 /* Function to handle the update of proto header based on field values */
791 static void
792 ulp_rte_l3_proto_type_update(struct ulp_rte_parser_params *param,
793 			     uint8_t proto, uint32_t in_flag)
794 {
795 	if (proto == IPPROTO_UDP) {
796 		if (in_flag) {
797 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
798 				       BNXT_ULP_HDR_BIT_I_UDP);
799 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_I_L4, 1);
800 		} else {
801 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
802 				       BNXT_ULP_HDR_BIT_O_UDP);
803 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_O_L4, 1);
804 		}
805 	} else if (proto == IPPROTO_TCP) {
806 		if (in_flag) {
807 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
808 				       BNXT_ULP_HDR_BIT_I_TCP);
809 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_I_L4, 1);
810 		} else {
811 			ULP_BITMAP_SET(param->hdr_fp_bit.bits,
812 				       BNXT_ULP_HDR_BIT_O_TCP);
813 			ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_O_L4, 1);
814 		}
815 	}
816 }
817 
818 /* Function to handle the parsing of RTE Flow item IPV4 Header. */
819 int32_t
820 ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,
821 			 struct ulp_rte_parser_params *params)
822 {
823 	const struct rte_flow_item_ipv4 *ipv4_spec = item->spec;
824 	const struct rte_flow_item_ipv4 *ipv4_mask = item->mask;
825 	struct ulp_rte_hdr_field *field;
826 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
827 	uint32_t idx = params->field_idx;
828 	uint32_t size;
829 	uint8_t proto = 0;
830 	uint32_t inner_flag = 0;
831 	uint32_t cnt;
832 
833 	/* validate there are no 3rd L3 header */
834 	cnt = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L3_HDR_CNT);
835 	if (cnt == 2) {
836 		BNXT_TF_DBG(ERR, "Parse Err:Third L3 header not supported\n");
837 		return BNXT_TF_RC_ERROR;
838 	}
839 
840 	/*
841 	 * Copy the rte_flow_item for ipv4 into hdr_field using ipv4
842 	 * header fields
843 	 */
844 	if (ipv4_spec) {
845 		size = sizeof(ipv4_spec->hdr.version_ihl);
846 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
847 						&ipv4_spec->hdr.version_ihl,
848 						size);
849 		size = sizeof(ipv4_spec->hdr.type_of_service);
850 		field = ulp_rte_parser_fld_copy(field,
851 						&ipv4_spec->hdr.type_of_service,
852 						size);
853 		size = sizeof(ipv4_spec->hdr.total_length);
854 		field = ulp_rte_parser_fld_copy(field,
855 						&ipv4_spec->hdr.total_length,
856 						size);
857 		size = sizeof(ipv4_spec->hdr.packet_id);
858 		field = ulp_rte_parser_fld_copy(field,
859 						&ipv4_spec->hdr.packet_id,
860 						size);
861 		size = sizeof(ipv4_spec->hdr.fragment_offset);
862 		field = ulp_rte_parser_fld_copy(field,
863 						&ipv4_spec->hdr.fragment_offset,
864 						size);
865 		size = sizeof(ipv4_spec->hdr.time_to_live);
866 		field = ulp_rte_parser_fld_copy(field,
867 						&ipv4_spec->hdr.time_to_live,
868 						size);
869 		size = sizeof(ipv4_spec->hdr.next_proto_id);
870 		field = ulp_rte_parser_fld_copy(field,
871 						&ipv4_spec->hdr.next_proto_id,
872 						size);
873 		proto = ipv4_spec->hdr.next_proto_id;
874 		size = sizeof(ipv4_spec->hdr.hdr_checksum);
875 		field = ulp_rte_parser_fld_copy(field,
876 						&ipv4_spec->hdr.hdr_checksum,
877 						size);
878 		size = sizeof(ipv4_spec->hdr.src_addr);
879 		field = ulp_rte_parser_fld_copy(field,
880 						&ipv4_spec->hdr.src_addr,
881 						size);
882 		size = sizeof(ipv4_spec->hdr.dst_addr);
883 		field = ulp_rte_parser_fld_copy(field,
884 						&ipv4_spec->hdr.dst_addr,
885 						size);
886 	}
887 	if (ipv4_mask) {
888 		ulp_rte_prsr_mask_copy(params, &idx,
889 				       &ipv4_mask->hdr.version_ihl,
890 				       sizeof(ipv4_mask->hdr.version_ihl));
891 		/*
892 		 * The tos field is ignored since OVS is setting it as wild card
893 		 * match and it is not supported. This is a work around and
894 		 * shall be addressed in the future.
895 		 */
896 		idx += 1;
897 
898 		ulp_rte_prsr_mask_copy(params, &idx,
899 				       &ipv4_mask->hdr.total_length,
900 				       sizeof(ipv4_mask->hdr.total_length));
901 		ulp_rte_prsr_mask_copy(params, &idx,
902 				       &ipv4_mask->hdr.packet_id,
903 				       sizeof(ipv4_mask->hdr.packet_id));
904 		ulp_rte_prsr_mask_copy(params, &idx,
905 				       &ipv4_mask->hdr.fragment_offset,
906 				       sizeof(ipv4_mask->hdr.fragment_offset));
907 		ulp_rte_prsr_mask_copy(params, &idx,
908 				       &ipv4_mask->hdr.time_to_live,
909 				       sizeof(ipv4_mask->hdr.time_to_live));
910 		ulp_rte_prsr_mask_copy(params, &idx,
911 				       &ipv4_mask->hdr.next_proto_id,
912 				       sizeof(ipv4_mask->hdr.next_proto_id));
913 		ulp_rte_prsr_mask_copy(params, &idx,
914 				       &ipv4_mask->hdr.hdr_checksum,
915 				       sizeof(ipv4_mask->hdr.hdr_checksum));
916 		ulp_rte_prsr_mask_copy(params, &idx,
917 				       &ipv4_mask->hdr.src_addr,
918 				       sizeof(ipv4_mask->hdr.src_addr));
919 		ulp_rte_prsr_mask_copy(params, &idx,
920 				       &ipv4_mask->hdr.dst_addr,
921 				       sizeof(ipv4_mask->hdr.dst_addr));
922 	}
923 	/* Add the number of ipv4 header elements */
924 	params->field_idx += BNXT_ULP_PROTO_HDR_IPV4_NUM;
925 
926 	/* Set the ipv4 header bitmap and computed l3 header bitmaps */
927 	if (ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV4) ||
928 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV6)) {
929 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_IPV4);
930 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L3, 1);
931 		inner_flag = 1;
932 	} else {
933 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV4);
934 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L3, 1);
935 	}
936 
937 	/* Update the field protocol hdr bitmap */
938 	ulp_rte_l3_proto_type_update(params, proto, inner_flag);
939 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_HDR_CNT, ++cnt);
940 	return BNXT_TF_RC_SUCCESS;
941 }
942 
943 /* Function to handle the parsing of RTE Flow item IPV6 Header */
944 int32_t
945 ulp_rte_ipv6_hdr_handler(const struct rte_flow_item *item,
946 			 struct ulp_rte_parser_params *params)
947 {
948 	const struct rte_flow_item_ipv6	*ipv6_spec = item->spec;
949 	const struct rte_flow_item_ipv6	*ipv6_mask = item->mask;
950 	struct ulp_rte_hdr_field *field;
951 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
952 	uint32_t idx = params->field_idx;
953 	uint32_t size;
954 	uint32_t vtcf, vtcf_mask;
955 	uint8_t proto = 0;
956 	uint32_t inner_flag = 0;
957 	uint32_t cnt;
958 
959 	/* validate there are no 3rd L3 header */
960 	cnt = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L3_HDR_CNT);
961 	if (cnt == 2) {
962 		BNXT_TF_DBG(ERR, "Parse Err:Third L3 header not supported\n");
963 		return BNXT_TF_RC_ERROR;
964 	}
965 
966 	/*
967 	 * Copy the rte_flow_item for ipv6 into hdr_field using ipv6
968 	 * header fields
969 	 */
970 	if (ipv6_spec) {
971 		size = sizeof(ipv6_spec->hdr.vtc_flow);
972 
973 		vtcf = BNXT_ULP_GET_IPV6_VER(ipv6_spec->hdr.vtc_flow);
974 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
975 						&vtcf,
976 						size);
977 
978 		vtcf = BNXT_ULP_GET_IPV6_TC(ipv6_spec->hdr.vtc_flow);
979 		field = ulp_rte_parser_fld_copy(field,
980 						&vtcf,
981 						size);
982 
983 		vtcf = BNXT_ULP_GET_IPV6_FLOWLABEL(ipv6_spec->hdr.vtc_flow);
984 		field = ulp_rte_parser_fld_copy(field,
985 						&vtcf,
986 						size);
987 
988 		size = sizeof(ipv6_spec->hdr.payload_len);
989 		field = ulp_rte_parser_fld_copy(field,
990 						&ipv6_spec->hdr.payload_len,
991 						size);
992 		size = sizeof(ipv6_spec->hdr.proto);
993 		field = ulp_rte_parser_fld_copy(field,
994 						&ipv6_spec->hdr.proto,
995 						size);
996 		proto = ipv6_spec->hdr.proto;
997 		size = sizeof(ipv6_spec->hdr.hop_limits);
998 		field = ulp_rte_parser_fld_copy(field,
999 						&ipv6_spec->hdr.hop_limits,
1000 						size);
1001 		size = sizeof(ipv6_spec->hdr.src_addr);
1002 		field = ulp_rte_parser_fld_copy(field,
1003 						&ipv6_spec->hdr.src_addr,
1004 						size);
1005 		size = sizeof(ipv6_spec->hdr.dst_addr);
1006 		field = ulp_rte_parser_fld_copy(field,
1007 						&ipv6_spec->hdr.dst_addr,
1008 						size);
1009 	}
1010 	if (ipv6_mask) {
1011 		size = sizeof(ipv6_mask->hdr.vtc_flow);
1012 
1013 		vtcf_mask = BNXT_ULP_GET_IPV6_VER(ipv6_mask->hdr.vtc_flow);
1014 		ulp_rte_prsr_mask_copy(params, &idx,
1015 				       &vtcf_mask,
1016 				       size);
1017 
1018 		vtcf_mask = BNXT_ULP_GET_IPV6_TC(ipv6_mask->hdr.vtc_flow);
1019 		ulp_rte_prsr_mask_copy(params, &idx,
1020 				       &vtcf_mask,
1021 				       size);
1022 
1023 		vtcf_mask =
1024 			BNXT_ULP_GET_IPV6_FLOWLABEL(ipv6_mask->hdr.vtc_flow);
1025 		ulp_rte_prsr_mask_copy(params, &idx,
1026 				       &vtcf_mask,
1027 				       size);
1028 
1029 		ulp_rte_prsr_mask_copy(params, &idx,
1030 				       &ipv6_mask->hdr.payload_len,
1031 				       sizeof(ipv6_mask->hdr.payload_len));
1032 		ulp_rte_prsr_mask_copy(params, &idx,
1033 				       &ipv6_mask->hdr.proto,
1034 				       sizeof(ipv6_mask->hdr.proto));
1035 		ulp_rte_prsr_mask_copy(params, &idx,
1036 				       &ipv6_mask->hdr.hop_limits,
1037 				       sizeof(ipv6_mask->hdr.hop_limits));
1038 		ulp_rte_prsr_mask_copy(params, &idx,
1039 				       &ipv6_mask->hdr.src_addr,
1040 				       sizeof(ipv6_mask->hdr.src_addr));
1041 		ulp_rte_prsr_mask_copy(params, &idx,
1042 				       &ipv6_mask->hdr.dst_addr,
1043 				       sizeof(ipv6_mask->hdr.dst_addr));
1044 	}
1045 	/* add number of ipv6 header elements */
1046 	params->field_idx += BNXT_ULP_PROTO_HDR_IPV6_NUM;
1047 
1048 	/* Set the ipv6 header bitmap and computed l3 header bitmaps */
1049 	if (ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV4) ||
1050 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV6)) {
1051 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_IPV6);
1052 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L3, 1);
1053 		inner_flag = 1;
1054 	} else {
1055 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV6);
1056 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L3, 1);
1057 	}
1058 
1059 	/* Update the field protocol hdr bitmap */
1060 	ulp_rte_l3_proto_type_update(params, proto, inner_flag);
1061 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_HDR_CNT, ++cnt);
1062 
1063 	return BNXT_TF_RC_SUCCESS;
1064 }
1065 
1066 /* Function to handle the update of proto header based on field values */
1067 static void
1068 ulp_rte_l4_proto_type_update(struct ulp_rte_parser_params *param,
1069 			     uint16_t dst_port)
1070 {
1071 	if (dst_port == tfp_cpu_to_be_16(ULP_UDP_PORT_VXLAN))
1072 		ULP_BITMAP_SET(param->hdr_fp_bit.bits,
1073 			       BNXT_ULP_HDR_BIT_T_VXLAN);
1074 }
1075 
1076 /* Function to handle the parsing of RTE Flow item UDP Header. */
1077 int32_t
1078 ulp_rte_udp_hdr_handler(const struct rte_flow_item *item,
1079 			struct ulp_rte_parser_params *params)
1080 {
1081 	const struct rte_flow_item_udp *udp_spec = item->spec;
1082 	const struct rte_flow_item_udp *udp_mask = item->mask;
1083 	struct ulp_rte_hdr_field *field;
1084 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
1085 	uint32_t idx = params->field_idx;
1086 	uint32_t size;
1087 	uint16_t dst_port = 0;
1088 	uint32_t cnt;
1089 
1090 	cnt = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L4_HDR_CNT);
1091 	if (cnt == 2) {
1092 		BNXT_TF_DBG(ERR, "Parse Err:Third L4 header not supported\n");
1093 		return BNXT_TF_RC_ERROR;
1094 	}
1095 
1096 	/*
1097 	 * Copy the rte_flow_item for ipv4 into hdr_field using ipv4
1098 	 * header fields
1099 	 */
1100 	if (udp_spec) {
1101 		size = sizeof(udp_spec->hdr.src_port);
1102 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
1103 						&udp_spec->hdr.src_port,
1104 						size);
1105 		size = sizeof(udp_spec->hdr.dst_port);
1106 		field = ulp_rte_parser_fld_copy(field,
1107 						&udp_spec->hdr.dst_port,
1108 						size);
1109 		dst_port = udp_spec->hdr.dst_port;
1110 		size = sizeof(udp_spec->hdr.dgram_len);
1111 		field = ulp_rte_parser_fld_copy(field,
1112 						&udp_spec->hdr.dgram_len,
1113 						size);
1114 		size = sizeof(udp_spec->hdr.dgram_cksum);
1115 		field = ulp_rte_parser_fld_copy(field,
1116 						&udp_spec->hdr.dgram_cksum,
1117 						size);
1118 	}
1119 	if (udp_mask) {
1120 		ulp_rte_prsr_mask_copy(params, &idx,
1121 				       &udp_mask->hdr.src_port,
1122 				       sizeof(udp_mask->hdr.src_port));
1123 		ulp_rte_prsr_mask_copy(params, &idx,
1124 				       &udp_mask->hdr.dst_port,
1125 				       sizeof(udp_mask->hdr.dst_port));
1126 		ulp_rte_prsr_mask_copy(params, &idx,
1127 				       &udp_mask->hdr.dgram_len,
1128 				       sizeof(udp_mask->hdr.dgram_len));
1129 		ulp_rte_prsr_mask_copy(params, &idx,
1130 				       &udp_mask->hdr.dgram_cksum,
1131 				       sizeof(udp_mask->hdr.dgram_cksum));
1132 	}
1133 
1134 	/* Add number of UDP header elements */
1135 	params->field_idx += BNXT_ULP_PROTO_HDR_UDP_NUM;
1136 
1137 	/* Set the udp header bitmap and computed l4 header bitmaps */
1138 	if (ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_UDP) ||
1139 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP)) {
1140 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_UDP);
1141 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L4, 1);
1142 	} else {
1143 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_UDP);
1144 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4, 1);
1145 		/* Update the field protocol hdr bitmap */
1146 		ulp_rte_l4_proto_type_update(params, dst_port);
1147 	}
1148 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L4_HDR_CNT, ++cnt);
1149 	return BNXT_TF_RC_SUCCESS;
1150 }
1151 
1152 /* Function to handle the parsing of RTE Flow item TCP Header. */
1153 int32_t
1154 ulp_rte_tcp_hdr_handler(const struct rte_flow_item *item,
1155 			struct ulp_rte_parser_params *params)
1156 {
1157 	const struct rte_flow_item_tcp *tcp_spec = item->spec;
1158 	const struct rte_flow_item_tcp *tcp_mask = item->mask;
1159 	struct ulp_rte_hdr_field *field;
1160 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
1161 	uint32_t idx = params->field_idx;
1162 	uint32_t size;
1163 	uint32_t cnt;
1164 
1165 	cnt = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_L4_HDR_CNT);
1166 	if (cnt == 2) {
1167 		BNXT_TF_DBG(ERR, "Parse Err:Third L4 header not supported\n");
1168 		return BNXT_TF_RC_ERROR;
1169 	}
1170 
1171 	/*
1172 	 * Copy the rte_flow_item for ipv4 into hdr_field using ipv4
1173 	 * header fields
1174 	 */
1175 	if (tcp_spec) {
1176 		size = sizeof(tcp_spec->hdr.src_port);
1177 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
1178 						&tcp_spec->hdr.src_port,
1179 						size);
1180 		size = sizeof(tcp_spec->hdr.dst_port);
1181 		field = ulp_rte_parser_fld_copy(field,
1182 						&tcp_spec->hdr.dst_port,
1183 						size);
1184 		size = sizeof(tcp_spec->hdr.sent_seq);
1185 		field = ulp_rte_parser_fld_copy(field,
1186 						&tcp_spec->hdr.sent_seq,
1187 						size);
1188 		size = sizeof(tcp_spec->hdr.recv_ack);
1189 		field = ulp_rte_parser_fld_copy(field,
1190 						&tcp_spec->hdr.recv_ack,
1191 						size);
1192 		size = sizeof(tcp_spec->hdr.data_off);
1193 		field = ulp_rte_parser_fld_copy(field,
1194 						&tcp_spec->hdr.data_off,
1195 						size);
1196 		size = sizeof(tcp_spec->hdr.tcp_flags);
1197 		field = ulp_rte_parser_fld_copy(field,
1198 						&tcp_spec->hdr.tcp_flags,
1199 						size);
1200 		size = sizeof(tcp_spec->hdr.rx_win);
1201 		field = ulp_rte_parser_fld_copy(field,
1202 						&tcp_spec->hdr.rx_win,
1203 						size);
1204 		size = sizeof(tcp_spec->hdr.cksum);
1205 		field = ulp_rte_parser_fld_copy(field,
1206 						&tcp_spec->hdr.cksum,
1207 						size);
1208 		size = sizeof(tcp_spec->hdr.tcp_urp);
1209 		field = ulp_rte_parser_fld_copy(field,
1210 						&tcp_spec->hdr.tcp_urp,
1211 						size);
1212 	} else {
1213 		idx += BNXT_ULP_PROTO_HDR_TCP_NUM;
1214 	}
1215 
1216 	if (tcp_mask) {
1217 		ulp_rte_prsr_mask_copy(params, &idx,
1218 				       &tcp_mask->hdr.src_port,
1219 				       sizeof(tcp_mask->hdr.src_port));
1220 		ulp_rte_prsr_mask_copy(params, &idx,
1221 				       &tcp_mask->hdr.dst_port,
1222 				       sizeof(tcp_mask->hdr.dst_port));
1223 		ulp_rte_prsr_mask_copy(params, &idx,
1224 				       &tcp_mask->hdr.sent_seq,
1225 				       sizeof(tcp_mask->hdr.sent_seq));
1226 		ulp_rte_prsr_mask_copy(params, &idx,
1227 				       &tcp_mask->hdr.recv_ack,
1228 				       sizeof(tcp_mask->hdr.recv_ack));
1229 		ulp_rte_prsr_mask_copy(params, &idx,
1230 				       &tcp_mask->hdr.data_off,
1231 				       sizeof(tcp_mask->hdr.data_off));
1232 		ulp_rte_prsr_mask_copy(params, &idx,
1233 				       &tcp_mask->hdr.tcp_flags,
1234 				       sizeof(tcp_mask->hdr.tcp_flags));
1235 		ulp_rte_prsr_mask_copy(params, &idx,
1236 				       &tcp_mask->hdr.rx_win,
1237 				       sizeof(tcp_mask->hdr.rx_win));
1238 		ulp_rte_prsr_mask_copy(params, &idx,
1239 				       &tcp_mask->hdr.cksum,
1240 				       sizeof(tcp_mask->hdr.cksum));
1241 		ulp_rte_prsr_mask_copy(params, &idx,
1242 				       &tcp_mask->hdr.tcp_urp,
1243 				       sizeof(tcp_mask->hdr.tcp_urp));
1244 	}
1245 	/* add number of TCP header elements */
1246 	params->field_idx += BNXT_ULP_PROTO_HDR_TCP_NUM;
1247 
1248 	/* Set the udp header bitmap and computed l4 header bitmaps */
1249 	if (ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_UDP) ||
1250 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP)) {
1251 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_TCP);
1252 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L4, 1);
1253 	} else {
1254 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP);
1255 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4, 1);
1256 	}
1257 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L4_HDR_CNT, ++cnt);
1258 	return BNXT_TF_RC_SUCCESS;
1259 }
1260 
1261 /* Function to handle the parsing of RTE Flow item Vxlan Header. */
1262 int32_t
1263 ulp_rte_vxlan_hdr_handler(const struct rte_flow_item *item,
1264 			  struct ulp_rte_parser_params *params)
1265 {
1266 	const struct rte_flow_item_vxlan *vxlan_spec = item->spec;
1267 	const struct rte_flow_item_vxlan *vxlan_mask = item->mask;
1268 	struct ulp_rte_hdr_field *field;
1269 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
1270 	uint32_t idx = params->field_idx;
1271 	uint32_t size;
1272 
1273 	/*
1274 	 * Copy the rte_flow_item for vxlan into hdr_field using vxlan
1275 	 * header fields
1276 	 */
1277 	if (vxlan_spec) {
1278 		size = sizeof(vxlan_spec->flags);
1279 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
1280 						&vxlan_spec->flags,
1281 						size);
1282 		size = sizeof(vxlan_spec->rsvd0);
1283 		field = ulp_rte_parser_fld_copy(field,
1284 						&vxlan_spec->rsvd0,
1285 						size);
1286 		size = sizeof(vxlan_spec->vni);
1287 		field = ulp_rte_parser_fld_copy(field,
1288 						&vxlan_spec->vni,
1289 						size);
1290 		size = sizeof(vxlan_spec->rsvd1);
1291 		field = ulp_rte_parser_fld_copy(field,
1292 						&vxlan_spec->rsvd1,
1293 						size);
1294 	}
1295 	if (vxlan_mask) {
1296 		ulp_rte_prsr_mask_copy(params, &idx,
1297 				       &vxlan_mask->flags,
1298 				       sizeof(vxlan_mask->flags));
1299 		ulp_rte_prsr_mask_copy(params, &idx,
1300 				       &vxlan_mask->rsvd0,
1301 				       sizeof(vxlan_mask->rsvd0));
1302 		ulp_rte_prsr_mask_copy(params, &idx,
1303 				       &vxlan_mask->vni,
1304 				       sizeof(vxlan_mask->vni));
1305 		ulp_rte_prsr_mask_copy(params, &idx,
1306 				       &vxlan_mask->rsvd1,
1307 				       sizeof(vxlan_mask->rsvd1));
1308 	}
1309 	/* Add number of vxlan header elements */
1310 	params->field_idx += BNXT_ULP_PROTO_HDR_VXLAN_NUM;
1311 
1312 	/* Update the hdr_bitmap with vxlan */
1313 	ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_T_VXLAN);
1314 	return BNXT_TF_RC_SUCCESS;
1315 }
1316 
1317 /* Function to handle the parsing of RTE Flow item void Header */
1318 int32_t
1319 ulp_rte_void_hdr_handler(const struct rte_flow_item *item __rte_unused,
1320 			 struct ulp_rte_parser_params *params __rte_unused)
1321 {
1322 	return BNXT_TF_RC_SUCCESS;
1323 }
1324 
1325 /* Function to handle the parsing of RTE Flow action void Header. */
1326 int32_t
1327 ulp_rte_void_act_handler(const struct rte_flow_action *action_item __rte_unused,
1328 			 struct ulp_rte_parser_params *params __rte_unused)
1329 {
1330 	return BNXT_TF_RC_SUCCESS;
1331 }
1332 
1333 /* Function to handle the parsing of RTE Flow action Mark Header. */
1334 int32_t
1335 ulp_rte_mark_act_handler(const struct rte_flow_action *action_item,
1336 			 struct ulp_rte_parser_params *param)
1337 {
1338 	const struct rte_flow_action_mark *mark;
1339 	struct ulp_rte_act_bitmap *act = &param->act_bitmap;
1340 	uint32_t mark_id;
1341 
1342 	mark = action_item->conf;
1343 	if (mark) {
1344 		mark_id = tfp_cpu_to_be_32(mark->id);
1345 		memcpy(&param->act_prop.act_details[BNXT_ULP_ACT_PROP_IDX_MARK],
1346 		       &mark_id, BNXT_ULP_ACT_PROP_SZ_MARK);
1347 
1348 		/* Update the hdr_bitmap with vxlan */
1349 		ULP_BITMAP_SET(act->bits, BNXT_ULP_ACTION_BIT_MARK);
1350 		return BNXT_TF_RC_SUCCESS;
1351 	}
1352 	BNXT_TF_DBG(ERR, "Parse Error: Mark arg is invalid\n");
1353 	return BNXT_TF_RC_ERROR;
1354 }
1355 
1356 /* Function to handle the parsing of RTE Flow action RSS Header. */
1357 int32_t
1358 ulp_rte_rss_act_handler(const struct rte_flow_action *action_item,
1359 			struct ulp_rte_parser_params *param)
1360 {
1361 	const struct rte_flow_action_rss *rss = action_item->conf;
1362 
1363 	if (rss) {
1364 		/* Update the hdr_bitmap with vxlan */
1365 		ULP_BITMAP_SET(param->act_bitmap.bits, BNXT_ULP_ACTION_BIT_RSS);
1366 		return BNXT_TF_RC_SUCCESS;
1367 	}
1368 	BNXT_TF_DBG(ERR, "Parse Error: RSS arg is invalid\n");
1369 	return BNXT_TF_RC_ERROR;
1370 }
1371 
1372 /* Function to handle the parsing of RTE Flow action vxlan_encap Header. */
1373 int32_t
1374 ulp_rte_vxlan_encap_act_handler(const struct rte_flow_action *action_item,
1375 				struct ulp_rte_parser_params *params)
1376 {
1377 	const struct rte_flow_action_vxlan_encap *vxlan_encap;
1378 	const struct rte_flow_item *item;
1379 	const struct rte_flow_item_eth *eth_spec;
1380 	const struct rte_flow_item_ipv4 *ipv4_spec;
1381 	const struct rte_flow_item_ipv6 *ipv6_spec;
1382 	struct rte_flow_item_vxlan vxlan_spec;
1383 	uint32_t vlan_num = 0, vlan_size = 0;
1384 	uint32_t ip_size = 0, ip_type = 0;
1385 	uint32_t vxlan_size = 0;
1386 	uint8_t *buff;
1387 	/* IP header per byte - ver/hlen, TOS, ID, ID, FRAG, FRAG, TTL, PROTO */
1388 	const uint8_t def_ipv4_hdr[] = {0x45, 0x00, 0x00, 0x01, 0x00,
1389 				    0x00, 0x40, 0x11};
1390 	struct ulp_rte_act_bitmap *act = &params->act_bitmap;
1391 	struct ulp_rte_act_prop *ap = &params->act_prop;
1392 
1393 	vxlan_encap = action_item->conf;
1394 	if (!vxlan_encap) {
1395 		BNXT_TF_DBG(ERR, "Parse Error: Vxlan_encap arg is invalid\n");
1396 		return BNXT_TF_RC_ERROR;
1397 	}
1398 
1399 	item = vxlan_encap->definition;
1400 	if (!item) {
1401 		BNXT_TF_DBG(ERR, "Parse Error: definition arg is invalid\n");
1402 		return BNXT_TF_RC_ERROR;
1403 	}
1404 
1405 	if (!ulp_rte_item_skip_void(&item, 0))
1406 		return BNXT_TF_RC_ERROR;
1407 
1408 	/* must have ethernet header */
1409 	if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
1410 		BNXT_TF_DBG(ERR, "Parse Error:vxlan encap does not have eth\n");
1411 		return BNXT_TF_RC_ERROR;
1412 	}
1413 	eth_spec = item->spec;
1414 	buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_L2_DMAC];
1415 	ulp_encap_buffer_copy(buff,
1416 			      eth_spec->dst.addr_bytes,
1417 			      BNXT_ULP_ACT_PROP_SZ_ENCAP_L2_DMAC);
1418 
1419 	buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_L2_SMAC];
1420 	ulp_encap_buffer_copy(buff,
1421 			      eth_spec->src.addr_bytes,
1422 			      BNXT_ULP_ACT_PROP_SZ_ENCAP_L2_SMAC);
1423 
1424 	/* Goto the next item */
1425 	if (!ulp_rte_item_skip_void(&item, 1))
1426 		return BNXT_TF_RC_ERROR;
1427 
1428 	/* May have vlan header */
1429 	if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
1430 		vlan_num++;
1431 		buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG];
1432 		ulp_encap_buffer_copy(buff,
1433 				      item->spec,
1434 				      sizeof(struct rte_flow_item_vlan));
1435 
1436 		if (!ulp_rte_item_skip_void(&item, 1))
1437 			return BNXT_TF_RC_ERROR;
1438 	}
1439 
1440 	/* may have two vlan headers */
1441 	if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
1442 		vlan_num++;
1443 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG +
1444 		       sizeof(struct rte_flow_item_vlan)],
1445 		       item->spec,
1446 		       sizeof(struct rte_flow_item_vlan));
1447 		if (!ulp_rte_item_skip_void(&item, 1))
1448 			return BNXT_TF_RC_ERROR;
1449 	}
1450 	/* Update the vlan count and size of more than one */
1451 	if (vlan_num) {
1452 		vlan_size = vlan_num * sizeof(struct rte_flow_item_vlan);
1453 		vlan_num = tfp_cpu_to_be_32(vlan_num);
1454 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG_NUM],
1455 		       &vlan_num,
1456 		       sizeof(uint32_t));
1457 		vlan_size = tfp_cpu_to_be_32(vlan_size);
1458 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG_SZ],
1459 		       &vlan_size,
1460 		       sizeof(uint32_t));
1461 	}
1462 
1463 	/* L3 must be IPv4, IPv6 */
1464 	if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) {
1465 		ipv4_spec = item->spec;
1466 		ip_size = BNXT_ULP_ENCAP_IPV4_SIZE;
1467 
1468 		/* copy the ipv4 details */
1469 		if (ulp_buffer_is_empty(&ipv4_spec->hdr.version_ihl,
1470 					BNXT_ULP_ENCAP_IPV4_VER_HLEN_TOS)) {
1471 			buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP];
1472 			ulp_encap_buffer_copy(buff,
1473 					      def_ipv4_hdr,
1474 					      BNXT_ULP_ENCAP_IPV4_VER_HLEN_TOS +
1475 					      BNXT_ULP_ENCAP_IPV4_ID_PROTO);
1476 		} else {
1477 			const uint8_t *tmp_buff;
1478 
1479 			buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP];
1480 			tmp_buff = (const uint8_t *)&ipv4_spec->hdr.packet_id;
1481 			ulp_encap_buffer_copy(buff,
1482 					      tmp_buff,
1483 					      BNXT_ULP_ENCAP_IPV4_ID_PROTO);
1484 			buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP +
1485 			     BNXT_ULP_ENCAP_IPV4_ID_PROTO];
1486 			ulp_encap_buffer_copy(buff,
1487 					      &ipv4_spec->hdr.version_ihl,
1488 					      BNXT_ULP_ENCAP_IPV4_VER_HLEN_TOS);
1489 		}
1490 		buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP +
1491 		    BNXT_ULP_ENCAP_IPV4_VER_HLEN_TOS +
1492 		    BNXT_ULP_ENCAP_IPV4_ID_PROTO];
1493 		ulp_encap_buffer_copy(buff,
1494 				      (const uint8_t *)&ipv4_spec->hdr.dst_addr,
1495 				      BNXT_ULP_ENCAP_IPV4_DEST_IP);
1496 
1497 		buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP_SRC];
1498 		ulp_encap_buffer_copy(buff,
1499 				      (const uint8_t *)&ipv4_spec->hdr.src_addr,
1500 				      BNXT_ULP_ACT_PROP_SZ_ENCAP_IP_SRC);
1501 
1502 		/* Update the ip size details */
1503 		ip_size = tfp_cpu_to_be_32(ip_size);
1504 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP_SZ],
1505 		       &ip_size, sizeof(uint32_t));
1506 
1507 		/* update the ip type */
1508 		ip_type = rte_cpu_to_be_32(BNXT_ULP_ETH_IPV4);
1509 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_L3_TYPE],
1510 		       &ip_type, sizeof(uint32_t));
1511 
1512 		/* update the computed field to notify it is ipv4 header */
1513 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_ENCAP_IPV4_FLAG,
1514 				    1);
1515 
1516 		if (!ulp_rte_item_skip_void(&item, 1))
1517 			return BNXT_TF_RC_ERROR;
1518 	} else if (item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
1519 		ipv6_spec = item->spec;
1520 		ip_size = BNXT_ULP_ENCAP_IPV6_SIZE;
1521 
1522 		/* copy the ipv4 details */
1523 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP],
1524 		       ipv6_spec, BNXT_ULP_ENCAP_IPV6_SIZE);
1525 
1526 		/* Update the ip size details */
1527 		ip_size = tfp_cpu_to_be_32(ip_size);
1528 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP_SZ],
1529 		       &ip_size, sizeof(uint32_t));
1530 
1531 		 /* update the ip type */
1532 		ip_type = rte_cpu_to_be_32(BNXT_ULP_ETH_IPV6);
1533 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_L3_TYPE],
1534 		       &ip_type, sizeof(uint32_t));
1535 
1536 		/* update the computed field to notify it is ipv6 header */
1537 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_ENCAP_IPV6_FLAG,
1538 				    1);
1539 
1540 		if (!ulp_rte_item_skip_void(&item, 1))
1541 			return BNXT_TF_RC_ERROR;
1542 	} else {
1543 		BNXT_TF_DBG(ERR, "Parse Error: Vxlan Encap expects L3 hdr\n");
1544 		return BNXT_TF_RC_ERROR;
1545 	}
1546 
1547 	/* L4 is UDP */
1548 	if (item->type != RTE_FLOW_ITEM_TYPE_UDP) {
1549 		BNXT_TF_DBG(ERR, "vxlan encap does not have udp\n");
1550 		return BNXT_TF_RC_ERROR;
1551 	}
1552 	/* copy the udp details */
1553 	ulp_encap_buffer_copy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_UDP],
1554 			      item->spec, BNXT_ULP_ENCAP_UDP_SIZE);
1555 
1556 	if (!ulp_rte_item_skip_void(&item, 1))
1557 		return BNXT_TF_RC_ERROR;
1558 
1559 	/* Finally VXLAN */
1560 	if (item->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
1561 		BNXT_TF_DBG(ERR, "vxlan encap does not have vni\n");
1562 		return BNXT_TF_RC_ERROR;
1563 	}
1564 	vxlan_size = sizeof(struct rte_flow_item_vxlan);
1565 	/* copy the vxlan details */
1566 	memcpy(&vxlan_spec, item->spec, vxlan_size);
1567 	vxlan_spec.flags = 0x08;
1568 	ulp_encap_buffer_copy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_TUN],
1569 			      (const uint8_t *)&vxlan_spec,
1570 			      vxlan_size);
1571 	vxlan_size = tfp_cpu_to_be_32(vxlan_size);
1572 	memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_TUN_SZ],
1573 	       &vxlan_size, sizeof(uint32_t));
1574 
1575 	/* update the hdr_bitmap with vxlan */
1576 	ULP_BITMAP_SET(act->bits, BNXT_ULP_ACTION_BIT_VXLAN_ENCAP);
1577 	return BNXT_TF_RC_SUCCESS;
1578 }
1579 
1580 /* Function to handle the parsing of RTE Flow action vxlan_encap Header */
1581 int32_t
1582 ulp_rte_vxlan_decap_act_handler(const struct rte_flow_action *action_item
1583 				__rte_unused,
1584 				struct ulp_rte_parser_params *params)
1585 {
1586 	/* update the hdr_bitmap with vxlan */
1587 	ULP_BITMAP_SET(params->act_bitmap.bits,
1588 		       BNXT_ULP_ACTION_BIT_VXLAN_DECAP);
1589 	return BNXT_TF_RC_SUCCESS;
1590 }
1591 
1592 /* Function to handle the parsing of RTE Flow action drop Header. */
1593 int32_t
1594 ulp_rte_drop_act_handler(const struct rte_flow_action *action_item __rte_unused,
1595 			 struct ulp_rte_parser_params *params)
1596 {
1597 	/* Update the hdr_bitmap with drop */
1598 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACTION_BIT_DROP);
1599 	return BNXT_TF_RC_SUCCESS;
1600 }
1601 
1602 /* Function to handle the parsing of RTE Flow action count. */
1603 int32_t
1604 ulp_rte_count_act_handler(const struct rte_flow_action *action_item,
1605 			  struct ulp_rte_parser_params *params)
1606 
1607 {
1608 	const struct rte_flow_action_count *act_count;
1609 	struct ulp_rte_act_prop *act_prop = &params->act_prop;
1610 
1611 	act_count = action_item->conf;
1612 	if (act_count) {
1613 		if (act_count->shared) {
1614 			BNXT_TF_DBG(ERR,
1615 				    "Parse Error:Shared count not supported\n");
1616 			return BNXT_TF_RC_PARSE_ERR;
1617 		}
1618 		memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_COUNT],
1619 		       &act_count->id,
1620 		       BNXT_ULP_ACT_PROP_SZ_COUNT);
1621 	}
1622 
1623 	/* Update the hdr_bitmap with count */
1624 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACTION_BIT_COUNT);
1625 	return BNXT_TF_RC_SUCCESS;
1626 }
1627 
1628 /* Function to handle the parsing of action ports. */
1629 static int32_t
1630 ulp_rte_parser_act_port_set(struct ulp_rte_parser_params *param,
1631 			    uint32_t ifindex)
1632 {
1633 	enum bnxt_ulp_direction_type dir;
1634 	uint16_t pid_s;
1635 	uint32_t pid;
1636 	struct ulp_rte_act_prop *act = &param->act_prop;
1637 	enum bnxt_ulp_intf_type port_type;
1638 	uint32_t vnic_type;
1639 
1640 	/* Get the direction */
1641 	dir = ULP_COMP_FLD_IDX_RD(param, BNXT_ULP_CF_IDX_DIRECTION);
1642 	if (dir == BNXT_ULP_DIR_EGRESS) {
1643 		/* For egress direction, fill vport */
1644 		if (ulp_port_db_vport_get(param->ulp_ctx, ifindex, &pid_s))
1645 			return BNXT_TF_RC_ERROR;
1646 
1647 		pid = pid_s;
1648 		pid = rte_cpu_to_be_32(pid);
1649 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_VPORT],
1650 		       &pid, BNXT_ULP_ACT_PROP_SZ_VPORT);
1651 	} else {
1652 		/* For ingress direction, fill vnic */
1653 		port_type = ULP_COMP_FLD_IDX_RD(param,
1654 						BNXT_ULP_CF_IDX_ACT_PORT_TYPE);
1655 		if (port_type == BNXT_ULP_INTF_TYPE_VF_REP)
1656 			vnic_type = BNXT_ULP_VF_FUNC_VNIC;
1657 		else
1658 			vnic_type = BNXT_ULP_DRV_FUNC_VNIC;
1659 
1660 		if (ulp_port_db_default_vnic_get(param->ulp_ctx, ifindex,
1661 						 vnic_type, &pid_s))
1662 			return BNXT_TF_RC_ERROR;
1663 
1664 		pid = pid_s;
1665 		pid = rte_cpu_to_be_32(pid);
1666 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_VNIC],
1667 		       &pid, BNXT_ULP_ACT_PROP_SZ_VNIC);
1668 	}
1669 
1670 	/* Update the action port set bit */
1671 	ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET, 1);
1672 	return BNXT_TF_RC_SUCCESS;
1673 }
1674 
1675 /* Function to handle the parsing of RTE Flow action PF. */
1676 int32_t
1677 ulp_rte_pf_act_handler(const struct rte_flow_action *action_item __rte_unused,
1678 		       struct ulp_rte_parser_params *params)
1679 {
1680 	uint32_t port_id;
1681 	uint32_t ifindex;
1682 	enum bnxt_ulp_intf_type intf_type;
1683 
1684 	/* Get the port id of the current device */
1685 	port_id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
1686 
1687 	/* Get the port db ifindex */
1688 	if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx, port_id,
1689 					      &ifindex)) {
1690 		BNXT_TF_DBG(ERR, "Invalid port id\n");
1691 		return BNXT_TF_RC_ERROR;
1692 	}
1693 
1694 	/* Check the port is PF port */
1695 	intf_type = ulp_port_db_port_type_get(params->ulp_ctx, ifindex);
1696 	if (intf_type != BNXT_ULP_INTF_TYPE_PF) {
1697 		BNXT_TF_DBG(ERR, "Port is not a PF port\n");
1698 		return BNXT_TF_RC_ERROR;
1699 	}
1700 	/* Update the action properties */
1701 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
1702 	return ulp_rte_parser_act_port_set(params, ifindex);
1703 }
1704 
1705 /* Function to handle the parsing of RTE Flow action VF. */
1706 int32_t
1707 ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
1708 		       struct ulp_rte_parser_params *params)
1709 {
1710 	const struct rte_flow_action_vf *vf_action;
1711 	uint32_t ifindex;
1712 	enum bnxt_ulp_intf_type intf_type;
1713 
1714 	vf_action = action_item->conf;
1715 	if (!vf_action) {
1716 		BNXT_TF_DBG(ERR, "ParseErr: Invalid Argument\n");
1717 		return BNXT_TF_RC_PARSE_ERR;
1718 	}
1719 
1720 	if (vf_action->original) {
1721 		BNXT_TF_DBG(ERR, "ParseErr:VF Original not supported\n");
1722 		return BNXT_TF_RC_PARSE_ERR;
1723 	}
1724 
1725 	/* Check the port is VF port */
1726 	if (ulp_port_db_dev_func_id_to_ulp_index(params->ulp_ctx, vf_action->id,
1727 						 &ifindex)) {
1728 		BNXT_TF_DBG(ERR, "VF is not valid interface\n");
1729 		return BNXT_TF_RC_ERROR;
1730 	}
1731 	intf_type = ulp_port_db_port_type_get(params->ulp_ctx, ifindex);
1732 	if (intf_type != BNXT_ULP_INTF_TYPE_VF &&
1733 	    intf_type != BNXT_ULP_INTF_TYPE_TRUSTED_VF) {
1734 		BNXT_TF_DBG(ERR, "Port is not a VF port\n");
1735 		return BNXT_TF_RC_ERROR;
1736 	}
1737 
1738 	/* Update the action properties */
1739 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
1740 	return ulp_rte_parser_act_port_set(params, ifindex);
1741 }
1742 
1743 /* Function to handle the parsing of RTE Flow action port_id. */
1744 int32_t
1745 ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
1746 			    struct ulp_rte_parser_params *param)
1747 {
1748 	const struct rte_flow_action_port_id *port_id = act_item->conf;
1749 	uint32_t ifindex;
1750 	enum bnxt_ulp_intf_type intf_type;
1751 
1752 	if (!port_id) {
1753 		BNXT_TF_DBG(ERR,
1754 			    "ParseErr: Invalid Argument\n");
1755 		return BNXT_TF_RC_PARSE_ERR;
1756 	}
1757 	if (port_id->original) {
1758 		BNXT_TF_DBG(ERR,
1759 			    "ParseErr:Portid Original not supported\n");
1760 		return BNXT_TF_RC_PARSE_ERR;
1761 	}
1762 
1763 	/* Get the port db ifindex */
1764 	if (ulp_port_db_dev_port_to_ulp_index(param->ulp_ctx, port_id->id,
1765 					      &ifindex)) {
1766 		BNXT_TF_DBG(ERR, "Invalid port id\n");
1767 		return BNXT_TF_RC_ERROR;
1768 	}
1769 
1770 	/* Get the intf type */
1771 	intf_type = ulp_port_db_port_type_get(param->ulp_ctx, ifindex);
1772 	if (!intf_type) {
1773 		BNXT_TF_DBG(ERR, "Invalid port type\n");
1774 		return BNXT_TF_RC_ERROR;
1775 	}
1776 
1777 	/* Set the action port */
1778 	ULP_COMP_FLD_IDX_WR(param, BNXT_ULP_CF_IDX_ACT_PORT_TYPE, intf_type);
1779 	return ulp_rte_parser_act_port_set(param, ifindex);
1780 }
1781 
1782 /* Function to handle the parsing of RTE Flow action phy_port. */
1783 int32_t
1784 ulp_rte_phy_port_act_handler(const struct rte_flow_action *action_item,
1785 			     struct ulp_rte_parser_params *prm)
1786 {
1787 	const struct rte_flow_action_phy_port *phy_port;
1788 	uint32_t pid;
1789 	int32_t rc;
1790 	uint16_t pid_s;
1791 	enum bnxt_ulp_direction_type dir;
1792 
1793 	phy_port = action_item->conf;
1794 	if (!phy_port) {
1795 		BNXT_TF_DBG(ERR,
1796 			    "ParseErr: Invalid Argument\n");
1797 		return BNXT_TF_RC_PARSE_ERR;
1798 	}
1799 
1800 	if (phy_port->original) {
1801 		BNXT_TF_DBG(ERR,
1802 			    "Parse Err:Port Original not supported\n");
1803 		return BNXT_TF_RC_PARSE_ERR;
1804 	}
1805 	dir = ULP_COMP_FLD_IDX_RD(prm, BNXT_ULP_CF_IDX_DIRECTION);
1806 	if (dir != BNXT_ULP_DIR_EGRESS) {
1807 		BNXT_TF_DBG(ERR,
1808 			    "Parse Err:Phy ports are valid only for egress\n");
1809 		return BNXT_TF_RC_PARSE_ERR;
1810 	}
1811 	/* Get the physical port details from port db */
1812 	rc = ulp_port_db_phy_port_vport_get(prm->ulp_ctx, phy_port->index,
1813 					    &pid_s);
1814 	if (rc) {
1815 		BNXT_TF_DBG(ERR, "Failed to get port details\n");
1816 		return -EINVAL;
1817 	}
1818 
1819 	pid = pid_s;
1820 	pid = rte_cpu_to_be_32(pid);
1821 	memcpy(&prm->act_prop.act_details[BNXT_ULP_ACT_PROP_IDX_VPORT],
1822 	       &pid, BNXT_ULP_ACT_PROP_SZ_VPORT);
1823 
1824 	/* Update the action port set bit */
1825 	ULP_COMP_FLD_IDX_WR(prm, BNXT_ULP_CF_IDX_ACT_PORT_IS_SET, 1);
1826 	ULP_COMP_FLD_IDX_WR(prm, BNXT_ULP_CF_IDX_ACT_PORT_TYPE,
1827 			    BNXT_ULP_INTF_TYPE_PHY_PORT);
1828 	return BNXT_TF_RC_SUCCESS;
1829 }
1830 
1831 /* Function to handle the parsing of RTE Flow action pop vlan. */
1832 int32_t
1833 ulp_rte_of_pop_vlan_act_handler(const struct rte_flow_action *a __rte_unused,
1834 				struct ulp_rte_parser_params *params)
1835 {
1836 	/* Update the act_bitmap with pop */
1837 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACTION_BIT_POP_VLAN);
1838 	return BNXT_TF_RC_SUCCESS;
1839 }
1840 
1841 /* Function to handle the parsing of RTE Flow action push vlan. */
1842 int32_t
1843 ulp_rte_of_push_vlan_act_handler(const struct rte_flow_action *action_item,
1844 				 struct ulp_rte_parser_params *params)
1845 {
1846 	const struct rte_flow_action_of_push_vlan *push_vlan;
1847 	uint16_t ethertype;
1848 	struct ulp_rte_act_prop *act = &params->act_prop;
1849 
1850 	push_vlan = action_item->conf;
1851 	if (push_vlan) {
1852 		ethertype = push_vlan->ethertype;
1853 		if (tfp_cpu_to_be_16(ethertype) != RTE_ETHER_TYPE_VLAN) {
1854 			BNXT_TF_DBG(ERR,
1855 				    "Parse Err: Ethertype not supported\n");
1856 			return BNXT_TF_RC_PARSE_ERR;
1857 		}
1858 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_PUSH_VLAN],
1859 		       &ethertype, BNXT_ULP_ACT_PROP_SZ_PUSH_VLAN);
1860 		/* Update the hdr_bitmap with push vlan */
1861 		ULP_BITMAP_SET(params->act_bitmap.bits,
1862 			       BNXT_ULP_ACTION_BIT_PUSH_VLAN);
1863 		return BNXT_TF_RC_SUCCESS;
1864 	}
1865 	BNXT_TF_DBG(ERR, "Parse Error: Push vlan arg is invalid\n");
1866 	return BNXT_TF_RC_ERROR;
1867 }
1868 
1869 /* Function to handle the parsing of RTE Flow action set vlan id. */
1870 int32_t
1871 ulp_rte_of_set_vlan_vid_act_handler(const struct rte_flow_action *action_item,
1872 				    struct ulp_rte_parser_params *params)
1873 {
1874 	const struct rte_flow_action_of_set_vlan_vid *vlan_vid;
1875 	uint32_t vid;
1876 	struct ulp_rte_act_prop *act = &params->act_prop;
1877 
1878 	vlan_vid = action_item->conf;
1879 	if (vlan_vid && vlan_vid->vlan_vid) {
1880 		vid = vlan_vid->vlan_vid;
1881 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_VLAN_VID],
1882 		       &vid, BNXT_ULP_ACT_PROP_SZ_SET_VLAN_VID);
1883 		/* Update the hdr_bitmap with vlan vid */
1884 		ULP_BITMAP_SET(params->act_bitmap.bits,
1885 			       BNXT_ULP_ACTION_BIT_SET_VLAN_VID);
1886 		return BNXT_TF_RC_SUCCESS;
1887 	}
1888 	BNXT_TF_DBG(ERR, "Parse Error: Vlan vid arg is invalid\n");
1889 	return BNXT_TF_RC_ERROR;
1890 }
1891 
1892 /* Function to handle the parsing of RTE Flow action set vlan pcp. */
1893 int32_t
1894 ulp_rte_of_set_vlan_pcp_act_handler(const struct rte_flow_action *action_item,
1895 				    struct ulp_rte_parser_params *params)
1896 {
1897 	const struct rte_flow_action_of_set_vlan_pcp *vlan_pcp;
1898 	uint8_t pcp;
1899 	struct ulp_rte_act_prop *act = &params->act_prop;
1900 
1901 	vlan_pcp = action_item->conf;
1902 	if (vlan_pcp) {
1903 		pcp = vlan_pcp->vlan_pcp;
1904 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_VLAN_PCP],
1905 		       &pcp, BNXT_ULP_ACT_PROP_SZ_SET_VLAN_PCP);
1906 		/* Update the hdr_bitmap with vlan vid */
1907 		ULP_BITMAP_SET(params->act_bitmap.bits,
1908 			       BNXT_ULP_ACTION_BIT_SET_VLAN_PCP);
1909 		return BNXT_TF_RC_SUCCESS;
1910 	}
1911 	BNXT_TF_DBG(ERR, "Parse Error: Vlan pcp arg is invalid\n");
1912 	return BNXT_TF_RC_ERROR;
1913 }
1914 
1915 /* Function to handle the parsing of RTE Flow action set ipv4 src.*/
1916 int32_t
1917 ulp_rte_set_ipv4_src_act_handler(const struct rte_flow_action *action_item,
1918 				 struct ulp_rte_parser_params *params)
1919 {
1920 	const struct rte_flow_action_set_ipv4 *set_ipv4;
1921 	struct ulp_rte_act_prop *act = &params->act_prop;
1922 
1923 	set_ipv4 = action_item->conf;
1924 	if (set_ipv4) {
1925 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_IPV4_SRC],
1926 		       &set_ipv4->ipv4_addr, BNXT_ULP_ACT_PROP_SZ_SET_IPV4_SRC);
1927 		/* Update the hdr_bitmap with set ipv4 src */
1928 		ULP_BITMAP_SET(params->act_bitmap.bits,
1929 			       BNXT_ULP_ACTION_BIT_SET_IPV4_SRC);
1930 		return BNXT_TF_RC_SUCCESS;
1931 	}
1932 	BNXT_TF_DBG(ERR, "Parse Error: set ipv4 src arg is invalid\n");
1933 	return BNXT_TF_RC_ERROR;
1934 }
1935 
1936 /* Function to handle the parsing of RTE Flow action set ipv4 dst.*/
1937 int32_t
1938 ulp_rte_set_ipv4_dst_act_handler(const struct rte_flow_action *action_item,
1939 				 struct ulp_rte_parser_params *params)
1940 {
1941 	const struct rte_flow_action_set_ipv4 *set_ipv4;
1942 	struct ulp_rte_act_prop *act = &params->act_prop;
1943 
1944 	set_ipv4 = action_item->conf;
1945 	if (set_ipv4) {
1946 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_IPV4_DST],
1947 		       &set_ipv4->ipv4_addr, BNXT_ULP_ACT_PROP_SZ_SET_IPV4_DST);
1948 		/* Update the hdr_bitmap with set ipv4 dst */
1949 		ULP_BITMAP_SET(params->act_bitmap.bits,
1950 			       BNXT_ULP_ACTION_BIT_SET_IPV4_DST);
1951 		return BNXT_TF_RC_SUCCESS;
1952 	}
1953 	BNXT_TF_DBG(ERR, "Parse Error: set ipv4 dst arg is invalid\n");
1954 	return BNXT_TF_RC_ERROR;
1955 }
1956 
1957 /* Function to handle the parsing of RTE Flow action set tp src.*/
1958 int32_t
1959 ulp_rte_set_tp_src_act_handler(const struct rte_flow_action *action_item,
1960 			       struct ulp_rte_parser_params *params)
1961 {
1962 	const struct rte_flow_action_set_tp *set_tp;
1963 	struct ulp_rte_act_prop *act = &params->act_prop;
1964 
1965 	set_tp = action_item->conf;
1966 	if (set_tp) {
1967 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_TP_SRC],
1968 		       &set_tp->port, BNXT_ULP_ACT_PROP_SZ_SET_TP_SRC);
1969 		/* Update the hdr_bitmap with set tp src */
1970 		ULP_BITMAP_SET(params->act_bitmap.bits,
1971 			       BNXT_ULP_ACTION_BIT_SET_TP_SRC);
1972 		return BNXT_TF_RC_SUCCESS;
1973 	}
1974 
1975 	BNXT_TF_DBG(ERR, "Parse Error: set tp src arg is invalid\n");
1976 	return BNXT_TF_RC_ERROR;
1977 }
1978 
1979 /* Function to handle the parsing of RTE Flow action set tp dst.*/
1980 int32_t
1981 ulp_rte_set_tp_dst_act_handler(const struct rte_flow_action *action_item,
1982 			       struct ulp_rte_parser_params *params)
1983 {
1984 	const struct rte_flow_action_set_tp *set_tp;
1985 	struct ulp_rte_act_prop *act = &params->act_prop;
1986 
1987 	set_tp = action_item->conf;
1988 	if (set_tp) {
1989 		memcpy(&act->act_details[BNXT_ULP_ACT_PROP_IDX_SET_TP_DST],
1990 		       &set_tp->port, BNXT_ULP_ACT_PROP_SZ_SET_TP_DST);
1991 		/* Update the hdr_bitmap with set tp dst */
1992 		ULP_BITMAP_SET(params->act_bitmap.bits,
1993 			       BNXT_ULP_ACTION_BIT_SET_TP_DST);
1994 		return BNXT_TF_RC_SUCCESS;
1995 	}
1996 
1997 	BNXT_TF_DBG(ERR, "Parse Error: set tp src arg is invalid\n");
1998 	return BNXT_TF_RC_ERROR;
1999 }
2000 
2001 /* Function to handle the parsing of RTE Flow action dec ttl.*/
2002 int32_t
2003 ulp_rte_dec_ttl_act_handler(const struct rte_flow_action *act __rte_unused,
2004 			    struct ulp_rte_parser_params *params)
2005 {
2006 	/* Update the act_bitmap with dec ttl */
2007 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACTION_BIT_DEC_TTL);
2008 	return BNXT_TF_RC_SUCCESS;
2009 }
2010