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