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