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