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