flexflow_stat.c (89292B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: flexflow_stat.c 8 * Purpose: Flex flow stat APIs. 9 */ 10 11 #include <shared/bsl.h> 12 #include <soc/defs.h> 13 14 #ifdef INCLUDE_L3 15 16 #include <assert.h> 17 #include <bcm/error.h> 18 #include <soc/error.h> 19 #include <bcm/types.h> 20 #include <soc/drv.h> 21 #include <soc/format.h> 22 #include <bcm/stat.h> 23 #include <bcm_int/esw/flex_ctr.h> 24 #include <bcm_int/esw_dispatch.h> 25 #include <bcm_int/esw/stack.h> 26 #include <bcm_int/esw/flow.h> 27 #include <soc/esw/flow_db.h> 28 #include <soc/esw/flow_db_core.h> 29 #include <bcm_int/esw/l3.h> 30 #include <soc/l3x.h> 31 #include <bcm_int/esw/virtual.h> 32 #include <bcm_int/esw/firebolt.h> 33 #include <bcm_int/esw/l2gre.h> 34 35 #define _BCM_FLOW_TUNNEL_ID_IF_INVALID_RETURN(unit, id) \ 36 do { \ 37 if (((id) < 0) || (id) >= (soc_mem_index_count((unit), \ 38 EGR_DVP_ATTRIBUTEm))) { \ 39 return (BCM_E_BADID); \ 40 } \ 41 } while(0) 42 43 #define BCM_FLOW_IS_FIXED_TABLE(info) \ 44 ((info)->function_type == SOC_FLOW_DB_FUNC_ID_START) 45 46 #define BCM_FLOW_IS_FIXED_VIEW(info) \ 47 ((info)->flow_option == SOC_FLOW_DB_FLOW_OP_MATCH_NONE) 48 49 #define BCM_FLEXFLOW_FLEX_COUNTER_MAX_TABLE 3 50 STATIC 51 int _bcm_esw_flow_stat_mem_direction_get(int unit, 52 soc_mem_t mem, 53 uint32 *direction); 54 STATIC 55 int _bcm_esw_flow_stat_info_validate(int unit, 56 bcm_flow_stat_info_t *info); 57 58 STATIC 59 int _bcm_esw_flow_l3_host_index_get(int unit, 60 bcm_flow_stat_info_t *info, 61 bcm_flow_logical_field_t *field, 62 uint32 num_of_fields, 63 int *index); 64 STATIC 65 int _bcm_esw_flow_stat_fixed_table_index_get(int unit, 66 bcm_flow_stat_info_t *info, 67 bcm_stat_flex_direction_t direction, 68 soc_mem_t *mem, 69 int *index); 70 STATIC 71 int _bcm_esw_flow_stat_table_index_get(int unit, 72 soc_flow_db_mem_view_info_t vinfo, 73 uint32 *entry, 74 uint32 is_flex_view, 75 soc_mem_t mem, 76 int *index); 77 STATIC 78 int _bcm_esw_flow_stat_fixed_view_index_get(int unit, 79 bcm_flow_stat_info_t *info, 80 uint32 num_of_fields, 81 bcm_flow_logical_field_t *field, 82 bcm_stat_flex_direction_t direction, 83 soc_mem_t *mem, 84 int *index); 85 STATIC 86 int _bcm_esw_flow_stat_flex_view_index_get(int unit, 87 bcm_flow_stat_info_t *info, 88 bcm_flow_logical_field_t *field, 89 uint32 num_of_fields, 90 soc_flow_db_mem_view_info_t vinfo, 91 bcm_stat_flex_direction_t direction, 92 int *index); 93 STATIC 94 int bcmi_flow_mac_addr_is_valid(bcm_mac_t addr) 95 { 96 uint32 idx = 0; 97 for (idx = 0; idx < 5; idx++) { 98 if (addr[idx]) { 99 return TRUE; 100 } 101 } 102 return FALSE; 103 } 104 105 /* 106 * Function: 107 * _bcm_esw_flow_stat_flex_mem_is_valid 108 * Purpose: 109 * Checks if the object resolved table matches the 110 * resolved fixed table, fixed view or flexible 111 * view memory 112 * 113 * unit - (IN) unit number. 114 * info - (IN) flow stat config structure. 115 * 116 * Returns: 117 * BCM_E_XXX 118 * 119 * Notes: 120 */ 121 STATIC 122 int _bcm_esw_flow_stat_flex_mem_is_valid(int unit, 123 soc_mem_t mem, 124 uint32 num_of_tables, 125 soc_mem_t *tables, 126 uint32 *valid) 127 { 128 int i = 0; 129 130 if ((mem == INVALIDm) || 131 (tables == NULL) || 132 (valid == NULL)) { 133 return BCM_E_INTERNAL; 134 } 135 136 *valid = FALSE; 137 for (i = 0; i < num_of_tables; i++) { 138 if (mem == tables[i]) { 139 *valid = TRUE; 140 return BCM_E_NONE; 141 } 142 } 143 144 return BCM_E_NOT_FOUND; 145 } 146 147 STATIC 148 int _bcm_esw_flow_stat_mem_direction_get(int unit, 149 soc_mem_t mem, 150 uint32 *direction) 151 { 152 int rv = BCM_E_NONE; 153 154 if((mem == INVALIDm)|| 155 (direction == NULL)) { 156 return BCM_E_PARAM; 157 } 158 159 switch(mem) { 160 case PORT_TABm: 161 case LPORT_TABm: 162 case VLAN_TABm: 163 case VLAN_XLATEm: 164 case VLAN_XLATE_1_DOUBLEm: 165 case VLAN_XLATE_2_DOUBLEm: 166 case VFIm: 167 case VRFm: 168 case VRF_ATTRS_2m: 169 case SOURCE_VPm: 170 case MPLS_ENTRYm: 171 case MPLS_ENTRY_EXTDm: 172 case VFP_POLICY_TABLEm: 173 case VFP_POLICY_TABLE_PIPE0m: 174 case VFP_POLICY_TABLE_PIPE1m: 175 case VFP_POLICY_TABLE_PIPE2m: 176 case VFP_POLICY_TABLE_PIPE3m: 177 case L3_TUNNELm: 178 case L3_ENTRY_2m: 179 case L3_ENTRY_4m: 180 case L3_ENTRY_IPV4_MULTICASTm: 181 case L3_ENTRY_DOUBLEm: 182 case L3_ENTRY_IPV6_MULTICASTm: 183 case L3_ENTRY_QUADm: 184 case L3_DEFIPm: 185 case L3_DEFIP_PAIR_128m: 186 case L3_DEFIP_ALPM_IPV4_1m: 187 case L3_DEFIP_ALPM_IPV6_64_1m: 188 case L3_DEFIP_ALPM_IPV6_128m: 189 *direction = bcmStatFlexDirectionIngress; 190 break; 191 192 case EGR_PORTm: 193 case EGR_LPORT_PROFILEm: 194 case EGR_VLANm: 195 case EGR_VLAN_XLATEm: 196 case EGR_VLAN_XLATE_1_DOUBLEm: 197 case EGR_VLAN_XLATE_2_DOUBLEm: 198 case EGR_VFIm: 199 case EGR_L3_NEXT_HOPm: 200 case EGR_DVP_ATTRIBUTE_1m: 201 case EGR_DVP_ATTRIBUTEm: 202 case EGR_NAT_PACKET_EDIT_INFOm: 203 case EFP_POLICY_TABLEm: 204 case EFP_POLICY_TABLE_PIPE0m: 205 case EFP_POLICY_TABLE_PIPE1m: 206 case EGR_IP_TUNNEL_MPLSm: 207 *direction = bcmStatFlexDirectionEgress; 208 break; 209 default: 210 rv = BCM_E_PARAM; 211 break; 212 } 213 return rv; 214 } 215 216 STATIC 217 int _bcm_esw_flow_stat_info_validate(int unit, 218 bcm_flow_stat_info_t *info) 219 { 220 221 /* verify against the valid bitmap */ 222 if (info->valid_elements & BCM_FLOW_STAT_FLOW_PORT_VALID) { 223 if (0 == info->flow_port) { 224 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 225 "Flow Stat : \ 226 mismatch valid_elements flag and flow_port field\n"))); 227 return BCM_E_PARAM; 228 } 229 } 230 if (info->valid_elements & BCM_FLOW_STAT_PORT_VALID) { 231 if (0 == info->port) { 232 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 233 "Flow Stat : \ 234 mismatch valid_elements flag and port field\n"))); 235 return BCM_E_PARAM; 236 } 237 } 238 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 239 if (0 == info->vpn) { 240 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 241 "Flow Stat : \ 242 mismatch valid_elements flag and vpn field\n"))); 243 return BCM_E_PARAM; 244 } 245 } 246 if (info->valid_elements & BCM_FLOW_STAT_INNER_VLAN_VALID) { 247 if (0 == info->inner_vlan) { 248 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 249 "Flow Stat : \ 250 mismatch valid_elements flag and inner_vlan field\n"))); 251 return BCM_E_PARAM; 252 } 253 } 254 if (info->valid_elements & BCM_FLOW_STAT_VLAN_VALID) { 255 if (0 == info->vlan) { 256 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 257 "Flow Stat : \ 258 mismatch valid_elements flag and vlan field\n"))); 259 return BCM_E_PARAM; 260 } 261 } 262 if (info->valid_elements & BCM_FLOW_STAT_VNID_VALID) { 263 if (0 == info->vnid) { 264 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 265 "Flow Stat : \ 266 mismatch valid_elements flag and vnid field\n"))); 267 return BCM_E_PARAM; 268 } 269 } 270 if (info->valid_elements & BCM_FLOW_STAT_SIP_VALID) { 271 if (0 == info->sip) { 272 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 273 "Flow Stat : \ 274 mismatch valid_elements flag and sip field\n"))); 275 return BCM_E_PARAM; 276 } 277 } 278 if (info->valid_elements & BCM_FLOW_STAT_DIP_VALID) { 279 if (0 == info->dip) { 280 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 281 "Flow Stat : \ 282 mismatch valid_elements flag and dip field\n"))); 283 return BCM_E_PARAM; 284 } 285 } 286 if (info->valid_elements & BCM_FLOW_STAT_SIP_MASK_VALID) { 287 if (0 == info->sip_mask) { 288 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 289 "Flow Stat : \ 290 mismatch valid_elements flag and sip_mask field\n"))); 291 return BCM_E_PARAM; 292 } 293 } 294 if (info->valid_elements & BCM_FLOW_STAT_DIP_MASK_VALID) { 295 if (0 == info->dip_mask) { 296 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 297 "Flow Stat : \ 298 mismatch valid_elements flag and dip_mask field\n"))); 299 return BCM_E_PARAM; 300 } 301 } 302 if (info->valid_elements & BCM_FLOW_STAT_SIP6_VALID) { 303 if (0 == bcmi_flow_ip6_addr_is_valid(info->sip6)) { 304 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 305 "Flow Stat : \ 306 mismatch valid_elements flag and sip6 field\n"))); 307 return BCM_E_PARAM; 308 } 309 } 310 if (info->valid_elements & BCM_FLOW_STAT_DIP6_VALID) { 311 if (0 == bcmi_flow_ip6_addr_is_valid(info->dip6)) { 312 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 313 "Flow Stat : \ 314 mismatch valid_elements flag and dip6 field\n"))); 315 return BCM_E_PARAM; 316 } 317 } 318 if (info->valid_elements & BCM_FLOW_STAT_SIP6_MASK_VALID) { 319 if (0 == bcmi_flow_ip6_addr_is_valid(info->sip6_mask)) { 320 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 321 "Flow Stat : \ 322 mismatch valid_elements flag and sip6_mask field\n"))); 323 return BCM_E_PARAM; 324 } 325 } 326 if (info->valid_elements & BCM_FLOW_STAT_DIP6_MASK_VALID) { 327 if (0 == bcmi_flow_ip6_addr_is_valid(info->dip6_mask)) { 328 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 329 "Flow Stat : \ 330 mismatch valid_elements flag and dip6_mask field\n"))); 331 return BCM_E_PARAM; 332 } 333 } 334 if (info->valid_elements & BCM_FLOW_STAT_UDP_SRC_PORT_VALID) { 335 if (0 == info->udp_src_port) { 336 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 337 "Flow Stat : \ 338 mismatch valid_elements flag and udp_src_port field\n"))); 339 return BCM_E_PARAM; 340 } 341 } 342 if (info->valid_elements & BCM_FLOW_STAT_UDP_DST_PORT_VALID) { 343 if (0 == info->udp_dst_port) { 344 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 345 "Flow Stat : \ 346 mismatch valid_elements flag and udp_dst_port field\n"))); 347 return BCM_E_PARAM; 348 } 349 } 350 if (info->valid_elements & BCM_FLOW_STAT_PROTOCOL_VALID) { 351 if (0 == info->protocol) { 352 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 353 "Flow Stat : \ 354 mismatch valid_elements flag and protocol field\n"))); 355 return BCM_E_PARAM; 356 } 357 } 358 if (info->valid_elements & BCM_FLOW_STAT_TUNNEL_ID_VALID) { 359 if (0 == info->tunnel_id) { 360 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 361 "Flow Stat : \ 362 mismatch valid_elements flag and tunnel_id field\n"))); 363 return BCM_E_PARAM; 364 } 365 } 366 if (info->valid_elements & BCM_FLOW_STAT_EGRESS_IF_VALID) { 367 if (0 == info->egress_if) { 368 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 369 "Flow Stat : \ 370 mismatch valid_elements flag and egress_if field\n"))); 371 return BCM_E_PARAM; 372 } 373 } 374 if (info->valid_elements & BCM_FLOW_STAT_INTF_ID_VALID) { 375 if (0 == info->intf_id) { 376 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 377 "Flow Stat : \ 378 mismatch valid_elements flag and intf_id field\n"))); 379 return BCM_E_PARAM; 380 } 381 } 382 if (info->valid_elements & BCM_FLOW_STAT_MAC_VALID) { 383 if (0 == bcmi_flow_mac_addr_is_valid(info->mac)) { 384 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 385 "Flow Stat : \ 386 mismatch valid_elements flag and mac field\n"))); 387 return BCM_E_PARAM; 388 } 389 } 390 if (info->valid_elements & BCM_FLOW_STAT_L3A_FLAGS_VALID) { 391 LOG_DEBUG(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 392 "Flow Stat : \ 393 No Range check for L3A flags \ 394 Since 0 is also valid value"))); 395 396 } 397 if (info->valid_elements & BCM_FLOW_STAT_L3A_VRF_VALID) { 398 if (0 == info->l3a_vrf) { 399 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 400 "Flow Stat : \ 401 mismatch valid_elements flag and l3a_vrf field\n"))); 402 return BCM_E_PARAM; 403 } 404 } 405 if (info->valid_elements & BCM_FLOW_STAT_DVP_GROUP_VALID) { 406 if (0 == info->dvp_group) { 407 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 408 "Flow Stat : \ 409 mismatch valid_elements flag and dvp_group field\n"))); 410 return BCM_E_PARAM; 411 } 412 } 413 if (info->valid_elements & BCM_FLOW_STAT_OIF_GROUP_VALID) { 414 if (0 == info->oif_group) { 415 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 416 "Flow Stat : \ 417 mismatch valid_elements flag and oif_group field\n"))); 418 return BCM_E_PARAM; 419 } 420 } 421 422 return BCM_E_NONE; 423 } 424 425 STATIC 426 int _bcm_esw_flow_l3_host_index_get(int unit, 427 bcm_flow_stat_info_t *info, 428 bcm_flow_logical_field_t *field, 429 uint32 num_of_fields, 430 int *index) 431 { 432 int rv = BCM_E_NONE; 433 _bcm_l3_cfg_t l3cfg; 434 435 BCM_IF_ERROR_RETURN(bcmi_l3_init_check(unit)); 436 437 if (info->function_type != bcmFlowFuncTypeL3Host) { 438 return BCM_E_PARAM; 439 } 440 441 if (info->valid_elements & BCM_FLOW_STAT_L3A_VRF_VALID) { 442 if ((info->l3a_vrf > SOC_VRF_MAX(unit)) || 443 (info->l3a_vrf < BCM_L3_VRF_GLOBAL)) { 444 return (BCM_E_PARAM); 445 } 446 447 } 448 449 sal_memset(&l3cfg, 0, sizeof(_bcm_l3_cfg_t)); 450 451 if (info->valid_elements & BCM_FLOW_STAT_FLEX_KEY_VALID) { 452 l3cfg.l3c_flow_handle = info->flow_handle; 453 l3cfg.l3c_flow_option_handle = info->flow_option; 454 l3cfg.l3c_num_of_fields = num_of_fields; 455 sal_memcpy(l3cfg.l3c_logical_fields, field, 456 num_of_fields*sizeof(bcm_flow_logical_field_t)); 457 } 458 if (info->valid_elements & BCM_FLOW_STAT_L3A_FLAGS_VALID) { 459 /* Check that device supports ipv6. */ 460 if (BCM_L3_NO_IP6_SUPPORT(unit, info->l3a_flags)) { 461 return (BCM_E_UNAVAIL); 462 } 463 464 L3_LOCK(unit); 465 l3cfg.l3c_flags = info->l3a_flags; 466 l3cfg.l3c_vrf = info->l3a_vrf; 467 if ((info->l3a_flags & BCM_L3_IP6) && 468 (info->valid_elements & BCM_FLOW_STAT_SIP6_VALID)) { 469 sal_memcpy(l3cfg.l3c_ip6, info->sip6, BCM_IP6_ADDRLEN); 470 rv = mbcm_driver[unit]->mbcm_l3_ip6_get(unit, &l3cfg); 471 } else if (info->valid_elements & BCM_FLOW_STAT_SIP_VALID) { 472 l3cfg.l3c_ip_addr = info->sip; 473 rv = mbcm_driver[unit]->mbcm_l3_ip4_get(unit, &l3cfg); 474 475 } 476 L3_UNLOCK(unit); 477 } 478 479 if (BCM_FAILURE(rv)) { 480 return rv; 481 } 482 483 *index = l3cfg.l3c_hw_index; 484 return BCM_E_NONE; 485 } 486 487 STATIC 488 int _bcm_esw_flow_l3_route_index_get(int unit, 489 bcm_flow_stat_info_t *info, 490 bcm_flow_logical_field_t *field, 491 uint32 num_of_fields, 492 int *index) 493 { 494 int max_prefix_length; 495 _bcm_defip_cfg_t defip; 496 int rv = BCM_E_NONE; 497 498 BCM_IF_ERROR_RETURN(bcmi_l3_init_check(unit)); 499 500 if (info->function_type == bcmFlowFuncTypeL3Route) { 501 return BCM_E_PARAM; 502 } 503 if (info->valid_elements & BCM_FLOW_STAT_L3A_VRF_VALID) { 504 if ((info->l3a_vrf > SOC_VRF_MAX(unit)) || 505 (info->l3a_vrf < BCM_L3_VRF_GLOBAL)) { 506 return (BCM_E_PARAM); 507 } 508 509 } 510 sal_memset(&defip, 0, sizeof(_bcm_defip_cfg_t)); 511 if (info->valid_elements & BCM_FLOW_STAT_FLEX_KEY_VALID) { 512 513 defip.defip_flow_handle = info->flow_handle; 514 defip.defip_flow_option_handle = info->flow_option; 515 defip.defip_num_of_fields = num_of_fields; 516 sal_memcpy(defip.defip_logical_fields, field, 517 num_of_fields*sizeof(bcm_flow_logical_field_t)); 518 } 519 if (info->valid_elements & BCM_FLOW_STAT_L3A_FLAGS_VALID) { 520 /* Check that device supports ipv6. */ 521 if (BCM_L3_NO_IP6_SUPPORT(unit, info->l3a_flags)) { 522 return (BCM_E_UNAVAIL); 523 } 524 525 L3_LOCK(unit); 526 if ((info->l3a_flags & BCM_L3_IP6) && 527 (info->valid_elements & BCM_FLOW_STAT_SIP6_VALID) && 528 (info->valid_elements & BCM_FLOW_STAT_SIP6_MASK_VALID)){ 529 max_prefix_length = 530 soc_feature(unit, soc_feature_lpm_prefix_length_max_128) ? 128 : 64; 531 /* copy the subnet address */ 532 sal_memcpy(defip.defip_ip6_addr, info->sip6, BCM_IP6_ADDRLEN); 533 defip.defip_sub_len = bcm_ip6_mask_length(info->sip6_mask); 534 if (defip.defip_sub_len > max_prefix_length) { 535 L3_UNLOCK(unit); 536 return (BCM_E_PARAM); 537 } 538 rv = mbcm_driver[unit]->mbcm_ip6_defip_cfg_get(unit, &defip); 539 } else if ((info->valid_elements & BCM_FLOW_STAT_SIP_VALID) && 540 (info->valid_elements & BCM_FLOW_STAT_SIP_MASK_VALID)) { 541 defip.defip_ip_addr = info->sip & info->sip_mask; 542 defip.defip_sub_len = bcm_ip_mask_length(info->sip_mask); 543 rv = mbcm_driver[unit]->mbcm_ip4_defip_cfg_get(unit, &defip); 544 } 545 L3_UNLOCK(unit); 546 } 547 548 if (BCM_FAILURE(rv)) { 549 return rv; 550 } 551 552 *index = defip.defip_l3hw_index; 553 return BCM_E_NONE; 554 } 555 556 /* 557 * Function: 558 * _bcm_esw_flow_stat_fixed table_index_get 559 * Purpose: 560 * Get the index for the fixed tables like SVP 561 * EGR_VFI,VFI,VC_SWAP 562 * unit - (IN) unit number. 563 * info - (IN) flow stat config structure. 564 * 565 * Returns: 566 * BCM_E_XXX 567 * 568 * Notes: 569 */ 570 STATIC 571 int _bcm_esw_flow_stat_fixed_table_index_get(int unit, 572 bcm_flow_stat_info_t *info, 573 bcm_stat_flex_direction_t direction, 574 soc_mem_t *mem, 575 int *index) 576 { 577 int vfi = -1; 578 int vp; 579 580 /* Resolve the index */ 581 if (info->valid_elements & BCM_FLOW_STAT_FLOW_PORT_VALID) 582 { 583 vp = _SHR_GPORT_FLOW_PORT_ID_GET(info->flow_port); 584 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeFlow)) { 585 LOG_ERROR(BSL_LS_BCM_FLOW, 586 (BSL_META_U(unit, "Flow stats : flow port ID is not valid\n"))); 587 588 return BCM_E_PORT; 589 } 590 *mem = SOURCE_VPm; 591 *index = vp; 592 } 593 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) 594 { 595 /*Validate the flow VPN */ 596 BCM_IF_ERROR_RETURN(bcmi_esw_flow_vpn_is_valid(unit, info->vpn)); 597 _BCM_FLOW_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, info->vpn); 598 if (direction == bcmStatFlexDirectionIngress) { 599 *mem = VFIm; 600 } else { 601 *mem = EGR_VFIm; 602 } 603 *index = vfi; 604 } 605 return BCM_E_NONE; 606 } 607 /* 608 * Function: 609 * _bcm_esw_flow_stat_table_index_get 610 * Purpose: 611 * Get the index for the fixed tables like SVP 612 * EGR_VFI,VFI,VC_SWAP 613 * unit - (IN) unit number. 614 * info - (IN) flow stat config structure. 615 * 616 * Returns: 617 * BCM_E_XXX 618 * 619 * Notes: 620 */ 621 STATIC 622 int _bcm_esw_flow_stat_table_index_get(int unit, 623 soc_flow_db_mem_view_info_t vinfo, 624 uint32 *entry, 625 uint32 is_flex_view, 626 soc_mem_t mem, 627 int *index) 628 { 629 uint32 mem_view_id = 0; 630 soc_tunnel_term_t tnl_entry; 631 soc_tunnel_term_t tnl_return_entry; 632 uint32 return_entry[SOC_MAX_MEM_WORDS]; 633 634 sal_memset(&tnl_entry, 0, sizeof(soc_tunnel_term_t)); 635 sal_memset(&tnl_return_entry, 0, sizeof(soc_tunnel_term_t)); 636 sal_memset(return_entry, 0, sizeof(return_entry)); 637 638 if (is_flex_view) { 639 /* flex view case */ 640 mem_view_id = vinfo.mem_view_id; 641 if (vinfo.type == SOC_FLOW_DB_VIEW_TYPE_TCAM) { 642 if (vinfo.mem == L3_TUNNELm) { 643 BCM_IF_ERROR_RETURN( 644 bcmi_esw_flow_entry_to_tnl_term(unit, entry, &tnl_entry)); 645 BCM_IF_ERROR_RETURN( 646 soc_tunnel_term_match(unit, &tnl_entry, 647 &tnl_return_entry, index)); 648 } 649 else { 650 return BCM_E_INTERNAL; 651 } 652 } else if (vinfo.type == SOC_FLOW_DB_VIEW_TYPE_HASH) { 653 BCM_IF_ERROR_RETURN( 654 soc_mem_search(unit, mem_view_id, MEM_BLOCK_ANY, index, entry, 655 return_entry, 0)); 656 } else if (vinfo.type == SOC_FLOW_DB_VIEW_TYPE_DIRECT) { 657 return BCM_E_NONE; 658 } 659 } else { 660 /* fixed view case 661 * Assuming only hash tables 662 * Other TCAM tables like L3_DEFIP is handled 663 * seperately 664 * L3 TUNNEL does not have fixed views 665 * in case of CLASSIC VXLAN and CLASSIC L2GRE Flows. 666 */ 667 BCM_IF_ERROR_RETURN( 668 soc_mem_search(unit, mem, MEM_BLOCK_ANY, index, entry, 669 return_entry, 0)); 670 671 } 672 return BCM_E_NONE; 673 } 674 675 /* 676 * Function: 677 * _bcm_esw_flow_stat_fixed_view_index_get 678 * Purpose: 679 * Get the index for the fixed view of flex tables 680 * Usually programmed for the supported classic flows. 681 * unit - (IN) unit number. 682 * info - (IN) flow stat config structure. 683 * 684 * Returns: 685 * BCM_E_XXX 686 * 687 * Notes: 688 */ 689 STATIC 690 int _bcm_esw_flow_stat_fixed_view_index_get(int unit, 691 bcm_flow_stat_info_t *info, 692 uint32 num_of_fields, 693 bcm_flow_logical_field_t *field, 694 bcm_stat_flex_direction_t direction, 695 soc_mem_t *mem, 696 int *index) 697 { 698 int rv = BCM_E_NONE; 699 uint32 key_type = 0; 700 bcm_module_t mod_out = -1; 701 bcm_port_t port_out = -1; 702 bcm_trunk_t trunk_id = -1; 703 bcm_port_t gport_id = -1; 704 soc_field_t ovid_f; 705 soc_field_t ivid_f; 706 soc_field_t vnid_f; 707 soc_field_t t_f; 708 soc_field_t tgid_f; 709 soc_field_t module_id_f; 710 soc_field_t port_num_f; 711 soc_field_t sip_f; 712 uint32 entry[SOC_MAX_MEM_WORDS]; 713 int soft_tnl_idx; 714 _bcm_flow_bookkeeping_t *flow_info; 715 uint32 mpath_flag=0; 716 int nh_index = -1; 717 int vfi = -1; 718 soc_mem_t mem_id = 0; 719 uint32 dvp = 0; 720 uint32 vrf = 0; 721 soc_field_t vfi_f; 722 soc_field_t vrf_f; 723 soc_field_t dvp_f; 724 soc_field_t dvp_grp_f; 725 soc_field_t oif_grp_f; 726 soc_flow_db_mem_view_info_t vinfo; 727 uint32 data_type; 728 flow_info = FLOW_INFO(unit); 729 730 sal_memset(entry, 0, sizeof(entry)); 731 732 if ((index == NULL) || 733 (mem == NULL) || 734 (info == NULL)) { 735 return BCM_E_INTERNAL; 736 } 737 if (info->valid_elements & BCM_FLOW_STAT_FLEX_KEY_VALID) 738 { 739 return BCM_E_PARAM; 740 } 741 742 if (info->function_type == bcmFlowFuncTypeMatch) { 743 if ((info->flow_handle != SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) && 744 (info->flow_handle != SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE)){ 745 return BCM_E_PARAM; 746 } 747 748 t_f = XLATE__Tf; 749 tgid_f = XLATE__TGIDf; 750 module_id_f = XLATE__MODULE_IDf; 751 port_num_f = XLATE__PORT_NUMf; 752 ovid_f = XLATE__OVIDf; 753 ivid_f = XLATE__IVIDf; 754 755 if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_VLAN) { 756 mem_id = VLAN_XLATE_1_DOUBLEm; /* fixed view */ 757 key_type = TR_VLXLT_HASH_KEY_TYPE_OVID; 758 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_INNER_VLAN) { 759 mem_id = VLAN_XLATE_1_DOUBLEm; 760 key_type = TR_VLXLT_HASH_KEY_TYPE_IVID; 761 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_VLAN_STACKED) { 762 mem_id = VLAN_XLATE_1_DOUBLEm; 763 key_type = TR_VLXLT_HASH_KEY_TYPE_IVID_OVID; 764 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_VLAN_PRI) { 765 mem_id = VLAN_XLATE_1_DOUBLEm; 766 key_type = TR_VLXLT_HASH_KEY_TYPE_PRI_CFI; 767 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_VN_ID) { 768 mem_id = MPLS_ENTRYm; /* fixed view */ 769 if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) { 770 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 771 mem_id = VLAN_XLATE_1_DOUBLEm; 772 key_type = _BCM_FLOW_MATCH_KEY_TYPE_VXLAN_FLEX_VNID; 773 } else { 774 key_type = _BCM_FLOW_MATCH_KEY_TYPE_VXLAN_VNID; 775 } 776 } else { 777 key_type = _BCM_FLOW_MATCH_KEY_TYPE_L2GRE_VPNID; 778 } 779 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_SIP) { 780 mem_id = MPLS_ENTRYm; /* fixed view */ 781 if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) { 782 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 783 mem_id = MPLS_ENTRY_SINGLEm; 784 } 785 key_type = _BCM_FLOW_MATCH_KEY_TYPE_VXLAN_SIP; 786 } else { 787 key_type = _BCM_FLOW_MATCH_KEY_TYPE_L2GRE_SIP; 788 } 789 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_SIP_VNID) { 790 mem_id = MPLS_ENTRYm; /* fixed view */ 791 if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) { 792 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 793 mem_id = VLAN_XLATE_1_DOUBLEm; 794 key_type = _BCM_FLOW_MATCH_KEY_TYPE_VXLAN_FLEX_SIP_VNID; 795 } else { 796 key_type = _BCM_FLOW_MATCH_KEY_TYPE_VXLAN_SIP_VNID; 797 } 798 } else { 799 key_type = _BCM_FLOW_MATCH_KEY_TYPE_L2GRE_SIP_VPNID; 800 } 801 } 802 803 *mem = mem_id; 804 soc_mem_field32_set(unit,mem_id, entry, KEY_TYPEf, key_type); 805 if (key_type == _BCM_FLOW_MATCH_KEY_TYPE_VXLAN_FLEX_VNID) { 806 soc_mem_field32_set(unit, mem_id, entry, DATA_TYPEf, 807 _BCM_FLOW_MATCH_KEY_TYPE_VXLAN_FLEX_SIP_VNID); 808 } else if (key_type == _BCM_FLOW_MATCH_KEY_TYPE_VXLAN_SIP) { 809 soc_mem_field32_set(unit, mem_id, entry, DATA_TYPEf, 810 _BCM_VXLAN_FLEX_DATA_TYPE_IPV4_SIP); 811 } else { 812 soc_mem_field32_set(unit, mem_id, entry, DATA_TYPEf, key_type); 813 } 814 815 if (soc_mem_field_valid(unit, mem_id, BASE_VALIDf)) { 816 soc_mem_field32_set(unit, mem_id, entry, BASE_VALIDf, 1); 817 } else { 818 soc_mem_field32_set(unit, mem_id, entry, BASE_VALID_0f, 3); 819 soc_mem_field32_set(unit, mem_id, entry, BASE_VALID_1f, 7); 820 } 821 822 if (info->valid_elements & BCM_FLOW_STAT_PORT_VALID) { 823 rv = _bcm_esw_gport_resolve(unit, info->port, &mod_out, 824 &port_out, &trunk_id, &gport_id); 825 BCM_IF_ERROR_RETURN(rv); 826 } 827 if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_VLAN || 828 info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_INNER_VLAN || 829 info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_VLAN_STACKED || 830 info->match_criteria == BCM_FLOW_MATCH_CRITERIA_VLAN_PRI) { 831 if (info->valid_elements & BCM_FLOW_STAT_PORT_VALID) { 832 if (BCM_GPORT_IS_TRUNK(info->port)) { 833 soc_mem_field32_set(unit,mem_id, entry, t_f, 1); 834 soc_mem_field32_set(unit,mem_id, entry, tgid_f, trunk_id); 835 } else { 836 if (mod_out != -1) { 837 soc_mem_field32_set(unit, mem_id, entry, module_id_f, 838 mod_out); 839 } 840 soc_mem_field32_set(unit,mem_id, entry, port_num_f, port_out); 841 } 842 } 843 soc_mem_field32_set(unit, mem_id, entry, SOURCE_TYPEf, 1); 844 } 845 846 if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_VLAN ) { 847 if (!BCM_VLAN_VALID(info->vlan)) { 848 LOG_ERROR(BSL_LS_BCM_FLOW, 849 (BSL_META_U(unit, "Invalid vlan\n"))); 850 return BCM_E_PARAM; 851 } 852 soc_mem_field32_set(unit,mem_id, entry, ovid_f, info->vlan); 853 854 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_INNER_VLAN) { 855 if (!BCM_VLAN_VALID(info->inner_vlan)) { 856 LOG_ERROR(BSL_LS_BCM_FLOW, 857 (BSL_META_U(unit, "Invalid inner vlan\n"))); 858 return BCM_E_PARAM; 859 } 860 soc_mem_field32_set(unit,mem_id, entry, ivid_f, info->inner_vlan); 861 862 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_VLAN_STACKED) { 863 if (!BCM_VLAN_VALID(info->vlan) || 864 !BCM_VLAN_VALID(info->inner_vlan)) { 865 LOG_ERROR(BSL_LS_BCM_FLOW, 866 (BSL_META_U(unit, "Invalid either outer vlan or inner vlan\n"))); 867 return BCM_E_PARAM; 868 } 869 870 soc_mem_field32_set(unit,mem_id, entry, ovid_f, info->vlan); 871 soc_mem_field32_set(unit,mem_id, entry, ivid_f, info->inner_vlan); 872 873 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_VLAN_PRI) { 874 875 /* match_vlan : Bits 12-15 contains VLAN_PRI + CFI, vlan=BCM_E_NONE */ 876 soc_mem_field32_set(unit,mem_id, entry, OTAGf, info->vlan); 877 878 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_SIP) { 879 if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) { 880 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 881 sip_f = VXLAN_FLEX_IPV4_SIP__SIPf; 882 } else { 883 ovid_f = VXLAN_SIP__OVIDf; 884 sip_f = VXLAN_SIP__SIPf; 885 } 886 } else if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE) { 887 sip_f = L2GRE_SIP__SIPf; 888 } else { 889 LOG_ERROR(BSL_LS_BCM_FLOW, 890 (BSL_META_U(unit, "Invalid legacy flow handle\n"))); 891 return BCM_E_PARAM; 892 } 893 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination) && 894 (info->valid_elements & BCM_FLOW_STAT_VLAN_VALID)) { 895 VLAN_CHK_ID(unit,info->vlan); 896 soc_mem_field32_set(unit,mem_id, entry, ovid_f, info->vlan); 897 } 898 soc_mem_field32_set(unit,mem_id, entry, sip_f, info->sip); 899 900 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_VN_ID || 901 info->match_criteria == BCM_FLOW_MATCH_CRITERIA_SIP_VNID) { 902 903 if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) { 904 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 905 ovid_f = VXLAN_FLEX__OVIDf; 906 sip_f = VXLAN_FLEX__SIPf; 907 vnid_f = VXLAN_FLEX__VNIDf; 908 } else { 909 ovid_f = VXLAN_VN_ID__OVIDf; 910 sip_f = VXLAN_VN_ID__SIPf; 911 vnid_f = VXLAN_VN_ID__VN_IDf; 912 } 913 } else if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE) { 914 vnid_f = L2GRE_VPNID__VPNIDf; 915 sip_f = L2GRE_VPNID__SIPf; 916 } else { 917 LOG_ERROR(BSL_LS_BCM_FLOW, 918 (BSL_META_U(unit, "Invalid legacy flow handle\n"))); 919 return BCM_E_PARAM; 920 } 921 soc_mem_field32_set(unit, mem_id, entry, vnid_f, info->vnid); 922 if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_SIP_VNID) { 923 soc_mem_field32_set(unit,mem_id, entry, sip_f, info->sip); 924 } 925 926 if (soc_feature(unit,soc_feature_vrf_aware_vxlan_termination) && 927 (info->valid_elements & BCM_FLOW_STAT_VLAN_VALID)) { 928 VLAN_CHK_ID(unit, info->vlan); 929 soc_mem_field32_set(unit,mem_id, entry, ovid_f, info->vlan); 930 } 931 } 932 /* End of Match */ 933 } else if (info->function_type == bcmFlowFuncTypeEncap) { 934 if ((info->flow_handle != SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) && 935 (info->flow_handle != SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE)){ 936 return BCM_E_PARAM; 937 } 938 mem_id = EGR_VLAN_XLATE_1_DOUBLEm; 939 if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VRF_MAPPING) { 940 key_type = _BCM_FLOW_ENCAP_KEY_TYPE_VRF_MAPPING; 941 } else if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VFI) { 942 if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) { 943 key_type = _BCM_FLOW_ENCAP_VXLAN_KEY_TYPE_VFI; 944 } else if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE) { 945 key_type = _BCM_FLOW_ENCAP_L2GRE_KEY_TYPE_VFI; 946 } 947 } else if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VFI_DVP) { 948 if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) { 949 key_type = _BCM_FLOW_ENCAP_VXLAN_KEY_TYPE_VFI_DVP; 950 } else if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE) { 951 key_type = _BCM_FLOW_ENCAP_L2GRE_KEY_TYPE_VFI_DVP; 952 } else if (!(info->flow_handle)) { /* access DVP */ 953 key_type = _BCM_FLOW_ENCAP_KEY_TYPE_VLAN_XLATE_VFI; 954 } 955 } else if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VFI_DVP_GROUP) { 956 key_type = _BCM_FLOW_ENCAP_KEY_TYPE_VFI_DVP_GROUP; 957 if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN || 958 info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE) { 959 } else if (!(info->flow_handle)) { /* access DVP */ 960 key_type = _BCM_FLOW_ENCAP_KEY_TYPE_VLAN_XLATE_VFI; 961 } 962 } 963 *mem = mem_id; 964 soc_mem_field32_set(unit, mem_id, entry, KEY_TYPEf, key_type); 965 soc_mem_field32_set(unit, mem_id, entry, DATA_TYPEf, key_type); 966 967 soc_mem_field32_set(unit, mem_id, entry, BASE_VALID_0f, 3); 968 soc_mem_field32_set(unit, mem_id, entry, BASE_VALID_1f, 7); 969 970 if (info->valid_elements & BCM_FLOW_STAT_FLOW_PORT_VALID) { 971 dvp = _SHR_GPORT_FLOW_PORT_ID_GET(info->flow_port); 972 } 973 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 974 _BCM_FLOW_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, info->vpn); 975 } 976 if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VRF_MAPPING) { 977 /* KEY : VRF,VT_DVP_GROUP_ID,VT_L3_OIF_GROUP_ID 978 * VT_DVP_GROUP_ID : from EGR_DVP_ATTRIBUTEm 979 * VT_L3_OIF_GROUP_ID : from EGR_L3_INTFm 980 */ 981 _BCM_FLOW_VPN_GET(vrf, _BCM_VPN_TYPE_L3, info->vpn); 982 vrf_f = VRF_MAPPING__VRFf; 983 dvp_grp_f = VRF_MAPPING__VT_DVP_GROUP_IDf; 984 oif_grp_f = VRF_MAPPING__VT_L3OIF_GROUP_IDf; 985 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 986 soc_mem_field32_set(unit,mem_id, entry, vrf_f, vrf); 987 } 988 if (info->valid_elements & BCM_FLOW_STAT_DVP_GROUP_VALID) { 989 soc_mem_field32_set(unit,mem_id, entry, dvp_grp_f, info->dvp_group); 990 } 991 if (info->valid_elements & BCM_FLOW_STAT_OIF_GROUP_VALID) { 992 soc_mem_field32_set(unit,mem_id, entry, oif_grp_f, info->oif_group); 993 } 994 } else if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VFI_DVP_GROUP) { 995 vfi_f = VFI_DVP_GROUP__VFIf; 996 dvp_grp_f = VFI_DVP_GROUP__VT_DVP_GROUP_IDf; 997 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 998 soc_mem_field32_set(unit,mem_id, entry, vfi_f, vfi); 999 } 1000 if (info->valid_elements & BCM_FLOW_STAT_DVP_GROUP_VALID) { 1001 soc_mem_field32_set(unit,mem_id, entry, dvp_grp_f, info->dvp_group); 1002 } 1003 soc_mem_field32_set(unit,mem_id, entry, 1004 VFI_DVP_GROUP__DATA_TYPEf, 0); 1005 } else if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VFI) { 1006 if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) { 1007 vfi_f = VXLAN_VFI__VFIf; 1008 } else if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE) { 1009 vfi_f = L2GRE_VFI__VFIf; 1010 } else { 1011 return BCM_E_PARAM; 1012 } 1013 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 1014 soc_mem_field32_set(unit,mem_id, entry, vfi_f, vfi); 1015 } 1016 } else if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VFI_DVP) { 1017 if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) { 1018 vfi_f = VXLAN_VFI__VFIf; 1019 dvp_f = VXLAN_VFI__DVPf; 1020 } else if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE) { 1021 vfi_f = L2GRE_VFI__VFIf; 1022 dvp_f = L2GRE_VFI__DVPf; 1023 } else { 1024 vfi_f = VLAN_XLATE_VFI__VFIf; 1025 dvp_f = VLAN_XLATE_VFI__DVPf; 1026 } 1027 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 1028 soc_mem_field32_set(unit, mem_id, entry, vfi_f, vfi); 1029 } 1030 if (info->valid_elements & BCM_FLOW_STAT_FLOW_PORT_VALID) { 1031 soc_mem_field32_set(unit, mem_id, entry, dvp_f, dvp); 1032 } 1033 } 1034 } else if (info->function_type == bcmFlowFuncTypeTunnelInit) { 1035 /* Tunnel intitator id - validate the tunnel index*/ 1036 if ((info->flow_handle != SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) && 1037 (info->flow_handle != SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE)){ 1038 return BCM_E_PARAM; 1039 } 1040 soft_tnl_idx = BCM_GPORT_TUNNEL_ID_GET(info->tunnel_id); 1041 _BCM_FLOW_TUNNEL_ID_IF_INVALID_RETURN(unit, soft_tnl_idx); 1042 if (!flow_info->init_tunnel[soft_tnl_idx].idx) { 1043 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 1044 "Invalid replace action, tunnel not created\n"))); 1045 return BCM_E_PARAM; 1046 } 1047 *mem = EGR_IP_TUNNELm; 1048 *index = flow_info->init_tunnel[soft_tnl_idx].idx; 1049 return BCM_E_NONE; 1050 1051 } else if (info->function_type == bcmFlowFuncTypeTunnelTerm) { 1052 if ((info->flow_handle != SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) && 1053 (info->flow_handle != SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE)){ 1054 return BCM_E_PARAM; 1055 } 1056 mem_id = VLAN_XLATE_1_DOUBLEm; 1057 *mem = mem_id; 1058 if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) { 1059 if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) { 1060 mem_id = MPLS_ENTRY_SINGLEm; 1061 *mem = mem_id; 1062 soc_mem_field32_set(unit, mem_id, entry, BASE_VALIDf, 1); 1063 soc_mem_field32_set(unit, mem_id, entry, DATA_TYPEf, 1064 _BCM_VXLAN_FLEX_KEY_TYPE_LOOKUP_DIP); 1065 soc_mem_field32_set(unit, mem_id, entry, KEY_TYPEf, _BCM_VXLAN_FLEX_KEY_TYPE_LOOKUP_DIP); 1066 soc_mem_field32_set(unit, mem_id, entry, VXLAN_FLEX_IPV4_DIP__DIPf, info->dip); 1067 } else { 1068 soc_mem_field32_set(unit, mem_id, entry, BASE_VALID_0f, 3); 1069 soc_mem_field32_set(unit, mem_id, entry, BASE_VALID_1f, 7); 1070 soc_mem_field32_set(unit, mem_id, entry, DATA_TYPEf, 1071 _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP); 1072 soc_mem_field32_set(unit, mem_id, entry, KEY_TYPEf, _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP); 1073 soc_mem_field32_set(unit, mem_id, entry, VXLAN_DIP__DIPf, info->dip); 1074 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 1075 soc_mem_field32_set(unit, mem_id, entry, 1076 VXLAN_DIP__OVIDf, info->vlan); 1077 } 1078 } 1079 } else if (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE) { 1080 1081 soc_mem_field32_set(unit, mem_id, entry, BASE_VALID_0f, 3); 1082 soc_mem_field32_set(unit, mem_id, entry, BASE_VALID_1f, 7); 1083 soc_mem_field32_set(unit, mem_id, entry, KEY_TYPEf, 1084 _BCM_TD2_L2GRE_KEY_TYPE_LOOKUP_DIP); 1085 soc_mem_field32_set(unit, mem_id, entry, DATA_TYPEf, 1086 _BCM_TD2_L2GRE_KEY_TYPE_LOOKUP_DIP); 1087 soc_mem_field32_set(unit, mem_id, entry, 1088 L2GRE_DIP__DIPf, info->dip); 1089 } 1090 } else if (info->function_type == bcmFlowFuncTypeEgressObj) { 1091 if (info->valid_elements & BCM_FLOW_STAT_EGRESS_IF_VALID) { 1092 /* Get the nexthop index from the egress object 1093 * info->egress_if 1094 */ 1095 rv = bcm_xgs3_get_nh_from_egress_object(unit, info->egress_if, 1096 &mpath_flag, 1097 1, 1098 &nh_index); 1099 *mem = EGR_L3_NEXT_HOPm; 1100 *index = nh_index; 1101 return BCM_E_NONE; 1102 } 1103 } else if (info->function_type == bcmFlowFuncTypeEgressIntf) { 1104 if (info->valid_elements & BCM_FLOW_STAT_INTF_ID_VALID) { 1105 /* index to EGR_L3_INTF */ 1106 *mem = EGR_L3_INTFm; 1107 *index = info->intf_id; 1108 return BCM_E_NONE; 1109 } 1110 1111 } else if (info->function_type == bcmFlowFuncTypeL2Switch) { 1112 if (info->valid_elements & BCM_FLOW_STAT_MAC_VALID) { 1113 /* L2_ENTRYm */ 1114 *mem = mem_id = L2_ENTRY_SINGLEm; 1115 soc_mem_mac_addr_set(unit, mem_id, entry, MAC_DAf, info->mac); 1116 } 1117 } else if (info->function_type == bcmFlowFuncTypeL3Route) { 1118 *mem = L3_DEFIPm; 1119 return _bcm_esw_flow_l3_route_index_get(unit, info, 1120 field, num_of_fields, index); 1121 } else if (info->function_type == bcmFlowFuncTypeL3Host) { 1122 *mem = L3_ENTRY_DOUBLEm; 1123 return _bcm_esw_flow_l3_host_index_get(unit, info, 1124 field, num_of_fields, index); 1125 } else if (info->function_type == bcmFlowFuncTypeEgressLabel) { 1126 return BCM_E_NONE; 1127 } else if (info->function_type == bcmFlowFuncTypeEncapSet) { 1128 if ((info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_VXLAN) || 1129 (info->flow_handle == SOC_FLOW_DB_FLOW_ID_LEGACY_L2GRE)) { 1130 if (info->valid_elements == BCM_FLOW_STAT_FLOW_PORT_VALID) { 1131 mem_id = EGR_DVP_ATTRIBUTEm; 1132 dvp = _SHR_GPORT_FLOW_PORT_ID_GET(info->flow_port); 1133 if(!_BCM_FLOW_EGR_DVP_USED_GET(unit,dvp)) { 1134 return BCM_E_NOT_FOUND; 1135 } 1136 BCM_IF_ERROR_RETURN(soc_mem_read(unit,mem_id, MEM_BLOCK_ANY, dvp, 1137 entry)); 1138 data_type = soc_mem_field32_get(unit, mem_id, entry, DATA_TYPEf); 1139 if ((data_type == _BCM_FLOW_VXLAN_EGRESS_DEST_VP_TYPE) || 1140 (data_type == _BCM_FLOW_L2GRE_EGRESS_DEST_VP_TYPE)) { 1141 *index = dvp; 1142 *mem = mem_id; 1143 return BCM_E_NONE; 1144 } 1145 return BCM_E_PARAM; 1146 } else { 1147 return BCM_E_PARAM; 1148 } 1149 } else { 1150 return BCM_E_PARAM; 1151 } 1152 } else { 1153 return BCM_E_PARAM; 1154 } 1155 /* Get the Hw index 1156 */ 1157 rv = _bcm_esw_flow_stat_table_index_get(unit, vinfo/*vinfo*/, 1158 entry, 0, mem_id, index); 1159 1160 return BCM_E_NONE; 1161 } 1162 1163 /* 1164 * Function: 1165 * _bcm_esw_flow_stat_flex_view_index_get 1166 * Purpose: 1167 * Get the index for the flex view of flex tables 1168 * Usually programmed for the supported flex flows. 1169 * unit - (IN) unit number. 1170 * info - (IN) flow stat config structure. 1171 * 1172 * Returns: 1173 * BCM_E_XXX 1174 * 1175 * Notes: 1176 */ 1177 1178 STATIC 1179 int _bcm_esw_flow_stat_flex_view_index_get(int unit, 1180 bcm_flow_stat_info_t *info, 1181 bcm_flow_logical_field_t *field, 1182 uint32 num_of_fields, 1183 soc_flow_db_mem_view_info_t vinfo, 1184 bcm_stat_flex_direction_t direction, 1185 int *index) 1186 { 1187 int rv = BCM_E_NONE; 1188 uint32 mem_view_id = 0; 1189 int i = 0; 1190 int j = 0; 1191 bcm_module_t mod_out = -1; 1192 bcm_port_t port_out = -1; 1193 bcm_trunk_t trunk_id = -1; 1194 soc_field_t ovid_f; 1195 soc_field_t ivid_f; 1196 soc_field_t vnid_f; 1197 soc_field_t t_f; 1198 soc_field_t tgid_f; 1199 soc_field_t module_id_f; 1200 soc_field_t port_num_f; 1201 soc_field_t lbl_f; 1202 soc_field_t vfi_f; 1203 uint32 entry[SOC_MAX_MEM_WORDS]; 1204 uint32 key_lg_list[_BCM_FLOW_LOGICAL_FIELD_MAX]; 1205 uint32 num_lg_keys = 0; 1206 uint32 key_list[_BCM_FLOW_LOGICAL_FIELD_MAX]; 1207 uint32 num_keys = 0; 1208 int soft_tnl_idx; 1209 _bcm_flow_bookkeeping_t *flow_info; 1210 uint32 mpath_flag=0; 1211 int nh_index = -1; 1212 int vfi = -1; 1213 uint32 dvp = 0; 1214 uint32 vrf = 0; 1215 soc_field_t vrf_f = 0; 1216 soc_field_t dvp_grp_f; 1217 soc_field_t oif_grp_f; 1218 soc_field_t dvp_f; 1219 soc_field_t sip_f; 1220 bcm_port_t gport_id = -1; 1221 1222 flow_info = FLOW_INFO(unit); 1223 1224 mem_view_id = vinfo.mem_view_id; 1225 1226 /* needed for flex function match */ 1227 sal_memset(entry, 0, sizeof(entry)); 1228 BCM_IF_ERROR_RETURN( 1229 soc_flow_db_mem_view_entry_init(unit, mem_view_id, entry)); 1230 if (info->function_type == bcmFlowFuncTypeL3Route) { 1231 return _bcm_esw_flow_l3_route_index_get(unit, info, 1232 field, num_of_fields, index); 1233 } else if (info->function_type == bcmFlowFuncTypeL3Host) { 1234 return _bcm_esw_flow_l3_host_index_get(unit, info, 1235 field, num_of_fields, index); 1236 } else if (info->function_type == bcmFlowFuncTypeEncapSet) { 1237 if (info->valid_elements & 1238 BCM_FLOW_STAT_FLOW_PORT_VALID) { 1239 dvp = _SHR_GPORT_FLOW_PORT_ID_GET(info->flow_port); 1240 if (!_BCM_FLOW_EGR_DVP_USED_GET(unit, dvp)) { 1241 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 1242 "DVP %d not programmed for Egress DVP \n"), dvp)); 1243 return BCM_E_NOT_FOUND; 1244 } 1245 if (!_bcm_vp_used_get(unit, dvp, _bcmVpTypeFlow)) { 1246 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 1247 "DVP %d is not flow port, create flow port first\n"), dvp)); 1248 return BCM_E_NOT_FOUND; 1249 } 1250 *index = dvp; 1251 return BCM_E_NONE; 1252 } 1253 } else if (info->function_type == bcmFlowFuncTypeEncap) { 1254 if (info->valid_elements & BCM_FLOW_STAT_FLOW_PORT_VALID) { 1255 dvp = _SHR_GPORT_FLOW_PORT_ID_GET(info->flow_port); 1256 if (!_bcm_vp_used_get(unit, dvp, _bcmVpTypeFlow)) { 1257 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 1258 "DVP %d is not the flow port\n"), dvp)); 1259 return BCM_E_NOT_FOUND; 1260 } 1261 } 1262 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 1263 _BCM_FLOW_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, info->vpn); 1264 } 1265 1266 if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_DVP) { 1267 if (!dvp) { 1268 return BCM_E_PARAM; 1269 } 1270 /* only apply to flex view */ 1271 if (!_BCM_FLOW_IS_FLEX_VIEW(info)) { 1272 return BCM_E_PARAM; 1273 } 1274 if (SOC_MEM_FIELD_VALID(unit, mem_view_id, DVPf)) { 1275 soc_mem_field32_set(unit, mem_view_id, entry, DVPf, dvp); 1276 } else { 1277 LOG_VERBOSE(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 1278 "DVPf not in memory view definition\n"))); 1279 return BCM_E_PARAM; 1280 } 1281 1282 } else if (info->encap_criteria == 1283 BCM_FLOW_ENCAP_CRITERIA_L3_INTF) { 1284 1285 if (info->valid_elements & BCM_FLOW_STAT_INTF_ID_VALID) { 1286 /* only apply to flex view */ 1287 if (SOC_MEM_FIELD_VALID(unit,mem_view_id, L3_OIFf)) { 1288 soc_mem_field32_set(unit,mem_view_id, entry, L3_OIFf, info->intf_id); 1289 } else { 1290 LOG_VERBOSE(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 1291 "L3_OIFf not in memory view definition\n"))); 1292 return BCM_E_PARAM; 1293 } 1294 } 1295 } else if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VRF_MAPPING) { 1296 /* KEY : VRF,VT_DVP_GROUP_ID,VT_L3_OIF_GROUP_ID 1297 * VT_DVP_GROUP_ID : from EGR_DVP_ATTRIBUTEm 1298 * VT_L3_OIF_GROUP_ID : from EGR_L3_INTFm 1299 */ 1300 _BCM_FLOW_VPN_GET(vrf, _BCM_VPN_TYPE_L3, info->vpn); 1301 vrf_f = VRFf; 1302 dvp_grp_f = VT_DVP_GROUP_IDf; 1303 oif_grp_f = VT_L3OIF_GROUP_IDf; 1304 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 1305 soc_mem_field32_set(unit,mem_view_id, entry, vrf_f, vrf); 1306 } 1307 if (info->valid_elements & BCM_FLOW_STAT_DVP_GROUP_VALID) { 1308 soc_mem_field32_set(unit,mem_view_id, entry, dvp_grp_f, info->dvp_group); 1309 } 1310 if (info->valid_elements & BCM_FLOW_STAT_OIF_GROUP_VALID) { 1311 soc_mem_field32_set(unit,mem_view_id, entry, oif_grp_f, info->oif_group); 1312 } 1313 } else if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VFI_DVP_GROUP) { 1314 vfi_f = VFIf; 1315 dvp_grp_f = VT_DVP_GROUP_IDf; 1316 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 1317 soc_mem_field32_set(unit,mem_view_id, entry, vfi_f, vfi); 1318 } 1319 if (info->valid_elements & BCM_FLOW_STAT_DVP_GROUP_VALID) { 1320 soc_mem_field32_set(unit,mem_view_id, entry, dvp_grp_f, info->dvp_group); 1321 } 1322 } else if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VFI) { 1323 vfi_f = VFIf; 1324 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 1325 soc_mem_field32_set(unit,mem_view_id, entry, vfi_f, vfi); 1326 } 1327 } else if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_VFI_DVP) { 1328 vfi_f = VFIf; 1329 dvp_f = DVPf; 1330 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 1331 soc_mem_field32_set(unit, mem_view_id, entry, vfi_f, vfi); 1332 } 1333 if (info->valid_elements & BCM_FLOW_STAT_FLOW_PORT_VALID) { 1334 soc_mem_field32_set(unit, mem_view_id, entry, dvp_f, dvp); 1335 } 1336 } else if (info->encap_criteria == BCM_FLOW_ENCAP_CRITERIA_FLEX) { 1337 rv = soc_flow_db_mem_view_field_list_get(unit, 1338 mem_view_id, 1339 SOC_FLOW_DB_FIELD_TYPE_LOGICAL_KEY, 1340 _BCM_FLOW_LOGICAL_FIELD_MAX, key_lg_list, &num_lg_keys); 1341 BCM_IF_ERROR_RETURN(rv); 1342 for (i = 0; i < num_of_fields; i++) { 1343 for (j = 0; j < num_lg_keys; j++) { 1344 if (field[i].id == key_lg_list[j]) { 1345 soc_mem_field32_set(unit,mem_view_id, entry, 1346 field[i].id, field[i].value); 1347 break; 1348 } 1349 } 1350 } 1351 if (info->valid_elements & BCM_FLOW_STAT_FLOW_PORT_VALID) { 1352 soc_mem_field32_set(unit,mem_view_id, entry, DVPf, dvp); 1353 } 1354 if (info->valid_elements & BCM_FLOW_STAT_VPN_VALID) { 1355 soc_mem_field32_set(unit,mem_view_id, entry, VFIf, vfi); 1356 } 1357 if (info->valid_elements & BCM_FLOW_STAT_INTF_ID_VALID) { 1358 soc_mem_field32_set(unit,mem_view_id, entry, L3_OIFf, info->intf_id); 1359 } 1360 if (info->valid_elements & BCM_FLOW_STAT_DVP_GROUP_VALID) { 1361 soc_mem_field32_set(unit,mem_view_id, entry, VT_DVP_GROUP_IDf, 1362 info->dvp_group); 1363 } 1364 if (info->valid_elements & BCM_FLOW_STAT_OIF_GROUP_VALID) { 1365 soc_mem_field32_set(unit,mem_view_id, entry, VT_L3OIF_GROUP_IDf, 1366 info->oif_group); 1367 } 1368 } 1369 } else if (info->function_type == bcmFlowFuncTypeMatch) { 1370 1371 t_f = Tf; 1372 tgid_f = TGIDf; 1373 module_id_f = MODULE_IDf; 1374 port_num_f = PORT_NUMf; 1375 ovid_f = OVIDf; 1376 ivid_f = IVIDf; 1377 if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_VLAN || 1378 info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_INNER_VLAN || 1379 info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_VLAN_STACKED || 1380 info->match_criteria == BCM_FLOW_MATCH_CRITERIA_VLAN_PRI) { 1381 if (info->valid_elements & BCM_FLOW_STAT_PORT_VALID) { 1382 BCM_IF_ERROR_RETURN( 1383 _bcm_esw_gport_resolve(unit, info->port, &mod_out, 1384 &port_out, &trunk_id, &gport_id)); 1385 if (BCM_GPORT_IS_TRUNK(info->port)) { 1386 soc_mem_field32_set(unit, mem_view_id, entry, t_f, 1); 1387 soc_mem_field32_set(unit, mem_view_id, entry, tgid_f, trunk_id); 1388 } else { 1389 if (mod_out != -1) { 1390 soc_mem_field32_set(unit, mem_view_id, entry, module_id_f, 1391 mod_out); 1392 } 1393 soc_mem_field32_set(unit, mem_view_id, entry, port_num_f, port_out); 1394 } 1395 } 1396 soc_mem_field32_set(unit, mem_view_id, entry, SOURCE_TYPEf, 1); 1397 } 1398 if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_VLAN ) { 1399 if (!BCM_VLAN_VALID(info->vlan)) { 1400 LOG_ERROR(BSL_LS_BCM_FLOW, 1401 (BSL_META_U(unit, "Invalid vlan\n"))); 1402 return BCM_E_PARAM; 1403 } 1404 soc_mem_field32_set(unit, mem_view_id, entry, ovid_f, info->vlan); 1405 1406 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_INNER_VLAN) { 1407 if (!BCM_VLAN_VALID(info->inner_vlan)) { 1408 LOG_ERROR(BSL_LS_BCM_FLOW, 1409 (BSL_META_U(unit, "Invalid inner vlan\n"))); 1410 return BCM_E_PARAM; 1411 } 1412 soc_mem_field32_set(unit, mem_view_id, entry, ivid_f, info->inner_vlan); 1413 1414 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_PORT_VLAN_STACKED) { 1415 if (!BCM_VLAN_VALID(info->vlan) || 1416 !BCM_VLAN_VALID(info->inner_vlan)) { 1417 LOG_ERROR(BSL_LS_BCM_FLOW, 1418 (BSL_META_U(unit, "Invalid either outer vlan or inner vlan\n"))); 1419 return BCM_E_PARAM; 1420 } 1421 soc_mem_field32_set(unit, mem_view_id, entry, ovid_f, info->vlan); 1422 soc_mem_field32_set(unit, mem_view_id, entry, ivid_f, info->inner_vlan); 1423 1424 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_VLAN_PRI) { 1425 1426 /* match_vlan : Bits 12-15 contains VLAN_PRI + CFI, vlan=BCM_E_NONE */ 1427 soc_mem_field32_set(unit, mem_view_id, entry, OTAGf, info->vlan); 1428 1429 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_SIP) { 1430 ovid_f = OVIDf; 1431 if (SOC_MEM_FIELD_VALID(unit, mem_view_id, IPV4__SIPf)) { 1432 sip_f = IPV4__SIPf; 1433 } else { 1434 sip_f = SIPf; 1435 } 1436 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination) && 1437 (info->valid_elements & BCM_FLOW_STAT_VLAN_VALID)) { 1438 VLAN_CHK_ID(unit,info->vlan); 1439 soc_mem_field32_set(unit, mem_view_id, entry, ovid_f, info->vlan); 1440 } 1441 soc_mem_field32_set(unit, mem_view_id, entry, sip_f, info->sip); 1442 1443 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_VN_ID || 1444 info->match_criteria == BCM_FLOW_MATCH_CRITERIA_SIP_VNID) { 1445 1446 ovid_f = OVIDf; 1447 vnid_f = VNIDf; 1448 if (SOC_MEM_FIELD_VALID(unit, mem_view_id, IPV4__SIPf)) { 1449 sip_f = IPV4__SIPf; 1450 } else { 1451 sip_f = SIPf; 1452 } 1453 soc_mem_field32_set(unit, mem_view_id, entry, vnid_f, info->vnid); 1454 if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_SIP_VNID) { 1455 soc_mem_field32_set(unit, mem_view_id, entry, sip_f, info->sip); 1456 } 1457 1458 if (soc_feature(unit,soc_feature_vrf_aware_vxlan_termination) && 1459 (info->valid_elements & BCM_FLOW_STAT_VLAN_VALID)) { 1460 VLAN_CHK_ID(unit, info->vlan); 1461 soc_mem_field32_set(unit, mem_view_id, entry, ovid_f, info->vlan); 1462 } 1463 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_MPLS_LABEL) { 1464 if (SOC_MEM_FIELD_VALID(unit, mem_view_id, MPLS_LABEL_1f)) { 1465 lbl_f = MPLS_LABEL_1f; 1466 } else if (SOC_MEM_FIELD_VALID(unit, mem_view_id, MPLS_LABEL_2f)) { 1467 lbl_f = MPLS_LABEL_2f; 1468 } else { 1469 LOG_ERROR(BSL_LS_BCM_FLOW, 1470 (BSL_META_U(unit, "mpls_label field not found\n"))); 1471 return BCM_E_PARAM; 1472 } 1473 soc_mem_field32_set(unit, mem_view_id, entry, lbl_f, info->mpls_label); 1474 } else if (info->match_criteria == BCM_FLOW_MATCH_CRITERIA_FLEX) { 1475 ovid_f = OVIDf; 1476 vnid_f = VNIDf; 1477 1478 rv = soc_flow_db_mem_view_field_list_get(unit, 1479 mem_view_id, 1480 SOC_FLOW_DB_FIELD_TYPE_LOGICAL_KEY, 1481 _BCM_FLOW_LOGICAL_FIELD_MAX, key_lg_list, &num_lg_keys); 1482 if (rv != SOC_E_NONE && rv != SOC_E_NOT_FOUND) { 1483 return rv; 1484 } 1485 if (rv == SOC_E_NONE) { 1486 for (i = 0; i < num_of_fields; i++) { 1487 for (j = 0; j < num_lg_keys; j++) { 1488 if (field[i].id == key_lg_list[j]) { 1489 soc_mem_field32_set(unit, mem_view_id, entry, 1490 field[i].id, field[i].value); 1491 break; 1492 } 1493 } 1494 } 1495 } 1496 rv = SOC_E_NONE; 1497 if (info->valid_elements & BCM_FLOW_STAT_VNID_VALID) { 1498 if (!SOC_MEM_FIELD_VALID(unit, mem_view_id,vnid_f)) { 1499 return SOC_E_PARAM; 1500 } 1501 soc_mem_field32_set(unit, mem_view_id, entry, vnid_f, info->vnid); 1502 } 1503 if (info->valid_elements & BCM_FLOW_STAT_VLAN_VALID) { 1504 if (!SOC_MEM_FIELD_VALID(unit, mem_view_id,ovid_f)) { 1505 return SOC_E_PARAM; 1506 } 1507 soc_mem_field32_set(unit, mem_view_id, entry, ovid_f, info->vlan); 1508 } 1509 if (info->valid_elements & BCM_FLOW_STAT_INNER_VLAN_VALID) { 1510 if (!SOC_MEM_FIELD_VALID(unit, mem_view_id, ivid_f)) { 1511 return SOC_E_PARAM; 1512 } 1513 soc_mem_field32_set(unit, mem_view_id, entry, ivid_f, info->inner_vlan); 1514 } 1515 if (info->valid_elements & BCM_FLOW_STAT_PORT_VALID) { 1516 if (BCM_GPORT_IS_TRUNK(info->port)) { 1517 if (!(SOC_MEM_FIELD_VALID(unit, mem_view_id,t_f) && 1518 SOC_MEM_FIELD_VALID(unit, mem_view_id, tgid_f))) { 1519 return SOC_E_PARAM; 1520 } 1521 1522 soc_mem_field32_set(unit, mem_view_id, entry, t_f, 1); 1523 soc_mem_field32_set(unit, mem_view_id, entry, tgid_f, trunk_id); 1524 } else { 1525 if ((SOC_MEM_FIELD_VALID(unit, mem_view_id,module_id_f) && 1526 SOC_MEM_FIELD_VALID(unit, mem_view_id,port_num_f))) { 1527 soc_mem_field32_set(unit, mem_view_id, entry, module_id_f, 1528 mod_out); 1529 soc_mem_field32_set(unit, mem_view_id, entry, port_num_f, 1530 port_out); 1531 } else if (SOC_MEM_FIELD_VALID(unit, mem_view_id, SGPPf)) { 1532 soc_mem_field32_set(unit, mem_view_id, entry, SGPPf, 1533 port_out | (mod_out << 8)); 1534 } else { 1535 return SOC_E_PARAM; 1536 } 1537 } 1538 } 1539 if (info->valid_elements & BCM_FLOW_STAT_SIP_VALID) { 1540 if (SOC_MEM_FIELD_VALID(unit, mem_view_id, SIPf)) { 1541 sip_f = SIPf; 1542 } else if (SOC_MEM_FIELD_VALID(unit, mem_view_id, IPV4__SIPf)) { 1543 sip_f = IPV4__SIPf; 1544 } else { 1545 return SOC_E_PARAM; 1546 } 1547 soc_mem_field32_set(unit, mem_view_id, entry, sip_f, info->sip); 1548 } 1549 if (info->valid_elements & BCM_FLOW_STAT_SIP6_VALID) { 1550 if (!SOC_MEM_FIELD_VALID(unit, mem_view_id,IPV6__SIPf)) { 1551 return SOC_E_PARAM; 1552 } 1553 soc_mem_ip6_addr_set(unit, mem_view_id, entry,IPV6__SIPf, info->sip6, 0); 1554 } 1555 if (info->valid_elements & BCM_FLOW_STAT_DIP_VALID) { 1556 if (!SOC_MEM_FIELD_VALID(unit, mem_view_id,IPV4__DIPf)) { 1557 return SOC_E_PARAM; 1558 } 1559 soc_mem_field32_set(unit, mem_view_id, entry, IPV4__DIPf, info->dip); 1560 } 1561 if (info->valid_elements & BCM_FLOW_STAT_DIP6_VALID) { 1562 if (!SOC_MEM_FIELD_VALID(unit, mem_view_id,IPV6__DIPf)) { 1563 return SOC_E_PARAM; 1564 } 1565 soc_mem_ip6_addr_set(unit, mem_view_id, entry,IPV6__DIPf, info->dip6, 0); 1566 } 1567 if (info->valid_elements & BCM_FLOW_STAT_PROTOCOL_VALID) { 1568 if (!SOC_MEM_FIELD_VALID(unit, mem_view_id, IPV4__PROTOCOLf)) { 1569 return SOC_E_PARAM; 1570 } 1571 soc_mem_field32_set(unit, mem_view_id, entry, IPV4__PROTOCOLf, 1572 info->protocol); 1573 } 1574 if (info->valid_elements & BCM_FLOW_STAT_UDP_SRC_PORT_VALID) { 1575 if (!SOC_MEM_FIELD_VALID(unit, mem_view_id,L4_SRC_PORTf)) { 1576 return SOC_E_PARAM; 1577 } 1578 soc_mem_field32_set(unit, mem_view_id, entry, L4_SRC_PORTf, 1579 info->udp_src_port); 1580 } 1581 if (info->valid_elements & BCM_FLOW_STAT_UDP_DST_PORT_VALID) { 1582 if (!SOC_MEM_FIELD_VALID(unit, mem_view_id, L4_DST_PORTf)) { 1583 return SOC_E_PARAM; 1584 } 1585 soc_mem_field32_set(unit, mem_view_id, entry, L4_DST_PORTf, 1586 info->udp_dst_port); 1587 } 1588 } 1589 } else if (info->function_type == bcmFlowFuncTypeTunnelTerm) { 1590 /* flex view, initialize all control fields such as data_type */ 1591 BCM_IF_ERROR_RETURN(soc_flow_db_mem_view_field_list_get(unit, 1592 mem_view_id, 1593 SOC_FLOW_DB_FIELD_TYPE_KEY, 1594 _BCM_FLOW_LOGICAL_FIELD_MAX, 1595 key_list, 1596 &num_keys)); 1597 for (i = 0; i < num_keys; i++) { 1598 if (key_list[i] == IPV4__DIPf) { 1599 if (info->valid_elements & BCM_FLOW_STAT_DIP_VALID) { 1600 rv = (info->dip) ? BCM_E_NONE : BCM_E_PARAM; 1601 BCM_IF_ERROR_RETURN(rv); 1602 soc_mem_field32_set(unit, mem_view_id, entry, 1603 IPV4__DIPf, info->dip); 1604 } 1605 } else if (key_list[i] == IPV4__SIPf) { 1606 if (info->valid_elements & BCM_FLOW_STAT_SIP_VALID) { 1607 rv = (info->sip) ? BCM_E_NONE : BCM_E_PARAM; 1608 BCM_IF_ERROR_RETURN(rv); 1609 soc_mem_field32_set(unit, mem_view_id, entry, 1610 IPV4__SIPf, info->sip); 1611 } 1612 } else if (key_list[i] == IPV4__DIP_MASKf) { 1613 if (info->valid_elements & BCM_FLOW_STAT_DIP_MASK_VALID) { 1614 rv = (info->dip_mask) ? BCM_E_NONE : BCM_E_PARAM; 1615 BCM_IF_ERROR_RETURN(rv); 1616 soc_mem_field32_set(unit, mem_view_id, entry, 1617 IPV4__DIP_MASKf, info->dip); 1618 } 1619 } else if (key_list[i] == IPV4__SIP_MASKf) { 1620 if (info->valid_elements & BCM_FLOW_STAT_SIP_MASK_VALID) { 1621 rv = (info->sip_mask) ? BCM_E_NONE : BCM_E_PARAM; 1622 BCM_IF_ERROR_RETURN(rv); 1623 soc_mem_field32_set(unit, mem_view_id, entry, 1624 IPV4__SIP_MASKf, info->sip_mask); 1625 } 1626 } else if (key_list[i] == L4_DEST_PORTf) { 1627 if(info->valid_elements & BCM_FLOW_STAT_UDP_DST_PORT_VALID) { 1628 rv = (info->udp_dst_port) ? BCM_E_NONE : BCM_E_PARAM; 1629 BCM_IF_ERROR_RETURN(rv); 1630 soc_mem_field32_set(unit, mem_view_id, entry, 1631 L4_DEST_PORTf, info->udp_dst_port); 1632 } 1633 } else if (key_list[i] == L4_SRC_PORTf) { 1634 if(info->valid_elements & BCM_FLOW_STAT_UDP_SRC_PORT_VALID) { 1635 rv = (info->udp_src_port) ? BCM_E_NONE : BCM_E_PARAM; 1636 BCM_IF_ERROR_RETURN(rv); 1637 soc_mem_field32_set(unit, mem_view_id, entry, 1638 L4_SRC_PORTf, info->udp_src_port); 1639 } 1640 } else if (key_list[i] == PROTOCOLf) { 1641 if(info->valid_elements & BCM_FLOW_STAT_PROTOCOL_VALID) { 1642 rv = (info->protocol) ? BCM_E_NONE : BCM_E_PARAM; 1643 BCM_IF_ERROR_RETURN(rv); 1644 soc_mem_field32_set(unit, mem_view_id, entry, 1645 PROTOCOLf, info->protocol); 1646 } 1647 } else if (key_list[i] == IPV6__SIPf) { 1648 if (info->valid_elements & BCM_FLOW_STAT_SIP6_VALID) { 1649 rv = (bcmi_flow_ip6_addr_is_valid(info->sip6)) ? 1650 BCM_E_NONE : BCM_E_PARAM; 1651 BCM_IF_ERROR_RETURN(rv); 1652 soc_mem_ip6_addr_set(unit, mem_view_id, entry, 1653 IPV6__SIPf, info->sip6, 0); 1654 } 1655 } else if (key_list[i] == IPV6__DIPf) { 1656 if (info->valid_elements & BCM_FLOW_STAT_DIP6_VALID) { 1657 rv = (bcmi_flow_ip6_addr_is_valid(info->dip6)) ? 1658 BCM_E_NONE : BCM_E_PARAM; 1659 BCM_IF_ERROR_RETURN(rv); 1660 soc_mem_ip6_addr_set(unit, mem_view_id, entry, 1661 IPV6__DIPf, info->dip6, 0); 1662 } 1663 } else if (key_list[i] == IPV6__SIP_MASKf) { 1664 if (info->valid_elements & BCM_FLOW_STAT_SIP6_MASK_VALID) { 1665 rv = (bcmi_flow_ip6_addr_is_valid(info->sip6_mask)) ? 1666 BCM_E_NONE : BCM_E_PARAM; 1667 BCM_IF_ERROR_RETURN(rv); 1668 soc_mem_ip6_addr_set(unit, mem_view_id, entry, 1669 IPV6__SIP_MASKf, info->sip6_mask, 0); 1670 } 1671 } else if (key_list[i] == IPV6__DIP_MASKf) { 1672 if (info->valid_elements & BCM_FLOW_STAT_DIP6_MASK_VALID) { 1673 rv = (bcmi_flow_ip6_addr_is_valid(info->dip6_mask)) ? 1674 BCM_E_NONE : BCM_E_PARAM; 1675 BCM_IF_ERROR_RETURN(rv); 1676 soc_mem_ip6_addr_set(unit, mem_view_id, entry, 1677 IPV6__DIP_MASKf, info->dip6_mask, 0); 1678 } 1679 } 1680 } 1681 if (info->valid_elements & BCM_FLOW_STAT_FLEX_KEY_VALID) { 1682 /* Logical key fields */ 1683 BCM_IF_ERROR_RETURN( 1684 soc_flow_db_mem_view_field_list_get(unit, 1685 mem_view_id, 1686 SOC_FLOW_DB_FIELD_TYPE_LOGICAL_KEY, 1687 SOC_FLOW_DB_MAX_VIEW_FIELDS, 1688 key_lg_list, 1689 &num_lg_keys)); 1690 for (i = 0;(i < num_of_fields); i++) { 1691 for (j = 0; j < num_lg_keys; j++) { 1692 if (field[i].id == key_lg_list[j]) { 1693 soc_mem_field32_set(unit, mem_view_id, entry, 1694 field[i].id, field[i].value); 1695 } 1696 } 1697 } 1698 } 1699 1700 } else if ((info->function_type == bcmFlowFuncTypeTunnelInit) && 1701 (info->valid_elements & BCM_FLOW_STAT_TUNNEL_ID_VALID)) { 1702 /* Tunnel intitator id - validate the tunnel index*/ 1703 soft_tnl_idx = BCM_GPORT_TUNNEL_ID_GET(info->tunnel_id); 1704 _BCM_FLOW_TUNNEL_ID_IF_INVALID_RETURN(unit, soft_tnl_idx); 1705 if (!flow_info->init_tunnel[soft_tnl_idx].idx) { 1706 LOG_ERROR(BSL_LS_BCM_FLOW, (BSL_META_U(unit, 1707 "Invalid replace action, tunnel not created\n"))); 1708 return BCM_E_PARAM; 1709 } 1710 *index = flow_info->init_tunnel[soft_tnl_idx].idx; 1711 1712 return BCM_E_NONE; 1713 } else if ((info->function_type == bcmFlowFuncTypeEgressObj) && 1714 (info->valid_elements & BCM_FLOW_STAT_EGRESS_IF_VALID)) { 1715 /* Get the nexthop index from the egress object 1716 * info->egress_if 1717 */ 1718 rv = bcm_xgs3_get_nh_from_egress_object(unit, info->egress_if, 1719 &mpath_flag, 1720 1, 1721 &nh_index); 1722 *index = nh_index; 1723 return BCM_E_NONE; 1724 } else if ((info->function_type == bcmFlowFuncTypeEgressIntf) && 1725 (info->valid_elements & BCM_FLOW_STAT_INTF_ID_VALID)) { 1726 /* index to EGR_L3_INTF */ 1727 *index = info->intf_id; 1728 return BCM_E_NONE; 1729 } else if ((info->function_type == bcmFlowFuncTypeL2Switch) && 1730 (info->valid_elements & BCM_FLOW_STAT_MAC_VALID)) { 1731 /* L2_ENTRYm */ 1732 soc_mem_mac_addr_set(unit, mem_view_id, entry, MAC_DAf, info->mac); 1733 } 1734 rv = _bcm_esw_flow_stat_table_index_get(unit, 1735 vinfo, 1736 entry, 1, mem_view_id, index); 1737 1738 return rv; 1739 } 1740 1741 int bcmi_esw_flow_stat_object_get(int unit, 1742 bcm_flow_handle_t flow_handle, 1743 bcm_flow_option_id_t flow_option_id, 1744 bcm_flow_function_type_t function_type, 1745 bcm_stat_object_t *stat_object) 1746 { 1747 int rv = BCM_E_NONE; 1748 uint32 mem_view_id = 0; 1749 soc_mem_t mem = 0; 1750 soc_flow_db_mem_view_info_t view_info; 1751 bcm_stat_flex_direction_t direction; 1752 1753 direction = bcmStatFlexDirectionIngress; 1754 /* get the view mem */ 1755 /* mem - Ingress/Egress */ 1756 1757 rv = soc_flow_db_ffo_to_mem_view_id_get(unit, 1758 flow_handle, flow_option_id, 1759 function_type, &mem_view_id); 1760 if (BCM_FAILURE(rv)) { 1761 LOG_ERROR(BSL_LS_BCM_FLOW, 1762 (BSL_META_U(unit, 1763 "Invalid combination of flow, \ 1764 flow_option and function_type.\n"))); 1765 return rv; 1766 } 1767 1768 LOG_VERBOSE(BSL_LS_BCM_FLOW, 1769 (BSL_META_U(unit, 1770 "Stat object get for View ID %d \n"), 1771 mem_view_id)); 1772 BCM_IF_ERROR_RETURN(soc_flow_db_mem_view_info_get(unit, mem_view_id, 1773 &view_info)); 1774 1775 mem = view_info.mem; 1776 1777 BCM_IF_ERROR_RETURN(_bcm_esw_flow_stat_mem_direction_get(unit, mem, 1778 &direction)); 1779 if (direction == bcmStatFlexDirectionIngress) { 1780 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object( 1781 unit, mem_view_id, 1782 0,NULL,stat_object)); 1783 } else if (direction == bcmStatFlexDirectionEgress) { 1784 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object( 1785 unit, mem_view_id, 1786 0, NULL,stat_object)); 1787 } else { 1788 return BCM_E_INTERNAL; 1789 } 1790 1791 return rv; 1792 } 1793 1794 int bcmi_esw_flow_stat_attach(int unit, 1795 bcm_flow_stat_info_t *info, 1796 uint32 num_of_fields, 1797 bcm_flow_logical_field_t *field, 1798 uint32 stat_counter_id) 1799 { 1800 int rv = BCM_E_NONE; 1801 uint32 mem_view_id = 0; 1802 soc_mem_t mem = 0; 1803 soc_flow_db_mem_view_info_t vinfo; 1804 soc_mem_t table[BCM_FLEXFLOW_FLEX_COUNTER_MAX_TABLE]; 1805 uint32 act_num_tables = 0; 1806 uint32 pool_number = 0; 1807 uint32 base_index = 0; 1808 bcm_stat_flex_mode_t offset_mode = 0; 1809 bcm_stat_object_t object = bcmStatObjectIngPort; 1810 bcm_stat_group_mode_t group_mode = bcmStatGroupModeSingle; 1811 bcm_stat_flex_direction_t direction = bcmStatFlexDirectionIngress; 1812 int index = -1; 1813 uint32 valid = FALSE; 1814 1815 1816 /* resolve the index */ 1817 1818 sal_memset(table, 0, sizeof(table)); 1819 BCM_IF_ERROR_RETURN( 1820 _bcm_esw_flow_stat_info_validate(unit, 1821 info)); 1822 1823 _bcm_esw_stat_get_counter_id_info( 1824 unit, stat_counter_id, 1825 &group_mode, &object, &offset_mode, &pool_number, &base_index); 1826 1827 /* Validate object and group mode */ 1828 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit, object, &direction)); 1829 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit, group_mode)); 1830 1831 /* Get Table index to attach flexible counter */ 1832 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info( 1833 unit, object, BCM_FLEXFLOW_FLEX_COUNTER_MAX_TABLE, 1834 &act_num_tables, &table[0], &direction)); 1835 LOG_ERROR(BSL_LS_BCM_FLOW, 1836 (BSL_META_U(unit,"flex counter attach for object %d table %d\n"), 1837 object, mem)); 1838 1839 if (soc_flow_db_mem_view_flow_handle_valid(unit, info->flow_handle)) { 1840 return BCM_E_PARAM; 1841 } 1842 1843 /* Flex Table - flex view */ 1844 rv = soc_flow_db_ffo_to_mem_view_id_get(unit, 1845 info->flow_handle, 1846 info->flow_option, 1847 info->function_type, 1848 &mem_view_id); 1849 1850 if (BCM_SUCCESS(rv)) { 1851 /* Flex Table - flex view */ 1852 BCM_IF_ERROR_RETURN( 1853 soc_flow_db_mem_view_info_get(unit, mem_view_id, &vinfo)); 1854 mem = vinfo.mem_view_id; 1855 1856 BCM_IF_ERROR_RETURN( 1857 _bcm_esw_flow_stat_flex_mem_is_valid(unit, 1858 vinfo.mem, 1859 act_num_tables, 1860 &table[0], 1861 &valid)); 1862 1863 if (valid != TRUE) { 1864 LOG_ERROR(BSL_LS_BCM_FLOW, 1865 (BSL_META_U(unit, 1866 "Mismatch in stat_object_id %d resolved memory \ 1867 and resolved memory %d.\n"), 1868 object, vinfo.mem)); 1869 return BCM_E_PARAM; 1870 } 1871 1872 /* Resolve the index from the key fields */ 1873 BCM_IF_ERROR_RETURN( 1874 _bcm_esw_flow_stat_flex_view_index_get(unit, info, 1875 field, num_of_fields, 1876 vinfo, direction, &index)); 1877 1878 1879 } else if (BCM_FLOW_IS_FIXED_TABLE(info)) { /* == 0 */ 1880 /* fixed tables SOURCE_VP, VFI, EGR_VFI 1881 * which are programmed as part of the flex flows 1882 */ 1883 BCM_IF_ERROR_RETURN( 1884 _bcm_esw_flow_stat_fixed_table_index_get(unit, 1885 info, 1886 direction, 1887 &mem, 1888 &index)); 1889 BCM_IF_ERROR_RETURN( 1890 _bcm_esw_flow_stat_flex_mem_is_valid(unit, 1891 mem, 1892 act_num_tables, 1893 &table[0], 1894 &valid)); 1895 1896 if (valid != TRUE) { 1897 LOG_ERROR(BSL_LS_BCM_FLOW, 1898 (BSL_META_U(unit, 1899 "Mismatch in stat_object_id %d resolved memory\ 1900 and resolved memory %d.\n"), 1901 object, mem)); 1902 return BCM_E_PARAM; 1903 } 1904 1905 } else if (BCM_FLOW_IS_FIXED_VIEW(info)) { 1906 /* Flex table - fixed views */ 1907 /* Classic flows */ 1908 1909 BCM_IF_ERROR_RETURN( 1910 _bcm_esw_flow_stat_fixed_view_index_get(unit, 1911 info, num_of_fields, 1912 field, direction, &mem, 1913 &index)); 1914 BCM_IF_ERROR_RETURN( 1915 _bcm_esw_flow_stat_flex_mem_is_valid(unit, 1916 mem, 1917 act_num_tables, 1918 &table[0], 1919 &valid)); 1920 1921 if (valid != TRUE) { 1922 LOG_ERROR(BSL_LS_BCM_FLOW, 1923 (BSL_META_U(unit, 1924 "Mismatch in stat_object_id %d resolved memory\ 1925 and resolved memory %d.\n"), 1926 object, mem)); 1927 return BCM_E_PARAM; 1928 } 1929 1930 } else { 1931 LOG_ERROR(BSL_LS_BCM_FLOW, 1932 (BSL_META_U(unit, 1933 "Invalid combination of flow, \ 1934 flow_option and function_type \ 1935 or not a supported memory\n"))); 1936 return BCM_E_PARAM; 1937 } 1938 1939 1940 if (direction == bcmStatFlexDirectionIngress) { 1941 rv = _bcm_esw_stat_flex_attach_ingress_table_counters( 1942 unit, 1943 mem, 1944 index, 1945 offset_mode, 1946 base_index, 1947 pool_number); 1948 } else { 1949 rv = _bcm_esw_stat_flex_attach_egress_table_counters( 1950 unit, 1951 mem, 1952 index, 1953 object, 1954 offset_mode, 1955 base_index, 1956 pool_number); 1957 } 1958 1959 return rv; 1960 } 1961 1962 int bcmi_esw_flow_stat_detach(int unit, 1963 bcm_flow_stat_info_t *info, 1964 uint32 num_of_fields, 1965 bcm_flow_logical_field_t *field, 1966 uint32 stat_counter_id) 1967 { 1968 bcm_error_t rv = BCM_E_NONE; 1969 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 1970 uint32 mem_view_id = 0; 1971 soc_mem_t mem = 0; 1972 soc_flow_db_mem_view_info_t vinfo; 1973 bcm_stat_object_t object = bcmStatObjectIngPort; 1974 soc_mem_t table[BCM_FLEXFLOW_FLEX_COUNTER_MAX_TABLE]; 1975 uint32 act_num_tables = 0; 1976 int index = -1; 1977 bcm_stat_flex_direction_t direction = bcmStatFlexDirectionIngress; 1978 uint32 pool_number = 0; 1979 uint32 base_index = 0; 1980 bcm_stat_flex_mode_t offset_mode = 0; 1981 bcm_stat_group_mode_t group_mode = bcmStatGroupModeSingle; 1982 uint32 valid = FALSE; 1983 1984 1985 sal_memset(table, 0, sizeof(table)); 1986 BCM_IF_ERROR_RETURN( 1987 _bcm_esw_flow_stat_info_validate(unit, 1988 info)); 1989 1990 _bcm_esw_stat_get_counter_id_info( 1991 unit, stat_counter_id, 1992 &group_mode, &object, &offset_mode, &pool_number, &base_index); 1993 1994 /* Validate object and group mode */ 1995 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit, object, &direction)); 1996 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit, group_mode)); 1997 1998 /* Get Table index to attach flexible counter */ 1999 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info( 2000 unit, object, BCM_FLEXFLOW_FLEX_COUNTER_MAX_TABLE, 2001 &act_num_tables, &table[0], &direction)); 2002 LOG_ERROR(BSL_LS_BCM_FLOW, 2003 (BSL_META_U(unit,"flex counter attach for object %d table %d\n"), 2004 object, mem)); 2005 2006 2007 if (soc_flow_db_mem_view_flow_handle_valid(unit, info->flow_handle)) { 2008 return BCM_E_PARAM; 2009 } 2010 rv = soc_flow_db_ffo_to_mem_view_id_get(unit, 2011 info->flow_handle, 2012 info->flow_option, 2013 info->function_type, &mem_view_id); 2014 2015 if (BCM_SUCCESS(rv)) { 2016 /* Flex Table - flex view */ 2017 BCM_IF_ERROR_RETURN( 2018 soc_flow_db_mem_view_info_get(unit, mem_view_id, &vinfo)); 2019 mem = vinfo.mem_view_id; 2020 BCM_IF_ERROR_RETURN( 2021 _bcm_esw_flow_stat_flex_mem_is_valid(unit, 2022 vinfo.mem, 2023 act_num_tables, 2024 &table[0], 2025 &valid)); 2026 2027 if (valid != TRUE) { 2028 LOG_ERROR(BSL_LS_BCM_FLOW, 2029 (BSL_META_U(unit, 2030 "Mismatch in stat_object_id %d resolved memory \ 2031 and resolved memory %d.\n"), 2032 object, vinfo.mem)); 2033 return BCM_E_PARAM; 2034 } 2035 2036 /* Resolve the index from the key fields */ 2037 BCM_IF_ERROR_RETURN( 2038 _bcm_esw_flow_stat_flex_view_index_get(unit, info, 2039 field, num_of_fields, 2040 vinfo, direction, &index)); 2041 } else if (BCM_FLOW_IS_FIXED_TABLE(info)) { /* == 0 */ 2042 /* fixed tables SOURCE_VP, VFI, EGR_VFI 2043 * which are programmed as part of the flex flows 2044 */ 2045 BCM_IF_ERROR_RETURN( 2046 _bcm_esw_flow_stat_fixed_table_index_get(unit, 2047 info, 2048 direction, 2049 &mem, 2050 &index)); 2051 BCM_IF_ERROR_RETURN( 2052 _bcm_esw_flow_stat_flex_mem_is_valid(unit, 2053 mem, 2054 act_num_tables, 2055 &table[0], 2056 &valid)); 2057 2058 if (valid != TRUE) { 2059 LOG_ERROR(BSL_LS_BCM_FLOW, 2060 (BSL_META_U(unit, 2061 "Mismatch in stat_object_id %d resolved memory \ 2062 and resolved memory %d.\n"), 2063 object, mem)); 2064 return BCM_E_PARAM; 2065 } 2066 2067 } else if (BCM_FLOW_IS_FIXED_VIEW(info)) { 2068 /* Flex table - fixed views */ 2069 /* Classic flows */ 2070 /* Resolve the index from the key fields*/ 2071 2072 BCM_IF_ERROR_RETURN( 2073 _bcm_esw_flow_stat_fixed_view_index_get(unit, 2074 info, num_of_fields, 2075 field, direction, &mem, 2076 &index)); 2077 BCM_IF_ERROR_RETURN( 2078 _bcm_esw_flow_stat_flex_mem_is_valid(unit, 2079 mem, 2080 act_num_tables, 2081 &table[0], 2082 &valid)); 2083 2084 if (valid != TRUE) { 2085 LOG_ERROR(BSL_LS_BCM_FLOW, 2086 (BSL_META_U(unit, 2087 "Mismatch in stat_object_id %d resolved memory \ 2088 and resolved memory %d.\n"), 2089 object, mem)); 2090 return BCM_E_PARAM; 2091 } 2092 2093 } else { 2094 LOG_ERROR(BSL_LS_BCM_FLOW, 2095 (BSL_META_U(unit, 2096 "Invalid combination of flow, \ 2097 flow_option and function_type or \ 2098 or not a supported memory\n"))); 2099 return BCM_E_PARAM; 2100 } 2101 2102 2103 if (direction == bcmStatFlexDirectionIngress) { 2104 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 2105 unit, 2106 mem, 2107 index); 2108 /* remember the first error code, but allow loop finish */ 2109 if (BCM_E_NONE != rv && 2110 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 2111 err_code[bcmStatFlexDirectionIngress] = rv; 2112 } 2113 2114 } else { 2115 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 2116 unit, 2117 object, 2118 mem, 2119 index); 2120 if (BCM_E_NONE != rv && 2121 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 2122 err_code[bcmStatFlexDirectionEgress] = rv; 2123 } 2124 2125 } 2126 2127 /* In case of success on one direction, and return NOT_FOUND on the other, 2128 * we still take it as a success */ 2129 BCM_STAT_FLEX_DETACH_RETURN(err_code) 2130 return rv; 2131 2132 } 2133 2134 int bcmi_esw_flow_stat_id_get(int unit, 2135 bcm_flow_stat_info_t *info, 2136 uint32 num_of_fields, 2137 bcm_flow_logical_field_t *field, 2138 bcm_stat_object_t stat_object, 2139 uint32 *stat_counter_id) 2140 { 2141 int rv = BCM_E_NONE; 2142 uint32 mem_view_id = 0; 2143 soc_mem_t mem = 0; 2144 soc_flow_db_mem_view_info_t vinfo; 2145 bcm_stat_flex_direction_t direction = bcmStatFlexDirectionIngress; 2146 int index = -1; 2147 bcm_stat_flex_table_info_t table_info; 2148 uint32 num_stat_counter_ids = 0; 2149 2150 BCM_IF_ERROR_RETURN( 2151 _bcm_esw_flow_stat_info_validate(unit, 2152 info)); 2153 /* Validate object and direction */ 2154 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit, stat_object, &direction)); 2155 if (soc_flow_db_mem_view_flow_handle_valid(unit, info->flow_handle)) { 2156 return BCM_E_PARAM; 2157 } 2158 2159 rv = soc_flow_db_ffo_to_mem_view_id_get(unit, 2160 info->flow_handle, 2161 info->flow_option, 2162 info->function_type, 2163 &mem_view_id); 2164 2165 if (BCM_SUCCESS(rv)) { 2166 /* Flex view of flows*/ 2167 BCM_IF_ERROR_RETURN( 2168 soc_flow_db_mem_view_info_get(unit, mem_view_id, &vinfo)); 2169 2170 mem = vinfo.mem_view_id; 2171 /* Resolve the index from the key fields */ 2172 BCM_IF_ERROR_RETURN( 2173 _bcm_esw_flow_stat_flex_view_index_get(unit, info, 2174 field, num_of_fields, 2175 vinfo, direction, &index)); 2176 2177 } else if (BCM_FLOW_IS_FIXED_TABLE(info)) { /* == 0 */ 2178 /* Fixed table of Flows - SOURCE_VP,VFI */ 2179 BCM_IF_ERROR_RETURN( 2180 _bcm_esw_flow_stat_fixed_table_index_get(unit, 2181 info, 2182 direction, 2183 &mem, 2184 &index)); 2185 2186 } else if (BCM_FLOW_IS_FIXED_VIEW(info)) { 2187 /* Fixed Views of Flows */ 2188 BCM_IF_ERROR_RETURN( 2189 _bcm_esw_flow_stat_fixed_view_index_get(unit, 2190 info, num_of_fields, field, 2191 direction, 2192 &mem, 2193 &index)); 2194 2195 2196 } else { 2197 LOG_ERROR(BSL_LS_BCM_FLOW, 2198 (BSL_META_U(unit, 2199 "Invalid combination of flow, \ 2200 flow_option and function_type or \ 2201 or not a supported memory\n"))); 2202 return BCM_E_PARAM; 2203 } 2204 2205 table_info.table = mem; 2206 table_info.index = index; 2207 table_info.direction = direction; 2208 2209 return _bcm_esw_stat_flex_get_counter_id(unit, 1, &table_info, 2210 &num_stat_counter_ids, stat_counter_id); 2211 2212 } 2213 2214 #endif /* INCLUDE_L3 */ 2215