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