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