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