openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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