xref: /dpdk/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c (revision cd346367f898d619edf53f13628d6e539dbcab40)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2020 Broadcom
3  * All rights reserved.
4  */
5 
6 #include "bnxt.h"
7 #include "ulp_template_db_enum.h"
8 #include "ulp_template_struct.h"
9 #include "bnxt_tf_common.h"
10 #include "ulp_rte_parser.h"
11 #include "ulp_utils.h"
12 #include "tfp.h"
13 #include "ulp_port_db.h"
14 
15 /* Utility function to skip the void items. */
16 static inline int32_t
17 ulp_rte_item_skip_void(const struct rte_flow_item **item, uint32_t increment)
18 {
19 	if (!*item)
20 		return 0;
21 	if (increment)
22 		(*item)++;
23 	while ((*item) && (*item)->type == RTE_FLOW_ITEM_TYPE_VOID)
24 		(*item)++;
25 	if (*item)
26 		return 1;
27 	return 0;
28 }
29 
30 /* Utility function to update the field_bitmap */
31 static void
32 ulp_rte_parser_field_bitmap_update(struct ulp_rte_parser_params *params,
33 				   uint32_t idx)
34 {
35 	struct ulp_rte_hdr_field *field;
36 
37 	field = &params->hdr_field[idx];
38 	if (ulp_bitmap_notzero(field->mask, field->size)) {
39 		ULP_INDEX_BITMAP_SET(params->fld_bitmap.bits, idx);
40 		/* Not exact match */
41 		if (!ulp_bitmap_is_ones(field->mask, field->size))
42 			ULP_BITMAP_SET(params->fld_bitmap.bits,
43 				       BNXT_ULP_MATCH_TYPE_BITMASK_WM);
44 	} else {
45 		ULP_INDEX_BITMAP_RESET(params->fld_bitmap.bits, idx);
46 	}
47 }
48 
49 /* Utility function to copy field spec items */
50 static struct ulp_rte_hdr_field *
51 ulp_rte_parser_fld_copy(struct ulp_rte_hdr_field *field,
52 			const void *buffer,
53 			uint32_t size)
54 {
55 	field->size = size;
56 	memcpy(field->spec, buffer, field->size);
57 	field++;
58 	return field;
59 }
60 
61 /* Utility function to copy field masks items */
62 static void
63 ulp_rte_prsr_mask_copy(struct ulp_rte_parser_params *params,
64 		       uint32_t *idx,
65 		       const void *buffer,
66 		       uint32_t size)
67 {
68 	struct ulp_rte_hdr_field *field = &params->hdr_field[*idx];
69 
70 	memcpy(field->mask, buffer, size);
71 	ulp_rte_parser_field_bitmap_update(params, *idx);
72 	*idx = *idx + 1;
73 }
74 
75 /*
76  * Function to handle the parsing of RTE Flows and placing
77  * the RTE flow items into the ulp structures.
78  */
79 int32_t
80 bnxt_ulp_rte_parser_hdr_parse(const struct rte_flow_item pattern[],
81 			      struct ulp_rte_parser_params *params)
82 {
83 	const struct rte_flow_item *item = pattern;
84 	struct bnxt_ulp_rte_hdr_info *hdr_info;
85 
86 	params->field_idx = BNXT_ULP_PROTO_HDR_SVIF_NUM;
87 	if (params->dir == ULP_DIR_EGRESS)
88 		ULP_BITMAP_SET(params->hdr_bitmap.bits,
89 			       BNXT_ULP_FLOW_DIR_BITMASK_EGR);
90 
91 	/* Parse all the items in the pattern */
92 	while (item && item->type != RTE_FLOW_ITEM_TYPE_END) {
93 		/* get the header information from the flow_hdr_info table */
94 		hdr_info = &ulp_hdr_info[item->type];
95 		if (hdr_info->hdr_type == BNXT_ULP_HDR_TYPE_NOT_SUPPORTED) {
96 			BNXT_TF_DBG(ERR,
97 				    "Truflow parser does not support type %d\n",
98 				    item->type);
99 			return BNXT_TF_RC_PARSE_ERR;
100 		} else if (hdr_info->hdr_type == BNXT_ULP_HDR_TYPE_SUPPORTED) {
101 			/* call the registered callback handler */
102 			if (hdr_info->proto_hdr_func) {
103 				if (hdr_info->proto_hdr_func(item, params) !=
104 				    BNXT_TF_RC_SUCCESS) {
105 					return BNXT_TF_RC_ERROR;
106 				}
107 			}
108 		}
109 		item++;
110 	}
111 	/* update the implied SVIF */
112 	(void)ulp_rte_parser_svif_process(params);
113 	return BNXT_TF_RC_SUCCESS;
114 }
115 
116 /*
117  * Function to handle the parsing of RTE Flows and placing
118  * the RTE flow actions into the ulp structures.
119  */
120 int32_t
121 bnxt_ulp_rte_parser_act_parse(const struct rte_flow_action actions[],
122 			      struct ulp_rte_parser_params *params)
123 {
124 	const struct rte_flow_action *action_item = actions;
125 	struct bnxt_ulp_rte_act_info *hdr_info;
126 
127 	if (params->dir == ULP_DIR_EGRESS)
128 		ULP_BITMAP_SET(params->act_bitmap.bits,
129 			       BNXT_ULP_FLOW_DIR_BITMASK_EGR);
130 
131 	/* Parse all the items in the pattern */
132 	while (action_item && action_item->type != RTE_FLOW_ACTION_TYPE_END) {
133 		/* get the header information from the flow_hdr_info table */
134 		hdr_info = &ulp_act_info[action_item->type];
135 		if (hdr_info->act_type ==
136 		    BNXT_ULP_ACT_TYPE_NOT_SUPPORTED) {
137 			BNXT_TF_DBG(ERR,
138 				    "Truflow parser does not support act %u\n",
139 				    action_item->type);
140 			return BNXT_TF_RC_ERROR;
141 		} else if (hdr_info->act_type ==
142 		    BNXT_ULP_ACT_TYPE_SUPPORTED) {
143 			/* call the registered callback handler */
144 			if (hdr_info->proto_act_func) {
145 				if (hdr_info->proto_act_func(action_item,
146 							     params) !=
147 				    BNXT_TF_RC_SUCCESS) {
148 					return BNXT_TF_RC_ERROR;
149 				}
150 			}
151 		}
152 		action_item++;
153 	}
154 	/* update the implied VNIC */
155 	ulp_rte_parser_vnic_process(params);
156 	return BNXT_TF_RC_SUCCESS;
157 }
158 
159 /* Function to handle the parsing of RTE Flow item PF Header. */
160 static int32_t
161 ulp_rte_parser_svif_set(struct ulp_rte_parser_params *params,
162 			enum rte_flow_item_type proto,
163 			uint16_t svif,
164 			uint16_t mask)
165 {
166 	uint16_t port_id = svif;
167 	uint32_t dir = 0;
168 	struct ulp_rte_hdr_field *hdr_field;
169 	uint32_t ifindex;
170 	int32_t rc;
171 
172 	if (ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_SVIF_FLAG) !=
173 	    BNXT_ULP_INVALID_SVIF_VAL) {
174 		BNXT_TF_DBG(ERR,
175 			    "SVIF already set,multiple source not support'd\n");
176 		return BNXT_TF_RC_ERROR;
177 	}
178 
179 	if (proto == RTE_FLOW_ITEM_TYPE_PORT_ID) {
180 		dir = ULP_COMP_FLD_IDX_RD(params,
181 					  BNXT_ULP_CF_IDX_DIRECTION);
182 		/* perform the conversion from dpdk port to bnxt svif */
183 		rc = ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx, port_id,
184 						       &ifindex);
185 		if (rc) {
186 			BNXT_TF_DBG(ERR,
187 				    "Invalid port id\n");
188 			return BNXT_TF_RC_ERROR;
189 		}
190 		ulp_port_db_svif_get(params->ulp_ctx, ifindex, dir, &svif);
191 		svif = rte_cpu_to_be_16(svif);
192 	}
193 	hdr_field = &params->hdr_field[BNXT_ULP_PROTO_HDR_FIELD_SVIF_IDX];
194 	memcpy(hdr_field->spec, &svif, sizeof(svif));
195 	memcpy(hdr_field->mask, &mask, sizeof(mask));
196 	hdr_field->size = sizeof(svif);
197 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_SVIF_FLAG,
198 			    rte_be_to_cpu_16(svif));
199 	return BNXT_TF_RC_SUCCESS;
200 }
201 
202 /* Function to handle the parsing of the RTE port id */
203 int32_t
204 ulp_rte_parser_svif_process(struct ulp_rte_parser_params *params)
205 {
206 	uint16_t port_id = 0;
207 	uint16_t svif_mask = 0xFFFF;
208 
209 	if (ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_SVIF_FLAG) !=
210 	    BNXT_ULP_INVALID_SVIF_VAL)
211 		return BNXT_TF_RC_SUCCESS;
212 
213 	/* SVIF not set. So get the port id */
214 	port_id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
215 
216 	/* Update the SVIF details */
217 	return ulp_rte_parser_svif_set(params, RTE_FLOW_ITEM_TYPE_PORT_ID,
218 				       port_id, svif_mask);
219 }
220 
221 /* Function to handle the implicit VNIC RTE port id */
222 int32_t
223 ulp_rte_parser_vnic_process(struct ulp_rte_parser_params *params)
224 {
225 	struct ulp_rte_act_bitmap *act = &params->act_bitmap;
226 
227 	if (ULP_BITMAP_ISSET(act->bits, BNXT_ULP_ACTION_BIT_VNIC) ||
228 	    ULP_BITMAP_ISSET(act->bits, BNXT_ULP_ACTION_BIT_VPORT))
229 		return BNXT_TF_RC_SUCCESS;
230 
231 	/* Update the vnic details */
232 	ulp_rte_pf_act_handler(NULL, params);
233 	/* Reset the hdr_bitmap with vnic bit */
234 	ULP_BITMAP_RESET(params->act_bitmap.bits, BNXT_ULP_ACTION_BIT_VNIC);
235 
236 	return BNXT_TF_RC_SUCCESS;
237 }
238 
239 /* Function to handle the parsing of RTE Flow item PF Header. */
240 int32_t
241 ulp_rte_pf_hdr_handler(const struct rte_flow_item *item,
242 		       struct ulp_rte_parser_params *params)
243 {
244 	uint16_t port_id = 0;
245 	uint16_t svif_mask = 0xFFFF;
246 
247 	/* Get the port id */
248 	port_id = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
249 
250 	/* Update the SVIF details */
251 	return ulp_rte_parser_svif_set(params,
252 				       item->type,
253 				       port_id, svif_mask);
254 }
255 
256 /* Function to handle the parsing of RTE Flow item VF Header. */
257 int32_t
258 ulp_rte_vf_hdr_handler(const struct rte_flow_item *item,
259 		       struct ulp_rte_parser_params *params)
260 {
261 	const struct rte_flow_item_vf *vf_spec = item->spec;
262 	const struct rte_flow_item_vf *vf_mask = item->mask;
263 	uint16_t svif = 0, mask = 0;
264 
265 	/* Get VF rte_flow_item for Port details */
266 	if (vf_spec)
267 		svif = (uint16_t)vf_spec->id;
268 	if (vf_mask)
269 		mask = (uint16_t)vf_mask->id;
270 
271 	return ulp_rte_parser_svif_set(params, item->type, svif, mask);
272 }
273 
274 /* Function to handle the parsing of RTE Flow item port id  Header. */
275 int32_t
276 ulp_rte_port_id_hdr_handler(const struct rte_flow_item *item,
277 			    struct ulp_rte_parser_params *params)
278 {
279 	const struct rte_flow_item_port_id *port_spec = item->spec;
280 	const struct rte_flow_item_port_id *port_mask = item->mask;
281 	uint16_t svif = 0, mask = 0;
282 
283 	/*
284 	 * Copy the rte_flow_item for Port into hdr_field using port id
285 	 * header fields.
286 	 */
287 	if (port_spec)
288 		svif = (uint16_t)port_spec->id;
289 	if (port_mask)
290 		mask = (uint16_t)port_mask->id;
291 
292 	/* Update the SVIF details */
293 	return ulp_rte_parser_svif_set(params, item->type, svif, mask);
294 }
295 
296 /* Function to handle the parsing of RTE Flow item phy port Header. */
297 int32_t
298 ulp_rte_phy_port_hdr_handler(const struct rte_flow_item *item,
299 			     struct ulp_rte_parser_params *params)
300 {
301 	const struct rte_flow_item_phy_port *port_spec = item->spec;
302 	const struct rte_flow_item_phy_port *port_mask = item->mask;
303 	uint32_t svif = 0, mask = 0;
304 
305 	/* Copy the rte_flow_item for phy port into hdr_field */
306 	if (port_spec)
307 		svif = port_spec->index;
308 	if (port_mask)
309 		mask = port_mask->index;
310 
311 	/* Update the SVIF details */
312 	return ulp_rte_parser_svif_set(params, item->type, svif, mask);
313 }
314 
315 /* Function to handle the parsing of RTE Flow item Ethernet Header. */
316 int32_t
317 ulp_rte_eth_hdr_handler(const struct rte_flow_item *item,
318 			struct ulp_rte_parser_params *params)
319 {
320 	const struct rte_flow_item_eth *eth_spec = item->spec;
321 	const struct rte_flow_item_eth *eth_mask = item->mask;
322 	struct ulp_rte_hdr_field *field;
323 	uint32_t idx = params->field_idx;
324 	uint64_t set_flag = 0;
325 	uint32_t size;
326 
327 	/*
328 	 * Copy the rte_flow_item for eth into hdr_field using ethernet
329 	 * header fields
330 	 */
331 	if (eth_spec) {
332 		size = sizeof(eth_spec->dst.addr_bytes);
333 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
334 						eth_spec->dst.addr_bytes,
335 						size);
336 		size = sizeof(eth_spec->src.addr_bytes);
337 		field = ulp_rte_parser_fld_copy(field,
338 						eth_spec->src.addr_bytes,
339 						size);
340 		field = ulp_rte_parser_fld_copy(field,
341 						&eth_spec->type,
342 						sizeof(eth_spec->type));
343 	}
344 	if (eth_mask) {
345 		ulp_rte_prsr_mask_copy(params, &idx, eth_mask->dst.addr_bytes,
346 				       sizeof(eth_mask->dst.addr_bytes));
347 		ulp_rte_prsr_mask_copy(params, &idx, eth_mask->src.addr_bytes,
348 				       sizeof(eth_mask->src.addr_bytes));
349 		ulp_rte_prsr_mask_copy(params, &idx, &eth_mask->type,
350 				       sizeof(eth_mask->type));
351 	}
352 	/* Add number of vlan header elements */
353 	params->field_idx += BNXT_ULP_PROTO_HDR_ETH_NUM;
354 	params->vlan_idx = params->field_idx;
355 	params->field_idx += BNXT_ULP_PROTO_HDR_VLAN_NUM;
356 
357 	/* Update the hdr_bitmap with BNXT_ULP_HDR_PROTO_I_ETH */
358 	set_flag = ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
359 				    BNXT_ULP_HDR_BIT_O_ETH);
360 	if (set_flag)
361 		ULP_BITMAP_SET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_I_ETH);
362 	else
363 		ULP_BITMAP_RESET(params->hdr_bitmap.bits,
364 				 BNXT_ULP_HDR_BIT_I_ETH);
365 
366 	/* update the hdr_bitmap with BNXT_ULP_HDR_PROTO_O_ETH */
367 	ULP_BITMAP_SET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_O_ETH);
368 
369 	return BNXT_TF_RC_SUCCESS;
370 }
371 
372 /* Function to handle the parsing of RTE Flow item Vlan Header. */
373 int32_t
374 ulp_rte_vlan_hdr_handler(const struct rte_flow_item *item,
375 			 struct ulp_rte_parser_params *params)
376 {
377 	const struct rte_flow_item_vlan *vlan_spec = item->spec;
378 	const struct rte_flow_item_vlan *vlan_mask = item->mask;
379 	struct ulp_rte_hdr_field *field;
380 	struct ulp_rte_hdr_bitmap	*hdr_bit;
381 	uint32_t idx = params->vlan_idx;
382 	uint16_t vlan_tag, priority;
383 	uint32_t outer_vtag_num;
384 	uint32_t inner_vtag_num;
385 
386 	/*
387 	 * Copy the rte_flow_item for vlan into hdr_field using Vlan
388 	 * header fields
389 	 */
390 	if (vlan_spec) {
391 		vlan_tag = ntohs(vlan_spec->tci);
392 		priority = htons(vlan_tag >> 13);
393 		vlan_tag &= 0xfff;
394 		vlan_tag = htons(vlan_tag);
395 
396 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
397 						&priority,
398 						sizeof(priority));
399 		field = ulp_rte_parser_fld_copy(field,
400 						&vlan_tag,
401 						sizeof(vlan_tag));
402 		field = ulp_rte_parser_fld_copy(field,
403 						&vlan_spec->inner_type,
404 						sizeof(vlan_spec->inner_type));
405 	}
406 
407 	if (vlan_mask) {
408 		vlan_tag = ntohs(vlan_mask->tci);
409 		priority = htons(vlan_tag >> 13);
410 		vlan_tag &= 0xfff;
411 		vlan_tag = htons(vlan_tag);
412 
413 		field = &params->hdr_field[idx];
414 		memcpy(field->mask, &priority, field->size);
415 		field++;
416 		memcpy(field->mask, &vlan_tag, field->size);
417 		field++;
418 		memcpy(field->mask, &vlan_mask->inner_type, field->size);
419 	}
420 	/* Set the vlan index to new incremented value */
421 	params->vlan_idx += BNXT_ULP_PROTO_HDR_S_VLAN_NUM;
422 
423 	/* Get the outer tag and inner tag counts */
424 	outer_vtag_num = ULP_COMP_FLD_IDX_RD(params,
425 					     BNXT_ULP_CF_IDX_O_VTAG_NUM);
426 	inner_vtag_num = ULP_COMP_FLD_IDX_RD(params,
427 					     BNXT_ULP_CF_IDX_I_VTAG_NUM);
428 
429 	/* Update the hdr_bitmap of the vlans */
430 	hdr_bit = &params->hdr_bitmap;
431 	if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
432 	    !outer_vtag_num) {
433 		/* Update the vlan tag num */
434 		outer_vtag_num++;
435 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_VTAG_NUM,
436 				    outer_vtag_num);
437 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_VTAG_PRESENT, 1);
438 	} else if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
439 		   ULP_COMP_FLD_IDX_RD(params,
440 				       BNXT_ULP_CF_IDX_O_VTAG_PRESENT) &&
441 		   outer_vtag_num == 1) {
442 		/* update the vlan tag num */
443 		outer_vtag_num++;
444 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_VTAG_NUM,
445 				    outer_vtag_num);
446 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_TWO_VTAGS, 1);
447 	} else if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
448 		   ULP_COMP_FLD_IDX_RD(params,
449 				       BNXT_ULP_CF_IDX_O_VTAG_PRESENT) &&
450 		   ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_I_ETH) &&
451 		   !inner_vtag_num) {
452 		/* update the vlan tag num */
453 		inner_vtag_num++;
454 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_VTAG_NUM,
455 				    inner_vtag_num);
456 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_VTAG_PRESENT, 1);
457 	} else if (ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_O_ETH) &&
458 		   ULP_COMP_FLD_IDX_RD(params,
459 				       BNXT_ULP_CF_IDX_O_VTAG_PRESENT) &&
460 		   ULP_BITMAP_ISSET(hdr_bit->bits, BNXT_ULP_HDR_BIT_I_ETH) &&
461 		   ULP_COMP_FLD_IDX_RD(params,
462 				       BNXT_ULP_CF_IDX_O_VTAG_PRESENT) &&
463 		   inner_vtag_num == 1) {
464 		/* update the vlan tag num */
465 		inner_vtag_num++;
466 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_VTAG_NUM,
467 				    inner_vtag_num);
468 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_TWO_VTAGS, 1);
469 	} else {
470 		BNXT_TF_DBG(ERR, "Error Parsing:Vlan hdr found withtout eth\n");
471 		return BNXT_TF_RC_ERROR;
472 	}
473 	return BNXT_TF_RC_SUCCESS;
474 }
475 
476 /* Function to handle the parsing of RTE Flow item IPV4 Header. */
477 int32_t
478 ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,
479 			 struct ulp_rte_parser_params *params)
480 {
481 	const struct rte_flow_item_ipv4 *ipv4_spec = item->spec;
482 	const struct rte_flow_item_ipv4 *ipv4_mask = item->mask;
483 	struct ulp_rte_hdr_field *field;
484 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
485 	uint32_t idx = params->field_idx;
486 	uint32_t size;
487 	uint32_t inner_l3, outer_l3;
488 
489 	inner_l3 = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_I_L3);
490 	if (inner_l3) {
491 		BNXT_TF_DBG(ERR, "Parse Error:Third L3 header not supported\n");
492 		return BNXT_TF_RC_ERROR;
493 	}
494 
495 	/*
496 	 * Copy the rte_flow_item for ipv4 into hdr_field using ipv4
497 	 * header fields
498 	 */
499 	if (ipv4_spec) {
500 		size = sizeof(ipv4_spec->hdr.version_ihl);
501 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
502 						&ipv4_spec->hdr.version_ihl,
503 						size);
504 		size = sizeof(ipv4_spec->hdr.type_of_service);
505 		field = ulp_rte_parser_fld_copy(field,
506 						&ipv4_spec->hdr.type_of_service,
507 						size);
508 		size = sizeof(ipv4_spec->hdr.total_length);
509 		field = ulp_rte_parser_fld_copy(field,
510 						&ipv4_spec->hdr.total_length,
511 						size);
512 		size = sizeof(ipv4_spec->hdr.packet_id);
513 		field = ulp_rte_parser_fld_copy(field,
514 						&ipv4_spec->hdr.packet_id,
515 						size);
516 		size = sizeof(ipv4_spec->hdr.fragment_offset);
517 		field = ulp_rte_parser_fld_copy(field,
518 						&ipv4_spec->hdr.fragment_offset,
519 						size);
520 		size = sizeof(ipv4_spec->hdr.time_to_live);
521 		field = ulp_rte_parser_fld_copy(field,
522 						&ipv4_spec->hdr.time_to_live,
523 						size);
524 		size = sizeof(ipv4_spec->hdr.next_proto_id);
525 		field = ulp_rte_parser_fld_copy(field,
526 						&ipv4_spec->hdr.next_proto_id,
527 						size);
528 		size = sizeof(ipv4_spec->hdr.hdr_checksum);
529 		field = ulp_rte_parser_fld_copy(field,
530 						&ipv4_spec->hdr.hdr_checksum,
531 						size);
532 		size = sizeof(ipv4_spec->hdr.src_addr);
533 		field = ulp_rte_parser_fld_copy(field,
534 						&ipv4_spec->hdr.src_addr,
535 						size);
536 		size = sizeof(ipv4_spec->hdr.dst_addr);
537 		field = ulp_rte_parser_fld_copy(field,
538 						&ipv4_spec->hdr.dst_addr,
539 						size);
540 	}
541 	if (ipv4_mask) {
542 		ulp_rte_prsr_mask_copy(params, &idx,
543 				       &ipv4_mask->hdr.version_ihl,
544 				       sizeof(ipv4_mask->hdr.version_ihl));
545 		ulp_rte_prsr_mask_copy(params, &idx,
546 				       &ipv4_mask->hdr.type_of_service,
547 				       sizeof(ipv4_mask->hdr.type_of_service));
548 		ulp_rte_prsr_mask_copy(params, &idx,
549 				       &ipv4_mask->hdr.total_length,
550 				       sizeof(ipv4_mask->hdr.total_length));
551 		ulp_rte_prsr_mask_copy(params, &idx,
552 				       &ipv4_mask->hdr.packet_id,
553 				       sizeof(ipv4_mask->hdr.packet_id));
554 		ulp_rte_prsr_mask_copy(params, &idx,
555 				       &ipv4_mask->hdr.fragment_offset,
556 				       sizeof(ipv4_mask->hdr.fragment_offset));
557 		ulp_rte_prsr_mask_copy(params, &idx,
558 				       &ipv4_mask->hdr.time_to_live,
559 				       sizeof(ipv4_mask->hdr.time_to_live));
560 		ulp_rte_prsr_mask_copy(params, &idx,
561 				       &ipv4_mask->hdr.next_proto_id,
562 				       sizeof(ipv4_mask->hdr.next_proto_id));
563 		ulp_rte_prsr_mask_copy(params, &idx,
564 				       &ipv4_mask->hdr.hdr_checksum,
565 				       sizeof(ipv4_mask->hdr.hdr_checksum));
566 		ulp_rte_prsr_mask_copy(params, &idx,
567 				       &ipv4_mask->hdr.src_addr,
568 				       sizeof(ipv4_mask->hdr.src_addr));
569 		ulp_rte_prsr_mask_copy(params, &idx,
570 				       &ipv4_mask->hdr.dst_addr,
571 				       sizeof(ipv4_mask->hdr.dst_addr));
572 	}
573 	/* Add the number of ipv4 header elements */
574 	params->field_idx += BNXT_ULP_PROTO_HDR_IPV4_NUM;
575 
576 	/* Set the ipv4 header bitmap and computed l3 header bitmaps */
577 	outer_l3 = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_O_L3);
578 	if (outer_l3 ||
579 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV4) ||
580 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV6)) {
581 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_IPV4);
582 		inner_l3++;
583 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L3, inner_l3);
584 	} else {
585 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV4);
586 		outer_l3++;
587 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L3, outer_l3);
588 	}
589 	return BNXT_TF_RC_SUCCESS;
590 }
591 
592 /* Function to handle the parsing of RTE Flow item IPV6 Header */
593 int32_t
594 ulp_rte_ipv6_hdr_handler(const struct rte_flow_item *item,
595 			 struct ulp_rte_parser_params *params)
596 {
597 	const struct rte_flow_item_ipv6	*ipv6_spec = item->spec;
598 	const struct rte_flow_item_ipv6	*ipv6_mask = item->mask;
599 	struct ulp_rte_hdr_field *field;
600 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
601 	uint32_t idx = params->field_idx;
602 	uint32_t size;
603 	uint32_t inner_l3, outer_l3;
604 	uint32_t vtcf, vtcf_mask;
605 
606 	inner_l3 = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_I_L3);
607 	if (inner_l3) {
608 		BNXT_TF_DBG(ERR, "Parse Error: 3'rd L3 header not supported\n");
609 		return BNXT_TF_RC_ERROR;
610 	}
611 
612 	/*
613 	 * Copy the rte_flow_item for ipv6 into hdr_field using ipv6
614 	 * header fields
615 	 */
616 	if (ipv6_spec) {
617 		size = sizeof(ipv6_spec->hdr.vtc_flow);
618 
619 		vtcf = BNXT_ULP_GET_IPV6_VER(ipv6_spec->hdr.vtc_flow);
620 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
621 						&vtcf,
622 						size);
623 
624 		vtcf = BNXT_ULP_GET_IPV6_TC(ipv6_spec->hdr.vtc_flow);
625 		field = ulp_rte_parser_fld_copy(field,
626 						&vtcf,
627 						size);
628 
629 		vtcf = BNXT_ULP_GET_IPV6_FLOWLABEL(ipv6_spec->hdr.vtc_flow);
630 		field = ulp_rte_parser_fld_copy(field,
631 						&vtcf,
632 						size);
633 
634 		size = sizeof(ipv6_spec->hdr.payload_len);
635 		field = ulp_rte_parser_fld_copy(field,
636 						&ipv6_spec->hdr.payload_len,
637 						size);
638 		size = sizeof(ipv6_spec->hdr.proto);
639 		field = ulp_rte_parser_fld_copy(field,
640 						&ipv6_spec->hdr.proto,
641 						size);
642 		size = sizeof(ipv6_spec->hdr.hop_limits);
643 		field = ulp_rte_parser_fld_copy(field,
644 						&ipv6_spec->hdr.hop_limits,
645 						size);
646 		size = sizeof(ipv6_spec->hdr.src_addr);
647 		field = ulp_rte_parser_fld_copy(field,
648 						&ipv6_spec->hdr.src_addr,
649 						size);
650 		size = sizeof(ipv6_spec->hdr.dst_addr);
651 		field = ulp_rte_parser_fld_copy(field,
652 						&ipv6_spec->hdr.dst_addr,
653 						size);
654 	}
655 	if (ipv6_mask) {
656 		size = sizeof(ipv6_mask->hdr.vtc_flow);
657 
658 		vtcf_mask = BNXT_ULP_GET_IPV6_VER(ipv6_mask->hdr.vtc_flow);
659 		ulp_rte_prsr_mask_copy(params, &idx,
660 				       &vtcf_mask,
661 				       size);
662 
663 		vtcf_mask = BNXT_ULP_GET_IPV6_TC(ipv6_mask->hdr.vtc_flow);
664 		ulp_rte_prsr_mask_copy(params, &idx,
665 				       &vtcf_mask,
666 				       size);
667 
668 		vtcf_mask =
669 			BNXT_ULP_GET_IPV6_FLOWLABEL(ipv6_mask->hdr.vtc_flow);
670 		ulp_rte_prsr_mask_copy(params, &idx,
671 				       &vtcf_mask,
672 				       size);
673 
674 		ulp_rte_prsr_mask_copy(params, &idx,
675 				       &ipv6_mask->hdr.payload_len,
676 				       sizeof(ipv6_mask->hdr.payload_len));
677 		ulp_rte_prsr_mask_copy(params, &idx,
678 				       &ipv6_mask->hdr.proto,
679 				       sizeof(ipv6_mask->hdr.proto));
680 		ulp_rte_prsr_mask_copy(params, &idx,
681 				       &ipv6_mask->hdr.hop_limits,
682 				       sizeof(ipv6_mask->hdr.hop_limits));
683 		ulp_rte_prsr_mask_copy(params, &idx,
684 				       &ipv6_mask->hdr.src_addr,
685 				       sizeof(ipv6_mask->hdr.src_addr));
686 		ulp_rte_prsr_mask_copy(params, &idx,
687 				       &ipv6_mask->hdr.dst_addr,
688 				       sizeof(ipv6_mask->hdr.dst_addr));
689 	}
690 	/* add number of ipv6 header elements */
691 	params->field_idx += BNXT_ULP_PROTO_HDR_IPV6_NUM;
692 
693 	/* Set the ipv6 header bitmap and computed l3 header bitmaps */
694 	outer_l3 = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_O_L3);
695 	if (outer_l3 ||
696 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV4) ||
697 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV6)) {
698 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_IPV6);
699 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L3, 1);
700 	} else {
701 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_IPV6);
702 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L3, 1);
703 	}
704 	return BNXT_TF_RC_SUCCESS;
705 }
706 
707 /* Function to handle the parsing of RTE Flow item UDP Header. */
708 int32_t
709 ulp_rte_udp_hdr_handler(const struct rte_flow_item *item,
710 			struct ulp_rte_parser_params *params)
711 {
712 	const struct rte_flow_item_udp *udp_spec = item->spec;
713 	const struct rte_flow_item_udp *udp_mask = item->mask;
714 	struct ulp_rte_hdr_field *field;
715 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
716 	uint32_t idx = params->field_idx;
717 	uint32_t size;
718 	uint32_t inner_l4, outer_l4;
719 
720 	inner_l4 = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_I_L4);
721 	if (inner_l4) {
722 		BNXT_TF_DBG(ERR, "Parse Err:Third L4 header not supported\n");
723 		return BNXT_TF_RC_ERROR;
724 	}
725 
726 	/*
727 	 * Copy the rte_flow_item for ipv4 into hdr_field using ipv4
728 	 * header fields
729 	 */
730 	if (udp_spec) {
731 		size = sizeof(udp_spec->hdr.src_port);
732 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
733 						&udp_spec->hdr.src_port,
734 						size);
735 		size = sizeof(udp_spec->hdr.dst_port);
736 		field = ulp_rte_parser_fld_copy(field,
737 						&udp_spec->hdr.dst_port,
738 						size);
739 		size = sizeof(udp_spec->hdr.dgram_len);
740 		field = ulp_rte_parser_fld_copy(field,
741 						&udp_spec->hdr.dgram_len,
742 						size);
743 		size = sizeof(udp_spec->hdr.dgram_cksum);
744 		field = ulp_rte_parser_fld_copy(field,
745 						&udp_spec->hdr.dgram_cksum,
746 						size);
747 	}
748 	if (udp_mask) {
749 		ulp_rte_prsr_mask_copy(params, &idx,
750 				       &udp_mask->hdr.src_port,
751 				       sizeof(udp_mask->hdr.src_port));
752 		ulp_rte_prsr_mask_copy(params, &idx,
753 				       &udp_mask->hdr.dst_port,
754 				       sizeof(udp_mask->hdr.dst_port));
755 		ulp_rte_prsr_mask_copy(params, &idx,
756 				       &udp_mask->hdr.dgram_len,
757 				       sizeof(udp_mask->hdr.dgram_len));
758 		ulp_rte_prsr_mask_copy(params, &idx,
759 				       &udp_mask->hdr.dgram_cksum,
760 				       sizeof(udp_mask->hdr.dgram_cksum));
761 	}
762 
763 	/* Add number of UDP header elements */
764 	params->field_idx += BNXT_ULP_PROTO_HDR_UDP_NUM;
765 
766 	/* Set the udp header bitmap and computed l4 header bitmaps */
767 	outer_l4 = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_O_L4);
768 	if (outer_l4 ||
769 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_UDP) ||
770 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP)) {
771 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_UDP);
772 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L4, 1);
773 	} else {
774 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_UDP);
775 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4, 1);
776 	}
777 	return BNXT_TF_RC_SUCCESS;
778 }
779 
780 /* Function to handle the parsing of RTE Flow item TCP Header. */
781 int32_t
782 ulp_rte_tcp_hdr_handler(const struct rte_flow_item *item,
783 			struct ulp_rte_parser_params *params)
784 {
785 	const struct rte_flow_item_tcp *tcp_spec = item->spec;
786 	const struct rte_flow_item_tcp *tcp_mask = item->mask;
787 	struct ulp_rte_hdr_field *field;
788 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
789 	uint32_t idx = params->field_idx;
790 	uint32_t size;
791 	uint32_t inner_l4, outer_l4;
792 
793 	inner_l4 = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_I_L4);
794 	if (inner_l4) {
795 		BNXT_TF_DBG(ERR, "Parse Error:Third L4 header not supported\n");
796 		return BNXT_TF_RC_ERROR;
797 	}
798 
799 	/*
800 	 * Copy the rte_flow_item for ipv4 into hdr_field using ipv4
801 	 * header fields
802 	 */
803 	if (tcp_spec) {
804 		size = sizeof(tcp_spec->hdr.src_port);
805 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
806 						&tcp_spec->hdr.src_port,
807 						size);
808 		size = sizeof(tcp_spec->hdr.dst_port);
809 		field = ulp_rte_parser_fld_copy(field,
810 						&tcp_spec->hdr.dst_port,
811 						size);
812 		size = sizeof(tcp_spec->hdr.sent_seq);
813 		field = ulp_rte_parser_fld_copy(field,
814 						&tcp_spec->hdr.sent_seq,
815 						size);
816 		size = sizeof(tcp_spec->hdr.recv_ack);
817 		field = ulp_rte_parser_fld_copy(field,
818 						&tcp_spec->hdr.recv_ack,
819 						size);
820 		size = sizeof(tcp_spec->hdr.data_off);
821 		field = ulp_rte_parser_fld_copy(field,
822 						&tcp_spec->hdr.data_off,
823 						size);
824 		size = sizeof(tcp_spec->hdr.tcp_flags);
825 		field = ulp_rte_parser_fld_copy(field,
826 						&tcp_spec->hdr.tcp_flags,
827 						size);
828 		size = sizeof(tcp_spec->hdr.rx_win);
829 		field = ulp_rte_parser_fld_copy(field,
830 						&tcp_spec->hdr.rx_win,
831 						size);
832 		size = sizeof(tcp_spec->hdr.cksum);
833 		field = ulp_rte_parser_fld_copy(field,
834 						&tcp_spec->hdr.cksum,
835 						size);
836 		size = sizeof(tcp_spec->hdr.tcp_urp);
837 		field = ulp_rte_parser_fld_copy(field,
838 						&tcp_spec->hdr.tcp_urp,
839 						size);
840 	} else {
841 		idx += BNXT_ULP_PROTO_HDR_TCP_NUM;
842 	}
843 
844 	if (tcp_mask) {
845 		ulp_rte_prsr_mask_copy(params, &idx,
846 				       &tcp_mask->hdr.src_port,
847 				       sizeof(tcp_mask->hdr.src_port));
848 		ulp_rte_prsr_mask_copy(params, &idx,
849 				       &tcp_mask->hdr.dst_port,
850 				       sizeof(tcp_mask->hdr.dst_port));
851 		ulp_rte_prsr_mask_copy(params, &idx,
852 				       &tcp_mask->hdr.sent_seq,
853 				       sizeof(tcp_mask->hdr.sent_seq));
854 		ulp_rte_prsr_mask_copy(params, &idx,
855 				       &tcp_mask->hdr.recv_ack,
856 				       sizeof(tcp_mask->hdr.recv_ack));
857 		ulp_rte_prsr_mask_copy(params, &idx,
858 				       &tcp_mask->hdr.data_off,
859 				       sizeof(tcp_mask->hdr.data_off));
860 		ulp_rte_prsr_mask_copy(params, &idx,
861 				       &tcp_mask->hdr.tcp_flags,
862 				       sizeof(tcp_mask->hdr.tcp_flags));
863 		ulp_rte_prsr_mask_copy(params, &idx,
864 				       &tcp_mask->hdr.rx_win,
865 				       sizeof(tcp_mask->hdr.rx_win));
866 		ulp_rte_prsr_mask_copy(params, &idx,
867 				       &tcp_mask->hdr.cksum,
868 				       sizeof(tcp_mask->hdr.cksum));
869 		ulp_rte_prsr_mask_copy(params, &idx,
870 				       &tcp_mask->hdr.tcp_urp,
871 				       sizeof(tcp_mask->hdr.tcp_urp));
872 	}
873 	/* add number of TCP header elements */
874 	params->field_idx += BNXT_ULP_PROTO_HDR_TCP_NUM;
875 
876 	/* Set the udp header bitmap and computed l4 header bitmaps */
877 	outer_l4 = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_O_L4);
878 	if (outer_l4 ||
879 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_UDP) ||
880 	    ULP_BITMAP_ISSET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP)) {
881 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_I_TCP);
882 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_I_L4, 1);
883 	} else {
884 		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_O_TCP);
885 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L4, 1);
886 	}
887 	return BNXT_TF_RC_SUCCESS;
888 }
889 
890 /* Function to handle the parsing of RTE Flow item Vxlan Header. */
891 int32_t
892 ulp_rte_vxlan_hdr_handler(const struct rte_flow_item *item,
893 			  struct ulp_rte_parser_params *params)
894 {
895 	const struct rte_flow_item_vxlan *vxlan_spec = item->spec;
896 	const struct rte_flow_item_vxlan *vxlan_mask = item->mask;
897 	struct ulp_rte_hdr_field *field;
898 	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
899 	uint32_t idx = params->field_idx;
900 	uint32_t size;
901 
902 	/*
903 	 * Copy the rte_flow_item for vxlan into hdr_field using vxlan
904 	 * header fields
905 	 */
906 	if (vxlan_spec) {
907 		size = sizeof(vxlan_spec->flags);
908 		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
909 						&vxlan_spec->flags,
910 						size);
911 		size = sizeof(vxlan_spec->rsvd0);
912 		field = ulp_rte_parser_fld_copy(field,
913 						&vxlan_spec->rsvd0,
914 						size);
915 		size = sizeof(vxlan_spec->vni);
916 		field = ulp_rte_parser_fld_copy(field,
917 						&vxlan_spec->vni,
918 						size);
919 		size = sizeof(vxlan_spec->rsvd1);
920 		field = ulp_rte_parser_fld_copy(field,
921 						&vxlan_spec->rsvd1,
922 						size);
923 	}
924 	if (vxlan_mask) {
925 		ulp_rte_prsr_mask_copy(params, &idx,
926 				       &vxlan_mask->flags,
927 				       sizeof(vxlan_mask->flags));
928 		ulp_rte_prsr_mask_copy(params, &idx,
929 				       &vxlan_mask->rsvd0,
930 				       sizeof(vxlan_mask->rsvd0));
931 		ulp_rte_prsr_mask_copy(params, &idx,
932 				       &vxlan_mask->vni,
933 				       sizeof(vxlan_mask->vni));
934 		ulp_rte_prsr_mask_copy(params, &idx,
935 				       &vxlan_mask->rsvd1,
936 				       sizeof(vxlan_mask->rsvd1));
937 	}
938 	/* Add number of vxlan header elements */
939 	params->field_idx += BNXT_ULP_PROTO_HDR_VXLAN_NUM;
940 
941 	/* Update the hdr_bitmap with vxlan */
942 	ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_T_VXLAN);
943 	return BNXT_TF_RC_SUCCESS;
944 }
945 
946 /* Function to handle the parsing of RTE Flow item void Header */
947 int32_t
948 ulp_rte_void_hdr_handler(const struct rte_flow_item *item __rte_unused,
949 			 struct ulp_rte_parser_params *params __rte_unused)
950 {
951 	return BNXT_TF_RC_SUCCESS;
952 }
953 
954 /* Function to handle the parsing of RTE Flow action void Header. */
955 int32_t
956 ulp_rte_void_act_handler(const struct rte_flow_action *action_item __rte_unused,
957 			 struct ulp_rte_parser_params *params __rte_unused)
958 {
959 	return BNXT_TF_RC_SUCCESS;
960 }
961 
962 /* Function to handle the parsing of RTE Flow action Mark Header. */
963 int32_t
964 ulp_rte_mark_act_handler(const struct rte_flow_action *action_item,
965 			 struct ulp_rte_parser_params *param)
966 {
967 	const struct rte_flow_action_mark *mark;
968 	struct ulp_rte_act_bitmap *act = &param->act_bitmap;
969 	uint32_t mark_id;
970 
971 	mark = action_item->conf;
972 	if (mark) {
973 		mark_id = tfp_cpu_to_be_32(mark->id);
974 		memcpy(&param->act_prop.act_details[BNXT_ULP_ACT_PROP_IDX_MARK],
975 		       &mark_id, BNXT_ULP_ACT_PROP_SZ_MARK);
976 
977 		/* Update the hdr_bitmap with vxlan */
978 		ULP_BITMAP_SET(act->bits, BNXT_ULP_ACTION_BIT_MARK);
979 		return BNXT_TF_RC_SUCCESS;
980 	}
981 	BNXT_TF_DBG(ERR, "Parse Error: Mark arg is invalid\n");
982 	return BNXT_TF_RC_ERROR;
983 }
984 
985 /* Function to handle the parsing of RTE Flow action RSS Header. */
986 int32_t
987 ulp_rte_rss_act_handler(const struct rte_flow_action *action_item,
988 			struct ulp_rte_parser_params *param)
989 {
990 	const struct rte_flow_action_rss *rss = action_item->conf;
991 
992 	if (rss) {
993 		/* Update the hdr_bitmap with vxlan */
994 		ULP_BITMAP_SET(param->act_bitmap.bits, BNXT_ULP_ACTION_BIT_RSS);
995 		return BNXT_TF_RC_SUCCESS;
996 	}
997 	BNXT_TF_DBG(ERR, "Parse Error: RSS arg is invalid\n");
998 	return BNXT_TF_RC_ERROR;
999 }
1000 
1001 /* Function to handle the parsing of RTE Flow action vxlan_encap Header. */
1002 int32_t
1003 ulp_rte_vxlan_encap_act_handler(const struct rte_flow_action *action_item,
1004 				struct ulp_rte_parser_params *params)
1005 {
1006 	const struct rte_flow_action_vxlan_encap *vxlan_encap;
1007 	const struct rte_flow_item *item;
1008 	const struct rte_flow_item_eth *eth_spec;
1009 	const struct rte_flow_item_ipv4 *ipv4_spec;
1010 	const struct rte_flow_item_ipv6 *ipv6_spec;
1011 	struct rte_flow_item_vxlan vxlan_spec;
1012 	uint32_t vlan_num = 0, vlan_size = 0;
1013 	uint32_t ip_size = 0, ip_type = 0;
1014 	uint32_t vxlan_size = 0;
1015 	uint8_t *buff;
1016 	/* IP header per byte - ver/hlen, TOS, ID, ID, FRAG, FRAG, TTL, PROTO */
1017 	const uint8_t def_ipv4_hdr[] = {0x45, 0x00, 0x00, 0x01, 0x00,
1018 				    0x00, 0x40, 0x11};
1019 	struct ulp_rte_act_bitmap *act = &params->act_bitmap;
1020 	struct ulp_rte_act_prop *ap = &params->act_prop;
1021 
1022 	vxlan_encap = action_item->conf;
1023 	if (!vxlan_encap) {
1024 		BNXT_TF_DBG(ERR, "Parse Error: Vxlan_encap arg is invalid\n");
1025 		return BNXT_TF_RC_ERROR;
1026 	}
1027 
1028 	item = vxlan_encap->definition;
1029 	if (!item) {
1030 		BNXT_TF_DBG(ERR, "Parse Error: definition arg is invalid\n");
1031 		return BNXT_TF_RC_ERROR;
1032 	}
1033 
1034 	if (!ulp_rte_item_skip_void(&item, 0))
1035 		return BNXT_TF_RC_ERROR;
1036 
1037 	/* must have ethernet header */
1038 	if (item->type != RTE_FLOW_ITEM_TYPE_ETH) {
1039 		BNXT_TF_DBG(ERR, "Parse Error:vxlan encap does not have eth\n");
1040 		return BNXT_TF_RC_ERROR;
1041 	}
1042 	eth_spec = item->spec;
1043 	buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_L2_DMAC];
1044 	ulp_encap_buffer_copy(buff,
1045 			      eth_spec->dst.addr_bytes,
1046 			      BNXT_ULP_ACT_PROP_SZ_ENCAP_L2_DMAC);
1047 
1048 	/* Goto the next item */
1049 	if (!ulp_rte_item_skip_void(&item, 1))
1050 		return BNXT_TF_RC_ERROR;
1051 
1052 	/* May have vlan header */
1053 	if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
1054 		vlan_num++;
1055 		buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG];
1056 		ulp_encap_buffer_copy(buff,
1057 				      item->spec,
1058 				      sizeof(struct rte_flow_item_vlan));
1059 
1060 		if (!ulp_rte_item_skip_void(&item, 1))
1061 			return BNXT_TF_RC_ERROR;
1062 	}
1063 
1064 	/* may have two vlan headers */
1065 	if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
1066 		vlan_num++;
1067 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG +
1068 		       sizeof(struct rte_flow_item_vlan)],
1069 		       item->spec,
1070 		       sizeof(struct rte_flow_item_vlan));
1071 		if (!ulp_rte_item_skip_void(&item, 1))
1072 			return BNXT_TF_RC_ERROR;
1073 	}
1074 	/* Update the vlan count and size of more than one */
1075 	if (vlan_num) {
1076 		vlan_size = vlan_num * sizeof(struct rte_flow_item_vlan);
1077 		vlan_num = tfp_cpu_to_be_32(vlan_num);
1078 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG_NUM],
1079 		       &vlan_num,
1080 		       sizeof(uint32_t));
1081 		vlan_size = tfp_cpu_to_be_32(vlan_size);
1082 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG_SZ],
1083 		       &vlan_size,
1084 		       sizeof(uint32_t));
1085 	}
1086 
1087 	/* L3 must be IPv4, IPv6 */
1088 	if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) {
1089 		ipv4_spec = item->spec;
1090 		ip_size = BNXT_ULP_ENCAP_IPV4_SIZE;
1091 
1092 		/* copy the ipv4 details */
1093 		if (ulp_buffer_is_empty(&ipv4_spec->hdr.version_ihl,
1094 					BNXT_ULP_ENCAP_IPV4_VER_HLEN_TOS)) {
1095 			buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP];
1096 			ulp_encap_buffer_copy(buff,
1097 					      def_ipv4_hdr,
1098 					      BNXT_ULP_ENCAP_IPV4_VER_HLEN_TOS +
1099 					      BNXT_ULP_ENCAP_IPV4_ID_PROTO);
1100 		} else {
1101 			const uint8_t *tmp_buff;
1102 
1103 			buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP];
1104 			ulp_encap_buffer_copy(buff,
1105 					      &ipv4_spec->hdr.version_ihl,
1106 					      BNXT_ULP_ENCAP_IPV4_VER_HLEN_TOS);
1107 			buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP +
1108 			     BNXT_ULP_ENCAP_IPV4_VER_HLEN_TOS];
1109 			tmp_buff = (const uint8_t *)&ipv4_spec->hdr.packet_id;
1110 			ulp_encap_buffer_copy(buff,
1111 					      tmp_buff,
1112 					      BNXT_ULP_ENCAP_IPV4_ID_PROTO);
1113 		}
1114 		buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP +
1115 		    BNXT_ULP_ENCAP_IPV4_VER_HLEN_TOS +
1116 		    BNXT_ULP_ENCAP_IPV4_ID_PROTO];
1117 		ulp_encap_buffer_copy(buff,
1118 				      (const uint8_t *)&ipv4_spec->hdr.dst_addr,
1119 				      BNXT_ULP_ENCAP_IPV4_DEST_IP);
1120 
1121 		/* Update the ip size details */
1122 		ip_size = tfp_cpu_to_be_32(ip_size);
1123 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP_SZ],
1124 		       &ip_size, sizeof(uint32_t));
1125 
1126 		/* update the ip type */
1127 		ip_type = rte_cpu_to_be_32(BNXT_ULP_ETH_IPV4);
1128 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_L3_TYPE],
1129 		       &ip_type, sizeof(uint32_t));
1130 
1131 		if (!ulp_rte_item_skip_void(&item, 1))
1132 			return BNXT_TF_RC_ERROR;
1133 	} else if (item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
1134 		ipv6_spec = item->spec;
1135 		ip_size = BNXT_ULP_ENCAP_IPV6_SIZE;
1136 
1137 		/* copy the ipv4 details */
1138 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP],
1139 		       ipv6_spec, BNXT_ULP_ENCAP_IPV6_SIZE);
1140 
1141 		/* Update the ip size details */
1142 		ip_size = tfp_cpu_to_be_32(ip_size);
1143 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_IP_SZ],
1144 		       &ip_size, sizeof(uint32_t));
1145 
1146 		 /* update the ip type */
1147 		ip_type = rte_cpu_to_be_32(BNXT_ULP_ETH_IPV6);
1148 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_L3_TYPE],
1149 		       &ip_type, sizeof(uint32_t));
1150 
1151 		if (!ulp_rte_item_skip_void(&item, 1))
1152 			return BNXT_TF_RC_ERROR;
1153 	} else {
1154 		BNXT_TF_DBG(ERR, "Parse Error: Vxlan Encap expects L3 hdr\n");
1155 		return BNXT_TF_RC_ERROR;
1156 	}
1157 
1158 	/* L4 is UDP */
1159 	if (item->type != RTE_FLOW_ITEM_TYPE_UDP) {
1160 		BNXT_TF_DBG(ERR, "vxlan encap does not have udp\n");
1161 		return BNXT_TF_RC_ERROR;
1162 	}
1163 	/* copy the udp details */
1164 	ulp_encap_buffer_copy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_UDP],
1165 			      item->spec, BNXT_ULP_ENCAP_UDP_SIZE);
1166 
1167 	if (!ulp_rte_item_skip_void(&item, 1))
1168 		return BNXT_TF_RC_ERROR;
1169 
1170 	/* Finally VXLAN */
1171 	if (item->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
1172 		BNXT_TF_DBG(ERR, "vxlan encap does not have vni\n");
1173 		return BNXT_TF_RC_ERROR;
1174 	}
1175 	vxlan_size = sizeof(struct rte_flow_item_vxlan);
1176 	/* copy the vxlan details */
1177 	memcpy(&vxlan_spec, item->spec, vxlan_size);
1178 	vxlan_spec.flags = 0x08;
1179 	ulp_encap_buffer_copy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_TUN],
1180 			      (const uint8_t *)&vxlan_spec,
1181 			      vxlan_size);
1182 	vxlan_size = tfp_cpu_to_be_32(vxlan_size);
1183 	memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_TUN_SZ],
1184 	       &vxlan_size, sizeof(uint32_t));
1185 
1186 	/*update the hdr_bitmap with vxlan */
1187 	ULP_BITMAP_SET(act->bits, BNXT_ULP_ACTION_BIT_VXLAN_ENCAP);
1188 	return BNXT_TF_RC_SUCCESS;
1189 }
1190 
1191 /* Function to handle the parsing of RTE Flow action vxlan_encap Header */
1192 int32_t
1193 ulp_rte_vxlan_decap_act_handler(const struct rte_flow_action *action_item
1194 				__rte_unused,
1195 				struct ulp_rte_parser_params *params)
1196 {
1197 	/* update the hdr_bitmap with vxlan */
1198 	ULP_BITMAP_SET(params->act_bitmap.bits,
1199 		       BNXT_ULP_ACTION_BIT_VXLAN_DECAP);
1200 	return BNXT_TF_RC_SUCCESS;
1201 }
1202 
1203 /* Function to handle the parsing of RTE Flow action drop Header. */
1204 int32_t
1205 ulp_rte_drop_act_handler(const struct rte_flow_action *action_item __rte_unused,
1206 			 struct ulp_rte_parser_params *params)
1207 {
1208 	/* Update the hdr_bitmap with drop */
1209 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACTION_BIT_DROP);
1210 	return BNXT_TF_RC_SUCCESS;
1211 }
1212 
1213 /* Function to handle the parsing of RTE Flow action count. */
1214 int32_t
1215 ulp_rte_count_act_handler(const struct rte_flow_action *action_item,
1216 			  struct ulp_rte_parser_params *params)
1217 
1218 {
1219 	const struct rte_flow_action_count *act_count;
1220 	struct ulp_rte_act_prop *act_prop = &params->act_prop;
1221 
1222 	act_count = action_item->conf;
1223 	if (act_count) {
1224 		if (act_count->shared) {
1225 			BNXT_TF_DBG(ERR,
1226 				    "Parse Error:Shared count not supported\n");
1227 			return BNXT_TF_RC_PARSE_ERR;
1228 		}
1229 		memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_COUNT],
1230 		       &act_count->id,
1231 		       BNXT_ULP_ACT_PROP_SZ_COUNT);
1232 	}
1233 
1234 	/* Update the hdr_bitmap with count */
1235 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACTION_BIT_COUNT);
1236 	return BNXT_TF_RC_SUCCESS;
1237 }
1238 
1239 /* Function to handle the parsing of RTE Flow action PF. */
1240 int32_t
1241 ulp_rte_pf_act_handler(const struct rte_flow_action *action_item __rte_unused,
1242 		       struct ulp_rte_parser_params *params)
1243 {
1244 	uint32_t svif;
1245 
1246 	/* Update the hdr_bitmap with vnic bit */
1247 	ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACTION_BIT_VNIC);
1248 
1249 	/* copy the PF of the current device into VNIC Property */
1250 	svif = ULP_COMP_FLD_IDX_RD(params, BNXT_ULP_CF_IDX_INCOMING_IF);
1251 	svif = bnxt_get_vnic_id(svif);
1252 	svif = rte_cpu_to_be_32(svif);
1253 	memcpy(&params->act_prop.act_details[BNXT_ULP_ACT_PROP_IDX_VNIC],
1254 	       &svif, BNXT_ULP_ACT_PROP_SZ_VNIC);
1255 
1256 	return BNXT_TF_RC_SUCCESS;
1257 }
1258 
1259 /* Function to handle the parsing of RTE Flow action VF. */
1260 int32_t
1261 ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
1262 		       struct ulp_rte_parser_params *param)
1263 {
1264 	const struct rte_flow_action_vf *vf_action;
1265 	uint32_t pid;
1266 
1267 	vf_action = action_item->conf;
1268 	if (vf_action) {
1269 		if (vf_action->original) {
1270 			BNXT_TF_DBG(ERR,
1271 				    "Parse Error:VF Original not supported\n");
1272 			return BNXT_TF_RC_PARSE_ERR;
1273 		}
1274 		/* TBD: Update the computed VNIC using VF conversion */
1275 		pid = bnxt_get_vnic_id(vf_action->id);
1276 		pid = rte_cpu_to_be_32(pid);
1277 		memcpy(&param->act_prop.act_details[BNXT_ULP_ACT_PROP_IDX_VNIC],
1278 		       &pid, BNXT_ULP_ACT_PROP_SZ_VNIC);
1279 	}
1280 
1281 	/* Update the hdr_bitmap with count */
1282 	ULP_BITMAP_SET(param->act_bitmap.bits, BNXT_ULP_ACTION_BIT_VNIC);
1283 	return BNXT_TF_RC_SUCCESS;
1284 }
1285 
1286 /* Function to handle the parsing of RTE Flow action port_id. */
1287 int32_t
1288 ulp_rte_port_id_act_handler(const struct rte_flow_action *act_item,
1289 			    struct ulp_rte_parser_params *param)
1290 {
1291 	const struct rte_flow_action_port_id *port_id;
1292 	uint32_t pid;
1293 
1294 	port_id = act_item->conf;
1295 	if (port_id) {
1296 		if (port_id->original) {
1297 			BNXT_TF_DBG(ERR,
1298 				    "ParseErr:Portid Original not supported\n");
1299 			return BNXT_TF_RC_PARSE_ERR;
1300 		}
1301 		/* TBD: Update the computed VNIC using port conversion */
1302 		pid = bnxt_get_vnic_id(port_id->id);
1303 		pid = rte_cpu_to_be_32(pid);
1304 		memcpy(&param->act_prop.act_details[BNXT_ULP_ACT_PROP_IDX_VNIC],
1305 		       &pid, BNXT_ULP_ACT_PROP_SZ_VNIC);
1306 	}
1307 
1308 	/* Update the hdr_bitmap with count */
1309 	ULP_BITMAP_SET(param->act_bitmap.bits, BNXT_ULP_ACTION_BIT_VNIC);
1310 	return BNXT_TF_RC_SUCCESS;
1311 }
1312 
1313 /* Function to handle the parsing of RTE Flow action phy_port. */
1314 int32_t
1315 ulp_rte_phy_port_act_handler(const struct rte_flow_action *action_item,
1316 			     struct ulp_rte_parser_params *prm)
1317 {
1318 	const struct rte_flow_action_phy_port *phy_port;
1319 	uint32_t vport;
1320 
1321 	phy_port = action_item->conf;
1322 	if (phy_port) {
1323 		if (phy_port->original) {
1324 			BNXT_TF_DBG(ERR,
1325 				    "Parse Err:Port Original not supported\n");
1326 			return BNXT_TF_RC_PARSE_ERR;
1327 		}
1328 		/* Get the vport of the physical port */
1329 		/* TBD: shall be changed later to portdb call */
1330 		vport = 1 << phy_port->index;
1331 		vport = rte_cpu_to_be_32(vport);
1332 		memcpy(&prm->act_prop.act_details[BNXT_ULP_ACT_PROP_IDX_VPORT],
1333 		       &vport, BNXT_ULP_ACT_PROP_SZ_VPORT);
1334 	}
1335 
1336 	/* Update the hdr_bitmap with count */
1337 	ULP_BITMAP_SET(prm->act_bitmap.bits, BNXT_ULP_ACTION_BIT_VPORT);
1338 	return BNXT_TF_RC_SUCCESS;
1339 }
1340