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

common.c (518212B)


      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:    common.c
      8  * Purpose: Manages resources shared across multiple modules
      9  */
     10 #include <shared/bsl.h>
     11 
     12 #include <soc/mem.h>
     13 #include <soc/drv.h>
     14 #include <soc/mcm/allenum.h>
     15 #include <soc/profile_mem.h>
     16 #include <sal/compiler.h>
     17 #include <soc/scache.h>
     18 
     19 #include <bcm/error.h>
     20 #include <bcm/types.h>
     21 #include <bcm_int/esw/firebolt.h>
     22 #include <bcm_int/esw/field.h>
     23 #include <bcm_int/esw/triumph2.h>
     24 #include <bcm_int/esw/mpls.h>
     25 #include <bcm_int/esw/mim.h>
     26 #include <bcm_int/esw/virtual.h>
     27 #include <bcm_int/esw/stack.h>
     28 #include <bcm_int/esw/trx.h>
     29 #include <bcm_int/esw_dispatch.h>
     30 #include <bcm_int/esw/switch.h>
     31 #ifdef BCM_TRX_SUPPORT
     32 #include <bcm_int/esw/triumph.h>
     33 #endif
     34 #ifdef BCM_TRIUMPH3_SUPPORT
     35 #include <bcm_int/esw/triumph3.h>
     36 #endif
     37 #ifdef BCM_KATANA2_SUPPORT
     38 #include <bcm_int/esw/katana2.h>
     39 #endif
     40 #ifdef BCM_TRIDENT2PLUS_SUPPORT
     41 #include <bcm_int/esw/trident2plus.h>
     42 #endif
     43 #ifdef BCM_SABER2_SUPPORT
     44 #include <bcm_int/esw/saber2.h>
     45 #endif
     46 #ifdef BCM_TRIDENT3_SUPPORT
     47 #include <bcm_int/esw/trident3.h>
     48 #endif
     49 #ifdef BCM_TOMAHAWK3_SUPPORT
     50 #include <soc/tomahawk3.h>
     51 #endif
     52 
     53 
     54 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
     55 #define MY_STATION_SHADOW_MASK_MAX_ARRAY_SIZE 1024
     56 typedef struct my_station_shadow_mask_s {
     57     uint32   buf[(MY_STATION_SHADOW_MASK_MAX_ARRAY_SIZE+31)/32];
     58 } my_station_shadow_mask_t;
     59 #endif
     60 
     61 typedef struct _bcm_common_bookkeeping_s {
     62     int initialized;            /* Flag to check initialized status */
     63     int mac_da_profile_created; /* Flag to check MAC_DA profile creation */
     64     int lport_profile_created;  /* Flag to check LPORT profile creation */
     65     int ing_pri_cng_map_created; /* Flag to check ING_PRI_CNG_MAP creation */
     66     int ing_vft_pri_map_created; /* Flag to check ING_VFT_PRI_MAP creation */
     67     int ing_l2_vlan_etag_map_created; /* Flag to check ING_ETAG_PCP_MAPPING creation */    
     68     int egr_vft_pri_map_created; /* Flag to check EGR_VFT_PRI_MAP creation */
     69     int egr_vsan_intpri_map_created; /* Flag to check EGR_VSAN_INTPRI_MAP created */
     70     int egr_l2_vlan_etag_map_created; /* Flag to check EGR_ETAG_PCP_MAPPING creation */
     71     int egr_vft_fields_created; /* Flag to check EGR_VFT_FIELDS_PROFILE created */
     72     int egr_mpls_combo_map_created; /* Flag to check combo map creation */
     73     int dscp_table_created; /* Flag to check DSCP_TABLE creation */
     74     int egr_dscp_table_created; /* Flag to check EGR_DSCP_TABLE creation */
     75     int ing_outer_dot1p_created; /* Flag to check ING_OUTER_DOT1P_MAPPING_TABLE 
     76                                     creation */
     77 #ifdef BCM_TRIUMPH3_SUPPORT
     78     int ing_l3_nh_attribute_created;  /* Flag to check ING_L3_NEXT_HOP_ATTRIBUTE_1
     79                                          creation */
     80 #endif /* BCM_TRIUMPH3_SUPPORT */
     81 #ifdef BCM_TRIDENT2_SUPPORT
     82     int l3_iif_profile_created;  /* Flag to check L3_IIF_PROFILE creation */
     83     int l3_ip4_options_profile_created;  /* Flag to check L3_IP4_OPTIONS_PROFILE creation */
     84     int fc_map_profile_created;          /* Flag to check FC_MAP_PROFILE */
     85 #endif /* BCM_TRIDENT2_SUPPORT */
     86 #ifdef BCM_TRIDENT2PLUS_SUPPORT
     87     int vfi_profile_created;     /* Flags to check vfi profile creation */
     88 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
     89 
     90     int prot_pkt_ctrl_created;
     91 #ifdef BCM_KATANA_SUPPORT
     92     int ing_queue_offset_map_created; /* Flag to check ING_QUEUE_OFFSET_MAP_
     93                                          TABLE creation */
     94 #endif
     95 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
     96     int vlan_protocol_data_profile_created; /* Flag to check if VLAN_PROTOCOL_DATA profile creation */
     97 #endif
     98 #ifdef BCM_HURRICANE3_SUPPORT
     99     int egr_header_encap_data_created; /* Flag to check if EGR_HEADER_ENCAP_DATA 
    100                                                  profile creation */
    101     int custom_header_match_created;  /* Flag to check if CUSTOM_HEADER_MATCH profile creation */
    102 #endif /* BCM_HURRICANE3_SUPPORT */
    103 #ifdef BCM_TOMAHAWK_SUPPORT
    104     int ing_tunnel_term_map_created; /* Flag to check if ING_TUNNEL_TERM_MAP profile creation */
    105 #endif /* BCM_TOMAHAWK_SUPPORT */
    106 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
    107 	defined(BCM_TRIDENT3_SUPPORT)
    108     int ing_exp_to_ip_ecn_map_created; /* Flag to check if ING_EXP_TO_IP_ECN_MAP profile creation */
    109     int egr_ip_ecn_to_exp_map_created; /* Flag to check if EGR_IP_ECN_TO_EXP_MAP profile creation */
    110     int egr_int_cn_to_exp_map_created; /* Flag to check if EGR_INT_CN_TO_EXP_MAP profile creation */
    111 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */
    112 
    113     soc_profile_mem_t *mac_da_profile; /* cache of EGR_MAC_DA_PROFILE */
    114     soc_profile_mem_t *lport_profile;  /* cache of LPORT_TABLE (profile) */
    115     soc_profile_mem_t *ing_pri_cng_map;  /* cache of ING_PRI_CNG_MAP (profile) */
    116     soc_profile_mem_t *egr_mpls_combo_map;  /* cache of combined tables */
    117     soc_profile_mem_t *dscp_table;  /* cache of DSCP_TABLE (profile) */
    118     soc_profile_mem_t *egr_dscp_table;  /* cache of EGR_DSCP_TABLE (profile) */
    119     soc_profile_mem_t *ing_outer_dot1p;  /* cache of ING_OUTER_DOT1P_MAPPING_TABLE 
    120                                             (profile) */
    121 #ifdef BCM_TRIUMPH3_SUPPORT
    122     soc_profile_mem_t *ing_l3_nh_attribute;  /* cache of ING_L3_NEXT_HOP_ATTRIBUTE_1
    123                                                 (profile) */ 
    124 #endif /* BCM_TRIUMPH3_SUPPORT */
    125 #ifdef BCM_TRIDENT2_SUPPORT
    126     soc_profile_mem_t *l3_iif_profile;  /* Cache of L3 IIF profile */
    127     soc_profile_mem_t *l3_ip4_options_profile;  /* Cache of L3 IP4 options profile */
    128     soc_profile_mem_t *fc_map_profile;
    129 #endif /* BCM_TRIDENT2_SUPPORT */
    130 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    131     soc_profile_mem_t *vfi_profile;  /* Cache of VFI profile */
    132 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
    133 #ifdef BCM_KATANA_SUPPORT
    134     soc_profile_mem_t *offset_map_table; /* cache of ING_QUEUE_OFFSET_MAP_TABLE
    135                                             (profile) */
    136 #endif /* BCM_KATANA_SUPPORT */
    137 /*TD2+ support is added here for xgs5/port.c usage*/
    138 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
    139     /* cache of VLAN_PROTOCOL_DATA profile */
    140     soc_profile_mem_t *vlan_protocol_data_profile;
    141 #endif
    142 
    143     soc_profile_mem_t *ing_vft_pri_map;
    144     soc_profile_mem_t *ing_l2_vlan_etag_map;
    145     soc_profile_mem_t *egr_vft_pri_map;
    146     soc_profile_mem_t *egr_vsan_intpri_map;
    147     soc_profile_mem_t *egr_l2_vlan_etag_map;
    148     soc_profile_mem_t *egr_vft_fields;
    149     soc_profile_reg_t *prot_pkt_ctrl;
    150     uint16      *mpls_station_hash; /* Hash values for MPLS STATION entries */
    151     my_station_tcam_entry_t *my_station_shadow;
    152 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
    153     my_station_shadow_mask_t *my_station_shadow_mask;
    154 #endif
    155     void *my_station_l3_mask;
    156     void *my_station_tunnel_mask;
    157     my_station_tcam_2_entry_t *my_station2_shadow;
    158 #if defined(BCM_TRIDENT3_SUPPORT)
    159         my_station_shadow_mask_t *my_station2_shadow_mask;
    160 #endif
    161     my_station_tcam_2_entry_t my_station2_l3_mask;
    162     my_station_tcam_2_entry_t my_station2_tunnel_mask;
    163 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    164     soc_profile_mem_t *ing_vlan_vfi_mbrship_profile;
    165     soc_profile_mem_t *egr_vlan_vfi_mbrship_profile;
    166     soc_profile_mem_t *misc_port_profile;  /* Misc port profile for IFP related per port attrs */
    167 #endif
    168 #ifdef BCM_TRIDENT3_SUPPORT
    169     soc_profile_mem_t *egr_vlan_vfi_untag_profile;
    170 #endif
    171     soc_profile_mem_t *lport_ind_profile;  /* Independent profile for ING LPORT */
    172     soc_profile_mem_t *rtag7_ind_profile;  /* Independent profile for RTAG7 */
    173     soc_profile_mem_t *egr_lport_profile; /* Egr LPORT profiling */
    174     soc_profile_mem_t *egr_qos_profile; /* Egr QOS profiling */
    175 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    176     int ing_vlan_vfi_mbrship_profile_created;
    177     int egr_vlan_vfi_mbrship_profile_created;    
    178 #endif
    179 #ifdef BCM_TRIDENT3_SUPPORT
    180     int egr_vlan_vfi_untag_profile_created;
    181 #endif
    182     int misc_port_profile_created;  /* Flag to check MISC PORT profile creation */
    183     int lport_ind_profile_created;  /* Flag to check LPORT_ 1 profile creation */
    184     int rtag7_ind_profile_created;  /* Flag to check RTAG7_ 1 profile creation */
    185     int egr_lport_profile_created;  /* Flag to check Egr LPORT profile creation */
    186     int egr_qos_profile_created;  /* Flag to check Egr QOS profile creation */
    187 #ifdef BCM_SABER2_SUPPORT
    188     int service_pri_map_created; /* Flag to check ING/EGR_SERVICE_PRI_MAP_0/1/2 
    189                                          TABLEs creation */
    190 #endif
    191 #ifdef BCM_SABER2_SUPPORT
    192     soc_profile_mem_t *service_pri_map_table; /* cache of ING/EGR_SERVICE_PRI_MAP_0/1/2 
    193                                             (profile) */
    194 #endif /* BCM_SABER2_SUPPORT */
    195 #ifdef BCM_HURRICANE3_SUPPORT
    196     soc_profile_mem_t *egr_header_encap_data;  /* cache of EGR_HEADER_ENCAP_DATA */
    197     soc_profile_mem_t *custom_header_match;     /* cache of CUSTOM_HEADER_MATCH */
    198 #endif /* BCM_HURRICANE3_SUPPORT */
    199 #ifdef BCM_TOMAHAWK_SUPPORT
    200     soc_profile_mem_t *ing_tunnel_term_map; /* cache of ING_TUNNEL_TERM_MAP profile */
    201 #endif /* BCM_TOMAHAWK_SUPPORT */
    202 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
    203     defined(BCM_TRIDENT3_SUPPORT)
    204     soc_profile_mem_t *ing_exp_to_ip_ecn_map; /* cache of ING_EXP_TO_IP_ECN_MAP profile */
    205     soc_profile_mem_t *egr_ip_ecn_to_exp_map; /* cache of EGR_IP_ECN_TO_EXP_MAP profile */
    206     soc_profile_mem_t *egr_int_cn_to_exp_map; /*cache of EGR_INT_CN_TO_EXP_MAP profile */
    207 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */
    208 #ifdef BCM_FLOWTRACKER_SUPPORT
    209     soc_profile_mem_t *age_out_profile;
    210     soc_profile_mem_t *flow_limit_profile;
    211     soc_profile_mem_t *collector_copy_profile;
    212     soc_profile_mem_t *pdd_profile;
    213     soc_profile_mem_t *meter_profile;
    214     soc_profile_mem_t *ts_profile;
    215 #endif /*BCM_FLOWTRACKER_SUPPORT*/
    216 } _bcm_common_bookkeeping_t;
    217 
    218 STATIC _bcm_common_bookkeeping_t  _bcm_common_bk_info[BCM_MAX_NUM_UNITS] = {{ 0 }};
    219 STATIC sal_mutex_t _common_mutex[BCM_MAX_NUM_UNITS] = {NULL};
    220  
    221 #define COMMON_INFO(_unit_)   (&_bcm_common_bk_info[_unit_])
    222 #define MAC_DA_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].mac_da_profile)
    223 #define LPORT_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].lport_profile)
    224 #define ING_PRI_CNG_MAP(_unit_) (_bcm_common_bk_info[_unit_].ing_pri_cng_map)
    225 #define EGR_MPLS_COMBO_MAP(_unit_) (_bcm_common_bk_info[_unit_].egr_mpls_combo_map)
    226 #define DSCP_TABLE(_unit_) (_bcm_common_bk_info[_unit_].dscp_table)
    227 #define EGR_DSCP_TABLE(_unit_) (_bcm_common_bk_info[_unit_].egr_dscp_table)
    228 #define ING_OUTER_DOT1P(_unit_) (_bcm_common_bk_info[_unit_].ing_outer_dot1p)
    229 #define PROT_PKT_CTRL(_unit_) (_bcm_common_bk_info[_unit_].prot_pkt_ctrl)
    230 #define ING_VFT_PRI_MAP(_unit_) (_bcm_common_bk_info[_unit_].ing_vft_pri_map)
    231 #define ING_L2_VLAN_ETAG_MAP(_unit_) (_bcm_common_bk_info[_unit_].ing_l2_vlan_etag_map)
    232 #define EGR_VFT_PRI_MAP(_unit_) (_bcm_common_bk_info[_unit_].egr_vft_pri_map)
    233 #define EGR_VSAN_INTPRI_MAP(_unit_) (_bcm_common_bk_info[_unit_].egr_vsan_intpri_map)
    234 #define EGR_VFT_FIELDS(_unit_) (_bcm_common_bk_info[_unit_].egr_vft_fields)
    235 #define EGR_L2_VLAN_ETAG_MAP(_unit_) (_bcm_common_bk_info[_unit_].egr_l2_vlan_etag_map)
    236 #define MPLS_STATION_HASH(_unit_, _index_) \
    237         (_bcm_common_bk_info[_unit_].mpls_station_hash[_index_])
    238 
    239 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    240 #define ING_VLAN_VFI_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].ing_vlan_vfi_mbrship_profile)
    241 #define EGR_VLAN_VFI_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].egr_vlan_vfi_mbrship_profile)
    242 #define MISC_PORT_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].misc_port_profile)
    243 #endif
    244 #ifdef BCM_TRIDENT3_SUPPORT
    245 #define EGR_VLAN_VFI_UNTAG_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].egr_vlan_vfi_untag_profile)
    246 #endif
    247 #define LPORT_IND_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].lport_ind_profile)
    248 #define RTAG7_IND_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].rtag7_ind_profile)
    249 #define EGR_LPORT_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].egr_lport_profile)
    250 #define EGR_QOS_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].egr_qos_profile)
    251 
    252 #ifdef BCM_TRIUMPH3_SUPPORT
    253 #define ING_L3_NH_ATTRIB_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].ing_l3_nh_attribute)
    254 #endif /* BCM_TRIUMPH3_SUPPORT */
    255 
    256 #ifdef BCM_TRIDENT2_SUPPORT
    257 #define L3_IIF_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].l3_iif_profile)
    258 #define L3_IP4_OPTIONS_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].l3_ip4_options_profile)
    259 #define FC_MAP_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].fc_map_profile)
    260 #endif /* BCM_TRIUMPH3_SUPPORT */
    261 
    262 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    263 #define VFI_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].vfi_profile)
    264 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
    265 
    266 #ifdef BCM_KATANA_SUPPORT
    267 #define OFFSET_MAP_TABLE(_unit_) (_bcm_common_bk_info[_unit_].offset_map_table)
    268 #endif /* BCM_KATANA_SUPPORT */
    269 
    270 #ifdef BCM_SABER2_SUPPORT
    271 #define SERVICE_PRI_MAP_TABLE(_unit_) (_bcm_common_bk_info[_unit_].service_pri_map_table)
    272 #endif /* BCM_SABER2_SUPPORT */
    273 
    274 
    275 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
    276 #define VLAN_PROTOCOL_DATA_TABLE(_unit_) \
    277         (_bcm_common_bk_info[_unit_].vlan_protocol_data_profile)
    278 #endif /* BCM_KATANA2_SUPPORT */
    279 
    280 #ifdef BCM_HURRICANE3_SUPPORT
    281 #define EGR_HEADER_ENCAP_DATA(_unit_) \
    282         (_bcm_common_bk_info[_unit_].egr_header_encap_data)
    283 #define CUSTOM_HEADER_MATCH(_unit_) \
    284         (_bcm_common_bk_info[_unit_].custom_header_match)
    285 #endif /* BCM_HURRICANE3_SUPPORT */
    286 #ifdef BCM_TOMAHAWK_SUPPORT
    287 #define ING_TUNNEL_TERM_MAP(_unit_) \
    288             (_bcm_common_bk_info[_unit_].ing_tunnel_term_map)
    289 #endif /* BCM_TOMAHAWK_SUPPORT */
    290 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
    291     defined(BCM_TRIDENT3_SUPPORT)
    292 #define ING_EXP_TO_IP_ECN_MAP(_unit_) \
    293                 (_bcm_common_bk_info[_unit_].ing_exp_to_ip_ecn_map)
    294 #define EGR_IP_ECN_TO_EXP_MAP(_unit_) \
    295                     (_bcm_common_bk_info[_unit_].egr_ip_ecn_to_exp_map)
    296 #define EGR_INT_CN_TO_EXP_MAP(_unit_) \
    297                     (_bcm_common_bk_info[_unit_].egr_int_cn_to_exp_map)
    298 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */
    299 
    300 #ifdef BCM_FLOWTRACKER_SUPPORT
    301 #define FT_AGE_OUT(_u) \
    302             (_bcm_common_bk_info[_u].age_out_profile)
    303 
    304 #define FT_FLOW_LIMIT(_u) \
    305             (_bcm_common_bk_info[_u].flow_limit_profile)
    306 
    307 #define FT_COLLECTOR_COPY(_u) \
    308             (_bcm_common_bk_info[_u].collector_copy_profile)
    309 
    310 #define FT_PDD_PROFILE(_u) \
    311             (_bcm_common_bk_info[_u].pdd_profile)
    312 
    313 #define FT_METER_PROFILE(_u) \
    314             (_bcm_common_bk_info[_u].meter_profile)
    315 
    316 #define FT_TS_PROFILE(_u) \
    317             (_bcm_common_bk_info[_u].ts_profile)
    318 
    319 
    320 #endif /* BCM_FLOWTRACKER_SUPPORT */
    321 
    322 /* 
    323  * Common resource lock
    324  */
    325 #define COMMON_LOCK(unit) \
    326         sal_mutex_take(_common_mutex[unit], sal_mutex_FOREVER); 
    327 
    328 #define COMMON_UNLOCK(unit) \
    329         sal_mutex_give(_common_mutex[unit]); 
    330 
    331 #if defined(BCM_TRIDENT3_SUPPORT)
    332 #define VFP_LO_FOR_TUNNEL_TERM_FLOW_STRENGTH 0x28
    333 #define VFP_LO_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH 0x28
    334 #define VFP_HI_FOR_TUNNEL_TERM_FLOW_STRENGTH 0x3c
    335 #define VFP_HI_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH 0x3c
    336 #define SGPP_FOR_TUNNEL_TERM_FLOW_STRENGTH 0x32
    337 #define SGPP_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH 0x32
    338 #define VFI_FOR_TUNNEL_TERM_FLOW_STRENGTH 0x1e
    339 #define VFI_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH 0x1e
    340 #define L3_IIF_FOR_TUNNEL_TERM_FLOW_STRENGTH 0xa
    341 #define L3_IIF_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH 0xa
    342 #endif
    343 
    344 /* Forward declaration */
    345 STATIC int
    346 _bcm_trx_mpls_station_hash_calc(int unit, bcm_mac_t mac,
    347                                 bcm_vlan_t vlan, uint16 *hash);
    348 #ifdef BCM_TRIUMPH2_SUPPORT
    349 STATIC int
    350 _bcm_esw_flex_stat_hw_set(int unit, _bcm_flex_stat_type_t type,
    351                           int fs_idx, _bcm_flex_stat_t stat, uint64 val);
    352 STATIC int
    353 _bcm_esw_flex_stat_sw_clear(int unit, _bcm_flex_stat_type_t type,
    354                             int fs_idx);
    355 #endif
    356 
    357 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
    358 static soc_memacc_t *_bcm_trx_mysta_memacc_list[BCM_MAX_NUM_UNITS];
    359 static soc_memacc_t *_bcm_trx_mysta2_memacc_list[BCM_MAX_NUM_UNITS];
    360 STATIC int _bcm_trx_mysta_memacc_init(int unit);
    361 #endif 
    362 
    363 
    364 /*
    365  * Function:
    366  *      _bcm_common_free_resource
    367  * Purpose:
    368  *      Free all allocated tables and memory
    369  *      Shared by MPLS and MIM
    370  * Parameters:
    371  *      unit - SOC unit number
    372  * Returns:
    373  *      Nothing
    374  */
    375 STATIC void
    376 _bcm_common_free_resource(int unit, _bcm_common_bookkeeping_t *info)
    377 {
    378     if (!info) {
    379         return;
    380     }
    381     if (_common_mutex[unit]) {
    382         sal_mutex_destroy(_common_mutex[unit]);
    383         _common_mutex[unit] = NULL;
    384     } 
    385     if (info->mpls_station_hash) {
    386         sal_free(info->mpls_station_hash);
    387         info->mpls_station_hash = NULL;
    388     }
    389     if (info->my_station_shadow) {
    390         sal_free(info->my_station_shadow);
    391         info->my_station_shadow = NULL;
    392     }
    393 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
    394     if (info->my_station_shadow_mask) {
    395         sal_free(info->my_station_shadow_mask);
    396         info->my_station_shadow_mask = NULL;
    397     }
    398 #endif
    399 #if defined(BCM_TRIDENT3_SUPPORT)
    400     if (info->my_station2_shadow_mask) {
    401         sal_free(info->my_station2_shadow_mask);
    402         info->my_station2_shadow_mask = NULL;
    403     }
    404 #endif
    405 
    406     if (info->my_station_l3_mask) {
    407         sal_free(info->my_station_l3_mask);
    408         info->my_station_l3_mask = NULL;
    409     }
    410     if (info->my_station_tunnel_mask) {
    411         sal_free(info->my_station_tunnel_mask);
    412         info->my_station_tunnel_mask = NULL;
    413     }
    414 
    415 #ifdef BCM_RIOT_SUPPORT
    416     if (info->my_station2_shadow) {
    417         sal_free(info->my_station2_shadow);
    418         info->my_station2_shadow = NULL;
    419     }
    420 #endif /* BCM_RIOT_SUPPORT */
    421 #ifdef BCM_TRIDENT_SUPPORT
    422     if (_bcm_trx_mysta_memacc_list[unit]) {
    423         sal_free(_bcm_trx_mysta_memacc_list[unit]);
    424         _bcm_trx_mysta_memacc_list[unit] = NULL;
    425     }
    426 #endif
    427 #ifdef BCM_RIOT_SUPPORT
    428     if (_bcm_trx_mysta2_memacc_list[unit]) {
    429         sal_free(_bcm_trx_mysta2_memacc_list[unit]);
    430         _bcm_trx_mysta2_memacc_list[unit] = NULL;
    431     }
    432 #endif /* BCM_RIOT_SUPPORT */
    433 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
    434     if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
    435         if (info->vlan_protocol_data_profile) {
    436             if(info->vlan_protocol_data_profile_created) {
    437                 (void) soc_profile_mem_destroy(unit, info->vlan_protocol_data_profile);
    438             }
    439             sal_free(info->vlan_protocol_data_profile);
    440             info->vlan_protocol_data_profile = NULL;
    441         }
    442     }
    443 #endif
    444     if (info->mac_da_profile) {
    445         if (info->mac_da_profile_created) {
    446             (void) soc_profile_mem_destroy(unit, info->mac_da_profile);
    447         }
    448         sal_free(info->mac_da_profile);
    449         info->mac_da_profile = NULL;
    450     }
    451     if (info->lport_profile) {
    452         if (info->lport_profile_created) {
    453             (void) soc_profile_mem_destroy(unit, info->lport_profile);
    454         }
    455         sal_free(info->lport_profile);
    456         info->lport_profile = NULL;
    457     }
    458 
    459     if (info->lport_ind_profile) {
    460         if (info->lport_ind_profile_created) {
    461             (void) soc_profile_mem_destroy(unit, info->lport_ind_profile);
    462         }
    463         sal_free(info->lport_ind_profile);
    464         info->lport_ind_profile = NULL;
    465     }
    466 
    467     if (info->rtag7_ind_profile) {
    468         if (info->rtag7_ind_profile_created) {
    469             (void) soc_profile_mem_destroy(unit, info->rtag7_ind_profile);
    470         }
    471         sal_free(info->rtag7_ind_profile);
    472         info->rtag7_ind_profile = NULL;
    473     }
    474 
    475     if (info->egr_lport_profile) {
    476         if (info->egr_lport_profile_created) {
    477             (void) soc_profile_mem_destroy(unit, info->egr_lport_profile);
    478         }
    479         sal_free(info->egr_lport_profile);
    480         info->egr_lport_profile = NULL;
    481     }
    482 
    483     if (info->egr_qos_profile) {
    484         if (info->egr_qos_profile_created) {
    485             (void) soc_profile_mem_destroy(unit, info->egr_qos_profile);
    486         }
    487         sal_free(info->egr_qos_profile);
    488         info->egr_qos_profile = NULL;
    489     }
    490 
    491     if (info->ing_pri_cng_map) {
    492         if (info->ing_pri_cng_map_created) {
    493             (void) soc_profile_mem_destroy(unit, info->ing_pri_cng_map);
    494         }
    495         sal_free(info->ing_pri_cng_map);
    496         info->ing_pri_cng_map = NULL;
    497     }
    498     if (info->ing_vft_pri_map) {
    499         if (info->ing_vft_pri_map_created) {
    500             (void) soc_profile_mem_destroy(unit, info->ing_vft_pri_map);
    501         }
    502         sal_free(info->ing_vft_pri_map);
    503         info->ing_vft_pri_map = NULL;
    504     }
    505     if (info->ing_l2_vlan_etag_map) {
    506         if (info->ing_l2_vlan_etag_map_created) {
    507             (void) soc_profile_mem_destroy(unit, info->ing_l2_vlan_etag_map);
    508         }
    509         sal_free(info->ing_l2_vlan_etag_map);
    510         info->ing_l2_vlan_etag_map = NULL;
    511     }    
    512     if (info->egr_vft_pri_map) {
    513         if (info->egr_vft_pri_map_created) {
    514             (void) soc_profile_mem_destroy(unit, info->egr_vft_pri_map);
    515         }
    516         sal_free(info->egr_vft_pri_map);
    517         info->egr_vft_pri_map = NULL;
    518     }
    519     if (info->egr_vsan_intpri_map) {
    520         if (info->egr_vsan_intpri_map_created) {
    521             (void) soc_profile_mem_destroy(unit, info->egr_vsan_intpri_map);
    522         }
    523         sal_free(info->egr_vsan_intpri_map);
    524         info->egr_vsan_intpri_map = NULL;
    525     }
    526     if (info->egr_l2_vlan_etag_map) {
    527         if (info->egr_l2_vlan_etag_map_created) {
    528             (void) soc_profile_mem_destroy(unit, info->egr_l2_vlan_etag_map);
    529         }
    530         sal_free(info->egr_l2_vlan_etag_map);
    531         info->egr_l2_vlan_etag_map = NULL;
    532     }
    533     if (info->egr_vft_fields) {
    534         if (info->egr_vft_fields_created) {
    535             (void) soc_profile_mem_destroy(unit, info->egr_vft_fields);
    536         }
    537         sal_free(info->egr_vft_fields);
    538         info->egr_vft_fields = NULL;
    539     }
    540     if (info->egr_mpls_combo_map) {
    541         if (info->egr_mpls_combo_map_created) {
    542             (void) soc_profile_mem_destroy(unit, info->egr_mpls_combo_map);
    543         }
    544         sal_free(info->egr_mpls_combo_map);
    545         info->egr_mpls_combo_map = NULL;
    546     }
    547     if (info->dscp_table) {
    548         if (info->dscp_table_created) {
    549             (void) soc_profile_mem_destroy(unit, info->dscp_table);
    550         }
    551         sal_free(info->dscp_table);
    552         info->dscp_table = NULL;
    553     }
    554     if (info->egr_dscp_table) {
    555         if (info->egr_dscp_table_created) {
    556             (void) soc_profile_mem_destroy(unit, info->egr_dscp_table);
    557         }
    558         sal_free(info->egr_dscp_table);
    559         info->egr_dscp_table = NULL;
    560     }
    561     if (info->ing_outer_dot1p) {
    562         if (info->ing_outer_dot1p_created) {
    563             (void) soc_profile_mem_destroy(unit, info->ing_outer_dot1p);
    564         }
    565         sal_free(info->ing_outer_dot1p);
    566         info->ing_outer_dot1p = NULL;
    567     }
    568     if (info->prot_pkt_ctrl) {
    569         if (info->prot_pkt_ctrl_created) {
    570             (void) soc_profile_reg_destroy(unit, info->prot_pkt_ctrl);
    571         }
    572         sal_free(info->prot_pkt_ctrl);
    573         info->prot_pkt_ctrl = NULL;
    574     }
    575 
    576 #ifdef BCM_TRIUMPH3_SUPPORT
    577     if (SOC_IS_TRIUMPH3(unit)) {
    578         if (info->ing_l3_nh_attribute) {
    579             if (info->ing_l3_nh_attribute_created) {
    580                 (void) soc_profile_mem_destroy(unit,
    581                         info->ing_l3_nh_attribute);
    582             }
    583             sal_free(info->ing_l3_nh_attribute);
    584             info->ing_l3_nh_attribute = NULL;
    585         }
    586     }
    587 #endif /* BCM_TRIUMPH3_SUPPORT */
    588 #ifdef BCM_TRIDENT2_SUPPORT
    589     if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
    590         if (info->l3_iif_profile) {
    591             if (info->l3_iif_profile_created) {
    592                 (void) soc_profile_mem_destroy(unit,
    593                         info->l3_iif_profile);
    594             }
    595             sal_free(info->l3_iif_profile);
    596             info->l3_iif_profile = NULL;
    597         }
    598         if (info->l3_ip4_options_profile) {
    599             if (info->l3_ip4_options_profile_created) {
    600                 (void) soc_profile_mem_destroy(unit,
    601                         info->l3_ip4_options_profile);
    602             }
    603             sal_free(info->l3_ip4_options_profile);
    604             info->l3_ip4_options_profile = NULL;
    605         }
    606         if (info->fc_map_profile) {
    607             if (info->fc_map_profile_created) {
    608                 (void) soc_profile_mem_destroy(unit,
    609                         info->fc_map_profile);
    610             }
    611             sal_free(info->fc_map_profile);
    612             info->fc_map_profile = NULL;
    613         }
    614     }
    615 #endif /* BCM_TRIDENT2_SUPPORT */
    616 #ifdef BCM_KATANA_SUPPORT
    617     if (info->offset_map_table) {
    618         if (info->ing_queue_offset_map_created) {
    619             (void) soc_profile_mem_destroy(unit, info->offset_map_table);
    620         }
    621         sal_free(info->offset_map_table);
    622         info->offset_map_table = NULL;
    623     }
    624 #endif /* BCM_KATANA_SUPPORT */
    625 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    626     if (info->vfi_profile) {
    627         if (info->vfi_profile_created) {
    628             (void)soc_profile_mem_destroy(unit, info->vfi_profile);
    629         }
    630         sal_free(info->vfi_profile);
    631         info->vfi_profile = NULL;
    632     }
    633 
    634     if (info->ing_vlan_vfi_mbrship_profile) {
    635         if (info->ing_vlan_vfi_mbrship_profile_created) {
    636             (void) soc_profile_mem_destroy(unit,
    637                     info->ing_vlan_vfi_mbrship_profile);
    638         }
    639         sal_free(info->ing_vlan_vfi_mbrship_profile);
    640         info->ing_vlan_vfi_mbrship_profile = NULL;
    641     }
    642 
    643     if (info->egr_vlan_vfi_mbrship_profile) {
    644         if (info->egr_vlan_vfi_mbrship_profile_created) {
    645             (void) soc_profile_mem_destroy(unit,
    646                     info->egr_vlan_vfi_mbrship_profile);
    647         }
    648         sal_free(info->egr_vlan_vfi_mbrship_profile);
    649         info->egr_vlan_vfi_mbrship_profile = NULL;
    650     }
    651 
    652     if (info->misc_port_profile) {
    653         if (info->misc_port_profile_created) {
    654             (void) soc_profile_mem_destroy(unit, info->misc_port_profile);
    655         }
    656         sal_free(info->misc_port_profile);
    657         info->misc_port_profile = NULL;
    658     }
    659 #endif
    660 
    661 #ifdef BCM_TRIDENT3_SUPPORT
    662     if (info->egr_vlan_vfi_untag_profile) {
    663         if (info->egr_vlan_vfi_untag_profile_created) {
    664             (void) soc_profile_mem_destroy(unit,
    665                     info->egr_vlan_vfi_untag_profile);
    666         }
    667         sal_free(info->egr_vlan_vfi_untag_profile);
    668         info->egr_vlan_vfi_untag_profile = NULL;
    669     }
    670 #endif
    671 
    672 #ifdef BCM_SABER2_SUPPORT
    673     if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
    674         if (info->service_pri_map_table) {
    675             if (info->service_pri_map_created) {
    676                 (void) soc_profile_mem_destroy(unit,
    677                                      info->service_pri_map_table);
    678             }
    679             sal_free(info->service_pri_map_table);
    680             info->service_pri_map_table = NULL;
    681         }
    682     }
    683 #endif /* BCM_KATANA_SUPPORT */
    684 #ifdef BCM_HURRICANE3_SUPPORT
    685     if (soc_feature(unit, soc_feature_miml) || 
    686         soc_feature(unit, soc_feature_custom_header)) {
    687         if (info->egr_header_encap_data) {
    688             if (info->egr_header_encap_data_created) {
    689                 (void) soc_profile_mem_destroy(unit, info->egr_header_encap_data);
    690             }
    691             sal_free(info->egr_header_encap_data);
    692             info->egr_header_encap_data = NULL;
    693         }
    694 
    695         if (info->custom_header_match) {
    696             if (info->custom_header_match) {
    697                 (void) soc_profile_mem_destroy(unit, info->custom_header_match);
    698             }
    699             sal_free(info->custom_header_match);
    700             info->custom_header_match = NULL;
    701         }
    702     }
    703 #endif /* BCM_HURRICANE3_SUPPORT */
    704 #ifdef BCM_TOMAHAWK_SUPPORT
    705         if (soc_feature(unit, soc_feature_ecn_wred)) {
    706             if (info->ing_tunnel_term_map) {
    707                 if (info->ing_tunnel_term_map_created) {
    708                     (void) soc_profile_mem_destroy(unit, info->ing_tunnel_term_map);
    709                 }
    710                 sal_free(info->ing_tunnel_term_map);
    711                 info->ing_tunnel_term_map = NULL;
    712             }
    713         }
    714 #endif
    715 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
    716     defined(BCM_TRIDENT3_SUPPORT)
    717         if (soc_feature(unit, soc_feature_mpls_ecn)) {
    718             if (info->ing_exp_to_ip_ecn_map) {
    719                 if (info->ing_exp_to_ip_ecn_map_created) {
    720                     (void) soc_profile_mem_destroy(unit, info->ing_exp_to_ip_ecn_map);
    721                 }
    722                 sal_free(info->ing_exp_to_ip_ecn_map);
    723                 info->ing_exp_to_ip_ecn_map = NULL;
    724             }
    725             if (info->egr_ip_ecn_to_exp_map) {
    726                 if (info->egr_ip_ecn_to_exp_map_created) {
    727                     (void) soc_profile_mem_destroy(unit, info->egr_ip_ecn_to_exp_map);
    728                 }
    729                 sal_free(info->egr_ip_ecn_to_exp_map);
    730                 info->egr_ip_ecn_to_exp_map = NULL;
    731             }
    732             if (info->egr_int_cn_to_exp_map) {
    733                 if (info->egr_int_cn_to_exp_map_created) {
    734                     (void) soc_profile_mem_destroy(unit, info->egr_int_cn_to_exp_map);
    735                 }
    736                 sal_free(info->egr_int_cn_to_exp_map);
    737                 info->egr_int_cn_to_exp_map = NULL;
    738             }            
    739         }
    740 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */
    741 #ifdef BCM_TRIUMPH2_SUPPORT
    742     if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
    743         if (soc_feature(unit, soc_feature_gport_service_counters)) {
    744             /* Initialize flex stats */
    745             (void) _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeGport);
    746             (void) _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeService);
    747             (void) _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeEgressGport);
    748             (void) _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeEgressService);
    749         }
    750     }
    751 #endif /* BCM_TRIUMPH2_SUPPORT */
    752 
    753 
    754 #ifdef BCM_FLOWTRACKER_SUPPORT
    755 
    756     if(soc_feature(unit, soc_feature_flex_flowtracker_ver_1)) {
    757         if (FT_AGE_OUT(unit)) {
    758             (void) soc_profile_mem_destroy(unit, FT_AGE_OUT(unit));
    759             sal_free(FT_AGE_OUT(unit));
    760             FT_AGE_OUT(unit) = NULL;
    761         }
    762 
    763         if (FT_FLOW_LIMIT(unit)) {
    764             (void) soc_profile_mem_destroy(unit, FT_FLOW_LIMIT(unit));
    765             sal_free(FT_FLOW_LIMIT(unit));
    766             FT_FLOW_LIMIT(unit) = NULL;
    767         }
    768 
    769         if (FT_COLLECTOR_COPY(unit)) {
    770             (void) soc_profile_mem_destroy(unit, FT_COLLECTOR_COPY(unit));
    771             sal_free(FT_COLLECTOR_COPY(unit));
    772             FT_COLLECTOR_COPY(unit) = NULL;
    773         }
    774 
    775         if (FT_PDD_PROFILE(unit)) {
    776             (void) soc_profile_mem_destroy(unit, FT_PDD_PROFILE(unit));
    777             sal_free(FT_PDD_PROFILE(unit));
    778             FT_PDD_PROFILE(unit) = NULL;
    779         }
    780 
    781         if (FT_METER_PROFILE(unit)) {
    782             (void) soc_profile_mem_destroy(unit, FT_METER_PROFILE(unit));
    783             sal_free(FT_METER_PROFILE(unit));
    784            FT_METER_PROFILE(unit) = NULL;
    785         }
    786 
    787         if (FT_TS_PROFILE(unit)) {
    788             (void) soc_profile_mem_destroy(unit, FT_TS_PROFILE(unit));
    789             sal_free(FT_TS_PROFILE(unit));
    790            FT_TS_PROFILE(unit) = NULL;
    791         }
    792 
    793 
    794     }
    795 
    796 #endif /* BCM_FLOWTRACKER_SUPPORT */
    797 
    798     return;
    799 }
    800 
    801 #ifdef BCM_WARM_BOOT_SUPPORT
    802 
    803 #define BCM_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
    804 #define BCM_WB_VERSION_1_1                SOC_SCACHE_VERSION(1,1)
    805 #define BCM_WB_VERSION_1_2                SOC_SCACHE_VERSION(1,2)
    806 #define BCM_WB_DEFAULT_VERSION            BCM_WB_VERSION_1_2
    807 
    808 #if defined(BCM_TRIUMPH2_SUPPORT)
    809 STATIC int
    810 _bcm_common_wb_scache_size_get_tr2_flex_stat(int unit,
    811                                                         int *req_scache_size);
    812 STATIC int
    813 _bcm_common_wb_tr2_flex_stat_sync(int unit, uint8 **scache_ptr);
    814 STATIC int
    815 _bcm_common_wb_tr2_flex_stat_reinit(int unit, uint8 **scache_ptr);
    816 #endif /* BCM_TRIUMPH2_SUPPORT */
    817 
    818 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
    819 STATIC int
    820 _bcm_common_wb_scache_size_get_my_station_shadow_mask(int unit,
    821                                                       int *req_scache_size);
    822 STATIC int
    823 _bcm_common_wb_my_station_shadow_mask_sync(int unit, uint8 **scache_ptr);
    824 STATIC int
    825 _bcm_common_wb_my_station_shadow_mask_reinit(int unit, int is_station2, uint8 **scache_ptr);
    826 #endif
    827 
    828 /* Returns required scache size for common module */
    829 STATIC int
    830 _bcm_common_wb_scache_size_get(int unit, int *req_scache_size)
    831 {
    832 #if defined(BCM_TRIUMPH2_SUPPORT)
    833     if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
    834         BCM_IF_ERROR_RETURN(
    835             _bcm_common_wb_scache_size_get_tr2_flex_stat(unit, req_scache_size));
    836     }
    837 #endif /* BCM_TRIUMPH2_SUPPORT */
    838 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
    839     BCM_IF_ERROR_RETURN(
    840         _bcm_common_wb_scache_size_get_my_station_shadow_mask(unit, req_scache_size));
    841 #if defined(BCM_TRIDENT3_SUPPORT)
    842     if (SOC_IS_TRIDENT3X(unit)) {
    843         int tmp_size=0;
    844 
    845         tmp_size = (*req_scache_size);
    846         (*req_scache_size) = 2*tmp_size;
    847     }
    848 #endif
    849 #endif
    850     return BCM_E_NONE;
    851 }
    852 
    853 /* Allocates required scache size for the common module recovery */
    854 STATIC int
    855 _bcm_common_wb_alloc(int unit)
    856 {
    857     int     rv;
    858     uint8   *scache_ptr;
    859     soc_scache_handle_t scache_handle;
    860     int     req_scache_size = 0;
    861 
    862     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COMMON, 0);
    863 
    864     rv = _bcm_common_wb_scache_size_get(unit, &req_scache_size);
    865     BCM_IF_ERROR_RETURN(rv);
    866 
    867     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE,
    868             req_scache_size, &scache_ptr, BCM_WB_DEFAULT_VERSION, NULL);
    869 
    870     if (BCM_E_NOT_FOUND == rv) {
    871         /* Proceed with Level 1 Warm Boot */
    872         rv = BCM_E_NONE;
    873     }
    874 
    875     BCM_IF_ERROR_RETURN(rv);
    876 
    877     return BCM_E_NONE;
    878 }
    879 
    880 /*
    881  * Function:
    882  *      _bcm_common_wb_sync
    883  * Purpose:
    884  *      Syncs common warmboot state to scache
    885  * Parameters:
    886  *      unit            - (IN)  Unit number.
    887  * Returns:
    888  *      BCM_E_XXX
    889  * Notes:
    890  */
    891 int
    892 _bcm_common_scache_sync(int unit)
    893 {
    894     uint8   *scache_ptr;
    895     soc_scache_handle_t scache_handle;
    896 
    897     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COMMON, 0);
    898 
    899     BCM_IF_ERROR_RETURN
    900         (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
    901                                  0, &scache_ptr,
    902                                  BCM_WB_DEFAULT_VERSION, NULL));
    903 #if defined(BCM_TRIUMPH2_SUPPORT)    
    904     if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
    905         BCM_IF_ERROR_RETURN(_bcm_common_wb_tr2_flex_stat_sync(unit, &scache_ptr));
    906     }
    907 #endif /* BCM_TRIUMPH2_SUPPORT */  
    908 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
    909     BCM_IF_ERROR_RETURN(_bcm_common_wb_my_station_shadow_mask_sync(unit, &scache_ptr));
    910 #endif
    911     return BCM_E_NONE;
    912 }
    913 
    914 /*
    915  * Function:
    916  *      _bcm_common_wb_reinit
    917  * Purpose:
    918  *      Recovers common warmboot state from scache
    919  * Parameters:
    920  *      unit            - (IN)  Unit number.
    921  * Returns:
    922  *      BCM_E_XXX
    923  * Notes:
    924  */
    925 STATIC int
    926 _bcm_common_wb_reinit(int unit)
    927 {
    928     int     rv = BCM_E_INTERNAL;
    929     uint8   *scache_ptr;
    930     uint16  recovered_ver = 0;
    931     soc_scache_handle_t scache_handle;
    932     int additional_scache_size = 0;
    933     int alloc_size = 0;
    934 
    935     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COMMON, 0);
    936 
    937     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
    938                                  0, &scache_ptr,
    939                                  BCM_WB_DEFAULT_VERSION, &recovered_ver);
    940 
    941     if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
    942         return rv;
    943     } else if (rv == BCM_E_NOT_FOUND) {
    944         return _bcm_common_wb_alloc(unit);
    945     } else if (BCM_E_NONE == rv) {
    946         if (recovered_ver >= BCM_WB_VERSION_1_0) {
    947 #if defined(BCM_TRIUMPH2_SUPPORT)
    948             if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
    949                 BCM_IF_ERROR_RETURN(_bcm_common_wb_tr2_flex_stat_reinit(unit, &scache_ptr));
    950             }
    951 #endif /* BCM_TRIUMPH2_SUPPORT */
    952         }
    953 
    954         if (recovered_ver >= BCM_WB_VERSION_1_1) {
    955 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
    956             BCM_IF_ERROR_RETURN(
    957                 _bcm_common_wb_my_station_shadow_mask_reinit(
    958                     unit, FALSE, &scache_ptr));
    959 #endif
    960         } else {
    961 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
    962             BCM_IF_ERROR_RETURN(
    963                 _bcm_common_wb_scache_size_get_my_station_shadow_mask(
    964                     unit, &alloc_size));
    965 #endif
    966             additional_scache_size += alloc_size;
    967         }
    968 
    969         if (recovered_ver >= BCM_WB_VERSION_1_2) {
    970 #if defined(BCM_TRIDENT3_SUPPORT)
    971             if (SOC_IS_TRIDENT3X(unit)) {
    972                 BCM_IF_ERROR_RETURN(
    973                      _bcm_common_wb_my_station_shadow_mask_reinit(
    974                          unit, TRUE, &scache_ptr));
    975             }
    976 #endif
    977         } else {
    978             alloc_size = 0;
    979 #if defined(BCM_TRIDENT3_SUPPORT)
    980             if (SOC_IS_TRIDENT3X(unit)) {
    981                 BCM_IF_ERROR_RETURN(
    982                     _bcm_common_wb_scache_size_get_my_station_shadow_mask(
    983                         unit, &alloc_size));
    984             }
    985 #endif
    986             additional_scache_size += alloc_size;
    987         }
    988 
    989         if (additional_scache_size > 0) {
    990             rv = soc_scache_realloc(unit,scache_handle,additional_scache_size);
    991             if(BCM_FAILURE(rv)) {
    992                return rv;
    993             }
    994         }
    995     }
    996 
    997     return rv;
    998 }
    999 
   1000 STATIC int
   1001 _bcm_common_reinit(int unit)
   1002 {
   1003     int i, num_station;
   1004     bcm_mac_t hw_mac;
   1005     bcm_vlan_t hw_vlan;
   1006     mpls_station_tcam_entry_t mpls_station_entry;
   1007     uint16 hash;
   1008 
   1009     if (SOC_MEM_IS_VALID(unit, MPLS_STATION_TCAMm)) {
   1010         /* Compute hash for each entry */
   1011         num_station = soc_mem_index_count(unit, MPLS_STATION_TCAMm);
   1012         for (i = 0; i < num_station; i++) {
   1013             BCM_IF_ERROR_RETURN
   1014                 (READ_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY, i, &mpls_station_entry));
   1015             soc_mem_mac_addr_get(unit, MPLS_STATION_TCAMm,
   1016                                  &mpls_station_entry, MAC_ADDRf, hw_mac);
   1017             hw_vlan = soc_mem_field32_get(unit, MPLS_STATION_TCAMm,
   1018                                           &mpls_station_entry, VLAN_IDf);
   1019             /* Get the hash value for this key */
   1020             BCM_IF_ERROR_RETURN
   1021                 (_bcm_trx_mpls_station_hash_calc(unit, hw_mac, hw_vlan, &hash));
   1022             MPLS_STATION_HASH(unit, i) = hash;
   1023         }
   1024     } else {
   1025 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   1026         if (SOC_MEM_IS_VALID(unit, MY_STATION_TCAMm)) {
   1027             _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
   1028             my_station_tcam_entry_t   entry;
   1029             bcm_mac_t                 mac_addr;
   1030             bcm_vlan_t                vid;
   1031             bcm_l2_addr_t             l2addr;
   1032             int                       rv;
   1033 
   1034             /*
   1035              * The code is used to recover COMMON_INFO(unit)->my_station_shadow
   1036              * before BCM_WB_VERSION_1_1 where L2 recovery for the bookkeeping
   1037              * is added.
   1038              */
   1039             /* Compute hash for each entry */
   1040             num_station = soc_mem_index_count(unit, MY_STATION_TCAMm);
   1041             for (i = 0; i < num_station; i++) {
   1042                 sal_memcpy(&entry, soc_mem_entry_null(unit, MY_STATION_TCAMm),
   1043                            sizeof(my_station_tcam_entry_t));
   1044                 BCM_IF_ERROR_RETURN
   1045                     (READ_MY_STATION_TCAMm(unit, MEM_BLOCK_ANY, i, &entry));
   1046                 if (!soc_mem_field32_get(unit,
   1047                                           MY_STATION_TCAMm, &entry, VALIDf)) {
   1048                     continue;
   1049                 }
   1050 
   1051                 soc_mem_mac_addr_get(unit, MY_STATION_TCAMm,
   1052                                      &entry, MAC_ADDRf, mac_addr);
   1053                 vid = soc_mem_field32_get(unit, MY_STATION_TCAMm,
   1054                                           &entry, VLAN_IDf);
   1055 #ifdef BCM_TRIUMPH3_SUPPORT
   1056                 if (soc_feature(unit, soc_feature_ism_memory)) {
   1057                     rv = _bcm_tr3_l2_addr_get(unit, mac_addr, vid, TRUE, &l2addr);
   1058                     if (BCM_FAILURE(rv)) {
   1059                         continue;
   1060                     }
   1061                 } else
   1062 #endif
   1063                 {
   1064                     rv = _bcm_tr_l2_addr_get(unit, mac_addr, vid, TRUE, &l2addr);
   1065                     if (BCM_FAILURE(rv)) {
   1066                         continue;
   1067                     }
   1068                 }
   1069 
   1070                 sal_memcpy(&info->my_station_shadow[i], &entry,
   1071                            sizeof(my_station_tcam_entry_t));
   1072             }
   1073 
   1074 #ifdef BCM_RIOT_SUPPORT
   1075             if (soc_feature(unit, soc_feature_riot) &&
   1076                                               !(SOC_IS_TRIDENT3X(unit))) {
   1077                num_station = soc_mem_index_count(unit, MY_STATION_TCAM_2m);
   1078                for (i = 0; i < num_station; i++) {
   1079                    BCM_IF_ERROR_RETURN
   1080                         (READ_MY_STATION_TCAM_2m(unit, MEM_BLOCK_ANY, i,
   1081                                                &info->my_station2_shadow[i]));
   1082                }
   1083             }
   1084 #endif /* BCM_RIOT_SUPPORT */
   1085 
   1086             /* Initialize memory accelation structures */
   1087             BCM_IF_ERROR_RETURN(_bcm_trx_mysta_memacc_init(unit));
   1088         }
   1089 #endif /* BCM_TRIDENT_SUPPORT || BCM_GREYHOUND2_SUPPORT */
   1090     }
   1091 
   1092     /* Restore the CPU TDM slot cache entry in soc_control */
   1093 #ifdef BCM_TRIUMPH2_SUPPORT
   1094     if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
   1095         SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit)) {
   1096         int i, alloc_size;
   1097         uint32 port_num;
   1098         arb_tdm_table_entry_t *arb_tdm, *arb_tdm_table;
   1099         iarb_tdm_table_entry_t *iarb_tdm, *iarb_tdm_table;
   1100         alloc_size = sizeof(arb_tdm_table_entry_t) * 
   1101                      soc_mem_index_count(unit, ARB_TDM_TABLEm);
   1102         arb_tdm_table = soc_cm_salloc(unit, alloc_size, "ARB TDM reload");
   1103         if (arb_tdm_table == NULL) {
   1104             return BCM_E_MEMORY;
   1105         }
   1106         sal_memset(arb_tdm_table, 0, alloc_size);
   1107         alloc_size = sizeof(iarb_tdm_table_entry_t) * 
   1108                      soc_mem_index_count(unit, IARB_TDM_TABLEm);
   1109         iarb_tdm_table = soc_cm_salloc(unit, alloc_size, "IARB TDM reload");
   1110         if (iarb_tdm_table == NULL) {
   1111             soc_cm_sfree(unit, arb_tdm_table);
   1112             return BCM_E_MEMORY;
   1113         }
   1114         sal_memset(iarb_tdm_table, 0, alloc_size);
   1115         if (soc_mem_read_range(unit, ARB_TDM_TABLEm, MEM_BLOCK_ANY,
   1116                                soc_mem_index_min(unit, ARB_TDM_TABLEm),
   1117                                soc_mem_index_max(unit, ARB_TDM_TABLEm),
   1118                                arb_tdm_table) < 0) {
   1119             soc_cm_sfree(unit, arb_tdm_table);
   1120             soc_cm_sfree(unit, iarb_tdm_table);
   1121             return SOC_E_INTERNAL;
   1122         }
   1123         if (soc_mem_read_range(unit, IARB_TDM_TABLEm, MEM_BLOCK_ANY,
   1124                                soc_mem_index_min(unit, IARB_TDM_TABLEm),
   1125                                soc_mem_index_max(unit, IARB_TDM_TABLEm),
   1126                                iarb_tdm_table) < 0) {
   1127             soc_cm_sfree(unit, arb_tdm_table);
   1128             soc_cm_sfree(unit, iarb_tdm_table);
   1129             return SOC_E_INTERNAL;
   1130         }
   1131         for (i = 0; i < soc_mem_index_count(unit, ARB_TDM_TABLEm); i++) {
   1132             arb_tdm = soc_mem_table_idx_to_pointer(unit, ARB_TDM_TABLEm,
   1133                                                    arb_tdm_table_entry_t *,
   1134                                                    arb_tdm_table, i);
   1135             iarb_tdm = soc_mem_table_idx_to_pointer(unit, IARB_TDM_TABLEm,
   1136                                                     iarb_tdm_table_entry_t *,
   1137                                                     iarb_tdm_table, i);             
   1138             if (soc_ARB_TDM_TABLEm_field32_get(unit, arb_tdm, WRAP_ENf)) {
   1139                 break;
   1140             }
   1141             port_num = soc_ARB_TDM_TABLEm_field32_get(unit, arb_tdm, PORT_NUMf);
   1142             if (IS_CPU_PORT(unit, port_num)) {
   1143                 sal_memcpy(&(SOC_CONTROL(unit)->iarb_tdm), iarb_tdm, 
   1144                            sizeof(iarb_tdm_table_entry_t));
   1145                 SOC_CONTROL(unit)->iarb_tdm_idx = i;
   1146             }
   1147         }
   1148         if (arb_tdm_table != NULL) {
   1149             soc_cm_sfree(unit, arb_tdm_table);
   1150         }
   1151         if (iarb_tdm_table != NULL) {
   1152             soc_cm_sfree(unit, iarb_tdm_table);
   1153         }
   1154     }
   1155 #endif /* BCM_TRIUMPH2_SUPPORT */  
   1156 
   1157     _bcm_common_wb_reinit(unit);
   1158 
   1159 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   1160     if (SOC_MEM_IS_VALID(unit, MY_STATION_TCAMm)) {
   1161         _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
   1162         my_station_tcam_entry_t   entry;
   1163 
   1164         /* Compute hash for each entry */
   1165         num_station = soc_mem_index_count(unit, MY_STATION_TCAMm);
   1166         for (i = 0; i < num_station; i++) {
   1167             sal_memcpy(&entry, soc_mem_entry_null(unit, MY_STATION_TCAMm),
   1168                        sizeof(my_station_tcam_entry_t));
   1169             BCM_IF_ERROR_RETURN
   1170                 (READ_MY_STATION_TCAMm(unit, MEM_BLOCK_ANY, i, &entry));
   1171             if (!(info->my_station_shadow_mask->buf[i/32] & 1<<(i%32))) {
   1172                 continue;
   1173             }
   1174             sal_memcpy(&info->my_station_shadow[i], &entry,
   1175                        sizeof(my_station_tcam_entry_t));
   1176         }
   1177     }
   1178 #endif /* BCM_TRIDENT_SUPPORT || BCM_GREYHOUND2_SUPPORT */
   1179 
   1180 #if defined(BCM_TRIDENT3_SUPPORT)
   1181     if (SOC_IS_TRIDENT3X(unit)) {
   1182         _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
   1183         my_station_tcam_2_entry_t   entry;
   1184 
   1185         /* Compute hash for each entry */
   1186         num_station = soc_mem_index_count(unit, MY_STATION_TCAM_2m);
   1187         for (i = 0; i < num_station; i++) {  
   1188             sal_memcpy(&entry, soc_mem_entry_null(unit, MY_STATION_TCAM_2m),
   1189                        sizeof(my_station_tcam_2_entry_t));
   1190             BCM_IF_ERROR_RETURN
   1191                 (READ_MY_STATION_TCAM_2m(unit, MEM_BLOCK_ANY, i, &entry));
   1192             if (!soc_mem_field32_get(unit,MY_STATION_TCAM_2m, &entry, VALIDf)) {
   1193                     continue;
   1194             }
   1195             if (!(info->my_station2_shadow_mask->buf[i/32] & 1<<(i%32))) {
   1196                 continue;
   1197             }
   1198             sal_memcpy(&info->my_station2_shadow[i], &entry,
   1199                        sizeof(my_station_tcam_2_entry_t));
   1200         }
   1201     }
   1202 #endif
   1203 
   1204     return BCM_E_NONE;
   1205 }
   1206 #endif /* BCM_WARM_BOOT_SUPPORT */
   1207 
   1208 /*
   1209  * Function:
   1210  *      _bcm_common_cleanup
   1211  * Purpose:
   1212  *      Internal function for initializing common resource management
   1213  *      Shared by MPLS and MIM
   1214  * Parameters:
   1215  *      unit    -  (IN) Device number.
   1216  * Returns:
   1217  *      BCM_X_XXX
   1218  */
   1219 int _bcm_common_cleanup(int unit)
   1220 {
   1221     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
   1222     _bcm_common_free_resource(unit, info);
   1223     info->mac_da_profile_created = FALSE;
   1224     info->lport_profile_created = FALSE;
   1225     info->ing_pri_cng_map_created = FALSE;
   1226     info->ing_vft_pri_map_created = FALSE;
   1227     info->ing_outer_dot1p_created = FALSE;
   1228     info->ing_l2_vlan_etag_map_created = FALSE;    
   1229     info->egr_l2_vlan_etag_map_created = FALSE;
   1230     info->egr_vsan_intpri_map_created = FALSE;
   1231     info->egr_vft_pri_map_created = FALSE;
   1232     info->egr_vft_fields_created = FALSE;
   1233     info->egr_mpls_combo_map_created = FALSE;
   1234     info->dscp_table_created = FALSE;
   1235     info->egr_dscp_table_created = FALSE;
   1236     info->prot_pkt_ctrl_created = FALSE;
   1237 #ifdef BCM_TRIUMPH3_SUPPORT
   1238     if (SOC_IS_TRIUMPH3(unit)) {
   1239         info->ing_l3_nh_attribute_created = FALSE;
   1240     }
   1241 #endif /* BCM_TRIUMPH3_SUPPORT */
   1242 #ifdef BCM_TRIDENT2_SUPPORT
   1243     if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   1244         info->l3_iif_profile_created = FALSE;
   1245         info->l3_ip4_options_profile_created = FALSE;
   1246         info->fc_map_profile_created = FALSE;
   1247     }
   1248 #endif /* BCM_TRIDENT2_SUPPORT */
   1249 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   1250     if (soc_feature(unit, soc_feature_vfi_profile)) {
   1251         info->vfi_profile_created = FALSE;
   1252     }
   1253 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   1254 #ifdef BCM_KATANA_SUPPORT
   1255     info->ing_queue_offset_map_created = FALSE;
   1256 #endif /* BCM_KATANA_SUPPORT */
   1257 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   1258     info->vlan_protocol_data_profile_created = FALSE;
   1259 #endif /* BCM_KATANA2_SUPPORT */
   1260 #ifdef BCM_SABER2_SUPPORT
   1261     if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   1262         info->service_pri_map_created = FALSE;
   1263     }
   1264 #endif /* BCM_SABER2_SUPPORT */
   1265 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   1266     info->ing_vlan_vfi_mbrship_profile_created = FALSE;
   1267     info->egr_vlan_vfi_mbrship_profile_created = FALSE;
   1268     info->misc_port_profile_created = FALSE;
   1269 #endif
   1270 
   1271 #ifdef BCM_TRIDENT3_SUPPORT
   1272     info->egr_vlan_vfi_untag_profile_created = FALSE;
   1273 #endif
   1274 
   1275     info->lport_ind_profile_created = FALSE;
   1276     info->rtag7_ind_profile_created = FALSE;
   1277     info->egr_lport_profile_created = FALSE;
   1278     info->egr_qos_profile_created = FALSE;
   1279 #ifdef BCM_HURRICANE3_SUPPORT
   1280     info->egr_header_encap_data_created = FALSE;
   1281     info->custom_header_match_created = FALSE;
   1282 #endif /* BCM_HURRICANE3_SUPPORT */
   1283 #ifdef BCM_TOMAHAWK_SUPPORT
   1284     info->ing_tunnel_term_map_created = FALSE;
   1285 #endif /* BCM_TOMAHAWK_SUPPORT */
   1286 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
   1287     defined(BCM_TRIDENT3_SUPPORT)
   1288     info->ing_exp_to_ip_ecn_map_created = FALSE;
   1289     info->egr_ip_ecn_to_exp_map_created = FALSE;
   1290     info->egr_int_cn_to_exp_map_created = FALSE;
   1291 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */
   1292 
   1293     info->initialized = FALSE;
   1294     return BCM_E_NONE;
   1295 }
   1296 
   1297 /*
   1298  * Function:
   1299  *      _bcm_common_init
   1300  * Purpose:
   1301  *      Internal function for initializing common resource management
   1302  *      Shared by MPLS and MIM
   1303  * Parameters:
   1304  *      unit    -  (IN) Device number.
   1305  * Returns:
   1306  *      BCM_X_XXX
   1307  */
   1308 int _bcm_common_init(int unit)
   1309 {
   1310     int num_station = 0, rv = BCM_E_NONE;
   1311     soc_mem_t mem;
   1312     soc_mem_t mems[10];
   1313     int mem_words[10];
   1314     int index_min[10];
   1315     int index_max[10];
   1316     int mems_cnt;
   1317     int entry_words, alloc_size;
   1318     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
   1319 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   1320     fp_i2e_classid_select_entry_t fp_ent;
   1321     fp_hg_classid_select_entry_t hg_ent;
   1322     void *entries[2];
   1323     uint32 base_id;
   1324 #endif
   1325 #ifdef BCM_RIOT_SUPPORT
   1326     soc_mem_t mem2;
   1327 #endif
   1328 #ifdef BCM_SABER2_SUPPORT
   1329     int mem_index;
   1330     soc_mem_t
   1331     _bcm_sb2_svc_pri_map_profile_mem_index_to_mem[_BCM_SB2_OAM_PRI_MAP_TABLE_MAX] =
   1332     {
   1333             ING_SERVICE_PRI_MAP_0m,
   1334             ING_SERVICE_PRI_MAP_1m,
   1335             ING_SERVICE_PRI_MAP_2m,
   1336 
   1337             EGR_SERVICE_PRI_MAP_0m,
   1338             EGR_SERVICE_PRI_MAP_1m,
   1339             EGR_SERVICE_PRI_MAP_2m
   1340     };
   1341 #endif
   1342 
   1343     if (info->initialized) {
   1344         BCM_IF_ERROR_RETURN(_bcm_common_cleanup(unit));
   1345     }
   1346 
   1347     /* Create mutex */
   1348     if (NULL == _common_mutex[unit]) {
   1349         _common_mutex[unit] = sal_mutex_create("common mutex");
   1350         if (_common_mutex[unit] == NULL) {
   1351             _bcm_common_free_resource(unit, info);
   1352             return BCM_E_MEMORY;
   1353         }
   1354     }
   1355 
   1356 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
   1357     if (soc_feature(unit, soc_feature_src_modid_base_index)) {
   1358         rv = bcmi_esw_src_modid_base_index_bk_init(unit);
   1359         if (BCM_FAILURE(rv)) {      
   1360             _bcm_common_free_resource(unit, info);
   1361             return rv;
   1362         }
   1363     }
   1364 
   1365 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */
   1366 
   1367     if (SAL_BOOT_SIMULATION &&
   1368         soc_property_get(unit, "skip_common_init", 0)) {
   1369         info->initialized = TRUE;
   1370         return BCM_E_NONE;
   1371     }
   1372 
   1373     /* MPLS station hash */
   1374     if (SOC_MEM_IS_VALID(unit, MPLS_STATION_TCAMm)) {
   1375         num_station = soc_mem_index_count(unit, MPLS_STATION_TCAMm);
   1376         if (NULL == info->mpls_station_hash) {
   1377             info->mpls_station_hash = sal_alloc(sizeof(uint16) *
   1378                                         num_station, "mpls station hash");
   1379             if (info->mpls_station_hash == NULL) {
   1380                 _bcm_common_free_resource(unit, info);
   1381                 return BCM_E_MEMORY;
   1382             }
   1383             sal_memset(info->mpls_station_hash, 0, 
   1384                 sizeof(uint16) * num_station);
   1385         }
   1386     } else if (SOC_MEM_IS_VALID(unit, MY_STATION_TCAMm)) {
   1387         num_station = soc_mem_index_count(unit, MY_STATION_TCAMm);
   1388         if (SOC_MEM_IS_VALID(unit, MY_STATION_TCAMm)) {
   1389             alloc_size = sizeof(my_station_tcam_entry_t) * num_station;
   1390             if (NULL == info->my_station_shadow) {
   1391                 info->my_station_shadow =
   1392                     sal_alloc(alloc_size, "my station shadow");
   1393                 if (info->my_station_shadow == NULL) {
   1394                     _bcm_common_free_resource(unit, info);
   1395                     return BCM_E_MEMORY;
   1396                 }
   1397                 sal_memset(info->my_station_shadow, 0, alloc_size);
   1398             }
   1399 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   1400             alloc_size = sizeof(my_station_shadow_mask_t);
   1401             if (NULL == info->my_station_shadow_mask) {
   1402                 info->my_station_shadow_mask =
   1403                     sal_alloc(alloc_size, "my station shadow mask");
   1404                 if (info->my_station_shadow_mask == NULL) {
   1405                     _bcm_common_free_resource(unit, info);
   1406                     return BCM_E_MEMORY;
   1407                 }
   1408                 sal_memset(info->my_station_shadow_mask, 0, alloc_size);
   1409             }
   1410 #endif
   1411             /* L3 flags */
   1412             if (SOC_IS_TRIDENT3X(unit)) {
   1413                 mem = MY_STATION_PROFILE_1m;
   1414             } else {
   1415                 mem = MY_STATION_TCAMm;
   1416             }
   1417 
   1418             if (NULL == info->my_station_l3_mask) {
   1419                 info->my_station_l3_mask =
   1420                     sal_alloc(soc_mem_entry_words(unit, mem) * 4, "l3_mask");
   1421                 if (info->my_station_l3_mask == NULL) {
   1422                     _bcm_common_free_resource(unit, info);
   1423                     return BCM_E_MEMORY;
   1424                 }
   1425                 sal_memset(info->my_station_l3_mask, 0,
   1426                            soc_mem_entry_words(unit, mem) * 4);
   1427             }
   1428 
   1429             soc_mem_field32_set(unit, mem, info->my_station_l3_mask,
   1430                                 IPV4_TERMINATION_ALLOWEDf, 1);
   1431             soc_mem_field32_set(unit, mem, info->my_station_l3_mask,
   1432                                 IPV6_TERMINATION_ALLOWEDf, 1);
   1433             soc_mem_field32_set(unit, mem, info->my_station_l3_mask,
   1434                                 ARP_RARP_TERMINATION_ALLOWEDf, 1);
   1435             /* OAM flags */
   1436             if (SOC_IS_KATANA(unit) || SOC_IS_TRIDENT3X(unit)) {
   1437                 if (soc_mem_field_valid(unit,mem, OAM_TERMINATION_ALLOWEDf)) {
   1438                     soc_mem_field32_set(unit, mem, info->my_station_l3_mask,
   1439                                         OAM_TERMINATION_ALLOWEDf, 1);
   1440                 }
   1441             }
   1442 
   1443             if (NULL == info->my_station_tunnel_mask) {
   1444                 info->my_station_tunnel_mask =
   1445                     sal_alloc(soc_mem_entry_words(unit, mem) * 4, "l3_mask");
   1446                 if (info->my_station_tunnel_mask == NULL) {
   1447                     _bcm_common_free_resource(unit, info);
   1448                     return BCM_E_MEMORY;
   1449                 }
   1450                 sal_memset(info->my_station_tunnel_mask, 0,
   1451                            soc_mem_entry_words(unit, mem) * 4);
   1452             }
   1453 
   1454             /* Tunnel flags */
   1455             if (soc_mem_field_valid(unit, mem, MIM_TERMINATION_ALLOWEDf)) {
   1456                 soc_mem_field32_set(unit, mem, info->my_station_tunnel_mask,
   1457                                 MIM_TERMINATION_ALLOWEDf, 1);
   1458             }
   1459             if (soc_mem_field_valid(unit, mem, MPLS_TERMINATION_ALLOWEDf)) {
   1460                 soc_mem_field32_set(unit, mem, info->my_station_tunnel_mask,
   1461                                 MPLS_TERMINATION_ALLOWEDf, 1);
   1462             }
   1463             if (soc_mem_field_valid(unit, mem, TRILL_TERMINATION_ALLOWEDf)) {
   1464                 soc_mem_field32_set(unit, mem, info->my_station_tunnel_mask,
   1465                                 TRILL_TERMINATION_ALLOWEDf, 1);
   1466             }
   1467         }
   1468 
   1469 #ifdef BCM_RIOT_SUPPORT
   1470         if (soc_feature(unit, soc_feature_riot) || SOC_IS_TRIDENT3X(unit)) {
   1471             if (SOC_IS_TRIDENT3X(unit)) {
   1472                 mem2 = MY_STATION_PROFILE_2m;
   1473             } else {
   1474                 mem2 = MY_STATION_TCAM_2m;
   1475             }
   1476 
   1477 
   1478             num_station = soc_mem_index_count(unit, MY_STATION_TCAM_2m);
   1479             alloc_size = sizeof(my_station_tcam_2_entry_t) * num_station;
   1480             if (NULL == info->my_station2_shadow) {
   1481                 info->my_station2_shadow =
   1482                     sal_alloc(alloc_size, "my_station2 shadow");
   1483                 if (info->my_station2_shadow == NULL) {
   1484                     _bcm_common_free_resource(unit, info);
   1485                     return BCM_E_MEMORY;
   1486                 }
   1487                 sal_memset(info->my_station2_shadow, 0, alloc_size);
   1488             }
   1489 #if defined(BCM_TRIDENT3_SUPPORT)
   1490             alloc_size = sizeof(my_station_shadow_mask_t);
   1491             if (NULL == info->my_station2_shadow_mask) {
   1492                 info->my_station2_shadow_mask =
   1493                     sal_alloc(alloc_size, "my station2 shadow mask");
   1494                 if (info->my_station2_shadow_mask == NULL) {
   1495                     _bcm_common_free_resource(unit, info);
   1496                     return BCM_E_MEMORY;
   1497                 }
   1498                 sal_memset(info->my_station2_shadow_mask, 0, alloc_size);
   1499             }
   1500 #endif
   1501             /* L3 flags */
   1502             soc_mem_field32_set(unit, mem2,
   1503                                 &info->my_station2_l3_mask,
   1504                                 IPV4_TERMINATION_ALLOWEDf, 1);
   1505             soc_mem_field32_set(unit, mem2,
   1506                                 &info->my_station2_l3_mask,
   1507                                 IPV6_TERMINATION_ALLOWEDf, 1);
   1508             soc_mem_field32_set(unit, mem2,
   1509                                 &info->my_station2_l3_mask,
   1510                                 ARP_RARP_TERMINATION_ALLOWEDf, 1);
   1511             /* Tunnel flags */
   1512             soc_mem_field32_set(unit, mem2,
   1513                                 &info->my_station2_tunnel_mask,
   1514                                 MIM_TERMINATION_ALLOWEDf, 1);
   1515             soc_mem_field32_set(unit, mem2,
   1516                                 &info->my_station2_tunnel_mask,
   1517                                 MPLS_TERMINATION_ALLOWEDf, 1);
   1518             if (soc_mem_field_valid(unit, mem2, 
   1519                                     TRILL_TERMINATION_ALLOWEDf)) {
   1520                 soc_mem_field32_set(unit, mem2,
   1521                                 &info->my_station2_tunnel_mask,
   1522                                 TRILL_TERMINATION_ALLOWEDf, 1);
   1523             }
   1524         }
   1525 #endif /* BCM_RIOT_SUPPORT */
   1526 
   1527 
   1528 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   1529         /* Initialize memory accelation structures */
   1530         rv = _bcm_trx_mysta_memacc_init(unit);    
   1531         if (BCM_FAILURE(rv)) {
   1532             _bcm_common_free_resource(unit, info);
   1533             return rv;
   1534         }
   1535 #endif
   1536     }
   1537 
   1538     /* Create profile table cache (or re-init if it already exists) */
   1539     mem = EGR_MAC_DA_PROFILEm;
   1540     if (SOC_MEM_IS_VALID(unit, mem)) {
   1541         if (NULL == info->mac_da_profile) {
   1542             info->mac_da_profile = sal_alloc(sizeof(soc_profile_mem_t),
   1543                     "MAC DA Profile Mem");
   1544             if (info->mac_da_profile == NULL) {
   1545                 _bcm_common_free_resource(unit, info);
   1546                 return BCM_E_MEMORY;
   1547             }
   1548             soc_profile_mem_t_init(info->mac_da_profile);
   1549 
   1550             entry_words = sizeof(egr_mac_da_profile_entry_t) / sizeof(uint32);
   1551             rv = soc_profile_mem_create(unit, &mem, &entry_words, 1,
   1552                     info->mac_da_profile);
   1553             info->mac_da_profile_created = TRUE;
   1554             if (rv < 0) {
   1555                 _bcm_common_free_resource(unit, info);
   1556                 return rv;
   1557             }
   1558         }
   1559     }
   1560 
   1561     if(soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) {
   1562 
   1563         /* Create profile table cache (or re-init if it already exists) */
   1564         /*
   1565          * The LPORT profile table is composed of these memory tables:
   1566          *     LPORT_TAB
   1567          */
   1568         mem = LPORT_TABm;
   1569         if (SOC_MEM_IS_VALID(unit, mem)) {
   1570             if (NULL == info->lport_ind_profile ) {
   1571                 info->lport_ind_profile = sal_alloc(sizeof(soc_profile_mem_t),
   1572                                                 "LPORT_PROFILE_TABLE Mem");
   1573                 if (info->lport_ind_profile == NULL) {
   1574                     _bcm_common_free_resource(unit, info);
   1575                     return BCM_E_MEMORY;
   1576                 }
   1577                 soc_profile_mem_t_init(info->lport_ind_profile);
   1578 
   1579                 mems_cnt = 0;
   1580                 mems[mems_cnt] = mem;
   1581                 mem_words[mems_cnt] = sizeof(lport_tab_entry_t) / sizeof(uint32);
   1582                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   1583                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1584                 mems_cnt++;
   1585 
   1586                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   1587                                                   index_min, index_max, NULL,
   1588                                                   mems_cnt, info->lport_ind_profile);
   1589 
   1590                 if (rv < 0) {
   1591                     _bcm_common_free_resource(unit, info);
   1592                     return rv;
   1593                 }
   1594 
   1595                 info->lport_ind_profile_created = TRUE;
   1596 
   1597                 if (SOC_WARM_BOOT(unit)) {
   1598                     /*
   1599                      * Set at least one reference count for default entry.
   1600                      *
   1601                      * Other modules that make a reference to the LPORT table are
   1602                      * responsible for updating the LPORT reference count.
   1603                      */
   1604                     rv = _bcm_lport_ind_profile_mem_reference
   1605                         (unit,
   1606                          _bcm_trx_lport_tab_default_entry_index_get(unit), 1); 
   1607                 } else {
   1608                     /* coverity[stack_use_callee] */
   1609                     /* coverity[stack_use_overflow] */
   1610                     rv = _bcm_trx_lport_tab_default_entry_add(unit,
   1611                                                               info->lport_ind_profile);
   1612                 }
   1613                 if (BCM_FAILURE(rv)) {
   1614                     _bcm_common_free_resource(unit, info);
   1615                     return rv;
   1616                 }
   1617             }
   1618         }
   1619 
   1620         mem = RTAG7_PORT_BASED_HASHm;
   1621         if (SOC_MEM_IS_VALID(unit, mem)) {
   1622             if (NULL == info->rtag7_ind_profile) {
   1623                 info->rtag7_ind_profile = sal_alloc(sizeof(soc_profile_mem_t),
   1624                                                 "RTAG7_PROFILE_TABLE Mem");
   1625                 if (info->rtag7_ind_profile == NULL) {
   1626                     _bcm_common_free_resource(unit, info);
   1627                     return BCM_E_MEMORY;
   1628                 }
   1629                 soc_profile_mem_t_init(info->rtag7_ind_profile);
   1630 
   1631                 mems_cnt = 0;
   1632                 mems[mems_cnt] = mem;
   1633                 mem_words[mems_cnt] = sizeof(rtag7_port_based_hash_entry_t) / sizeof(uint32);
   1634                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   1635                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1636                 /* Reserving the last set of entries for Front-Panel ports */
   1637                 /* Not sure why TD2PLUS reserves the RTAG7_PORT_BASED_HASH indices,
   1638                    TD3 don't seem to be necessary any index should work for FP ports*/
   1639                 if (!SOC_IS_TRIDENT3X(unit)) {
   1640                 index_max[mems_cnt] = soc_mem_index_max(unit, mem) - 
   1641                                         soc_mem_index_max(unit, PORT_TABm);
   1642                 }
   1643                 mems_cnt++;
   1644 
   1645                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   1646                                                   index_min, index_max, NULL,
   1647                                                   mems_cnt, info->rtag7_ind_profile);
   1648 
   1649                 if (BCM_FAILURE(rv)) {
   1650                     _bcm_common_free_resource(unit, info);
   1651                     return rv;
   1652                 }
   1653 
   1654                 info->rtag7_ind_profile_created = TRUE;
   1655 
   1656                 if (SOC_WARM_BOOT(unit)) {
   1657                     /*
   1658                      * Set at least one reference count for default entry.
   1659  */
   1660                     rv = _bcm_rtag7_ind_profile_mem_reference
   1661                         (unit,
   1662                          _bcm_trx_rtag7_tab_default_entry_index_get(unit), 1); 
   1663                 } else {
   1664                     /* coverity[stack_use_callee] */
   1665                     /* coverity[stack_use_overflow] */
   1666                     rv = _bcm_trx_rtag7_tab_default_entry_add(unit,
   1667                                                               info->rtag7_ind_profile);
   1668                 }
   1669             }
   1670         }
   1671     } else {
   1672 
   1673         /* Create profile table cache (or re-init if it already exists) */
   1674         /*
   1675          * The LPORT profile table is composed of these memory tables:
   1676          *     LPORT_TAB
   1677          *     RTAG7_PORT_BASED_HASH (when available)
   1678          *
   1679          * The first set of entries in the RTAG7 table is used by the
   1680          * LPORT profile table (when RTAG7 is larger than LPORT).
   1681          */
   1682         mem = LPORT_TABm;
   1683         if (SOC_MEM_IS_VALID(unit, mem)) {
   1684             if (NULL == info->lport_profile && 
   1685                 soc_feature(unit, soc_feature_lport_tab_profile)) {
   1686                 info->lport_profile = sal_alloc(sizeof(soc_profile_mem_t),
   1687                                                 "LPORT_PROFILE_TABLE Mem");
   1688                 if (info->lport_profile == NULL) {
   1689                     _bcm_common_free_resource(unit, info);
   1690                     return BCM_E_MEMORY;
   1691                 }
   1692                 soc_profile_mem_t_init(info->lport_profile);
   1693 
   1694                 mems_cnt = 0;
   1695                 mems[mems_cnt] = mem;
   1696                 mem_words[mems_cnt] = sizeof(lport_tab_entry_t) / sizeof(uint32);
   1697                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   1698                 /* Tomahawk 3 split this memory into per pipe, so need to
   1699                  * access differently if the memory is unique */
   1700 #ifdef BCM_TOMAHAWK3_SUPPORT
   1701                 if (SOC_IS_TOMAHAWK3(unit)) {
   1702                     /* Create one logical table for all of the unique per pipe
   1703                      * memories */
   1704                     index_max[mems_cnt] =
   1705                         ((soc_mem_index_max(unit, mem) + 1) * _TH3_PIPES_PER_DEV) - 1;
   1706                 } else
   1707 #endif
   1708                 {
   1709                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1710                 }
   1711                 mems_cnt++;
   1712 
   1713                 mem = RTAG7_PORT_BASED_HASHm;
   1714                 /* For TD2Plus, RTA7_PORT_PROFILE_INDEX is derived
   1715                  * from L/PORT_PROFILE_TABLE__RTAG7_PORT_PROFILE_INDEX
   1716                  * so Allocate only available entries (i.e) LPORT 
   1717                  * entries > RTAG7_PORT_PROFILE_TABLE entries. 
   1718                  */
   1719                 if (SOC_MEM_IS_VALID(unit, mem) && 
   1720                     (!SOC_IS_TRIDENT2PLUS(unit)) &&
   1721                     (!SOC_IS_TRIDENT3X(unit)) &&
   1722                     (!SOC_IS_TD2P_TT2P(unit))) {
   1723                     int lport_index = 0;
   1724 
   1725                     mems[mems_cnt] = mem;
   1726                     mem_words[mems_cnt] = sizeof(rtag7_port_based_hash_entry_t) /
   1727                         sizeof(uint32);
   1728                     index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   1729                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1730 
   1731                     /* Make sure RTAG7 table is at least as large as LPORT */
   1732                     if ((index_max[mems_cnt] - index_min[mems_cnt]) <
   1733                         (index_max[lport_index] - index_min[lport_index])) { 
   1734                         _bcm_common_free_resource(unit, info);
   1735                         return BCM_E_INTERNAL;
   1736                     }
   1737                     /* Use size of LPORT table */
   1738                     index_max[mems_cnt] = index_min[mems_cnt] +
   1739                         index_max[lport_index] - index_min[lport_index];
   1740                     
   1741                     mems_cnt++;
   1742                 }
   1743 
   1744                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   1745                                                   index_min, index_max, NULL,
   1746                                                   mems_cnt, info->lport_profile);
   1747 
   1748                 info->lport_profile_created = TRUE;
   1749                 if (rv < 0) {
   1750                     _bcm_common_free_resource(unit, info);
   1751                     return rv;
   1752                 }
   1753 
   1754                 if (SOC_WARM_BOOT(unit)) {
   1755                     /*
   1756                      * Set at least one reference count for default entry.
   1757                      *
   1758                      * Other modules that make a reference to the LPORT table are
   1759                      * responsible for updating the LPORT reference count.
   1760                      */
   1761                     rv = _bcm_lport_profile_mem_reference
   1762                         (unit,
   1763                          _bcm_trx_lport_tab_default_entry_index_get(unit), 1);
   1764                 } else {
   1765                     /* coverity[stack_use_callee] */
   1766                     /* coverity[stack_use_overflow] */
   1767                     rv = _bcm_trx_lport_tab_default_entry_add(unit,
   1768                                                               info->lport_profile);
   1769                 }
   1770                 if (BCM_FAILURE(rv)) {
   1771                     _bcm_common_free_resource(unit, info);
   1772                     return rv;
   1773                 }
   1774             }
   1775         }
   1776     }
   1777 
   1778     if(soc_feature(unit, soc_feature_egr_lport_tab_profile)) {
   1779         int amend = soc_mem_index_max(unit, EGR_PORTm);
   1780         /* Create profile table cache (or re-init if it already exists) */
   1781         /*
   1782          * The LPORT profile table is composed of these memory tables:
   1783          *     EGR_LPORT_PROFILE
   1784          *     EGR_VLAN_CONTROL_1
   1785          *     EGR_VLAN_CONTROL_2
   1786          *     EGR_VLAN_CONTROL_3
   1787          *     EGR_IPMC_CFG2
   1788          *     EGR_MTU
   1789          *     EGR_PORT_1
   1790          *     EGR_COUNTER_CONTROL
   1791          *     EGR_SHAPING_CONTROL
   1792          *     
   1793          * The first set of entries in the RTAG7 table is used by the
   1794          * LPORT profile table (when RTAG7 is larger than LPORT).
   1795          */
   1796         mem = EGR_LPORT_PROFILEm;
   1797         if (soc_feature(unit, soc_feature_egr_all_profile)) {
   1798             amend = 0;
   1799         }
   1800         if (SOC_MEM_IS_VALID(unit, mem)) {
   1801             if (NULL == info->egr_lport_profile) {
   1802 
   1803                 if (!SOC_WARM_BOOT(unit) &&
   1804                     soc_feature(unit, soc_feature_egr_all_profile)) {
   1805                     soc_port_t port;
   1806                     PBMP_ALL_ITER(unit, port) {
   1807                         rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
   1808                                 EGR_LPORT_PROFILE_IDXf, 0);
   1809                         if (SOC_FAILURE(rv)) {
   1810                             _bcm_common_free_resource(unit, info);
   1811                             return rv;
   1812                         }
   1813                     }
   1814                 }
   1815 
   1816                 info->egr_lport_profile = sal_alloc(sizeof(soc_profile_mem_t),
   1817                                                 "EGR_LPORT_PROFILE_TABLE Mem");
   1818                 if (info->egr_lport_profile == NULL) {
   1819                     _bcm_common_free_resource(unit, info);
   1820                     return BCM_E_MEMORY;
   1821                 }
   1822                 soc_profile_mem_t_init(info->egr_lport_profile);
   1823 
   1824                 mems_cnt = 0;
   1825                 mems[mems_cnt] = mem;
   1826                 mem_words[mems_cnt] = sizeof(egr_lport_profile_entry_t) / sizeof(uint32);
   1827                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   1828                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1829 
   1830                 mems_cnt++;
   1831 
   1832                 mem = EGR_VLAN_CONTROL_1m;
   1833                 if (SOC_MEM_IS_VALID(unit, mem)) {
   1834                     mems[mems_cnt] = mem;
   1835                     mem_words[mems_cnt] = sizeof(egr_vlan_control_1_entry_t) /
   1836                         sizeof(uint32);
   1837 
   1838                     /* The first */
   1839                     index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend;
   1840                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1841 
   1842                     mems_cnt++;
   1843                 }
   1844 
   1845                 mem = EGR_VLAN_CONTROL_2m;
   1846                 if (SOC_MEM_IS_VALID(unit, mem)) {
   1847                     mems[mems_cnt] = mem;
   1848                     mem_words[mems_cnt] = sizeof(egr_vlan_control_2_entry_t) /
   1849                         sizeof(uint32);
   1850                     index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend;
   1851                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1852 
   1853                     mems_cnt++;
   1854                 }
   1855 
   1856                 mem = EGR_VLAN_CONTROL_3m;
   1857                 if (SOC_MEM_IS_VALID(unit, mem)) {
   1858                     mems[mems_cnt] = mem;
   1859                     mem_words[mems_cnt] = sizeof(egr_vlan_control_3_entry_t) /
   1860                         sizeof(uint32);
   1861                     index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend;
   1862                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1863 
   1864                     mems_cnt++;
   1865                 }
   1866 
   1867                 mem = EGR_IPMC_CFG2m;
   1868                 if (SOC_MEM_IS_VALID(unit, mem)) {
   1869                     mems[mems_cnt] = mem;
   1870                     mem_words[mems_cnt] = sizeof(egr_ipmc_cfg2_entry_t) /
   1871                         sizeof(uint32);
   1872                     index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend;
   1873                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1874 
   1875                     mems_cnt++;
   1876                 }
   1877 
   1878                 mem = EGR_MTUm;
   1879                 if (SOC_MEM_IS_VALID(unit, mem)) {
   1880                     mems[mems_cnt] = mem;
   1881                     mem_words[mems_cnt] = sizeof(egr_mtu_entry_t) /
   1882                         sizeof(uint32);
   1883                     index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend;
   1884                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1885 
   1886                     mems_cnt++;
   1887                 }
   1888 
   1889                 mem = EGR_PORT_1m;
   1890                 if (SOC_MEM_IS_VALID(unit, mem) &&
   1891                     (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_L3_AND_FP)) {
   1892                     mems[mems_cnt] = mem;
   1893                     mem_words[mems_cnt] = sizeof(egr_port_1_entry_t) /
   1894                         sizeof(uint32);
   1895                     index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend;
   1896                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1897 
   1898                     mems_cnt++;
   1899                 }
   1900 
   1901                 if (soc_feature(unit, soc_feature_egr_all_profile) == 0) {
   1902                 mem = EGR_COUNTER_CONTROLm;
   1903                 if (SOC_MEM_IS_VALID(unit, mem)) {
   1904                     mems[mems_cnt] = mem;
   1905                     mem_words[mems_cnt] = sizeof(egr_counter_control_entry_t) /
   1906                         sizeof(uint32);
   1907                         index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend;
   1908                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1909 
   1910                     mems_cnt++;
   1911                 }
   1912 
   1913                 mem = EGR_SHAPING_CONTROLm;
   1914                 if (SOC_MEM_IS_VALID(unit, mem)) {
   1915                     mems[mems_cnt] = mem;
   1916                     mem_words[mems_cnt] = sizeof(egr_shaping_control_entry_t) /
   1917                         sizeof(uint32);
   1918                         index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend;
   1919                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1920 
   1921                     mems_cnt++;
   1922                 }
   1923                 }
   1924 
   1925                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   1926                                                   index_min, index_max, NULL,
   1927                                                   mems_cnt, info->egr_lport_profile);
   1928 
   1929                 if (rv < 0) {
   1930                     _bcm_common_free_resource(unit, info);
   1931                     return rv;
   1932                 }
   1933 
   1934                 info->egr_lport_profile_created = TRUE;
   1935 
   1936                 /* coverity[stack_use_callee] */
   1937                 /* coverity[stack_use_overflow] */
   1938                 rv = _bcm_trx_egr_lport_tab_default_entry_add(unit,
   1939                                                           info->egr_lport_profile);
   1940 
   1941                 if (BCM_FAILURE(rv)) {
   1942                     _bcm_common_free_resource(unit, info);
   1943                     return rv;
   1944                 }
   1945             }
   1946         }
   1947     }
   1948 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   1949     if(soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) {
   1950 
   1951         /* Create profile table cache (or re-init if it already exists) */
   1952         /*
   1953          * The MISC PORT profile table is composed of these memory tables:
   1954          *     FP_I2E_CLASSID_SELECT
   1955          *     FP_HG_CLASSID_SELECT
   1956  */
   1957         mem = FP_I2E_CLASSID_SELECTm;
   1958 
   1959         if (SOC_MEM_IS_VALID(unit, mem)) {
   1960             if (NULL == info->misc_port_profile) {
   1961                 info->misc_port_profile = sal_alloc(sizeof(soc_profile_mem_t),
   1962                                                 "MISC_PORT_PROFILE_TABLE Mem");
   1963                 if (info->misc_port_profile == NULL) {
   1964                     _bcm_common_free_resource(unit, info);
   1965                     return BCM_E_MEMORY;
   1966                 }
   1967                 soc_profile_mem_t_init(info->misc_port_profile);
   1968 
   1969                 mems_cnt = 0;
   1970                 mems[mems_cnt] = mem;
   1971                 mem_words[mems_cnt] = sizeof(fp_i2e_classid_select_entry_t) / sizeof(uint32);
   1972                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   1973                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1974                 mems_cnt++;
   1975 
   1976                 mem = FP_HG_CLASSID_SELECTm;
   1977                 if (SOC_MEM_IS_VALID(unit, mem)) {
   1978 
   1979                     mems[mems_cnt] = mem;
   1980                     mem_words[mems_cnt] = sizeof(fp_hg_classid_select_entry_t) /
   1981                         sizeof(uint32);
   1982                     index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   1983                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   1984                     mems_cnt++;
   1985                 }
   1986 
   1987                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   1988                                                   index_min, index_max, NULL,
   1989                                                   mems_cnt, info->misc_port_profile);
   1990 
   1991                 if (rv < 0) {
   1992                     _bcm_common_free_resource(unit, info);
   1993                     return rv;
   1994                 }
   1995 
   1996                 /* Create a default entry */
   1997                 sal_memset(&fp_ent, 0, sizeof(fp_i2e_classid_select_entry_t));
   1998                 sal_memset(&hg_ent, 0, sizeof(fp_hg_classid_select_entry_t));
   1999                 entries[0] = &fp_ent;
   2000                 entries[1] = &hg_ent;
   2001                 BCM_IF_ERROR_RETURN
   2002                     (_bcm_misc_port_profile_entry_add(unit, entries, 1, &base_id));
   2003 
   2004                 info->misc_port_profile_created = TRUE;
   2005             }
   2006         }
   2007     }
   2008 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   2009 
   2010     /* Create profile table cache (or re-init if it already exists) */
   2011     mem = (SOC_IS_TRIDENT3X(unit))? PHB_MAPPING_TBL_1m : ING_PRI_CNG_MAPm;
   2012     if (SOC_MEM_IS_VALID(unit, mem)) {
   2013         if (NULL == info->ing_pri_cng_map) {
   2014             info->ing_pri_cng_map = sal_alloc(sizeof(soc_profile_mem_t),
   2015                                               "ING_PRI_CNG_MAP Profile Mem");
   2016             if (info->ing_pri_cng_map == NULL) {
   2017                 _bcm_common_free_resource(unit, info);
   2018                 return BCM_E_MEMORY;
   2019             }
   2020             soc_profile_mem_t_init(info->ing_pri_cng_map);
   2021 
   2022             mems_cnt = 0;
   2023             mems[mems_cnt] = mem;
   2024             if(SOC_IS_TRIDENT3X(unit)) {
   2025                 mem_words[mems_cnt] = sizeof(phb_mapping_tbl_1_entry_t) /
   2026                                       sizeof(uint32);
   2027             } else {
   2028             mem_words[mems_cnt] = sizeof(ing_pri_cng_map_entry_t) /
   2029                 sizeof(uint32);
   2030             }
   2031             index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2032             index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2033             if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 
   2034                 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) ||
   2035                 SOC_IS_HURRICANEX(unit) || SOC_IS_TRIUMPH3(unit) ||
   2036                 SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit)) {
   2037                 /* 63 profiles * 16 enitres for tagged packets
   2038                  * entry 1008 to 1070 are 63 profiles for untagged packets */
   2039                 index_max[mems_cnt] = 1007;
   2040             } else if (SOC_IS_TRIUMPH(unit) || SOC_IS_VALKYRIE(unit)) {
   2041                 /* First 53 chunks are hard-wired to physical ports */
   2042                 /* Only the nine remaining are flexible profiles */    
   2043                 index_min[mems_cnt] = 848;
   2044                 index_max[mems_cnt] = 1007;
   2045             }
   2046             mems_cnt++;
   2047 
   2048             mem = ING_UNTAGGED_PHBm;
   2049             if (SOC_MEM_IS_VALID(unit, mem)) {
   2050                 mems[mems_cnt] = mem;
   2051                 mem_words[mems_cnt] = sizeof(ing_untagged_phb_entry_t) /
   2052                     sizeof(uint32);
   2053                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2054                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2055                 mems_cnt++;
   2056             }
   2057             rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2058                                               index_min, index_max, NULL,
   2059                                               mems_cnt, info->ing_pri_cng_map);
   2060             info->ing_pri_cng_map_created = TRUE;
   2061             if (rv < 0) {
   2062                 _bcm_common_free_resource(unit, info);
   2063                 return rv;
   2064             }
   2065         }
   2066     }
   2067 
   2068     if (soc_feature(unit, soc_feature_fcoe)) {
   2069         mem = ING_VFT_PRI_MAPm;
   2070         if (SOC_MEM_IS_VALID(unit, mem)) {
   2071             if (NULL == info->ing_vft_pri_map) {
   2072                 info->ing_vft_pri_map = sal_alloc(sizeof(soc_profile_mem_t),
   2073                                               "ING_VFT_PRI_MAP Profile Mem");
   2074                 if (info->ing_vft_pri_map == NULL) {
   2075                     _bcm_common_free_resource(unit, info);
   2076                     return BCM_E_MEMORY;
   2077                 }
   2078                 soc_profile_mem_t_init(info->ing_vft_pri_map);
   2079 
   2080                 mems_cnt = 0;
   2081                 mems[mems_cnt] = mem;
   2082                 mem_words[mems_cnt] = sizeof(ing_vft_pri_map_entry_t) /
   2083                     sizeof(uint32);
   2084                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2085                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2086                 mems_cnt++;
   2087 
   2088                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2089                         index_min, index_max, NULL, mems_cnt,
   2090                         info->ing_vft_pri_map);
   2091                 info->ing_vft_pri_map_created = TRUE;
   2092                 if (rv < 0) {
   2093                     _bcm_common_free_resource(unit, info);
   2094                     return rv;
   2095                 }
   2096             }
   2097         }
   2098     }
   2099 
   2100     if (soc_mem_index_max(unit, ING_ETAG_PCP_MAPPINGm) > 0) {
   2101 
   2102         mem = ING_ETAG_PCP_MAPPINGm;
   2103         if (SOC_MEM_IS_VALID(unit, mem)) {
   2104             if (NULL == info->ing_l2_vlan_etag_map) {
   2105                 info->ing_l2_vlan_etag_map = sal_alloc(sizeof(soc_profile_mem_t),
   2106                                                   "ING_ETAG_PCP_MAPPING Profile Mem");
   2107                 if (info->ing_l2_vlan_etag_map == NULL) {
   2108                     _bcm_common_free_resource(unit, info);
   2109                     return BCM_E_MEMORY;
   2110                 }
   2111                 soc_profile_mem_t_init(info->ing_l2_vlan_etag_map);
   2112     
   2113                 mems_cnt = 0;
   2114                 mems[mems_cnt] = mem;
   2115                 mem_words[mems_cnt] = sizeof(ing_etag_pcp_mapping_entry_t) /
   2116                     sizeof(uint32);
   2117                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2118                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2119                 mems_cnt++;
   2120 
   2121                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2122                                                   index_min, index_max, NULL,
   2123                                                   mems_cnt, info->ing_l2_vlan_etag_map);
   2124                 info->ing_l2_vlan_etag_map_created = TRUE;
   2125                 if (rv < 0) {
   2126                     _bcm_common_free_resource(unit, info);
   2127                     return rv;
   2128                 }
   2129             }
   2130         }    
   2131     }
   2132 
   2133     if (soc_feature(unit, soc_feature_fcoe)) {
   2134         mem = EGR_VFT_PRI_MAPm;
   2135         if (SOC_MEM_IS_VALID(unit, mem)) {
   2136             if (NULL == info->egr_vft_pri_map) {
   2137                 info->egr_vft_pri_map = sal_alloc(sizeof(soc_profile_mem_t),
   2138                                               "EGR_VFT_PRI_MAP Profile Mem");
   2139                 if (info->egr_vft_pri_map == NULL) {
   2140                     _bcm_common_free_resource(unit, info);
   2141                     return BCM_E_MEMORY;
   2142                 }
   2143                 soc_profile_mem_t_init(info->egr_vft_pri_map);
   2144 
   2145                 mems_cnt = 0;
   2146                 mems[mems_cnt] = mem;
   2147                 mem_words[mems_cnt] = sizeof(egr_vft_pri_map_entry_t) /
   2148                                         sizeof(uint32);
   2149                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2150                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2151                 mems_cnt++;
   2152 
   2153                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2154                         index_min, index_max, NULL, mems_cnt,
   2155                         info->egr_vft_pri_map);
   2156                 info->egr_vft_pri_map_created = TRUE;
   2157                 if (rv < 0) {
   2158                     _bcm_common_free_resource(unit, info);
   2159                     return rv;
   2160                 }
   2161             }
   2162         }
   2163 
   2164         mem = EGR_VSAN_INTPRI_MAPm;
   2165         if (SOC_MEM_IS_VALID(unit, mem)) {
   2166             if (NULL == info->egr_vsan_intpri_map) {
   2167                 info->egr_vsan_intpri_map = sal_alloc(sizeof(soc_profile_mem_t),
   2168                                             "EGR_VSAN_INTPRI_MAP Profile Mem");
   2169                 if (info->egr_vsan_intpri_map == NULL) {
   2170                     _bcm_common_free_resource(unit, info);
   2171                     return BCM_E_MEMORY;
   2172                 }
   2173                 soc_profile_mem_t_init(info->egr_vsan_intpri_map);
   2174                 
   2175                 mems_cnt = 0;
   2176                 mems[mems_cnt] = mem;
   2177                 mem_words[mems_cnt] = sizeof(egr_vsan_intpri_map_entry_t) /
   2178                                             sizeof(uint32);
   2179                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2180                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2181                 mems_cnt++;
   2182 
   2183                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2184                         index_min, index_max, NULL, mems_cnt,
   2185                         info->egr_vsan_intpri_map);
   2186                 info->egr_vsan_intpri_map_created = TRUE;
   2187                 if (rv < 0) {
   2188                     _bcm_common_free_resource(unit, info);
   2189                     return rv;
   2190                 }
   2191             }
   2192         }
   2193     }
   2194 
   2195     if (SOC_IS_TRIDENT3X(unit)) {
   2196         mem = EGR_ZONE_3_DOT1P_MAPPING_TABLE_2m;
   2197         if (SOC_MEM_IS_VALID(unit, mem)) {
   2198             if (NULL == info->egr_l2_vlan_etag_map) {
   2199                 info->egr_l2_vlan_etag_map = sal_alloc(sizeof(soc_profile_mem_t),
   2200                                                   "EGR_ETAG_PCP_MAPPING Profile Mem");
   2201                 if (info->egr_l2_vlan_etag_map == NULL) {
   2202                     _bcm_common_free_resource(unit, info);
   2203                     return BCM_E_MEMORY;
   2204                 }
   2205                 soc_profile_mem_t_init(info->egr_l2_vlan_etag_map);
   2206 
   2207                 mems_cnt = 0;
   2208                 /* outer etag */
   2209                 mems[mems_cnt] = mem;
   2210                 mem_words[mems_cnt] = sizeof(egr_zone_3_dot1p_mapping_table_2_entry_t) /
   2211                                       sizeof(uint32);
   2212                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2213                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2214                 mems_cnt++;
   2215 
   2216                 /* inner etag */
   2217                 mem = EGR_ZONE_1_DOT1P_MAPPING_TABLE_2m;
   2218                 mems[mems_cnt] = mem;
   2219                 mem_words[mems_cnt] = sizeof(egr_zone_1_dot1p_mapping_table_2_entry_t) /
   2220                                       sizeof(uint32);
   2221                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2222                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2223                 mems_cnt++;
   2224 
   2225                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2226                                                   index_min, index_max, NULL,
   2227                                                   mems_cnt, info->egr_l2_vlan_etag_map);
   2228                 if (rv < 0) {
   2229                     _bcm_common_free_resource(unit, info);
   2230                     return rv;
   2231                 }
   2232                 info->egr_l2_vlan_etag_map_created = TRUE;
   2233             }
   2234         }
   2235     } else {
   2236     mem = EGR_ETAG_PCP_MAPPINGm;
   2237     if (SOC_MEM_IS_VALID(unit, mem)) {
   2238         if (NULL == info->egr_l2_vlan_etag_map) {
   2239             info->egr_l2_vlan_etag_map = sal_alloc(sizeof(soc_profile_mem_t),
   2240                                               "EGR_ETAG_PCP_MAPPING Profile Mem");
   2241             if (info->egr_l2_vlan_etag_map == NULL) {
   2242                 _bcm_common_free_resource(unit, info);
   2243                 return BCM_E_MEMORY;
   2244             }
   2245             soc_profile_mem_t_init(info->egr_l2_vlan_etag_map);
   2246 
   2247             mems_cnt = 0;
   2248             mems[mems_cnt] = mem;
   2249             mem_words[mems_cnt] = sizeof(egr_etag_pcp_mapping_entry_t) /
   2250                 sizeof(uint32);
   2251             index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2252             index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2253             mems_cnt++;
   2254 
   2255             rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2256                                               index_min, index_max, NULL,
   2257                                               mems_cnt, info->egr_l2_vlan_etag_map);
   2258             if (rv < 0) {
   2259                 _bcm_common_free_resource(unit, info);
   2260                 return rv;
   2261             }
   2262                 info->egr_l2_vlan_etag_map_created = TRUE;
   2263             }
   2264         }
   2265     }
   2266 
   2267     if (soc_feature(unit, soc_feature_fcoe)) {
   2268         mem = EGR_VFT_FIELDS_PROFILEm;
   2269         if (SOC_MEM_IS_VALID(unit, mem)) {
   2270             if (NULL == info->egr_vft_fields) {
   2271                 info->egr_vft_fields = sal_alloc(sizeof(soc_profile_mem_t),
   2272                                             "EGR_VFT_FIELDS_PROFILE Mem");
   2273                 if (info->egr_vft_fields == NULL) {
   2274                     _bcm_common_free_resource(unit, info);
   2275                     return BCM_E_MEMORY;
   2276                 }
   2277                 soc_profile_mem_t_init(info->egr_vft_fields);
   2278 
   2279                 mems_cnt = 0;
   2280                 mems[mems_cnt] = mem;
   2281                 mem_words[mems_cnt] = sizeof(egr_vft_fields_profile_entry_t) /
   2282                                         sizeof(uint32);
   2283                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2284                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2285                 mems_cnt++;
   2286 
   2287                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2288                         index_min, index_max, NULL, mems_cnt,
   2289                         info->egr_vft_fields);
   2290                 info->egr_vft_fields_created = TRUE;
   2291                 if (rv < 0) {
   2292                     _bcm_common_free_resource(unit, info);
   2293                     return rv;
   2294                 }
   2295             }
   2296         }
   2297     }
   2298 
   2299     mem = EGR_MPLS_PRI_MAPPINGm;
   2300 #ifdef BCM_TRIDENT3_SUPPORT
   2301     if (SOC_IS_TRIDENT3X(unit)) {
   2302         /* TRIDENT3 use Flex QoS architecture - memory binding and mappings are 
   2303            completely different from old design
   2304          */
   2305         /* Init per SOC control structure */
   2306         bcm_td3_egr_mpls_combo_map_info_init(unit);
   2307 
   2308         /* Create memory binding */
   2309         rv = bcm_td3_egr_mpls_combo_map_create(unit, 
   2310                                           &info->egr_mpls_combo_map_created,
   2311                                           &info->egr_mpls_combo_map);
   2312        if (rv < 0) {
   2313            _bcm_common_free_resource(unit, info);
   2314            return rv;
   2315        }
   2316 
   2317        /* Now fill in the defaults MPLS and L2 mapping */
   2318        rv = bcm_td3_egr_mpls_combo_map_default(unit);
   2319        if (rv < 0) {
   2320            _bcm_common_free_resource(unit, info);
   2321            return rv;
   2322        }
   2323     } else
   2324 #endif /* End of BCM_TRIDENT3_SUPPORT */
   2325 
   2326     if (SOC_MEM_IS_VALID(unit, mem)) {
   2327         if (NULL == info->egr_mpls_combo_map) {
   2328             info->egr_mpls_combo_map = sal_alloc(sizeof(soc_profile_mem_t),
   2329                                                  "MPLS Combo Profile Mem");
   2330             if (info->egr_mpls_combo_map == NULL) {
   2331                 _bcm_common_free_resource(unit, info);
   2332                 return BCM_E_MEMORY;
   2333             }
   2334             soc_profile_mem_t_init(info->egr_mpls_combo_map);
   2335 
   2336             /* Prevent entries from moving around in the tables */
   2337             info->egr_mpls_combo_map->flags = SOC_PROFILE_MEM_F_NO_SHARE;
   2338 
   2339             mems_cnt = 0;
   2340             mems[mems_cnt] = mem;
   2341             mem_words[mems_cnt] = sizeof(egr_mpls_pri_mapping_entry_t) /
   2342                 sizeof(uint32);
   2343             mems_cnt++;
   2344             if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) {
   2345                 mems[mems_cnt] = EGR_MPLS_EXP_MAPPING_1m;
   2346                 mem_words[mems_cnt] = sizeof(egr_mpls_exp_mapping_1_entry_t) /
   2347                     sizeof(uint32);
   2348                 mems_cnt++;
   2349             }
   2350             if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m)) {
   2351                 mems[mems_cnt] = EGR_MPLS_EXP_MAPPING_2m;
   2352                 mem_words[mems_cnt] = sizeof(egr_mpls_exp_mapping_2_entry_t) /
   2353                     sizeof(uint32);
   2354                 mems_cnt++;
   2355             }
   2356             rv = soc_profile_mem_create(unit, mems, mem_words, mems_cnt,
   2357                                         info->egr_mpls_combo_map);
   2358             info->egr_mpls_combo_map_created = TRUE;
   2359             if (rv < 0) {
   2360                 _bcm_common_free_resource(unit, info);
   2361                 return rv;
   2362             }
   2363             /* Create a set of default 1-to-1 internal priority to packet priority
   2364              * mapping profiles for reference by egress objects such as egr_vlan_xlate
   2365              * Must create first to get the 0 indexed profile. 
   2366              */
   2367             if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   2368                 egr_mpls_pri_mapping_entry_t egr_mpls_pri_map[64];
   2369                 egr_mpls_exp_mapping_1_entry_t egr_mpls_exp_map1[64];
   2370                 egr_mpls_exp_mapping_2_entry_t egr_mpls_exp_map2[64];
   2371                 uint32 index;
   2372                 int int_pri;
   2373                 int cng;
   2374                 void *entries[3];
   2375 
   2376                 mem = EGR_MPLS_PRI_MAPPINGm;
   2377                 mems_cnt = 0;
   2378                 if (SOC_MEM_IS_VALID(unit, mem)) {
   2379                     sal_memset(egr_mpls_pri_map, 0, sizeof(egr_mpls_pri_map));
   2380                     for (int_pri = 0; int_pri < 16; int_pri++) {
   2381                         for (cng = 0; cng < 4; cng++) {
   2382                             soc_mem_field32_set(unit, mem, 
   2383                                 (uint32 *)&egr_mpls_pri_map[(int_pri << 2) | cng],
   2384                                 NEW_PRIf, int_pri > 7? 7: int_pri);
   2385                             soc_mem_field32_set(unit, mem, 
   2386                                 (uint32 *)&egr_mpls_pri_map[(int_pri << 2) | cng],
   2387                                 NEW_CFIf, cng > 1? 1:cng);
   2388                         }
   2389                     }
   2390                     entries[mems_cnt++] = egr_mpls_pri_map;
   2391                 }
   2392 
   2393                 mem = EGR_MPLS_EXP_MAPPING_1m;
   2394                     sal_memset(egr_mpls_exp_map1, 0, sizeof(egr_mpls_exp_map1));
   2395                 if (SOC_MEM_IS_VALID(unit, mem)) {
   2396                     if (!SOC_IS_TRIDENT3X(unit)) {
   2397                 for (int_pri = 0; int_pri < 16; int_pri++) {
   2398                     for (cng = 0; cng < 4; cng++) {
   2399                         soc_mem_field32_set(unit, mem, 
   2400                             (uint32 *)&egr_mpls_exp_map1[(int_pri << 2) | cng],
   2401                             PRIf, int_pri > 7? 7: int_pri);
   2402                         soc_mem_field32_set(unit, mem, 
   2403                             (uint32 *)&egr_mpls_exp_map1[(int_pri << 2) | cng],
   2404                             CFIf, cng > 1?1:cng);
   2405                     }
   2406                 }
   2407                     }
   2408                 entries[mems_cnt++] = egr_mpls_exp_map1;
   2409                 }
   2410 
   2411                 mem = EGR_MPLS_EXP_MAPPING_2m;
   2412                     sal_memset(egr_mpls_exp_map2, 0, sizeof(egr_mpls_exp_map2));
   2413                 if (SOC_MEM_IS_VALID(unit, mem)) {
   2414                     if (!SOC_IS_TRIDENT3X(unit)) {
   2415                 for (int_pri = 0; int_pri < 16; int_pri++) {
   2416                     for (cng = 0; cng < 4; cng++) {
   2417                         soc_mem_field32_set(unit, mem,
   2418                             (uint32 *)&egr_mpls_exp_map2[(int_pri << 2) | cng],
   2419                             PRIf, int_pri > 7? 7: int_pri);
   2420                         soc_mem_field32_set(unit, mem, 
   2421                             (uint32 *)&egr_mpls_exp_map2[(int_pri << 2) | cng],
   2422                             CFIf, cng > 1?1:cng);
   2423                     }
   2424                 }
   2425                     }
   2426                 entries[mems_cnt++] = egr_mpls_exp_map2;
   2427                 }
   2428 
   2429                 BCM_IF_ERROR_RETURN
   2430                     (_bcm_egr_mpls_combo_map_entry_add(unit, entries, 64,
   2431                                                        &index));
   2432             }
   2433         }
   2434     }
   2435 
   2436     mem = SOC_IS_TRIDENT3X(unit) ? PHB_MAPPING_TBL_2m : DSCP_TABLEm;
   2437     if (SOC_MEM_IS_VALID(unit, mem)) {
   2438         if (NULL == info->dscp_table) {
   2439             info->dscp_table = sal_alloc(sizeof(soc_profile_mem_t),
   2440                                          "DSCP_TABLE Profile Mem");
   2441             if (info->dscp_table == NULL) {
   2442                 _bcm_common_free_resource(unit, info);
   2443                 return BCM_E_MEMORY;
   2444             }
   2445             soc_profile_mem_t_init(info->dscp_table);
   2446             if(SOC_IS_TRIDENT3X(unit)) {
   2447                 entry_words = sizeof(phb_mapping_tbl_2_entry_t) / sizeof(uint32);
   2448             } else {
   2449             entry_words = sizeof(dscp_table_entry_t) / sizeof(uint32);
   2450             }
   2451             index_min[0] = soc_mem_index_min(unit, mem);
   2452             index_max[0] = soc_mem_index_max(unit, mem);
   2453             mems[0] = mem;
   2454             mem_words[0] = entry_words;
   2455             if (SOC_IS_TRIUMPH(unit) || SOC_IS_VALKYRIE(unit)) {
   2456                 /* First 53 chunks are hard-wired to physical ports */
   2457                 /* Only the nine remaining are flexible profiles */
   2458                 index_min[0] = 3392;
   2459             }
   2460             if (SOC_IS_KATANA(unit) || SOC_IS_TRIUMPH3(unit) ||
   2461                 SOC_IS_TRIDENT(unit)) {
   2462                 index_min[0] = SOC_PORT_MAX(unit,all) * 64;
   2463             }
   2464             rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2465                                               index_min, index_max, NULL, 1,
   2466                                               info->dscp_table);
   2467             info->dscp_table_created = TRUE;
   2468             if (rv < 0) {
   2469                 _bcm_common_free_resource(unit, info);
   2470                 return rv;
   2471             }
   2472         }
   2473     }
   2474 
   2475     if(soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   2476         /* Create profile table cache (or re-init if it already exists) */
   2477         
   2478         mem = SOC_IS_TRIDENT3X(unit) ? EGR_ZONE_1_DOT1P_MAPPING_TABLE_4m:EGR_PRI_CNG_MAPm;
   2479         if (SOC_MEM_IS_VALID(unit, mem)) {
   2480             if (NULL == info->egr_qos_profile) {
   2481                 egr_qos_l2_map_entry_t egr_pri_cng_map[64];
   2482                 egr_qos_l3_map_entry_t egr_dscp_table[64];
   2483                 soc_field_t mem_field;
   2484                 uint32 index;
   2485                 int int_pri;
   2486                 int cng;
   2487                 int dscp;
   2488                 void *entries[3];
   2489                 int i;
   2490                 egr_pri_cng_map_entry_t egr_pri_cng_map_mask;
   2491                 egr_dscp_table_entry_t egr_dscp_table_mask;
   2492                 egr_zone_1_dot1p_mapping_table_4_entry_t egr_zone_1_dot1p_mapping_table_4_mask;
   2493                 egr_zone_4_qos_mapping_table_entry_t egr_zone_4_qos_mapping_table_mask;
   2494                 egr_zone_2_qos_mapping_table_entry_t egr_zone_2_qos_mapping_table_mask;
   2495 
   2496                 info->egr_qos_profile = sal_alloc(sizeof(soc_profile_mem_t),
   2497                                                 "MISC_PORT_PROFILE_TABLE Mem");
   2498                 if (info->egr_qos_profile == NULL) {
   2499                     _bcm_common_free_resource(unit, info);
   2500                     return BCM_E_MEMORY;
   2501                 }
   2502                 soc_profile_mem_t_init(info->egr_qos_profile);
   2503 
   2504                 mems_cnt = 0;
   2505                 if (SOC_IS_TRIDENT3X(unit)) {
   2506                     mem = EGR_ZONE_1_DOT1P_MAPPING_TABLE_4m;
   2507                     entries[mems_cnt] = &egr_zone_1_dot1p_mapping_table_4_mask;
   2508                     sal_memset(&egr_zone_1_dot1p_mapping_table_4_mask, 0xff,
   2509                                sizeof(egr_zone_1_dot1p_mapping_table_4_mask));
   2510                 } else {
   2511                     mem = EGR_PRI_CNG_MAPm;
   2512                     entries[mems_cnt] = &egr_pri_cng_map_mask;
   2513                     sal_memset(&egr_pri_cng_map_mask, 0xff,
   2514                                sizeof(egr_pri_cng_map_mask));
   2515                 }
   2516 
   2517                 mems[mems_cnt] = mem;
   2518                 mem_words[mems_cnt] = soc_mem_entry_words(unit,mem);
   2519                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2520                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2521                 mems_cnt++;
   2522 
   2523                 if (SOC_IS_TRIDENT3X(unit)) {
   2524                     mem = EGR_ZONE_4_QOS_MAPPING_TABLEm;
   2525                     entries[mems_cnt] = &egr_zone_4_qos_mapping_table_mask;
   2526                     sal_memset(&egr_zone_4_qos_mapping_table_mask, 0xff,
   2527                                sizeof(egr_zone_4_qos_mapping_table_mask));
   2528                 } else {
   2529                 mem = EGR_DSCP_TABLEm;
   2530                     entries[mems_cnt] = &egr_dscp_table_mask;
   2531                     sal_memset(&egr_dscp_table_mask, 0xff,
   2532                                sizeof(egr_dscp_table_mask));
   2533                 }
   2534 
   2535                 if (SOC_MEM_IS_VALID(unit, mem)) {
   2536                     mems[mems_cnt] = mem;
   2537                     mem_words[mems_cnt] = soc_mem_entry_words(unit,mem);;
   2538                     index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2539                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2540                     mems_cnt++;
   2541                 }
   2542 
   2543                 if (SOC_IS_TRIDENT3X(unit)) {
   2544                     mem = EGR_ZONE_2_QOS_MAPPING_TABLEm;
   2545                     entries[mems_cnt] = &egr_zone_2_qos_mapping_table_mask;
   2546                     sal_memset(&egr_zone_2_qos_mapping_table_mask, 0xff,
   2547                                sizeof(egr_zone_2_qos_mapping_table_mask));
   2548                     if (SOC_MEM_IS_VALID(unit, mem)) {
   2549                         mems[mems_cnt] = mem;
   2550                         mem_words[mems_cnt] = soc_mem_entry_words(unit,mem);;
   2551                         index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2552                         index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2553                         mems_cnt++;
   2554                     }
   2555                 }
   2556 
   2557                 for (i = 0; i < mems_cnt; i++) {
   2558                     if (SOC_MEM_FIELD_VALID(unit, mems[i], ECCPf)) {
   2559                         soc_mem_field32_set(unit, mems[i], entries[i],
   2560                                             ECCPf, 0);
   2561                     } else if (SOC_MEM_FIELD_VALID(unit, mems[i],
   2562                                EVEN_PARITYf)) {
   2563                         soc_mem_field32_set(unit, mems[i], entries[i],
   2564                                             EVEN_PARITYf, 0);
   2565                     }
   2566                 }
   2567                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2568                                                   index_min, index_max, entries,
   2569                                                   mems_cnt, info->egr_qos_profile);
   2570 
   2571                 if (rv < 0) {
   2572                     _bcm_common_free_resource(unit, info);
   2573                     return rv;
   2574                 }
   2575 
   2576                 
   2577                 info->egr_qos_profile_created = TRUE;
   2578 
   2579                 /* Create a set of default 1-to-1 internal priority to packet priority
   2580                  * mapping profiles for reference by egress objects
   2581                  * Must create first to get the 0 indexed profile. 
   2582                  */
   2583                 if (SOC_IS_TRIDENT3X(unit)) {
   2584                     mem = EGR_ZONE_1_DOT1P_MAPPING_TABLE_4m;
   2585                 } else {
   2586                 mem = EGR_PRI_CNG_MAPm;
   2587                 }
   2588                 mems_cnt = 0;
   2589                 if (SOC_MEM_IS_VALID(unit, mem)) {
   2590                     sal_memset(egr_pri_cng_map, 0, sizeof(egr_pri_cng_map));
   2591                     for (int_pri = 0; int_pri < 16; int_pri++) {
   2592                         for (cng = 0; cng < 4; cng++) {
   2593                             soc_mem_field32_set(unit, mem, 
   2594                                 (uint32 *)((char *)egr_pri_cng_map + 
   2595                                                    soc_mem_entry_words(unit, mem) * 
   2596                                                    sizeof(uint32) * (int_pri << 2 | cng)),
   2597                                 PRIf, int_pri > 7? 7: int_pri);
   2598                             soc_mem_field32_set(unit, mem, 
   2599                                 (uint32 *)((char *)egr_pri_cng_map +
   2600                                                    soc_mem_entry_words(unit, mem) *           
   2601                                                    sizeof(uint32) * (int_pri << 2 | cng)),
   2602                                 CFIf, cng > 1? 1:cng);
   2603                         }
   2604                     }
   2605                     entries[mems_cnt++] = egr_pri_cng_map;
   2606                 }
   2607 
   2608                 if (SOC_IS_TRIDENT3X(unit)) {
   2609                     mem = EGR_ZONE_4_QOS_MAPPING_TABLEm;
   2610                     mem_field = QOSf; 
   2611                 } else {
   2612                 mem = EGR_DSCP_TABLEm;
   2613                     mem_field = DSCPf;
   2614                 }
   2615                 if (SOC_MEM_IS_VALID(unit, mem)) {
   2616                     sal_memset(egr_dscp_table, 0, sizeof(egr_dscp_table));
   2617                     dscp = 0;
   2618                     for (int_pri = 0; int_pri < 16; int_pri++) {
   2619                         for (cng = 0; cng < 4; cng++) {
   2620                             soc_mem_field32_set(unit, mem, 
   2621                                 (uint32 *)((char *)egr_dscp_table +
   2622                                            soc_mem_entry_words(unit, mem) *
   2623                                            sizeof(uint32) * (int_pri << 2 | cng)),
   2624                                 mem_field, (dscp++));
   2625                         }
   2626                     }
   2627                     entries[mems_cnt++] = egr_dscp_table;
   2628 
   2629                     if (SOC_IS_TRIDENT3X(unit)) {
   2630                         if (SOC_MEM_IS_VALID(unit,
   2631                                       EGR_ZONE_2_QOS_MAPPING_TABLEm)) {
   2632                             /* same setting for EGR_ZONE_2_QOS_MAPPING_TABLEm*/
   2633                             entries[mems_cnt++] = egr_dscp_table;
   2634                         }
   2635                     }
   2636                 }
   2637 
   2638                 BCM_IF_ERROR_RETURN 
   2639                     (_bcm_egr_qos_profile_entry_add(unit, entries, 64,
   2640                                                        &index));
   2641             }
   2642         }
   2643     } else {
   2644         mems_cnt = 0;
   2645         if (SOC_IS_TRIDENT3X(unit)) {
   2646             mem = EGR_ZONE_4_QOS_MAPPING_TABLEm;
   2647         } else {
   2648         mem = EGR_DSCP_TABLEm;
   2649         }
   2650 
   2651         if (SOC_MEM_IS_VALID(unit, mem)) {
   2652             mems[mems_cnt] = mem;
   2653             mem_words[mems_cnt] = soc_mem_entry_words(unit,mem); 
   2654             mems_cnt++;
   2655 
   2656             /* One dscp profile for EGR_ZONE_2/4_QOS_MAPPING_TABLEs 
   2657              * Zone2 for outer L3 header and Zone4 for inner L3 
   2658              */
   2659             if (SOC_IS_TRIDENT3X(unit)) {
   2660                 mem = EGR_ZONE_2_QOS_MAPPING_TABLEm;
   2661                 if (SOC_MEM_IS_VALID(unit, mem)) {
   2662                     mems[mems_cnt] = mem;
   2663                     mem_words[mems_cnt] = soc_mem_entry_words(unit,mem); 
   2664                     mems_cnt++;
   2665                 }
   2666             }
   2667 
   2668             if (NULL == info->egr_dscp_table) {
   2669                 info->egr_dscp_table = sal_alloc(sizeof(soc_profile_mem_t),
   2670                                                  "EGR_DSCP_TABLE Profile Mem");
   2671                 if (info->egr_dscp_table == NULL) {
   2672                     _bcm_common_free_resource(unit, info);
   2673                     return BCM_E_MEMORY;
   2674                 }
   2675                 soc_profile_mem_t_init(info->egr_dscp_table);
   2676 
   2677                 rv = soc_profile_mem_create(unit, mems, mem_words, mems_cnt,
   2678                                             info->egr_dscp_table);
   2679                 info->egr_dscp_table_created = TRUE;
   2680                 if (rv < 0) {
   2681                     _bcm_common_free_resource(unit, info);
   2682                     return rv;
   2683                 }
   2684             }
   2685         }
   2686     }
   2687 
   2688     if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype != soc_portreg &&
   2689         SOC_REG_INFO(unit, IGMP_MLD_PKT_CONTROLr).regtype != soc_portreg) {
   2690         if (info->prot_pkt_ctrl == NULL) {
   2691             soc_reg_t reg[2];
   2692             info->prot_pkt_ctrl = 
   2693                 sal_alloc(sizeof(soc_profile_reg_t),
   2694                           "PROTOCOL_PKT_CONTROL Profile Reg");
   2695             if (info->prot_pkt_ctrl == NULL) {
   2696                 _bcm_common_free_resource(unit, info);
   2697                 return BCM_E_MEMORY;
   2698             }
   2699             soc_profile_reg_t_init(info->prot_pkt_ctrl);
   2700 
   2701             reg[0] = PROTOCOL_PKT_CONTROLr;
   2702             reg[1] = IGMP_MLD_PKT_CONTROLr;
   2703             rv = soc_profile_reg_create(unit, reg, 2,
   2704                                         info->prot_pkt_ctrl);
   2705             info->prot_pkt_ctrl_created = TRUE;
   2706             if (rv < 0) {
   2707                 _bcm_common_free_resource(unit, info);
   2708                 return rv;
   2709             }
   2710         }
   2711     }
   2712 #ifdef BCM_TRIDENT_SUPPORT
   2713     mem = ING_OUTER_DOT1P_MAPPING_TABLEm;
   2714     if (SOC_MEM_IS_VALID(unit, mem)) {
   2715         uint32 idx, max;
   2716         ing_outer_dot1p_mapping_table_entry_t dot1p[16];
   2717         void *entries[1];
   2718         int base = 0;
   2719 
   2720         if (NULL == info->ing_outer_dot1p) {
   2721             info->ing_outer_dot1p = sal_alloc(sizeof(soc_profile_mem_t),
   2722                                "ING_OUTER_DOT1P_MAPPING_TABLE Profile Mem");
   2723             if (info->ing_outer_dot1p == NULL) {
   2724                 _bcm_common_free_resource(unit, info);
   2725                 return BCM_E_MEMORY;
   2726             }
   2727             soc_profile_mem_t_init(info->ing_outer_dot1p);
   2728 
   2729             entry_words = sizeof(ing_outer_dot1p_mapping_table_entry_t) / 
   2730                           sizeof(uint32);
   2731             rv = soc_profile_mem_create(unit, &mem, &entry_words, 1,
   2732                                         info->ing_outer_dot1p);
   2733             info->ing_outer_dot1p_created = TRUE;
   2734             if (rv < 0) {
   2735                 _bcm_common_free_resource(unit, info);
   2736                 return rv;
   2737             }
   2738         }
   2739         /* Add default profile entry - identity mapping */
   2740         idx = soc_mem_index_min(unit, mem);
   2741         max = 16;
   2742         sal_memset(&dot1p, 0, sizeof(dot1p));
   2743         while (BCM_SUCCESS(rv) && idx < max) {
   2744             soc_mem_field32_set(unit, mem, &dot1p[idx], NEW_CFIf, idx & 1);
   2745             soc_mem_field32_set(unit, mem, &dot1p[idx], NEW_DOT1Pf, 
   2746                                 (idx >> 1) & 7);
   2747             idx++;
   2748         }
   2749         entries[0] = &dot1p;
   2750         BCM_IF_ERROR_RETURN
   2751             (soc_profile_mem_add(unit, ING_OUTER_DOT1P(unit), entries, 16, 
   2752                                  (uint32 *)&base));
   2753     }
   2754 #endif /* BCM_TRIDENT_SUPPORT */
   2755 #ifdef BCM_TRIUMPH2_SUPPORT
   2756     if (SOC_IS_TRIUMPH2(unit) || SOC_IS_VALKYRIE2(unit) ||
   2757         SOC_IS_HURRICANEX(unit) || SOC_IS_TRIUMPH3(unit) ||
   2758         SOC_IS_APOLLO(unit) || SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
   2759         SOC_IS_ENDURO(unit) || SOC_IS_GREYHOUND(unit) || 
   2760         SOC_IS_GREYHOUND2(unit)) {
   2761 #ifdef BCM_TRIDENT3_SUPPORT
   2762         if (SOC_IS_TRIDENT3X(unit)) {
   2763             rv = _bcm_td3_port_phb_map_tab1_default_entry_add
   2764                      (unit, info->ing_pri_cng_map);
   2765         } else
   2766 #endif
   2767         {
   2768         rv = _bcm_tr2_ing_pri_cng_map_default_entry_add
   2769             (unit, info->ing_pri_cng_map);
   2770         }
   2771         if (BCM_FAILURE(rv)) {
   2772             _bcm_common_free_resource(unit, info);
   2773             return rv;
   2774         }
   2775     }
   2776 
   2777 #ifdef BCM_TRIUMPH3_SUPPORT
   2778     mem = ING_L3_NEXT_HOP_ATTRIBUTE_1m;
   2779     if (SOC_MEM_IS_VALID(unit, mem)) {
   2780         if (NULL == info->ing_l3_nh_attribute) {
   2781             info->ing_l3_nh_attribute = sal_alloc(sizeof(soc_profile_mem_t),
   2782                                      "ING_L3_NEXT_HOP_ATTRIBUTE_1 Profile Mem");
   2783             if (info->ing_l3_nh_attribute == NULL) {
   2784                 _bcm_common_free_resource(unit, info);
   2785                 return BCM_E_MEMORY;
   2786             }
   2787             soc_profile_mem_t_init(info->ing_l3_nh_attribute);
   2788 
   2789             entry_words = sizeof(ing_l3_next_hop_attribute_1_entry_t) /
   2790                                  sizeof(uint32);
   2791 
   2792             rv = soc_profile_mem_create(unit, &mem, &entry_words, 1,
   2793                                         info->ing_l3_nh_attribute);
   2794             info->ing_l3_nh_attribute_created = TRUE;
   2795             if (rv < 0) {
   2796                 _bcm_common_free_resource(unit, info);
   2797                 return rv;
   2798             }
   2799         }
   2800     }
   2801 #endif /* BCM_TRIUMPH3_SUPPORT */
   2802 
   2803 #ifdef BCM_TRIDENT2_SUPPORT
   2804     mem = L3_IIF_PROFILEm;
   2805     if (SOC_MEM_IS_VALID(unit, mem)) {
   2806         if (NULL == info->l3_iif_profile) {
   2807             void *entries[1];
   2808             iif_profile_entry_t l3_iif_profile;
   2809 
   2810             info->l3_iif_profile = sal_alloc(sizeof(soc_profile_mem_t),
   2811                                      "L3_IIF_PROFILE Mem");
   2812             if (info->l3_iif_profile == NULL) {
   2813                 _bcm_common_free_resource(unit, info);
   2814                 return BCM_E_MEMORY;
   2815             }
   2816             soc_profile_mem_t_init(info->l3_iif_profile);
   2817 
   2818             entry_words = soc_mem_entry_words(unit, mem);
   2819 
   2820             index_min[0] = soc_mem_index_min(unit, mem);
   2821             index_max[0] = soc_mem_index_max(unit, mem);
   2822             mems[0] = mem;
   2823             mem_words[0] = entry_words;
   2824 
   2825             entries[0] = &l3_iif_profile;
   2826             sal_memset(&l3_iif_profile, 0xff, sizeof(iif_profile_entry_t));
   2827 
   2828             if (soc_mem_field_valid(unit, L3_IIF_PROFILEm, ECCPf)) {
   2829                 soc_mem_field32_set(unit, L3_IIF_PROFILEm, &l3_iif_profile,
   2830                                     ECCPf, 0);
   2831             } else {
   2832                 if (soc_mem_field_valid(unit, L3_IIF_PROFILEm, EVEN_PARITYf)) {
   2833             soc_mem_field32_set(unit, L3_IIF_PROFILEm, &l3_iif_profile,
   2834                                 EVEN_PARITYf, 0);
   2835             }
   2836             }
   2837 
   2838             rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2839                                               index_min, index_max, entries, 1,
   2840                                         info->l3_iif_profile);
   2841             info->l3_iif_profile_created = TRUE;
   2842             if (rv < 0) {
   2843                 _bcm_common_free_resource(unit, info);
   2844                 return rv;
   2845             }
   2846         }
   2847     }
   2848     mem = IP_OPTION_CONTROL_PROFILE_TABLEm;
   2849     if (SOC_MEM_IS_VALID(unit, mem)) {
   2850         if (NULL == info->l3_ip4_options_profile) {
   2851             info->l3_ip4_options_profile = sal_alloc(sizeof(soc_profile_mem_t),
   2852                                          "IP_OPTION_CONTROL_PROFILE_TABLEm Profile Mem");
   2853             if (info->l3_ip4_options_profile == NULL) {
   2854                 _bcm_common_free_resource(unit, info);
   2855                 return BCM_E_MEMORY;
   2856             }
   2857             soc_profile_mem_t_init(info->l3_ip4_options_profile);
   2858 
   2859             entry_words = 1;
   2860             index_min[0] = soc_mem_index_min(unit, mem);
   2861             index_max[0] = soc_mem_index_max(unit, mem);
   2862             mems[0] = mem;
   2863             mem_words[0] = entry_words;
   2864             rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2865                                               index_min, index_max, NULL, 1,
   2866                                               info->l3_ip4_options_profile);
   2867             info->l3_ip4_options_profile_created = TRUE;
   2868             if (rv < 0) {
   2869                 _bcm_common_free_resource(unit, info);
   2870                 return rv;
   2871             }
   2872         }
   2873     }
   2874 
   2875     if (soc_feature(unit, soc_feature_fcoe)) {
   2876         mem = FC_MAP_PROFILEm;
   2877         if (SOC_MEM_IS_VALID(unit, mem)) {
   2878             if (NULL == info->fc_map_profile) {
   2879                 info->fc_map_profile = sal_alloc(sizeof(soc_profile_mem_t),
   2880                                             "FC MAP PROFILE Mem");
   2881                 if (info->fc_map_profile == NULL) {
   2882                     _bcm_common_free_resource(unit, info);
   2883                     return BCM_E_MEMORY;
   2884                 }
   2885                 soc_profile_mem_t_init(info->fc_map_profile);
   2886 
   2887                 entry_words = 1;
   2888                 index_min[0] = soc_mem_index_min(unit, mem);
   2889                 index_max[0] = soc_mem_index_max(unit, mem);
   2890                 mems[0] = mem;
   2891                 mem_words[0] = entry_words;
   2892                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2893                         index_min, index_max, NULL, 1, info->fc_map_profile);
   2894                 info->fc_map_profile_created = TRUE;
   2895                 if (rv < 0) {
   2896                     _bcm_common_free_resource(unit, info);
   2897                     return rv;
   2898                 }
   2899             }
   2900         }
   2901     }
   2902 
   2903 #endif /* BCM_TRIDENT2_SUPPORT */
   2904 
   2905 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   2906     mem = VFI_PROFILEm;
   2907     if (soc_feature(unit, soc_feature_vfi_profile)) {
   2908         uint32 index;
   2909         void *entries[3];
   2910         vfi_profile_entry_t vfi_profile_entry;
   2911         vfi_profile_2_entry_t vfi_profile_2_entry;
   2912 
   2913         if (NULL == info->vfi_profile) {
   2914             info->vfi_profile = sal_alloc(sizeof(soc_profile_mem_t),
   2915                                           "VFI_PROFILE Mem");
   2916             if (info->vfi_profile == NULL) {
   2917                 _bcm_common_free_resource(unit, info);
   2918                 return BCM_E_MEMORY;
   2919             }
   2920             /*
   2921              * Mark the profile as created so _bcm_common_free_resource()
   2922              * can free the allocated memory on error.
   2923              */
   2924             info->vfi_profile_created = TRUE;
   2925 
   2926             soc_profile_mem_t_init(info->vfi_profile);
   2927 
   2928             mems_cnt = 0;
   2929             mems[mems_cnt] = mem;
   2930             mem_words[mems_cnt] = soc_mem_entry_words(unit, mem);
   2931             index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2932             index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2933             mems_cnt++;
   2934 
   2935             if (soc_feature(unit, soc_feature_vfi_combo_profile)) {
   2936                 mem = VFI_PROFILE_2m;
   2937                 mems[mems_cnt] = mem;
   2938                 mem_words[mems_cnt] = soc_mem_entry_words(unit, mem);
   2939                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   2940                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   2941                 mems_cnt++;
   2942             }
   2943 
   2944             rv = soc_profile_mem_index_create(unit, mems, mem_words,
   2945                                               index_min, index_max, NULL,
   2946                                               mems_cnt,
   2947                                         info->vfi_profile);
   2948             if (rv < 0) {
   2949                 _bcm_common_free_resource(unit, info);
   2950                 return rv;
   2951             }
   2952         }
   2953 
   2954         entries[0] = &vfi_profile_entry;
   2955         if (soc_feature(unit, soc_feature_vfi_combo_profile)) {
   2956             entries[1] = &vfi_profile_2_entry;
   2957         }
   2958         sal_memset(&vfi_profile_entry, 0, sizeof(vfi_profile_entry_t));
   2959         sal_memset(&vfi_profile_2_entry, 0, sizeof(vfi_profile_2_entry_t));
   2960         soc_mem_field32_set(unit, VFI_PROFILEm, &vfi_profile_entry, EN_IFILTERf, 1);
   2961 
   2962         /* Create/Reserve profile 0 for defaults */
   2963         rv = soc_profile_mem_add(unit, info->vfi_profile, entries, 1, &index);
   2964         SOC_IF_ERROR_RETURN(rv);
   2965     }
   2966 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   2967 
   2968 
   2969    if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
   2970     if (soc_feature(unit, soc_feature_gport_service_counters)) {
   2971         /* Initialize flex stats */
   2972         BCM_IF_ERROR_RETURN
   2973             (_bcm_esw_flex_stat_init(unit, _bcmFlexStatTypeGport));
   2974         BCM_IF_ERROR_RETURN
   2975             (_bcm_esw_flex_stat_init(unit, _bcmFlexStatTypeService));
   2976         BCM_IF_ERROR_RETURN
   2977             (_bcm_esw_flex_stat_init(unit, _bcmFlexStatTypeEgressGport));
   2978         BCM_IF_ERROR_RETURN
   2979             (_bcm_esw_flex_stat_init(unit, _bcmFlexStatTypeEgressService));
   2980     }
   2981    }
   2982 #endif /* BCM_TRIUMPH2_SUPPORT */
   2983 #ifdef BCM_KATANA_SUPPORT
   2984     mem = ING_QUEUE_OFFSET_MAPPING_TABLEm;
   2985     if (SOC_MEM_IS_VALID(unit, mem)) {
   2986         if (NULL == info->offset_map_table) {
   2987             info->offset_map_table = sal_alloc(sizeof(soc_profile_mem_t),
   2988                                          "OFFSET_MAP_TABLE Profile Mem");
   2989             if (info->offset_map_table == NULL) {
   2990                 _bcm_common_free_resource(unit, info);
   2991                 return BCM_E_MEMORY;
   2992             }
   2993             soc_profile_mem_t_init(info->offset_map_table);
   2994 
   2995             entry_words = 1;
   2996             index_min[0] = soc_mem_index_min(unit, mem);
   2997             index_max[0] = soc_mem_index_max(unit, mem);
   2998             mems[0] = mem;
   2999             mem_words[0] = entry_words;
   3000             rv = soc_profile_mem_index_create(unit, mems, mem_words,
   3001                                               index_min, index_max, NULL, 1,
   3002                                               info->offset_map_table);
   3003             info->ing_queue_offset_map_created = TRUE;
   3004             if (rv < 0) {
   3005                 _bcm_common_free_resource(unit, info);
   3006                 return rv;
   3007             }
   3008         }
   3009     }
   3010 #endif /* BCM_KATANA_SUPPORT */
   3011 
   3012 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   3013     if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit)
   3014          || SOC_IS_TRIDENT3X(unit)) &&
   3015         (soc_mem_index_max(unit, VLAN_PROTOCOL_DATAm) > 0)) {
   3016         mem = VLAN_PROTOCOL_DATAm;
   3017         if (SOC_MEM_IS_VALID(unit, mem)) {
   3018             if (NULL == info->vlan_protocol_data_profile) {
   3019                 info->vlan_protocol_data_profile =
   3020                     sal_alloc(sizeof(soc_profile_mem_t),
   3021                     "VLAN_PROTOCOL_DATA Profile Mem");
   3022                 if (info->vlan_protocol_data_profile == NULL) {
   3023                     _bcm_common_free_resource(unit, info);
   3024                     return BCM_E_MEMORY;
   3025                 }
   3026                 soc_profile_mem_t_init(info->vlan_protocol_data_profile);
   3027 
   3028                 entry_words = sizeof(vlan_protocol_data_entry_t) / sizeof(uint32);
   3029                 index_min[0] = soc_mem_index_min(unit, mem);
   3030                 index_max[0] = soc_mem_index_max(unit, mem);
   3031                 mems[0] = mem;
   3032                 mem_words[0] = entry_words;
   3033                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   3034                                                   index_min, index_max, NULL, 1,
   3035                                                   info->vlan_protocol_data_profile);
   3036                 info->vlan_protocol_data_profile_created= TRUE;
   3037                 if (rv < 0) {
   3038                     _bcm_common_free_resource(unit, info);
   3039                     return rv;
   3040                 }
   3041             }
   3042         }
   3043     }
   3044 #endif /* BCM_KATANA2_SUPPORT */
   3045 
   3046 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   3047     mem = ING_VLAN_VFI_MEMBERSHIPm;
   3048     if (SOC_MEM_IS_VALID(unit, mem)) {
   3049         if (NULL == info->ing_vlan_vfi_mbrship_profile) {
   3050             info->ing_vlan_vfi_mbrship_profile = 
   3051                 sal_alloc(sizeof(soc_profile_mem_t),
   3052                 "ING_VLAN_VFI_MEMBERSHIP Profile Mem");
   3053 
   3054             if (info->ing_vlan_vfi_mbrship_profile == NULL) {
   3055                 _bcm_common_free_resource(unit, info);
   3056                 return BCM_E_MEMORY;
   3057             }
   3058             soc_profile_mem_t_init(info->ing_vlan_vfi_mbrship_profile);
   3059 
   3060             mems_cnt = 0;
   3061             mems[mems_cnt] = mem;
   3062             mem_words[mems_cnt] = sizeof(ing_vlan_vfi_membership_entry_t) /
   3063                 sizeof(uint32);
   3064             index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   3065             index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   3066             mems_cnt++;
   3067 
   3068             rv = soc_profile_mem_index_create(unit, mems, mem_words,
   3069                                               index_min, index_max, NULL,
   3070                                               mems_cnt, info->ing_vlan_vfi_mbrship_profile);
   3071 
   3072             if (rv < 0) {
   3073                 _bcm_common_free_resource(unit, info);
   3074                 return rv;
   3075             }
   3076 
   3077             /*
   3078              * Set one reference count for default entry.
   3079              */
   3080             if (SOC_WARM_BOOT(unit)) {
   3081                 rv = _bcm_vlan_vfi_membership_profile_mem_reference
   3082                     (unit,
   3083                      soc_mem_index_min(unit, ING_VLAN_VFI_MEMBERSHIPm), 1, 0); 
   3084                 rv = _bcm_vlan_vfi_membership_profile_mem_reference(unit, 1, 1, 0);
   3085             } else {
   3086                 /* coverity[stack_use_callee] */
   3087                 /* coverity[stack_use_overflow] */
   3088                 ing_vlan_vfi_membership_entry_t ing_vlan_vfi_entry;
   3089                 void *entries[1];
   3090                 uint32 prof_index = 0;
   3091                 bcm_pbmp_t pbmp;
   3092 
   3093                 BCM_PBMP_CLEAR(pbmp);
   3094                 BCM_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
   3095                 BCM_PBMP_REMOVE(pbmp, PBMP_LB(unit));
   3096                 BCM_PBMP_REMOVE(pbmp, PBMP_RDB_ALL(unit));
   3097                 BCM_PBMP_REMOVE(pbmp, PBMP_MACSEC_ALL(unit));
   3098 
   3099                 sal_memcpy(&ing_vlan_vfi_entry,
   3100                            soc_mem_entry_null(unit, ING_VLAN_VFI_MEMBERSHIPm),
   3101                            (soc_mem_entry_words(unit, ING_VLAN_VFI_MEMBERSHIPm)
   3102                             * sizeof(uint32)));
   3103 
   3104                 entries[0] = &ing_vlan_vfi_entry;
   3105                 BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit,
   3106                     info->ing_vlan_vfi_mbrship_profile, entries, 1, &prof_index));
   3107 
   3108                 /* VFIs should have all physical ports in VFI membership tables, by default.
   3109                    When membership checks are disabled on virtual ports, it defaults to
   3110                    checks at the physical ports. Since the membership checks are enabled
   3111                    by default in SDK, we'll have packet drops without programming these. */
   3112                 soc_mem_pbmp_field_set(unit, mem,
   3113                     &ing_vlan_vfi_entry, ING_PORT_BITMAPf, &pbmp);
   3114                 /* Reserve profile 1 as default VFI membership profile */
   3115                 BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit,
   3116                     info->ing_vlan_vfi_mbrship_profile, entries, 1, &prof_index));
   3117             }
   3118 
   3119             info->ing_vlan_vfi_mbrship_profile_created = TRUE;
   3120         }
   3121     }
   3122 
   3123     mem = EGR_VLAN_VFI_MEMBERSHIPm;
   3124     if (SOC_MEM_IS_VALID(unit, mem)) {
   3125         if (NULL == info->egr_vlan_vfi_mbrship_profile) {
   3126             info->egr_vlan_vfi_mbrship_profile = 
   3127                 sal_alloc(sizeof(soc_profile_mem_t),
   3128                           "EGR_VLAN_VFI_MEMBERSHIP Profile Mem");
   3129             if (info->egr_vlan_vfi_mbrship_profile == NULL) {
   3130                 _bcm_common_free_resource(unit, info);
   3131                 return BCM_E_MEMORY;
   3132             }
   3133             soc_profile_mem_t_init(info->egr_vlan_vfi_mbrship_profile);
   3134 
   3135             mems_cnt = 0;
   3136             mems[mems_cnt] = mem;
   3137             mem_words[mems_cnt] = sizeof(egr_vlan_vfi_membership_entry_t) /
   3138                 sizeof(uint32);
   3139             index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   3140             index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   3141             mems_cnt++;
   3142 
   3143             rv = soc_profile_mem_index_create(unit, mems, mem_words,
   3144                                               index_min, index_max, NULL,
   3145                                               mems_cnt, info->egr_vlan_vfi_mbrship_profile);
   3146 
   3147             if (rv < 0) {
   3148                 _bcm_common_free_resource(unit, info);
   3149                 return rv;
   3150             }
   3151 
   3152             /*
   3153              * Set one reference count for default entry.
   3154              */
   3155             if (SOC_WARM_BOOT(unit)) {
   3156                 rv = _bcm_vlan_vfi_membership_profile_mem_reference
   3157                     (unit, soc_mem_index_min(unit, EGR_VLAN_VFI_MEMBERSHIPm), 
   3158                      1, 1); 
   3159                 rv = _bcm_vlan_vfi_membership_profile_mem_reference(unit, 1, 1, 1);
   3160             } else {
   3161                 /* coverity[stack_use_callee] */
   3162                 /* coverity[stack_use_overflow] */
   3163                 egr_vlan_vfi_membership_entry_t egr_vlan_vfi_entry;
   3164                 void *entries[1];
   3165                 uint32 prof_index = 0;
   3166                 bcm_pbmp_t pbmp;
   3167 
   3168                 BCM_PBMP_CLEAR(pbmp);
   3169                 BCM_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
   3170                 BCM_PBMP_REMOVE(pbmp, PBMP_LB(unit));
   3171                 BCM_PBMP_REMOVE(pbmp, PBMP_RDB_ALL(unit));
   3172                 BCM_PBMP_REMOVE(pbmp, PBMP_MACSEC_ALL(unit));
   3173 
   3174                 sal_memcpy(&egr_vlan_vfi_entry,
   3175                            soc_mem_entry_null(unit, EGR_VLAN_VFI_MEMBERSHIPm),
   3176                            (soc_mem_entry_words(unit, EGR_VLAN_VFI_MEMBERSHIPm)
   3177                             * sizeof(uint32)));
   3178 
   3179                 entries[0] = &egr_vlan_vfi_entry;
   3180                 BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit,
   3181                     info->egr_vlan_vfi_mbrship_profile, entries, 1, &prof_index));
   3182 
   3183                 /* VFIs should have all physical ports in VFI membership tables, by default.
   3184                    When membership checks are disabled on virtual ports, it defaults to
   3185                    checks at the physical ports. Since the membership checks are enabled
   3186                    by default in SDK, we'll have packet drops without programming these. */
   3187                 soc_mem_pbmp_field_set(unit, mem, &egr_vlan_vfi_entry, PORT_BITMAPf, &pbmp);
   3188                 /* Reserve profile 1 as default VFI membership profile */
   3189                 BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit,
   3190                     info->egr_vlan_vfi_mbrship_profile, entries, 1, &prof_index));
   3191             }
   3192 
   3193             info->egr_vlan_vfi_mbrship_profile_created = TRUE;
   3194         }
   3195     }
   3196 #endif
   3197 
   3198 #if defined(BCM_TRIDENT3_SUPPORT)
   3199     mem = EGR_VLAN_VFI_UNTAGm;
   3200     if (SOC_MEM_IS_VALID(unit, mem)) {
   3201         if (NULL == info->egr_vlan_vfi_untag_profile) {
   3202             info->egr_vlan_vfi_untag_profile = 
   3203                 sal_alloc(sizeof(soc_profile_mem_t),
   3204                           "EGR_VLAN_VFI_UNTAG Profile Mem");
   3205             if (info->egr_vlan_vfi_untag_profile == NULL) {
   3206                 _bcm_common_free_resource(unit, info);
   3207                 return BCM_E_MEMORY;
   3208             }
   3209             soc_profile_mem_t_init(info->egr_vlan_vfi_untag_profile);
   3210 
   3211             mems_cnt = 0;
   3212             mems[mems_cnt] = mem;
   3213             mem_words[mems_cnt] = sizeof(egr_vlan_vfi_untag_entry_t) /
   3214                 sizeof(uint32);
   3215             index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   3216             index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   3217             mems_cnt++;
   3218 
   3219             rv = soc_profile_mem_index_create(unit, mems, mem_words,
   3220                                               index_min, index_max, NULL,
   3221                                               mems_cnt, info->egr_vlan_vfi_untag_profile);
   3222 
   3223             if (rv < 0) {
   3224                 _bcm_common_free_resource(unit, info);
   3225                 return rv;
   3226             }
   3227 
   3228             /*
   3229              * Set one reference count for default entry.
   3230              */
   3231             if (SOC_WARM_BOOT(unit)) {
   3232                 rv = _bcm_vlan_vfi_untag_profile_mem_reference
   3233                     (unit, soc_mem_index_min(unit, mem), 1); 
   3234             } else {
   3235                 /* coverity[stack_use_callee] */
   3236                 /* coverity[stack_use_overflow] */
   3237                 egr_vlan_vfi_untag_entry_t egr_vlan_vfi_entry;
   3238                 void *entries[1];
   3239                 uint32 prof_index = 0;
   3240 
   3241                 sal_memcpy(&egr_vlan_vfi_entry,
   3242                            soc_mem_entry_null(unit, mem),
   3243                            (soc_mem_entry_words(unit, mem)
   3244                             * sizeof(uint32)));
   3245 
   3246                 entries[0] = &egr_vlan_vfi_entry;
   3247                 /* Reserve profile 1 as default VFI membership profile */
   3248                 BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit,
   3249                     info->egr_vlan_vfi_untag_profile, entries, 1, &prof_index));
   3250             }
   3251 
   3252             info->egr_vlan_vfi_untag_profile_created = TRUE;
   3253         }
   3254     }
   3255 #endif /* BCM_TRIDENT3_SUPPORT */
   3256 
   3257 #ifdef BCM_SABER2_SUPPORT
   3258     if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   3259         if (NULL == info->service_pri_map_table) {
   3260             info->service_pri_map_table = sal_alloc(sizeof(soc_profile_mem_t),
   3261                     "SERVICE_PRI_MAP TABLE Profile Mem");
   3262             if (info->service_pri_map_table == NULL) {
   3263                 _bcm_common_free_resource(unit, info);
   3264                 return BCM_E_MEMORY;
   3265             }
   3266             soc_profile_mem_t_init(info->service_pri_map_table);
   3267 
   3268             for(mem_index = 0; mem_index < _BCM_SB2_OAM_PRI_MAP_TABLE_MAX; mem_index++)
   3269             {
   3270                 mem_words[mem_index] = (sizeof(ing_service_pri_map_0_entry_t) / sizeof(uint32));
   3271                 mems[mem_index] = _bcm_sb2_svc_pri_map_profile_mem_index_to_mem[mem_index];
   3272             }
   3273             rv = soc_profile_mem_create(unit, mems, mem_words,
   3274                     _BCM_SB2_OAM_PRI_MAP_TABLE_MAX,
   3275                     info->service_pri_map_table);
   3276             info->service_pri_map_created = TRUE;
   3277             if (rv < 0) {
   3278                 _bcm_common_free_resource(unit, info);
   3279                 return rv;
   3280             }
   3281         }
   3282     }
   3283 #endif /* BCM_SABER2_SUPPORT */
   3284 
   3285 #ifdef BCM_HURRICANE3_SUPPORT
   3286     /* Create profile table cache (or re-init if it already exists) */
   3287     mem = EGR_HEADER_ENCAP_DATAm;
   3288     if (SOC_MEM_IS_VALID(unit, mem)) {
   3289         if (NULL == info->egr_header_encap_data) {
   3290             info->egr_header_encap_data = sal_alloc(sizeof(soc_profile_mem_t),
   3291                     "EGR_HEADER_ENCAP_DATA Profile Mem");
   3292             if (info->egr_header_encap_data == NULL) {
   3293                 _bcm_common_free_resource(unit, info);
   3294                 return BCM_E_MEMORY;
   3295             }
   3296             soc_profile_mem_t_init(info->egr_header_encap_data);
   3297 
   3298             entry_words = sizeof(egr_header_encap_data_entry_t) / sizeof(uint32);
   3299             rv = soc_profile_mem_create(unit, &mem, &entry_words, 1,
   3300                     info->egr_header_encap_data);
   3301             info->egr_header_encap_data_created = TRUE;
   3302             if (rv < 0) {
   3303                 _bcm_common_free_resource(unit, info);
   3304                 return rv;
   3305             }
   3306         }
   3307     }
   3308 
   3309     mem = CUSTOM_HEADER_MATCHm;
   3310     if (SOC_MEM_IS_VALID(unit, mem)) {
   3311         if (NULL == info->custom_header_match) {
   3312             info->custom_header_match = sal_alloc(sizeof(soc_profile_mem_t),
   3313                     "CUSTOM_HEADER_MATCH Profile Mem");
   3314             if (info->custom_header_match == NULL) {
   3315                 _bcm_common_free_resource(unit, info);
   3316                 return BCM_E_MEMORY;
   3317             }
   3318             soc_profile_mem_t_init(info->custom_header_match);
   3319 
   3320             entry_words = sizeof(custom_header_match_entry_t) / sizeof(uint32);
   3321             rv = soc_profile_mem_create(unit, &mem, &entry_words, 1,
   3322                     info->custom_header_match);
   3323             info->custom_header_match_created = TRUE;
   3324             if (rv < 0) {
   3325                 _bcm_common_free_resource(unit, info);
   3326                 return rv;
   3327             }
   3328         }
   3329     }
   3330 #endif /* BCM_HURRICANE3_SUPPORT */
   3331 
   3332 #ifdef BCM_TOMAHAWK_SUPPORT
   3333     if (soc_feature(unit, soc_feature_ecn_wred)) {
   3334         mem = ING_TUNNEL_ECN_DECAPm;
   3335         if (SOC_MEM_IS_VALID(unit, mem)) {
   3336             if (NULL == info->ing_tunnel_term_map) {
   3337                 info->ing_tunnel_term_map = sal_alloc(sizeof(soc_profile_mem_t),
   3338                                                       "ING_TUNNEL_TERM_MAP Profile Mem");
   3339                 if (info->ing_tunnel_term_map == NULL) {
   3340                     _bcm_common_free_resource(unit, info);
   3341                     return BCM_E_MEMORY;
   3342                 }
   3343                 soc_profile_mem_t_init(info->ing_tunnel_term_map);
   3344                 mems_cnt = 0;
   3345                 mems[mems_cnt] = mem;
   3346                 info->ing_tunnel_term_map->flags = SOC_PROFILE_MEM_F_NO_SHARE;
   3347                 mem_words[mems_cnt] =
   3348                     sizeof(ing_tunnel_ecn_decap_entry_t) / sizeof(uint32);
   3349                 index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   3350                 index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   3351                 mems_cnt++;
   3352 
   3353                 if (SOC_MEM_IS_VALID(unit, ING_TUNNEL_ECN_DECAP_2m)) {
   3354                     mem = ING_TUNNEL_ECN_DECAP_2m;
   3355                     mems[mems_cnt] = mem;
   3356                     mem_words[mems_cnt] =
   3357                         sizeof(ing_tunnel_ecn_decap_2_entry_t) /
   3358                         sizeof(uint32);
   3359                     index_min[mems_cnt] = soc_mem_index_min(unit, mem);
   3360                     index_max[mems_cnt] = soc_mem_index_max(unit, mem);
   3361                     mems_cnt++;
   3362                 }
   3363                 rv = soc_profile_mem_index_create(unit, mems, mem_words,
   3364                                                   index_min, index_max, NULL,
   3365                                                   mems_cnt,
   3366                                             info->ing_tunnel_term_map);
   3367                 info->ing_tunnel_term_map_created = TRUE;
   3368                 if (rv < 0) {
   3369                     _bcm_common_free_resource(unit, info);
   3370                     return rv;
   3371                 }
   3372             }
   3373         }
   3374     }
   3375 #endif /* BCM_TOMAHAWK_SUPPORT */
   3376 
   3377 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
   3378     defined(BCM_TRIDENT3_SUPPORT)
   3379     if (soc_feature(unit, soc_feature_mpls_ecn)) {
   3380 #if defined(BCM_TRIDENT3_SUPPORT)
   3381         if(soc_feature(unit, soc_feature_td3_style_mpls)) {
   3382             mem = ING_EXP_TO_ECN_MAPPING_1m;
   3383         } else
   3384 #endif
   3385         {
   3386         mem = ING_EXP_TO_IP_ECN_MAPPINGm;
   3387         }
   3388         if (SOC_MEM_IS_VALID(unit, mem)) {
   3389             if (NULL == info->ing_exp_to_ip_ecn_map) {
   3390                 info->ing_exp_to_ip_ecn_map = sal_alloc(sizeof(soc_profile_mem_t),
   3391                                                         "ING_EXP_TO_IP_ECN_MAP Profile Mem");
   3392                 if (info->ing_exp_to_ip_ecn_map == NULL) {
   3393                     _bcm_common_free_resource(unit, info);
   3394                     return BCM_E_MEMORY;
   3395                 }
   3396                 soc_profile_mem_t_init(info->ing_exp_to_ip_ecn_map);
   3397                 info->ing_exp_to_ip_ecn_map->flags = SOC_PROFILE_MEM_F_NO_SHARE;
   3398                 entry_words = 
   3399                     sizeof(ing_exp_to_ip_ecn_mapping_entry_t) / sizeof(uint32);
   3400                 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1,
   3401                                             info->ing_exp_to_ip_ecn_map);
   3402                 info->ing_exp_to_ip_ecn_map_created = TRUE;
   3403                 if (rv < 0) {
   3404                     _bcm_common_free_resource(unit, info);
   3405                     return rv;
   3406                 }
   3407             }
   3408         }
   3409 
   3410 #if defined(BCM_TRIDENT3_SUPPORT)
   3411     if(soc_feature(unit, soc_feature_td3_style_mpls)) {
   3412         mem = EGR_PKT_ECN_TO_EXP_MAPPING_1m;
   3413     } else
   3414 #endif
   3415     {
   3416         mem = EGR_IP_ECN_TO_EXP_MAPPING_TABLEm;
   3417     }
   3418         if (SOC_MEM_IS_VALID(unit, mem)) {
   3419             if (NULL == info->egr_ip_ecn_to_exp_map) {
   3420                 info->egr_ip_ecn_to_exp_map = sal_alloc(sizeof(soc_profile_mem_t),
   3421                                                         "EGR_IP_ECN_TO_EXP_MAP Profile Mem");
   3422                 if (info->egr_ip_ecn_to_exp_map == NULL) {
   3423                     _bcm_common_free_resource(unit, info);
   3424                     return BCM_E_MEMORY;
   3425                 }
   3426                 soc_profile_mem_t_init(info->egr_ip_ecn_to_exp_map);
   3427                 info->egr_ip_ecn_to_exp_map->flags = SOC_PROFILE_MEM_F_NO_SHARE;
   3428 
   3429 #if defined(BCM_TRIDENT3_SUPPORT)
   3430                 if(soc_feature(unit, soc_feature_td3_style_mpls)) {
   3431                     entry_words =
   3432                         sizeof(egr_pkt_ecn_to_exp_mapping_1_entry_t) / sizeof(uint32);
   3433                 } else
   3434 #endif
   3435                 {
   3436                 entry_words = 
   3437                     sizeof(egr_ip_ecn_to_exp_mapping_table_entry_t) / sizeof(uint32);
   3438                 }
   3439                 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1,
   3440                                             info->egr_ip_ecn_to_exp_map);
   3441                 info->egr_ip_ecn_to_exp_map_created = TRUE;
   3442                 if (rv < 0) {
   3443                     _bcm_common_free_resource(unit, info);
   3444                     return rv;
   3445                 }
   3446             }
   3447         }  
   3448         mem = EGR_INT_CN_TO_EXP_MAPPING_TABLEm;
   3449         if (SOC_MEM_IS_VALID(unit, mem)) {
   3450             if (NULL == info->egr_int_cn_to_exp_map) {
   3451                 info->egr_int_cn_to_exp_map = sal_alloc(sizeof(soc_profile_mem_t),
   3452                                                         "EGR_INT_CN_TO_EXP_MAP Profile Mem");
   3453                 if (info->egr_int_cn_to_exp_map == NULL) {
   3454                     _bcm_common_free_resource(unit, info);
   3455                     return BCM_E_MEMORY;
   3456                 }
   3457                 soc_profile_mem_t_init(info->egr_int_cn_to_exp_map);
   3458                 info->egr_int_cn_to_exp_map->flags = SOC_PROFILE_MEM_F_NO_SHARE;
   3459                 entry_words = 
   3460                     sizeof(egr_int_cn_to_exp_mapping_table_entry_t) / sizeof(uint32);
   3461                 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1,
   3462                                             info->egr_int_cn_to_exp_map);
   3463                 info->egr_int_cn_to_exp_map_created = TRUE;
   3464                 if (rv < 0) {
   3465                     _bcm_common_free_resource(unit, info);
   3466                     return rv;
   3467                 }
   3468             }
   3469         }                
   3470     }
   3471 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */
   3472 
   3473 #ifdef BCM_FLOWTRACKER_SUPPORT
   3474     if(soc_feature(unit, soc_feature_flex_flowtracker_ver_1)) {
   3475 
   3476         /* Memory for the Age out profile. */
   3477         mem = BSC_KG_AGE_OUT_PROFILEm;
   3478 
   3479         /* Set the Age out profile entry. */
   3480         FT_AGE_OUT(unit) = sal_alloc(sizeof(soc_profile_mem_t), "Age Out Profile");
   3481 
   3482         if (FT_AGE_OUT(unit) == NULL) {
   3483             _bcm_common_free_resource(unit, info);
   3484             return BCM_E_MEMORY;
   3485         }
   3486 
   3487         soc_profile_mem_t_init(FT_AGE_OUT(unit));
   3488         entry_words = sizeof(bsc_kg_age_out_profile_entry_t) / sizeof(uint32);
   3489 
   3490         rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_AGE_OUT(unit));
   3491 
   3492         if (BCM_FAILURE(rv)) {
   3493             /* Clear the memory allocated for profile above. */
   3494             _bcm_common_free_resource(unit, info);
   3495 
   3496             return rv;
   3497         }
   3498 
   3499 
   3500         /* Memory for the Flow limit profile. */
   3501         mem = BSC_KG_FLOW_EXCEED_PROFILEm;
   3502 
   3503         /* Set the Age out profile entry. */
   3504         FT_FLOW_LIMIT(unit) = sal_alloc(sizeof(soc_profile_mem_t), "Flow Limit Profile");
   3505 
   3506         if (FT_FLOW_LIMIT(unit) == NULL) {
   3507             _bcm_common_free_resource(unit, info);
   3508             return BCM_E_MEMORY;
   3509         }
   3510 
   3511         soc_profile_mem_t_init(FT_FLOW_LIMIT(unit));
   3512         entry_words = sizeof(bsc_kg_flow_exceed_profile_entry_t) / sizeof(uint32);
   3513 
   3514         rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_FLOW_LIMIT(unit));
   3515 
   3516         if (BCM_FAILURE(rv)) {
   3517             /* Clear the memory allocated for profile above. */
   3518             _bcm_common_free_resource(unit, info);
   3519 
   3520             return rv;
   3521         }
   3522 
   3523         mem = BSC_DG_GROUP_COPY_TO_COLLECTOR_PROFILEm;
   3524 
   3525         /* Set the Collector copy profile entry. */
   3526         FT_COLLECTOR_COPY(unit) = sal_alloc(sizeof(soc_profile_mem_t), "collector copy Profile");
   3527 
   3528         if (FT_COLLECTOR_COPY(unit) == NULL) {
   3529             _bcm_common_free_resource(unit, info);
   3530             return BCM_E_MEMORY;
   3531         }
   3532 
   3533         soc_profile_mem_t_init(FT_COLLECTOR_COPY(unit));
   3534         entry_words = sizeof(bsc_dg_group_copy_to_collector_profile_entry_t) / sizeof(uint32);
   3535 
   3536         rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_COLLECTOR_COPY(unit));
   3537 
   3538         if (BCM_FAILURE(rv)) {
   3539             /* Clear the memory allocated for profile above. */
   3540             _bcm_common_free_resource(unit, info);
   3541 
   3542             return rv;
   3543         }
   3544 
   3545         mem = BSD_POLICY_ACTION_PROFILEm;
   3546 
   3547         /* Set the PDD profile entry. */
   3548         FT_PDD_PROFILE(unit) = sal_alloc(sizeof(soc_profile_mem_t), "pdd Profile");
   3549 
   3550         if (FT_PDD_PROFILE(unit) == NULL) {
   3551             _bcm_common_free_resource(unit, info);
   3552             return BCM_E_MEMORY;
   3553         }
   3554 
   3555         soc_profile_mem_t_init(FT_PDD_PROFILE(unit));
   3556         entry_words = sizeof(bsd_policy_action_profile_entry_t) / sizeof(uint32);
   3557 
   3558         rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_PDD_PROFILE(unit));
   3559 
   3560         if (BCM_FAILURE(rv)) {
   3561             /* Clear the memory allocated for profile above. */
   3562             _bcm_common_free_resource(unit, info);
   3563 
   3564             return rv;
   3565         }
   3566 
   3567         mem = BSC_DG_GROUP_METER_PROFILEm;
   3568 
   3569         /* Set the Meter profile entry. */
   3570         FT_METER_PROFILE(unit) = sal_alloc(sizeof(soc_profile_mem_t), "FT meter Profile");
   3571 
   3572         if (FT_METER_PROFILE(unit) == NULL) {
   3573             _bcm_common_free_resource(unit, info);
   3574             return BCM_E_MEMORY;
   3575         }
   3576 
   3577         soc_profile_mem_t_init(FT_METER_PROFILE(unit));
   3578         entry_words = sizeof(bsc_dg_group_meter_profile_entry_t) / sizeof(uint32);
   3579 
   3580         rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_METER_PROFILE(unit));
   3581 
   3582         if (BCM_FAILURE(rv)) {
   3583             /* Clear the memory allocated for profile above. */
   3584             _bcm_common_free_resource(unit, info);
   3585 
   3586             return rv;
   3587         }
   3588 
   3589         /* Set the Timestamp profile entry. */
   3590         mem = BSC_DG_GROUP_TIMESTAMP_PROFILEm;
   3591         FT_TS_PROFILE(unit) = sal_alloc(sizeof(soc_profile_mem_t), "FT timestamp Profile");
   3592 
   3593         if (FT_TS_PROFILE(unit) == NULL) {
   3594             _bcm_common_free_resource(unit, info);
   3595             return BCM_E_MEMORY;
   3596         }
   3597 
   3598         soc_profile_mem_t_init(FT_TS_PROFILE(unit));
   3599         entry_words = sizeof(bsc_dg_group_timestamp_profile_entry_t) / sizeof(uint32);
   3600 
   3601         rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_TS_PROFILE(unit));
   3602 
   3603         if (BCM_FAILURE(rv)) {
   3604             /* Clear the memory allocated for profile above. */
   3605             _bcm_common_free_resource(unit, info);
   3606 
   3607             return rv;
   3608         }
   3609 
   3610     }
   3611 #endif /* BCM_FLOWTRACKER_SUPPORT */
   3612 
   3613 #if defined(BCM_TRIDENT3_SUPPORT)
   3614     mem = PKT_FLOW_VRF_STRENGTH_PROFILE_1_Am;
   3615     if (SOC_MEM_IS_VALID(unit, mem)) {
   3616         pkt_flow_vrf_strength_profile_1_a_entry_t vrf_strength_profile_a_ent;
   3617         sal_memset(&vrf_strength_profile_a_ent, 0,
   3618                    sizeof(pkt_flow_vrf_strength_profile_1_a_entry_t));
   3619         soc_mem_field32_set(
   3620             unit, mem, &vrf_strength_profile_a_ent, VFP_LO_FOR_TUNNEL_TERM_FLOWf,
   3621             VFP_LO_FOR_TUNNEL_TERM_FLOW_STRENGTH);
   3622         soc_mem_field32_set(
   3623             unit, mem, &vrf_strength_profile_a_ent,
   3624             VFP_LO_FOR_NON_TUNNEL_TERM_FLOWf,
   3625             VFP_LO_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH);
   3626         soc_mem_field32_set(
   3627             unit, mem, &vrf_strength_profile_a_ent, VFP_HI_FOR_TUNNEL_TERM_FLOWf,
   3628             VFP_HI_FOR_TUNNEL_TERM_FLOW_STRENGTH);
   3629         soc_mem_field32_set(
   3630             unit, mem, &vrf_strength_profile_a_ent,
   3631             VFP_HI_FOR_NON_TUNNEL_TERM_FLOWf,
   3632             VFP_HI_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH);
   3633         soc_mem_field32_set(
   3634             unit, mem, &vrf_strength_profile_a_ent, SGPP_FOR_TUNNEL_TERM_FLOWf,
   3635             SGPP_FOR_TUNNEL_TERM_FLOW_STRENGTH);
   3636         soc_mem_field32_set(
   3637             unit, mem, &vrf_strength_profile_a_ent,
   3638             SGPP_FOR_NON_TUNNEL_TERM_FLOWf,
   3639             SGPP_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH);
   3640         BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 1,
   3641                             &vrf_strength_profile_a_ent));
   3642     }
   3643     mem = PKT_FLOW_VRF_STRENGTH_PROFILE_1_Bm;
   3644     if (SOC_MEM_IS_VALID(unit, mem)) {
   3645         pkt_flow_vrf_strength_profile_1_b_entry_t vrf_strength_profile_b_ent;
   3646         sal_memset(&vrf_strength_profile_b_ent, 0,
   3647                    sizeof(pkt_flow_vrf_strength_profile_1_b_entry_t));
   3648         soc_mem_field32_set(
   3649             unit, mem, &vrf_strength_profile_b_ent, VFI_FOR_TUNNEL_TERM_FLOWf,
   3650             VFI_FOR_TUNNEL_TERM_FLOW_STRENGTH);
   3651         soc_mem_field32_set(
   3652             unit, mem, &vrf_strength_profile_b_ent,
   3653             VFI_FOR_NON_TUNNEL_TERM_FLOWf,
   3654             VFI_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH);
   3655         soc_mem_field32_set(
   3656             unit, mem, &vrf_strength_profile_b_ent, L3_IIF_FOR_TUNNEL_TERM_FLOWf,
   3657             L3_IIF_FOR_TUNNEL_TERM_FLOW_STRENGTH);
   3658         soc_mem_field32_set(
   3659             unit, mem, &vrf_strength_profile_b_ent,
   3660             L3_IIF_FOR_NON_TUNNEL_TERM_FLOWf,
   3661             L3_IIF_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH);
   3662         BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 1,
   3663                             &vrf_strength_profile_b_ent));
   3664     }
   3665 #endif
   3666 
   3667 #ifdef BCM_WARM_BOOT_SUPPORT
   3668     if (SOC_WARM_BOOT(unit)) {
   3669         rv = _bcm_common_reinit(unit);
   3670         if (BCM_FAILURE(rv)) {
   3671             _bcm_common_free_resource(unit, info);
   3672             return rv;
   3673         }
   3674     } else {
   3675         rv = _bcm_common_wb_alloc(unit);
   3676         BCM_IF_ERROR_RETURN(rv);
   3677     }
   3678 
   3679 #endif /* BCM_WARM_BOOT_SUPPORT */
   3680     
   3681     info->initialized = TRUE;
   3682     return rv;
   3683 }
   3684 
   3685 /*
   3686  * Function:
   3687  *      _bcm_mac_da_profile_entry_add
   3688  * Purpose:
   3689  *      Internal function for adding an entry to the MAC_DA_PROFILE table
   3690  *      Adds an entry to the global shared SW copy of the MAC_DA_PROFILE table
   3691  *      Shared by MPLS and MIM
   3692  * Parameters:
   3693  *      unit    -  (IN) Device number.
   3694  *      entries -  (IN) Array of pointer to table entries set
   3695  *      entries_per_set - (IN)  Number of entries in the set
   3696  *      index   -  (OUT) Base index for the entires allocated in HW
   3697  * Returns:
   3698  *      BCM_X_XXX
   3699  */
   3700 int
   3701 _bcm_mac_da_profile_entry_add(int unit, void **entries, 
   3702                               int entries_per_set, uint32 *index)
   3703 {
   3704     int rv;
   3705     COMMON_LOCK(unit);
   3706     rv = soc_profile_mem_add(unit, MAC_DA_PROFILE(unit), entries,
   3707                              entries_per_set, index);
   3708     COMMON_UNLOCK(unit);
   3709     return rv;
   3710 }
   3711 
   3712 /*
   3713  * Function:
   3714  *      _bcm_mac_da_profile_entry_delete
   3715  * Purpose:
   3716  *      Internal function for deleting an entry from the MAC_DA_PROFILE table
   3717  *      Deletes an entry from the global shared SW copy of the MAC_DA_PROFILE table
   3718  *      Shared by MPLS and MIM
   3719  * Parameters:
   3720  *      unit    -  (IN) Device number.
   3721  *      entries -  (IN) Array of pointer to table entries set
   3722  *      entries_per_set - (IN)  Number of entries in the set
   3723  *      index   -  (OUT) Base index for the entires allocated in HW
   3724  * Returns:
   3725  *      BCM_X_XXX
   3726  */
   3727 int
   3728 _bcm_mac_da_profile_entry_delete(int unit, int index) 
   3729 {
   3730     int rv;
   3731     COMMON_LOCK(unit);
   3732     rv = soc_profile_mem_delete(unit, MAC_DA_PROFILE(unit), index);
   3733     COMMON_UNLOCK(unit);
   3734     return rv;
   3735 }
   3736 
   3737 /*
   3738  * Function:
   3739  *      _bcm_lport_profile_mem_reference_unique
   3740  * Purpose:
   3741  *      Update LPORT_PROFILE_TABLE entry reference count and entries_per_set
   3742  *      for memories split across pipes as unique memory
   3743  *      information for given index.
   3744  * Parameters:
   3745  *      unit            - (IN) Device number
   3746  *      index           - (IN) Base index for entry to update
   3747  *      entries_per_set - (IN) Number of entries in the set
   3748  *      pipe            - (IN) Pipe to affect
   3749  * Returns:
   3750  *      BCM_E_XXX
   3751  */
   3752 int
   3753 _bcm_lport_profile_mem_reference_unique(int unit, int index, int entries_per_set, int pipe)
   3754 {
   3755     int rv;
   3756     COMMON_LOCK(unit);
   3757     rv = soc_profile_mem_reference_unique(unit, LPORT_PROFILE(unit),
   3758                                    index, entries_per_set, pipe);
   3759     COMMON_UNLOCK(unit);
   3760     return rv;
   3761 }
   3762 
   3763 /*
   3764  * Function:
   3765  *      _bcm_lport_profile_mem_reference
   3766  * Purpose:
   3767  *      Update LPORT_PROFILE_TABLE entry reference count and entries_per_set 
   3768  *      information for given index.
   3769  * Parameters:
   3770  *      unit            - (IN) Device number
   3771  *      index           - (IN) Base index for entry to update
   3772  *      entries_per_set - (IN) Number of entries in the set
   3773  * Returns:
   3774  *      BCM_E_XXX
   3775  */
   3776 int
   3777 _bcm_lport_profile_mem_reference(int unit, int index, int entries_per_set)
   3778 {
   3779     int rv;
   3780     COMMON_LOCK(unit);
   3781     rv = soc_profile_mem_reference(unit, LPORT_PROFILE(unit),
   3782                                    index, entries_per_set);
   3783     COMMON_UNLOCK(unit);
   3784     return rv;
   3785 }
   3786 
   3787 /*
   3788  * Function:
   3789  *      _bcm_lport_profile_entry_add_unique
   3790  * Purpose:
   3791  *      Internal function for adding an entry to the LPORT_PROFILE_TABLE.
   3792  *      Adds an entry to the global shared SW copy of the LPORT_PROFILE_TABLE.
   3793  *      Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table.
   3794  *
   3795  *      This is for memories who have been split across pipes as UNIQUE
   3796  * Parameters:
   3797  *      unit    -  (IN) Device number.
   3798  *      entries -  (IN) Array of pointer to table entries set
   3799  *      entries_per_set - (IN)  Number of entries in the set
   3800  *      pipe    -  (IN) Pipe to affect
   3801  *      index   -  (OUT) Base index for the entries allocated in HW
   3802  * Returns:
   3803  *      BCM_E_XXX
   3804  */
   3805 int
   3806 _bcm_lport_profile_entry_add_unique(int unit, void **entries,
   3807                               int entries_per_set, int pipe, uint32 *index)
   3808 {
   3809     int rv;
   3810     COMMON_LOCK(unit);
   3811     rv = soc_profile_mem_add_unique(unit, LPORT_PROFILE(unit), entries,
   3812                              entries_per_set, pipe, index);
   3813     COMMON_UNLOCK(unit);
   3814     return rv;
   3815 }
   3816 
   3817 /*
   3818  * Function:
   3819  *      _bcm_lport_profile_entry_add
   3820  * Purpose:
   3821  *      Internal function for adding an entry to the LPORT_PROFILE_TABLE.
   3822  *      Adds an entry to the global shared SW copy of the LPORT_PROFILE_TABLE.
   3823  *      Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table.
   3824  * Parameters:
   3825  *      unit    -  (IN) Device number.
   3826  *      entries -  (IN) Array of pointer to table entries set
   3827  *      entries_per_set - (IN)  Number of entries in the set
   3828  *      index   -  (OUT) Base index for the entries allocated in HW
   3829  * Returns:
   3830  *      BCM_E_XXX
   3831  */
   3832 int
   3833 _bcm_lport_profile_entry_add(int unit, void **entries, 
   3834                               int entries_per_set, uint32 *index)
   3835 {
   3836     int rv;
   3837     COMMON_LOCK(unit);
   3838     rv = soc_profile_mem_add(unit, LPORT_PROFILE(unit), entries,
   3839                              entries_per_set, index);
   3840     COMMON_UNLOCK(unit);
   3841     return rv;
   3842 }
   3843 
   3844 /*
   3845  * Function:
   3846  *      _bcm_lport_profile_entry_delete_unique
   3847  * Purpose:
   3848  *      Internal function for deleting an entry from the LPORT_PROFILE_TABLE.
   3849  *      Deletes an entry from the global shared SW copy of the
   3850  *      LPORT_PROFILE_TABLE.
   3851  *      Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table.
   3852  * Parameters:
   3853  *      unit    -  (IN) Device number.
   3854  *      index   -  (IN) Base index for the entry to be deleted
   3855  *      pipe    -  (IN) Pipe to affect
   3856  * Returns:
   3857  *      BCM_E_XXX
   3858  */
   3859 int
   3860 _bcm_lport_profile_entry_delete_unique(int unit, int index, int pipe)
   3861 {
   3862     int rv;
   3863     COMMON_LOCK(unit);
   3864     rv = soc_profile_mem_delete_unique(unit, LPORT_PROFILE(unit), index, pipe);
   3865     COMMON_UNLOCK(unit);
   3866     return rv;
   3867 }
   3868 
   3869 /*
   3870  * Function:
   3871  *      _bcm_lport_profile_entry_delete
   3872  * Purpose:
   3873  *      Internal function for deleting an entry from the LPORT_PROFILE_TABLE.
   3874  *      Deletes an entry from the global shared SW copy of the
   3875  *      LPORT_PROFILE_TABLE.
   3876  *      Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table.
   3877  * Parameters:
   3878  *      unit    -  (IN) Device number.
   3879  *      index   -  (IN) Base index for the entry to be deleted
   3880  * Returns:
   3881  *      BCM_E_XXX
   3882  */
   3883 int
   3884 _bcm_lport_profile_entry_delete(int unit, int index) 
   3885 {
   3886     int rv;
   3887     COMMON_LOCK(unit);
   3888     rv = soc_profile_mem_delete(unit, LPORT_PROFILE(unit), index);
   3889     COMMON_UNLOCK(unit);
   3890     return rv;
   3891 }
   3892 
   3893 /*
   3894  * Function:
   3895  *      _bcm_lport_profile_entry_get
   3896  * Purpose:
   3897  *      Internal function for getting an entry from the LPORT_PROFILE_TABLE.
   3898  *      Gets an entry from the global shared SW copy of the
   3899  *      LPORT_PROFILE_TABLE.
   3900  *      Shared by WLAN and proxy, and SOURCE_TRUNK_MAP table.
   3901  * Parameters:
   3902  *      unit    - (IN) Device number
   3903  *      index   - (IN) Base index to the entries in HW for table
   3904  *      count   - (IN) Array of number of entries to retrieve
   3905  *      entries - (OUT) Array of pointer to table entries to get
   3906  * Returns:
   3907  *      BCM_E_XXX
   3908  */
   3909 int
   3910 _bcm_lport_profile_entry_get(int unit, int index, int count, void **entries)
   3911 {
   3912     int rv;
   3913     COMMON_LOCK(unit);
   3914     rv = soc_profile_mem_get(unit, LPORT_PROFILE(unit), index, count,
   3915                              entries);
   3916     COMMON_UNLOCK(unit);
   3917     return rv;
   3918 }
   3919 
   3920 /*
   3921  * Function:
   3922  *      _bcm_lport_profile_fields32_modify
   3923  * Purpose:
   3924  *      Modify the specified fields for all valid (non-zero reference count)
   3925  *      entries in the LPORT Profile Table.
   3926  *
   3927  *      The LPORT Profile Table consists of:
   3928  *          LPORT_TAB (must exist)
   3929  *          RTAG7_PORT_BASED_HASH (IF available, extension of LPORT_TAB)
   3930  *
   3931  *      This is useful when a field(s) needs to be set globally
   3932  *      in the profile table.
   3933  * Parameters:
   3934  *      unit        - (IN) Device number
   3935  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   3936  *      field_count - (IN) Number of fields to modify
   3937  *      fields      - (IN) Array of fields to modify
   3938  *      values      - (IN) Array of new field values
   3939  * Returns:
   3940  *      BCM_E_XXX
   3941  */
   3942 int
   3943 _bcm_lport_profile_fields32_modify(int unit, int table_id, int field_count,
   3944                                    soc_field_t *fields, uint32 *values)
   3945 {
   3946     int rv;
   3947     int i;
   3948     soc_mem_t mem;
   3949     soc_profile_mem_t *profile = NULL;
   3950 
   3951     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   3952         mem = LPORT_TABm;
   3953     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   3954         mem = RTAG7_PORT_BASED_HASHm;
   3955     } else {
   3956         return BCM_E_INTERNAL;
   3957     }
   3958 
   3959     /* Check all fields are valid */
   3960     for (i = 0; i < field_count; i++) {
   3961         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   3962             return BCM_E_UNAVAIL;
   3963         }
   3964     }
   3965 
   3966     COMMON_LOCK(unit);
   3967 
   3968     if(soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) {
   3969         profile = LPORT_IND_PROFILE(unit);
   3970     } else {
   3971         profile =  LPORT_PROFILE(unit);
   3972     }
   3973 
   3974     /* For memories who are split per pipe, they need to be handled
   3975      * differently.  The function needs to iterate per pipe memory
   3976      * rather than a single memory */
   3977     if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   3978         rv = soc_profile_mem_fields32_modify_unique(unit, profile, table_id,
   3979                                          field_count, fields, values);
   3980     } else {
   3981     rv = soc_profile_mem_fields32_modify(unit, profile, table_id,
   3982                                          field_count, fields, values);
   3983     }
   3984 
   3985     COMMON_UNLOCK(unit);
   3986 
   3987     return rv;
   3988 }
   3989 
   3990 /*
   3991  * Function:
   3992  *      _bcm_lport_profile_field32_modify
   3993  * Purpose:
   3994  *      Modify the specified field for all valid (non-zero reference count)
   3995  *      entries in the LPORT Profile Table.
   3996  *
   3997  *      This is useful when a field needs to be set globally
   3998  *      in the profile table.
   3999  * Parameters:
   4000  *      unit     - (IN) Device number
   4001  *      table_id - (IN) Index of table to modify, LPORT or RTAG7
   4002  *      field    - (IN) Fields to modify
   4003  *      value    - (IN) New field value
   4004  * Returns:
   4005  *      BCM_E_XXX
   4006  */
   4007 int
   4008 _bcm_lport_profile_field32_modify(int unit, int table_id,
   4009                                   soc_field_t field, uint32 value)
   4010 {
   4011     return _bcm_lport_profile_fields32_modify(unit, table_id,
   4012                                               1, &field, &value);
   4013 }
   4014 
   4015 /*
   4016  * Function:
   4017  *      _bcm_lport_ind_profile_mem_reference
   4018  * Purpose:
   4019  *      Update LPORT_1_PROFILE_TABLE entry reference count and entries_per_set 
   4020  *      information for given index.
   4021  * Parameters:
   4022  *      unit            - (IN) Device number
   4023  *      index           - (IN) Base index for entry to update
   4024  *      entries_per_set - (IN) Number of entries in the set
   4025  * Returns:
   4026  *      BCM_E_XXX
   4027  */
   4028 int
   4029 _bcm_lport_ind_profile_mem_reference(int unit, int index, int entries_per_set)
   4030 {
   4031     int rv;
   4032     COMMON_LOCK(unit);
   4033     rv = soc_profile_mem_reference(unit, LPORT_IND_PROFILE(unit),
   4034                                    index, entries_per_set);
   4035     COMMON_UNLOCK(unit);
   4036     return rv;
   4037 }
   4038 
   4039 /*
   4040  * Function:
   4041  *      _bcm_lport_ind_profile_entry_add
   4042  * Purpose:
   4043  *      Internal function for adding an entry to the LPORT_PROFILE_TABLE.
   4044  *      Adds an entry to the global shared SW copy of the LPORT_PROFILE_TABLE.
   4045  *      Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table.
   4046  * Parameters:
   4047  *      unit    -  (IN) Device number.
   4048  *      entries -  (IN) Array of pointer to table entries set
   4049  *      entries_per_set - (IN)  Number of entries in the set
   4050  *      index   -  (OUT) Base index for the entries allocated in HW
   4051  * Returns:
   4052  *      BCM_E_XXX
   4053  */
   4054 int
   4055 _bcm_lport_ind_profile_entry_add(int unit, void **entries, 
   4056                               int entries_per_set, uint32 *index)
   4057 {
   4058     int rv;
   4059     COMMON_LOCK(unit);
   4060     rv = soc_profile_mem_add(unit, LPORT_IND_PROFILE(unit), entries,
   4061                              entries_per_set, index);
   4062     COMMON_UNLOCK(unit);
   4063     return rv;
   4064 }
   4065 
   4066 /*
   4067  * Function:
   4068  *      _bcm_lport_ind_profile_entry_delete
   4069  * Purpose:
   4070  *      Internal function for deleting an entry from the LPORT_PROFILE_TABLE.
   4071  *      Deletes an entry from the global shared SW copy of the
   4072  *      LPORT_PROFILE_TABLE.
   4073  *      Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table.
   4074  * Parameters:
   4075  *      unit    -  (IN) Device number.
   4076  *      index   -  (IN) Base index for the entry to be deleted
   4077  * Returns:
   4078  *      BCM_E_XXX
   4079  */
   4080 int
   4081 _bcm_lport_ind_profile_entry_delete(int unit, int index) 
   4082 {
   4083     int rv;
   4084     COMMON_LOCK(unit);
   4085     rv = soc_profile_mem_delete(unit, LPORT_IND_PROFILE(unit), index);
   4086     COMMON_UNLOCK(unit);
   4087     return rv;
   4088 }
   4089 
   4090 /*
   4091  * Function:
   4092  *      _bcm_lport_ind_profile_entry_get
   4093  * Purpose:
   4094  *      Internal function for getting an entry from the LPORT_PROFILE_TABLE.
   4095  *      Gets an entry from the global shared SW copy of the
   4096  *      LPORT_PROFILE_TABLE.
   4097  *      Shared by WLAN and proxy, and SOURCE_TRUNK_MAP table.
   4098  * Parameters:
   4099  *      unit    - (IN) Device number
   4100  *      index   - (IN) Base index to the entries in HW for table
   4101  *      count   - (IN) Array of number of entries to retrieve
   4102  *      entries - (OUT) Array of pointer to table entries to get
   4103  * Returns:
   4104  *      BCM_E_XXX
   4105  */
   4106 int
   4107 _bcm_lport_ind_profile_entry_get(int unit, int index, int count, void **entries)
   4108 {
   4109     int rv;
   4110     COMMON_LOCK(unit);
   4111     rv = soc_profile_mem_get(unit, LPORT_IND_PROFILE(unit), index, count,
   4112                              entries);
   4113     COMMON_UNLOCK(unit);
   4114     return rv;
   4115 }
   4116 
   4117 /*
   4118  * Function:
   4119  *      _bcm_lport_ind_profile_fields32_modify
   4120  * Purpose:
   4121  *      Modify the specified fields for all valid (non-zero reference count)
   4122  *      entries in the LPORT Profile Table.
   4123  *
   4124  *      The LPORT Profile Table consists of:
   4125  *          LPORT_TAB (must exist)
   4126  *          RTAG7_PORT_BASED_HASH (IF available, extension of LPORT_TAB)
   4127  *
   4128  *      This is useful when a field(s) needs to be set globally
   4129  *      in the profile table.
   4130  * Parameters:
   4131  *      unit        - (IN) Device number
   4132  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   4133  *      field_count - (IN) Number of fields to modify
   4134  *      fields      - (IN) Array of fields to modify
   4135  *      values      - (IN) Array of new field values
   4136  * Returns:
   4137  *      BCM_E_XXX
   4138  */
   4139 int
   4140 _bcm_lport_ind_profile_fields32_modify(int unit, int table_id, int field_count,
   4141                                    soc_field_t *fields, uint32 *values)
   4142 {
   4143     int rv;
   4144     int i;
   4145     soc_mem_t mem;
   4146 
   4147     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   4148         mem = LPORT_TABm;
   4149     } else {
   4150         return BCM_E_INTERNAL;
   4151     }
   4152 
   4153     /* Check all fields are valid */
   4154     for (i = 0; i < field_count; i++) {
   4155         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   4156             return BCM_E_UNAVAIL;
   4157         }
   4158     }
   4159 
   4160     COMMON_LOCK(unit);
   4161     rv = soc_profile_mem_fields32_modify(unit, LPORT_IND_PROFILE(unit), table_id,
   4162                                          field_count, fields, values);
   4163     COMMON_UNLOCK(unit);
   4164 
   4165     return rv;
   4166 }
   4167 
   4168 /*
   4169  * Function:
   4170  *      _bcm_lport_ind_profile_field32_modify
   4171  * Purpose:
   4172  *      Modify the specified field for all valid (non-zero reference count)
   4173  *      entries in the LPORT Profile Table.
   4174  *
   4175  *      This is useful when a field needs to be set globally
   4176  *      in the profile table.
   4177  * Parameters:
   4178  *      unit     - (IN) Device number
   4179  *      table_id - (IN) Index of table to modify, LPORT or RTAG7
   4180  *      field    - (IN) Fields to modify
   4181  *      value    - (IN) New field value
   4182  * Returns:
   4183  *      BCM_E_XXX
   4184  */
   4185 int
   4186 _bcm_lport_ind_profile_field32_modify(int unit, int table_id,
   4187                                   soc_field_t field, uint32 value)
   4188 {
   4189     return _bcm_lport_ind_profile_fields32_modify(unit, table_id,
   4190                                               1, &field, &value);
   4191 }
   4192 
   4193 /*
   4194  * Function:
   4195  *      _bcm_rtag7_ind_profile_mem_reference
   4196  * Purpose:
   4197  *      Update RTAG7_1_PROFILE_TABLE entry reference count and entries_per_set 
   4198  *      information for given index.
   4199  * Parameters:
   4200  *      unit            - (IN) Device number
   4201  *      index           - (IN) Base index for entry to update
   4202  *      entries_per_set - (IN) Number of entries in the set
   4203  * Returns:
   4204  *      BCM_E_XXX
   4205  */
   4206 int
   4207 _bcm_rtag7_ind_profile_mem_reference(int unit, int index, int entries_per_set)
   4208 {
   4209     int rv;
   4210     COMMON_LOCK(unit);
   4211     rv = soc_profile_mem_reference(unit, RTAG7_IND_PROFILE(unit),
   4212                                    index, entries_per_set);
   4213     COMMON_UNLOCK(unit);
   4214     return rv;
   4215 }
   4216 
   4217 /*
   4218  * Function:
   4219  *      _bcm_rtag7_ind_profile_entry_add
   4220  * Purpose:
   4221  *      Internal function for adding an entry to the LPORT_PROFILE_TABLE.
   4222  *      Adds an entry to the global shared SW copy of the LPORT_PROFILE_TABLE.
   4223  *      Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table.
   4224  * Parameters:
   4225  *      unit    -  (IN) Device number.
   4226  *      entries -  (IN) Array of pointer to table entries set
   4227  *      entries_per_set - (IN)  Number of entries in the set
   4228  *      index   -  (OUT) Base index for the entries allocated in HW
   4229  * Returns:
   4230  *      BCM_E_XXX
   4231  */
   4232 int
   4233 _bcm_rtag7_ind_profile_entry_add(int unit, void **entries, 
   4234                               int entries_per_set, uint32 *index)
   4235 {
   4236     int rv;
   4237     COMMON_LOCK(unit);
   4238     rv = soc_profile_mem_add(unit, RTAG7_IND_PROFILE(unit), entries,
   4239                              entries_per_set, index);
   4240     COMMON_UNLOCK(unit);
   4241     return rv;
   4242 }
   4243 
   4244 /*
   4245  * Function:
   4246  *      _bcm_rtag7_ind_profile_entry_delete
   4247  * Purpose:
   4248  *      Internal function for deleting an entry from the LPORT_PROFILE_TABLE.
   4249  *      Deletes an entry from the global shared SW copy of the
   4250  *      LPORT_PROFILE_TABLE.
   4251  *      Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table.
   4252  * Parameters:
   4253  *      unit    -  (IN) Device number.
   4254  *      index   -  (IN) Base index for the entry to be deleted
   4255  * Returns:
   4256  *      BCM_E_XXX
   4257  */
   4258 int
   4259 _bcm_rtag7_ind_profile_entry_delete(int unit, int index) 
   4260 {
   4261     int rv;
   4262     COMMON_LOCK(unit);
   4263     rv = soc_profile_mem_delete(unit, RTAG7_IND_PROFILE(unit), index);
   4264     COMMON_UNLOCK(unit);
   4265     return rv;
   4266 }
   4267 
   4268 /*
   4269  * Function:
   4270  *      _bcm_rtag7_ind_profile_entry_get
   4271  * Purpose:
   4272  *      Internal function for getting an entry from the LPORT_PROFILE_TABLE.
   4273  *      Gets an entry from the global shared SW copy of the
   4274  *      LPORT_PROFILE_TABLE.
   4275  *      Shared by WLAN and proxy, and SOURCE_TRUNK_MAP table.
   4276  * Parameters:
   4277  *      unit    - (IN) Device number
   4278  *      index   - (IN) Base index to the entries in HW for table
   4279  *      count   - (IN) Array of number of entries to retrieve
   4280  *      entries - (OUT) Array of pointer to table entries to get
   4281  * Returns:
   4282  *      BCM_E_XXX
   4283  */
   4284 int
   4285 _bcm_rtag7_ind_profile_entry_get(int unit, int index, int count, void **entries)
   4286 {
   4287     int rv;
   4288     COMMON_LOCK(unit);
   4289     rv = soc_profile_mem_get(unit, RTAG7_IND_PROFILE(unit), index, count,
   4290                              entries);
   4291     COMMON_UNLOCK(unit);
   4292     return rv;
   4293 }
   4294 
   4295 /*
   4296  * Function:
   4297  *      _bcm_rtag7_ind_profile_fields32_modify
   4298  * Purpose:
   4299  *      Modify the specified fields for all valid (non-zero reference count)
   4300  *      entries in the LPORT Profile Table.
   4301  *
   4302  *      The LPORT Profile Table consists of:
   4303  *          LPORT_TAB (must exist)
   4304  *          RTAG7_PORT_BASED_HASH (IF available, extension of LPORT_TAB)
   4305  *
   4306  *      This is useful when a field(s) needs to be set globally
   4307  *      in the profile table.
   4308  * Parameters:
   4309  *      unit        - (IN) Device number
   4310  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   4311  *      field_count - (IN) Number of fields to modify
   4312  *      fields      - (IN) Array of fields to modify
   4313  *      values      - (IN) Array of new field values
   4314  * Returns:
   4315  *      BCM_E_XXX
   4316  */
   4317 int
   4318 _bcm_rtag7_ind_profile_fields32_modify(int unit, int table_id, int field_count,
   4319                                    soc_field_t *fields, uint32 *values)
   4320 {
   4321     int rv;
   4322     int i;
   4323     soc_mem_t mem;
   4324 
   4325     if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   4326         mem = RTAG7_PORT_BASED_HASHm;
   4327     } else {
   4328         return BCM_E_INTERNAL;
   4329     }
   4330 
   4331     /* Check all fields are valid */
   4332     for (i = 0; i < field_count; i++) {
   4333         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   4334             return BCM_E_UNAVAIL;
   4335         }
   4336     }
   4337 
   4338     COMMON_LOCK(unit);
   4339     rv = soc_profile_mem_fields32_modify(unit, RTAG7_IND_PROFILE(unit), table_id,
   4340                                          field_count, fields, values);
   4341     COMMON_UNLOCK(unit);
   4342 
   4343     return rv;
   4344 }
   4345 
   4346 /*
   4347  * Function:
   4348  *      _bcm_rtag7_ind_profile_field32_modify
   4349  * Purpose:
   4350  *      Modify the specified field for all valid (non-zero reference count)
   4351  *      entries in the LPORT Profile Table.
   4352  *
   4353  *      This is useful when a field needs to be set globally
   4354  *      in the profile table.
   4355  * Parameters:
   4356  *      unit     - (IN) Device number
   4357  *      table_id - (IN) Index of table to modify, LPORT or RTAG7
   4358  *      field    - (IN) Fields to modify
   4359  *      value    - (IN) New field value
   4360  * Returns:
   4361  *      BCM_E_XXX
   4362  */
   4363 int
   4364 _bcm_rtag7_ind_profile_field32_modify(int unit, int table_id,
   4365                                   soc_field_t field, uint32 value)
   4366 {
   4367     return _bcm_rtag7_ind_profile_fields32_modify(unit, table_id,
   4368                                               1, &field, &value);
   4369 }
   4370 
   4371 int
   4372 _bcm_egr_lport_profile_mem_index_get(int unit, soc_mem_t mem, int *index)
   4373 {
   4374     int rv = BCM_E_NOT_FOUND;
   4375 
   4376     COMMON_LOCK(unit);
   4377     rv = soc_profile_mem_index_get(unit, EGR_LPORT_PROFILE(unit), mem, index);
   4378     COMMON_UNLOCK(unit);
   4379 
   4380     return rv;
   4381 }
   4382 
   4383 /*
   4384  * Function:
   4385  *      _bcm_egr_lport_profile_mem_reference
   4386  * Purpose:
   4387  *      Update LPORT_1_PROFILE_TABLE entry reference count and entries_per_set 
   4388  *      information for given index.
   4389  * Parameters:
   4390  *      unit            - (IN) Device number
   4391  *      index           - (IN) Base index for entry to update
   4392  *      entries_per_set - (IN) Number of entries in the set
   4393  * Returns:
   4394  *      BCM_E_XXX
   4395  */
   4396 int
   4397 _bcm_egr_lport_profile_mem_reference(int unit, int index, int entries_per_set)
   4398 {
   4399     int rv;
   4400     COMMON_LOCK(unit);
   4401     rv = soc_profile_mem_reference(unit, EGR_LPORT_PROFILE(unit),
   4402                                    index, entries_per_set);
   4403     COMMON_UNLOCK(unit);
   4404     return rv;
   4405 }
   4406 
   4407 /*
   4408  * Function:
   4409  *      _bcm_egr_lport_profile_entry_add
   4410  * Purpose:
   4411  *      Internal function for adding an entry to the EGR_LPORT_PROFILE_TABLE.
   4412  *      Adds an entry to the global shared SW copy of the EGR_LPORT_PROFILE_TABLE.
   4413  * Parameters:
   4414  *      unit    -  (IN) Device number.
   4415  *      entries -  (IN) Array of pointer to table entries set
   4416  *      entries_per_set - (IN)  Number of entries in the set
   4417  *      index   -  (OUT) Base index for the entries allocated in HW
   4418  * Returns:
   4419  *      BCM_E_XXX
   4420  */
   4421 int
   4422 _bcm_egr_lport_profile_entry_add(int unit, void **entries, 
   4423                               int entries_per_set, uint32 *index)
   4424 {
   4425     int rv;
   4426     COMMON_LOCK(unit);
   4427     rv = soc_profile_mem_add(unit, EGR_LPORT_PROFILE(unit), entries,
   4428                              entries_per_set, index);
   4429     COMMON_UNLOCK(unit);
   4430     return rv;
   4431 }
   4432 
   4433 /*
   4434  * Function:
   4435  *      _bcm_egr_lport_profile_entry_delete
   4436  * Purpose:
   4437  *      Internal function for deleting an entry from the EGR_LPORT_PROFILE_TABLE.
   4438  *      Deletes an entry from the global shared SW copy of the
   4439  *      EGR_LPORT_PROFILE_TABLE.
   4440  *      Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table.
   4441  * Parameters:
   4442  *      unit    -  (IN) Device number.
   4443  *      index   -  (IN) Base index for the entry to be deleted
   4444  * Returns:
   4445  *      BCM_E_XXX
   4446  */
   4447 int
   4448 _bcm_egr_lport_profile_entry_delete(int unit, int index) 
   4449 {
   4450     int rv;
   4451     COMMON_LOCK(unit);
   4452     rv = soc_profile_mem_delete(unit, EGR_LPORT_PROFILE(unit), index);
   4453     COMMON_UNLOCK(unit);
   4454     return rv;
   4455 }
   4456 
   4457 /*
   4458  * Function:
   4459  *      _bcm_egr_lport_profile_entry_get
   4460  * Purpose:
   4461  *      Internal function for getting an entry from the EGR_LPORT_PROFILE_TABLE.
   4462  *      Gets an entry from the global shared SW copy of the
   4463  *      EGR_LPORT_PROFILE_TABLE.
   4464  *      Shared by WLAN and proxy, and SOURCE_TRUNK_MAP table.
   4465  * Parameters:
   4466  *      unit    - (IN) Device number
   4467  *      index   - (IN) Base index to the entries in HW for table
   4468  *      count   - (IN) Array of number of entries to retrieve
   4469  *      entries - (OUT) Array of pointer to table entries to get
   4470  * Returns:
   4471  *      BCM_E_XXX
   4472  */
   4473 int
   4474 _bcm_egr_lport_profile_entry_get(int unit, int index, int count, void **entries)
   4475 {
   4476     int rv;
   4477     COMMON_LOCK(unit);
   4478     rv = soc_profile_mem_get(unit, EGR_LPORT_PROFILE(unit), index, count,
   4479                              entries);
   4480     COMMON_UNLOCK(unit);
   4481     return rv;
   4482 }
   4483 
   4484 /*
   4485  * Function:
   4486  *      _bcm_egr_lport_profile_fields32_modify
   4487  * Purpose:
   4488  *      Modify the specified fields for all valid (non-zero reference count)
   4489  *      entries in the EGR_LPORT Profile Table.
   4490  *
   4491  *      The EGR_LPORT Profile Table consists of: 
   4492  *      EGR_LPORT_PROFILE
   4493  *      EGR_VLAN_CONTROL_1
   4494  *      EGR_VLAN_CONTROL_2
   4495  *      EGR_VLAN_CONTROL_3
   4496  *      EGR_IPMC_CFG2
   4497  *      EGR_MTU
   4498  *      EGR_PORT_1
   4499  *      EGR_COUNTER_CONTROL (non-TD3)
   4500  *      EGR_SHAPING_CONTROL (non-TD3)
   4501  * 
   4502  *      This is useful when a field(s) needs to be set globally
   4503  *      in the profile table.
   4504  * Parameters:
   4505  *      unit        - (IN) Device number
   4506  *      mem         - (IN) Table to modify
   4507  *      field_count - (IN) Number of fields to modify
   4508  *      fields      - (IN) Array of fields to modify
   4509  *      values      - (IN) Array of new field values
   4510  * Returns:
   4511  *      BCM_E_XXX
   4512  */
   4513 int
   4514 _bcm_egr_lport_profile_fields32_modify(int unit, soc_mem_t mem, int field_count,
   4515                                    soc_field_t *fields, uint32 *values)
   4516 {
   4517     int rv;
   4518     int i, table_id;
   4519 
   4520     /* Check all fields are valid */
   4521     for (i = 0; i < field_count; i++) {
   4522         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   4523             return BCM_E_UNAVAIL;
   4524         }
   4525     }
   4526 
   4527     COMMON_LOCK(unit);
   4528     rv = soc_profile_mem_index_get(unit, EGR_LPORT_PROFILE(unit), mem,
   4529                                    &table_id);
   4530     if (SOC_SUCCESS(rv)) {
   4531         rv = soc_profile_mem_fields32_modify(unit, EGR_LPORT_PROFILE(unit),
   4532                     table_id, field_count, fields, values);
   4533     }
   4534     COMMON_UNLOCK(unit);
   4535 
   4536     return rv;
   4537 }
   4538 
   4539 /*
   4540  * Function:
   4541  *      _bcm_egr_lport_profile_field32_modify
   4542  * Purpose:
   4543  *      Modify the specified field for all valid (non-zero reference count)
   4544  *      entries in the EGR_LPORT Profile Table.
   4545  *
   4546  *      This is useful when a field needs to be set globally
   4547  *      in the profile table.
   4548  * Parameters:
   4549  *      unit     - (IN) Device number
   4550  *      mem      - (IN) Table to modify
   4551  *      field    - (IN) Fields to modify
   4552  *      value    - (IN) New field value
   4553  * Returns:
   4554  *      BCM_E_XXX
   4555  */
   4556 int
   4557 _bcm_egr_lport_profile_field32_modify(int unit, soc_mem_t mem,
   4558                                   soc_field_t field, uint32 value)
   4559 {
   4560     return _bcm_egr_lport_profile_fields32_modify(unit, mem, 1, &field, &value);
   4561 }
   4562 
   4563 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4564 /*
   4565  * Function:
   4566  *      _bcm_misc_port_profile_mem_reference
   4567  * Purpose:
   4568  *      Update MISC_PORT_PROFILE_TABLE entry reference count and entries_per_set
   4569  *      information for given index.
   4570  * Parameters:
   4571  *      unit            - (IN) Device number
   4572  *      index           - (IN) Base index for entry to update
   4573  *      entries_per_set - (IN) Number of entries in the set
   4574  * Returns:
   4575  *      BCM_E_XXX
   4576  */
   4577 int
   4578 _bcm_misc_port_profile_mem_reference(int unit, int index, int entries_per_set)
   4579 {
   4580     int rv;
   4581     COMMON_LOCK(unit);
   4582     rv = soc_profile_mem_reference(unit, MISC_PORT_PROFILE(unit),
   4583                                    index, entries_per_set);
   4584     COMMON_UNLOCK(unit);
   4585     return rv;
   4586 }
   4587 
   4588 /*
   4589  * Function:
   4590  *      _bcm_misc_port_profile_entry_add
   4591  * Purpose:
   4592  *      Internal function for adding an entry to the MISC_PORT_PROFILE_TABLE.
   4593  *      Adds an entry to the global shared SW copy of the MISC_PORT_PROFILE_TABLE.
   4594  * Parameters:
   4595  *      unit    -  (IN) Device number.
   4596  *      entries -  (IN) Array of pointer to table entries set
   4597  *      entries_per_set - (IN)  Number of entries in the set
   4598  *      index   -  (OUT) Base index for the entries allocated in HW
   4599  * Returns:
   4600  *      BCM_E_XXX
   4601  */
   4602 int
   4603 _bcm_misc_port_profile_entry_add(int unit, void **entries, 
   4604                               int entries_per_set, uint32 *index)
   4605 {
   4606     int rv;
   4607     COMMON_LOCK(unit);
   4608     rv = soc_profile_mem_add(unit, MISC_PORT_PROFILE(unit), entries,
   4609                              entries_per_set, index);
   4610     COMMON_UNLOCK(unit);
   4611     return rv;
   4612 }
   4613 
   4614 /*
   4615  * Function:
   4616  *      _bcm_misc_port_profile_entry_delete
   4617  * Purpose:
   4618  *      Internal function for deleting an entry from the MISC_PORT_PROFILE_TABLE.
   4619  *      Deletes an entry from the global shared SW copy of the
   4620  *      MISC_PORT_PROFILE_TABLE.
   4621  * Parameters:
   4622  *      unit    -  (IN) Device number.
   4623  *      index   -  (IN) Base index for the entry to be deleted
   4624  * Returns:
   4625  *      BCM_E_XXX
   4626  */
   4627 int
   4628 _bcm_misc_port_profile_entry_delete(int unit, int index) 
   4629 {
   4630     int rv;
   4631     COMMON_LOCK(unit);
   4632     rv = soc_profile_mem_delete(unit, MISC_PORT_PROFILE(unit), index);
   4633     COMMON_UNLOCK(unit);
   4634     return rv;
   4635 }
   4636 
   4637 /*
   4638  * Function:
   4639  *      _bcm_misc_port_profile_entry_get
   4640  * Purpose:
   4641  *      Internal function for getting an entry from the MISC_PORT_PROFILE_TABLE.
   4642  *      Gets an entry from the global shared SW copy of the
   4643  *      MISC_PORT_PROFILE_TABLE.
   4644  * Parameters:
   4645  *      unit    - (IN) Device number
   4646  *      index   - (IN) Base index to the entries in HW for table
   4647  *      count   - (IN) Array of number of entries to retrieve
   4648  *      entries - (OUT) Array of pointer to table entries to get
   4649  * Returns:
   4650  *      BCM_E_XXX
   4651  */
   4652 int
   4653 _bcm_misc_port_profile_entry_get(int unit, int index, int count, void **entries)
   4654 {
   4655     int rv;
   4656     COMMON_LOCK(unit);
   4657     rv = soc_profile_mem_get(unit, MISC_PORT_PROFILE(unit), index, count,
   4658                              entries);
   4659     COMMON_UNLOCK(unit);
   4660     return rv;
   4661 }
   4662 
   4663 /*
   4664  * Function:
   4665  *      _bcm_misc_port_profile_fields32_modify
   4666  * Purpose:
   4667  *      Modify the specified fields for all valid (non-zero reference count)
   4668  *      entries in the MISC_PORT_PROFILE_TABLE.
   4669  *
   4670  *      The MISC_PORT_PROFILE_TABLE consists of:
   4671  *          FP_I2E_CLASSID_SELECT
   4672  *          FP_HG_CLASSID_SELECT
   4673  *
   4674  *      This is useful when a field(s) needs to be set globally
   4675  *      in the profile table.
   4676  * Parameters:
   4677  *      unit        - (IN) Device number
   4678  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   4679  *      field_count - (IN) Number of fields to modify
   4680  *      fields      - (IN) Array of fields to modify
   4681  *      values      - (IN) Array of new field values
   4682  * Returns:
   4683  *      BCM_E_XXX
   4684  */
   4685 int
   4686 _bcm_misc_port_profile_fields32_modify(int unit, int table_id, int field_count,
   4687                                    soc_field_t *fields, uint32 *values)
   4688 {
   4689     int rv;
   4690     int i;
   4691     soc_mem_t mem;
   4692 
   4693     if (table_id == 0) {
   4694         mem = FP_I2E_CLASSID_SELECTm;
   4695     } else if (table_id == 1) {
   4696         mem = FP_HG_CLASSID_SELECTm;
   4697     } else {
   4698         return BCM_E_INTERNAL;
   4699     }
   4700 
   4701     /* Check all fields are valid */
   4702     for (i = 0; i < field_count; i++) {
   4703         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   4704             return BCM_E_UNAVAIL;
   4705         }
   4706     }
   4707 
   4708     COMMON_LOCK(unit);
   4709     rv = soc_profile_mem_fields32_modify(unit, MISC_PORT_PROFILE(unit), table_id,
   4710                                          field_count, fields, values);
   4711     COMMON_UNLOCK(unit);
   4712 
   4713     return rv;
   4714 }
   4715 
   4716 /*
   4717  * Function:
   4718  *      _bcm_misc_port_profile_field32_modify
   4719  * Purpose:
   4720  *      Modify the specified field for all valid (non-zero reference count)
   4721  *      entries in the MISC_PORT_PROFILE_TABLE.
   4722  *
   4723  *      This is useful when a field needs to be set globally
   4724  *      in the profile table.
   4725  * Parameters:
   4726  *      unit     - (IN) Device number
   4727  *      table_id - (IN) Index of table to modify, LPORT or RTAG7
   4728  *      field    - (IN) Fields to modify
   4729  *      value    - (IN) New field value
   4730  * Returns:
   4731  *      BCM_E_XXX
   4732  */
   4733 int
   4734 _bcm_misc_port_profile_field32_modify(int unit, int table_id,
   4735                                   soc_field_t field, uint32 value)
   4736 {
   4737     return _bcm_misc_port_profile_fields32_modify(unit, table_id,
   4738                                               1, &field, &value);
   4739 }
   4740 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   4741 
   4742 /*
   4743  * Function:
   4744  *      _bcm_egr_qos_profile_mem_reference
   4745  * Purpose:
   4746  *      Update EGR_EGR_QOS_PROFILE_TABLE entry reference count and entries_per_set 
   4747  *      information for given index.
   4748  * Parameters:
   4749  *      unit            - (IN) Device number
   4750  *      index           - (IN) Base index for entry to update
   4751  *      entries_per_set - (IN) Number of entries in the set
   4752  * Returns:
   4753  *      BCM_E_XXX
   4754  */
   4755 int
   4756 _bcm_egr_qos_profile_mem_reference(int unit, int index, int entries_per_set)
   4757 {
   4758     int rv;
   4759     COMMON_LOCK(unit);
   4760     rv = soc_profile_mem_reference(unit, EGR_QOS_PROFILE(unit),
   4761                                    index, entries_per_set);
   4762     COMMON_UNLOCK(unit);
   4763     return rv;
   4764 }
   4765 
   4766 /*
   4767  * Function:
   4768  *      _bcm_egr_qos_profile_entry_add
   4769  * Purpose:
   4770  *      Internal function for adding an entry to the EGR_QOS_PROFILE_TABLE.
   4771  *      Adds an entry to the global shared SW copy of the EGR_QOS_PROFILE_TABLE.
   4772  *      Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table.
   4773  * Parameters:
   4774  *      unit    -  (IN) Device number.
   4775  *      entries -  (IN) Array of pointer to table entries set
   4776  *      entries_per_set - (IN)  Number of entries in the set
   4777  *      index   -  (OUT) Base index for the entries allocated in HW
   4778  * Returns:
   4779  *      BCM_E_XXX
   4780  */
   4781 int
   4782 _bcm_egr_qos_profile_entry_add(int unit, void **entries, 
   4783                               int entries_per_set, uint32 *index)
   4784 {
   4785     int rv;
   4786     COMMON_LOCK(unit);
   4787     rv = soc_profile_mem_add(unit, EGR_QOS_PROFILE(unit), entries,
   4788                              entries_per_set, index);
   4789     COMMON_UNLOCK(unit);
   4790     return rv;
   4791 }
   4792 
   4793 /*
   4794  * Function:
   4795  *      _bcm_egr_qos_profile_entry_delete
   4796  * Purpose:
   4797  *      Internal function for deleting an entry from the EGR_QOS_PROFILE_TABLE.
   4798  *      Deletes an entry from the global shared SW copy of the
   4799  *      EGR_QOS_PROFILE_TABLE.
   4800  *      Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table.
   4801  * Parameters:
   4802  *      unit    -  (IN) Device number.
   4803  *      index   -  (IN) Base index for the entry to be deleted
   4804  * Returns:
   4805  *      BCM_E_XXX
   4806  */
   4807 int
   4808 _bcm_egr_qos_profile_entry_delete(int unit, int index) 
   4809 {
   4810     int rv;
   4811     COMMON_LOCK(unit);
   4812     rv = soc_profile_mem_delete(unit, EGR_QOS_PROFILE(unit), index);
   4813     COMMON_UNLOCK(unit);
   4814     return rv;
   4815 }
   4816 
   4817 /*
   4818  * Function:
   4819  *      _bcm_egr_qos_profile_entry_get
   4820  * Purpose:
   4821  *      Internal function for getting an entry from the EGR_QOS_PROFILE_TABLE.
   4822  *      Gets an entry from the global shared SW copy of the
   4823  *      EGR_QOS_PROFILE_TABLE.
   4824  *      Shared by WLAN and proxy, and SOURCE_TRUNK_MAP table.
   4825  * Parameters:
   4826  *      unit    - (IN) Device number
   4827  *      index   - (IN) Base index to the entries in HW for table
   4828  *      count   - (IN) Array of number of entries to retrieve
   4829  *      entries - (OUT) Array of pointer to table entries to get
   4830  * Returns:
   4831  *      BCM_E_XXX
   4832  */
   4833 int
   4834 _bcm_egr_qos_profile_entry_get(int unit, int index, int count, void **entries)
   4835 {
   4836     int rv;
   4837     COMMON_LOCK(unit);
   4838     rv = soc_profile_mem_get(unit, EGR_QOS_PROFILE(unit), index, count,
   4839                              entries);
   4840     COMMON_UNLOCK(unit);
   4841     return rv;
   4842 }
   4843 
   4844 /*
   4845  * Function:
   4846  *      _bcm_egr_qos_profile_fields32_modify
   4847  * Purpose:
   4848  *      Modify the specified fields for all valid (non-zero reference count)
   4849  *      entries in the LPORT Profile Table.
   4850  *
   4851  *      The LPORT Profile Table consists of:
   4852  *          LPORT_TAB (must exist)
   4853  *          RTAG7_PORT_BASED_HASH (IF available, extension of LPORT_TAB)
   4854  *
   4855  *      This is useful when a field(s) needs to be set globally
   4856  *      in the profile table.
   4857  * Parameters:
   4858  *      unit        - (IN) Device number
   4859  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   4860  *      field_count - (IN) Number of fields to modify
   4861  *      fields      - (IN) Array of fields to modify
   4862  *      values      - (IN) Array of new field values
   4863  * Returns:
   4864  *      BCM_E_XXX
   4865  */
   4866 int
   4867 _bcm_egr_qos_profile_fields32_modify(int unit, int table_id, int field_count,
   4868                                    soc_field_t *fields, uint32 *values)
   4869 {
   4870     int rv;
   4871     int i;
   4872     soc_mem_t mem;
   4873 
   4874     if (table_id == EGR_PRI_CNG_MAPm) {
   4875         mem = EGR_PRI_CNG_MAPm;
   4876     } else if (table_id == EGR_DSCP_TABLEm) {
   4877         mem = EGR_DSCP_TABLEm;
   4878     } else if (table_id == EGR_ZONE_2_QOS_MAPPING_TABLEm) {
   4879         mem = EGR_ZONE_2_QOS_MAPPING_TABLEm;
   4880     } else {
   4881         return BCM_E_INTERNAL;
   4882     }
   4883 
   4884     /* Check all fields are valid */
   4885     for (i = 0; i < field_count; i++) {
   4886         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   4887             return BCM_E_UNAVAIL;
   4888         }
   4889     }
   4890 
   4891     COMMON_LOCK(unit);
   4892     rv = soc_profile_mem_fields32_modify(unit, EGR_QOS_PROFILE(unit), table_id,
   4893                                          field_count, fields, values);
   4894     COMMON_UNLOCK(unit);
   4895 
   4896     return rv;
   4897 }
   4898 
   4899 /*
   4900  * Function:
   4901  *      _bcm_egr_qos_profile_field32_modify
   4902  * Purpose:
   4903  *      Modify the specified field for all valid (non-zero reference count)
   4904  *      entries in the LPORT Profile Table.
   4905  *
   4906  *      This is useful when a field needs to be set globally
   4907  *      in the profile table.
   4908  * Parameters:
   4909  *      unit     - (IN) Device number
   4910  *      table_id - (IN) Index of table to modify, LPORT or RTAG7
   4911  *      field    - (IN) Fields to modify
   4912  *      value    - (IN) New field value
   4913  * Returns:
   4914  *      BCM_E_XXX
   4915  */
   4916 int
   4917 _bcm_egr_qos_profile_field32_modify(int unit, int table_id,
   4918                                   soc_field_t field, uint32 value)
   4919 {
   4920     return _bcm_egr_qos_profile_fields32_modify(unit, table_id,
   4921                                               1, &field, &value);
   4922 }
   4923 
   4924 
   4925 /*
   4926  * Function:
   4927  *      _bcm_ing_vft_pri_map_entry_add
   4928  * Purpose:
   4929  *      Adds an entry to the global shared SW copy of the ING_VFT_PRI_MAP table.
   4930  * Parameters:
   4931  *      unit            - (IN)  Device number.
   4932  *      entries         - (IN)  Array of pointer to table entries set
   4933  *      entries_per_set - (IN)  Number of entries in the set
   4934  *      index           - (OUT) Base index for the entires allocated in HW
   4935  * Returns:
   4936  *      BCM_E_XXX
   4937  */
   4938 int
   4939 _bcm_ing_vft_pri_map_entry_add(int unit, void **entries,
   4940                                int entries_per_set, uint32 *index)
   4941 {
   4942     int rv;
   4943     COMMON_LOCK(unit);
   4944     rv = soc_profile_mem_add(unit, ING_VFT_PRI_MAP(unit), entries,
   4945                              entries_per_set, index);
   4946     COMMON_UNLOCK(unit);
   4947     return rv;
   4948 }
   4949 
   4950 /*
   4951  * Function:
   4952  *      _bcm_ing_l2_vlan_etag_map_entry_add
   4953  * Purpose:
   4954  *      Adds an entry to the global shared SW copy of the ING_ETAG_PCP_MAPPING table.
   4955  * Parameters:
   4956  *      unit            - (IN)  Device number.
   4957  *      entries         - (IN)  Array of pointer to table entries set
   4958  *      entries_per_set - (IN)  Number of entries in the set
   4959  *      index           - (OUT) Base index for the entires allocated in HW
   4960  * Returns:
   4961  *      BCM_E_XXX
   4962  */
   4963 int
   4964 _bcm_ing_l2_vlan_etag_map_entry_add(int unit, void **entries,
   4965                                int entries_per_set, uint32 *index)
   4966 {
   4967     int rv;
   4968     COMMON_LOCK(unit);
   4969     rv = soc_profile_mem_add(unit, ING_L2_VLAN_ETAG_MAP(unit), entries,
   4970                              entries_per_set, index);
   4971     COMMON_UNLOCK(unit);
   4972     return rv;
   4973 }
   4974 
   4975 /*
   4976  * Function:
   4977  *      _bcm_egr_l2_vlan_etag_map_entry_add
   4978  * Purpose:
   4979  *      Adds an entry to the global shared SW copy of the EGR_ETAG_PCP_MAPPING table.
   4980  * Parameters:
   4981  *      unit            - (IN)  Device number.
   4982  *      entries         - (IN)  Array of pointer to table entries set
   4983  *      entries_per_set - (IN)  Number of entries in the set
   4984  *      index           - (OUT) Base index for the entires allocated in HW
   4985  * Returns:
   4986  *      BCM_E_XXX
   4987  */
   4988 int
   4989 _bcm_egr_l2_vlan_etag_map_entry_add(int unit, void **entries,
   4990                                int entries_per_set, uint32 *index)
   4991 {
   4992     int rv;
   4993     COMMON_LOCK(unit);
   4994     rv = soc_profile_mem_add(unit, EGR_L2_VLAN_ETAG_MAP(unit), entries,
   4995                              entries_per_set, index);
   4996     COMMON_UNLOCK(unit);
   4997     return rv;
   4998 }
   4999 
   5000 /*
   5001  * Function:
   5002  *      _bcm_egr_vft_pri_map_entry_add
   5003  * Purpose:
   5004  *      Adds an entry to the EGR_VFT_PRI_MAP table (both the hardware and 
   5005  *      the global shared SW cache).
   5006  * Parameters:
   5007  *      unit            - (IN)  Device number.
   5008  *      entries         - (IN)  Array of pointer to table entries set
   5009  *      entries_per_set - (IN)  Number of entries in the set
   5010  *      index           - (OUT) Base index for the entries allocated
   5011  * Returns:
   5012  *      BCM_E_XXX
   5013  */
   5014 int
   5015 _bcm_egr_vft_pri_map_entry_add(int unit, void **entries,
   5016                                int entries_per_set, uint32 *index)
   5017 {
   5018     int rv;
   5019     COMMON_LOCK(unit);
   5020     rv = soc_profile_mem_add(unit, EGR_VFT_PRI_MAP(unit), entries,
   5021                              entries_per_set, index);
   5022     COMMON_UNLOCK(unit);
   5023     return rv;
   5024 }
   5025 
   5026 /*
   5027  * Function:
   5028  *      _bcm_egr_vsan_intpri_map_entry_add
   5029  * Purpose:
   5030  *      Adds an entry to the EGR_VSAN_INTPRI_MAP table (both the hardware and 
   5031  *      the global shared SW cache).
   5032  * Parameters:
   5033  *      unit            - (IN)  Device number.
   5034  *      entries         - (IN)  Array of pointer to table entries set
   5035  *      entries_per_set - (IN)  Number of entries in the set
   5036  *      index           - (OUT) Base index for the entries allocated
   5037  * Returns:
   5038  *      BCM_E_XXX
   5039  */
   5040 int
   5041 _bcm_egr_vsan_intpri_map_entry_add(int unit, void **entries,
   5042                                    int entries_per_set, uint32 *index)
   5043 {
   5044     int rv;
   5045     COMMON_LOCK(unit);
   5046     rv = soc_profile_mem_add(unit, EGR_VSAN_INTPRI_MAP(unit), entries,
   5047                              entries_per_set, index);
   5048     COMMON_UNLOCK(unit);
   5049     return rv;
   5050 }
   5051 
   5052 /*
   5053  * Function:
   5054  *      _bcm_egr_vft_fields_entry_add
   5055  * Purpose:
   5056  *      Adds an entry to the EGR_VFT_FIELDS_PROFILE table (both the hardware and 
   5057  *      the global shared SW cache).
   5058  * Parameters:
   5059  *      unit            - (IN)  Device number.
   5060  *      entries         - (IN)  Array of pointer to table entries set
   5061  *      entries_per_set - (IN)  Number of entries in the set
   5062  *      index           - (OUT) Base index for the entries allocated
   5063  * Returns:
   5064  *      BCM_E_XXX
   5065  */
   5066 int
   5067 _bcm_egr_vft_fields_entry_add(int unit, void **entries, int entries_per_set,
   5068                               uint32 *index)
   5069 {
   5070     int rv;
   5071     COMMON_LOCK(unit);
   5072     rv = soc_profile_mem_add(unit, EGR_VFT_FIELDS(unit), entries, 
   5073                              entries_per_set, index);
   5074     COMMON_UNLOCK(unit);
   5075     return rv;
   5076 }
   5077 
   5078 /*
   5079  * Function: 
   5080  *     _bcm_ing_vft_pri_map_entry_del
   5081  * Purpose:
   5082  *      Deletes an entry from the ING_VFT_PRI_MAP table (both the hardware and
   5083  *      the global shared SW cache).
   5084  * Parameters:
   5085  *      unit    -  (IN) Device number.
   5086  *      index   -  (IN) Base index for the entries to be deleted
   5087  * Returns:
   5088  *     BCM_E_XXX
   5089  */
   5090 int
   5091 _bcm_ing_vft_pri_map_entry_del(int unit, int index) 
   5092 {
   5093     int rv;
   5094     COMMON_LOCK(unit);
   5095     rv = soc_profile_mem_delete(unit, ING_VFT_PRI_MAP(unit), index);
   5096     COMMON_UNLOCK(unit);
   5097     return rv;
   5098 }
   5099 
   5100 /*
   5101  * Function: 
   5102  *     _bcm_ing_l2_vlan_etag_map_entry_del
   5103  * Purpose:
   5104  *      Deletes an entry from the ING_ETAG_PCP_MAPPING table (both the hardware and
   5105  *      the global shared SW cache).
   5106  * Parameters:
   5107  *      unit    -  (IN) Device number.
   5108  *      index   -  (IN) Base index for the entries to be deleted
   5109  * Returns:
   5110  *     BCM_E_XXX
   5111  */
   5112 int
   5113 _bcm_ing_l2_vlan_etag_map_entry_del(int unit, int index) 
   5114 {
   5115     int rv;
   5116     COMMON_LOCK(unit);
   5117     rv = soc_profile_mem_delete(unit, ING_L2_VLAN_ETAG_MAP(unit), index);
   5118     COMMON_UNLOCK(unit);
   5119     return rv;
   5120 }
   5121 
   5122 /*
   5123  * Function: 
   5124  *     _bcm_egr_vft_pri_map_entry_del
   5125  * Purpose:
   5126  *      Deletes an entry from the EGR_VFT_PRI_MAP table (both the hardware and
   5127  *      the global shared SW cache).
   5128  * Parameters:
   5129  *      unit    -  (IN) Device number.
   5130  *      index   -  (IN) Base index for the entries to be deleted
   5131  * Returns:
   5132  *     BCM_E_XXX
   5133  */
   5134 int
   5135 _bcm_egr_vft_pri_map_entry_del(int unit, int index) 
   5136 {
   5137     int rv;
   5138     COMMON_LOCK(unit);
   5139     rv = soc_profile_mem_delete(unit, EGR_VFT_PRI_MAP(unit), index);
   5140     COMMON_UNLOCK(unit);
   5141     return rv;
   5142 }
   5143 
   5144 /*
   5145  * Function: 
   5146  *     _bcm_egr_vft_fields_entry_del
   5147  * Purpose:
   5148  *      Deletes an entry from the EGR_VFT_FIELDS_PROFILE table (both the 
   5149  *      hardware and the global shared SW cache).
   5150  * Parameters:
   5151  *      unit    -  (IN) Device number.
   5152  *      index   -  (IN) Base index for the entries to be deleted
   5153  * Returns:
   5154  *     BCM_E_XXX
   5155  */
   5156 int
   5157 _bcm_egr_vft_fields_entry_del(int unit, int index) 
   5158 {
   5159     int rv;
   5160     COMMON_LOCK(unit);
   5161     rv = soc_profile_mem_delete(unit, EGR_VFT_FIELDS(unit), index);
   5162     COMMON_UNLOCK(unit);
   5163     return rv;
   5164 }
   5165 
   5166 /*
   5167  * Function: 
   5168  *     _bcm_egr_vsan_intpri_map_entry_del
   5169  * Purpose:
   5170  *      Deletes an entry from the EGR_VSAN_INTPRI_MAP table (both the hardware
   5171  *      and the global shared SW cache).
   5172  * Parameters:
   5173  *      unit    -  (IN) Device number.
   5174  *      index   -  (IN) Base index for the entries to be deleted
   5175  * Returns:
   5176  *     BCM_E_XXX
   5177  */
   5178 int
   5179 _bcm_egr_vsan_intpri_map_entry_del(int unit, int index) 
   5180 {
   5181     int rv;
   5182     COMMON_LOCK(unit);
   5183     rv = soc_profile_mem_delete(unit, EGR_VSAN_INTPRI_MAP(unit), index);
   5184     COMMON_UNLOCK(unit);
   5185     return rv;
   5186 }
   5187 
   5188 /*
   5189  * Function: 
   5190  *     _bcm_egr_l2_vlan_etag_map_entry_del
   5191  * Purpose:
   5192  *      Deletes an entry from the EGR_ETAG_PCP_MAPPING table (both the hardware and
   5193  *      the global shared SW cache).
   5194  * Parameters:
   5195  *      unit    -  (IN) Device number.
   5196  *      index   -  (IN) Base index for the entries to be deleted
   5197  * Returns:
   5198  *     BCM_E_XXX
   5199  */
   5200 int
   5201 _bcm_egr_l2_vlan_etag_map_entry_del(int unit, int index) 
   5202 {
   5203     int rv;
   5204     COMMON_LOCK(unit);
   5205     rv = soc_profile_mem_delete(unit, EGR_L2_VLAN_ETAG_MAP(unit), index);
   5206     COMMON_UNLOCK(unit);
   5207     return rv;
   5208 }
   5209 
   5210 
   5211 /*
   5212  * Function: 
   5213  *     _bcm_ing_vft_pri_map_entry_get
   5214  * Purpose:
   5215  *     Get a set of entries from the ING_VFT_PRI_MAP table.
   5216  * Parameters:
   5217  *     unit    - (IN)  Device number.
   5218  *     index   - (IN)  Base index for the entries to be retrieved
   5219  *     count   - (IN)  Number of entries in the set
   5220  *     entries - (OUT) Array of pointer to table entries set
   5221  * Returns:
   5222  *     BCM_E_XXX
   5223  */
   5224 int
   5225 _bcm_ing_vft_pri_map_entry_get(int unit, int index, int count, void **entries)
   5226 {
   5227     int rv;
   5228     COMMON_LOCK(unit);
   5229     rv = soc_profile_mem_get(unit, ING_VFT_PRI_MAP(unit), index, count,
   5230                              entries);
   5231     COMMON_UNLOCK(unit);
   5232     return rv;
   5233 }
   5234 
   5235 /*
   5236  * Function:
   5237  *      _bcm_ing_vft_pri_map_entry_reference
   5238  * Purpose:
   5239  *      Internal function for indicating that an entry in ING_VFT_PRI table
   5240  *      is being used. Updates the global shared SW copy.
   5241  * Parameters:
   5242  *      unit    -  (IN) Device number
   5243  *      index   -  (IN) Base index for the entry to be updated
   5244  * Returns:
   5245  *      BCM_X_XXX
   5246  */
   5247 int
   5248 _bcm_ing_vft_pri_map_entry_reference(int unit, int index,
   5249                                      int entries_per_set_override) 
   5250 {
   5251     int rv;
   5252     COMMON_LOCK(unit);
   5253     rv = soc_profile_mem_reference(unit, ING_VFT_PRI_MAP(unit), index, 
   5254                                    entries_per_set_override);
   5255     COMMON_UNLOCK(unit);
   5256     return rv;
   5257 }
   5258 
   5259 
   5260 /*
   5261  * Function: 
   5262  *     _bcm_ing_l2_vlan_etag_map_entry_get
   5263  * Purpose:
   5264  *     Get a set of entries from the ING_ETAG_PCP_MAPPING table.
   5265  * Parameters:
   5266  *     unit    - (IN)  Device number.
   5267  *     index   - (IN)  Base index for the entries to be retrieved
   5268  *     count   - (IN)  Number of entries in the set
   5269  *     entries - (OUT) Array of pointer to table entries set
   5270  * Returns:
   5271  *     BCM_E_XXX
   5272  */
   5273 int
   5274 _bcm_ing_l2_vlan_etag_map_entry_get(int unit, int index, 
   5275                                               int count, void **entries)
   5276 {
   5277     int rv;
   5278     COMMON_LOCK(unit);
   5279     rv = soc_profile_mem_get(unit, ING_L2_VLAN_ETAG_MAP(unit), index, count,
   5280                              entries);
   5281     COMMON_UNLOCK(unit);
   5282     return rv;
   5283 }
   5284 
   5285 /*
   5286  * Function:
   5287  *      _bcm_ing_l2_vlan_etag_map_entry_reference
   5288  * Purpose:
   5289  *      Internal function for indicating that an entry in ING_L2_VLAN_ETAG table
   5290  *      is being used. Updates the global shared SW copy.
   5291  * Parameters:
   5292  *      unit    -  (IN) Device number
   5293  *      index   -  (IN) Base index for the entry to be updated
   5294  * Returns:
   5295  *      BCM_X_XXX
   5296  */
   5297 int
   5298 _bcm_ing_l2_vlan_etag_map_entry_reference(int unit, int index,
   5299                                      int entries_per_set_override) 
   5300 {
   5301     int rv;
   5302     COMMON_LOCK(unit);
   5303     rv = soc_profile_mem_reference(unit, ING_L2_VLAN_ETAG_MAP(unit), index, 
   5304                                    entries_per_set_override);
   5305     COMMON_UNLOCK(unit);
   5306     return rv;
   5307 }
   5308 
   5309 /*
   5310  * Function: 
   5311  *     _bcm_egr_vft_pri_map_entry_get
   5312  * Purpose:
   5313  *     Get a set of entries from the EGR_VFT_PRI_MAP table.
   5314  * Parameters:
   5315  *     unit    - (IN)  Device number.
   5316  *     index   - (IN)  Base index for the entries to be retrieved
   5317  *     count   - (IN)  Number of entries in the set
   5318  *     entries - (OUT) Array of pointer to table entries set
   5319  * Returns:
   5320  *     BCM_E_XXX
   5321  */
   5322 int
   5323 _bcm_egr_vft_pri_map_entry_get(int unit, int index, int count, void **entries)
   5324 {
   5325     int rv;
   5326     COMMON_LOCK(unit);
   5327     rv = soc_profile_mem_get(unit, EGR_VFT_PRI_MAP(unit), index, count,
   5328                              entries);
   5329     COMMON_UNLOCK(unit);
   5330     return rv;
   5331 }
   5332 
   5333 /*
   5334  * Function:
   5335  *      _bcm_egr_vft_pri_map_entry_reference
   5336  * Purpose:
   5337  *      Internal function for indicating that an entry in ING_VFT_PRI table
   5338  *      is being used. Updates the global shared SW copy.
   5339  * Parameters:
   5340  *      unit    -  (IN) Device number
   5341  *      index   -  (IN) Base index for the entry to be updated
   5342  * Returns:
   5343  *      BCM_X_XXX
   5344  */
   5345 int
   5346 _bcm_egr_vft_pri_map_entry_reference(int unit, int index,
   5347                                      int entries_per_set_override) 
   5348 {
   5349     int rv;
   5350     COMMON_LOCK(unit);
   5351     rv = soc_profile_mem_reference(unit, EGR_VFT_PRI_MAP(unit), index, 
   5352                                    entries_per_set_override);
   5353     COMMON_UNLOCK(unit);
   5354     return rv;
   5355 }
   5356 
   5357 /*
   5358  * Function: 
   5359  *     _bcm_egr_vft_fields_entry_get
   5360  * Purpose:
   5361  *     Get a set of entries from the EGR_VFT_FIELDS_PROFILE table.
   5362  * Parameters:
   5363  *     unit    - (IN)  Device number.
   5364  *     index   - (IN)  Base index for the entries to be retrieved
   5365  *     count   - (IN)  Number of entries in the set
   5366  *     entries - (OUT) Array of pointer to table entries set
   5367  * Returns:
   5368  *     BCM_E_XXX
   5369  */
   5370 int
   5371 _bcm_egr_vft_fields_entry_get(int unit, int index, int count, void **entries)
   5372 {
   5373     int rv;
   5374     COMMON_LOCK(unit);
   5375     rv = soc_profile_mem_get(unit, EGR_VFT_FIELDS(unit), index, count,
   5376                              entries);
   5377     COMMON_UNLOCK(unit);
   5378     return rv;
   5379 }
   5380 
   5381 /*
   5382  * Function: 
   5383  *     _bcm_egr_vsan_intpri_map_entry_get
   5384  * Purpose:
   5385  *     Get a set of entries from the EGR_VSAN_INTPRI_MAP table.
   5386  * Parameters:
   5387  *     unit    - (IN)  Device number.
   5388  *     index   - (IN)  Base index for the entries to be retrieved
   5389  *     count   - (IN)  Number of entries in the set
   5390  *     entries - (OUT) Array of pointer to table entries set
   5391  * Returns:
   5392  *     BCM_E_XXX
   5393  */
   5394 int
   5395 _bcm_egr_vsan_intpri_map_entry_get(int unit, int index, int count, 
   5396                                    void **entries)
   5397 {
   5398     int rv;
   5399     COMMON_LOCK(unit);
   5400     rv = soc_profile_mem_get(unit, EGR_VSAN_INTPRI_MAP(unit), index, count,
   5401                              entries);
   5402     COMMON_UNLOCK(unit);
   5403     return rv;
   5404 }
   5405 
   5406 /*
   5407  * Function:
   5408  *      _bcm_egr_vft_fields_entry_reference
   5409  * Purpose:
   5410  *      Internal function for indicating that an entry in EGR_VFT_FIELDS_PROFILE table
   5411  *      is being used. Updates the global shared SW copy.
   5412  * Parameters:
   5413  *      unit    -  (IN) Device number
   5414  *      index   -  (IN) Base index for the entry to be updated
   5415  * Returns:
   5416  *      BCM_X_XXX
   5417  */
   5418 int
   5419 _bcm_egr_vft_fields_entry_reference(int unit, int index,
   5420                                     int entries_per_set_override)
   5421 {
   5422     int rv;
   5423     COMMON_LOCK(unit);
   5424     rv = soc_profile_mem_reference(unit, EGR_VFT_FIELDS(unit), index,
   5425                                    entries_per_set_override);
   5426     COMMON_UNLOCK(unit);
   5427     return rv;
   5428 }
   5429 
   5430 /*
   5431  * Function:
   5432  *      _bcm_egr_vsan_intpri_map_entry_reference
   5433  * Purpose:
   5434  *      Internal function for indicating that an entry in EGR_VSAN_INT_PRI table
   5435  *      is being used. Updates the global shared SW copy.
   5436  * Parameters:
   5437  *      unit    -  (IN) Device number
   5438  *      index   -  (IN) Base index for the entry to be updated
   5439  * Returns:
   5440  *      BCM_X_XXX
   5441  */
   5442 int
   5443 _bcm_egr_vsan_intpri_map_entry_reference(int unit, int index,
   5444                                      int entries_per_set_override) 
   5445 {
   5446     int rv;
   5447     COMMON_LOCK(unit);
   5448     rv = soc_profile_mem_reference(unit, EGR_VSAN_INTPRI_MAP(unit), index, 
   5449                                    entries_per_set_override);
   5450     COMMON_UNLOCK(unit);
   5451     return rv;
   5452 }
   5453 
   5454 /*
   5455  * Function: 
   5456  *     _bcm_egr_l2_vlan_etag_map_entry_get
   5457  * Purpose:
   5458  *     Get a set of entries from the EGR_ETAG_PCP_MAPPING table.
   5459  * Parameters:
   5460  *     unit    - (IN)  Device number.
   5461  *     index   - (IN)  Base index for the entries to be retrieved
   5462  *     count   - (IN)  Number of entries in the set
   5463  *     entries - (OUT) Array of pointer to table entries set
   5464  * Returns:
   5465  *     BCM_E_XXX
   5466  */
   5467 int
   5468 _bcm_egr_l2_vlan_etag_map_entry_get(int unit, int index, 
   5469                                               int count, void **entries)
   5470 {
   5471     int rv;
   5472     COMMON_LOCK(unit);
   5473     rv = soc_profile_mem_get(unit, EGR_L2_VLAN_ETAG_MAP(unit), index, count,
   5474                              entries);
   5475     COMMON_UNLOCK(unit);
   5476     return rv;
   5477 }
   5478 
   5479 /*
   5480  * Function:
   5481  *      _bcm_egr_l2_vlan_etag_map_entry_reference
   5482  * Purpose:
   5483  *      Internal function for indicating that an entry in EGR_L2_VLAN_ETAG table
   5484  *      is being used. Updates the global shared SW copy.
   5485  * Parameters:
   5486  *      unit    -  (IN) Device number
   5487  *      index   -  (IN) Base index for the entry to be updated
   5488  * Returns:
   5489  *      BCM_X_XXX
   5490  */
   5491 int
   5492 _bcm_egr_l2_vlan_etag_map_entry_reference(int unit, int index,
   5493                                      int entries_per_set_override) 
   5494 {
   5495     int rv;
   5496     COMMON_LOCK(unit);
   5497     rv = soc_profile_mem_reference(unit, EGR_L2_VLAN_ETAG_MAP(unit), index, 
   5498                                    entries_per_set_override);
   5499     COMMON_UNLOCK(unit);
   5500     return rv;
   5501 }
   5502 
   5503 /*
   5504  * Function:
   5505  *      _bcm_ing_pri_cng_map_entry_add
   5506  * Purpose:
   5507  *      Internal function for adding an entry to the ING_PRI_CNG_MAP table
   5508  *      Adds an entry to the global shared SW copy of the ING_PRI_CNG_MAP table
   5509  *      Shared by several applications.
   5510  * Parameters:
   5511  *      unit    -  (IN) Device number.
   5512  *      entries -  (IN) Array of pointer to table entries set
   5513  *      entries_per_set - (IN)  Number of entries in the set
   5514  *      index   -  (OUT) Base index for the entires allocated in HW
   5515  * Returns:
   5516  *      BCM_X_XXX
   5517  */
   5518 int
   5519 _bcm_ing_pri_cng_map_entry_add(int unit, void **entries, 
   5520                               int entries_per_set, uint32 *index)
   5521 {
   5522     int rv;
   5523     COMMON_LOCK(unit);
   5524     rv = soc_profile_mem_add(unit, ING_PRI_CNG_MAP(unit), entries,
   5525                              entries_per_set, index);
   5526     COMMON_UNLOCK(unit);
   5527     return rv;
   5528 }
   5529 
   5530 /*
   5531  * Function:
   5532  *      _bcm_ing_pri_cng_map_entry_delete
   5533  * Purpose:
   5534  *      Internal function for deleting an entry from the ING_PRI_CNG_MAP table
   5535  *      Deletes an entry from the global shared SW copy of the ING_PRI_CNG_MAP table
   5536  *      Shared by several applications.
   5537  * Parameters:
   5538  *      unit    -  (IN) Device number.
   5539  *      index   -  (IN) Base index for the entry to be deleted
   5540  * Returns:
   5541  *      BCM_X_XXX
   5542  */
   5543 int
   5544 _bcm_ing_pri_cng_map_entry_delete(int unit, int index) 
   5545 {
   5546     int rv;
   5547     COMMON_LOCK(unit);
   5548     rv = soc_profile_mem_delete(unit, ING_PRI_CNG_MAP(unit), index);
   5549     COMMON_UNLOCK(unit);
   5550     return rv;
   5551 }
   5552 
   5553 int
   5554 _bcm_ing_pri_cng_map_entry_get(int unit, int index, int count, void **entries)
   5555 {
   5556     int rv;
   5557     COMMON_LOCK(unit);
   5558     rv = soc_profile_mem_get(unit, ING_PRI_CNG_MAP(unit), index, count,
   5559                              entries);
   5560     COMMON_UNLOCK(unit);
   5561     return rv;
   5562 }
   5563 
   5564 /*
   5565  * Function:
   5566  *      _bcm_ing_pri_cng_map_entry_reference
   5567  * Purpose:
   5568  *      Internal function for indicating that an entry in ING_PRI_CNG_MAP table
   5569  *      is being used. Updates the global shared SW copy.
   5570  * Parameters:
   5571  *      unit    -  (IN) Device number
   5572  *      index   -  (IN) Base index for the entry to be updated
   5573  * Returns:
   5574  *      BCM_X_XXX
   5575  */
   5576 int
   5577 _bcm_ing_pri_cng_map_entry_reference(int unit, int index,
   5578                                      int entries_per_set_override) 
   5579 {
   5580     int rv;
   5581     COMMON_LOCK(unit);
   5582     rv = soc_profile_mem_reference(unit, ING_PRI_CNG_MAP(unit), index, 
   5583                                    entries_per_set_override);
   5584     COMMON_UNLOCK(unit);
   5585     return rv;
   5586 }
   5587 
   5588 /*
   5589  * Function:
   5590  *      _bcm_egr_mpls_combo_map_entry_add
   5591  * Purpose:
   5592  *      Internal function for adding an entry to the combined
   5593  *      EGR_MPLS_PRI_MAPPING and EGR_MPLS_EXP_MAPPING_1 table.
   5594  *      Adds an entry to the global shared SW copy of the combo table
   5595  *      Shared by several applications.
   5596  * Parameters:
   5597  *      unit    -  (IN) Device number.
   5598  *      entries -  (IN) Array of pointer to table entries set
   5599  *      entries_per_set - (IN)  Number of entries in the set
   5600  *      index   -  (OUT) Base index for the entires allocated in HW
   5601  * Returns:
   5602  *      BCM_X_XXX
   5603  */
   5604 int
   5605 _bcm_egr_mpls_combo_map_entry_add(int unit, void **entries, 
   5606                                 int entries_per_set, uint32 *index)
   5607 {
   5608     int rv;
   5609     COMMON_LOCK(unit);
   5610     rv = soc_profile_mem_add(unit, EGR_MPLS_COMBO_MAP(unit), entries,
   5611                              entries_per_set, index);
   5612     COMMON_UNLOCK(unit);
   5613     return rv;
   5614 }
   5615 
   5616 /*
   5617  * Function:
   5618  *      _bcm_egr_mpls_combo_map_entry_update
   5619  * Purpose:
   5620  *      Internal function for updating an entry to the combined
   5621  *      EGR_MPLS_PRI_MAPPING and EGR_MPLS_EXP_MAPPING_1 table.
   5622  *      Shared by several applications.
   5623  * Parameters:
   5624  *      unit    -  (IN) Device number.
   5625  *      entries -  (IN) Array of pointer to table entries set
   5626  *      index   -  (OUT) Base index to update
   5627  * Returns:
   5628  *      BCM_X_XXX
   5629  */
   5630 int
   5631 _bcm_egr_mpls_combo_map_entry_update(int unit, void **entries, 
   5632                                      uint32 index)
   5633 {
   5634     int rv;
   5635     COMMON_LOCK(unit);
   5636     rv = soc_profile_mem_set(unit, EGR_MPLS_COMBO_MAP(unit), entries,
   5637                              index);
   5638     COMMON_UNLOCK(unit);
   5639     return rv;
   5640 }
   5641 
   5642 /*
   5643  * Function:
   5644  *      _bcm_egr_mpls_combo_map_entry_delete
   5645  * Purpose:
   5646  *      Internal function for deleting an entry from the combined
   5647  *      EGR_MPLS_PRI_MAPPING and EGR_MPLS_EXP_MAPPING_1 table.
   5648  *      Deletes an entry from the global shared SW copy of the combo table
   5649  *      Shared by several applications.
   5650  * Parameters:
   5651  *      unit    -  (IN) Device number.
   5652  *      entries -  (IN) Array of pointer to table entries set
   5653  *      entries_per_set - (IN)  Number of entries in the set
   5654  *      index   -  (OUT) Base index for the entires allocated in HW
   5655  * Returns:
   5656  *      BCM_X_XXX
   5657  */
   5658 int
   5659 _bcm_egr_mpls_combo_map_entry_delete(int unit, int index) 
   5660 {
   5661     int rv;
   5662     COMMON_LOCK(unit);
   5663     rv = soc_profile_mem_delete(unit, EGR_MPLS_COMBO_MAP(unit), index);
   5664     COMMON_UNLOCK(unit);
   5665     return rv;
   5666 }
   5667 
   5668 /*
   5669  * Function:
   5670  *      _bcm_egr_mpls_combo_map_entry_reference
   5671  * Purpose:
   5672  *      Internal function for indicating an entry in the combined
   5673  *      EGR_MPLS_PRI_MAPPING and EGR_MPLS_EXP_MAPPING_1 table
   5674  *      is being used. Updates global shared SW copy.
   5675  * Parameters:
   5676  *      unit    -  (IN) Device number.
   5677  *      index   -  (IN) Base index for the entry to be updated
   5678  * Returns:
   5679  *      BCM_X_XXX
   5680  */
   5681 int
   5682 _bcm_egr_mpls_combo_map_entry_reference(int unit, int index, 
   5683                                         int entries_per_set_override) 
   5684 {
   5685     int rv;
   5686     COMMON_LOCK(unit);
   5687     rv = soc_profile_mem_reference(unit, EGR_MPLS_COMBO_MAP(unit), index, 
   5688                                    entries_per_set_override);
   5689     COMMON_UNLOCK(unit);
   5690     return rv;
   5691 }
   5692 
   5693 /*
   5694  * Function:
   5695  *      _bcm_egr_mpls_combo_map_entry_write_mode_get
   5696  * Purpose:
   5697  *      Internal function to get write mode of
   5698  *      EGR_MPLS_PRI_MAPPING and EGR_MPLS_EXP_MAPPING_1 table.
   5699  * Parameters:
   5700  *      unit    -  (IN) Device number.
   5701  *      index   -  (IN) Base index to get
   5702  *      mode    -  (OUT) table write mode
   5703  * Returns:
   5704  *      BCM_X_XXX
   5705  */
   5706 int
   5707 _bcm_egr_mpls_combo_map_entry_write_mode_get(int unit,
   5708         uint32 index, int *mode)
   5709 {
   5710     int rv;
   5711     COMMON_LOCK(unit);
   5712     rv = soc_profile_mem_write_mode_get(unit, EGR_MPLS_COMBO_MAP(unit),
   5713             index, mode);
   5714     COMMON_UNLOCK(unit);
   5715     return rv;
   5716 }
   5717 
   5718 /*
   5719  * Function:
   5720  *      _bcm_dscp_table_entry_add
   5721  * Purpose:
   5722  *      Internal function for adding an entry to the DSCP_TABLE table
   5723  *      Adds an entry to the global shared SW copy of the DSCP_TABLE table
   5724  *      Shared by several applications.
   5725  * Parameters:
   5726  *      unit    -  (IN) Device number.
   5727  *      entries -  (IN) Array of pointer to table entries set
   5728  *      entries_per_set - (IN)  Number of entries in the set
   5729  *      index   -  (OUT) Base index for the entires allocated in HW
   5730  * Returns:
   5731  *      BCM_X_XXX
   5732  */
   5733 int
   5734 _bcm_dscp_table_entry_add(int unit, void **entries, 
   5735                               int entries_per_set, uint32 *index)
   5736 {
   5737     int rv;
   5738     COMMON_LOCK(unit);
   5739     rv = soc_profile_mem_add(unit, DSCP_TABLE(unit), entries,
   5740                              entries_per_set, index);
   5741     COMMON_UNLOCK(unit);
   5742     return rv;
   5743 }
   5744 
   5745 /*
   5746  * Function:
   5747  *      _bcm_dscp_table_entry_delete
   5748  * Purpose:
   5749  *      Internal function for deleting an entry from the DSCP_TABLE table
   5750  *      Deletes an entry from the global shared SW copy of the DSCP_TABLE table
   5751  *      Shared by several applications.
   5752  * Parameters:
   5753  *      unit    -  (IN) Device number.
   5754  *      index   -  (IN) Base index for the entry to be deleted
   5755  * Returns:
   5756  *      BCM_X_XXX
   5757  */
   5758 int
   5759 _bcm_dscp_table_entry_delete(int unit, int index) 
   5760 {
   5761     int rv;
   5762     COMMON_LOCK(unit);
   5763     rv = soc_profile_mem_delete(unit, DSCP_TABLE(unit), index);
   5764     COMMON_UNLOCK(unit);
   5765     return rv;
   5766 }
   5767 
   5768 /*
   5769  * Function:
   5770  *      _bcm_dscp_table_entry_reference
   5771  * Purpose:
   5772  *      Internal function for indicating an entry in the DSCP_TABLE table
   5773  *      is being used. Updates the global shared SW copy
   5774  * Parameters:
   5775  *      unit    -  (IN) Device number.
   5776  *      index   -  (IN) Base index for the entry to be updated
   5777  * Returns:
   5778  *      BCM_X_XXX
   5779  */
   5780 int
   5781 _bcm_dscp_table_entry_reference(int unit, int index, 
   5782                                 int entries_per_set_override) 
   5783 {
   5784     int rv;
   5785     COMMON_LOCK(unit);
   5786     rv = soc_profile_mem_reference(unit, DSCP_TABLE(unit), index, 
   5787                                    entries_per_set_override);
   5788     COMMON_UNLOCK(unit);
   5789     return rv;
   5790 }
   5791 
   5792 int
   5793 _bcm_dscp_table_entry_ref_count_get(int unit, uint32 index,
   5794                                                 int* ref_count)
   5795 {
   5796     int rv;
   5797     rv = soc_profile_mem_ref_count_get(unit,
   5798                                        DSCP_TABLE(unit), index, ref_count);
   5799     return rv;
   5800 }
   5801 
   5802 int
   5803 _bcm_dscp_table_entry_get(int unit, int index, int count, void **entries)
   5804 {
   5805     int rv;
   5806     COMMON_LOCK(unit);
   5807     rv = soc_profile_mem_get(unit, DSCP_TABLE(unit), index, count,
   5808                              entries);
   5809     COMMON_UNLOCK(unit);
   5810     return rv;
   5811 }
   5812 
   5813 int
   5814 _bcm_dscp_table_entry_range(int unit, int *index_min, int *index_max)
   5815 {
   5816     if (DSCP_TABLE(unit) == NULL) {
   5817         return BCM_E_INIT;
   5818     }
   5819 
   5820     if (index_min) {
   5821         *index_min = DSCP_TABLE(unit)->tables[0].index_min;
   5822     }
   5823 
   5824     if (index_max) {
   5825         *index_max = DSCP_TABLE(unit)->tables[0].index_max;
   5826     }
   5827     return BCM_E_NONE;
   5828 }
   5829 /*
   5830  * Function:
   5831  *      _bcm_egr_dscp_table_entry_add
   5832  * Purpose:
   5833  *      Internal function for adding an entry to the EGR_DSCP_TABLE table
   5834  *      Adds an entry to the global shared SW copy of the EGR_DSCP_TABLE table
   5835  *      Shared by several applications.
   5836  * Parameters:
   5837  *      unit    -  (IN) Device number.
   5838  *      entries -  (IN) Array of pointer to table entries set
   5839  *      entries_per_set - (IN)  Number of entries in the set
   5840  *      index   -  (OUT) Base index for the entires allocated in HW
   5841  * Returns:
   5842  *      BCM_X_XXX
   5843  */
   5844 int
   5845 _bcm_egr_dscp_table_entry_add(int unit, void **entries, 
   5846                               int entries_per_set, uint32 *index, uint32 flags)
   5847 {
   5848     int rv;
   5849     int old_flags;
   5850     COMMON_LOCK(unit);
   5851     old_flags = EGR_DSCP_TABLE(unit)->flags;
   5852     EGR_DSCP_TABLE(unit)->flags = flags;
   5853     rv = soc_profile_mem_add(unit, EGR_DSCP_TABLE(unit), entries,
   5854                              entries_per_set, index);
   5855     EGR_DSCP_TABLE(unit)->flags = old_flags;
   5856     COMMON_UNLOCK(unit);
   5857     return rv;
   5858 }
   5859 
   5860 /*
   5861  * Function:
   5862  *      _bcm_egr_dscp_table_entry_delete
   5863  * Purpose:
   5864  *      Internal function for deleting an entry from the EGR_DSCP_TABLE table
   5865  *      Deletes an entry from the global shared SW copy of the EGR_DSCP_TABLE table
   5866  *      Shared by several applications.
   5867  * Parameters:
   5868  *      unit    -  (IN) Device number.
   5869  *      index   -  (IN) Base index for the entry to be deleted
   5870  * Returns:
   5871  *      BCM_X_XXX
   5872  */
   5873 int
   5874 _bcm_egr_dscp_table_entry_delete(int unit, int index) 
   5875 {
   5876     int rv;
   5877     COMMON_LOCK(unit);
   5878     rv = soc_profile_mem_delete(unit, EGR_DSCP_TABLE(unit), index);
   5879     COMMON_UNLOCK(unit);
   5880     return rv;
   5881 }
   5882 
   5883 /*
   5884  * Function:
   5885  *      _bcm_egr_dscp_table_entry_reference
   5886  * Purpose:
   5887  *      Internal function for indicating an entry from the EGR_DSCP_TABLE table
   5888  *      is being used. Updates the global shared SW copy
   5889  * Parameters:
   5890  *      unit    -  (IN) Device number.
   5891  *      index   -  (IN) Base index for the entry to be updated
   5892  * Returns:
   5893  *      BCM_X_XXX
   5894  */
   5895 int
   5896 _bcm_egr_dscp_table_entry_reference(int unit, int index, 
   5897                                     int entries_per_set_override) 
   5898 {
   5899     int rv;
   5900     COMMON_LOCK(unit);
   5901     rv = soc_profile_mem_reference(unit, EGR_DSCP_TABLE(unit), index, 
   5902                                    entries_per_set_override);
   5903     COMMON_UNLOCK(unit);
   5904     return rv;
   5905 }
   5906 
   5907 int
   5908 _bcm_egr_dscp_table_entry_ref_count_get(int unit, uint32 index,
   5909                                                       int *ref_count)
   5910 {
   5911     int rv;
   5912     rv = soc_profile_mem_ref_count_get(unit,
   5913                                        EGR_DSCP_TABLE(unit), index, ref_count);
   5914     return rv;
   5915 }
   5916 
   5917 
   5918 /*
   5919  * Function:
   5920  *      _bcm_egr_dscp_table_entry_set
   5921  * Purpose:
   5922  *      Internal function for setting an entry to the EGR_DSCP_TABLE table
   5923  *      Sets an entry to the global shared SW copy of the EGR_DSCP_TABLE table
   5924  * Parameters:
   5925  *      unit    -  (IN) Device number.
   5926  *      entries -  (IN) Array of pointer to table entries set
   5927  *      index   -  (IN) Base index for the entires allocated in HW
   5928  * Returns:
   5929  *      BCM_X_XXX
   5930  */
   5931 int
   5932 _bcm_egr_dscp_table_entry_set(int unit, void **entries, uint32 index)
   5933 {
   5934     int rv;
   5935     COMMON_LOCK(unit);
   5936     rv = soc_profile_mem_set(unit, EGR_DSCP_TABLE(unit), entries, index);
   5937     COMMON_UNLOCK(unit);
   5938     return rv;
   5939 }
   5940 
   5941 int
   5942 _bcm_egr_dscp_table_entry_get(int unit, int index, int count, void **entries)
   5943 {
   5944     int rv;
   5945     COMMON_LOCK(unit);
   5946     rv = soc_profile_mem_get(unit, EGR_DSCP_TABLE(unit), index, count,
   5947                              entries);
   5948     COMMON_UNLOCK(unit);
   5949     return rv;
   5950 }
   5951 
   5952 
   5953 int
   5954 _bcm_prot_pkt_ctrl_add(int unit, uint32 prot_pkt_ctrl,
   5955                        uint32 igmp_mld_pkt_ctrl, uint32 *index)
   5956 {
   5957     int rv;
   5958     uint64 rval64[2], *rval64s[2];
   5959 
   5960     COMPILER_64_SET(rval64[0], 0, prot_pkt_ctrl);
   5961     COMPILER_64_SET(rval64[1], 0, igmp_mld_pkt_ctrl);
   5962     rval64s[0] = &rval64[0];
   5963     rval64s[1] = &rval64[1];
   5964 
   5965     COMMON_LOCK(unit);
   5966     rv = soc_profile_reg_add(unit, PROT_PKT_CTRL(unit), rval64s, 1, index);
   5967     COMMON_UNLOCK(unit);
   5968 
   5969     return rv;
   5970 }
   5971 
   5972 int
   5973 _bcm_prot_pkt_ctrl_delete(int unit, uint32 index)
   5974 {
   5975     int rv;
   5976 
   5977     COMMON_LOCK(unit);
   5978     rv = soc_profile_reg_delete(unit, PROT_PKT_CTRL(unit), index);
   5979     COMMON_UNLOCK(unit);
   5980 
   5981     return rv;
   5982 }
   5983 
   5984 int
   5985 _bcm_prot_pkt_ctrl_get(int unit, uint32 index, uint32 *prot_pkt_ctrl,
   5986                        uint32 *igmp_mld_pkt_ctrl)
   5987 {
   5988     int rv;
   5989     uint64 rval64[2], *rval64s[2];
   5990 
   5991     rval64s[0] = &rval64[0];
   5992     rval64s[1] = &rval64[1];
   5993 
   5994     COMMON_LOCK(unit);
   5995     rv = soc_profile_reg_get(unit, PROT_PKT_CTRL(unit), index, 1, rval64s);
   5996     COMMON_UNLOCK(unit);
   5997 
   5998     if (BCM_SUCCESS(rv)) {
   5999         *prot_pkt_ctrl = COMPILER_64_LO(rval64[0]);
   6000         *igmp_mld_pkt_ctrl = COMPILER_64_LO(rval64[1]);
   6001     }
   6002 
   6003     return rv;
   6004 }
   6005 
   6006 int
   6007 _bcm_prot_pkt_ctrl_reference(int unit, uint32 index)
   6008 {
   6009     int rv;
   6010 
   6011     COMMON_LOCK(unit);
   6012     rv = soc_profile_reg_reference(unit, PROT_PKT_CTRL(unit), index, 1);
   6013     COMMON_UNLOCK(unit);
   6014 
   6015     return rv;
   6016 }
   6017 
   6018 int
   6019 _bcm_prot_pkt_ctrl_ref_count_get(int unit, uint32 index,
   6020                                                 int* ref_count)
   6021 {
   6022     int rv;
   6023     COMMON_LOCK(unit);
   6024     rv = soc_profile_reg_ref_count_get(unit,
   6025                                        PROT_PKT_CTRL(unit), index, ref_count);
   6026     COMMON_UNLOCK(unit);
   6027 
   6028     return rv;
   6029 }
   6030 #ifdef BCM_TOMAHAWK_SUPPORT
   6031 /*
   6032  * Function:
   6033  *      _bcm_ing_tunnel_term_map_entry_add
   6034  * Purpose:
   6035  *      Internal function for adding an entry to the ING_TUNNEL_ECN_DECAP table
   6036  *      Adds an entry to the global shared SW copy of the ING_TUNNEL_ECN_DECAP table
   6037  *      Shared by several applications.
   6038  * Parameters:
   6039  *      unit    -  (IN) Device number.
   6040  *      entries -  (IN) Array of pointer to table entries set
   6041  *      entries_per_set - (IN)  Number of entries in the set
   6042  *      index   -  (OUT) Base index for the entires allocated in HW
   6043  * Returns:
   6044  *      BCM_X_XXX
   6045  */
   6046 int
   6047 _bcm_ing_tunnel_term_map_entry_add(int unit, void **entries, 
   6048                               int entries_per_set, uint32 *index)
   6049 {
   6050     int rv;
   6051     COMMON_LOCK(unit);
   6052     rv = soc_profile_mem_add(unit, ING_TUNNEL_TERM_MAP(unit), entries,
   6053                              entries_per_set, index);
   6054     COMMON_UNLOCK(unit);
   6055     return rv;
   6056 }
   6057 
   6058 /*
   6059  * Function:
   6060  *      _bcm_ing_tunnel_term_map_entry_delete
   6061  * Purpose:
   6062  *      Internal function for deleting an entry from the ING_TUNNEL_ECN_DECAP table
   6063  *      Deletes an entry from the global shared SW copy of the ING_TUNNEL_ECN_DECAP table
   6064  *      Shared by several applications.
   6065  * Parameters:
   6066  *      unit    -  (IN) Device number.
   6067  *      index   -  (IN) Base index for the entry to be deleted
   6068  * Returns:
   6069  *      BCM_X_XXX
   6070  */
   6071 int
   6072 _bcm_ing_tunnel_term_map_entry_delete(int unit, int index) 
   6073 {
   6074     int rv;
   6075     COMMON_LOCK(unit);
   6076     rv = soc_profile_mem_delete(unit, ING_TUNNEL_TERM_MAP(unit), index);
   6077     COMMON_UNLOCK(unit);
   6078     return rv;
   6079 }
   6080 
   6081 int
   6082 _bcm_ing_tunnel_term_map_entry_get(int unit, int index, int count, void **entries)
   6083 {
   6084     int rv;
   6085     COMMON_LOCK(unit);
   6086     rv = soc_profile_mem_get(unit, ING_TUNNEL_TERM_MAP(unit), index, count,
   6087                              entries);
   6088     COMMON_UNLOCK(unit);
   6089     return rv;
   6090 }
   6091 
   6092 /*
   6093  * Function:
   6094  *      _bcm_ing_tunnel_term_map_entry_reference
   6095  * Purpose:
   6096  *      Internal function for indicating that an entry in ING_TUNNEL_ECN_DECAP table
   6097  *      is being used. Updates the global shared SW copy.
   6098  * Parameters:
   6099  *      unit    -  (IN) Device number
   6100  *      index   -  (IN) Base index for the entry to be updated
   6101  * Returns:
   6102  *      BCM_X_XXX
   6103  */
   6104 int
   6105 _bcm_ing_tunnel_term_map_entry_reference(int unit, int index,
   6106                                      int entries_per_set_override) 
   6107 {
   6108     int rv;
   6109     COMMON_LOCK(unit);
   6110     rv = soc_profile_mem_reference(unit, ING_TUNNEL_TERM_MAP(unit), index, 
   6111                                    entries_per_set_override);
   6112     COMMON_UNLOCK(unit);
   6113     return rv;
   6114 }
   6115 #endif /* BCM_TOMAHAWK_SUPPORT */
   6116 
   6117 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
   6118     defined(BCM_TRIDENT3_SUPPORT) 
   6119 /*
   6120  * Function:
   6121  *      _bcm_ing_exp_to_ip_ecn_map_entry_add
   6122  * Purpose:
   6123  *      Internal function for adding an entry to the ING_EXP_TO_IP_ECN_MAPPING table
   6124  *      Adds an entry to the global shared SW copy of the ING_EXP_TO_IP_ECN_MAPPING table
   6125  *      Shared by several applications.
   6126  * Parameters:
   6127  *      unit    -  (IN) Device number.
   6128  *      entries -  (IN) Array of pointer to table entries set
   6129  *      entries_per_set - (IN)  Number of entries in the set
   6130  *      index   -  (OUT) Base index for the entires allocated in HW
   6131  * Returns:
   6132  *      BCM_X_XXX
   6133  */
   6134 int
   6135 _bcm_ing_exp_to_ip_ecn_map_entry_add(int unit, void **entries, 
   6136                               int entries_per_set, uint32 *index)
   6137 {
   6138     int rv;
   6139     COMMON_LOCK(unit);
   6140     rv = soc_profile_mem_add(unit, ING_EXP_TO_IP_ECN_MAP(unit), entries,
   6141                              entries_per_set, index);
   6142     COMMON_UNLOCK(unit);
   6143     return rv;
   6144 }
   6145 
   6146 /*
   6147  * Function:
   6148  *      _bcm_ing_exp_to_ip_ecn_map_entry_delete
   6149  * Purpose:
   6150  *      Internal function for deleting an entry from the ING_EXP_TO_IP_ECN_MAPPING table
   6151  *      Deletes an entry from the global shared SW copy of the ING_EXP_TO_IP_ECN_MAPPING table
   6152  *      Shared by several applications.
   6153  * Parameters:
   6154  *      unit    -  (IN) Device number.
   6155  *      index   -  (IN) Base index for the entry to be deleted
   6156  * Returns:
   6157  *      BCM_X_XXX
   6158  */
   6159 int
   6160 _bcm_ing_exp_to_ip_ecn_map_entry_delete(int unit, int index) 
   6161 {
   6162     int rv;
   6163     COMMON_LOCK(unit);
   6164     rv = soc_profile_mem_delete(unit, ING_EXP_TO_IP_ECN_MAP(unit), index);
   6165     COMMON_UNLOCK(unit);
   6166     return rv;
   6167 }
   6168 
   6169 int
   6170 _bcm_ing_exp_to_ip_ecn_map_entry_get(int unit, int index, int count, void **entries)
   6171 {
   6172     int rv;
   6173     COMMON_LOCK(unit);
   6174     rv = soc_profile_mem_get(unit, ING_EXP_TO_IP_ECN_MAP(unit), index, count,
   6175                              entries);
   6176     COMMON_UNLOCK(unit);
   6177     return rv;
   6178 }
   6179 
   6180 /*
   6181  * Function:
   6182  *      _bcm_ing_exp_to_ip_ecn_map_entry_reference
   6183  * Purpose:
   6184  *      Internal function for indicating that an entry in ING_EXP_TO_IP_ECN_MAPPING table
   6185  *      is being used. Updates the global shared SW copy.
   6186  * Parameters:
   6187  *      unit    -  (IN) Device number
   6188  *      index   -  (IN) Base index for the entry to be updated
   6189  * Returns:
   6190  *      BCM_X_XXX
   6191  */
   6192 int
   6193 _bcm_ing_exp_to_ip_ecn_map_entry_reference(int unit, int index,
   6194                                      int entries_per_set_override) 
   6195 {
   6196     int rv;
   6197     COMMON_LOCK(unit);
   6198     rv = soc_profile_mem_reference(unit, ING_EXP_TO_IP_ECN_MAP(unit), index, 
   6199                                    entries_per_set_override);
   6200     COMMON_UNLOCK(unit);
   6201     return rv;
   6202 }
   6203 
   6204 /*
   6205  * Function:
   6206  *      _bcm_egr_ip_ecn_to_exp_map_entry_add
   6207  * Purpose:
   6208  *      Internal function for adding an entry to the EGR_IP_ECN_TO_EXP_MAPPING table
   6209  *      Adds an entry to the global shared SW copy of the EGR_IP_ECN_TO_EXP_MAPPING table
   6210  *      Shared by several applications.
   6211  * Parameters:
   6212  *      unit    -  (IN) Device number.
   6213  *      entries -  (IN) Array of pointer to table entries set
   6214  *      entries_per_set - (IN)  Number of entries in the set
   6215  *      index   -  (OUT) Base index for the entires allocated in HW
   6216  * Returns:
   6217  *      BCM_X_XXX
   6218  */
   6219 int
   6220 _bcm_egr_ip_ecn_to_exp_map_entry_add(int unit, void **entries, 
   6221                               int entries_per_set, uint32 *index)
   6222 {
   6223     int rv;
   6224     COMMON_LOCK(unit);
   6225     rv = soc_profile_mem_add(unit, EGR_IP_ECN_TO_EXP_MAP(unit), entries,
   6226                              entries_per_set, index);
   6227     COMMON_UNLOCK(unit);
   6228     return rv;
   6229 }
   6230 
   6231 /*
   6232  * Function:
   6233  *      _bcm_egr_ip_ecn_to_exp_map_entry_delete
   6234  * Purpose:
   6235  *      Internal function for deleting an entry from the EGR_IP_ECN_TO_EXP_MAPPING table
   6236  *      Deletes an entry from the global shared SW copy of the EGR_IP_ECN_TO_EXP_MAPPING table
   6237  *      Shared by several applications.
   6238  * Parameters:
   6239  *      unit    -  (IN) Device number.
   6240  *      index   -  (IN) Base index for the entry to be deleted
   6241  * Returns:
   6242  *      BCM_X_XXX
   6243  */
   6244 int
   6245 _bcm_egr_ip_ecn_to_exp_map_entry_delete(int unit, int index) 
   6246 {
   6247     int rv;
   6248     COMMON_LOCK(unit);
   6249     rv = soc_profile_mem_delete(unit, EGR_IP_ECN_TO_EXP_MAP(unit), index);
   6250     COMMON_UNLOCK(unit);
   6251     return rv;
   6252 }
   6253 
   6254 int
   6255 _bcm_egr_ip_ecn_to_exp_map_entry_get(int unit, int index, int count, void **entries)
   6256 {
   6257     int rv;
   6258     COMMON_LOCK(unit);
   6259     rv = soc_profile_mem_get(unit, EGR_IP_ECN_TO_EXP_MAP(unit), index, count,
   6260                              entries);
   6261     COMMON_UNLOCK(unit);
   6262     return rv;
   6263 }
   6264 
   6265 /*
   6266  * Function:
   6267  *      _bcm_egr_ip_ecn_to_exp_map_entry_reference
   6268  * Purpose:
   6269  *      Internal function for indicating that an entry in EGR_IP_ECN_TO_EXP_MAPPING table
   6270  *      is being used. Updates the global shared SW copy.
   6271  * Parameters:
   6272  *      unit    -  (IN) Device number
   6273  *      index   -  (IN) Base index for the entry to be updated
   6274  * Returns:
   6275  *      BCM_X_XXX
   6276  */
   6277 int
   6278 _bcm_egr_ip_ecn_to_exp_map_entry_reference(int unit, int index,
   6279                                      int entries_per_set_override) 
   6280 {
   6281     int rv;
   6282     COMMON_LOCK(unit);
   6283     rv = soc_profile_mem_reference(unit, EGR_IP_ECN_TO_EXP_MAP(unit), index, 
   6284                                    entries_per_set_override);
   6285     COMMON_UNLOCK(unit);
   6286     return rv;
   6287 }
   6288 
   6289 /*
   6290  * Function:
   6291  *      _bcm_egr_int_cn_to_exp_map_entry_add
   6292  * Purpose:
   6293  *      Internal function for adding an entry to the EGR_INT_CN_TO_EXP_MAPPING table
   6294  *      Adds an entry to the global shared SW copy of the EGR_INT_CN_TO_EXP_MAPPING table
   6295  *      Shared by several applications.
   6296  * Parameters:
   6297  *      unit    -  (IN) Device number.
   6298  *      entries -  (IN) Array of pointer to table entries set
   6299  *      entries_per_set - (IN)  Number of entries in the set
   6300  *      index   -  (OUT) Base index for the entires allocated in HW
   6301  * Returns:
   6302  *      BCM_X_XXX
   6303  */
   6304 int
   6305 _bcm_egr_int_cn_to_exp_map_entry_add(int unit, void **entries, 
   6306                               int entries_per_set, uint32 *index)
   6307 {
   6308     int rv;
   6309     COMMON_LOCK(unit);
   6310     rv = soc_profile_mem_add(unit, EGR_INT_CN_TO_EXP_MAP(unit), entries,
   6311                              entries_per_set, index);
   6312     COMMON_UNLOCK(unit);
   6313     return rv;
   6314 }
   6315 
   6316 /*
   6317  * Function:
   6318  *      _bcm_egr_int_cn_to_exp_map_entry_delete
   6319  * Purpose:
   6320  *      Internal function for deleting an entry from the EGR_INT_CN_TO_EXP_MAPPING table
   6321  *      Deletes an entry from the global shared SW copy of the EGR_INT_CN_TO_EXP_MAPPING table
   6322  *      Shared by several applications.
   6323  * Parameters:
   6324  *      unit    -  (IN) Device number.
   6325  *      index   -  (IN) Base index for the entry to be deleted
   6326  * Returns:
   6327  *      BCM_X_XXX
   6328  */
   6329 int
   6330 _bcm_egr_int_cn_to_exp_map_entry_delete(int unit, int index) 
   6331 {
   6332     int rv;
   6333     COMMON_LOCK(unit);
   6334     rv = soc_profile_mem_delete(unit, EGR_INT_CN_TO_EXP_MAP(unit), index);
   6335     COMMON_UNLOCK(unit);
   6336     return rv;
   6337 }
   6338 
   6339 int
   6340 _bcm_egr_int_cn_to_exp_map_entry_get(int unit, int index, int count, void **entries)
   6341 {
   6342     int rv;
   6343     COMMON_LOCK(unit);
   6344     rv = soc_profile_mem_get(unit, EGR_INT_CN_TO_EXP_MAP(unit), index, count,
   6345                              entries);
   6346     COMMON_UNLOCK(unit);
   6347     return rv;
   6348 }
   6349 
   6350 /*
   6351  * Function:
   6352  *      _bcm_egr_int_cn_to_exp_map_entry_reference
   6353  * Purpose:
   6354  *      Internal function for indicating that an entry in EGR_INT_CN_TO_EXP_MAPPING table
   6355  *      is being used. Updates the global shared SW copy.
   6356  * Parameters:
   6357  *      unit    -  (IN) Device number
   6358  *      index   -  (IN) Base index for the entry to be updated
   6359  * Returns:
   6360  *      BCM_X_XXX
   6361  */
   6362 int
   6363 _bcm_egr_int_cn_to_exp_map_entry_reference(int unit, int index,
   6364                                      int entries_per_set_override) 
   6365 {
   6366     int rv;
   6367     COMMON_LOCK(unit);
   6368     rv = soc_profile_mem_reference(unit, EGR_INT_CN_TO_EXP_MAP(unit), index, 
   6369                                    entries_per_set_override);
   6370     COMMON_UNLOCK(unit);
   6371     return rv;
   6372 }
   6373 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */
   6374 
   6375 
   6376 #ifdef BCM_TRIUMPH3_SUPPORT
   6377 /*
   6378  * Function:
   6379  *      _bcm_ing_l3_nh_attrib_entry_add
   6380  * Purpose:
   6381  *      Internal function for adding an entry to the ING_L3_NEXT_HOP_ATTRIBUTE_1
   6382  *      table. Adds an entry to the global shared SW copy of the
   6383  *      ING_L3_NEXT_HOP_ATTRIBUTE_1 table
   6384  *      Shared by several applications.
   6385  * Parameters:
   6386  *      unit    -  (IN) Device number.
   6387  *      entries -  (IN) Array of pointer to table entries set
   6388  *      entries_per_set - (IN)  Number of entries in the set
   6389  *      index   -  (OUT) Base index for the entires allocated in HW
   6390  * Returns:
   6391  *      BCM_X_XXX
   6392  */
   6393 int
   6394 _bcm_ing_l3_nh_attrib_entry_add(int unit, void **entries, 
   6395                               int entries_per_set, uint32 *index)
   6396 {
   6397     int rv;
   6398     COMMON_LOCK(unit);
   6399     rv = soc_profile_mem_add(unit, ING_L3_NH_ATTRIB_PROFILE(unit), entries,
   6400                              entries_per_set, index);
   6401     COMMON_UNLOCK(unit);
   6402     return rv;
   6403 }
   6404 
   6405 /*
   6406  * Function:
   6407  *      _bcm_ing_l3_nh_attrib_entry_delete
   6408  * Purpose:
   6409  *      Internal function for deleting an entry from the
   6410  *      ING_L3_NEXT_HOP_ATTRIBUTE_1 table Deletes an entry from
   6411  *      the global shared SW copy of the IN_L3_NEXT_HOP_ATTRIBUTE_1 table
   6412  *      Shared by several applications.
   6413  * Parameters:
   6414  *      unit    -  (IN) Device number.
   6415  *      index   -  (IN) Base index for the entry to be deleted
   6416  * Returns:
   6417  *      BCM_X_XXX
   6418  */
   6419 int
   6420 _bcm_ing_l3_nh_attrib_entry_delete(int unit, int index) 
   6421 {
   6422     int rv;
   6423     COMMON_LOCK(unit);
   6424     rv = soc_profile_mem_delete(unit, ING_L3_NH_ATTRIB_PROFILE(unit), index);
   6425     COMMON_UNLOCK(unit);
   6426     return rv;
   6427 }
   6428 
   6429 /*
   6430  * Function:
   6431  *      _bcm_ing_l3_nh_attrib_entry_reference
   6432  * Purpose:
   6433  *      Internal function for indicating an entry in the
   6434  *      IN_L3_NEXT_HOP_ATTRIBUTE_1 table is being used.
   6435  *      Updates the global shared SW copy
   6436  * Parameters:
   6437  *      unit    -  (IN) Device number.
   6438  *      index   -  (IN) Base index for the entry to be updated
   6439  * Returns:
   6440  *      BCM_X_XXX
   6441  */
   6442 int
   6443 _bcm_ing_l3_nh_attrib_entry_reference(int unit, int index, 
   6444                                 int entries_per_set_override) 
   6445 {
   6446     int rv;
   6447     COMMON_LOCK(unit);
   6448     rv = soc_profile_mem_reference(unit, ING_L3_NH_ATTRIB_PROFILE(unit), index, 
   6449                                    entries_per_set_override);
   6450     COMMON_UNLOCK(unit);
   6451     return rv;
   6452 }
   6453 #endif /* BCM_TRIUMPH3_SUPPORT */
   6454 
   6455 
   6456 #ifdef BCM_TRIDENT2_SUPPORT
   6457 /*
   6458  * Function:
   6459  *      _bcm_l3_iif_profile_sw_state_set
   6460  * Purpose:
   6461  *      Internal function for setting sw state for L3_IIF_PROFILE table
   6462  *      It is used in the warmboot recover. entry will not be written 
   6463  *      in hardware. Only software cache will be se and refcount will 
   6464  *      be maintained.
   6465  * Parameters:
   6466  *      unit    -  (IN) Device number.
   6467  *      entries -  (IN) Array of pointer to table entries set
   6468  *      entries_per_set - (IN)  Number of entries in the set
   6469  *      index   -  (IN) Base index for the entires allocated in HW
   6470  * Returns:
   6471  *      BCM_X_XXX
   6472  */
   6473 int
   6474 _bcm_l3_iif_profile_sw_state_set(int unit, void **entries,             
   6475                               int entries_per_set, uint32 index)
   6476 {
   6477     int rv;
   6478     COMMON_LOCK(unit);
   6479     rv = soc_profile_mem_sw_state_set(unit, L3_IIF_PROFILE(unit),
   6480                              entries, entries_per_set, index);
   6481     COMMON_UNLOCK(unit);
   6482     return rv;
   6483 }   
   6484     
   6485 /*
   6486  * Function:
   6487  *      _bcm_l3_iif_profile_entry_add
   6488  * Purpose:
   6489  *      Internal function for adding an entry to the L3_IIF_PROFILE table
   6490  *      Adds an entry to the global shared SW copy of the L3_IIF_PROFILE table
   6491  *      Shared by several applications.
   6492  * Parameters:
   6493  *      unit    -  (IN) Device number.
   6494  *      entries -  (IN) Array of pointer to table entries set
   6495  *      entries_per_set - (IN)  Number of entries in the set
   6496  *      index   -  (OUT) Base index for the entires allocated in HW
   6497  * Returns:
   6498  *      BCM_X_XXX
   6499  */
   6500 int
   6501 _bcm_l3_iif_profile_entry_add(int unit, void **entries, 
   6502                               int entries_per_set, uint32 *index)
   6503 {
   6504     int rv;
   6505     COMMON_LOCK(unit);
   6506     rv = soc_profile_mem_add(unit, L3_IIF_PROFILE(unit), entries,
   6507                              entries_per_set, index);
   6508     COMMON_UNLOCK(unit);
   6509     return rv;
   6510 }
   6511 
   6512 /*
   6513  * Function:
   6514  *      _bcm_l3_iif_profile_entry_delete
   6515  * Purpose:
   6516  *      Internal function for deleting an entry from the L3_IIF_PROFILE table
   6517  *      Deletes an entry from the global shared SW copy of the L3_IIF_PROFILE table
   6518  *      Shared by several applications.
   6519  * Parameters:
   6520  *      unit    -  (IN) Device number.
   6521  *      index   -  (IN) Base index for the entry to be deleted
   6522  * Returns:
   6523  *      BCM_X_XXX
   6524  */
   6525 int
   6526 _bcm_l3_iif_profile_entry_delete(int unit, int index) 
   6527 {
   6528     int rv;
   6529     COMMON_LOCK(unit);
   6530     rv = soc_profile_mem_delete(unit, L3_IIF_PROFILE(unit), index);
   6531     COMMON_UNLOCK(unit);
   6532     return rv;
   6533 }
   6534 
   6535 int
   6536 _bcm_l3_iif_profile_entry_get(int unit, int index, int count, void **entries)
   6537 {
   6538     int rv;
   6539     COMMON_LOCK(unit);
   6540     rv = soc_profile_mem_get(unit, L3_IIF_PROFILE(unit), index, count,
   6541                              entries);
   6542     COMMON_UNLOCK(unit);
   6543     return rv;
   6544 }
   6545 
   6546 /*
   6547  * Function:
   6548  *      _bcm_l3_iif_profile_entry_reference
   6549  * Purpose:
   6550  *      Internal function for indicating an entry in the
   6551  *      L3_IIF_PROFILE table is being used.
   6552  *      Updates the global shared SW copy
   6553  * Parameters:
   6554  *      unit    -  (IN) Device number.
   6555  *      index   -  (IN) Base index for the entry to be updated
   6556  * Returns:
   6557  *      BCM_X_XXX
   6558  */
   6559 int
   6560 _bcm_l3_iif_profile_entry_reference(int unit, int index, 
   6561                                 int entries_per_set_override) 
   6562 {
   6563     int rv;
   6564     COMMON_LOCK(unit);
   6565     rv = soc_profile_mem_reference(unit, L3_IIF_PROFILE(unit), index, 
   6566                                    entries_per_set_override);
   6567     COMMON_UNLOCK(unit);
   6568     return rv;
   6569 }
   6570 
   6571 int
   6572 _bcm_l3_iif_profile_entry_reference_get(int unit, int index, 
   6573                                 int *ref_count) 
   6574 {
   6575     int rv;
   6576     COMMON_LOCK(unit);
   6577     rv = soc_profile_mem_ref_count_get(unit,
   6578                               L3_IIF_PROFILE(unit),
   6579                               index,
   6580                               ref_count);
   6581     COMMON_UNLOCK(unit);
   6582     return rv;
   6583 }
   6584 
   6585 /*
   6586  * Function:
   6587  *      _bcm_l3_iif_profile_entry_update
   6588  * Purpose:
   6589  *      Internal function for updating an entry to the combined
   6590  *      L3_IIF_PROFILE and L3_IIF_PROFILE table.
   6591  *      Shared by several applications.
   6592  * Parameters:
   6593  *      unit    -  (IN) Device number.
   6594  *      entries -  (IN) Array of pointer to table entries set
   6595  *      index   -  (IN) Base index to update
   6596  * Returns:
   6597  *      BCM_X_XXX
   6598  */
   6599 int
   6600 _bcm_l3_iif_profile_entry_update(int unit, void **entries, 
   6601                                      uint32 *index)
   6602 {
   6603     int rv;
   6604     int ref_count;
   6605     void *entries_get[1];
   6606     iif_profile_entry_t l3_iif_profile;
   6607 
   6608     /* Do not overwrite the default enrty */
   6609     if (*index == 0) {
   6610         return BCM_E_INTERNAL;
   6611     }
   6612 
   6613     entries_get[0] = &l3_iif_profile;
   6614     sal_memset(&l3_iif_profile, 0, sizeof(iif_profile_entry_t));
   6615     BCM_IF_ERROR_RETURN
   6616         (_bcm_l3_iif_profile_entry_get(unit, *index, 1, entries_get));
   6617 
   6618     if (!sal_memcmp(entries[0], &l3_iif_profile, sizeof(iif_profile_entry_t))) {
   6619         /* Profile entry needs no update */
   6620         return BCM_E_NONE;
   6621     }
   6622 
   6623     COMMON_LOCK(unit);
   6624    
   6625     rv = soc_profile_mem_ref_count_get(unit, L3_IIF_PROFILE(unit), *index, &ref_count);
   6626     if (SOC_FAILURE(rv)) {
   6627         COMMON_UNLOCK(unit);
   6628         return rv;
   6629     }
   6630 
   6631     if (0 == ref_count) {
   6632        /* Profile entry does not exist */ 
   6633        /* coverity[assigned_value] */
   6634        rv = BCM_E_NOT_FOUND;
   6635     }
   6636     /*
   6637      * Check in profile table if the new entry matches with any other
   6638      * entry. This is important otherwise we may have duplicate entries.
   6639      * profile_add routine will take care of match and will add new entry if 
   6640      * no match is found.
   6641      *
   6642      * The caller has the responsibility to delete the old entry after
   6643      * the new entry is written in the hardware else remove new entry
   6644      * as old entry is still used in hardware and return error to user.
   6645      * 
   6646      * if the following condition is true 
   6647      * (entry not found + no space left in table + entry not shared by anyone)
   6648      * then just overide the old entry.
   6649      */
   6650     rv = _bcm_l3_iif_profile_entry_add(unit, entries, 1, index);
   6651     if (rv == BCM_E_RESOURCE) {
   6652 
   6653         if (1 == ref_count) { 
   6654             /* Profile entry exist and not shared */
   6655             rv = soc_profile_mem_set(unit, L3_IIF_PROFILE(unit), entries,
   6656                                      *index);
   6657         }
   6658     }
   6659 
   6660     COMMON_UNLOCK(unit);
   6661 
   6662     return rv;
   6663 }
   6664 
   6665 /*
   6666  * Function:
   6667  *      _bcm_l3_ip4_options_profile_entry_add
   6668  * Purpose:
   6669  *      Internal function for adding an entry to the L3_IP_OPTIONS_PROFILE table
   6670  *      Adds an entry to the global shared SW copy of the L3_IP_OPTIONS_PROFILE table
   6671  *      Shared by several applications.
   6672  * Parameters:
   6673  *      unit    -  (IN) Device number.
   6674  *      entries -  (IN) Array of pointer to table entries set
   6675  *      entries_per_set - (IN)  Number of entries in the set
   6676  *      index   -  (OUT) Base index for the entires allocated in HW
   6677  * Returns:
   6678  *      BCM_X_XXX
   6679  */
   6680 int
   6681 _bcm_l3_ip4_options_profile_entry_add(int unit, void **entries, 
   6682                               int entries_per_set, uint32 *index)
   6683 {
   6684     int rv;
   6685     COMMON_LOCK(unit);
   6686     rv = soc_profile_mem_add(unit, L3_IP4_OPTIONS_PROFILE(unit), entries,
   6687                              entries_per_set, index);
   6688     COMMON_UNLOCK(unit);
   6689     return rv;
   6690 }
   6691 
   6692 /*
   6693  * Function:
   6694  *      _bcm_l3_ip4_options_profile_entry_delete
   6695  * Purpose:
   6696  *      Internal function for deleting an entry from the L3_IP_OPTIONS_PROFILE table
   6697  *      Deletes an entry from the global shared SW copy of the L3_IP_OPTIONS_PROFILE table
   6698  *      Shared by several applications.
   6699  * Parameters:
   6700  *      unit    -  (IN) Device number.
   6701  *      index   -  (IN) Base index for the entry to be deleted
   6702  * Returns:
   6703  *      BCM_X_XXX
   6704  */
   6705 int
   6706 _bcm_l3_ip4_options_profile_entry_delete(int unit, int index) 
   6707 {
   6708     int rv;
   6709     COMMON_LOCK(unit);
   6710     rv = soc_profile_mem_delete(unit, L3_IP4_OPTIONS_PROFILE(unit), index);
   6711     COMMON_UNLOCK(unit);
   6712     return rv;
   6713 }
   6714 
   6715 int
   6716 _bcm_l3_ip4_options_profile_entry_get(int unit, int index, int count, void **entries)
   6717 {
   6718     int rv;
   6719     COMMON_LOCK(unit);
   6720     rv = soc_profile_mem_get(unit, L3_IP4_OPTIONS_PROFILE(unit), index, count,
   6721                              entries);
   6722     COMMON_UNLOCK(unit);
   6723     return rv;
   6724 }
   6725 
   6726 /*
   6727  * Function:
   6728  *      _bcm_l3_ip4_options_profile_entry_reference
   6729  * Purpose:
   6730  *      Internal function for indicating an entry in the
   6731  *      L3_IP_OPTIONS_PROFILE table is being used.
   6732  *      Updates the global shared SW copy
   6733  * Parameters:
   6734  *      unit    -  (IN) Device number.
   6735  *      index   -  (IN) Base index for the entry to be updated
   6736  * Returns:
   6737  *      BCM_X_XXX
   6738  */
   6739 int
   6740 _bcm_l3_ip4_options_profile_entry_reference(int unit, int index, 
   6741                                 int entries_per_set_override) 
   6742 {
   6743     int rv;
   6744     COMMON_LOCK(unit);
   6745     rv = soc_profile_mem_reference(unit, L3_IP4_OPTIONS_PROFILE(unit), index, 
   6746                                    entries_per_set_override);
   6747     COMMON_UNLOCK(unit);
   6748     return rv;
   6749 }
   6750 
   6751 /*
   6752  * Function:
   6753  *      _bcm_l3_ip4_options_profile_entry_update
   6754  * Purpose:
   6755  *      Internal function for updating an entry to the combined
   6756  *      L3_IP_OPTIONS_PROFILE and L3_IP_OPTIONS_PROFILE table.
   6757  *      Shared by several applications.
   6758  * Parameters:
   6759  *      unit    -  (IN) Device number.
   6760  *      entries -  (IN) Array of pointer to table entries set
   6761  *      index   -  (OUT) Base index to update
   6762  * Returns:
   6763  *      BCM_X_XXX
   6764  */
   6765 int
   6766 _bcm_l3_ip4_options_profile_entry_update(int unit, void **entries, 
   6767                                      uint32 index)
   6768 {
   6769     int rv;
   6770     COMMON_LOCK(unit);
   6771     rv = soc_profile_mem_set(unit, L3_IP4_OPTIONS_PROFILE(unit), entries,
   6772                              index);
   6773     COMMON_UNLOCK(unit);
   6774     return rv;
   6775 }
   6776 
   6777 /*
   6778  * Function:
   6779  *      _bcm_fc_map_profile_entry_add
   6780  * Purpose:
   6781  *      Internal function for adding an entry to the FC_MAP_PROFILE table
   6782  *      Adds an entry to the global shared SW copy of the FC_MAP_PROFILE table
   6783  *      Shared by several applications.
   6784  * Parameters:
   6785  *      unit    -  (IN) Device number.
   6786  *      entries -  (IN) Array of pointer to table entries set
   6787  *      entries_per_set - (IN)  Number of entries in the set
   6788  *      index   -  (OUT) Base index for the entires allocated in HW
   6789  * Returns:
   6790  *      BCM_X_XXX
   6791  */
   6792 int
   6793 _bcm_fc_map_profile_entry_add(int unit, void **entries, 
   6794                               int entries_per_set, uint32 *index)
   6795 {
   6796     int rv;
   6797     COMMON_LOCK(unit);
   6798     rv = soc_profile_mem_add(unit, FC_MAP_PROFILE(unit), entries,
   6799                              entries_per_set, index);
   6800     COMMON_UNLOCK(unit);
   6801     return rv;
   6802 }
   6803 
   6804 /*
   6805  * Function:
   6806  *      _bcm_fc_profile_entry_delete
   6807  * Purpose:
   6808  *      Internal function for deleting an entry from the FC_MAP_PROFILE table
   6809  *      Deletes an entry from the global shared SW copy of the FC_MAP_PROFILE
   6810  *      table shared by several applications.
   6811  * Parameters:
   6812  *      unit    -  (IN) Device number.
   6813  *      index   -  (IN) Base index for the entry to be deleted
   6814  * Returns:
   6815  *      BCM_X_XXX
   6816  */
   6817 int
   6818 _bcm_fc_map_profile_entry_delete(int unit, int index) 
   6819 {
   6820     int rv;
   6821     COMMON_LOCK(unit);
   6822     rv = soc_profile_mem_delete(unit, FC_MAP_PROFILE(unit), index);
   6823     COMMON_UNLOCK(unit);
   6824     return rv;
   6825 }
   6826 
   6827 int
   6828 _bcm_fc_map_profile_entry_get(int unit, int index, int count, void **entries)
   6829 {
   6830     int rv;
   6831     COMMON_LOCK(unit);
   6832     rv = soc_profile_mem_get(unit, FC_MAP_PROFILE(unit), index, count,
   6833                              entries);
   6834     COMMON_UNLOCK(unit);
   6835     return rv;
   6836 }
   6837 
   6838 /*
   6839  * Function:
   6840  *      _bcm_fc_map_profile_entry_reference
   6841  * Purpose:
   6842  *      Internal function for indicating that an entry in FC_MAP_PROFILE table
   6843  *      is being used. Updates the global shared SW copy.
   6844  * Parameters:
   6845  *      unit    -  (IN) Device number
   6846  *      index   -  (IN) Base index for the entry to be updated
   6847  * Returns:
   6848  *      BCM_X_XXX
   6849  */
   6850  int
   6851 _bcm_fc_map_profile_entry_reference(int unit, int index,
   6852                                     int entries_per_set_override)
   6853 {
   6854     int rv;
   6855     COMMON_LOCK(unit);
   6856     rv = soc_profile_mem_reference(unit, FC_MAP_PROFILE(unit), index,
   6857                                    entries_per_set_override);
   6858     COMMON_UNLOCK(unit);
   6859     return rv;
   6860 }
   6861 
   6862 #endif /* BCM_TRIDENT2_SUPPORT */
   6863 
   6864 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   6865 
   6866 
   6867 /*
   6868  * Function:
   6869  *      _bcm_vfi_profile_entry_add
   6870  * Purpose:
   6871  *      Internal function for adding an entry to the vfi_profile table
   6872  *      Adds an entry to the global shared SW copy of the vfi_profile table
   6873  *      Shared by several applications.
   6874  * Parameters:
   6875  *      unit    -  (IN) Device number.
   6876  *      entries -  (IN) Array of pointer to table entries set
   6877  *      entries_per_set - (IN)  Number of entries in the set
   6878  *      index   -  (OUT) Base index for the entires allocated in HW
   6879  * Returns:
   6880  *      BCM_X_XXX
   6881  */
   6882 int
   6883 _bcm_vfi_profile_entry_add(int unit, void **entries,
   6884                               int entries_per_set, uint32 *index)
   6885 {
   6886     int rv;
   6887     COMMON_LOCK(unit);
   6888     rv = soc_profile_mem_add(unit, VFI_PROFILE(unit), entries,
   6889                              entries_per_set, index);
   6890     COMMON_UNLOCK(unit);
   6891     return rv;
   6892 }
   6893 
   6894 /*
   6895  * Function:
   6896  *      _bcm_vfi_profile_entry_delete
   6897  * Purpose:
   6898  *      Internal function for deleting an entry from the vfi_profile table
   6899  *      Deletes an entry from the global shared SW copy of the vfi_profile table
   6900  *      Shared by several applications.
   6901  * Parameters:
   6902  *      unit    -  (IN) Device number.
   6903  *      index   -  (IN) Base index for the entry to be deleted
   6904  * Returns:
   6905  *      BCM_X_XXX
   6906  */
   6907 int
   6908 _bcm_vfi_profile_entry_delete(int unit, int index)
   6909 {
   6910     int rv;
   6911 
   6912     /* index 0 should never be deleted */
   6913     if (index == 0) {
   6914         return BCM_E_NONE;
   6915     }
   6916 
   6917     COMMON_LOCK(unit);
   6918     rv = soc_profile_mem_delete(unit, VFI_PROFILE(unit), index);
   6919     COMMON_UNLOCK(unit);
   6920     return rv;
   6921 }
   6922 
   6923 /*
   6924  * Function:
   6925  *      _bcm_vfi_profile_entry_get
   6926  * Purpose:
   6927  *      Internal function for retrieving entry from the vfi_profile table
   6928  * Parameters:
   6929  *      unit    -  (IN) Device number.
   6930  *      index   -  (IN) Base index for the entry to be fetched
   6931  *      count   -  (IN) Array size
   6932  *      entries -  (OUT) Output array of entries
   6933  * Returns:
   6934  *      BCM_X_XXX
   6935  */
   6936 int
   6937 _bcm_vfi_profile_entry_get(int unit, int index, int count, void **entries)
   6938 {
   6939     int rv;
   6940     COMMON_LOCK(unit);
   6941     rv = soc_profile_mem_get(unit, VFI_PROFILE(unit), index, count,
   6942                              entries);
   6943     COMMON_UNLOCK(unit);
   6944     return rv;
   6945 }
   6946 
   6947 /*
   6948  * Function:
   6949  *      _bcm_vfi_profile_entry_reference
   6950  * Purpose:
   6951  *      Internal function for indicating an entry in the
   6952  *      vfi_profile table is being used.
   6953  *      Updates the global shared SW copy
   6954  * Parameters:
   6955  *      unit    -  (IN) Device number.
   6956  *      index   -  (IN) Base index for the entry to be updated
   6957  * Returns:
   6958  *      BCM_X_XXX
   6959  */
   6960 int
   6961 _bcm_vfi_profile_entry_reference(int unit, int index,
   6962                                 int entries_per_set_override)
   6963 {
   6964     int rv;
   6965     COMMON_LOCK(unit);
   6966     rv = soc_profile_mem_reference(unit, VFI_PROFILE(unit), index,
   6967                                    entries_per_set_override);
   6968     COMMON_UNLOCK(unit);
   6969     return rv;
   6970 }
   6971 
   6972 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   6973 
   6974 
   6975 #ifdef BCM_KATANA_SUPPORT
   6976 /*
   6977  * Function:
   6978  *      _bcm_offset_map_table_entry_add
   6979  * Purpose:
   6980  *      Internal function for adding an entry to the 
   6981  *      ING_QUEUE_OFFSET_MAPPING_TABLE table.
   6982  *      Adds an entry to the global shared SW copy of the 
   6983  *      ING_QUEUE_OFFSET_MAPPING_TABLE table
   6984  *      Shared by several applications.
   6985  * Parameters:
   6986  *      unit    -  (IN) Device number.
   6987  *      entries -  (IN) Array of pointer to table entries set
   6988  *      entries_per_set - (IN)  Number of entries in the set
   6989  *      index   -  (OUT) Base index for the entires allocated in HW
   6990  * Returns:
   6991  *      BCM_X_XXX
   6992  */
   6993 
   6994 
   6995 int
   6996 _bcm_offset_map_table_entry_add(int unit, void **entries,
   6997                                 int entries_per_set, uint32 *index)
   6998 {
   6999     int rv;
   7000     COMMON_LOCK(unit);
   7001     rv = soc_profile_mem_add(unit, OFFSET_MAP_TABLE(unit), entries,
   7002                              entries_per_set, index);
   7003     COMMON_UNLOCK(unit);
   7004     return rv;
   7005 }
   7006 /*
   7007  * Function:
   7008  *      _bcm_offset_map_table_entry_delete
   7009  * Purpose:
   7010  *      Internal function for deleting an entry from the 
   7011  *      ING_QUEUE_OFFSET_MAPPING_TABLE table
   7012  *      Deletes an entry from the global shared SW copy of the 
   7013  *      ING_QUEUE_OFFSET_MAPPING_TABLE table
   7014  *      Shared by several applications.
   7015  * Parameters:
   7016  *      unit    -  (IN) Device number.
   7017  *      index   -  (IN) Base index for the entry to be deleted
   7018  * Returns:
   7019  *      BCM_X_XXX
   7020  */
   7021 int
   7022 _bcm_offset_map_table_entry_delete(int unit, int index)
   7023 {
   7024     int rv;
   7025     COMMON_LOCK(unit);
   7026     rv = soc_profile_mem_delete(unit, OFFSET_MAP_TABLE(unit), index);
   7027     COMMON_UNLOCK(unit);
   7028     return rv;
   7029 }
   7030 
   7031 /*
   7032  * Function:
   7033  *      _bcm_offset_map_table_entry_get
   7034  * Purpose:
   7035  *      Internal function for getting an entry from the 
   7036  *      ING_QUEUE_OFFSET_MAPPING_TABLE table
   7037  * Parameters:
   7038  *      unit    -  (IN) Device number.
   7039  *      index  - (IN) Base index for the entry to be deleted
   7040  *      count  - (IN) number of entries  
   7041  *      entries - (OUT) enrtries
   7042  * Returns:
   7043  *      BCM_X_XXX
   7044  */
   7045 int
   7046 _bcm_offset_map_table_entry_get(int unit, int index, int count, 
   7047                                       void **entries)
   7048 {
   7049     int rv;
   7050     COMMON_LOCK(unit);
   7051     rv = soc_profile_mem_get(unit, OFFSET_MAP_TABLE(unit), index, count,
   7052                              entries);
   7053     COMMON_UNLOCK(unit);
   7054     return rv;
   7055 }
   7056 
   7057 /*
   7058  * Function:
   7059  *      _bcm_offset_map_table_entry_reference
   7060  * Purpose:
   7061  *      Internal function for indicating an entry in the 
   7062  *      ING_QUEUE_OFFSET_MAPPING_TABLE table
   7063  *      is being used. Updates the global shared SW copy
   7064  * Parameters:
   7065  *      unit    -  (IN) Device number.
   7066  *      index   -  (IN) Base index for the entry to be updated
   7067  * Returns:
   7068  *      BCM_X_XXX
   7069  */
   7070 int
   7071 _bcm_offset_map_table_entry_reference(int unit, int index,
   7072                                 int entries_per_set_override)
   7073 {
   7074     int rv;
   7075     COMMON_LOCK(unit);
   7076     rv = soc_profile_mem_reference(unit, OFFSET_MAP_TABLE(unit), index,
   7077                                    entries_per_set_override);
   7078     COMMON_UNLOCK(unit);
   7079     return rv;
   7080 }
   7081 #endif /* BCM_KATANA_SUPPORT */
   7082 
   7083 #ifdef BCM_SABER2_SUPPORT
   7084 /*
   7085  * Function:
   7086  *      _bcm_service_pri_map_table_entry_add
   7087  * Purpose:
   7088  *      Internal function for adding an entry to the 
   7089  *      ING/EGR_SERVICE_PRI_MAP_0/1/2 tables.
   7090  *      Adds an entry to the global shared SW copy of the 
   7091  *      ING/EGR_SERVICE_PRI_MAP_0/1/2 tables
   7092  *      Shared by several applications.
   7093  * Parameters:
   7094  *      unit    -  (IN) Device number.
   7095  *      entries -  (IN) Array of pointer to table entries set
   7096  *      entries_per_set - (IN)  Number of entries in the set
   7097  *      index   -  (OUT) Base index for the entires allocated in HW
   7098  * Returns:
   7099  *      BCM_X_XXX
   7100  */
   7101 
   7102 
   7103 int
   7104 _bcm_service_pri_map_table_entry_add(int unit, void **entries,
   7105                                 int entries_per_set, uint32 *index)
   7106 {
   7107     int rv;
   7108     COMMON_LOCK(unit);
   7109     rv = soc_profile_mem_add(unit, SERVICE_PRI_MAP_TABLE(unit), entries,
   7110                              entries_per_set, index);
   7111     COMMON_UNLOCK(unit);
   7112     return rv;
   7113 }
   7114 /*
   7115  * Function:
   7116  *      _bcm_service_pri_map_table_entry_delete
   7117  * Purpose:
   7118  *      Internal function for deleting an entry from the 
   7119  *      ING/EGR_SERVICE_PRI_MAP_0/1/2 tables
   7120  *      Deletes an entry from the global shared SW copy of the 
   7121  *      ING/EGR_SERVICE_PRI_MAP_0/1/2 tables
   7122  *      Shared by several applications.
   7123  * Parameters:
   7124  *      unit    -  (IN) Device number.
   7125  *      index   -  (IN) Base index for the entry to be deleted
   7126  * Returns:
   7127  *      BCM_X_XXX
   7128  */
   7129 int
   7130 _bcm_service_pri_map_table_entry_delete(int unit, int index)
   7131 {
   7132     int rv;
   7133     COMMON_LOCK(unit);
   7134     rv = soc_profile_mem_delete(unit, SERVICE_PRI_MAP_TABLE(unit), index);
   7135     COMMON_UNLOCK(unit);
   7136     return rv;
   7137 }
   7138 
   7139 /*
   7140  * Function:
   7141  *      _bcm_service_pri_map_table_entry_get
   7142  * Purpose:
   7143  *      Internal function for getting an entry from the 
   7144  *      ING/EGR_SERVICE_PRI_MAP_0/1/2 tables
   7145  * Parameters:
   7146  *      unit    -  (IN) Device number.
   7147  *      index  - (IN) Base index for the entry to be deleted
   7148  *      count  - (IN) number of entries  
   7149  *      entries - (OUT) enrtries
   7150  * Returns:
   7151  *      BCM_X_XXX
   7152  */
   7153 int
   7154 _bcm_service_pri_map_table_entry_get(int unit, int index, int count, 
   7155                                       void **entries)
   7156 {
   7157     int rv;
   7158     COMMON_LOCK(unit);
   7159     rv = soc_profile_mem_get(unit, SERVICE_PRI_MAP_TABLE(unit), index, count,
   7160                              entries);
   7161     COMMON_UNLOCK(unit);
   7162     return rv;
   7163 }
   7164 
   7165 /*
   7166  * Function:
   7167  *      _bcm_service_pri_map_table_entry_reference
   7168  * Purpose:
   7169  *      Internal function for indicating an entry in the 
   7170  *      ING_QUEUE_OFFSET_MAPPING_TABLE table
   7171  *      is being used. Updates the global shared SW copy
   7172  * Parameters:
   7173  *      unit    -  (IN) Device number.
   7174  *      index   -  (IN) Base index for the entry to be updated
   7175  * Returns:
   7176  *      BCM_X_XXX
   7177  */
   7178 int
   7179 _bcm_service_pri_map_table_entry_reference(int unit, int index,
   7180                                 int entries_per_set_override)
   7181 {
   7182     int rv;
   7183     COMMON_LOCK(unit);
   7184     rv = soc_profile_mem_reference(unit, SERVICE_PRI_MAP_TABLE(unit), index,
   7185                                    entries_per_set_override);
   7186     COMMON_UNLOCK(unit);
   7187     return rv;
   7188 }
   7189 #endif /* BCM_SABER2_SUPPORT */
   7190 
   7191 /*TD2+ support is added here for xgs5/port.c usage*/
   7192 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
   7193 /*
   7194  * Function:
   7195  *      _bcm_port_vlan_protocol_data_entry_add
   7196  * Purpose:
   7197  *      Internal function for adding an entry to the 
   7198  *      VLAN_PROTOCOL_DATA table.
   7199  *      Adds an entry to the global shared SW copy of the 
   7200  *      VLAN_PROTOCOL_DATA table
   7201  *      Shared by several applications.
   7202  * Parameters:
   7203  *      unit    -  (IN) Device number.
   7204  *      entries -  (IN) Array of pointer to table entries set
   7205  *      entries_per_set - (IN)  Number of entries in the set
   7206  *      index   -  (OUT) Base index for the entires allocated in HW
   7207  * Returns:
   7208  *      BCM_X_XXX
   7209  */
   7210 int
   7211 _bcm_port_vlan_protocol_data_entry_add(int unit, void **entries, 
   7212                               int entries_per_set, uint32 *index)
   7213 {
   7214     int rv = BCM_E_NONE;
   7215     if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm)) {
   7216     COMMON_LOCK(unit);
   7217     rv = soc_profile_mem_add(unit, VLAN_PROTOCOL_DATA_TABLE(unit), entries,
   7218                              entries_per_set, index);
   7219     COMMON_UNLOCK(unit);
   7220     }
   7221     return rv;
   7222 }
   7223 
   7224 /*
   7225  * Function:
   7226  *      _bcm_port_vlan_protocol_data_entry_delete
   7227  * Purpose:
   7228  *      Internal function for deleting an entry from the 
   7229  *      VLAN_PROTOCOL_DATA table
   7230  *      Deletes an entry from the global shared SW copy of the 
   7231  *      VLAN_PROTOCOL_DATA table
   7232  *      Shared by several applications.
   7233  * Parameters:
   7234  *      unit    -  (IN) Device number.
   7235  *      index   -  (IN) Base index for the entry to be deleted
   7236  * Returns:
   7237  *      BCM_X_XXX
   7238  */
   7239 int
   7240 _bcm_port_vlan_protocol_data_entry_delete(int unit, int index)
   7241 {
   7242     int rv = BCM_E_NONE;
   7243     if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm)) {
   7244     COMMON_LOCK(unit);
   7245     rv = soc_profile_mem_delete(unit, VLAN_PROTOCOL_DATA_TABLE(unit), index);
   7246     COMMON_UNLOCK(unit);
   7247     }
   7248     return rv;
   7249 }
   7250 #endif
   7251 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   7252 /*
   7253  * Function:
   7254  *      _bcm_port_vlan_protocol_data_entry_get
   7255  * Purpose:
   7256  *      Internal function for getting an entry from the 
   7257  *      VLAN_PROTOCOL_DATA table
   7258  * Parameters:
   7259  *      unit    -  (IN) Device number.
   7260  *      index  - (IN) Base index for the entry to be deleted
   7261  *      count  - (IN) number of entries  
   7262  *      entries - (OUT) enrtries
   7263  * Returns:
   7264  *      BCM_X_XXX
   7265  */
   7266 int
   7267 _bcm_port_vlan_protocol_data_entry_get(int unit,
   7268     int index, int count, void **entries)
   7269 {
   7270     int rv = BCM_E_NONE;
   7271     if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm)) {
   7272     COMMON_LOCK(unit);
   7273     rv = soc_profile_mem_get(unit, VLAN_PROTOCOL_DATA_TABLE(unit), index, count,
   7274                              entries);
   7275     COMMON_UNLOCK(unit);
   7276     }
   7277     return rv;
   7278 }
   7279 
   7280 /*
   7281  * Function:
   7282  *      _bcm_vlan_port_protocol_data_entry_reference
   7283  * Purpose:
   7284  *      Internal function for indicating an entry in the 
   7285  *      VLAN_PROTOCOL_DATA table
   7286  *      is being used. Updates the global shared SW copy
   7287  * Parameters:
   7288  *      unit    -  (IN) Device number.
   7289  *      index   -  (IN) Base index for the entry to be updated
   7290  * Returns:
   7291  *      BCM_X_XXX
   7292  */
   7293 int
   7294 _bcm_port_vlan_protocol_data_entry_reference(int unit, int index,
   7295                                 int entries_per_set_override) 
   7296 {
   7297     int rv = BCM_E_NONE;
   7298     if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm)) {
   7299     COMMON_LOCK(unit);
   7300     rv = soc_profile_mem_reference(unit, VLAN_PROTOCOL_DATA_TABLE(unit), index, 
   7301                                    entries_per_set_override);
   7302     COMMON_UNLOCK(unit);
   7303     }
   7304     return rv;
   7305 }
   7306 
   7307 #endif /*BCM_KATANA2_SUPPORT */
   7308 
   7309 #ifdef BCM_HURRICANE3_SUPPORT
   7310 /*
   7311  * Function:
   7312  *      _bcm_egr_header_encap_data_entry_add
   7313  * Purpose:
   7314  *      Internal function for adding an entry to the EGR_HEADER_ENCAP_DATA table
   7315  *      Adds an entry to the global shared SW copy of the EGR_HEADER_ENCAP_DATA table
   7316  *      Shared by MIML and Custom Packet Header
   7317  * Parameters:
   7318  *      unit    -  (IN) Device number.
   7319  *      entries -  (IN) Array of pointer to table entries set
   7320  *      entries_per_set - (IN)  Number of entries in the set
   7321  *      index   -  (OUT) Base index for the entires allocated in HW
   7322  * Returns:
   7323  *      BCM_X_XXX
   7324  */
   7325 int
   7326 _bcm_egr_header_encap_data_entry_add(int unit, void **entries, 
   7327                               int entries_per_set, uint32 *index)
   7328 {
   7329     int rv;
   7330     COMMON_LOCK(unit);
   7331     rv = soc_profile_mem_add(unit, EGR_HEADER_ENCAP_DATA(unit), entries,
   7332                              entries_per_set, index);
   7333     COMMON_UNLOCK(unit);
   7334     return rv;
   7335 }
   7336 
   7337 /*
   7338  * Function:
   7339  *      _bcm_egr_header_encap_data_entry_delete
   7340  * Purpose:
   7341  *      Internal function for deleting an entry from the EGR_HEADER_ENCAP_DATA table
   7342  *      Deletes an entry from the global shared SW copy of the EGR_HEADER_ENCAP_DATA table
   7343  *      Shared by MIML and Custom Packet Header
   7344  * Parameters:
   7345  *      unit    -  (IN) Device number.
   7346  *      entries -  (IN) Array of pointer to table entries set
   7347  *      entries_per_set - (IN)  Number of entries in the set
   7348  *      index   -  (OUT) Base index for the entires allocated in HW
   7349  * Returns:
   7350  *      BCM_X_XXX
   7351  */
   7352 int
   7353 _bcm_egr_header_encap_data_entry_delete(int unit, int index) 
   7354 {
   7355     int rv;
   7356     COMMON_LOCK(unit);
   7357     rv = soc_profile_mem_delete(unit, EGR_HEADER_ENCAP_DATA(unit), index);
   7358     COMMON_UNLOCK(unit);
   7359     return rv;
   7360 }
   7361 
   7362 /*
   7363  * Function:
   7364  *      _bcm_egr_header_encap_data_entry_update
   7365  * Purpose:
   7366  *      Internal function for updating an entry to theEGR_HEADER_ENCAP_DATA table.
   7367  *      Shared by several applications.
   7368  * Parameters:
   7369  *      unit    -  (IN) Device number.
   7370  *      entries -  (IN) Array of pointer to table entries set
   7371  *      index   -  (OUT) Base index to update
   7372  * Returns:
   7373  *      BCM_X_XXX
   7374  */
   7375 int
   7376 _bcm_egr_header_encap_data_entry_update(int unit, void **entries, 
   7377                               uint32 index)
   7378 {
   7379     int rv;
   7380     COMMON_LOCK(unit);
   7381     rv = soc_profile_mem_set(unit, EGR_HEADER_ENCAP_DATA(unit), entries, index);
   7382     COMMON_UNLOCK(unit);
   7383     return rv;
   7384 }
   7385 
   7386 int
   7387 _bcm_egr_header_encap_data_entry_ref_count_get(int unit, 
   7388                               uint32 index, int *ref_count)
   7389 {
   7390     int rv;
   7391     COMMON_LOCK(unit);
   7392     rv = soc_profile_mem_ref_count_get(unit, 
   7393         EGR_HEADER_ENCAP_DATA(unit), index, ref_count);
   7394     COMMON_UNLOCK(unit);
   7395     return rv;
   7396 }
   7397 
   7398 int
   7399 _bcm_egr_header_encap_data_entry_search(int unit, void **entries,
   7400                               int entries_per_set, uint32 *index)
   7401 {
   7402     int rv;
   7403     COMMON_LOCK(unit);
   7404     rv = soc_profile_mem_search(unit, EGR_HEADER_ENCAP_DATA(unit), entries,
   7405                                 entries_per_set, index);
   7406     COMMON_UNLOCK(unit);
   7407     return rv;
   7408 }
   7409 
   7410 /*
   7411  * Function:
   7412  *      _bcm_custom_header_match_entry_add
   7413  * Purpose:
   7414  *      Internal function for adding an entry to the CUSTOM_HEADER_MATCH table
   7415  *      Adds an entry to the global shared SW copy of the CUSTOM_HEADER_MATCH table
   7416  *      Shared by MIML and Custom Packet Header
   7417  * Parameters:
   7418  *      unit    -  (IN) Device number.
   7419  *      entries -  (IN) Array of pointer to table entries set
   7420  *      entries_per_set - (IN)  Number of entries in the set
   7421  *      index   -  (OUT) Base index for the entires allocated in HW
   7422  * Returns:
   7423  *      BCM_X_XXX
   7424  */
   7425 int
   7426 _bcm_custom_header_match_entry_add(int unit, void **entries, 
   7427                               int entries_per_set, uint32 *index)
   7428 {
   7429     int rv;
   7430     COMMON_LOCK(unit);
   7431     rv = soc_profile_mem_add(unit, CUSTOM_HEADER_MATCH(unit), entries,
   7432                              entries_per_set, index);
   7433     COMMON_UNLOCK(unit);
   7434     return rv;
   7435 }
   7436 
   7437 /*
   7438  * Function:
   7439  *      _bcm_custom_header_match_entry_delete
   7440  * Purpose:
   7441  *      Internal function for deleting an entry from the CUSTOM_HEADER_MATCH table
   7442  *      Deletes an entry from the global shared SW copy of the CUSTOM_HEADER_MATCH table
   7443  *      Shared by MIML and Custom Packet Header
   7444  * Parameters:
   7445  *      unit    -  (IN) Device number.
   7446  *      entries -  (IN) Array of pointer to table entries set
   7447  *      entries_per_set - (IN)  Number of entries in the set
   7448  *      index   -  (OUT) Base index for the entires allocated in HW
   7449  * Returns:
   7450  *      BCM_X_XXX
   7451  */
   7452 int
   7453 _bcm_custom_header_match_entry_delete(int unit, int index) 
   7454 {
   7455     int rv;
   7456     COMMON_LOCK(unit);
   7457     rv = soc_profile_mem_delete(unit, CUSTOM_HEADER_MATCH(unit), index);
   7458     COMMON_UNLOCK(unit);
   7459     return rv;
   7460 }
   7461 
   7462 /*
   7463  * Function:
   7464  *      _bcm_custom_header_match_entry_update
   7465  * Purpose:
   7466  *      Internal function for updating an entry to theCUSTOM_HEADER_MATCH table.
   7467  *      Shared by several applications.
   7468  * Parameters:
   7469  *      unit    -  (IN) Device number.
   7470  *      entries -  (IN) Array of pointer to table entries set
   7471  *      index   -  (OUT) Base index to update
   7472  * Returns:
   7473  *      BCM_X_XXX
   7474  */
   7475 int
   7476 _bcm_custom_header_match_entry_update(int unit, void **entries, 
   7477                               uint32 index)
   7478 {
   7479     int rv;
   7480     COMMON_LOCK(unit);
   7481     rv = soc_profile_mem_set(unit, CUSTOM_HEADER_MATCH(unit), entries, index);
   7482     COMMON_UNLOCK(unit);
   7483     return rv;
   7484 }
   7485 
   7486 /*
   7487  * Function:
   7488  *      _bcm_custom_header_match_entry_get
   7489  * Purpose:
   7490  *      Internal function for getting an entry to theCUSTOM_HEADER_MATCH table.
   7491  *      Shared by several applications.
   7492  * Parameters:
   7493  *      unit    -  (IN) Device number.
   7494  *      index  - (IN) Base index for the entry to be deleted
   7495  *      count  - (IN) number of entries  
   7496  *      entries - (OUT) enrtries
   7497  * Returns:
   7498  *      BCM_X_XXX
   7499  */
   7500 int
   7501 _bcm_custom_header_match_entry_get(int unit,
   7502     int index, int count, void **entries)
   7503 {
   7504     int rv;
   7505     COMMON_LOCK(unit);
   7506     rv = soc_profile_mem_get(unit, CUSTOM_HEADER_MATCH(unit), index, count,
   7507                              entries);
   7508     COMMON_UNLOCK(unit);
   7509     return rv;
   7510 }
   7511 
   7512 int
   7513 _bcm_custom_header_match_entry_ref_count_get(int unit, 
   7514                               uint32 index, int *ref_count)
   7515 {
   7516     int rv;
   7517     COMMON_LOCK(unit);
   7518     rv = soc_profile_mem_ref_count_get(unit, 
   7519         CUSTOM_HEADER_MATCH(unit), index, ref_count);
   7520     COMMON_UNLOCK(unit);
   7521     return rv;
   7522 }
   7523 
   7524 #endif /* BCM_HURRICANE3_SUPPORT */
   7525 
   7526 void
   7527 _bcm_common_profile_mem_ref_cnt_update(int unit, soc_mem_t mem,
   7528                                        int profile_ptr, int count)
   7529 {
   7530     int entries_per_set, index, i;
   7531     soc_profile_mem_t *profile;
   7532 
   7533     switch (mem) {
   7534     case EGR_MAC_DA_PROFILEm:
   7535         profile = MAC_DA_PROFILE(unit);
   7536         entries_per_set = 1;
   7537         break;
   7538     case ING_PRI_CNG_MAPm:
   7539         profile = ING_PRI_CNG_MAP(unit);
   7540         entries_per_set = 16;
   7541         break;
   7542     case LPORT_TABm:
   7543         profile = LPORT_PROFILE(unit);
   7544         entries_per_set = 1;
   7545         break;
   7546     case EGR_MPLS_PRI_MAPPINGm:
   7547     case EGR_MPLS_EXP_MAPPING_1m:
   7548         profile = EGR_MPLS_COMBO_MAP(unit);
   7549         entries_per_set = 64;
   7550         break;
   7551     case DSCP_TABLEm:
   7552         profile = DSCP_TABLE(unit);
   7553         entries_per_set = 64;
   7554         break;
   7555     case PHB_MAPPING_TBL_2m:
   7556         profile = DSCP_TABLE(unit);
   7557         entries_per_set = 64;
   7558         break;
   7559 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   7560     case EGR_PRI_CNG_MAPm:
   7561         if(soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   7562             profile = EGR_QOS_PROFILE(unit);
   7563             entries_per_set = 64;
   7564         } else {
   7565             return;
   7566         }
   7567         break;
   7568 #endif
   7569     case EGR_DSCP_TABLEm:
   7570 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   7571         if(soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   7572             profile = EGR_QOS_PROFILE(unit);
   7573             entries_per_set = 64;
   7574         } else
   7575 #endif
   7576         {
   7577         profile = EGR_DSCP_TABLE(unit);
   7578         entries_per_set = 64;
   7579         }
   7580         break;
   7581     case EGR_ZONE_2_QOS_MAPPING_TABLEm:
   7582         profile = EGR_DSCP_TABLE(unit);
   7583         entries_per_set = 64;
   7584         break;
   7585 #ifdef BCM_TRIUMPH3_SUPPORT
   7586     case ING_L3_NEXT_HOP_ATTRIBUTE_1m:
   7587         profile = NULL;
   7588         entries_per_set = 0;
   7589         if (SOC_IS_TRIUMPH3(unit)) {
   7590             profile = ING_L3_NH_ATTRIB_PROFILE(unit);
   7591             entries_per_set = 1;
   7592         }
   7593         break;
   7594 #endif /* BCM_TRIUMPH3_SUPPORT */
   7595 #ifdef BCM_TRIDENT2_SUPPORT
   7596     case L3_IIF_PROFILEm:
   7597         profile = NULL;
   7598         entries_per_set = 0;
   7599         if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   7600             profile = L3_IIF_PROFILE(unit);
   7601             entries_per_set = 1;
   7602         }
   7603         break;
   7604     case IP_OPTION_CONTROL_PROFILE_TABLEm:
   7605         profile = NULL;
   7606         entries_per_set = 1;
   7607         if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit)) {
   7608             profile = L3_IP4_OPTIONS_PROFILE(unit);
   7609             entries_per_set = 256;
   7610         }
   7611         break;
   7612 #endif /* BCM_TRIDENT2_SUPPORT */
   7613 #ifdef BCM_KATANA_SUPPORT
   7614     case ING_QUEUE_OFFSET_MAPPING_TABLEm:
   7615         profile = OFFSET_MAP_TABLE(unit);
   7616         entries_per_set = 16;
   7617         break;
   7618 #endif /* BCM_KATANA_SUPPORT */
   7619 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   7620     case VLAN_PROTOCOL_DATAm:
   7621         profile = VLAN_PROTOCOL_DATA_TABLE(unit);
   7622         entries_per_set = 16;
   7623         break;
   7624 #endif /* BCM_KATANA2_SUPPORT */
   7625 #ifdef BCM_HURRICANE3_SUPPORT
   7626     case EGR_HEADER_ENCAP_DATAm:
   7627         profile = EGR_HEADER_ENCAP_DATA(unit);
   7628         entries_per_set = 1;
   7629         break;
   7630     case CUSTOM_HEADER_MATCHm:
   7631         profile = CUSTOM_HEADER_MATCH(unit);
   7632         entries_per_set = 1;
   7633         break;
   7634 #endif /* BCM_HURRICANE3_SUPPORT */
   7635 #ifdef BCM_TOMAHAWK_SUPPORT
   7636     case ING_TUNNEL_ECN_DECAPm:
   7637         profile = ING_TUNNEL_TERM_MAP(unit);
   7638         entries_per_set = 16;
   7639         break;
   7640 #endif /* BCM_TOMAHAWK_SUPPORT */
   7641 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
   7642     defined(BCM_TRIDENT3_SUPPORT)
   7643     case EGR_INT_CN_TO_EXP_MAPPING_TABLEm:
   7644         profile = EGR_INT_CN_TO_EXP_MAP(unit);
   7645         entries_per_set = 32;
   7646         break;
   7647     case EGR_PKT_ECN_TO_EXP_MAPPING_1m:
   7648         profile = EGR_IP_ECN_TO_EXP_MAP(unit);
   7649         entries_per_set = 32;
   7650         break;
   7651     case EGR_IP_ECN_TO_EXP_MAPPING_TABLEm:
   7652         profile = EGR_IP_ECN_TO_EXP_MAP(unit);
   7653         entries_per_set = 32;
   7654         break;
   7655     case ING_EXP_TO_IP_ECN_MAPPINGm:
   7656         profile = ING_EXP_TO_IP_ECN_MAP(unit);
   7657         entries_per_set = 32;
   7658         break;            
   7659 #endif /* BCM_TOMAHAWK2_SUPPORT||BCM_TOMAHAWK3_SUPPORT||BCM_TRIDENT3_SUPPORT */
   7660     
   7661 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   7662     case ING_EXP_TO_ECN_MAPPING_1m:
   7663         profile = ING_EXP_TO_IP_ECN_MAP(unit);
   7664         entries_per_set = 32;
   7665         break;
   7666 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TRIDENT3_SUPPORT */
   7667 
   7668     default:
   7669         return;
   7670     }
   7671 
   7672     index = profile_ptr * entries_per_set;
   7673     for (i = 0; i < entries_per_set; i++) {
   7674         SOC_PROFILE_MEM_REFERENCE(unit, profile, index + i, count);
   7675         SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, profile, index + i, 
   7676                                         entries_per_set);
   7677     }
   7678     return;
   7679 }
   7680 
   7681 /* Structure used for hash calculation */
   7682 typedef struct _bcm_trx_mpls_station_key_s {
   7683     bcm_mac_t  mac;
   7684     bcm_vlan_t vlan;
   7685 } _bcm_trx_mpls_station_key_t;
   7686 
   7687 /*
   7688  * Function:
   7689  *      _bcm_trx_mpls_station_hash_calc
   7690  * Purpose:
   7691  *      Calculate MPLS_STATION_TCAM entry hash.
   7692  * Parameters:
   7693  *      unit -  (IN)  Device number.
   7694  *      mac  -  (IN)  MAC address
   7695  *      vlan -  (IN)  VLAN ID
   7696  *      hash -  (OUT) Hash valu.
   7697  * Returns:
   7698  *      BCM_X_XXX
   7699  */
   7700 STATIC int
   7701 _bcm_trx_mpls_station_hash_calc(int unit, bcm_mac_t mac,
   7702                                 bcm_vlan_t vlan, uint16 *hash)
   7703 {
   7704     _bcm_trx_mpls_station_key_t key;
   7705 
   7706     if (hash == NULL) {
   7707         return (BCM_E_PARAM);
   7708     }
   7709     sal_memcpy(key.mac, mac, sizeof(bcm_mac_t));
   7710     key.vlan = vlan;
   7711     *hash = _shr_crc16(0, (uint8 *)&key, sizeof(_bcm_trx_mpls_station_key_t));
   7712 
   7713     return (BCM_E_NONE);
   7714 }
   7715 
   7716 /*
   7717  * Function:
   7718  *      bcm_l2_tunnel_add
   7719  * Purpose:
   7720  *    Add a (MAC, VLAN) for tunnel/MPLS processing.
   7721  *    Frames destined to (MAC, VLAN) is subjected to MPLS processing.
   7722  *    Shared by MPLS and MIM
   7723  * Parameters:
   7724  *      unit - Unit number
   7725  *      mac  - MAC address
   7726  *      vlan - VLAN ID
   7727  */
   7728 int
   7729 bcm_trx_metro_l2_tunnel_add(int unit, bcm_mac_t mac, bcm_vlan_t vlan)
   7730 {
   7731     mpls_station_tcam_entry_t station_entry;
   7732     uint16 hash;
   7733     bcm_mac_t hw_mac;
   7734     bcm_vlan_t hw_vlan;
   7735     int rv, i, num_station, free_index = -1;
   7736 
   7737     /* Get the hash value for this key */
   7738     BCM_IF_ERROR_RETURN(_bcm_trx_mpls_station_hash_calc(unit, mac, vlan, &hash));
   7739 
   7740     /* see if the entry already exists or find free entry */
   7741     num_station = soc_mem_index_count(unit, MPLS_STATION_TCAMm);
   7742     COMMON_LOCK(unit);
   7743     for (i = 0; i < num_station; i++) {
   7744         if (hash == MPLS_STATION_HASH(unit, i)) {
   7745             /* Read HW entry to see if it's really a match */
   7746             rv = READ_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY,
   7747                                          i, &station_entry);
   7748             if (rv < 0) {
   7749                 COMMON_UNLOCK(unit);
   7750                 return rv;
   7751             }
   7752             soc_mem_mac_addr_get(unit, MPLS_STATION_TCAMm,
   7753                                  &station_entry, MAC_ADDRf, hw_mac);
   7754             hw_vlan = soc_mem_field32_get(unit, MPLS_STATION_TCAMm,
   7755                                           &station_entry, VLAN_IDf);
   7756             if ((vlan == hw_vlan) &&
   7757                 !sal_memcmp(mac, hw_mac, sizeof(bcm_mac_t))) {
   7758                 break;
   7759             }
   7760         }
   7761         if ((free_index == -1) && (MPLS_STATION_HASH(unit, i) == 0)) {
   7762             /* Read HW entry to see if it's unused */
   7763             rv = READ_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY,
   7764                                          i, &station_entry);
   7765             if (rv < 0) {
   7766                 COMMON_UNLOCK(unit);
   7767                 return rv;
   7768             }
   7769             if (!soc_mem_field32_get(unit, MPLS_STATION_TCAMm,
   7770                                      &station_entry, VALIDf)) {
   7771                 free_index = i;
   7772             }
   7773         }
   7774     }
   7775     if (i < num_station) {
   7776         /* Entry already exists */
   7777         COMMON_UNLOCK(unit);
   7778         return BCM_E_EXISTS;
   7779     } else if (free_index == -1) {
   7780         /* Table is full */
   7781         COMMON_UNLOCK(unit);
   7782         return BCM_E_FULL;
   7783     }
   7784     /* Commit entry to HW */
   7785     sal_memset(&station_entry, 0, sizeof(mpls_station_tcam_entry_t));
   7786     soc_mem_field32_set(unit, MPLS_STATION_TCAMm, &station_entry, VALIDf, 1);
   7787     soc_mem_mac_addr_set(unit, MPLS_STATION_TCAMm, &station_entry,
   7788                          MAC_ADDRf, mac);
   7789     soc_mem_field32_set(unit, MPLS_STATION_TCAMm, &station_entry,
   7790                         VLAN_IDf, vlan);
   7791     /* set masks to all 1's */
   7792     for (i = 0; i < 6; i++) {
   7793         hw_mac[i] = 0xff;
   7794     }
   7795     hw_vlan = 0xfff;
   7796     soc_mem_mac_addr_set(unit, MPLS_STATION_TCAMm, &station_entry,
   7797                          MAC_ADDR_MASKf, hw_mac);
   7798     soc_mem_field32_set(unit, MPLS_STATION_TCAMm, &station_entry,
   7799                         VLAN_ID_MASKf, hw_vlan);
   7800     rv = WRITE_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY,
   7801                                   free_index, &station_entry);
   7802     if (rv < 0) {
   7803         COMMON_UNLOCK(unit);
   7804         return rv;
   7805     }
   7806     MPLS_STATION_HASH(unit, free_index) = hash;
   7807     COMMON_UNLOCK(unit);
   7808     return BCM_E_NONE;
   7809 }
   7810 
   7811 /*
   7812  * Function:
   7813  *      bcm_l2_tunnel_delete
   7814  * Purpose:
   7815  *    Delete a (MAC, VLAN) for tunnel/MPLS processing.
   7816  *    Shared by MPLS and MIM
   7817  * Parameters:
   7818  *      unit - Unit number
   7819  *      mac  - MAC address
   7820  *      vlan - VLAN ID
   7821  */
   7822 int
   7823 bcm_trx_metro_l2_tunnel_delete(int unit, bcm_mac_t mac, bcm_vlan_t vlan)
   7824 {
   7825     mpls_station_tcam_entry_t station_entry;
   7826     uint16 hash;
   7827     bcm_mac_t hw_mac;
   7828     bcm_vlan_t hw_vlan;
   7829     int rv, i, num_station;
   7830 
   7831     /* Get the hash value for this key */
   7832     BCM_IF_ERROR_RETURN(_bcm_trx_mpls_station_hash_calc(unit, mac, vlan, &hash));
   7833 
   7834     /* find the entry to be deleted */
   7835     num_station = soc_mem_index_count(unit, MPLS_STATION_TCAMm);
   7836     COMMON_LOCK(unit);
   7837     for (i = 0; i < num_station; i++) {
   7838         if (hash == MPLS_STATION_HASH(unit, i)) {
   7839             /* Read HW entry to see if it's really a match */
   7840             rv = READ_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY,
   7841                                          i, &station_entry);
   7842             if (rv < 0) {
   7843                 COMMON_UNLOCK(unit);
   7844                 return rv;
   7845             }
   7846             soc_mem_mac_addr_get(unit, MPLS_STATION_TCAMm,
   7847                                  &station_entry, MAC_ADDRf, hw_mac);
   7848             hw_vlan = soc_mem_field32_get(unit, MPLS_STATION_TCAMm,
   7849                                           &station_entry, VLAN_IDf);
   7850             if ((vlan == hw_vlan) &&
   7851                 !sal_memcmp(mac, hw_mac, sizeof(bcm_mac_t))) {
   7852                 break;
   7853             }
   7854         }
   7855     }
   7856     if (i == num_station) {
   7857         /* Entry not found */
   7858         COMMON_UNLOCK(unit);
   7859         return BCM_E_NOT_FOUND;
   7860     }
   7861     /* Clear the entry in HW */
   7862     sal_memset(&station_entry, 0, sizeof(mpls_station_tcam_entry_t));
   7863     rv = WRITE_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY, i, &station_entry);
   7864     if (rv < 0) {
   7865         COMMON_UNLOCK(unit);
   7866         return rv;
   7867     }
   7868     COMMON_UNLOCK(unit);
   7869     MPLS_STATION_HASH(unit, i) = 0;
   7870     return BCM_E_NONE;
   7871 }
   7872 
   7873 /*
   7874  * Function:
   7875  *     bcm_l2_tunnel_delete_all
   7876  * Purpose:
   7877  *     Delete all (MAC, VLAN) for tunnel/MPLS processing.
   7878  *    Shared by MPLS and MIM
   7879  * Parameters:
   7880  *      unit - Unit number
   7881  */
   7882 int
   7883 bcm_trx_metro_l2_tunnel_delete_all(int unit)
   7884 {
   7885     int rv, num_station;
   7886 
   7887     num_station = soc_mem_index_count(unit, MPLS_STATION_TCAMm);
   7888     COMMON_LOCK(unit);
   7889     rv = soc_mem_clear(unit, MPLS_STATION_TCAMm, COPYNO_ALL, 0);
   7890     if (rv < 0) {
   7891         COMMON_UNLOCK(unit);
   7892         return rv;
   7893     }
   7894     sal_memset(COMMON_INFO(unit)->mpls_station_hash, 0,
   7895                sizeof(uint16) * num_station);
   7896     COMMON_UNLOCK(unit);
   7897     return BCM_E_NONE;
   7898 }
   7899 
   7900 #if defined(BCM_TRIUMPH2_SUPPORT)
   7901 /*
   7902  * Flexible stats:
   7903  * 
   7904  * Ingress/egress packet/byte counters which may be assigned from a pool
   7905  * to various packet categories.  There are two pools available:
   7906  * Service interface types:  VLAN, VRF, VFI
   7907  * Virtual interface types:  Some GPORT categories
   7908  * The source table responsible for the packet classification holds an
   7909  * index to the counter pool.  Otherwise, the implementation of the two
   7910  * types is equivalent, so it is abstracted here.
   7911  * This is implemented here because so many modules are touched by
   7912  * this feature.
   7913  */
   7914 
   7915 
   7916 
   7917 static _bcm_flex_stat_info_t *fs_info[BCM_MAX_NUM_UNITS][_bcmFlexStatTypeAllHwNum];
   7918 static int _tr2_flex_stat_api_ver[BCM_MAX_NUM_UNITS] = {0};
   7919 static sal_mutex_t _flex_stat_mutex[BCM_MAX_NUM_UNITS] = {NULL};
   7920 static uint64 *_bcm_flex_stat_mem[BCM_MAX_NUM_UNITS][_bcmFlexStatTypeHwNum]
   7921                                  [_BCM_FLEX_STAT_DIRS][_BCM_FLEX_STAT_GRANS];
   7922 static ing_service_counter_table_entry_t *_bcm_flex_stat_buff
   7923                                  [BCM_MAX_NUM_UNITS][_bcmFlexStatTypeHwNum]
   7924                                  [_BCM_FLEX_STAT_DIRS][_BCM_FLEX_STAT_BUFFS];
   7925 #ifdef BCM_TRIDENT_SUPPORT
   7926 static ing_service_counter_table_entry_t *_bcm_flex_stat_buff_y
   7927                                  [BCM_MAX_NUM_UNITS][_bcmFlexStatTypeHwNum]
   7928                                  [_BCM_FLEX_STAT_DIRS][_BCM_FLEX_STAT_BUFFS];
   7929 #endif /* BCM_TRIDENT_SUPPORT */
   7930 static uint32 _bcm_flex_stat_mem_types[] = {
   7931     ING_SERVICE_COUNTER_TABLEm,
   7932     EGR_SERVICE_COUNTER_TABLEm,
   7933     ING_VINTF_COUNTER_TABLEm,
   7934     EGR_VINTF_COUNTER_TABLEm
   7935 };
   7936 static uint8 _bcm_flex_stat_buff_toggle[BCM_MAX_NUM_UNITS] = {0};
   7937 
   7938 static soc_memacc_t *_bcm_flex_stat_memacc[BCM_MAX_NUM_UNITS];
   7939 
   7940 /* The gport, fp, MPLS label and both vxlt types are currently
   7941  * implemented in the same HW. Here we collapse them into the same
   7942  * info array for tracking.
   7943  * We need the different types to distinguish the different handles.
   7944  */
   7945 #define FS_TYPE_TO_HW_TYPE(unit, type) \
   7946         (((type == _bcmFlexStatTypeService) || \
   7947           (type == _bcmFlexStatTypeVrf))? _bcmFlexStatTypeService : \
   7948           (type == _bcmFlexStatTypeEgressService)? \
   7949           _bcmFlexStatTypeEgressService: \
   7950          (type == _bcmFlexStatTypeEgressGport || \
   7951           type == _bcmFlexStatTypeEgrVxlt)? \
   7952            _bcmFlexStatTypeEgressGport: _bcmFlexStatTypeGport)
   7953 
   7954 #define FS_TYPE_TO_SVC_VINTF_HW_TYPE(unit, type) \
   7955         (((type == _bcmFlexStatTypeService) || \
   7956           (type == _bcmFlexStatTypeVrf) || \
   7957           (type == _bcmFlexStatTypeEgressService))? \
   7958          _bcmFlexStatTypeService : \
   7959          _bcmFlexStatTypeGport)
   7960 
   7961 #define FS_INFO(unit, hw_type) \
   7962             fs_info[unit][hw_type]
   7963 
   7964 #define FS_MEM_SIZE(unit, hw_type)     FS_INFO(unit, hw_type)->stat_mem_size
   7965 #define FS_USED_BITMAP(unit, hw_type)  FS_INFO(unit, hw_type)->stats
   7966 #define FS_HANDLE_LIST_SIZE(unit, hw_type)  \
   7967                             FS_INFO(unit, hw_type)->handle_list_size
   7968 #define FS_HANDLE_LIST(unit, hw_type)  FS_INFO(unit, hw_type)->handle_list
   7969 #define FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, list_index) \
   7970             (&(FS_INFO(unit, hw_type)->handle_list[list_index]))
   7971 #define FS_HANDLE_LIST_ELEMENT_HANDLE(unit, hw_type, list_index) \
   7972             ((FS_INFO(unit, hw_type)->handle_list[list_index].handle))
   7973 #define FS_HANDLE_LIST_ELEMENT_TYPE(unit, hw_type, list_index) \
   7974             ((FS_INFO(unit, hw_type)->handle_list[list_index].type))
   7975 #define FS_HANDLE_LIST_ELEMENT_INDEX(unit, hw_type, list_index) \
   7976             ((FS_INFO(unit, hw_type)->handle_list[list_index].index))
   7977 #define FS_HANDLE_LIST_ELEMENT_SIZE \
   7978                                   sizeof(_bcm_flex_stat_handle_to_index_t)
   7979 #define FS_REF_CNT_ELEMENT(_u, _htype, _inx) \
   7980             (FS_INFO((_u), (_htype))->ref_cnt[(_inx)])
   7981 
   7982 /* Below, the macros work with the FS type */
   7983 /* type takes ingress hardware types */
   7984 #define FS_ING_MEM(type)         \
   7985         ((FS_TYPE_TO_HW_TYPE(unit, type) == _bcmFlexStatTypeService) ? \
   7986                 ING_SERVICE_COUNTER_TABLEm : ING_VINTF_COUNTER_TABLEm)
   7987 /* type takes egress hardware types */
   7988 #define FS_EGR_MEM(type)         \
   7989         (((FS_TYPE_TO_HW_TYPE(unit, type) == \
   7990                         _bcmFlexStatTypeEgressService) || \
   7991          (FS_TYPE_TO_HW_TYPE(unit, type) == _bcmFlexStatTypeService)) ? \
   7992                 EGR_SERVICE_COUNTER_TABLEm : EGR_VINTF_COUNTER_TABLEm)
   7993 
   7994 /* 
   7995  * Common resource lock
   7996  */
   7997 #define FS_LOCK(unit) \
   7998         sal_mutex_take(_flex_stat_mutex[unit], sal_mutex_FOREVER);
   7999 
   8000 #define FS_UNLOCK(unit) \
   8001         sal_mutex_give(_flex_stat_mutex[unit]); 
   8002 
   8003 #define FS_INIT(unit, type) \
   8004         if (FS_INFO(unit, FS_TYPE_TO_HW_TYPE(unit, type)) == NULL) { \
   8005             FS_UNLOCK(unit); \
   8006             return BCM_E_INIT; \
   8007         }
   8008 
   8009 #define TR2_FLEX_STAT_API_LEGACY    1
   8010 #define TR2_FLEX_STAT_API_NEW       2
   8011 
   8012 #ifdef BCM_WARM_BOOT_SUPPORT
   8013 
   8014 STATIC int
   8015 _bcm_common_wb_scache_size_get_tr2_flex_stat(int unit, int *req_scache_size)
   8016 {
   8017     int alloc_size = 0;
   8018 
   8019     alloc_size += sizeof (_tr2_flex_stat_api_ver);
   8020 
   8021     *req_scache_size += alloc_size;
   8022 
   8023     return BCM_E_NONE;
   8024 
   8025 }
   8026 
   8027 /* Syncs _tr2_flex_stat_api_ver into scache */
   8028 STATIC int
   8029 _bcm_common_wb_tr2_flex_stat_sync(int unit, uint8 **scache_ptr)
   8030 {
   8031     int i;
   8032     uint32 *u32_scache_p;
   8033 
   8034     u32_scache_p = (uint32 *)(*scache_ptr);
   8035 
   8036     for (i = 0; i < BCM_MAX_NUM_UNITS; i++)
   8037     {
   8038         *u32_scache_p = _tr2_flex_stat_api_ver[i];
   8039         u32_scache_p++;
   8040     }
   8041 
   8042     *scache_ptr = (uint8 *)u32_scache_p;
   8043 
   8044     return BCM_E_NONE;
   8045 }
   8046 
   8047 /* Recovers _tr2_flex_stat_api_ver from scache  */
   8048 STATIC int
   8049 _bcm_common_wb_tr2_flex_stat_reinit(int unit, uint8 **scache_ptr)
   8050 {
   8051     int i;
   8052 
   8053     uint32 *u32_scache_p;
   8054 
   8055     u32_scache_p = (uint32 *)(*scache_ptr);
   8056 
   8057     for (i = 0; i < BCM_MAX_NUM_UNITS; i++) {
   8058         _tr2_flex_stat_api_ver[i] = *u32_scache_p;
   8059         u32_scache_p++;
   8060 
   8061     }
   8062     *scache_ptr = (uint8 *)u32_scache_p;
   8063 
   8064     return BCM_E_NONE;
   8065 }
   8066 
   8067 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   8068 STATIC int
   8069 _bcm_common_wb_scache_size_get_my_station_shadow_mask(int unit, int *req_scache_size)
   8070 {
   8071     int alloc_size = 0;
   8072 
   8073     alloc_size += sizeof (my_station_shadow_mask_t);
   8074 
   8075     *req_scache_size += alloc_size;
   8076 
   8077     return BCM_E_NONE;
   8078 
   8079 }
   8080 
   8081 STATIC int
   8082 _bcm_common_wb_my_station_shadow_mask_sync(int unit, uint8 **scache_ptr)
   8083 {
   8084     int i;
   8085     uint32 *u32_scache_p;
   8086     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
   8087 
   8088     if (info->my_station_shadow_mask == NULL) {
   8089         return BCM_E_NONE;
   8090     }
   8091 
   8092     u32_scache_p = (uint32 *)(*scache_ptr);
   8093 
   8094     for (i = 0; i < (MY_STATION_SHADOW_MASK_MAX_ARRAY_SIZE+31)/32; i++)
   8095     {
   8096         *u32_scache_p = info->my_station_shadow_mask->buf[i];
   8097         u32_scache_p++;
   8098     }
   8099 #if defined(BCM_TRIDENT3_SUPPORT)
   8100     if (SOC_IS_TRIDENT3X(unit)) {
   8101         for (i = 0; i < (MY_STATION_SHADOW_MASK_MAX_ARRAY_SIZE+31)/32; i++)
   8102         {
   8103             *u32_scache_p = info->my_station2_shadow_mask->buf[i];
   8104             u32_scache_p++;
   8105         }
   8106     }
   8107 #endif
   8108     *scache_ptr = (uint8 *)u32_scache_p;
   8109 
   8110     return BCM_E_NONE;
   8111 }
   8112 
   8113 STATIC int
   8114 _bcm_common_wb_my_station_shadow_mask_reinit(int unit, int is_station2, uint8 **scache_ptr)
   8115 {
   8116     int i;
   8117 
   8118     uint32 *u32_scache_p;
   8119     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
   8120 
   8121     if (info->my_station_shadow_mask == NULL) {
   8122         return BCM_E_NONE;
   8123     }
   8124 
   8125     u32_scache_p = (uint32 *)(*scache_ptr);
   8126 
   8127     for (i = 0; i < (MY_STATION_SHADOW_MASK_MAX_ARRAY_SIZE+31)/32; i++) {
   8128         if (!is_station2) {
   8129             info->my_station_shadow_mask->buf[i] = *u32_scache_p;
   8130         }
   8131 #if defined(BCM_TRIDENT3_SUPPORT)
   8132         else if (SOC_IS_TRIDENT3X(unit)){
   8133             info->my_station2_shadow_mask->buf[i] = *u32_scache_p;
   8134         }
   8135 #endif
   8136         u32_scache_p++;
   8137 
   8138     }
   8139     *scache_ptr = (uint8 *)u32_scache_p;
   8140 
   8141     return BCM_E_NONE;
   8142 }
   8143 #endif
   8144 #endif /* BCM_WARM_BOOT_SUPPORT */
   8145 
   8146 
   8147 /* Allocate Flex counter table SW caches and fetch buffers */
   8148 STATIC int
   8149 _bcm_esw_flex_stat_mem_init(int unit)
   8150 {
   8151     int i /* types */, j /* dir */, k /* grans/buffs */;
   8152     int alloc_size, rv = BCM_E_NONE; 
   8153     soc_mem_t mem;
   8154     for (i = 0; i < _bcmFlexStatTypeHwNum; i++) {
   8155         for (j = 0; j < _BCM_FLEX_STAT_DIRS; j++) {
   8156             mem = _bcm_flex_stat_mem_types[(i * _BCM_FLEX_STAT_DIRS) + j];
   8157             for (k = 0; k < _BCM_FLEX_STAT_GRANS; k++) {
   8158                 alloc_size = SOC_MEM_SIZE(unit, mem) * sizeof(uint64);
   8159                 _bcm_flex_stat_mem[unit][i][j][k] = 
   8160                     sal_alloc(alloc_size, "Flexible counters cache");
   8161                 if (NULL == _bcm_flex_stat_mem[unit][i][j][k]) {
   8162                     LOG_CLI((BSL_META_U(unit,
   8163                                         "bcm_esw_flex_stat_mem_init: Mem alloc failed - "
   8164                                         "unit: %d, type: %d, dir: %d, gran: %d\n"),
   8165                              unit, i, j, k));
   8166                     return BCM_E_MEMORY;
   8167                 }
   8168                 sal_memset(_bcm_flex_stat_mem[unit][i][j][k], 0, alloc_size);
   8169             }
   8170         }
   8171     }
   8172     for (i = 0; i < _bcmFlexStatTypeHwNum; i++) {
   8173         for (j = 0; j < _BCM_FLEX_STAT_DIRS; j++) {
   8174             mem = _bcm_flex_stat_mem_types[(i * _BCM_FLEX_STAT_DIRS) + j];
   8175             alloc_size = SOC_MEM_TABLE_BYTES(unit, mem);
   8176             for (k = 0; k < _BCM_FLEX_STAT_BUFFS; k++) {
   8177                 _bcm_flex_stat_buff[unit][i][j][k] = \
   8178                     soc_cm_salloc(unit, alloc_size, "Flexible counters buff");
   8179                 if (NULL == _bcm_flex_stat_buff[unit][i][j][k]) {
   8180                     LOG_CLI((BSL_META_U(unit,
   8181                                         "bcm_esw_flex_stat_mem_init: Mem alloc failed - "
   8182                                         "unit: %d, type: %d, dir: %d, buff: %d\n"),
   8183                              unit, i, j, k));
   8184                     LOG_CLI((BSL_META_U(unit,
   8185                                         "Mem alloc failed.\n")));
   8186                     return BCM_E_MEMORY;
   8187                 }
   8188                 sal_memset(_bcm_flex_stat_buff[unit][i][j][k], 0, alloc_size);
   8189 #ifdef BCM_TRIDENT_SUPPORT
   8190                 if (SOC_IS_TD_TT(unit)) {
   8191                     _bcm_flex_stat_buff_y[unit][i][j][k] = \
   8192                         soc_cm_salloc(unit, alloc_size, 
   8193                                       "Flexible counters buff_y");
   8194                     if (NULL == _bcm_flex_stat_buff_y[unit][i][j][k]) {
   8195                             return BCM_E_MEMORY;
   8196                     }
   8197                     sal_memset(_bcm_flex_stat_buff_y[unit][i][j][k], 0, 
   8198                                alloc_size);
   8199                 }
   8200 #endif /* BCM_TRIDENT_SUPPORT */
   8201             }
   8202         } 
   8203     }
   8204     return rv;
   8205 }
   8206 
   8207 /* Free Flex counter table SW caches and fetch buffers */
   8208 STATIC void
   8209 _bcm_esw_flex_stat_mem_free(int unit)
   8210 {
   8211     int i /* types */, j /* dir */, k /* grans/buffs */;
   8212     for (i = 0; i < _bcmFlexStatTypeHwNum; i++) {
   8213         for (j = 0; j < _BCM_FLEX_STAT_DIRS; j++) {
   8214             for (k = 0; k < _BCM_FLEX_STAT_GRANS; k++) {
   8215                 sal_free(_bcm_flex_stat_mem[unit][i][j][k]);
   8216             }
   8217         }
   8218     }
   8219     for (i = 0; i < _bcmFlexStatTypeHwNum; i++) {
   8220         for (j = 0; j < _BCM_FLEX_STAT_DIRS; j++) {
   8221             for (k = 0; k < _BCM_FLEX_STAT_BUFFS; k++) {
   8222                 soc_cm_sfree(unit, _bcm_flex_stat_buff[unit][i][j][k]);
   8223 #ifdef BCM_TRIDENT_SUPPORT
   8224                 if (SOC_IS_TD_TT(unit)) {
   8225                     soc_cm_sfree(unit, _bcm_flex_stat_buff_y[unit][i][j][k]);
   8226                 }
   8227 #endif /* BCM_TRIDENT_SUPPORT */
   8228             }
   8229         }
   8230     }
   8231 }
   8232 
   8233 typedef struct _bcm_fs_memacc_map_s {
   8234     soc_mem_t mem;
   8235     soc_field_t fld;
   8236     int type_index;
   8237 } _bcm_fs_memacc_map_t;
   8238 
   8239 static _bcm_fs_memacc_map_t _bcm_tr2_fs_memacc_map[] = {
   8240     {ING_SERVICE_COUNTER_TABLEm, PACKET_COUNTERf,
   8241      _BCM_FS_MEMACC_SERVICE_ING_PKT},
   8242     {ING_SERVICE_COUNTER_TABLEm, BYTE_COUNTERf,
   8243      _BCM_FS_MEMACC_SERVICE_ING_BYTE},
   8244     {EGR_SERVICE_COUNTER_TABLEm, PACKET_COUNTERf,
   8245      _BCM_FS_MEMACC_SERVICE_EGR_PKT},
   8246     {EGR_SERVICE_COUNTER_TABLEm, BYTE_COUNTERf,
   8247      _BCM_FS_MEMACC_SERVICE_EGR_BYTE},
   8248     {ING_VINTF_COUNTER_TABLEm, PACKET_COUNTERf,
   8249      _BCM_FS_MEMACC_VINTF_ING_PKT},
   8250     {ING_VINTF_COUNTER_TABLEm, BYTE_COUNTERf,
   8251      _BCM_FS_MEMACC_VINTF_ING_BYTE},
   8252     {EGR_VINTF_COUNTER_TABLEm, PACKET_COUNTERf,
   8253      _BCM_FS_MEMACC_VINTF_EGR_PKT},
   8254     {EGR_VINTF_COUNTER_TABLEm, BYTE_COUNTERf,
   8255      _BCM_FS_MEMACC_VINTF_EGR_BYTE},
   8256 };
   8257 
   8258 #ifdef BCM_TRIDENT_SUPPORT
   8259 static _bcm_fs_memacc_map_t _bcm_td_fs_memacc_map[] = {
   8260     {ING_SERVICE_COUNTER_TABLE_Xm, PACKET_COUNTERf,
   8261      _BCM_FS_MEMACC_SERVICE_ING_PKT},
   8262     {ING_SERVICE_COUNTER_TABLE_Xm, BYTE_COUNTERf,
   8263      _BCM_FS_MEMACC_SERVICE_ING_BYTE},
   8264     {EGR_SERVICE_COUNTER_TABLE_Xm, PACKET_COUNTERf,
   8265      _BCM_FS_MEMACC_SERVICE_EGR_PKT},
   8266     {EGR_SERVICE_COUNTER_TABLE_Xm, BYTE_COUNTERf,
   8267      _BCM_FS_MEMACC_SERVICE_EGR_BYTE},
   8268     {ING_VINTF_COUNTER_TABLE_Xm, PACKET_COUNTERf,
   8269      _BCM_FS_MEMACC_VINTF_ING_PKT},
   8270     {ING_VINTF_COUNTER_TABLE_Xm, BYTE_COUNTERf,
   8271      _BCM_FS_MEMACC_VINTF_ING_BYTE},
   8272     {EGR_VINTF_COUNTER_TABLE_Xm, PACKET_COUNTERf,
   8273      _BCM_FS_MEMACC_VINTF_EGR_PKT},
   8274     {EGR_VINTF_COUNTER_TABLE_Xm, BYTE_COUNTERf,
   8275      _BCM_FS_MEMACC_VINTF_EGR_BYTE},
   8276 
   8277     {ING_SERVICE_COUNTER_TABLE_Ym, PACKET_COUNTERf,
   8278      _BCM_FS_MEMACC_SERVICE_ING_PKT + _BCM_FS_MEMACC_NUM},
   8279     {ING_SERVICE_COUNTER_TABLE_Ym, BYTE_COUNTERf,
   8280      _BCM_FS_MEMACC_SERVICE_ING_BYTE + _BCM_FS_MEMACC_NUM},
   8281     {EGR_SERVICE_COUNTER_TABLE_Ym, PACKET_COUNTERf,
   8282      _BCM_FS_MEMACC_SERVICE_EGR_PKT + _BCM_FS_MEMACC_NUM},
   8283     {EGR_SERVICE_COUNTER_TABLE_Ym, BYTE_COUNTERf,
   8284      _BCM_FS_MEMACC_SERVICE_EGR_BYTE + _BCM_FS_MEMACC_NUM},
   8285     {ING_VINTF_COUNTER_TABLE_Ym, PACKET_COUNTERf,
   8286      _BCM_FS_MEMACC_VINTF_ING_PKT + _BCM_FS_MEMACC_NUM},
   8287     {ING_VINTF_COUNTER_TABLE_Ym, BYTE_COUNTERf,
   8288      _BCM_FS_MEMACC_VINTF_ING_BYTE + _BCM_FS_MEMACC_NUM},
   8289     {EGR_VINTF_COUNTER_TABLE_Ym, PACKET_COUNTERf,
   8290      _BCM_FS_MEMACC_VINTF_EGR_PKT + _BCM_FS_MEMACC_NUM},
   8291     {EGR_VINTF_COUNTER_TABLE_Ym, BYTE_COUNTERf,
   8292      _BCM_FS_MEMACC_VINTF_EGR_BYTE + _BCM_FS_MEMACC_NUM},
   8293 };
   8294 #endif /*  BCM_TRIDENT_SUPPORT */
   8295 
   8296 STATIC int
   8297 _bcm_esw_flex_stat_memacc_init(int unit)
   8298 {
   8299     int alloc_size, rv = BCM_E_NONE;
   8300     _bcm_fs_memacc_map_t *memacc_map = _bcm_tr2_fs_memacc_map;
   8301     int mam_ix, memacc_map_size = _BCM_FS_MEMACC_NUM;
   8302 
   8303     alloc_size = (_BCM_FS_MEMACC_NUM * sizeof(soc_memacc_t));
   8304 
   8305 #ifdef BCM_TRIDENT_SUPPORT
   8306     if (SOC_IS_TD_TT(unit)) {
   8307         /* X & Y pipes */
   8308         alloc_size *= 2;
   8309         memacc_map = _bcm_td_fs_memacc_map;
   8310         memacc_map_size = 2 * _BCM_FS_MEMACC_NUM;
   8311     }
   8312 #endif /* BCM_TRIDENT_SUPPORT */
   8313 
   8314     _bcm_flex_stat_memacc[unit] =
   8315         sal_alloc(alloc_size, "Flexible counters memacc data");
   8316     if (NULL == _bcm_flex_stat_memacc[unit]) {
   8317         rv = BCM_E_MEMORY;
   8318     }
   8319 
   8320     for (mam_ix = 0; mam_ix < memacc_map_size; mam_ix++) {
   8321         if (BCM_SUCCESS(rv)) {
   8322             rv = soc_memacc_init(unit, memacc_map[mam_ix].mem,
   8323                                  memacc_map[mam_ix].fld,
   8324                                  &(_bcm_flex_stat_memacc[unit]
   8325                                    [memacc_map[mam_ix].type_index]));
   8326         }
   8327         if (BCM_SUCCESS(rv) &&
   8328             (0 == SOC_MEMACC_FIELD_LENGTH(&(_bcm_flex_stat_memacc[unit]
   8329                                          [memacc_map[mam_ix].type_index])))) {
   8330             LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8331                         (BSL_META_U(unit,
   8332                                     "bcm_esw_flex_stat_memacc_init: " 
   8333                                     "Invalid memacc field info.\n")));
   8334             rv = BCM_E_INTERNAL;
   8335         }
   8336     }
   8337     return rv;
   8338 }
   8339 
   8340 /* Callback to be invoked from counter thread */
   8341 void
   8342 _bcm_esw_flex_stat_collection(int unit,
   8343                               _bcm_flex_stat_type_t type,
   8344                               int fs_idx, _bcm_flex_stat_t stat)
   8345 {
   8346     int i = 0 /* types */, j = 0 /* dir */, k = 0 /* index */, max = 0;
   8347     soc_mem_t mem;
   8348     ing_service_counter_table_entry_t *curr_ptr = NULL;
   8349     ing_service_counter_table_entry_t *prev_ptr = NULL;
   8350     ing_service_counter_table_entry_t *curr_eptr = NULL;
   8351     ing_service_counter_table_entry_t *prev_eptr = NULL;
   8352     ing_service_counter_table_entry_t flex_ctr_entry;
   8353     uint64 *prev_pktptr, *prev_bytptr;
   8354     int rv = BCM_E_NONE;
   8355     soc_memacc_t *memacc_pkt = NULL;
   8356     soc_memacc_t *memacc_byte = NULL;
   8357     int field_length_byte = 0;
   8358     int field_length_packet = 0;
   8359     int max_stat_types, max_dirs;
   8360     int min_dirs = 0;
   8361     int min_stat_types, min_index;
   8362     uint64 curr, prev, diff, size; 
   8363     SHR_BITDCL *stat_bmp;
   8364 #ifdef BCM_TRIDENT_SUPPORT
   8365     ing_service_counter_table_entry_t *curr_ptr_y = NULL; 
   8366     ing_service_counter_table_entry_t *prev_ptr_y = NULL;
   8367     ing_service_counter_table_entry_t *curr_eptr_y = NULL;
   8368     ing_service_counter_table_entry_t *prev_eptr_y = NULL;
   8369     ing_service_counter_table_entry_t flex_ctr_entry_y;
   8370     soc_mem_t mem_x = 0, mem_y = 0;
   8371     soc_memacc_t *memacc_pkt_x = NULL;
   8372     soc_memacc_t *memacc_byte_x = NULL;
   8373     soc_memacc_t *memacc_pkt_y = NULL;
   8374     soc_memacc_t *memacc_byte_y = NULL;
   8375     int field_length_byte_x = 0;
   8376     int field_length_packet_x = 0;
   8377     int field_length_byte_y = 0;
   8378     int field_length_packet_y = 0;
   8379     uint64 diff_y;
   8380 #endif /* BCM_TRIDENT_SUPPORT */
   8381 
   8382     /*
   8383      * If fs_idx!= -1 is The request is to sync a specific statistics 
   8384      * sw count with hw count.
   8385      */
   8386     if (fs_idx != -1) {
   8387         /* set type, dir, index for a specific stat to retrieved */
   8388         min_stat_types  = FS_TYPE_TO_SVC_VINTF_HW_TYPE(unit, type);
   8389         max_stat_types = min_stat_types + 1;
   8390 
   8391         if (stat > _bcmFlexStatIngressBytes) {
   8392             /* egress */
   8393             min_dirs = 1;
   8394         }
   8395 
   8396         min_index = fs_idx;
   8397         max_dirs = min_dirs + 1;
   8398     } else {
   8399         /* retrieve all the flex stats */    
   8400         min_stat_types = 0;
   8401         max_stat_types = _bcmFlexStatTypeHwNum;
   8402         min_dirs = 0;
   8403         max_dirs = _BCM_FLEX_STAT_DIRS;
   8404         min_index = 0;
   8405     }
   8406 
   8407     /* For each table fetch stats from h/w */
   8408     for (i = min_stat_types; i < max_stat_types; i++) {
   8409         for (j = min_dirs; j < max_dirs; j++) {
   8410             /* Take and release lock to permit other threads'
   8411              * activity in between table scans. */
   8412             FS_LOCK(unit);
   8413             if (_tr2_flex_stat_api_ver[unit] == TR2_FLEX_STAT_API_NEW) {
   8414                 stat_bmp = FS_USED_BITMAP(unit,i+(_bcmFlexStatTypeHwNum * j));
   8415             } else {
   8416                 stat_bmp = FS_USED_BITMAP(unit, i);
   8417             }
   8418             mem = _bcm_flex_stat_mem_types[(i * _BCM_FLEX_STAT_DIRS) + j];
   8419             curr_ptr = _bcm_flex_stat_buff[unit][i][j]
   8420                                           [_bcm_flex_stat_buff_toggle[unit]];
   8421             if (NULL == curr_ptr) {
   8422                 LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8423                             (BSL_META_U(unit,
   8424                                         "bcm_esw_flex_stat_callback: " 
   8425                                         "Bad mem ptr - unit: %d, type: %d, dir: %d\n"),
   8426                              unit, i, j));
   8427                 /* we are in a callback; no point continuing */
   8428                 FS_UNLOCK(unit);
   8429                 return;
   8430             }
   8431 #ifdef BCM_TRIDENT_SUPPORT
   8432             if (SOC_IS_TD_TT(unit)) {
   8433                 curr_ptr_y = _bcm_flex_stat_buff_y[unit][i][j]
   8434                                  [_bcm_flex_stat_buff_toggle[unit]];
   8435                 if (NULL == curr_ptr_y) {
   8436                     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8437                                 (BSL_META_U(unit,
   8438                                             "bcm_esw_flex_stat_callback: " 
   8439                                             "Bad mem ptr - unit: %d, type: %d, dir: %d\n"),
   8440                                  unit, i, j));
   8441                     /* we are in a callback; no point continuing */
   8442                     FS_UNLOCK(unit);
   8443                     return;
   8444                 }
   8445                 switch (mem) {
   8446                 case ING_SERVICE_COUNTER_TABLEm:
   8447                     mem_x = ING_SERVICE_COUNTER_TABLE_Xm;
   8448                     memacc_pkt_x = &(_bcm_flex_stat_memacc[unit]
   8449                         [_BCM_FS_MEMACC_SERVICE_ING_PKT]);
   8450                     memacc_byte_x = &(_bcm_flex_stat_memacc[unit]
   8451                         [_BCM_FS_MEMACC_SERVICE_ING_BYTE]);
   8452                     mem_y = ING_SERVICE_COUNTER_TABLE_Ym;
   8453                     memacc_pkt_y = &(_bcm_flex_stat_memacc[unit]
   8454                         [_BCM_FS_MEMACC_SERVICE_ING_PKT +
   8455                          _BCM_FS_MEMACC_NUM]);
   8456                     memacc_byte_y = &(_bcm_flex_stat_memacc[unit]
   8457                         [_BCM_FS_MEMACC_SERVICE_ING_BYTE +
   8458                          _BCM_FS_MEMACC_NUM]);
   8459                     break;
   8460                 case EGR_SERVICE_COUNTER_TABLEm:
   8461                     mem_x = EGR_SERVICE_COUNTER_TABLE_Xm; 
   8462                     memacc_pkt_x = &(_bcm_flex_stat_memacc[unit]
   8463                         [_BCM_FS_MEMACC_SERVICE_EGR_PKT]);
   8464                     memacc_byte_x = &(_bcm_flex_stat_memacc[unit]
   8465                         [_BCM_FS_MEMACC_SERVICE_EGR_BYTE]);
   8466                     mem_y = EGR_SERVICE_COUNTER_TABLE_Ym; 
   8467                     memacc_pkt_y = &(_bcm_flex_stat_memacc[unit]
   8468                         [_BCM_FS_MEMACC_SERVICE_EGR_PKT +
   8469                          _BCM_FS_MEMACC_NUM]);
   8470                     memacc_byte_y = &(_bcm_flex_stat_memacc[unit]
   8471                         [_BCM_FS_MEMACC_SERVICE_EGR_BYTE +
   8472                          _BCM_FS_MEMACC_NUM]);
   8473                     break;
   8474                 case ING_VINTF_COUNTER_TABLEm:
   8475                     mem_x = ING_VINTF_COUNTER_TABLE_Xm; 
   8476                     memacc_pkt_x = &(_bcm_flex_stat_memacc[unit]
   8477                         [_BCM_FS_MEMACC_VINTF_ING_PKT]);
   8478                     memacc_byte_x = &(_bcm_flex_stat_memacc[unit]
   8479                         [_BCM_FS_MEMACC_VINTF_ING_BYTE]);
   8480                     mem_y = ING_VINTF_COUNTER_TABLE_Ym; 
   8481                     memacc_pkt_y = &(_bcm_flex_stat_memacc[unit]
   8482                         [_BCM_FS_MEMACC_VINTF_ING_PKT +
   8483                          _BCM_FS_MEMACC_NUM]);
   8484                     memacc_byte_y = &(_bcm_flex_stat_memacc[unit]
   8485                         [_BCM_FS_MEMACC_VINTF_ING_BYTE +
   8486                          _BCM_FS_MEMACC_NUM]);
   8487                     break;
   8488                 case EGR_VINTF_COUNTER_TABLEm:
   8489                     mem_x = EGR_VINTF_COUNTER_TABLE_Xm; 
   8490                     memacc_pkt_x = &(_bcm_flex_stat_memacc[unit]
   8491                         [_BCM_FS_MEMACC_VINTF_EGR_PKT]);
   8492                     memacc_byte_x = &(_bcm_flex_stat_memacc[unit]
   8493                         [_BCM_FS_MEMACC_VINTF_EGR_BYTE]);
   8494                     mem_y = EGR_VINTF_COUNTER_TABLE_Ym; 
   8495                     memacc_pkt_y = &(_bcm_flex_stat_memacc[unit]
   8496                         [_BCM_FS_MEMACC_VINTF_EGR_PKT +
   8497                          _BCM_FS_MEMACC_NUM]);
   8498                     memacc_byte_y = &(_bcm_flex_stat_memacc[unit]
   8499                         [_BCM_FS_MEMACC_VINTF_EGR_BYTE +
   8500                          _BCM_FS_MEMACC_NUM]);
   8501                     break;
   8502                 default:
   8503                     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8504                                 (BSL_META_U(unit,
   8505                                             "bcm_esw_flex_stat_callback: " 
   8506                                             "Bad mem type (%d) - unit: %d, "
   8507                                             "type: %d, dir: %d\n"), mem, unit, i, j));
   8508                     /* we are in a callback; no point continuing */
   8509                     FS_UNLOCK(unit);
   8510                     return;
   8511                 }
   8512 
   8513                 /*
   8514                  * If fs_idx!= -1 is The request is to sync a specific statistic 
   8515                  * sw count with hw count. fs_idx is the index of the flex stat 
   8516                  * to be read. issue a mem_read only for the index and process 
   8517                  * the count.
   8518                  */
   8519                 if (fs_idx != -1) {
   8520                     rv = soc_mem_read(unit, mem_x, MEM_BLOCK_ANY,
   8521                                       fs_idx, &flex_ctr_entry);
   8522                     if (rv < 0) {
   8523                         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8524                                    (BSL_META_U(unit,
   8525                                                "bcm_esw_flex_stat_callback: " 
   8526                                                "Mem read failed.\n")));
   8527                         /* we are in a callback; no point continuing */
   8528                         FS_UNLOCK(unit);
   8529                         return;
   8530                     } 
   8531 
   8532                     /* Dual pipe, read from X pipe and Y pipe then add */
   8533                     rv = soc_mem_read(unit, mem_y, MEM_BLOCK_ANY,
   8534                                       fs_idx, &flex_ctr_entry_y);
   8535 
   8536                     if (rv < 0) {
   8537                         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8538                                    (BSL_META_U(unit,
   8539                                                "bcm_esw_flex_stat_callback: " 
   8540                                                "Mem read failed.\n")));
   8541                         /* we are in a callback; no point continuing */
   8542                         FS_UNLOCK(unit);
   8543                         return;
   8544                     } 
   8545                     /* read and process specific index */
   8546                     max = k + 1;
   8547                 } else {
   8548 
   8549                     rv = soc_mem_read_range(unit, mem_x, MEM_BLOCK_ANY, 
   8550                                             soc_mem_index_min(unit, mem_x), 
   8551                                             soc_mem_index_max(unit, mem_x), 
   8552                                             curr_ptr);
   8553                     if (rv < 0) {
   8554                         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8555                                    (BSL_META_U(unit,
   8556                                                "bcm_esw_flex_stat_callback: " 
   8557                                                "Mem read failed.\n")));
   8558                         /* we are in a callback; no point continuing */
   8559                         FS_UNLOCK(unit);
   8560                         return;
   8561                     } 
   8562                     rv = soc_mem_read_range(unit, mem_y, MEM_BLOCK_ANY, 
   8563                                             soc_mem_index_min(unit, mem_y), 
   8564                                             soc_mem_index_max(unit, mem_y), 
   8565                                             curr_ptr_y);
   8566                     if (rv < 0) {
   8567                         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8568                                    (BSL_META_U(unit,
   8569                                                "bcm_esw_flex_stat_callback: " 
   8570                                                "Mem read failed.\n")));
   8571                         /* we are in a callback; no point continuing */
   8572                         FS_UNLOCK(unit);
   8573                         return;
   8574                     } 
   8575                     max = soc_mem_index_max(unit, mem_x);
   8576                 }
   8577 
   8578                 field_length_packet_x =
   8579                     SOC_MEMACC_FIELD_LENGTH(memacc_pkt_x);
   8580                 field_length_byte_x =
   8581                     SOC_MEMACC_FIELD_LENGTH(memacc_byte_x);
   8582                 field_length_packet_y =
   8583                     SOC_MEMACC_FIELD_LENGTH(memacc_pkt_y);
   8584                 field_length_byte_y =
   8585                     SOC_MEMACC_FIELD_LENGTH(memacc_byte_y);
   8586             } else 
   8587 #endif /* BCM_TRIDENT_SUPPORT */
   8588             {
   8589                 switch (mem) {
   8590                 case ING_SERVICE_COUNTER_TABLEm:
   8591                     memacc_pkt = &(_bcm_flex_stat_memacc[unit]
   8592                         [_BCM_FS_MEMACC_SERVICE_ING_PKT]);
   8593                     memacc_byte = &(_bcm_flex_stat_memacc[unit]
   8594                         [_BCM_FS_MEMACC_SERVICE_ING_BYTE]);
   8595                     break;
   8596                 case EGR_SERVICE_COUNTER_TABLEm:
   8597                     memacc_pkt = &(_bcm_flex_stat_memacc[unit]
   8598                         [_BCM_FS_MEMACC_SERVICE_EGR_PKT]);
   8599                     memacc_byte = &(_bcm_flex_stat_memacc[unit]
   8600                         [_BCM_FS_MEMACC_SERVICE_EGR_BYTE]);
   8601                     break;
   8602                 case ING_VINTF_COUNTER_TABLEm:
   8603                     memacc_pkt = &(_bcm_flex_stat_memacc[unit]
   8604                         [_BCM_FS_MEMACC_VINTF_ING_PKT]);
   8605                     memacc_byte = &(_bcm_flex_stat_memacc[unit]
   8606                         [_BCM_FS_MEMACC_VINTF_ING_BYTE]);
   8607                     break;
   8608                 case EGR_VINTF_COUNTER_TABLEm:
   8609                     memacc_pkt = &(_bcm_flex_stat_memacc[unit]
   8610                         [_BCM_FS_MEMACC_VINTF_EGR_PKT]);
   8611                     memacc_byte = &(_bcm_flex_stat_memacc[unit]
   8612                         [_BCM_FS_MEMACC_VINTF_EGR_BYTE]);
   8613                     break;
   8614                 default:
   8615                     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8616                                 (BSL_META_U(unit,
   8617                                             "bcm_esw_flex_stat_callback: " 
   8618                                             "Bad mem type (%d) - unit: %d, "
   8619                                             "type: %d, dir: %d\n"), mem, unit, i, j));
   8620                     /* we are in a callback; no point continuing */
   8621                     FS_UNLOCK(unit);
   8622                     return;
   8623                 }
   8624 
   8625                 /*
   8626                  * If fs_idx!= -1 is The request is to sync a specific statistic 
   8627                  * sw count with hw count. fs_idx is the index of the flex stat 
   8628                  * to be read. issue a mem_read only for the index and process 
   8629                  * the count.
   8630                  */
   8631                 if (fs_idx != -1) {
   8632                     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   8633                                       fs_idx, &flex_ctr_entry);
   8634                     if (rv < 0) {
   8635                         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8636                                    (BSL_META_U(unit,
   8637                                                "bcm_esw_flex_stat_callback: " 
   8638                                                "Mem read failed.\n")));
   8639                         /* we are in a callback; no point continuing */
   8640                         FS_UNLOCK(unit);
   8641                         return;
   8642                     } 
   8643 
   8644                     /* fetching only 1 index */
   8645                     max = k + 1;
   8646                 } else {
   8647                     rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 
   8648                                             soc_mem_index_min(unit, mem), 
   8649                                             soc_mem_index_max(unit, mem), 
   8650                                             curr_ptr);
   8651                     if (rv < 0) {
   8652                         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   8653                                    (BSL_META_U(unit,
   8654                                                "bcm_esw_flex_stat_callback: " 
   8655                                                "Mem read failed.\n")));
   8656                         /* we are in a callback; no point continuing */
   8657                         FS_UNLOCK(unit);
   8658                         return;
   8659                     } 
   8660 
   8661                     max = soc_mem_index_max(unit, mem);
   8662                 }
   8663                 field_length_packet = SOC_MEMACC_FIELD_LENGTH(memacc_pkt);
   8664                 field_length_byte = SOC_MEMACC_FIELD_LENGTH(memacc_byte);
   8665             }
   8666 
   8667             /* Iterate through and check/get diffs */
   8668             prev_ptr = _bcm_flex_stat_buff[unit][i][j]
   8669                                           [!_bcm_flex_stat_buff_toggle[unit]];
   8670 #ifdef BCM_TRIDENT_SUPPORT
   8671             if (SOC_IS_TD_TT(unit)) {
   8672                 prev_ptr_y = _bcm_flex_stat_buff_y[unit][i][j]
   8673                                  [!_bcm_flex_stat_buff_toggle[unit]];
   8674             }
   8675 #endif /* BCM_TRIDENT_SUPPORT */
   8676             prev_pktptr = _bcm_flex_stat_mem[unit][i][j][0];
   8677             prev_bytptr = _bcm_flex_stat_mem[unit][i][j][1];
   8678             for (k = min_index ; k < max; k++) {
   8679                 if (!SHR_BITGET(stat_bmp, k)) {
   8680                     /* Stat not enabled, don't bother to collect */
   8681                     continue;
   8682                 }
   8683 
   8684                 /* DMA memory entry arithmetic */ 
   8685                 if (fs_idx == -1) { 
   8686                     curr_eptr = soc_mem_table_idx_to_pointer(unit,
   8687                                             ING_SERVICE_COUNTER_TABLEm,
   8688                                             ing_service_counter_table_entry_t *,
   8689                                                              curr_ptr, k);
   8690                 } else {
   8691                     /* stat retrieval for a specific index */
   8692                     curr_eptr = &flex_ctr_entry;
   8693                 }
   8694 
   8695                 prev_eptr = soc_mem_table_idx_to_pointer(unit,
   8696                                         ING_SERVICE_COUNTER_TABLEm,
   8697                                         ing_service_counter_table_entry_t *,
   8698                                                          prev_ptr, k);
   8699 #ifdef BCM_TRIDENT_SUPPORT
   8700                 if (SOC_IS_TD_TT(unit)) {
   8701                     if (fs_idx == -1) { 
   8702                         curr_eptr_y = soc_mem_table_idx_to_pointer(unit,
   8703                                             ING_SERVICE_COUNTER_TABLEm,
   8704                                             ing_service_counter_table_entry_t *,
   8705                                             curr_ptr_y, k);
   8706                     } else {
   8707                         /* stat retrieval for a specific index */
   8708                         curr_eptr_y = &flex_ctr_entry_y;
   8709                     }
   8710                     prev_eptr_y = soc_mem_table_idx_to_pointer(unit,
   8711                                         ING_SERVICE_COUNTER_TABLEm,
   8712                                         ing_service_counter_table_entry_t *,
   8713                                             prev_ptr_y, k);
   8714                 }
   8715 #endif /* BCM_TRIDENT_SUPPORT */
   8716 
   8717                 /* first packets */
   8718 #ifdef BCM_TRIDENT_SUPPORT
   8719                 if (SOC_IS_TD_TT(unit)) {
   8720                     soc_memacc_field64_get(memacc_pkt_x,
   8721                                            (uint32 *)curr_eptr, &curr);
   8722                     soc_memacc_field64_get(memacc_pkt_x,
   8723                                            (uint32 *)prev_eptr, &prev);
   8724                     /* Take care of rollovers */
   8725                     if (COMPILER_64_LT(curr, prev)) {
   8726                        COMPILER_64_SET(size, 0, 1);
   8727                        COMPILER_64_SHL(size, field_length_packet_x);
   8728                        COMPILER_64_ADD_64(curr, size); 
   8729                     }
   8730                     diff = curr;
   8731                     COMPILER_64_SUB_64(diff, prev);
   8732 
   8733                     soc_memacc_field64_get(memacc_pkt_y,
   8734                                            (uint32 *)curr_eptr_y, &curr);
   8735                     soc_memacc_field64_get(memacc_pkt_y,
   8736                                            (uint32 *)prev_eptr_y, &prev);
   8737                     /* Take care of rollovers */
   8738                     if (COMPILER_64_LT(curr, prev)) {
   8739                        COMPILER_64_SET(size, 0, 1);
   8740                        COMPILER_64_SHL(size, field_length_packet_y);
   8741                        COMPILER_64_ADD_64(curr, size); 
   8742                     }
   8743                     diff_y = curr;         
   8744                     COMPILER_64_SUB_64(diff_y, prev);
   8745                     COMPILER_64_ADD_64(diff, diff_y);
   8746                 } else
   8747 #endif /* BCM_TRIDENT_SUPPORT */
   8748                 {
   8749                     soc_memacc_field64_get(memacc_pkt,
   8750                                            (uint32 *)curr_eptr, &curr);
   8751                     soc_memacc_field64_get(memacc_pkt,
   8752                                            (uint32 *)prev_eptr, &prev);
   8753                     /* Take care of rollovers */
   8754                     if (COMPILER_64_LT(curr, prev)) {
   8755                        COMPILER_64_SET(size, 0, 1);
   8756                        COMPILER_64_SHL(size, field_length_packet);
   8757                        COMPILER_64_ADD_64(curr, size); 
   8758                     }
   8759                     diff = curr;                    
   8760                     COMPILER_64_SUB_64(diff, prev);
   8761                 }
   8762                 if (!COMPILER_64_IS_ZERO(diff)) {
   8763                     /* Update soft copy */
   8764                     COMPILER_64_ADD_64(prev_pktptr[k], diff);
   8765                 }
   8766 
   8767                 /* then bytes */
   8768 #ifdef BCM_TRIDENT_SUPPORT
   8769                 if (SOC_IS_TD_TT(unit)) {
   8770                     soc_memacc_field64_get(memacc_byte_x,
   8771                                            (uint32 *)curr_eptr,
   8772                                            &curr);
   8773                     soc_memacc_field64_get(memacc_byte_x,
   8774                                            (uint32 *)prev_eptr,
   8775                                            &prev);
   8776                     /* Take care of rollovers */
   8777                     if (COMPILER_64_LT(curr, prev)) {
   8778                        COMPILER_64_SET(size, 0, 1);
   8779                        COMPILER_64_SHL(size, field_length_byte_x);
   8780                        COMPILER_64_ADD_64(curr, size); 
   8781                     }
   8782                     diff = curr;
   8783                     COMPILER_64_SUB_64(diff, prev);
   8784 
   8785                     soc_memacc_field64_get(memacc_byte_y,
   8786                                            (uint32 *)curr_eptr_y,
   8787                                            &curr);
   8788                     soc_memacc_field64_get(memacc_byte_y,
   8789                                            (uint32 *)prev_eptr_y,
   8790                                            &prev);
   8791                     /* Take care of rollovers */
   8792                     if (COMPILER_64_LT(curr, prev)) {
   8793                        COMPILER_64_SET(size, 0, 1);
   8794                        COMPILER_64_SHL(size, field_length_byte_y);
   8795                        COMPILER_64_ADD_64(curr, size); 
   8796                     }
   8797                     diff_y = curr;
   8798                     COMPILER_64_SUB_64(diff_y, prev);
   8799                     COMPILER_64_ADD_64(diff, diff_y);
   8800                 } else
   8801 #endif /* BCM_TRIDENT_SUPPORT */
   8802                 {
   8803                     soc_memacc_field64_get(memacc_byte,
   8804                                            (uint32 *)curr_eptr,
   8805                                            &curr);
   8806                     soc_memacc_field64_get(memacc_byte,
   8807                                            (uint32 *)prev_eptr,
   8808                                            &prev);
   8809                     /* Take care of rollovers */
   8810                     if (COMPILER_64_LT(curr, prev)) {
   8811                        COMPILER_64_SET(size, 0, 1);
   8812                        COMPILER_64_SHL(size, field_length_byte);
   8813                        COMPILER_64_ADD_64(curr, size); 
   8814                     }
   8815                     diff = curr;                    
   8816                     COMPILER_64_SUB_64(diff, prev);
   8817                 }
   8818                 if (!COMPILER_64_IS_ZERO(diff)) {
   8819                     /* Update soft copy */
   8820                     COMPILER_64_ADD_64(prev_bytptr[k], diff);
   8821                 }
   8822             }
   8823             FS_UNLOCK(unit);
   8824         }
   8825     }
   8826 
   8827     /* Flip toggle with lock */
   8828     FS_LOCK(unit);
   8829     _bcm_flex_stat_buff_toggle[unit] = !_bcm_flex_stat_buff_toggle[unit];
   8830     FS_UNLOCK(unit);
   8831 }
   8832 
   8833 /* Callback to be invoked from counter thread */
   8834 void
   8835 _bcm_esw_flex_stat_callback(int unit)
   8836 {
   8837 
   8838     /* Flip toggle with lock */
   8839     FS_LOCK(unit);
   8840     _bcm_esw_flex_stat_collection(unit, 0, -1, 0);
   8841     FS_UNLOCK(unit);
   8842 }
   8843 
   8844 /*
   8845  * Function:
   8846  *      _bcm_esw_flex_stat_detach
   8847  * Purpose:
   8848  *      De-allocate memory used by flexible counters.
   8849  * Parameters:
   8850  *      unit - SOC unit number
   8851  *      fs_type - flexible stat type
   8852  * Returns:
   8853  *      BCM_X_XXX
   8854  */
   8855 int
   8856 _bcm_esw_flex_stat_detach(int unit, _bcm_flex_stat_type_t fs_type)
   8857 {
   8858     _bcm_flex_stat_info_t  *stat_info;
   8859     _bcm_flex_stat_type_t type_idx,
   8860         hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   8861     int mutex = TRUE;
   8862 
   8863     if (fs_type >= _bcmFlexStatTypeAllHwNum) {
   8864         /* We shouldn't be deallocating this */
   8865         return BCM_E_INTERNAL;
   8866     }
   8867 
   8868     if (NULL != _flex_stat_mutex[unit]) {
   8869         FS_LOCK(unit);
   8870     }
   8871 
   8872     stat_info = FS_INFO(unit, hw_type);
   8873 
   8874     if (stat_info != NULL) {
   8875         if (stat_info->stats != NULL) {
   8876             sal_free(stat_info->stats);
   8877         }
   8878         if (stat_info->handle_list != NULL) {
   8879             sal_free(stat_info->handle_list);
   8880         }
   8881         if (stat_info->ref_cnt != NULL) {
   8882             sal_free(stat_info->ref_cnt);
   8883         }
   8884         sal_free(stat_info);
   8885         FS_INFO(unit, hw_type) = NULL;
   8886     }
   8887 
   8888     if (NULL != _flex_stat_mutex[unit]) {
   8889         FS_UNLOCK(unit);
   8890         /* Check if all counter types are detached */
   8891         for (type_idx = _bcmFlexStatTypeService;
   8892              type_idx < _bcmFlexStatTypeAllHwNum; type_idx ++) {
   8893             if (FS_INFO(unit, type_idx) != NULL) {
   8894                 mutex = FALSE;
   8895                 break;
   8896             }
   8897         }
   8898         /* If so, unregister, free the memory and destroy the mutex also */
   8899         if (mutex) {
   8900             soc_counter_extra_unregister(unit, _bcm_esw_flex_stat_callback);
   8901             _bcm_esw_flex_stat_mem_free(unit);
   8902             if (NULL != _bcm_flex_stat_memacc[unit]) {
   8903                 sal_free(_bcm_flex_stat_memacc[unit]);
   8904                 _bcm_flex_stat_memacc[unit] = NULL;
   8905             }
   8906             sal_mutex_destroy(_flex_stat_mutex[unit]);
   8907             _flex_stat_mutex[unit] = NULL;
   8908         }
   8909     }
   8910     return BCM_E_NONE;
   8911 }
   8912 
   8913 /*
   8914  * Function:
   8915  *      _bcm_esw_flex_stat_init
   8916  * Purpose:
   8917  *      Allocate memory used by flexible counters.
   8918  * Parameters:
   8919  *      unit - SOC unit number
   8920  *      fs_type - flexible stat type
   8921  * Returns:
   8922  *      BCM_X_XXX
   8923  */
   8924 int
   8925 _bcm_esw_flex_stat_init(int unit, _bcm_flex_stat_type_t fs_type)
   8926 {
   8927     _bcm_flex_stat_info_t  *stat_info = NULL;
   8928     int alloc_size, rv = BCM_E_NONE;
   8929     soc_mem_t mem;
   8930     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   8931 
   8932     if (fs_type >= _bcmFlexStatTypeAllHwNum) {
   8933         /* We shouldn't be allocating this */
   8934         return BCM_E_INTERNAL;
   8935     }
   8936 
   8937     BCM_IF_ERROR_RETURN(_bcm_esw_flex_stat_detach(unit, fs_type));
   8938 
   8939     /* Without the lock and memory, we can't do anything */
   8940     if (_flex_stat_mutex[unit] == NULL) {
   8941         _flex_stat_mutex[unit] = sal_mutex_create("common mutex");
   8942         if (_flex_stat_mutex[unit] == NULL) {
   8943             return BCM_E_MEMORY;
   8944         }
   8945         /* Allocate cache and buffer memory */
   8946         rv = _bcm_esw_flex_stat_mem_init(unit);
   8947         if (BCM_SUCCESS(rv)) {
   8948             /* Predetermined memory access accelerators */
   8949             rv = _bcm_esw_flex_stat_memacc_init(unit);
   8950         }
   8951         if (BCM_SUCCESS(rv)) {
   8952             /* Register for counter callback */
   8953             rv = soc_counter_extra_register(unit, _bcm_esw_flex_stat_callback);
   8954         }
   8955     }
   8956 
   8957     FS_LOCK(unit);
   8958 
   8959     if (BCM_SUCCESS(rv)) {
   8960         alloc_size = sizeof(_bcm_flex_stat_info_t);
   8961         stat_info = sal_alloc(alloc_size, "Flexible counters info");
   8962         if (NULL == stat_info) {
   8963             rv = BCM_E_MEMORY;
   8964         } else {
   8965             sal_memset(stat_info, 0, alloc_size);
   8966             mem = FS_ING_MEM(fs_type);
   8967             stat_info->stat_mem_size = soc_mem_index_count(unit, mem);
   8968         }
   8969     }
   8970 
   8971     if (BCM_SUCCESS(rv)) {
   8972         alloc_size = SHR_BITALLOCSIZE(stat_info->stat_mem_size);
   8973         stat_info->stats =
   8974             sal_alloc(alloc_size, "Flexible counters usage bitmap");
   8975         if (NULL == stat_info->stats) {
   8976             rv = BCM_E_MEMORY;
   8977         } else {
   8978             sal_memset(stat_info->stats, 0, alloc_size);
   8979             SHR_BITSET(stat_info->stats, 0); /* Index 0 is invalid */
   8980         }
   8981     }
   8982 
   8983     if (BCM_SUCCESS(rv)) {
   8984         alloc_size = (FS_HANDLE_LIST_ELEMENT_SIZE *
   8985                       stat_info->stat_mem_size);
   8986         stat_info->handle_list =
   8987             sal_alloc(alloc_size, "Flexible counters handle list");
   8988         if (NULL == stat_info->handle_list) {
   8989             rv = BCM_E_MEMORY;
   8990         } else {
   8991             sal_memset(stat_info->handle_list, 0, alloc_size);
   8992             stat_info->handle_list_size = 0;
   8993         }
   8994     }
   8995 
   8996     if (BCM_SUCCESS(rv)) {
   8997         alloc_size = (sizeof(uint16) *
   8998                       stat_info->stat_mem_size);
   8999         stat_info->ref_cnt =
   9000             sal_alloc(alloc_size, "Flexible counters reference table");
   9001         if (NULL == stat_info->ref_cnt) {
   9002             rv = BCM_E_MEMORY;
   9003         } else {
   9004             sal_memset(stat_info->ref_cnt, 0, alloc_size);
   9005         }
   9006     }
   9007 
   9008     FS_INFO(unit, hw_type) = stat_info;
   9009 
   9010     if (!SOC_WARM_BOOT(unit)) {
   9011         if (_tr2_flex_stat_api_ver[unit]) {
   9012             _tr2_flex_stat_api_ver[unit] = 0;
   9013         }
   9014     }
   9015     FS_UNLOCK(unit);
   9016     if (BCM_FAILURE(rv)) {
   9017         /* Clean up */
   9018         (void)_bcm_esw_flex_stat_detach(unit, fs_type);
   9019         /* We already have an error in rv */
   9020     }
   9021     return rv;
   9022 }
   9023 
   9024 /*
   9025  * Function:
   9026  *      _bcm_flex_stat_handle_to_index_t_compare
   9027  * Purpose:
   9028  *      Compare two _bcm_flex_stat_handle_to_index_t elements for 
   9029  *      binary table sort.
   9030  * Parameters:
   9031  *      a - (IN) pointer to first _bcm_flex_stat_handle_to_index_t
   9032  *      b - (IN) pointer to second _bcm_flex_stat_handle_to_index_t
   9033  * Returns:
   9034  *      a<=>b
   9035  */
   9036 STATIC int
   9037 _bcm_flex_stat_handle_to_index_t_compare(void *a, void *b)
   9038 {
   9039     _bcm_flex_stat_handle_to_index_t *first, *second;
   9040     int word;
   9041 
   9042     first = (_bcm_flex_stat_handle_to_index_t *)a;
   9043     second = (_bcm_flex_stat_handle_to_index_t *)b;
   9044 
   9045     if (first->type < second->type) {
   9046         return (-1);
   9047     } else if (first->type > second->type) {
   9048         return (1);
   9049     }
   9050 
   9051     /* Types equal, check handle */
   9052     for (word = (_BCM_FLEX_STAT_HANDLE_WORDS - 1); word >= 0; word--) {
   9053         if (_BCM_FLEX_STAT_HANDLE_WORD_GET(first->handle, word) <
   9054             _BCM_FLEX_STAT_HANDLE_WORD_GET(second->handle, word)) {
   9055             return (-1);
   9056         } else if (_BCM_FLEX_STAT_HANDLE_WORD_GET(first->handle, word) >
   9057                    _BCM_FLEX_STAT_HANDLE_WORD_GET(second->handle, word)) {
   9058             return (1);
   9059         }
   9060     }
   9061 
   9062     return (0);
   9063 }
   9064 
   9065 /*
   9066  * Function:
   9067  *      _bcm_esw_flex_stat_index
   9068  * Purpose:
   9069  *      Retrieve the flexible stat index for the given handle and stat type.
   9070  * Parameters:
   9071  *      unit - SOC unit number
   9072  *      fs_type - flexible stat type
   9073  *      handle - the encoded handle for the type of packets to count.
   9074  * Returns:
   9075  *      Flexible stat index
   9076  */
   9077 STATIC int
   9078 _bcm_esw_flex_stat_index(int unit, _bcm_flex_stat_type_t fs_type,
   9079                          _bcm_flex_stat_handle_t handle)
   9080 {
   9081     int list_index;
   9082     _bcm_flex_stat_handle_to_index_t target;
   9083     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9084 
   9085     _BCM_FLEX_STAT_HANDLE_ASSIGN(target.handle, handle);
   9086     target.type = fs_type;
   9087     list_index = _shr_bsearch(FS_HANDLE_LIST(unit, hw_type),
   9088                               FS_HANDLE_LIST_SIZE(unit, hw_type),
   9089                               FS_HANDLE_LIST_ELEMENT_SIZE, &target,
   9090                               &_bcm_flex_stat_handle_to_index_t_compare);
   9091 
   9092     if ((list_index >= 0) &&
   9093         (list_index < FS_HANDLE_LIST_SIZE(unit, hw_type))) {
   9094         return FS_HANDLE_LIST_ELEMENT_INDEX(unit, hw_type, list_index);
   9095     }
   9096     return 0;
   9097 }
   9098 
   9099 /*
   9100  * Function:
   9101  *      _bcm_esw_flex_stat_handle_list_insert
   9102  * Purpose:
   9103  *      Add the flexible stat index for the given handle and stat type
   9104  *      to the handle list.
   9105  * Parameters:
   9106  *      unit - SOC unit number
   9107  *      fs_type - flexible stat type
   9108  *      handle - the encoded handle for the type of packets to count.
   9109  *      index - flexible stat index
   9110  * Returns:
   9111  *      Flexible stat index, or 0 on resource failure
   9112  */
   9113 STATIC int
   9114 _bcm_esw_flex_stat_handle_list_insert(int unit, _bcm_flex_stat_type_t fs_type,
   9115                                 _bcm_flex_stat_handle_t handle, uint32 index)
   9116 {
   9117     int list_index, idx, tmp;
   9118     _bcm_flex_stat_handle_to_index_t target;
   9119     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9120 
   9121     if (FS_HANDLE_LIST_SIZE(unit, hw_type) >= FS_MEM_SIZE(unit, hw_type)) {
   9122         
   9123         return 0;
   9124     }
   9125 
   9126     _BCM_FLEX_STAT_HANDLE_ASSIGN(target.handle, handle);
   9127     target.type = fs_type;
   9128     list_index = _shr_bsearch(FS_HANDLE_LIST(unit, hw_type),
   9129                               FS_HANDLE_LIST_SIZE(unit, hw_type),
   9130                               FS_HANDLE_LIST_ELEMENT_SIZE, &target,
   9131                               &_bcm_flex_stat_handle_to_index_t_compare);
   9132 
   9133 
   9134     if (list_index >= 0) {
   9135         
   9136         return 0;
   9137     }
   9138 
   9139     idx = (((-1) * list_index) - 1);
   9140     tmp = FS_HANDLE_LIST_SIZE(unit, hw_type) - 1;
   9141     while (tmp >= idx) {
   9142         sal_memcpy(FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp + 1),
   9143                    FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp),
   9144                    FS_HANDLE_LIST_ELEMENT_SIZE);
   9145         tmp--;
   9146     }
   9147     _BCM_FLEX_STAT_HANDLE_ASSIGN
   9148         (FS_HANDLE_LIST_ELEMENT_HANDLE(unit, hw_type, idx), handle);
   9149     FS_HANDLE_LIST_ELEMENT_TYPE(unit, hw_type, idx) = fs_type;
   9150     FS_HANDLE_LIST_ELEMENT_INDEX(unit, hw_type, idx) = index;
   9151     FS_HANDLE_LIST_SIZE(unit, hw_type)++;
   9152     return index;
   9153 }
   9154 
   9155 STATIC int
   9156 _bcm_esw_flex_stat_index_set(int unit, _bcm_flex_stat_type_t fs_type,
   9157                                uint32 index)
   9158 {
   9159     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9160 
   9161     SHR_BITSET(FS_USED_BITMAP(unit, hw_type), index);
   9162     return index;
   9163 }
   9164 
   9165 STATIC uint32
   9166 _bcm_esw_flex_stat_index_get(int unit, _bcm_flex_stat_type_t fs_type,
   9167                                uint32 index)
   9168 {
   9169     uint32 ret;
   9170 
   9171     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9172 
   9173     ret = SHR_BITGET(FS_USED_BITMAP(unit, hw_type), index);
   9174     return ret;
   9175 }
   9176 
   9177 STATIC int
   9178 _bcm_esw_flex_stat_ref_cnt_dec(int unit, _bcm_flex_stat_type_t fs_type,
   9179                                uint32 fs_inx)
   9180 {
   9181     int ret = BCM_E_NONE;
   9182     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9183 
   9184     if (FS_REF_CNT_ELEMENT(unit,hw_type,fs_inx)) {
   9185         FS_REF_CNT_ELEMENT(unit,hw_type,fs_inx) -= 1;
   9186     } else {
   9187         ret = BCM_E_PARAM;
   9188     }
   9189 
   9190     return ret;
   9191 }
   9192 
   9193 STATIC uint16
   9194 _bcm_esw_flex_stat_ref_cnt_get(int unit, _bcm_flex_stat_type_t fs_type,
   9195                                uint32 fs_inx)
   9196 {
   9197     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9198 
   9199     return FS_REF_CNT_ELEMENT(unit,hw_type,fs_inx);
   9200 }
   9201 
   9202 STATIC int
   9203 _bcm_esw_flex_stat_ref_cnt_inc(int unit, _bcm_flex_stat_type_t fs_type,
   9204                                uint32 fs_inx)
   9205 {
   9206     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9207     int rv = BCM_E_NONE;
   9208 
   9209     if (!FS_REF_CNT_ELEMENT(unit,hw_type,fs_inx)) {
   9210         /* if first time, clear both hardware/software count */
   9211         rv = _bcm_esw_flex_stat_sw_clear(unit, fs_type, fs_inx);
   9212     }
   9213     FS_REF_CNT_ELEMENT(unit,hw_type,fs_inx) += 1;
   9214     return rv;
   9215 }
   9216 
   9217 /*
   9218  * Function:
   9219  *      _bcm_esw_flex_stat_index_insert
   9220  * Purpose:
   9221  *      Add the flexible stat index for the given handle and stat type
   9222  *      to the handle list.
   9223  * Parameters:
   9224  *      unit - SOC unit number
   9225  *      fs_type - flexible stat type
   9226  *      handle - the encoded handle for the type of packets to count.
   9227  *      index - flexible stat index
   9228  * Returns:
   9229  *      Flexible stat index, or 0 on resource failure
   9230  */
   9231 STATIC int
   9232 _bcm_esw_flex_stat_index_insert(int unit, _bcm_flex_stat_type_t fs_type,
   9233                                 _bcm_flex_stat_handle_t handle, uint32 index)
   9234 {
   9235     int rv;
   9236 
   9237     rv = _bcm_esw_flex_stat_handle_list_insert(unit,fs_type,handle,index);
   9238     if (!rv) {
   9239         return 0;
   9240     }
   9241     return _bcm_esw_flex_stat_index_set(unit,fs_type,index);
   9242 }
   9243 
   9244 /*
   9245  * Function:
   9246  *      _bcm_esw_flex_stat_handle_list_delete
   9247  * Purpose:
   9248  *      Remove the flexible stat index for the given handle and stat type
   9249  *      from the handle list.
   9250  * Parameters:
   9251  *      unit - SOC unit number
   9252  *      fs_type - flexible stat type
   9253  *      handle - the encoded handle for the type of packets to count.
   9254  *      index - flexible stat index
   9255  * Returns:
   9256  *      Flexible stat index, or 0 on resource failure
   9257  */
   9258 STATIC void
   9259 _bcm_esw_flex_stat_handle_list_delete(int unit, _bcm_flex_stat_type_t fs_type,
   9260                                 _bcm_flex_stat_handle_t handle)
   9261 {
   9262     int list_index, max, tmp;
   9263     _bcm_flex_stat_handle_to_index_t target;
   9264     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9265 
   9266     _BCM_FLEX_STAT_HANDLE_ASSIGN(target.handle, handle);
   9267     target.type = fs_type;
   9268     list_index = _shr_bsearch(FS_HANDLE_LIST(unit, hw_type),
   9269                               FS_HANDLE_LIST_SIZE(unit, hw_type),
   9270                               FS_HANDLE_LIST_ELEMENT_SIZE, &target,
   9271                               &_bcm_flex_stat_handle_to_index_t_compare);
   9272 
   9273     if (list_index < 0) {
   9274         
   9275         return;
   9276     }
   9277 
   9278     tmp = list_index;
   9279     max = FS_HANDLE_LIST_SIZE(unit, hw_type) - 1;
   9280     while (tmp < max) {
   9281         sal_memcpy(FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp),
   9282                    FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp + 1),
   9283                    FS_HANDLE_LIST_ELEMENT_SIZE);
   9284         tmp++;
   9285     }
   9286     FS_HANDLE_LIST_SIZE(unit, hw_type)--;
   9287     sal_memset(FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type,
   9288                                       FS_HANDLE_LIST_SIZE(unit, hw_type)),
   9289                0, FS_HANDLE_LIST_ELEMENT_SIZE);
   9290     return;
   9291 }
   9292 
   9293 STATIC void
   9294 _bcm_esw_flex_stat_index_clear(int unit, _bcm_flex_stat_type_t fs_type,
   9295                                 uint32 index)
   9296 {
   9297     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9298     SHR_BITCLR(FS_USED_BITMAP(unit, hw_type), index);
   9299 }
   9300 
   9301 /*
   9302  * Function:
   9303  *      _bcm_esw_flex_stat_index_delete
   9304  * Purpose:
   9305  *      Remove the flexible stat index for the given handle and stat type
   9306  *      from the handle list.
   9307  * Parameters:
   9308  *      unit - SOC unit number
   9309  *      fs_type - flexible stat type
   9310  *      handle - the encoded handle for the type of packets to count.
   9311  *      index - flexible stat index
   9312  * Returns:
   9313  *      Flexible stat index, or 0 on resource failure
   9314  */
   9315 STATIC void
   9316 _bcm_esw_flex_stat_index_delete(int unit, _bcm_flex_stat_type_t fs_type,
   9317                                 _bcm_flex_stat_handle_t handle, uint32 index)
   9318 {
   9319      _bcm_esw_flex_stat_handle_list_delete(unit,fs_type,handle);
   9320      _bcm_esw_flex_stat_index_clear(unit,fs_type,index);
   9321 }
   9322 
   9323 /*
   9324  * Function:
   9325  *      _bcm_esw_flex_stat_next_free_index
   9326  * Purpose:
   9327  *      Retrieve the next available flexible stat index for a stat type.
   9328  * Parameters:
   9329  *      unit - SOC unit number
   9330  *      fs_type - flexible stat type
   9331  * Returns:
   9332  *      Flexible stat index
   9333  */
   9334 STATIC int
   9335 _bcm_esw_flex_stat_next_free_index(int unit, _bcm_flex_stat_type_t fs_type)
   9336 {
   9337     int                 ix, mem_size;
   9338     uint32              bit;
   9339     SHR_BITDCL          not_ptrs, *stat_bmp;
   9340     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9341 
   9342     mem_size = FS_MEM_SIZE(unit, hw_type);
   9343     stat_bmp = FS_USED_BITMAP(unit, hw_type);
   9344     for (ix = 0; ix < _SHR_BITDCLSIZE(mem_size); ix++) {
   9345         not_ptrs = ~stat_bmp[ix];
   9346         if (not_ptrs) {
   9347             for (bit = 0; bit < SHR_BITWID; bit++) {
   9348                 if (not_ptrs & (1 << bit)) {
   9349                     return (ix * SHR_BITWID) + bit;
   9350                 }
   9351             }
   9352         }
   9353     }
   9354 
   9355     return 0;
   9356 }
   9357 
   9358 STATIC int
   9359 _bcm_esw_flex_stat_hw_index_set(int unit, _bcm_flex_stat_type_t fs_type,
   9360             int fs_inx, uint64 val)
   9361 {
   9362     int rv;
   9363     _bcm_flex_stat_type_t htype;
   9364 
   9365     htype = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9366 
   9367     if ((htype == _bcmFlexStatTypeService) ||
   9368         (htype == _bcmFlexStatTypeGport)) {
   9369         rv = _bcm_esw_flex_stat_hw_set(unit, fs_type, fs_inx,
   9370                       _bcmFlexStatIngressPackets, val);
   9371         if (BCM_SUCCESS(rv)) {
   9372             rv = _bcm_esw_flex_stat_hw_set(unit, fs_type, fs_inx,
   9373                       _bcmFlexStatIngressBytes, val);
   9374         }
   9375     } else  {
   9376         rv = _bcm_esw_flex_stat_hw_set(unit, fs_type, fs_inx,
   9377                       _bcmFlexStatEgressPackets, val);
   9378         if (BCM_SUCCESS(rv)) {
   9379             rv = _bcm_esw_flex_stat_hw_set(unit, fs_type, fs_inx,
   9380                       _bcmFlexStatEgressBytes, val);
   9381         }
   9382     }
   9383     return rv;
   9384 }
   9385 
   9386 /*
   9387  * Function:
   9388  *      _bcm_esw_flex_stat_free_index_assign
   9389  * Purpose:
   9390  *      get the next available flexible stat index for a stat type.
   9391  * Parameters:
   9392  *      unit - SOC unit number
   9393  *      fs_type - flexible stat type
   9394  * Returns:
   9395  *      Flexible stat index
   9396  */
   9397 int
   9398 _bcm_esw_flex_stat_free_index_assign(int unit, _bcm_flex_stat_type_t fs_type)
   9399 {
   9400     int fs_inx;
   9401     int rv;
   9402     uint64 val64;
   9403 
   9404     COMPILER_64_SET(val64,0,1);
   9405     FS_LOCK(unit);
   9406     fs_inx = _bcm_esw_flex_stat_next_free_index(unit,fs_type);
   9407     fs_inx = _bcm_esw_flex_stat_index_set(unit,fs_type,fs_inx);
   9408     FS_UNLOCK(unit);
   9409 
   9410     /* set a initial value 1 to the hardware counter to indicate
   9411      * the counter has been reserved, but not used yet, for warmboot
   9412      * purpose.
   9413      */
   9414     rv = _bcm_esw_flex_stat_hw_index_set(unit, fs_type, fs_inx, val64);
   9415 
   9416     if (BCM_SUCCESS(rv)) {
   9417         return fs_inx;  
   9418     } else {
   9419         return 0;
   9420     }
   9421 }
   9422 
   9423 /*
   9424  * Function:
   9425  *      _bcm_esw_flex_stat_free_index_assign
   9426  * Purpose:
   9427  *      get the next available flexible stat index for a stat type.
   9428  * Parameters:
   9429  *      unit - SOC unit number
   9430  *      fs_type - flexible stat type
   9431  * Returns:
   9432  *      Flexible stat index
   9433  */
   9434 int
   9435 _bcm_esw_flex_stat_count_index_remove(int unit, _bcm_flex_stat_type_t fs_type,
   9436                  int fs_inx)
   9437 {
   9438     int rv;
   9439     uint16 ref_cnt;
   9440     uint64 val64;
   9441 
   9442     COMPILER_64_SET(val64,0,0);
   9443     rv = BCM_E_NONE;
   9444     FS_LOCK(unit);
   9445     ref_cnt = _bcm_esw_flex_stat_ref_cnt_get(unit,fs_type,fs_inx);
   9446     if (!ref_cnt) {
   9447         _bcm_esw_flex_stat_index_clear(unit,fs_type,fs_inx);
   9448     }  else {
   9449          rv = BCM_E_PARAM;
   9450     }
   9451     FS_UNLOCK(unit);
   9452 
   9453     /* clear the hardware counter */
   9454     if (rv == BCM_E_NONE) {
   9455         rv = _bcm_esw_flex_stat_hw_index_set(unit, fs_type, fs_inx, val64);
   9456     }
   9457     return rv;
   9458 
   9459 }
   9460 
   9461 /*
   9462  * Function:
   9463  *      _bcm_esw_flex_stat_alloc
   9464  * Purpose:
   9465  *      Attempt to allocate a flexible stat index for a stat type.
   9466  * Parameters:
   9467  *      unit - SOC unit number
   9468  *      type - flexible stat type
   9469  *      handle - the encoded handle for the type of packets to count.
   9470  * Returns:
   9471  *      Success: Flexible stat index
   9472  *      Failure: 0 (invalid stat index)
   9473  */
   9474 STATIC int
   9475 _bcm_esw_flex_stat_alloc(int unit, _bcm_flex_stat_type_t type,
   9476                          _bcm_flex_stat_handle_t handle)
   9477 {
   9478     int index;
   9479 
   9480     /* Already checked for existence */
   9481     index = _bcm_esw_flex_stat_next_free_index(unit, type);
   9482     if (index) {
   9483         /* Returns 0 on error */
   9484         index = _bcm_esw_flex_stat_index_insert(unit, type, handle, index);
   9485     }
   9486 
   9487     return index;
   9488 }
   9489 
   9490 /*
   9491  * Function:
   9492  *      _bcm_esw_flex_stat_release_handles
   9493  * Purpose:
   9494  *      Deallocate all handles of the given stat type.
   9495  * Parameters:
   9496  *      unit - SOC unit number
   9497  *      fs_type - flexible stat type
   9498  * Returns:
   9499  *      Flexible stat index
   9500  */
   9501 void
   9502 _bcm_esw_flex_stat_release_handles(int unit, _bcm_flex_stat_type_t fs_type)
   9503 {
   9504     int list_index, idx, tmp, max;
   9505     _bcm_flex_stat_handle_to_index_t target;
   9506     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type);
   9507 
   9508     /* Find start of this type */
   9509     _BCM_FLEX_STAT_HANDLE_CLEAR(target.handle); 
   9510     target.type = fs_type;
   9511     
   9512     FS_LOCK(unit);
   9513 
   9514     max = FS_HANDLE_LIST_SIZE(unit, hw_type);
   9515     if (max == 0) {
   9516         FS_UNLOCK(unit);
   9517         return;
   9518     }
   9519     list_index = _shr_bsearch(FS_HANDLE_LIST(unit, hw_type), max,
   9520                               FS_HANDLE_LIST_ELEMENT_SIZE, &target,
   9521                               &_bcm_flex_stat_handle_to_index_t_compare);
   9522 
   9523     /* Starting point */
   9524     if (list_index < 0) {
   9525         idx = (((-1) * list_index) - 1);
   9526     } else {
   9527         idx = list_index;
   9528     }
   9529 
   9530     tmp = idx;
   9531     while (tmp < max) {
   9532         if (FS_HANDLE_LIST_ELEMENT_TYPE(unit, hw_type, tmp) != fs_type) {
   9533             if (tmp != idx) {
   9534                 /* Copy up entry */
   9535                 sal_memcpy(FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, idx),
   9536                            FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp),
   9537                            FS_HANDLE_LIST_ELEMENT_SIZE);
   9538                 idx++;
   9539             }
   9540         }
   9541         if (tmp != idx) {
   9542             /* Blank out current position */
   9543             sal_memset(FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp),
   9544                        0, FS_HANDLE_LIST_ELEMENT_SIZE);
   9545         }
   9546         tmp++;
   9547     }
   9548     if (idx < tmp) {
   9549         FS_HANDLE_LIST_SIZE(unit, hw_type) = idx + 1;
   9550     }
   9551     FS_UNLOCK(unit);
   9552 }
   9553 
   9554 /*
   9555  * Function:
   9556  *      _bcm_esw_flex_stat_reinit_add
   9557  * Purpose:
   9558  *      Record the flexible stat information during reinitialization.
   9559  * Parameters:
   9560  *      unit - SOC unit number
   9561  *      type - flexible stat type
   9562  *      fs_index - the flexible stat index
   9563  *      handle - the encoded handle for the type of packets to count.
   9564  * Returns:
   9565  *      BCM_X_XXX
   9566  */
   9567 void
   9568 _bcm_esw_flex_stat_ext_reinit_add(int unit, _bcm_flex_stat_type_t type,
   9569                                   int fs_index,
   9570                                   _bcm_flex_stat_handle_t handle)
   9571 {
   9572     FS_LOCK(unit);
   9573     (void)_bcm_esw_flex_stat_index_insert(unit, type, handle, fs_index);
   9574     FS_UNLOCK(unit);
   9575     /* Ignoring insert return code */
   9576 }
   9577 
   9578 /*
   9579  * Function:
   9580  *      _bcm_esw_vlan_flex_stat_hw_index_set
   9581  * Purpose:
   9582  *      Update the flexible stat pointers of HW tables for VLAN/VFI types.
   9583  * Parameters:
   9584  *      unit - SOC unit number
   9585  *      handle - the encoded handle for the type of packets to count.
   9586  *      fs_idx - the flexible stat index
   9587  *      cookie - info to be used from original calling routine
   9588  * Returns:
   9589  *      BCM_X_XXX
   9590  */
   9591 int
   9592 _bcm_esw_vlan_flex_stat_hw_index_set(int unit, _bcm_flex_stat_handle_t fsh,
   9593                                      int fs_idx, void *cookie)
   9594 {
   9595     bcm_vlan_t handle = _BCM_FLEX_STAT_HANDLE_WORD_GET(fsh, 0);
   9596     uint32 flags;
   9597 #if defined(INCLUDE_L3)
   9598     int vfi;
   9599 #endif /* INCLUDE_L3 */
   9600 
   9601     flags = cookie==NULL? _BCM_FLEX_STAT_HW_BOTH:
   9602             PTR_TO_INT(cookie);
   9603 #if defined(INCLUDE_L3)
   9604 
   9605     /* Is it a VPN? */
   9606     if (_BCM_MPLS_VPN_IS_SET(handle)) {
   9607         _BCM_MPLS_VPN_GET(vfi, _BCM_MPLS_VPN_TYPE_VPLS, handle);
   9608         return _bcm_vfi_flex_stat_index_set(unit, vfi,
   9609                                             _bcmVfiTypeMpls, fs_idx,flags);
   9610     } else if (_BCM_MIM_VPN_IS_SET(handle)) {
   9611         _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, handle);
   9612         return _bcm_vfi_flex_stat_index_set(unit, vfi,
   9613                                             _bcmVfiTypeMim, fs_idx,flags);
   9614     } else 
   9615 #endif /* INCLUDE_L3 */
   9616     {
   9617         return _bcm_esw_vlan_flex_stat_index_set(unit, handle, fs_idx,flags);
   9618     }    
   9619 }
   9620 
   9621 /*
   9622  * Function:
   9623  *      _bcm_esw_port_flex_stat_hw_index_set
   9624  * Purpose:
   9625  *      Update the flexible stat pointers of HW tables for GPORT types.
   9626  * Parameters:
   9627  *      unit - SOC unit number
   9628  *      handle - the encoded handle for the type of packets to count.
   9629  *      fs_idx - the flexible stat index
   9630  *      cookie - info to be used from original calling routine
   9631  * Returns:
   9632  *      BCM_X_XXX
   9633  */
   9634 int
   9635 _bcm_esw_port_flex_stat_hw_index_set(int unit, _bcm_flex_stat_handle_t fsh,
   9636                                      int fs_idx, void *cookie)
   9637 {
   9638     uint32 flags;
   9639     uint32 handle = _BCM_FLEX_STAT_HANDLE_WORD_GET(fsh, 0);
   9640 
   9641     COMPILER_REFERENCE(cookie);
   9642 
   9643     flags = cookie==NULL? _BCM_FLEX_STAT_HW_BOTH:
   9644             PTR_TO_INT(cookie);
   9645 
   9646 #if defined(INCLUDE_L3)
   9647     if (BCM_GPORT_IS_MPLS_PORT(handle)) {
   9648 #if defined(BCM_MPLS_SUPPORT)
   9649         return _bcm_esw_mpls_flex_stat_index_set(unit, handle, fs_idx,flags);
   9650 #else
   9651         return BCM_E_UNAVAIL;
   9652 #endif /* BCM_MPLS_SUPPORT */
   9653     } else if (BCM_GPORT_IS_SUBPORT_GROUP(handle) ||
   9654                BCM_GPORT_IS_SUBPORT_PORT(handle)) {
   9655         return _bcm_esw_subport_flex_stat_index_set(unit, handle, fs_idx,flags);
   9656     } else if (BCM_GPORT_IS_MIM_PORT(handle)) {
   9657         return _bcm_esw_mim_flex_stat_index_set(unit, handle, fs_idx,flags);
   9658     } else if (BCM_GPORT_IS_WLAN_PORT(handle)) {
   9659         return _bcm_esw_wlan_flex_stat_index_set(unit, handle, fs_idx,flags);
   9660     } else 
   9661 #endif /* INCLUDE_L3 */
   9662     {
   9663         /* handle GPORT must be a local physical port */
   9664         return _bcm_esw_port_flex_stat_index_set(unit, handle, fs_idx,flags);
   9665     }
   9666 }
   9667 
   9668 /*
   9669  * Function:
   9670  *      _bcm_esw_flex_stat_handle_free
   9671  * Purpose:
   9672  *      Deallocate the flexible stat for a handle that has been deleted
   9673  *      by its controlling module.
   9674  * Parameters:
   9675  *      unit - SOC unit number
   9676  *      type - flexible stat type
   9677  *      handle - the encoded handle for the type of packets to count.
   9678  * Returns:
   9679  *      Success: Flexible stat index
   9680  *      Failure: 0 (invalid stat index)
   9681  * Notes:
   9682  *      No HW update is required because the controlling module clears
   9683  *      the entry for the associated handle. We note that this FS index
   9684  *      is again usable, and the FS HW counters will be reset when this
   9685  *      index is next used.
   9686  */
   9687 void
   9688 _bcm_esw_flex_stat_ext_handle_free(int unit, _bcm_flex_stat_type_t type,
   9689                                    _bcm_flex_stat_handle_t handle)
   9690 {
   9691     int fs_idx;
   9692     _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, type);
   9693 
   9694     FS_LOCK(unit);
   9695     if (FS_INFO(unit, hw_type) != NULL) {
   9696         fs_idx = _bcm_esw_flex_stat_index(unit, type, handle);
   9697         if (fs_idx > 0) {
   9698             _bcm_esw_flex_stat_index_delete(unit, type, handle, fs_idx);
   9699         }
   9700     }
   9701     FS_UNLOCK(unit);
   9702 }
   9703 
   9704 /* Write to Flexible Counter HW */
   9705 STATIC int
   9706 _bcm_esw_flex_stat_hw_set(int unit, _bcm_flex_stat_type_t type,
   9707                           int fs_idx, _bcm_flex_stat_t stat, uint64 val)
   9708 {
   9709     ing_service_counter_table_entry_t flex_ctr_entry;
   9710     soc_mem_t mem;
   9711     soc_field_t stat_field = BYTE_COUNTERf;
   9712     int rv;
   9713 
   9714     switch (stat) {
   9715     case _bcmFlexStatIngressPackets:
   9716         stat_field = PACKET_COUNTERf;
   9717         /* Fall thru */
   9718     case _bcmFlexStatIngressBytes:
   9719         mem = FS_ING_MEM(type);
   9720         break;
   9721     case _bcmFlexStatEgressPackets:
   9722         stat_field = PACKET_COUNTERf;
   9723         /* Fall thru */
   9724     case _bcmFlexStatEgressBytes:
   9725         mem = FS_EGR_MEM(type);
   9726         break;
   9727     default:
   9728         return BCM_E_PARAM;
   9729     }
   9730 
   9731     MEM_LOCK(unit, mem);
   9732 #ifdef BCM_TRIDENT_SUPPORT
   9733     if (SOC_IS_TD_TT(unit)) {
   9734         soc_mem_t mem_x, mem_y;
   9735         uint64 zero64;
   9736 
   9737         switch (mem) {
   9738         case ING_SERVICE_COUNTER_TABLEm:
   9739             mem_x = ING_SERVICE_COUNTER_TABLE_Xm;
   9740             mem_y = ING_SERVICE_COUNTER_TABLE_Ym;
   9741             break;
   9742         case EGR_SERVICE_COUNTER_TABLEm:
   9743             mem_x = EGR_SERVICE_COUNTER_TABLE_Xm; 
   9744             mem_y = EGR_SERVICE_COUNTER_TABLE_Ym; 
   9745             break;
   9746         case ING_VINTF_COUNTER_TABLEm:
   9747             mem_x = ING_VINTF_COUNTER_TABLE_Xm; 
   9748             mem_y = ING_VINTF_COUNTER_TABLE_Ym; 
   9749             break;
   9750         case EGR_VINTF_COUNTER_TABLEm:
   9751             mem_x = EGR_VINTF_COUNTER_TABLE_Xm; 
   9752             mem_y = EGR_VINTF_COUNTER_TABLE_Ym; 
   9753             break;
   9754         /* Defensive Default */
   9755         /* coverity[dead_error_begin] */
   9756         default:
   9757             MEM_UNLOCK(unit, mem);
   9758             return BCM_E_INTERNAL;
   9759         }
   9760         rv = soc_mem_read(unit, mem_x, MEM_BLOCK_ANY,
   9761                           fs_idx, &flex_ctr_entry);
   9762         if (BCM_SUCCESS(rv)) {
   9763             soc_mem_field64_set(unit, mem_x, (uint32 *)&flex_ctr_entry,
   9764                                 stat_field, val);
   9765             rv = soc_mem_write(unit, mem_x, MEM_BLOCK_ANY, fs_idx,
   9766                                &flex_ctr_entry);
   9767         }
   9768         /* Dual pipe, write non-zero value to X pipe, 0 to Y pipe */
   9769         if (BCM_SUCCESS(rv)) {
   9770             rv = soc_mem_read(unit, mem_y, MEM_BLOCK_ANY,
   9771                               fs_idx, &flex_ctr_entry);
   9772         }
   9773         if (BCM_SUCCESS(rv)) {
   9774             COMPILER_64_ZERO(zero64);
   9775             soc_mem_field64_set(unit, mem_y, (uint32 *)&flex_ctr_entry,
   9776                                 stat_field, zero64);
   9777             rv = soc_mem_write(unit, mem_y, MEM_BLOCK_ANY, fs_idx,
   9778                                &flex_ctr_entry);
   9779         }
   9780     } else
   9781 #endif /* BCM_TRIDENT_SUPPORT */
   9782     {
   9783         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, fs_idx, &flex_ctr_entry);
   9784         if (BCM_SUCCESS(rv)) {
   9785             soc_mem_field64_set(unit, mem, (uint32 *)&flex_ctr_entry,
   9786                                 stat_field, val);
   9787             rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, fs_idx,
   9788                                &flex_ctr_entry);
   9789         }
   9790     }
   9791     MEM_UNLOCK(unit, mem);
   9792 
   9793     return rv;
   9794 }
   9795 
   9796 /* Write to Flexible Counter SW cache and HW. 
   9797    Value is written to SW as is but is trimmed for HW */
   9798 STATIC int
   9799 _bcm_esw_flex_stat_sw_set(int unit, _bcm_flex_stat_type_t type,
   9800                           int fs_idx, _bcm_flex_stat_t stat, uint64 val)
   9801 {
   9802     uint8 htype, dir = 0 /* ingress */, gran = 0 /* pkts */;
   9803     soc_mem_t mem;
   9804     soc_field_t stat_field = PACKET_COUNTERf;
   9805     ing_service_counter_table_entry_t *bptr, *eptr;
   9806     uint64 *cptr;
   9807     uint32 value[2], mask[2];
   9808 
   9809     htype = FS_TYPE_TO_SVC_VINTF_HW_TYPE(unit, type);
   9810 
   9811     if (stat > _bcmFlexStatIngressBytes) {
   9812         /* egress */
   9813         dir = 1;
   9814     }
   9815     if ((stat == _bcmFlexStatIngressBytes) || 
   9816         (stat == _bcmFlexStatEgressBytes)) {
   9817         /* bytes */ 
   9818         gran = 1;
   9819         mask[0] = 0xffffffff;
   9820 #ifdef BCM_TRIDENT_SUPPORT
   9821         if (SOC_IS_TD_TT(unit)) {
   9822             mask[1] = 0xf; /* 36 bits */
   9823             stat_field = BYTE_COUNTERf;
   9824         } else 
   9825 #endif /* BCM_TRIDENT_SUPPORT */
   9826         {
   9827             mask[1] = 0x7; /* 35 bits */
   9828             stat_field = BYTE_COUNTERf;
   9829         }
   9830     } else {
   9831         /* packets */
   9832         mask[0] = 0x1fffffff; /* 29 bits */
   9833         mask[1] = 0; 
   9834     }
   9835     cptr = _bcm_flex_stat_mem[unit][htype][dir][gran];
   9836     cptr[fs_idx] = val; 
   9837     value[0] = COMPILER_64_LO(val) & mask[0];
   9838     value[1] = COMPILER_64_HI(val) & mask[1];
   9839     COMPILER_64_SET(val, value[1], value[0]);
   9840     /* Set in the 'other' HW buffer */
   9841     bptr = _bcm_flex_stat_buff[unit][htype][dir]
   9842                               [!_bcm_flex_stat_buff_toggle[unit]];
   9843     mem = _bcm_flex_stat_mem_types[(htype * _BCM_FLEX_STAT_DIRS) + dir];
   9844     eptr = soc_mem_table_idx_to_pointer(unit, mem,
   9845                                         ing_service_counter_table_entry_t *,
   9846                                         bptr, fs_idx);
   9847     soc_mem_field_set(unit, mem, (uint32 *)eptr, stat_field, value);
   9848 #ifdef BCM_TRIDENT_SUPPORT
   9849     if (SOC_IS_TD_TT(unit)) {
   9850         /* Clear Y-Pipe 'other' HW buffer. */
   9851         bptr = _bcm_flex_stat_buff_y[unit][htype][dir]
   9852             [!_bcm_flex_stat_buff_toggle[unit]];
   9853         if (NULL == bptr) {
   9854             /* Lock released in calling routine. */
   9855             return (BCM_E_INTERNAL);
   9856         }
   9857         eptr = soc_mem_table_idx_to_pointer(unit, mem,
   9858                                         ing_service_counter_table_entry_t *,
   9859                                             bptr, fs_idx);
   9860         /* Clear Y-pipe buffer value. */
   9861         value[0] = value[1] = 0;
   9862         soc_mem_field_set(unit, mem, (uint32 *)eptr, stat_field, value);
   9863     }
   9864 #endif /* BCM_TRIDENT_SUPPORT */
   9865 
   9866     return _bcm_esw_flex_stat_hw_set(unit, type, fs_idx, stat, val);
   9867 }
   9868 
   9869 /* 
   9870  * Read from Flexible Counters SW cache 
   9871  * if sync_mode is set, sync the sw accumulated count
   9872  * with hw count value first, else return sw count.  
   9873  */
   9874 STATIC int
   9875 _bcm_esw_flex_stat_sw_get(int unit, int sync_mode, _bcm_flex_stat_type_t type,
   9876                           int fs_idx, _bcm_flex_stat_t stat, uint64 *val)
   9877 {
   9878     int rv = BCM_E_NONE;
   9879     uint8 htype, dir = 0 /* ingress */, gran = 0 /* pkts */;
   9880     uint64 *cptr;
   9881     htype = FS_TYPE_TO_SVC_VINTF_HW_TYPE(unit, type);
   9882     if (stat > _bcmFlexStatIngressBytes) {
   9883         /* egress */
   9884         dir = 1;
   9885     }
   9886     if ((stat == _bcmFlexStatIngressBytes) || 
   9887         (stat == _bcmFlexStatEgressBytes)) {
   9888         /* bytes */ 
   9889         gran = 1;
   9890     } 
   9891 
   9892     /* if sync_mode is set, sync the sw count with hw count */
   9893     if (sync_mode == 1) {
   9894         FS_LOCK(unit);
   9895         _bcm_esw_flex_stat_collection(unit, type, fs_idx, stat);
   9896         FS_UNLOCK(unit);
   9897     }
   9898 
   9899     cptr = _bcm_flex_stat_mem[unit][htype][dir][gran];
   9900     *val = cptr[fs_idx];
   9901     return rv;
   9902 }
   9903 
   9904 /* Read from Flexible Counters HW */
   9905 int
   9906 _bcm_esw_flex_stat_hw_get(int unit, _bcm_flex_stat_type_t type,
   9907                           int fs_idx, _bcm_flex_stat_t stat, uint64 *val)
   9908 {
   9909     ing_service_counter_table_entry_t flex_ctr_entry;
   9910     soc_mem_t mem;
   9911     soc_field_t stat_field = BYTE_COUNTERf;
   9912     int rv;
   9913 
   9914     switch (stat) {
   9915     case _bcmFlexStatIngressPackets:
   9916         stat_field = PACKET_COUNTERf;
   9917         /* Fall thru */
   9918     case _bcmFlexStatIngressBytes:
   9919         mem = FS_ING_MEM(type);
   9920         break;
   9921     case _bcmFlexStatEgressPackets:
   9922         stat_field = PACKET_COUNTERf;
   9923         /* Fall thru */
   9924     case _bcmFlexStatEgressBytes:
   9925         mem = FS_EGR_MEM(type);
   9926         break;
   9927     default:
   9928         return BCM_E_PARAM;
   9929     }
   9930 
   9931     MEM_LOCK(unit, mem);
   9932 #ifdef BCM_TRIDENT_SUPPORT
   9933     if (SOC_IS_TD_TT(unit)) {
   9934         soc_mem_t mem_x, mem_y;
   9935         uint64 val_y;
   9936 
   9937         switch (mem) {
   9938         case ING_SERVICE_COUNTER_TABLEm:
   9939             mem_x = ING_SERVICE_COUNTER_TABLE_Xm;
   9940             mem_y = ING_SERVICE_COUNTER_TABLE_Ym;
   9941             break;
   9942         case EGR_SERVICE_COUNTER_TABLEm:
   9943             mem_x = EGR_SERVICE_COUNTER_TABLE_Xm; 
   9944             mem_y = EGR_SERVICE_COUNTER_TABLE_Ym; 
   9945             break;
   9946         case ING_VINTF_COUNTER_TABLEm:
   9947             mem_x = ING_VINTF_COUNTER_TABLE_Xm; 
   9948             mem_y = ING_VINTF_COUNTER_TABLE_Ym; 
   9949             break;
   9950         case EGR_VINTF_COUNTER_TABLEm:
   9951             mem_x = EGR_VINTF_COUNTER_TABLE_Xm; 
   9952             mem_y = EGR_VINTF_COUNTER_TABLE_Ym; 
   9953             break;
   9954         /* Defensive Default */
   9955         /* coverity[dead_error_begin] */
   9956         default:
   9957             return BCM_E_INTERNAL;
   9958         }
   9959         rv = soc_mem_read(unit, mem_x, MEM_BLOCK_ANY,
   9960                           fs_idx, &flex_ctr_entry);
   9961         if (BCM_SUCCESS(rv)) {
   9962             soc_mem_field64_get(unit, mem_x, (uint32 *)&flex_ctr_entry,
   9963                                 stat_field, val);
   9964         }
   9965         /* Dual pipe, read from X pipe and Y pipe then add */
   9966         if (BCM_SUCCESS(rv)) {
   9967             rv = soc_mem_read(unit, mem_y, MEM_BLOCK_ANY,
   9968                               fs_idx, &flex_ctr_entry);
   9969         }
   9970         if (BCM_SUCCESS(rv)) {
   9971             soc_mem_field64_get(unit, mem_y, (uint32 *)&flex_ctr_entry,
   9972                                 stat_field, &val_y);
   9973             COMPILER_64_ADD_64(*val, val_y);
   9974         }
   9975     } else
   9976 #endif /* BCM_TRIDENT_SUPPORT */
   9977     {
   9978         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, fs_idx, &flex_ctr_entry);
   9979 
   9980         if (BCM_SUCCESS(rv)) {
   9981             soc_mem_field64_get(unit, mem, (uint32 *)&flex_ctr_entry,
   9982                                 stat_field, val);
   9983         }
   9984     }
   9985     MEM_UNLOCK(unit, mem);
   9986 
   9987     return rv;
   9988 }
   9989 
   9990 /* Clear the Flexible Counter HW */
   9991 STATIC int
   9992 _bcm_esw_flex_stat_hw_clear(int unit, _bcm_flex_stat_type_t type,
   9993                             int fs_idx)
   9994 {
   9995     ing_service_counter_table_entry_t flex_ctr_entry;
   9996     soc_mem_t mem;
   9997     int rv = BCM_E_NONE;
   9998 
   9999     /* This will work on dual-pipes because the base memory will write
  10000      * the same value to both pipe memories. */
  10001     sal_memset(&flex_ctr_entry, 0, sizeof(flex_ctr_entry));
  10002 
  10003     mem = FS_ING_MEM(type);
  10004     MEM_LOCK(unit, mem);
  10005     rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, fs_idx, &flex_ctr_entry);
  10006     MEM_UNLOCK(unit, mem);
  10007 
  10008     if (SOC_MEM_IS_VALID(unit, ING_VINTF_COUNTER_TABLE_Ym) && 
  10009         (mem == ING_VINTF_COUNTER_TABLEm) && BCM_SUCCESS(rv)) {
  10010         ing_vintf_counter_table_y_entry_t flex_ctr_vintf_entry;
  10011         sal_memset(&flex_ctr_vintf_entry, 0, sizeof(flex_ctr_vintf_entry));
  10012 
  10013         MEM_LOCK(unit, mem);
  10014         rv = soc_mem_write(unit, ING_VINTF_COUNTER_TABLE_Ym,
  10015             MEM_BLOCK_ANY, fs_idx, &flex_ctr_vintf_entry);
  10016         MEM_UNLOCK(unit, mem);
  10017     } else if (SOC_MEM_IS_VALID(unit, ING_SERVICE_COUNTER_TABLE_Ym) && 
  10018         (mem == ING_SERVICE_COUNTER_TABLEm) && BCM_SUCCESS(rv)) {
  10019         ing_service_counter_table_y_entry_t flex_ctr_service_entry;
  10020         sal_memset(&flex_ctr_service_entry, 0, sizeof(flex_ctr_service_entry));
  10021 
  10022         MEM_LOCK(unit, mem);
  10023         rv = soc_mem_write(unit, ING_SERVICE_COUNTER_TABLE_Ym,
  10024             MEM_BLOCK_ANY, fs_idx, &flex_ctr_service_entry);
  10025         MEM_UNLOCK(unit, mem);
  10026     }
  10027 
  10028     if (BCM_SUCCESS(rv)) {
  10029         mem = FS_EGR_MEM(type);
  10030         MEM_LOCK(unit, mem);
  10031         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, fs_idx,
  10032                            &flex_ctr_entry);
  10033         MEM_UNLOCK(unit, mem);
  10034     }
  10035 
  10036     if (SOC_MEM_IS_VALID(unit, EGR_VINTF_COUNTER_TABLE_Ym) &&
  10037         (mem == EGR_VINTF_COUNTER_TABLEm) && BCM_SUCCESS(rv)) {
  10038         egr_vintf_counter_table_y_entry_t flex_ctr_egr_vintf_entry;
  10039         sal_memset(&flex_ctr_egr_vintf_entry, 0, sizeof(flex_ctr_egr_vintf_entry));
  10040 
  10041         MEM_LOCK(unit, mem);
  10042         rv = soc_mem_write(unit, EGR_VINTF_COUNTER_TABLE_Ym,
  10043             MEM_BLOCK_ANY, fs_idx, &flex_ctr_egr_vintf_entry);
  10044         MEM_UNLOCK(unit, mem);
  10045     } else if (SOC_MEM_IS_VALID(unit, EGR_SERVICE_COUNTER_TABLE_Ym) &&
  10046         (mem == EGR_SERVICE_COUNTER_TABLEm) && BCM_SUCCESS(rv)) {
  10047         egr_service_counter_table_y_entry_t flex_ctr_egr_service_entry;
  10048         sal_memset(&flex_ctr_egr_service_entry, 0, sizeof(flex_ctr_egr_service_entry));
  10049 
  10050         MEM_LOCK(unit, mem);
  10051         rv = soc_mem_write(unit, EGR_SERVICE_COUNTER_TABLE_Ym,
  10052             MEM_BLOCK_ANY, fs_idx, &flex_ctr_egr_service_entry);
  10053         MEM_UNLOCK(unit, mem);
  10054     }
  10055 
  10056     return rv;
  10057 }
  10058 
  10059 /* Clear the Flexible Counter SW and HW */
  10060 STATIC int
  10061 _bcm_esw_flex_stat_sw_clear(int unit, _bcm_flex_stat_type_t type,
  10062                             int fs_idx)
  10063 {
  10064     uint64 *cptr;
  10065     ing_service_counter_table_entry_t *bptr, *eptr;
  10066     uint8 htype = FS_TYPE_TO_SVC_VINTF_HW_TYPE(unit, type);
  10067     /* Clear for both directions and both granularities */
  10068     cptr = _bcm_flex_stat_mem[unit][htype][0][0];
  10069     COMPILER_64_ZERO(cptr[fs_idx]);
  10070     cptr = _bcm_flex_stat_mem[unit][htype][0][1];
  10071     COMPILER_64_ZERO(cptr[fs_idx]);
  10072     cptr = _bcm_flex_stat_mem[unit][htype][1][0];
  10073     COMPILER_64_ZERO(cptr[fs_idx]);
  10074     cptr = _bcm_flex_stat_mem[unit][htype][1][1];
  10075     COMPILER_64_ZERO(cptr[fs_idx]);
  10076     /* Clear for both directions only in the 'other' HW buffer */
  10077     bptr = _bcm_flex_stat_buff[unit][htype][0]
  10078                               [!_bcm_flex_stat_buff_toggle[unit]];
  10079     eptr = soc_mem_table_idx_to_pointer(unit, ING_SERVICE_COUNTER_TABLEm,
  10080                                         ing_service_counter_table_entry_t *,
  10081                                         bptr, fs_idx);
  10082     sal_memset(eptr, 0, sizeof(ing_service_counter_table_entry_t));
  10083     bptr = _bcm_flex_stat_buff[unit][htype][1]
  10084                                     [!_bcm_flex_stat_buff_toggle[unit]];
  10085     eptr = soc_mem_table_idx_to_pointer(unit, ING_SERVICE_COUNTER_TABLEm,
  10086                                         ing_service_counter_table_entry_t *,
  10087                                         bptr, fs_idx);
  10088     sal_memset(eptr, 0, sizeof(ing_service_counter_table_entry_t));
  10089 #ifdef BCM_TRIDENT_SUPPORT
  10090     if (SOC_IS_TD_TT(unit)) {
  10091         bptr = _bcm_flex_stat_buff_y[unit][htype][0]
  10092                                     [!_bcm_flex_stat_buff_toggle[unit]];
  10093         eptr = soc_mem_table_idx_to_pointer(unit, ING_SERVICE_COUNTER_TABLEm,
  10094                                         ing_service_counter_table_entry_t *,
  10095                                             bptr, fs_idx);
  10096         sal_memset(eptr, 0, sizeof(ing_service_counter_table_entry_t));
  10097         bptr = _bcm_flex_stat_buff_y[unit][htype][1]
  10098                                     [!_bcm_flex_stat_buff_toggle[unit]];
  10099         eptr = soc_mem_table_idx_to_pointer(unit, ING_SERVICE_COUNTER_TABLEm,
  10100                                         ing_service_counter_table_entry_t *,
  10101                                             bptr, fs_idx);
  10102         sal_memset(eptr, 0, sizeof(ing_service_counter_table_entry_t));
  10103     }
  10104 #endif /* BCM_TRIDENT_SUPPORT */
  10105     return _bcm_esw_flex_stat_hw_clear(unit, type, fs_idx);
  10106 }
  10107 
  10108 /*
  10109  * Function:
  10110  *      _bcm_esw_flex_stat_enable_set
  10111  * Purpose:
  10112  *      Attach/detach a flexible statistic resource to a given packet
  10113  *      lookup table hit.
  10114  * Parameters:
  10115  *      unit - SOC unit number
  10116  *      type - flexible stat type
  10117  *      fs_set_f - callback function to write index into HW table
  10118  *      cookie - cookie for callback function
  10119  *      handle - the encoded handle for the type of packets to count.
  10120  *      enable - TRUE: configure flexible stat collection for the handle.
  10121  *               FALSE: stop flexible stat collection for the handle.
  10122  * Returns:
  10123  *      BCM_X_XXX
  10124  */
  10125 int
  10126 _bcm_esw_flex_stat_ext_enable_set(int unit, _bcm_flex_stat_type_t type,
  10127                                   _bcm_flex_stat_src_index_set_f fs_set_f,
  10128                                   void *cookie,
  10129                                   _bcm_flex_stat_handle_t handle, int enable,
  10130                                   int cnt_inx)
  10131                        
  10132 {
  10133     int fs_idx, rv = BCM_E_NONE;
  10134 
  10135     FS_LOCK(unit);
  10136     FS_INIT(unit, type);
  10137 
  10138     /* non-zero cnt_inx,  used by the new flex count APIs
  10139      * indicates a counter index is allocated outside of this routine. 
  10140      * It doesn't have one-to-one mapping with a handle. Several handles
  10141      * may be associated with a same counter index. For delete operation, 
  10142      * cnt_inx should be ignore. A entry is removed from the handle list 
  10143      * based on the handle.
  10144      *
  10145      * zero cnt_inx
  10146      * Implies the legacy implementation. The counter index is automatically 
  10147      * allocated with the handle entry, and has one-to-one mapping with a
  10148      * handle.
  10149      */
  10150     if (cnt_inx) {
  10151         /* legacy and new APIs cannot be mixed. Validate it first */
  10152         if (_tr2_flex_stat_api_ver[unit]) {
  10153             /* must be new APIs */
  10154             if (_tr2_flex_stat_api_ver[unit] != TR2_FLEX_STAT_API_NEW) {
  10155                 LOG_CLI((BSL_META_U(unit,
  10156                                     "ERROR: _bcm_esw_flex_stat_ext_enable_set: "
  10157                                     "cannot mix the new API with legacy API\n")));
  10158                 FS_UNLOCK(unit);
  10159                 return BCM_E_PARAM;
  10160             }
  10161         } else {  /* first time */
  10162             _tr2_flex_stat_api_ver[unit] = TR2_FLEX_STAT_API_NEW;
  10163         }
  10164 
  10165         /* Check if stat group is created, if not return error */
  10166         if (!_bcm_esw_flex_stat_index_get(unit, type, cnt_inx)) {
  10167             /* During reinit, stat module reset/reinit is done before other
  10168              * modules reinit, hence check needs to be restricted to insert case.
  10169              * For delete case fs_idx will be 0 and will return BCM_E_NOT_FOUND */
  10170             if (enable) {
  10171                 FS_UNLOCK(unit);
  10172                 return BCM_E_PARAM;
  10173             }
  10174         }
  10175 
  10176         fs_idx = _bcm_esw_flex_stat_index(unit, type, handle);
  10177         if (enable) {
  10178             if (fs_idx > 0) {
  10179                 rv = BCM_E_EXISTS;
  10180             } else {
  10181                 _bcm_esw_flex_stat_handle_list_insert(unit,type,handle,
  10182                                                       cnt_inx);
  10183                 rv = (*fs_set_f)(unit, handle, cnt_inx, cookie);
  10184                 if (BCM_FAILURE(rv)) {
  10185                     _bcm_esw_flex_stat_handle_list_delete(unit, type, handle);
  10186                 } else {
  10187                     rv = _bcm_esw_flex_stat_ref_cnt_inc(unit,type,cnt_inx);
  10188                 }
  10189             }
  10190         } else {  /* enable FALSE */
  10191             if (fs_idx) { 
  10192                 _bcm_esw_flex_stat_handle_list_delete(unit,type,handle);
  10193                 rv = (*fs_set_f)(unit, handle, 0, cookie);
  10194                 if (BCM_SUCCESS(rv)) {
  10195                     rv = _bcm_esw_flex_stat_ref_cnt_dec(unit,type,fs_idx);
  10196                 } 
  10197             } else {
  10198                 rv = BCM_E_NOT_FOUND;
  10199             }
  10200         }
  10201         FS_UNLOCK(unit);
  10202         return rv;
  10203     }
  10204 
  10205     /* legacy API is used */
  10206     if (_tr2_flex_stat_api_ver[unit]) {    /* must be legacy APIs */
  10207         if (_tr2_flex_stat_api_ver[unit] != TR2_FLEX_STAT_API_LEGACY) {
  10208             LOG_CLI((BSL_META_U(unit,
  10209                                 "ERROR _bcm_esw_flex_stat_ext_enable_set: cannot mix "
  10210                                 "the new API with legacy API\n")));
  10211             FS_UNLOCK(unit);
  10212             return BCM_E_PARAM;
  10213         }
  10214     } else {  /* first time */
  10215         _tr2_flex_stat_api_ver[unit] = TR2_FLEX_STAT_API_LEGACY;
  10216     }
  10217 
  10218     fs_idx = _bcm_esw_flex_stat_index(unit, type, handle);
  10219     if (fs_idx > 0) {
  10220         if (enable) {
  10221             rv = BCM_E_EXISTS;
  10222         } else {
  10223             _bcm_esw_flex_stat_index_delete(unit, type, handle, fs_idx);
  10224             rv = (*fs_set_f)(unit, handle, 0, cookie);
  10225         }
  10226     } else {
  10227         if (!enable) {
  10228             rv = BCM_E_NOT_FOUND;
  10229         } else {
  10230             fs_idx = _bcm_esw_flex_stat_alloc(unit, type, handle);
  10231             if (fs_idx) {
  10232                 rv = (*fs_set_f)(unit, handle, fs_idx, cookie);
  10233                 if (BCM_FAILURE(rv)) {
  10234                     _bcm_esw_flex_stat_index_delete(unit, type,
  10235                                                     handle, fs_idx);
  10236                 }
  10237             } else {
  10238                 rv = BCM_E_RESOURCE;
  10239             }
  10240             /* Start with cleared stats for this index */
  10241             if (BCM_SUCCESS(rv)) {
  10242                 rv = _bcm_esw_flex_stat_sw_clear(unit, type, fs_idx);
  10243             }
  10244         }
  10245     }
  10246     FS_UNLOCK(unit);
  10247     return rv;
  10248 }
  10249 
  10250 /*
  10251  * Function:
  10252  *      _bcm_esw_flex_stat_get
  10253  * Purpose:
  10254  *      Retrieve a flexible stat for a handle 
  10255  *      if sync_mode is set, sync the sw accumulated count
  10256  *      with hw count value first, else return sw count.  
  10257  *
  10258  * Parameters:
  10259  *      unit      - SOC unit number
  10260  *      sync_mode - hwcount is to be synced to sw count
  10261  *      type      - flexible stat type
  10262  *      handle    - the encoded handle for the type of packets to count.
  10263  *      stat      - (IN) Type of the flexible statistic to retrieve.
  10264  *      val       - (OUT) Pointer to a counter value.
  10265  * Returns:
  10266  *      BCM_X_XXX
  10267  */
  10268 int
  10269 _bcm_esw_flex_stat_ext_get(int unit, int sync_mode, 
  10270                            _bcm_flex_stat_type_t type,
  10271                            _bcm_flex_stat_handle_t handle,
  10272                            _bcm_flex_stat_t stat, uint64 *val)
  10273 {
  10274     int fs_idx, rv = BCM_E_NONE;
  10275 
  10276     if (NULL == val) {
  10277         return (BCM_E_PARAM);
  10278     }
  10279 
  10280     if ((stat < _bcmFlexStatIngressPackets) ||
  10281         (stat >= _bcmFlexStatNum)) {
  10282         return (BCM_E_PARAM);
  10283     }
  10284 
  10285     FS_LOCK(unit);
  10286     FS_INIT(unit, type);
  10287 
  10288     fs_idx = _bcm_esw_flex_stat_index(unit, type, handle);
  10289     if (fs_idx > 0) {
  10290         rv = _bcm_esw_flex_stat_sw_get(unit, sync_mode, type, 
  10291                                        fs_idx, stat, val);
  10292     } else {
  10293         rv = BCM_E_NOT_FOUND;
  10294     }
  10295     FS_UNLOCK(unit);
  10296     return rv;
  10297 }
  10298 
  10299 /*
  10300  * Function:
  10301  *      _bcm_esw_flex_stat_get32
  10302  * Purpose:
  10303  *      Retrieve a flexible stat for a handle in 32-bit form 
  10304  * Parameters:
  10305  *      unit - SOC unit number
  10306  *      type - flexible stat type
  10307  *      handle - the encoded handle for the type of packets to count.
  10308  *      stat - (IN) Type of the flexible statistic to retrieve.
  10309  *      val - (OUT) Pointer to a counter value.
  10310  * Returns:
  10311  *      BCM_X_XXX
  10312  */
  10313 int
  10314 _bcm_esw_flex_stat_ext_get32(int unit, int sync_mode, 
  10315                              _bcm_flex_stat_type_t type,
  10316                              _bcm_flex_stat_handle_t handle,
  10317                              _bcm_flex_stat_t stat, uint32 *val)
  10318 {
  10319     uint64 val64;            /* 64 bit counter value.    */
  10320     int rv;
  10321 
  10322     if (NULL == val) {
  10323         return (BCM_E_PARAM);
  10324     }
  10325 
  10326     rv = _bcm_esw_flex_stat_ext_get(unit, sync_mode, type, 
  10327                                     handle, stat, &val64);
  10328 
  10329     if (BCM_SUCCESS(rv)) {
  10330         *val = COMPILER_64_LO(val64);
  10331     }
  10332 
  10333     return rv;
  10334 }
  10335 
  10336 /*
  10337  * Function:
  10338  *      _bcm_esw_flex_stat_set
  10339  * Purpose:
  10340  *      Assign a flexible stat for a handle 
  10341  * Parameters:
  10342  *      unit - SOC unit number
  10343  *      type - flexible stat type
  10344  *      handle - the encoded handle for the type of packets to count.
  10345  *      stat - (IN) Type of the flexible statistic to retrieve.
  10346  *      val - (IN) Counter value.
  10347  * Returns:
  10348  *      BCM_X_XXX
  10349  */
  10350 int
  10351 _bcm_esw_flex_stat_ext_set(int unit, _bcm_flex_stat_type_t type,
  10352                            _bcm_flex_stat_handle_t handle,
  10353                            _bcm_flex_stat_t stat, uint64 val)
  10354 {
  10355     int fs_idx, rv = BCM_E_NONE;
  10356 
  10357     if ((stat < _bcmFlexStatIngressPackets) ||
  10358         (stat >= _bcmFlexStatNum)) {
  10359         return (BCM_E_PARAM);
  10360     }
  10361 
  10362     FS_LOCK(unit);
  10363     FS_INIT(unit, type);
  10364 
  10365     fs_idx = _bcm_esw_flex_stat_index(unit, type, handle);
  10366     if (fs_idx > 0) {
  10367         rv = _bcm_esw_flex_stat_sw_set(unit, type, fs_idx, stat, val);
  10368     } else {
  10369         rv = BCM_E_NOT_FOUND;
  10370     }
  10371     FS_UNLOCK(unit);
  10372     return rv;
  10373 }
  10374 
  10375 /*
  10376  * Function:
  10377  *      _bcm_esw_flex_stat_set32
  10378  * Purpose:
  10379  *      Assign a flexible stat for a handle in 32-bit form 
  10380  * Parameters:
  10381  *      unit - SOC unit number
  10382  *      type - flexible stat type
  10383  *      handle - the encoded handle for the type of packets to count.
  10384  *      stat - (IN) Type of the flexible statistic to retrieve.
  10385  *      val - (OUT) Pointer to a counter value.
  10386  * Returns:
  10387  *      BCM_X_XXX
  10388  */
  10389 int
  10390 _bcm_esw_flex_stat_ext_set32(int unit, _bcm_flex_stat_type_t type,
  10391                              _bcm_flex_stat_handle_t handle,
  10392                              _bcm_flex_stat_t stat, uint32 val)
  10393 {
  10394     uint64 val64;            /* 64 bit counter value.    */
  10395 
  10396     COMPILER_64_SET(val64, 0, val);
  10397     return _bcm_esw_flex_stat_ext_set(unit, type, handle, stat, val64);
  10398 }
  10399 
  10400 /*
  10401  * Function:
  10402  *      _bcm_esw_flex_stat_multi_get
  10403  * Purpose:
  10404  *      Get 64-bit counter value for multiple flexible statistic types.
  10405  * Parameters:
  10406  *      unit - (IN) Unit number.
  10407  *      type - flexible stat type
  10408  *      handle - the encoded handle for the type of packets to count.
  10409  *      nstat - (IN) Number of elements in stat array
  10410  *      stat_arr - (IN) Collected statistics descriptors array
  10411  *      value_arr - (OUT) Collected counters values
  10412  * Returns:
  10413  *      BCM_E_XXX
  10414  * Notes:
  10415  */
  10416 int 
  10417 _bcm_esw_flex_stat_ext_multi_get(int unit, _bcm_flex_stat_type_t type,
  10418                                  _bcm_flex_stat_handle_t handle, int nstat,
  10419                                  _bcm_flex_stat_t *stat_arr,
  10420                                  uint64 *value_arr)
  10421 {
  10422     int                 rv = BCM_E_NONE; /* Operation return status.    */
  10423     int                 idx;             /* Statistics iteration index. */
  10424     int                 fs_idx;          /* Flexible stat mem index.    */
  10425 
  10426     FS_LOCK(unit);
  10427     FS_INIT(unit, type);
  10428 
  10429     fs_idx = _bcm_esw_flex_stat_index(unit, type, handle);
  10430     if (fs_idx > 0) {
  10431         /* Read individual statistics. */
  10432         for (idx = 0; idx < nstat; idx++) {
  10433             if ((stat_arr[idx] < _bcmFlexStatIngressPackets) ||
  10434                 (stat_arr[idx] >= _bcmFlexStatNum)) {
  10435                 rv = BCM_E_PARAM;
  10436                 break;
  10437             }
  10438             rv = _bcm_esw_flex_stat_sw_get(unit, 0, type, fs_idx,
  10439                                            stat_arr[idx], value_arr + idx);
  10440             if (BCM_FAILURE(rv)) {
  10441                 break;
  10442             }
  10443         }
  10444     } else {
  10445         rv = BCM_E_NOT_FOUND;
  10446     }
  10447     FS_UNLOCK(unit);
  10448 
  10449     return rv;
  10450 }
  10451 
  10452 /*
  10453  * Function:
  10454  *      _bcm_esw_flex_stat_multi_get32
  10455  * Purpose:
  10456  *      Get 32-bit counter value for multiple flexible statistic types.
  10457  * Parameters:
  10458  *      unit - (IN) Unit number.
  10459  *      type - flexible stat type
  10460  *      handle - the encoded handle for the type of packets to count.
  10461  *      nstat - (IN) Number of elements in stat array
  10462  *      stat_arr - (IN) Collected statistics descriptors array
  10463  *      value_arr - (OUT) Collected counters values
  10464  * Returns:
  10465  *      BCM_E_XXX
  10466  * Notes:
  10467  */
  10468 int 
  10469 _bcm_esw_flex_stat_ext_multi_get32(int unit, _bcm_flex_stat_type_t type,
  10470                                    _bcm_flex_stat_handle_t handle, int nstat,
  10471                                    _bcm_flex_stat_t *stat_arr,
  10472                                    uint32 *value_arr)
  10473 {
  10474     uint64              value;           /* 64 bit counter value.       */
  10475     int                 rv = BCM_E_NONE; /* Operation return status.    */
  10476     int                 idx;             /* Statistics iteration index. */
  10477     int                 fs_idx;          /* Flexible stat mem index.    */
  10478 
  10479     FS_LOCK(unit);
  10480     FS_INIT(unit, type);
  10481 
  10482     fs_idx = _bcm_esw_flex_stat_index(unit, type, handle);
  10483     if (fs_idx > 0) {
  10484         /* Read individual statistics. */
  10485         for (idx = 0; idx < nstat; idx++) {
  10486             if ((stat_arr[idx] < _bcmFlexStatIngressPackets) ||
  10487                 (stat_arr[idx] >= _bcmFlexStatNum)) {
  10488                 rv = BCM_E_PARAM;
  10489                 break;
  10490             }
  10491             rv = _bcm_esw_flex_stat_sw_get(unit, 0, type, fs_idx,
  10492                                            stat_arr[idx], &value);
  10493             if (BCM_FAILURE(rv)) {
  10494                 break;
  10495             }
  10496             value_arr[idx] = COMPILER_64_LO(value);
  10497         }
  10498     } else {
  10499         rv = BCM_E_NOT_FOUND;
  10500     }
  10501     FS_UNLOCK(unit);
  10502 
  10503     return rv;
  10504 }
  10505 
  10506 /*
  10507  * Function:
  10508  *      _bcm_esw_flex_stat_multi_set
  10509  * Purpose:
  10510  *      Assign 64-bit counter value for multiple flexible statistic types.
  10511  * Parameters:
  10512  *      unit - (IN) Unit number.
  10513  *      type - flexible stat type
  10514  *      handle - the encoded handle for the type of packets to count.
  10515  *      nstat - (IN) Number of elements in stat array
  10516  *      stat_arr - (IN) Collected statistics descriptors array
  10517  *      value_arr - (IN) Collected counters values
  10518  * Returns:
  10519  *      BCM_E_XXX
  10520  * Notes:
  10521  */
  10522 int 
  10523 _bcm_esw_flex_stat_ext_multi_set(int unit, _bcm_flex_stat_type_t type,
  10524                                  _bcm_flex_stat_handle_t handle, int nstat,
  10525                                  _bcm_flex_stat_t *stat_arr, 
  10526                                  uint64 *value_arr)
  10527 {
  10528     int                 rv = BCM_E_NONE; /* Operation return status.    */
  10529     int                 idx;             /* Statistics iteration index. */
  10530     int                 fs_idx;          /* Flexible stat mem index.    */
  10531 
  10532     FS_LOCK(unit);
  10533     FS_INIT(unit, type);
  10534 
  10535     fs_idx = _bcm_esw_flex_stat_index(unit, type, handle);
  10536     if (fs_idx > 0) {
  10537         /* Read individual statistics. */
  10538         for (idx = 0; idx < nstat; idx++) {
  10539             if ((stat_arr[idx] < _bcmFlexStatIngressPackets) ||
  10540                 (stat_arr[idx] >= _bcmFlexStatNum)) {
  10541                 rv = BCM_E_PARAM;
  10542                 break;
  10543             }
  10544             rv = _bcm_esw_flex_stat_sw_set(unit, type, fs_idx,
  10545                                            stat_arr[idx], value_arr[idx]);
  10546             if (BCM_FAILURE(rv)) {
  10547                 break;
  10548             }
  10549         }
  10550     } else {
  10551         rv = BCM_E_NOT_FOUND;
  10552     }
  10553     FS_UNLOCK(unit);
  10554 
  10555     return rv;
  10556 }
  10557 
  10558 /*
  10559  * Function:
  10560  *      _bcm_esw_flex_stat_multi_set32
  10561  * Purpose:
  10562  *      Assign 32-bit counter value for multiple flexible statistic types.
  10563  * Parameters:
  10564  *      unit - (IN) Unit number.
  10565  *      type - flexible stat type
  10566  *      handle - the encoded handle for the type of packets to count.
  10567  *      nstat - (IN) Number of elements in stat array
  10568  *      stat_arr - (IN) Collected statistics descriptors array
  10569  *      value_arr - (IN) Collected counters values
  10570  * Returns:
  10571  *      BCM_E_XXX
  10572  * Notes:
  10573  */
  10574 int 
  10575 _bcm_esw_flex_stat_ext_multi_set32(int unit, _bcm_flex_stat_type_t type,
  10576                                    _bcm_flex_stat_handle_t handle, int nstat,
  10577                                    _bcm_flex_stat_t *stat_arr, 
  10578                                    uint32 *value_arr)
  10579 {
  10580     uint64              value;           /* 64 bit counter value.       */
  10581     int                 rv = BCM_E_NONE; /* Operation return status.    */
  10582     int                 idx;             /* Statistics iteration index. */
  10583     int                 fs_idx;          /* Flexible stat mem index.    */
  10584 
  10585     FS_LOCK(unit);
  10586     FS_INIT(unit, type);
  10587 
  10588     fs_idx = _bcm_esw_flex_stat_index(unit, type, handle);
  10589     if (fs_idx > 0) {
  10590         /* Read individual statistics. */
  10591         for (idx = 0; idx < nstat; idx++) {
  10592             if ((stat_arr[idx] < _bcmFlexStatIngressPackets) ||
  10593                 (stat_arr[idx] >= _bcmFlexStatNum)) {
  10594                 rv = BCM_E_PARAM;
  10595                 break;
  10596             }
  10597             COMPILER_64_SET(value, 0, value_arr[idx]);
  10598             rv = _bcm_esw_flex_stat_sw_set(unit, type, fs_idx,
  10599                                            stat_arr[idx], value);
  10600             if (BCM_FAILURE(rv)) {
  10601                 break;
  10602             }
  10603         }
  10604     } else {
  10605         rv = BCM_E_NOT_FOUND;
  10606     }
  10607     FS_UNLOCK(unit);
  10608 
  10609     return rv;
  10610 }
  10611 
  10612 /* Functions for legacy uint32 handles to newer extended handles */
  10613 void
  10614 _bcm_esw_flex_stat_reinit_add(int unit, _bcm_flex_stat_type_t type,
  10615                               int fs_index, uint32 handle)
  10616 {
  10617     _bcm_flex_stat_handle_t fsh;
  10618     _BCM_FLEX_STAT_HANDLE_CLEAR(fsh);
  10619     _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle);
  10620 
  10621     _bcm_esw_flex_stat_ext_reinit_add(unit, type, fs_index, fsh);
  10622 }
  10623 
  10624 void
  10625 _bcm_esw_flex_stat_handle_free(int unit, _bcm_flex_stat_type_t type,
  10626                                uint32 handle)
  10627 {
  10628     _bcm_flex_stat_handle_t fsh;
  10629     _BCM_FLEX_STAT_HANDLE_CLEAR(fsh);
  10630     _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle);
  10631 
  10632     _bcm_esw_flex_stat_ext_handle_free(unit, type, fsh);
  10633 }
  10634 
  10635 int
  10636 _bcm_esw_flex_stat_enable_set(int unit, _bcm_flex_stat_type_t type,
  10637                               _bcm_flex_stat_src_index_set_f fs_set_f,
  10638                               void *cookie, uint32 handle, int enable,
  10639            int cnt_inx /* count index, 0 for legacy API, auto allocated */
  10640            )
  10641 {
  10642     _bcm_flex_stat_handle_t fsh;
  10643     _BCM_FLEX_STAT_HANDLE_CLEAR(fsh);
  10644     _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle);
  10645 
  10646     return _bcm_esw_flex_stat_ext_enable_set(unit, type, fs_set_f,
  10647                                              cookie, fsh, enable,cnt_inx);
  10648 }
  10649 
  10650 int
  10651 _bcm_esw_flex_stat_get(int unit, int sync_mode, _bcm_flex_stat_type_t type,
  10652                        uint32 handle, _bcm_flex_stat_t stat, uint64 *val)
  10653 {
  10654     _bcm_flex_stat_handle_t fsh;
  10655     _BCM_FLEX_STAT_HANDLE_CLEAR(fsh);
  10656     _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle);
  10657 
  10658     return _bcm_esw_flex_stat_ext_get(unit, sync_mode, type, fsh, stat, val);
  10659 }
  10660 
  10661 int
  10662 _bcm_esw_flex_stat_get32(int unit, int sync_mode, _bcm_flex_stat_type_t type,
  10663                          uint32 handle, _bcm_flex_stat_t stat, uint32 *val)
  10664 {
  10665     _bcm_flex_stat_handle_t fsh;
  10666     _BCM_FLEX_STAT_HANDLE_CLEAR(fsh);
  10667     _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle);
  10668 
  10669     return _bcm_esw_flex_stat_ext_get32(unit, sync_mode, type, fsh, stat, val);
  10670 }
  10671 
  10672 int
  10673 _bcm_esw_flex_stat_set(int unit, _bcm_flex_stat_type_t type,
  10674                        uint32 handle, _bcm_flex_stat_t stat, uint64 val)
  10675 {
  10676     _bcm_flex_stat_handle_t fsh;
  10677     _BCM_FLEX_STAT_HANDLE_CLEAR(fsh);
  10678     _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle);
  10679 
  10680     return _bcm_esw_flex_stat_ext_set(unit, type, fsh, stat, val);
  10681 }
  10682 
  10683 int
  10684 _bcm_esw_flex_stat_set32(int unit, _bcm_flex_stat_type_t type,
  10685                          uint32 handle, _bcm_flex_stat_t stat, uint32 val)
  10686 {
  10687     _bcm_flex_stat_handle_t fsh;
  10688     _BCM_FLEX_STAT_HANDLE_CLEAR(fsh);
  10689     _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle);
  10690 
  10691     return _bcm_esw_flex_stat_ext_set32(unit, type, fsh, stat, val);
  10692 }
  10693 
  10694 int 
  10695 _bcm_esw_flex_stat_multi_get(int unit, _bcm_flex_stat_type_t type,
  10696                              uint32 handle, int nstat,
  10697                              _bcm_flex_stat_t *stat_arr,
  10698                              uint64 *value_arr)
  10699 {
  10700     _bcm_flex_stat_handle_t fsh;
  10701     _BCM_FLEX_STAT_HANDLE_CLEAR(fsh);
  10702     _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle);
  10703 
  10704     return _bcm_esw_flex_stat_ext_multi_get(unit, type, fsh,
  10705                                             nstat, stat_arr, value_arr);
  10706 }
  10707 
  10708 int 
  10709 _bcm_esw_flex_stat_multi_get32(int unit, _bcm_flex_stat_type_t type,
  10710                                uint32 handle, int nstat,
  10711                                _bcm_flex_stat_t *stat_arr,
  10712                                uint32 *value_arr)
  10713 {
  10714     _bcm_flex_stat_handle_t fsh;
  10715     _BCM_FLEX_STAT_HANDLE_CLEAR(fsh);
  10716     _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle);
  10717 
  10718     return _bcm_esw_flex_stat_ext_multi_get32(unit, type, fsh,
  10719                                               nstat, stat_arr, value_arr);
  10720 }
  10721 
  10722 int 
  10723 _bcm_esw_flex_stat_multi_set(int unit, _bcm_flex_stat_type_t type,
  10724                              uint32 handle, int nstat,
  10725                              _bcm_flex_stat_t *stat_arr, 
  10726                              uint64 *value_arr)
  10727 {
  10728     _bcm_flex_stat_handle_t fsh;
  10729     _BCM_FLEX_STAT_HANDLE_CLEAR(fsh);
  10730     _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle);
  10731 
  10732     return _bcm_esw_flex_stat_ext_multi_set(unit, type, fsh,
  10733                                             nstat, stat_arr, value_arr);
  10734 }
  10735 
  10736 int 
  10737 _bcm_esw_flex_stat_multi_set32(int unit, _bcm_flex_stat_type_t type,
  10738                                uint32 handle, int nstat,
  10739                                _bcm_flex_stat_t *stat_arr, 
  10740                                uint32 *value_arr)
  10741 {
  10742     _bcm_flex_stat_handle_t fsh;
  10743     _BCM_FLEX_STAT_HANDLE_CLEAR(fsh);
  10744     _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle);
  10745 
  10746     return _bcm_esw_flex_stat_ext_multi_set32(unit, type, fsh,
  10747                                               nstat, stat_arr, value_arr);
  10748 }
  10749 #endif /* BCM_TRIUMPH2_SUPPORT */
  10750 
  10751 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  10752 
  10753 typedef enum _bcm_trx_mysta_memacc_type_e {
  10754     _BCM_TRX_MYSTA_MEMACC_MAC_ADDRf,
  10755     _BCM_TRX_MYSTA_MEMACC_MAC_ADDR_MASKf,
  10756     _BCM_TRX_MYSTA_MEMACC_VLAN_IDf,
  10757     _BCM_TRX_MYSTA_MEMACC_VLAN_ID_MASKf,
  10758     _BCM_TRX_MYSTA_MEMACC_ING_PORT_NUMf,
  10759     _BCM_TRX_MYSTA_MEMACC_ING_PORT_NUM_MASKf,
  10760     _BCM_TRX_MYSTA_MEMACC_SOURCE_FIELDf,
  10761     _BCM_TRX_MYSTA_MEMACC_SOURCE_FIELD_MASKf, 
  10762     _BCM_TRX_MYSTA_MEMACC_SOURCE_TYPEf,
  10763     _BCM_TRX_MYSTA_MEMACC_SOURCE_TYPE_MASKf,
  10764     _BCM_TRX_MYSTA_MEMACC_VALIDf,
  10765     _BCM_TRX_MYSTA_MEMACC_COPY_TO_CPUf,
  10766     _BCM_TRX_MYSTA_MEMACC_DISCARDf,
  10767     _BCM_TRX_MYSTA_MEMACC_IPV4_TERMINATION_ALLOWEDf,
  10768     _BCM_TRX_MYSTA_MEMACC_NUM
  10769 } _bcm_trx_mysta_memacc_type_t;
  10770 
  10771 #define _BCM_TRX_MYSTA_MEMACC_LIST(u, mem) \
  10772         (mem == MY_STATION_TCAM_2m) ? &(_bcm_trx_mysta2_memacc_list[u]) : \
  10773                                       &(_bcm_trx_mysta_memacc_list[u])
  10774 
  10775 #define _BCM_TRX_MYSTA_MEMACC(u, memacc_list, memacc_type) \
  10776         (&((*memacc_list)[memacc_type]))
  10777 
  10778 #define _BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, fld) \
  10779         (&((*memacc_list)[fld]))
  10780 
  10781 #define _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(u, memacc_list, ent, fld) \
  10782         soc_memacc_field32_get(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \
  10783                             _BCM_TRX_MYSTA_MEMACC_##fld), ent)
  10784 #define _BCM_TRX_MYSTA_FIELD_MEMACC_GET(u, memacc_list, ent, fld, fldbuf) \
  10785         soc_memacc_field_get(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \
  10786                             _BCM_TRX_MYSTA_MEMACC_##fld), ent, fldbuf)
  10787 #define _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(u, memacc_list, ent, fld, mac) \
  10788         soc_memacc_mac_addr_get(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \
  10789                             _BCM_TRX_MYSTA_MEMACC_##fld), ent, mac)                                           
  10790 #define _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(u, memacc_list, ent, fld, val) \
  10791         soc_memacc_field32_set(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \
  10792                             _BCM_TRX_MYSTA_MEMACC_##fld), ent, val)
  10793 #define _BCM_TRX_MYSTA_FIELD_MEMACC_SET(u, memacc_list, ent, fld, fldbuf) \
  10794         soc_memacc_field_set(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \
  10795                             _BCM_TRX_MYSTA_MEMACC_##fld), ent, fldbuf)
  10796 #define _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(u, memacc_list, ent, fld, mac) \
  10797         soc_memacc_mac_addr_set(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \
  10798                             _BCM_TRX_MYSTA_MEMACC_##fld), ent, mac) 
  10799 
  10800 static soc_field_t 
  10801 _bcm_trx_mysta_field_memacc_map[_BCM_TRX_MYSTA_MEMACC_NUM] = {
  10802     MAC_ADDRf,
  10803     MAC_ADDR_MASKf,
  10804     VLAN_IDf,
  10805     VLAN_ID_MASKf,
  10806     ING_PORT_NUMf,
  10807     ING_PORT_NUM_MASKf,
  10808     SOURCE_FIELDf,
  10809     SOURCE_FIELD_MASKf, 
  10810     SOURCE_TYPEf,
  10811     SOURCE_TYPE_MASKf,
  10812     VALIDf,
  10813     COPY_TO_CPUf,
  10814     DISCARDf,
  10815     IPV4_TERMINATION_ALLOWEDf
  10816 };
  10817 
  10818 STATIC int
  10819 _bcm_trx_mysta_memacc_init(int unit)
  10820 {
  10821     int alloc_size, rv = BCM_E_NONE;
  10822     soc_field_t *memacc_map;
  10823     soc_memacc_t **memacc_list = NULL;
  10824     int mam_ix, memacc_map_size = _BCM_TRX_MYSTA_MEMACC_NUM;
  10825     int i;
  10826     soc_mem_t mem, mem_list[] = {
  10827                       MY_STATION_TCAMm
  10828 #ifdef BCM_RIOT_SUPPORT
  10829                       , MY_STATION_TCAM_2m
  10830 #endif /* BCM_RIOT_SUPPORT */
  10831                       };
  10832 
  10833     alloc_size = (memacc_map_size * sizeof(soc_memacc_t));
  10834 
  10835     for (i = 0; i < COUNTOF(mem_list); i++) {
  10836         mem = mem_list[i];
  10837 
  10838 #ifdef BCM_RIOT_SUPPORT
  10839         if ((!soc_feature(unit, soc_feature_riot)) &&
  10840             !(SOC_IS_TRIDENT3X(unit)) &&
  10841             (mem == MY_STATION_TCAM_2m)) {
  10842             continue;
  10843         }
  10844 #endif /* BCM_RIOT_SUPPORT */
  10845 
  10846         memacc_map = _bcm_trx_mysta_field_memacc_map;
  10847         memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  10848 
  10849         *memacc_list = sal_alloc(alloc_size, "L2 tables memacc data");
  10850         if (NULL == *memacc_list) {
  10851             rv = BCM_E_MEMORY;
  10852             break;
  10853         }
  10854 
  10855         for (mam_ix = 0; mam_ix < memacc_map_size; mam_ix++) {
  10856             if (INVALIDf == memacc_map[mam_ix]) {
  10857                 SOC_MEMACC_INVALID_SET(&((*memacc_list)[mam_ix]));
  10858                 continue;
  10859             }
  10860             if (!soc_mem_field_valid(unit, mem,
  10861                                      memacc_map[mam_ix])) {
  10862                 continue;
  10863             }
  10864             rv = soc_memacc_init(unit, mem,
  10865                                  memacc_map[mam_ix],
  10866                                  &((*memacc_list)[mam_ix]));
  10867             if (BCM_FAILURE(rv)) {
  10868                 break;
  10869             }
  10870         }
  10871 
  10872         if (BCM_FAILURE(rv)) {
  10873             break;
  10874         }
  10875     } while (0);
  10876 
  10877     if (BCM_FAILURE(rv)) {
  10878         sal_free(*memacc_list);
  10879         *memacc_list = NULL;
  10880     }
  10881 
  10882     return rv;
  10883 }
  10884 
  10885 /*
  10886  * Function:
  10887  *     _bcm_td_l2cache_from_my_station
  10888  * Purpose:
  10889  *     Convert a MY_STATION_TCAM entry to an L2cache API data structure
  10890  * Parameters:
  10891  *     unit              Unit number
  10892  *     l2caddr           L2 cache API data structure
  10893  *     entry             MY_STATION_TCAM entry
  10894  */
  10895 STATIC void
  10896 _bcm_td_l2cache_from_my_station(int unit, bcm_l2_cache_addr_t *l2caddr,
  10897                                 my_station_tcam_entry_t *entry)
  10898 {
  10899     soc_mem_t mem = MY_STATION_TCAMm;
  10900     soc_memacc_t **memacc_list = NULL;
  10901 
  10902     sal_memset(l2caddr, 0, sizeof(*l2caddr));
  10903 
  10904     if (soc_feature(unit, soc_feature_riot)) {
  10905         mem = MY_STATION_TCAM_2m;
  10906     }
  10907 
  10908     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  10909     
  10910     /* Valid bit is ignored here; entry is assumed valid */
  10911 
  10912     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(unit, memacc_list, entry, MAC_ADDRf, l2caddr->mac);
  10913     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(unit, memacc_list, entry, MAC_ADDR_MASKf, l2caddr->mac_mask);
  10914     l2caddr->vlan = 
  10915         _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VLAN_IDf);
  10916     l2caddr->vlan_mask = 
  10917         _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VLAN_ID_MASKf);
  10918     if (soc_feature(unit, soc_feature_gh2_my_station)) {
  10919     l2caddr->src_port = 
  10920             _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list,
  10921                     entry, SOURCE_FIELDf);
  10922     l2caddr->src_port_mask = 
  10923             _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list,
  10924                     entry, SOURCE_FIELD_MASKf);
  10925     } else {
  10926         l2caddr->src_port =
  10927             _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list,
  10928                     entry, ING_PORT_NUMf);
  10929         l2caddr->src_port_mask =
  10930             _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list,
  10931                     entry, ING_PORT_NUM_MASKf);
  10932     }
  10933 
  10934     l2caddr->flags |= BCM_L2_CACHE_L3;
  10935     if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, DISCARDf)) {
  10936         l2caddr->flags |= BCM_L2_CACHE_DISCARD;
  10937     }
  10938     if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, COPY_TO_CPUf)) {
  10939         l2caddr->flags |= BCM_L2_CACHE_CPU;
  10940     }
  10941 }
  10942 
  10943 /*
  10944  * Function:
  10945  *      _bcm_td_l2cache_to_my_station
  10946  * Purpose:
  10947  *     Convert an L2 API data structure to a MY_STATION_TCAM entry
  10948  * Parameters:
  10949  *     unit              Unit number
  10950  *     entry             MY_STATION_TCAM entry
  10951  *     entry_prof        MY_STATION_PROFILE_1 entry
  10952  *     l2caddr           L2 cache API data structure
  10953  */
  10954 STATIC void
  10955 _bcm_td_l2cache_to_my_station(int unit, my_station_tcam_entry_t *entry,
  10956                               my_station_profile_1_entry_t *entry_prof,
  10957                               bcm_l2_cache_addr_t *l2caddr)
  10958 {
  10959     int i, entry_words;
  10960     uint32 *l3_mask;
  10961     soc_mem_t mem = MY_STATION_TCAMm;
  10962     soc_memacc_t **memacc_list = NULL;
  10963 
  10964     l3_mask = COMMON_INFO(unit)->my_station_l3_mask;
  10965 
  10966     if (soc_feature(unit, soc_feature_riot)) {
  10967         mem = MY_STATION_TCAM_2m;
  10968         l3_mask = COMMON_INFO(unit)->my_station2_l3_mask.entry_data;
  10969     }
  10970 
  10971     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  10972 
  10973     entry_words = soc_mem_entry_words(unit, mem);
  10974 
  10975     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VALIDf,
  10976         (1 << soc_mem_field_length(unit, mem, VALIDf)) - 1);
  10977     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_IDf,
  10978                         l2caddr->vlan);
  10979     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_ID_MASKf,
  10980                         l2caddr->vlan_mask);
  10981     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDRf,
  10982                          l2caddr->mac);
  10983     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDR_MASKf,
  10984                          l2caddr->mac_mask);
  10985     if (soc_feature(unit, soc_feature_gh2_my_station)) {
  10986         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry,
  10987                             SOURCE_FIELDf, l2caddr->src_port);
  10988         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry,
  10989                             SOURCE_FIELD_MASKf, l2caddr->src_port_mask);
  10990     } else {
  10991         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry,
  10992                             ING_PORT_NUMf, l2caddr->src_port);
  10993         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry,
  10994                             ING_PORT_NUM_MASKf, l2caddr->src_port_mask);
  10995     }
  10996 
  10997     if (soc_feature(unit, soc_feature_mysta_profile)) {
  10998         for (i = 0; i < soc_mem_entry_words(unit, MY_STATION_PROFILE_1m); i++) {
  10999             entry_prof->entry_data[i] |= l3_mask[i];
  11000         }
  11001     } else {
  11002     for (i = 0; i < entry_words; i++) {
  11003         entry->entry_data[i] |= l3_mask[i];
  11004     }
  11005     }
  11006 
  11007     if (l2caddr->flags & BCM_L2_CACHE_DISCARD) {
  11008         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, DISCARDf, 1);
  11009     }
  11010     if (l2caddr->flags & BCM_L2_CACHE_CPU) {
  11011         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, COPY_TO_CPUf, 1);
  11012     }
  11013 }
  11014 
  11015 /*
  11016  * Function:
  11017  *     _bcm_td_l2_from_my_station
  11018  * Purpose:
  11019  *     Convert a MY_STATION_TCAM entry to an L2 API data structure
  11020  * Parameters:
  11021  *     unit              Unit number
  11022  *     l2addr            L2 API data structure
  11023  *     entry             MY_STATION_TCAM entry
  11024  */
  11025 STATIC void
  11026 _bcm_td_l2_from_my_station(int unit, bcm_l2_addr_t *l2addr,
  11027                            my_station_tcam_entry_t *entry,
  11028                            my_station_profile_1_entry_t *entry_prof)
  11029 {
  11030     soc_mem_t mem = MY_STATION_TCAMm;
  11031     soc_memacc_t **memacc_list = NULL;
  11032 
  11033     if (soc_feature(unit, soc_feature_riot)) {
  11034         mem = MY_STATION_TCAM_2m;
  11035     }
  11036 
  11037     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  11038     sal_memset(l2addr, 0, sizeof(*l2addr));
  11039 
  11040     /* Valid bit is ignored here; entry is assumed valid */
  11041 
  11042     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(unit, memacc_list, entry, MAC_ADDRf,
  11043                          l2addr->mac);
  11044     l2addr->vid = _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VLAN_IDf);
  11045 
  11046     if (soc_feature(unit, soc_feature_mysta_profile)) {
  11047         if (soc_mem_field32_get(unit, MY_STATION_PROFILE_1m, entry_prof,
  11048                                 IPV4_TERMINATION_ALLOWEDf)) {
  11049             l2addr->flags |= BCM_L2_L3LOOKUP;
  11050         }
  11051     } else {
  11052     if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry,
  11053                             IPV4_TERMINATION_ALLOWEDf)) {
  11054         l2addr->flags |= BCM_L2_L3LOOKUP;
  11055     }
  11056     }
  11057     if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, DISCARDf)) {
  11058         l2addr->flags |= BCM_L2_DISCARD_DST;
  11059     }
  11060     if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, COPY_TO_CPUf)) {
  11061         l2addr->flags |= BCM_L2_COPY_TO_CPU;
  11062     }
  11063     l2addr->flags |= BCM_L2_LEARN_LIMIT_EXEMPT;
  11064 }
  11065 
  11066 /*
  11067  * Function:
  11068  *     _bcm_td_l2_to_my_station
  11069  * Purpose:
  11070  *     Convert an L2 API data structure to a MY_STATION_TCAM entry
  11071  * Parameters:
  11072  *     unit              Unit number
  11073  *     entry             MY_STATION_TCAM entry
  11074  *     l2addr            L2 API data structure
  11075  *     incl_key_mask     Update key and mask fields as well
  11076  */
  11077 STATIC void
  11078 _bcm_td_l2_to_my_station(int unit, int tcam_no, my_station_tcam_entry_t *entry,
  11079                          my_station_profile_1_entry_t *entry_prof,
  11080                          bcm_l2_addr_t *l2addr, int incl_key_mask)
  11081 {
  11082     bcm_mac_t mac_mask;
  11083     uint32 fval;
  11084     int i, entry_words;
  11085     uint32 *l3_mask;
  11086     soc_mem_t mem = MY_STATION_TCAMm;
  11087     soc_memacc_t **memacc_list = NULL;
  11088     soc_mem_t proft = MY_STATION_PROFILE_1m;
  11089 
  11090     l3_mask = COMMON_INFO(unit)->my_station_l3_mask;
  11091 
  11092     if (tcam_no == 2) {
  11093         mem = MY_STATION_TCAM_2m;
  11094         l3_mask = COMMON_INFO(unit)->my_station2_l3_mask.entry_data;
  11095         proft = MY_STATION_PROFILE_2m;
  11096     }
  11097 
  11098     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  11099     entry_words = soc_mem_entry_words(unit, mem);
  11100 
  11101     if (incl_key_mask) {
  11102         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VALIDf,
  11103             (1 << soc_mem_field_length(unit, mem, VALIDf)) - 1);
  11104         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_IDf,
  11105                             l2addr->vid);
  11106         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_ID_MASKf,
  11107                             0xfff);
  11108         _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDRf,
  11109                              l2addr->mac);
  11110         sal_memset(&mac_mask, 0xff, sizeof(mac_mask));
  11111         _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDR_MASKf,
  11112                              mac_mask);
  11113     }
  11114 
  11115     if (soc_feature(unit, soc_feature_mysta_profile)) {
  11116         entry_words = soc_mem_entry_words(unit, proft);
  11117         for (i = 0; i < entry_words; i++) {
  11118             entry_prof->entry_data[i] |= l3_mask[i];
  11119         }
  11120     } else {
  11121     for (i = 0; i < entry_words; i++) {
  11122         entry->entry_data[i] |= l3_mask[i];
  11123     }
  11124     }
  11125 
  11126     fval = l2addr->flags & BCM_L2_DISCARD_DST ? 1 : 0;
  11127     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, DISCARDf, fval);
  11128 
  11129     fval = l2addr->flags & BCM_L2_COPY_TO_CPU ? 1 : 0;
  11130     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, COPY_TO_CPUf, fval);
  11131 }
  11132 
  11133 /*
  11134  * Function:
  11135  *     _bcm_td_my_station_lookup
  11136  * Purpose:
  11137  *     Perform following exact matched in MY_STATION_TCAM table:
  11138  *     - target entry lookup:
  11139  *       match the entry specified by vlan/mac and optional port
  11140  *     - (optional) alternate entry lookup: (when alt_index != NULL)
  11141  *       match the possible entry having the same vlan/mac as the target entry
  11142  * Parameters:
  11143  *     unit              Unit number
  11144  *     mac               MAC address key
  11145  *     vlan              VLAN id key
  11146  *     port              Source port number key (-1 means to match any)
  11147  *     index_to_be_skip  The index to be omit during lookup
  11148  *     entry_index       (OUT) target entry index (if BCM_E_NONE)
  11149  *                             available entry index or -1 (if BCM_E_NOT_FOUND)
  11150  *     alt_index         (OUT) alternate entry index or -1 (if BCM_E_NOT_FOUND)
  11151  *                       if alt_index is NULL, that means lookup only
  11152  * Returns:
  11153  *      BCM_E_NONE - target entry found
  11154  *      BCM_E_NOT_FOUND - target entry not found
  11155  * Notes:
  11156  *     if (target entry is found) {
  11157  *         entry_index: index for the matched target entry
  11158  *         alt_index: N/A
  11159  *     } else if (alternate entry is found) {
  11160  *         entry_index: index for the free entry to be used (-1 if table full)
  11161  *         alt_index: index for the matched alternate entry
  11162  *         *** caller needs to compare both indices, move the entry if needed
  11163  *     } else {
  11164  *         entry_index: index for the free entry to be used (-1 if table full)
  11165  *         alt_index: -1
  11166  *     }
  11167  */
  11168 STATIC int
  11169 _bcm_td_my_station_lookup(int unit, soc_mem_t mem, bcm_mac_t mac, bcm_vlan_t vlan,
  11170                           bcm_port_t port, int index_to_skip,
  11171                           int *entry_index, int *alt_index)
  11172 {
  11173     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  11174     my_station_tcam_entry_t *entry, entry0, entry1, entry2, mask0, mask1;
  11175     int index0, index1, free_index, i, entry_words;
  11176     int start, end, step;
  11177     bcm_mac_t mac_mask;
  11178     uint32 port_mask;
  11179     soc_memacc_t **memacc_list = NULL;
  11180     my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow;
  11181 
  11182     if (mem == MY_STATION_TCAM_2m) {
  11183         my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow;
  11184     }
  11185 
  11186     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  11187 
  11188     LOG_INFO(BSL_LS_BCM_L2,
  11189              (BSL_META_U(unit,
  11190                          "_bcm_td_my_station_lookup: unit=%d "
  11191                          "mac=%02x:%02x:%02x:%02x:%02x:%02x vlan=%d port=%d "
  11192                          "index_to_skip=%d\n"),
  11193               unit, vlan, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
  11194               port, index_to_skip));
  11195 
  11196     sal_memset(&mac_mask, 0xff, sizeof(mac_mask));
  11197 
  11198     if (soc_mem_field_valid(unit, mem, SOURCE_FIELDf)) {
  11199         port_mask =
  11200             (1 << soc_mem_field_length(unit, mem, SOURCE_FIELDf)) - 1;
  11201     } else {
  11202         port_mask =
  11203             (1 << soc_mem_field_length(unit, mem, ING_PORT_NUMf)) - 1;
  11204     }
  11205     entry_words = soc_mem_entry_words(unit, mem);
  11206 
  11207     /*
  11208      * entry0, mask0 are for target entry
  11209      * entry1, mask1 are for alternate entry
  11210      * if (port == -1)
  11211      *     entry0 is: vlan/mac/00/fff/ffffffffffff/ff
  11212      *     entry1 is: vlan/mac/xx/fff/ffffffffffff/ff
  11213      *     start from last entry (free index needs to have larger index than
  11214      *     any alternate entry)
  11215      * else
  11216      *     entry0 is: vlan/mac/port/fff/ffffffffffff/ff
  11217      *     entry1 is: vlan/mac/00/fff/ffffffffffff/ff
  11218      *     start from first entry (free index needs to have smaller index than
  11219      *     the alternate entry)
  11220      */
  11221     sal_memset(&entry0, 0, sizeof(entry0));
  11222     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, VALIDf,
  11223         (1 << soc_mem_field_length(unit, MY_STATION_TCAMm, VALIDf)) - 1);
  11224     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, VLAN_IDf, vlan);
  11225     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, &entry0, MAC_ADDRf, mac);
  11226     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, VLAN_ID_MASKf, 0xfff);
  11227     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, &entry0, MAC_ADDR_MASKf,
  11228                          mac_mask);
  11229     mask0 = entry0;
  11230     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, VLAN_IDf, 0xfff);
  11231     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, &mask0, MAC_ADDRf, mac_mask);
  11232 
  11233     if (soc_mem_field_valid(unit, mem, SOURCE_FIELDf)) {
  11234         if (SOC_IS_KATANAX(unit)) {
  11235             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, SOURCE_TYPEf, 1);
  11236             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, 
  11237                             SOURCE_TYPE_MASKf, 1);             
  11238         }
  11239         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, SOURCE_FIELDf,
  11240                             port_mask);
  11241         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, SOURCE_FIELD_MASKf,
  11242                             port_mask);
  11243     } else {
  11244         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, ING_PORT_NUMf,
  11245                             port_mask);
  11246         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, ING_PORT_NUM_MASKf,
  11247                             port_mask);
  11248     }
  11249     if (alt_index != NULL) {
  11250         entry1 = entry0;
  11251         mask1 = mask0;
  11252     }
  11253 
  11254     if (port == -1) {
  11255         start = soc_mem_index_max(unit, mem);
  11256         end = -1;
  11257         step = -1;
  11258     } else {
  11259         if (soc_mem_field_valid(unit, mem, SOURCE_FIELDf)) {
  11260             if (SOC_IS_KATANAX(unit)) {
  11261                 if ((1 << SOC_TRUNK_BIT_POS(unit)) & port){
  11262                     /* trunk */
  11263                     if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) {  
  11264                         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, 
  11265                                         SOURCE_TYPEf, 1);
  11266                         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, 
  11267                                         SOURCE_TYPE_MASKf, 1);  
  11268                         port &= ~(1 << (SOC_TRUNK_BIT_POS(unit)));
  11269                     }    
  11270                 }            
  11271             }
  11272             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, SOURCE_FIELDf, port);
  11273             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0,
  11274                             SOURCE_FIELD_MASKf, port_mask);
  11275             
  11276         } else {
  11277             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, ING_PORT_NUMf, port);
  11278             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0,
  11279                             ING_PORT_NUM_MASKf, port_mask);
  11280         }
  11281         start = 0;
  11282         end = soc_mem_index_count(unit, mem);
  11283         step = 1;
  11284     }
  11285 
  11286     if (alt_index != NULL) {
  11287         if (port == -1) {
  11288             if (soc_mem_field_valid(unit, mem, SOURCE_FIELDf)) {
  11289                 if (SOC_IS_KATANAX(unit)) 
  11290                 {
  11291                     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask1, SOURCE_TYPEf,
  11292                                         0);              
  11293                 }
  11294                 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask1, SOURCE_FIELDf,
  11295                                     0);
  11296             } else {      
  11297                 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask1, ING_PORT_NUMf,
  11298                                     0);
  11299             }
  11300         }
  11301 
  11302         /* entry2 is for checking VALID bit */
  11303         sal_memset(&entry2, 0, sizeof(entry2));
  11304         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry2, VALIDf,
  11305             (1 << soc_mem_field_length(unit, MY_STATION_TCAMm, VALIDf)) - 1);
  11306     }
  11307 
  11308     index1 = -1;
  11309     free_index = -1;
  11310     for (index0 = start; index0 != end; index0 += step) {
  11311         /* Skip the entry that we want to move (we know it matches) */
  11312         if (index0 == index_to_skip) {
  11313             continue;
  11314         }
  11315 
  11316         entry = &my_station_shadow[index0];
  11317 
  11318         /* Try matching target entry */
  11319         for (i = 0; i < entry_words; i++) {
  11320             if ((entry->entry_data[i] ^ entry0.entry_data[i]) &
  11321                 mask0.entry_data[i]) {
  11322                 break;
  11323             }
  11324         }
  11325         if (i == entry_words) {
  11326             /* Target entry is found, no more action needed */
  11327             *entry_index = index0;
  11328             LOG_INFO(BSL_LS_BCM_L2,
  11329                      (BSL_META_U(unit,
  11330                                  "_bcm_td_my_station_lookup: found entry_index=%d\n"),
  11331                       *entry_index));
  11332             return BCM_E_NONE;
  11333         }
  11334 
  11335         if (alt_index == NULL) { /* lookup only */
  11336             continue;
  11337         }
  11338 
  11339         /* Keep track index of the first free entry */
  11340         if (free_index == -1) {
  11341             for (i = 0; i < entry_words; i++) {
  11342                 if (entry->entry_data[i] & entry2.entry_data[i]) {
  11343                     break;
  11344                 }
  11345             }
  11346             if (i == entry_words) {
  11347                 if (index1 != -1) {
  11348                     /* Both free entry and alternate entry are found */
  11349                     *entry_index = index0;
  11350                     *alt_index = index1;
  11351                     LOG_INFO(BSL_LS_BCM_L2,
  11352                              (BSL_META_U(unit,
  11353                                          "_bcm_td_my_station_lookup: not found "
  11354                                          "entry_index=%d alt_index=%d\n"),
  11355                               *entry_index, *alt_index));
  11356                     return BCM_E_NOT_FOUND;
  11357                 } else {
  11358                     free_index = index0;
  11359                     continue;
  11360                 }
  11361             }
  11362         }
  11363 
  11364         /* Try matching alternate entry. If alternate entry is found, it
  11365          * implies target entry is not in the table */
  11366         for (i = 0; i < entry_words; i++) {
  11367             if ((entry->entry_data[i] ^ entry1.entry_data[i]) &
  11368                 mask1.entry_data[i]) {
  11369                 break;
  11370             }
  11371         }
  11372         if (i == entry_words) {
  11373             if (free_index != -1) {
  11374                 /* both free entry and alternate entry are found */
  11375                 *entry_index = free_index;
  11376                 *alt_index = index0;
  11377                 LOG_INFO(BSL_LS_BCM_L2,
  11378                          (BSL_META_U(unit,
  11379                                      "_bcm_td_my_station_lookup: not found "
  11380                                      "entry_index=%d alt_index=%d\n"),
  11381                           *entry_index, *alt_index));
  11382                 return BCM_E_NOT_FOUND;
  11383             } else {
  11384                 index1 = index0;
  11385                 continue;
  11386             }
  11387         }
  11388     }
  11389 
  11390     *entry_index = free_index;
  11391     if (alt_index != NULL) {
  11392         *alt_index = index1;
  11393     }
  11394     LOG_INFO(BSL_LS_BCM_L2,
  11395              (BSL_META_U(unit,
  11396                          "_bcm_td_my_station_lookup: not found "
  11397                          "entry_index=%d alt_index=%d\n"),
  11398               *entry_index, alt_index != NULL ? *alt_index : -100));
  11399 
  11400     return BCM_E_NOT_FOUND;
  11401 }
  11402 
  11403 /*
  11404  * Function:
  11405  *     bcm_td_l2_myStation_add
  11406  * Purpose:
  11407  *     Add MY_STATION_TCAM entry by L2 API
  11408  * Parameters:
  11409  *     unit              Unit number
  11410  *     l2addr            L2 API data structure
  11411  */
  11412 STATIC int
  11413 bcm_td_l2_myStation_insert(int unit, int tcam_no, bcm_l2_addr_t *l2addr)
  11414 {
  11415     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  11416     int rv, rv1, index, alt_index;
  11417     my_station_tcam_entry_t *entry;
  11418     my_station_profile_1_entry_t entry_prof;
  11419     uint32 old_pid = 0, new_pid;
  11420 #if defined(BCM_TRIDENT_SUPPORT)
  11421     l2u_entry_t l2u_entry;
  11422 #endif
  11423     soc_mem_t mem = MY_STATION_TCAMm;
  11424     my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow;
  11425     int proft = 0;
  11426 
  11427     if (tcam_no == 2) {
  11428         mem = MY_STATION_TCAM_2m;
  11429         my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow;
  11430         proft = 1;
  11431     }
  11432 
  11433     VLAN_CHK_ID(unit, l2addr->vid);
  11434 
  11435     soc_mem_lock(unit, mem);
  11436 
  11437     rv = _bcm_td_my_station_lookup(unit, mem, l2addr->mac, l2addr->vid, -1, -1,
  11438                                    &index, &alt_index);
  11439     if (BCM_SUCCESS(rv)) {
  11440 #if defined(BCM_TRIDENT_SUPPORT)
  11441         if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) {
  11442             /* Check if the entry is not added by l2cache API */
  11443             if (BCM_SUCCESS(soc_l2u_get(unit, &l2u_entry, index))) {
  11444             if ((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) &&
  11445                  soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) ||
  11446                 (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) &&
  11447                  soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry,
  11448                                  RESERVED_0f))) {
  11449                 soc_mem_unlock(unit, mem);
  11450                 return BCM_E_EXISTS;
  11451             }
  11452         }
  11453         }
  11454 #endif
  11455         /* Entry exist, update the entry */
  11456         entry = &my_station_shadow[index];
  11457         if (soc_feature(unit, soc_feature_mysta_profile)) {
  11458             uint32 dest_type;
  11459             old_pid = soc_mem_field32_dest_get(unit, mem, entry,
  11460                                     DESTINATIONf, &dest_type);
  11461             if (dest_type == SOC_MEM_FIF_DEST_MYSTA) {
  11462                 rv1 = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, proft,
  11463                                                       old_pid);
  11464             } else {
  11465                 rv1 = BCM_E_FAIL;
  11466             }
  11467             if (BCM_FAILURE(rv1)) {
  11468                 soc_mem_unlock(unit, mem);
  11469                 return rv1;
  11470             }
  11471         }
  11472         _bcm_td_l2_to_my_station(unit, tcam_no, entry, &entry_prof, l2addr, FALSE);
  11473         if (soc_feature(unit, soc_feature_mysta_profile)) {
  11474             if (proft == 1) {
  11475                 bcm_l2_station_t station;
  11476                 sal_memset(&station, 0, sizeof(bcm_l2_station_t));
  11477                 station.flags = BCM_L2_STATION_MPLS | BCM_L2_STATION_IPV4 | BCM_L2_STATION_IPV6 |
  11478                             BCM_L2_STATION_ARP_RARP;
  11479                 _bcm_l2_mysta_station_to_entry(unit, &station, MY_STATION_PROFILE_2m, &entry_prof);
  11480             }
  11481 
  11482             rv1 = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid);
  11483             LOG_INFO(BSL_LS_BCM_L2,
  11484                      (BSL_META_U(unit,
  11485                                  "_bcm_td_my_station_insert: added proft %d new %d\n"),
  11486                       proft, new_pid));
  11487             if (BCM_SUCCESS(rv1)) {
  11488                 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf,
  11489                                          SOC_MEM_FIF_DEST_MYSTA, new_pid);
  11490             LOG_INFO(BSL_LS_BCM_L2,
  11491                      (BSL_META_U(unit,
  11492                                  "_bcm_td_my_station_insert: found proft %d old %d new %d\n"),
  11493                       proft, old_pid, new_pid));
  11494                 if (old_pid != new_pid)
  11495                      rv1 = _bcm_l2_mysta_profile_entry_delete(unit, proft, old_pid);
  11496             }
  11497             if (BCM_FAILURE(rv1)) {
  11498                 soc_mem_unlock(unit, mem);
  11499                 return rv1;
  11500             }
  11501         }
  11502         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry);
  11503 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  11504         if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) {
  11505             info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32);
  11506         }
  11507 #if defined(BCM_TRIDENT3_SUPPORT)
  11508         else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){
  11509             info->my_station2_shadow_mask->buf[index/32] |= 1<<(index%32);
  11510         }
  11511 #endif
  11512 #endif
  11513     } else if (rv == BCM_E_NOT_FOUND && index == -1) {
  11514         /* No free entry available for insertion */
  11515         rv = BCM_E_FULL;
  11516     }
  11517     if (rv != BCM_E_NOT_FOUND) {
  11518         soc_mem_unlock(unit, mem);
  11519         return rv;
  11520     }
  11521 
  11522     if (alt_index > index) {
  11523         /* Free entry is available for new entry insertion and alternate entry
  11524          * exists. However need to swap these 2 entries to maintain proper
  11525          * lookup precedence */
  11526         my_station_shadow[index] = my_station_shadow[alt_index];
  11527         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index,
  11528                            &my_station_shadow[index]);
  11529         if (BCM_FAILURE(rv)) {
  11530             soc_mem_unlock(unit, mem);
  11531             return rv;
  11532         }
  11533 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  11534         if (mem == MY_STATION_TCAMm) {
  11535             info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32);
  11536         }
  11537 #if defined(BCM_TRIDENT3_SUPPORT)
  11538         else if (mem == MY_STATION_TCAM_2m){
  11539             info->my_station2_shadow_mask->buf[index/32] |= 1<<(index%32);
  11540         }
  11541 #endif
  11542 #endif
  11543         index = alt_index;
  11544     }
  11545 
  11546     /* Add the new entry */
  11547     entry = &my_station_shadow[index];
  11548     sal_memset(entry, 0, sizeof(*entry));
  11549     sal_memset(&entry_prof, 0, sizeof(entry_prof));
  11550     _bcm_td_l2_to_my_station(unit, tcam_no, entry, &entry_prof, l2addr, TRUE);
  11551     if (soc_feature(unit, soc_feature_mysta_profile)) {
  11552         if (proft == 1) {
  11553             bcm_l2_station_t station;
  11554             sal_memset(&station, 0, sizeof(bcm_l2_station_t));
  11555             station.flags = BCM_L2_STATION_MPLS | BCM_L2_STATION_IPV4 | BCM_L2_STATION_IPV6 |
  11556                             BCM_L2_STATION_ARP_RARP;
  11557             _bcm_l2_mysta_station_to_entry(unit, &station, MY_STATION_PROFILE_2m, &entry_prof);
  11558         }
  11559 
  11560         rv1 = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid);
  11561         if (BCM_SUCCESS(rv1)) {
  11562             soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf,
  11563                                      SOC_MEM_FIF_DEST_MYSTA, new_pid);
  11564         } else {
  11565             soc_mem_unlock(unit, mem);
  11566             return rv1;
  11567         }
  11568     }
  11569     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry);
  11570 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  11571     if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) {
  11572         info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32);
  11573     }
  11574 #if defined(BCM_TRIDENT3_SUPPORT)
  11575     else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){
  11576         info->my_station2_shadow_mask->buf[index/32] |= 1<<(index%32);
  11577     }
  11578 #endif
  11579 #endif
  11580 
  11581     soc_mem_unlock(unit, mem);
  11582     return rv;
  11583 }
  11584 
  11585 
  11586 int
  11587 bcm_td_l2_myStation_add(int unit, bcm_l2_addr_t *l2addr)
  11588 {
  11589     int rv;
  11590 
  11591     if (soc_feature(unit, soc_feature_riot) ||
  11592                  (SOC_IS_TRIDENT3X(unit)  && (l2addr->flags & BCM_L2_L3LOOKUP))) {
  11593         rv = bcm_td_l2_myStation_insert(unit, 2, l2addr);
  11594         if (SOC_IS_TRIDENT3X(unit)) {
  11595             /* In TD3 MY_STATION TCAMS have  two times capacity and
  11596                can handle this */
  11597             rv = bcm_td_l2_myStation_insert(unit, 1, l2addr);
  11598         }
  11599     } else {
  11600         rv = bcm_td_l2_myStation_insert(unit, 1, l2addr);
  11601     }
  11602     return rv;
  11603 }
  11604 
  11605 
  11606 /*
  11607  * Function:
  11608  *     bcm_td_l2_myStation_delete
  11609  * Purpose:
  11610  *     Delete MY_STATION_TCAM entry added by L2 API
  11611  * Parameters:
  11612  *     unit              Unit number
  11613  *     mac               MAC address
  11614  *     vlan              VLAN ID
  11615  */
  11616 int
  11617 bcm_td_l2_myStation_delete_entry(int unit, int tcam_no, bcm_mac_t mac, bcm_vlan_t vlan,
  11618                            int *l2_index)
  11619 {
  11620     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  11621     int rv = BCM_E_NONE, index, i, entry_words, old_pid = 0;
  11622     uint32 *entry;
  11623 #if defined(BCM_TRIDENT_SUPPORT)
  11624     l2u_entry_t l2u_entry;
  11625 #endif
  11626     uint32 *l3_mask, *tunnel_mask;
  11627     soc_mem_t mem = MY_STATION_TCAMm;
  11628     soc_memacc_t **memacc_list = NULL;
  11629     my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow;
  11630     int proft = 0;
  11631     my_station_profile_1_entry_t entry_prof;
  11632 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  11633     int delete_flag = 0;
  11634 #endif
  11635 
  11636     VLAN_CHK_ID(unit, vlan);
  11637 
  11638     l3_mask = info->my_station_l3_mask;
  11639     tunnel_mask = info->my_station_tunnel_mask;
  11640     entry_words = soc_mem_entry_words(unit, mem);
  11641 
  11642     if (tcam_no == 2) {
  11643         mem = MY_STATION_TCAM_2m;
  11644         my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow;
  11645         l3_mask = info->my_station2_l3_mask.entry_data;
  11646         tunnel_mask = info->my_station2_tunnel_mask.entry_data;
  11647         proft = 1;
  11648         if (soc_feature(unit, soc_feature_mysta_profile)) {
  11649             soc_mem_field32_set(unit, MY_STATION_PROFILE_2m, tunnel_mask,
  11650                                  MPLS_TERMINATION_ALLOWEDf, 0);
  11651         }
  11652 
  11653     }
  11654 
  11655     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  11656 
  11657     soc_mem_lock(unit, mem);
  11658 
  11659     rv = _bcm_td_my_station_lookup(unit, mem, mac, vlan, -1, -1, &index, NULL);
  11660     if (BCM_FAILURE(rv)) {
  11661         soc_mem_unlock(unit, mem);
  11662         return rv;
  11663     }
  11664 
  11665     entry = (uint32 *)&my_station_shadow[index];
  11666 
  11667     if (soc_feature(unit, soc_feature_mysta_profile)) {
  11668         uint32 dest_type;
  11669         old_pid = soc_mem_field32_dest_get(unit, mem, entry,
  11670                                            DESTINATIONf, &dest_type);
  11671         if (dest_type != SOC_MEM_FIF_DEST_MYSTA) {
  11672             soc_mem_unlock(unit, mem);
  11673             return BCM_E_NOT_FOUND;
  11674         }
  11675 
  11676         rv = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, proft, old_pid);
  11677         if (BCM_FAILURE(rv)) {
  11678             soc_mem_unlock(unit, mem);
  11679             return rv;
  11680         }
  11681         entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m);
  11682         entry = entry_prof.entry_data;
  11683     }
  11684 
  11685         /* Check if the entry has L3 related flag enabled */
  11686         for (i = 0; i < entry_words; i++) {
  11687         if (entry[i] & l3_mask[i]) {
  11688                 break;
  11689             }
  11690         }
  11691         if (i == entry_words) {
  11692             soc_mem_unlock(unit, mem);
  11693             return BCM_E_NOT_FOUND;
  11694         }
  11695 
  11696 #if defined(BCM_TRIDENT_SUPPORT)
  11697 
  11698         if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) {
  11699             /* Check if the entry is not added by l2cache API */
  11700             if (BCM_SUCCESS(soc_l2u_get(unit, &l2u_entry, index))) {
  11701             if ((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) &&
  11702                  soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) ||
  11703                 (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) &&
  11704                  soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry,
  11705                                  RESERVED_0f))) {
  11706                 soc_mem_unlock(unit, mem);
  11707                 return BCM_E_NOT_FOUND;
  11708             }
  11709         }
  11710         }
  11711 #endif
  11712         /* Check to see if we need to delete or modify the entry */
  11713         for (i = 0; i < entry_words; i++) {
  11714         if (entry[i] & tunnel_mask[i]) {
  11715                 break;
  11716             }
  11717         }
  11718         if (i == entry_words) {
  11719         if (soc_feature(unit, soc_feature_mysta_profile)) {
  11720             rv = _bcm_l2_mysta_profile_entry_delete(unit, proft, old_pid);
  11721         }
  11722             /* Delete the entry if no tunnel related flag is enabled */
  11723         entry = (uint32 *)&my_station_shadow[index];
  11724         sal_memset(entry, 0, sizeof(my_station_tcam_entry_t));
  11725 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  11726         delete_flag = 1;
  11727 #endif
  11728         } else {
  11729             /* Modify the entry if any tunnel related flag is enabled */
  11730             for (i = 0; i < entry_words; i++) {
  11731             entry[i] &= ~l3_mask[i];
  11732         }
  11733         entry = (uint32 *)&my_station_shadow[index];
  11734         if (soc_feature(unit, soc_feature_mysta_profile)) {
  11735             uint32 new_pid;
  11736             rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid);
  11737             if (BCM_SUCCESS(rv)) {
  11738                 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf,
  11739                                          SOC_MEM_FIF_DEST_MYSTA, new_pid);
  11740                 rv = _bcm_l2_mysta_profile_entry_delete(unit, proft, old_pid);
  11741             }
  11742             }
  11743             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, DISCARDf, 0);
  11744             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, COPY_TO_CPUf,
  11745                                 0);
  11746         }
  11747 
  11748     if (BCM_SUCCESS(rv)) {
  11749         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry);
  11750 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  11751         if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm) && delete_flag) {
  11752             info->my_station_shadow_mask->buf[index/32] &= ~(1<<(index%32));
  11753         }
  11754 #if defined(BCM_TRIDENT3_SUPPORT)
  11755         else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m) && delete_flag){
  11756             info->my_station2_shadow_mask->buf[index/32] &= ~(1<<(index%32));
  11757         }
  11758 #endif
  11759 #endif
  11760     }
  11761 
  11762     soc_mem_unlock(unit, mem);
  11763     return rv;
  11764 }
  11765 
  11766 int
  11767 bcm_td_l2_myStation_delete(int unit, bcm_mac_t mac, bcm_vlan_t vlan,
  11768                            int *l2_index)
  11769 {
  11770     int rv = BCM_E_NONE;
  11771     if (soc_feature(unit, soc_feature_riot)  ||
  11772                   (SOC_IS_TRIDENT3X(unit))) {
  11773         rv = bcm_td_l2_myStation_delete_entry(unit, 2, mac, vlan, l2_index);
  11774         if (SOC_IS_TRIDENT3X(unit)) {
  11775             rv = bcm_td_l2_myStation_delete_entry(unit, 1, mac, vlan, l2_index);
  11776         }
  11777     } else {
  11778         rv =  bcm_td_l2_myStation_delete_entry(unit, 1, mac, vlan, l2_index);
  11779     }
  11780     return rv;
  11781 }
  11782 
  11783 /*
  11784  * Function:
  11785  *     bcm_td_l2_myStation_get
  11786  * Purpose:
  11787  *     Get MY_STATION_TCAM entry added by L2 API
  11788  * Parameters:
  11789  *     unit              Unit number
  11790  *     mac               MAC address
  11791  *     vlan              VLAN ID
  11792  */
  11793 int
  11794 bcm_td_l2_myStation_get(int unit, bcm_mac_t mac, bcm_vlan_t vlan,
  11795                         bcm_l2_addr_t *l2addr)
  11796 {
  11797     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  11798     int index, i, entry_words;
  11799     uint32 old_pid = 0;
  11800     uint32 *entry;
  11801 #if defined(BCM_TRIDENT_SUPPORT)
  11802     l2u_entry_t l2u_entry;
  11803 #endif
  11804     uint32 *l3_mask;
  11805     soc_mem_t mem = MY_STATION_TCAMm;
  11806     my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow;
  11807     my_station_profile_1_entry_t entry_prof;
  11808     int proft = 0;
  11809     int rv = BCM_E_NONE;
  11810 
  11811     VLAN_CHK_ID(unit, vlan);
  11812 
  11813     l3_mask = info->my_station_l3_mask;
  11814 
  11815     if (soc_feature(unit, soc_feature_riot) ||
  11816             (SOC_IS_TRIDENT3X(unit))) {
  11817 
  11818         mem = MY_STATION_TCAM_2m;
  11819         my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow;
  11820         l3_mask = info->my_station2_l3_mask.entry_data;
  11821         proft = 1;
  11822     }
  11823 
  11824     entry_words = soc_mem_entry_words(unit, mem);
  11825 
  11826     rv = _bcm_td_my_station_lookup(unit, mem, mac, vlan, -1, -1, &index, NULL);
  11827 
  11828     if ((rv == BCM_E_NOT_FOUND) && (SOC_IS_TRIDENT3X(unit))) {
  11829         mem = MY_STATION_TCAMm;
  11830         BCM_IF_ERROR_RETURN(
  11831             _bcm_td_my_station_lookup(unit, mem, mac, vlan, -1, -1, &index, NULL));
  11832         my_station_shadow = (my_station_tcam_entry_t *)info->my_station_shadow;
  11833         l3_mask = info->my_station_l3_mask;
  11834         proft = 0;
  11835     } else if (rv != BCM_E_NONE) {
  11836         return rv;
  11837     }
  11838 
  11839     entry = (uint32 *)&my_station_shadow[index];
  11840 
  11841     if (soc_feature(unit, soc_feature_mysta_profile)) {
  11842         uint32 dest_type;
  11843         old_pid = soc_mem_field32_dest_get(unit, mem, entry,
  11844                                            DESTINATIONf, &dest_type);
  11845         if (dest_type != SOC_MEM_FIF_DEST_MYSTA) {
  11846             return BCM_E_NOT_FOUND;
  11847         }
  11848 
  11849         BCM_IF_ERROR_RETURN(
  11850             _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, proft, old_pid));
  11851         entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m);
  11852         entry = entry_prof.entry_data;
  11853     }
  11854 
  11855     /* Check if the entry has L3 related flag enabled */
  11856     for (i = 0; i < entry_words; i++) {
  11857         if (entry[i] & l3_mask[i]) {
  11858             break;
  11859         }
  11860     }
  11861     if (i == entry_words) {
  11862         return BCM_E_NOT_FOUND;
  11863     }
  11864 
  11865 #if defined(BCM_TRIDENT_SUPPORT)
  11866     if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) {
  11867         /* Check if the entry is not added by l2cache API */
  11868         if (BCM_SUCCESS(soc_l2u_get(unit, &l2u_entry, index))) {
  11869         if ((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) &&
  11870              soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) ||
  11871             (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) &&
  11872              soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry,
  11873                              RESERVED_0f))) {
  11874             return BCM_E_NOT_FOUND;
  11875         }
  11876     }
  11877     }
  11878 #endif
  11879 
  11880     _bcm_td_l2_from_my_station(unit, l2addr, &my_station_shadow[index],
  11881                                &entry_prof);
  11882 
  11883     return BCM_E_NONE;
  11884 }
  11885 
  11886 /*
  11887  * Function:
  11888  *     bcm_td_l2cache_myStation_set
  11889  * Purpose:
  11890  *     Add MY_STATION_TCAM entry from L2 cache API
  11891  * Parameters:
  11892  *     unit              Unit number
  11893  *     index             Index
  11894  *     l2caddr           L2 cache API data structure
  11895  */
  11896 int
  11897 bcm_td_l2cache_myStation_set(int unit, int index, bcm_l2_cache_addr_t *l2caddr)
  11898 {
  11899     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  11900     soc_mem_t mem = MY_STATION_TCAMm;
  11901     int rv, entry_index, alt_index;
  11902     my_station_tcam_entry_t *entry;
  11903     my_station_profile_1_entry_t entry_prof;
  11904     uint32 new_pid = 0;
  11905 #if defined(BCM_TRIDENT_SUPPORT)
  11906     l2u_entry_t l2u_entry;
  11907 #endif
  11908     bcm_vlan_t vlan;
  11909     bcm_mac_t mac;
  11910     bcm_port_t port;
  11911     soc_memacc_t **memacc_list = NULL;
  11912     my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow;
  11913     int proft = 0;
  11914 
  11915     if (soc_feature(unit, soc_feature_riot) ||
  11916         (SOC_IS_TRIDENT3X(unit)  && (l2caddr->flags & BCM_L2_CACHE_L3))) {
  11917         mem = MY_STATION_TCAM_2m;
  11918         my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow;
  11919         proft = 1;
  11920     }
  11921 
  11922     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  11923 
  11924 
  11925     VLAN_CHK_ID(unit, l2caddr->vlan);
  11926 
  11927     soc_mem_lock(unit, mem);
  11928 
  11929     entry_index = -1;
  11930     entry = &my_station_shadow[index];
  11931     if (!_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VALIDf)) {
  11932         /* Entry is not in used */
  11933         entry_index = index;
  11934     } else {
  11935 #if defined(BCM_TRIDENT_SUPPORT)
  11936         if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) {
  11937             /* Check if the existing entry is added by l2cache API */
  11938             rv = soc_l2u_get(unit, &l2u_entry, index);
  11939             if (BCM_SUCCESS(rv) &&
  11940                 ((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) &&
  11941                   soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) ||
  11942                  (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) &&
  11943                   soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry,
  11944                                   RESERVED_0f)))) {
  11945                 entry_index = index;
  11946             }
  11947         }
  11948 #endif
  11949     }
  11950     if (entry_index != -1) {
  11951         /* The entry is not used by API other than l2cache */
  11952         sal_memset(entry, 0, sizeof(*entry));
  11953         sal_memset(&entry_prof, 0, sizeof(entry_prof));
  11954         _bcm_td_l2cache_to_my_station(unit, entry, &entry_prof, l2caddr);
  11955 
  11956         if (soc_feature(unit, soc_feature_mysta_profile)) {
  11957             rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid);
  11958             if (BCM_FAILURE(rv)) {
  11959                 soc_mem_unlock(unit, mem);
  11960                 return rv;
  11961             }
  11962             soc_mem_field32_dest_set(unit, mem, entry,
  11963                 DESTINATIONf, SOC_MEM_FIF_DEST_MYSTA, new_pid);
  11964         }
  11965         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index,
  11966                            entry);
  11967 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  11968         if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) {
  11969             info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32);
  11970         }
  11971 #if defined(BCM_TRIDENT3_SUPPORT)
  11972         else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){
  11973             info->my_station2_shadow_mask->buf[index/32] |= 1<<(index%32);
  11974         }
  11975 #endif
  11976 #endif
  11977         soc_mem_unlock(unit, mem);
  11978         return rv;
  11979     }
  11980 
  11981     /* Need to move the current entry */
  11982     vlan = _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VLAN_IDf);
  11983     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(unit, memacc_list, entry, MAC_ADDRf, mac);
  11984     if (soc_feature(unit, soc_feature_gh2_my_station)) {
  11985         if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry,
  11986                                 SOURCE_FIELD_MASKf) == 0) {
  11987             port = -1;
  11988         } else {
  11989             port = _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry,
  11990                                        SOURCE_FIELDf);
  11991         }
  11992 
  11993     } else {
  11994     if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry,
  11995                             ING_PORT_NUM_MASKf) == 0) {
  11996         port = -1;
  11997     } else {
  11998         port = _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry,
  11999                                    ING_PORT_NUMf);
  12000     }
  12001     }
  12002     rv = _bcm_td_my_station_lookup(unit, mem, mac, vlan, port, index, &entry_index,
  12003                                    &alt_index);
  12004     if (rv == BCM_E_NOT_FOUND && entry_index == -1) {
  12005         /* No free entry available for insertion */
  12006         rv = BCM_E_FULL;
  12007     }
  12008     if (rv != BCM_E_NOT_FOUND) {
  12009         soc_mem_unlock(unit, mem);
  12010         return rv;
  12011     }
  12012 
  12013     if (alt_index != -1 &&
  12014         ((port == -1 && alt_index > entry_index) ||
  12015          (port != -1 && alt_index < entry_index))) {
  12016         /* Free entry is available for moving the target entry and alternate
  12017          * entry exists. However need to swap these 2 entries to maintain
  12018          * proper lookup precedence */
  12019         my_station_shadow[entry_index] =
  12020             my_station_shadow[alt_index];
  12021         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, entry_index,
  12022                            &my_station_shadow[entry_index]);
  12023 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12024         if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) {
  12025             info->my_station_shadow_mask->buf[entry_index/32] |= 1<<(entry_index%32);
  12026         }
  12027 #if defined(BCM_TRIDENT3_SUPPORT)
  12028         else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){
  12029             info->my_station2_shadow_mask->buf[entry_index/32] |= 1<<(entry_index%32);
  12030         }
  12031 #endif
  12032 #endif
  12033         if (BCM_FAILURE(rv)) {
  12034             soc_mem_unlock(unit, mem);
  12035             return rv;
  12036         }
  12037         entry_index = alt_index;
  12038     }
  12039 
  12040     /* Move the entry at specified index to the available free location */
  12041     my_station_shadow[entry_index] = *entry;
  12042     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, entry_index,
  12043                        entry);
  12044 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12045     if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) {
  12046         info->my_station_shadow_mask->buf[entry_index/32] |= 1<<(entry_index%32);
  12047     }
  12048 #if defined(BCM_TRIDENT3_SUPPORT)
  12049     else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){
  12050         info->my_station2_shadow_mask->buf[entry_index/32] |= 1<<(entry_index%32);
  12051     }
  12052 #endif
  12053 #endif
  12054     if (BCM_FAILURE(rv)) {
  12055         soc_mem_unlock(unit, mem);
  12056         return rv;
  12057     }
  12058 
  12059     /* Add the new entry */
  12060     sal_memset(entry, 0, sizeof(*entry));
  12061     sal_memset(&entry_prof, 0, sizeof(entry_prof));
  12062     _bcm_td_l2cache_to_my_station(unit, entry, &entry_prof, l2caddr);
  12063     if (soc_feature(unit, soc_feature_mysta_profile)) {
  12064         rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid);
  12065         if (BCM_FAILURE(rv)) {
  12066             soc_mem_unlock(unit, mem);
  12067             return rv;
  12068         }
  12069         soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf,
  12070                                  SOC_MEM_FIF_DEST_MYSTA, new_pid);
  12071     }
  12072     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index,
  12073                        entry);
  12074 
  12075 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12076     if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) {
  12077         info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32);
  12078     }
  12079 #if defined(BCM_TRIDENT3_SUPPORT)
  12080     else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){
  12081         /* coverity[negative_shift] */
  12082         info->my_station2_shadow_mask->buf[index/32] |= 1<<(index%32);
  12083     }
  12084 #endif
  12085 #endif
  12086     soc_mem_unlock(unit, mem);
  12087     return rv;
  12088 }
  12089 
  12090 /*
  12091  * Function:
  12092  *     bcm_td_l2cache_myStation_get
  12093  * Purpose:
  12094  *     Get MY_STATION_TCAM entry added by L2 cache API
  12095  * Parameters:
  12096  *     unit              Unit number
  12097  *     index             Index
  12098  *     l2caddr           L2 cache API data structure
  12099  */
  12100 static int
  12101 bcm_td_l2cache_myStation_get_entry(int unit, soc_mem_t mem, int index, bcm_l2_cache_addr_t *l2caddr)
  12102 {
  12103     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  12104     int i, entry_words;
  12105     uint32 old_pid = 0;
  12106     uint32 *entry;
  12107 #if defined(BCM_TRIDENT_SUPPORT)
  12108     l2u_entry_t l2u_entry;
  12109 #endif
  12110     uint32 *l3_mask;
  12111     soc_memacc_t **memacc_list = NULL;
  12112     my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow;
  12113     my_station_profile_1_entry_t entry_prof;
  12114     int proft = 0;
  12115 
  12116     l3_mask = info->my_station_l3_mask;
  12117 
  12118     if (mem == MY_STATION_TCAM_2m) {
  12119         my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow;
  12120         l3_mask = info->my_station2_l3_mask.entry_data;
  12121         proft = 1;
  12122     }
  12123 
  12124     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  12125     entry_words = soc_mem_entry_words(unit, mem);
  12126     entry = (uint32 *)&my_station_shadow[index];
  12127 
  12128     /* Check if the entry is valid */
  12129     if (!_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VALIDf)) {
  12130         return BCM_E_NOT_FOUND;
  12131     }
  12132 
  12133     if (soc_feature(unit, soc_feature_mysta_profile)) {
  12134         uint32 dest_type;
  12135         old_pid = soc_mem_field32_dest_get(unit, mem, entry,
  12136                                            DESTINATIONf, &dest_type);
  12137         if (dest_type != SOC_MEM_FIF_DEST_MYSTA) {
  12138             return BCM_E_NOT_FOUND;
  12139         }
  12140 
  12141         BCM_IF_ERROR_RETURN(
  12142             _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, proft, old_pid));
  12143         entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m);
  12144         entry = entry_prof.entry_data;
  12145     }
  12146 
  12147     /* Check if the entry has L3 related flag enabled */
  12148     for (i = 0; i < entry_words; i++) {
  12149         if (entry[i] & l3_mask[i]) {
  12150             break;
  12151         }
  12152     }
  12153     if (i == entry_words) {
  12154         return BCM_E_NOT_FOUND;
  12155     }
  12156 
  12157 #if defined(BCM_TRIDENT_SUPPORT)
  12158     if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) {
  12159         /* Check if the entry is added by l2cache API */
  12160         SOC_IF_ERROR_RETURN(soc_l2u_get(unit, &l2u_entry, index));
  12161         if (!((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) &&
  12162                soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) ||
  12163               (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) &&
  12164                soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry,    
  12165                                RESERVED_0f)))) {
  12166             return BCM_E_NOT_FOUND;
  12167         }
  12168     }
  12169 #endif
  12170 
  12171     _bcm_td_l2cache_from_my_station(unit, l2caddr, &my_station_shadow[index]);
  12172 
  12173     return BCM_E_NONE;
  12174 }
  12175 
  12176 int
  12177 bcm_td_l2cache_myStation_get(int unit, int index, bcm_l2_cache_addr_t *l2caddr)
  12178 {
  12179     int         rv = BCM_E_NONE;
  12180     soc_mem_t mem = MY_STATION_TCAMm;
  12181 
  12182     if (soc_feature(unit, soc_feature_riot) ||
  12183                  (SOC_IS_TRIDENT3X(unit)  && (l2caddr->flags & BCM_L2_CACHE_L3))) {
  12184         mem = MY_STATION_TCAM_2m;
  12185     }
  12186 
  12187     rv = bcm_td_l2cache_myStation_get_entry(unit, mem, index, l2caddr);
  12188 
  12189     if ((rv == BCM_E_NOT_FOUND) && (SOC_IS_TRIDENT3X(unit))) {
  12190         mem = MY_STATION_TCAMm;
  12191         BCM_IF_ERROR_RETURN(
  12192             bcm_td_l2cache_myStation_get_entry(unit, mem, index, l2caddr));
  12193     }
  12194 
  12195     return rv;
  12196 
  12197 }
  12198 
  12199 /*
  12200  * Function:
  12201  *     bcm_td_l2cache_myStation_delete
  12202  * Purpose:
  12203  *     Delete MY_STATION_TCAM entry added by L2 cache API
  12204  * Parameters:
  12205  *     unit              Unit number
  12206  *     index             Index
  12207  */
  12208 static int
  12209 bcm_td_l2cache_myStation_delete_entry(int unit, soc_mem_t mem, int index)
  12210 {
  12211     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  12212     int rv = BCM_E_NONE, i, entry_words, old_pid = 0;
  12213     uint32 *entry;
  12214 #if defined(BCM_TRIDENT_SUPPORT)
  12215     l2u_entry_t l2u_entry;
  12216 #endif
  12217     uint32 *l3_mask, *tunnel_mask;
  12218     soc_memacc_t **memacc_list = NULL;
  12219     int proft = 0;
  12220     my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow;
  12221     my_station_profile_1_entry_t entry_prof;
  12222 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12223     int delete_flag = 0;
  12224 #endif
  12225 
  12226     l3_mask = info->my_station_l3_mask;
  12227     tunnel_mask = info->my_station_tunnel_mask;
  12228 
  12229     if (mem == MY_STATION_TCAM_2m) {
  12230         my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow;
  12231         l3_mask = info->my_station2_l3_mask.entry_data;
  12232         tunnel_mask = info->my_station2_tunnel_mask.entry_data;
  12233         proft = 1;
  12234     }
  12235 
  12236     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  12237     entry_words = soc_mem_entry_words(unit, mem);
  12238 
  12239     soc_mem_lock(unit, mem);
  12240 
  12241     entry = (uint32 *)&my_station_shadow[index];
  12242     /* Check if the entry is valid */
  12243     if (!_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VALIDf)) {
  12244         soc_mem_unlock(unit, mem);
  12245         return BCM_E_NOT_FOUND;
  12246     }
  12247 
  12248     if (soc_feature(unit, soc_feature_mysta_profile)) {
  12249         uint32 dest_type;
  12250         old_pid = soc_mem_field32_dest_get(unit, mem, entry,
  12251                                            DESTINATIONf, &dest_type);
  12252         if (dest_type != SOC_MEM_FIF_DEST_MYSTA) {
  12253             soc_mem_unlock(unit, mem);
  12254             return BCM_E_NOT_FOUND;
  12255         }
  12256 
  12257         rv = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, proft, old_pid);
  12258         if (BCM_FAILURE(rv)) {
  12259             soc_mem_unlock(unit, mem);
  12260             return rv;
  12261         }
  12262         entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m);
  12263         entry = entry_prof.entry_data;
  12264     }
  12265 
  12266     /* Check if the entry has L3 related flag enabled */
  12267     for (i = 0; i < entry_words; i++) {
  12268         if (entry[i] & l3_mask[i]) {
  12269             break;
  12270         }
  12271     }
  12272     if (i == entry_words) {
  12273         soc_mem_unlock(unit, mem);
  12274         return BCM_E_NOT_FOUND;
  12275     }
  12276 
  12277 #if defined(BCM_TRIDENT_SUPPORT)
  12278     if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) {
  12279         if (!soc_feature(unit, soc_feature_my_station_tcam_check)) {
  12280         /* Check if the entry is added by l2cache API */
  12281         SOC_IF_ERROR_RETURN(soc_l2u_get(unit, &l2u_entry, index));
  12282         if (!((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) &&
  12283                soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) ||
  12284               (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) &&
  12285                soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry,
  12286                                RESERVED_0f)))) {
  12287             soc_mem_unlock(unit, mem);
  12288             return BCM_E_NOT_FOUND;
  12289         }
  12290     }
  12291     }
  12292 #endif
  12293     /* Check to see if we need to delete or modify the entry */
  12294     for (i = 0; i < entry_words; i++) {
  12295         if (entry[i] & tunnel_mask[i]) {
  12296             break;
  12297         }
  12298     }
  12299     if (i == entry_words) {
  12300         if (soc_feature(unit, soc_feature_mysta_profile)) {
  12301             rv = _bcm_l2_mysta_profile_entry_delete(unit, proft, old_pid);
  12302         }
  12303         /* Delete the entry if no tunnel related flag is enabled */
  12304         entry = (uint32 *)&my_station_shadow[index];
  12305         sal_memset(entry, 0, sizeof(my_station_tcam_entry_t));
  12306 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12307         delete_flag = 1;
  12308 #endif
  12309     } else {
  12310         /* Modify the entry if any tunnel related flag is enabled */
  12311         for (i = 0; i < entry_words; i++) {
  12312             entry[i] &= ~l3_mask[i];
  12313         }
  12314         entry = (uint32 *)&my_station_shadow[index];
  12315         if (soc_feature(unit, soc_feature_mysta_profile)) {
  12316             uint32 new_pid;
  12317             rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid);
  12318             if (BCM_SUCCESS(rv)) {
  12319                 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf,
  12320                                          SOC_MEM_FIF_DEST_MYSTA, new_pid);
  12321                 rv = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid);
  12322             }
  12323         }
  12324         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, DISCARDf, 0);
  12325         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, COPY_TO_CPUf, 0);
  12326     }
  12327 
  12328     if (BCM_SUCCESS(rv)) {
  12329         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry);
  12330 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12331         if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm) && delete_flag) {
  12332             info->my_station_shadow_mask->buf[index/32] &= ~(1<<(index%32));
  12333         }
  12334 #if defined(BCM_TRIDENT3_SUPPORT)
  12335         else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m) && delete_flag){
  12336             info->my_station2_shadow_mask->buf[index/32] &= ~(1<<(index%32));
  12337         }
  12338 #endif
  12339 #endif
  12340     }
  12341 
  12342     soc_mem_unlock(unit, mem);
  12343     return rv;
  12344 }
  12345 
  12346 int
  12347 bcm_td_l2cache_myStation_delete(int unit, int index)
  12348 {
  12349     soc_mem_t mem = MY_STATION_TCAMm;
  12350     int rv = BCM_E_NONE;
  12351     if (soc_feature(unit, soc_feature_riot) ||
  12352                  (SOC_IS_TRIDENT3X(unit))) {
  12353         mem = MY_STATION_TCAM_2m;
  12354     }
  12355     rv = bcm_td_l2cache_myStation_delete_entry(unit, mem, index);
  12356 
  12357     if (SOC_IS_TRIDENT3X(unit) &&
  12358             (rv == BCM_E_NOT_FOUND)) {
  12359              mem = MY_STATION_TCAMm;
  12360              rv = bcm_td_l2cache_myStation_delete_entry(unit, mem, index);
  12361     }
  12362     return rv;
  12363 
  12364 }
  12365 
  12366 /*
  12367  * Function:
  12368  *     bcm_td_l2cache_myStation_lookup
  12369  * Purpose:
  12370  *     Search MY_STATION_TCAM for entry added by L2 cache API
  12371  * Parameters:
  12372  *     unit              Unit number
  12373  *     l2caddr           L2 cache API data structure
  12374  *     result_index      Index
  12375  */
  12376 int
  12377 bcm_td_l2cache_myStation_lookup(int unit, bcm_l2_cache_addr_t *l2caddr,
  12378                              int *result_index)
  12379 {
  12380     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  12381     int index, i, num_entries, prof_num_entries = 0;
  12382     int entry_words, entry_prof_words = 0;
  12383     my_station_tcam_entry_t *entry, entry0, mask0;
  12384     my_station_profile_1_entry_t entry_prof, entry0_prof, mask0_prof;
  12385     uint32 *l3_mask;
  12386     bcm_mac_t mac_mask;
  12387     uint32 port_mask;
  12388     soc_mem_t mem = MY_STATION_TCAMm;
  12389     soc_memacc_t **memacc_list = NULL;
  12390     my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow;
  12391 
  12392     l3_mask = info->my_station_l3_mask;
  12393 
  12394     if (soc_feature(unit, soc_feature_riot) ||
  12395                  (SOC_IS_TRIDENT3X(unit)  && (l2caddr->flags & BCM_L2_CACHE_L3))) {
  12396         mem = MY_STATION_TCAM_2m;
  12397         my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow;
  12398         l3_mask = info->my_station2_l3_mask.entry_data;
  12399     }
  12400 
  12401     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  12402 
  12403 
  12404     sal_memset(&mac_mask, 0xff, sizeof(mac_mask));
  12405     if (soc_feature(unit, soc_feature_gh2_my_station)) {
  12406         port_mask =
  12407             (1 << soc_mem_field_length(unit, mem, SOURCE_FIELDf)) - 1;
  12408     } else {
  12409     port_mask =
  12410         (1 << soc_mem_field_length(unit, mem, ING_PORT_NUMf)) - 1;
  12411     }
  12412 
  12413     num_entries = soc_mem_index_count(unit, mem);
  12414     entry_words = soc_mem_entry_words(unit, mem);
  12415 
  12416     sal_memset(&entry0, 0, sizeof(entry0));
  12417     sal_memset(&entry0_prof, 0, sizeof(entry0_prof));
  12418     _bcm_td_l2cache_to_my_station(unit, &entry0, &entry0_prof, l2caddr);
  12419 
  12420     sal_memset(&mask0, 0, sizeof(mask0));
  12421     sal_memset(&mask0_prof, 0, sizeof(mask0_prof));
  12422     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, VALIDf,
  12423         (1 << soc_mem_field_length(unit, mem, VALIDf)) - 1);
  12424     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, VLAN_IDf,
  12425                         l2caddr->vlan_mask);
  12426     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, &mask0, MAC_ADDRf,
  12427                          l2caddr->mac_mask);
  12428     if (soc_feature(unit, soc_feature_gh2_my_station)) {
  12429         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0,
  12430                             SOURCE_FIELDf, l2caddr->src_port_mask);
  12431         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0,
  12432                             SOURCE_FIELD_MASKf, port_mask);
  12433     } else {
  12434         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0,
  12435                             ING_PORT_NUMf, l2caddr->src_port_mask);
  12436         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0,
  12437                             ING_PORT_NUM_MASKf, port_mask);
  12438     }
  12439     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, VLAN_ID_MASKf, 0xfff);
  12440     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, &mask0, MAC_ADDR_MASKf,
  12441                          mac_mask);
  12442 
  12443     if (soc_feature(unit, soc_feature_mysta_profile)) {
  12444         entry_prof_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m);
  12445         prof_num_entries = soc_mem_index_count(unit, MY_STATION_PROFILE_1m);
  12446         for (i = 0; i < entry_prof_words; i++) {
  12447             mask0_prof.entry_data[i] |= l3_mask[i];
  12448         }
  12449     } else {
  12450     for (i = 0; i < entry_words; i++) {
  12451         mask0.entry_data[i] |= l3_mask[i];
  12452     }
  12453     }
  12454 
  12455     /* Check profile table first */
  12456     if (soc_feature(unit, soc_feature_mysta_profile)) {
  12457         int rv;
  12458         uint32 prof_id = 0xffffffff;
  12459         for (index = 0; index < prof_num_entries; index ++) {
  12460             rv = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, 0, index);
  12461             if (rv == BCM_E_NOT_FOUND) {
  12462                 continue;
  12463             } else if (BCM_FAILURE(rv)) {
  12464                 break;
  12465             }
  12466             for (i = 0; i < entry_prof_words; i++) {
  12467                 if ((entry_prof.entry_data[i] ^ entry0_prof.entry_data[i]) &
  12468                     mask0_prof.entry_data[i]) {
  12469                     break;
  12470                 }
  12471             }
  12472 
  12473             if (i == entry_prof_words) {
  12474                 prof_id = index;
  12475                 break;
  12476             }
  12477         }
  12478         if (prof_id == 0xffffffff) {
  12479             soc_mem_field32_set(unit, mem, &entry0, DESTINATIONf, 0);
  12480         } else {
  12481             soc_mem_field32_dest_set(unit, mem, &entry0, DESTINATIONf,
  12482                                      SOC_MEM_FIF_DEST_MYSTA, prof_id);
  12483         }
  12484     }
  12485 
  12486     for (index = 0; index < num_entries; index++) {
  12487         entry = &my_station_shadow[index];
  12488         /* Try matching the entry */
  12489         for (i = 0; i < entry_words; i++) {
  12490             if ((entry->entry_data[i] ^ entry0.entry_data[i]) &
  12491                 mask0.entry_data[i]) {
  12492                 break;
  12493             }
  12494         }
  12495         if (i == entry_words) {
  12496             *result_index = index;
  12497             return BCM_E_NONE;
  12498         }
  12499     }
  12500 
  12501     return BCM_E_NOT_FOUND;
  12502 }
  12503 #endif /* BCM_TRIDENT_SUPPORT || BCM_GREYHOUND2_SUPPORT */
  12504 
  12505 #ifdef BCM_TRIDENT_SUPPORT
  12506 /*
  12507  * Function:
  12508  *      bcm_td_metro_myStation_add
  12509  * Purpose:
  12510  *     Add a MY_STATION_TCAM entry from L2 tunnel API
  12511  *     Shared by MPLS, MIM and TRILL
  12512  * Parameters:
  12513  *     unit              Unit number
  12514  *     mac               MAC address
  12515  *     vlan              VLAN ID
  12516  *     port              Source port number
  12517  *     int               Tunnel (1) or L3 (0) termination
  12518  */
  12519 int
  12520 bcm_td_metro_myStation_add(int unit, bcm_mac_t mac, bcm_vlan_t vlan,
  12521                            bcm_port_t port, int tunnel_term)
  12522 {
  12523     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  12524     int rv, rv1, index, alt_index, i, entry_words;
  12525     uint32 *entry;
  12526     uint32 *term_mask;
  12527     bcm_mac_t mac_mask;
  12528     uint32 port_mask;
  12529     soc_mem_t mem = MY_STATION_TCAMm;
  12530     soc_memacc_t **memacc_list = NULL;
  12531     my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow;
  12532     my_station_profile_1_entry_t entry_prof;
  12533     uint32 old_pid = 0, new_pid;
  12534 
  12535     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  12536 
  12537     if (tunnel_term) {
  12538         term_mask = info->my_station_tunnel_mask;
  12539     } else {
  12540         term_mask = info->my_station_l3_mask;
  12541     }
  12542 
  12543     if (soc_feature(unit, soc_feature_mysta_profile)) {
  12544         entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m);
  12545     } else {
  12546         entry_words = soc_mem_entry_words(unit, mem);
  12547     }
  12548 
  12549     soc_mem_lock(unit, mem);
  12550 
  12551     rv = _bcm_td_my_station_lookup(unit, mem, mac, vlan, port, -1, &index,
  12552                                    &alt_index);
  12553     if (BCM_SUCCESS(rv)) {
  12554         /* Entry exist, update the entry */
  12555         entry = (uint32 *)&my_station_shadow[index];
  12556         if (soc_feature(unit, soc_feature_mysta_profile)) {
  12557             uint32 dest_type;
  12558             old_pid = soc_mem_field32_dest_get(unit, mem, entry,
  12559                                     DESTINATIONf, &dest_type);
  12560             if (dest_type == SOC_MEM_FIF_DEST_MYSTA) {
  12561                 rv1 = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, 0, old_pid);
  12562             } else {
  12563                 rv1 = BCM_E_FAIL;
  12564             }
  12565             if (BCM_FAILURE(rv1)) {
  12566                 soc_mem_unlock(unit, mem);
  12567                 return rv1;
  12568             }
  12569             entry = entry_prof.entry_data;
  12570         }
  12571 
  12572         for (i = 0; i < entry_words; i++) {
  12573             entry[i] |= term_mask[i];
  12574         }
  12575 
  12576         entry = (uint32 *)&my_station_shadow[index];
  12577         if (soc_feature(unit, soc_feature_mysta_profile)) {
  12578             rv1 = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, 0,
  12579                                                   &new_pid);
  12580             if (BCM_SUCCESS(rv1)) {
  12581                 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf,
  12582                     SOC_MEM_FIF_DEST_MYSTA, new_pid);
  12583                 rv1 = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid);
  12584             }
  12585             if (BCM_FAILURE(rv1)) {
  12586                 soc_mem_unlock(unit, mem);
  12587                 return rv1;
  12588             }
  12589         }
  12590 
  12591         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry);
  12592 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12593         if (BCM_SUCCESS(unit) && (mem == MY_STATION_TCAMm)) {
  12594             info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32);
  12595         }
  12596 #endif
  12597     } else if (rv == BCM_E_NOT_FOUND && index == -1) {
  12598         /* No free entry available for insertion */
  12599         rv = BCM_E_FULL;
  12600     }
  12601     if (rv != BCM_E_NOT_FOUND) {
  12602         soc_mem_unlock(unit, mem);
  12603         return rv;
  12604     }
  12605 
  12606     if (alt_index != -1 &&
  12607         ((port == -1 && alt_index > index) ||
  12608          (port != -1 && alt_index < index))) {
  12609         /* Free entry is available for new entry insertion and alternate entry
  12610          * exists. However need to swap these 2 entries to maintain proper
  12611          * lookup precedence */
  12612         rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, alt_index,
  12613                           &my_station_shadow[index]);
  12614         if (BCM_SUCCESS(rv)) {
  12615             rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index,
  12616                                &my_station_shadow[index]);
  12617 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12618             if (BCM_SUCCESS(unit) && (mem == MY_STATION_TCAMm)) {
  12619                 info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32);
  12620             }
  12621 #endif
  12622         }
  12623         if (BCM_FAILURE(rv)) {
  12624             soc_mem_unlock(unit, mem);
  12625             return rv;
  12626         }
  12627         index = alt_index;
  12628     }
  12629 
  12630     /* Add the new entry */
  12631     entry = (uint32 *)&my_station_shadow[index];
  12632     sal_memset(entry, 0, sizeof(my_station_tcam_entry_t));
  12633     sal_memset(&entry_prof, 0, sizeof(entry_prof));
  12634     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VALIDf,
  12635                                      (1 << soc_mem_field_length(unit, mem, VALIDf)) - 1);
  12636     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_IDf, vlan);
  12637     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_ID_MASKf, 0xfff);
  12638     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDRf, mac);
  12639     sal_memset(&mac_mask, 0xff, sizeof(mac_mask));
  12640     _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDR_MASKf,
  12641                          mac_mask);
  12642     if (port != -1) {
  12643         if (soc_mem_field_valid(unit, mem, SOURCE_FIELDf)) {
  12644             if (SOC_IS_KATANAX(unit)) {
  12645                 SOC_IF_ERROR_RETURN(soc_mem_field32_fit(unit, mem,
  12646                             SOURCE_FIELD_MASKf,
  12647                             1 << (SOC_TRUNK_BIT_POS(unit) - 1 )));
  12648                 if ((1 << SOC_TRUNK_BIT_POS(unit)) & port) {
  12649                     /* trunk */
  12650                     if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) {
  12651                         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry,
  12652                                             SOURCE_TYPEf, 1);
  12653                         _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry,
  12654                                             SOURCE_TYPE_MASKf, 1);
  12655                         port &= ~(1 << (SOC_TRUNK_BIT_POS(unit)));
  12656                     }
  12657                 }
  12658             }
  12659             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, SOURCE_FIELDf, port);
  12660             port_mask = (1 << soc_mem_field_length(unit, mem, SOURCE_FIELDf)) - 1;
  12661             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, SOURCE_FIELD_MASKf, port_mask);
  12662         } else {
  12663             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, ING_PORT_NUMf, port);
  12664             port_mask = (1 << soc_mem_field_length(unit, mem, ING_PORT_NUMf)) - 1;
  12665             _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, ING_PORT_NUM_MASKf, port_mask);
  12666         }
  12667     }
  12668 
  12669     for (i = 0; i < entry_words; i++) {
  12670         if (soc_feature(unit, soc_feature_mysta_profile)) {
  12671             entry_prof.entry_data[i] |= term_mask[i];
  12672         } else {
  12673             entry[i] |= term_mask[i];
  12674         }
  12675     }
  12676 
  12677     if (soc_feature(unit, soc_feature_mysta_profile)) {
  12678         rv1 = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, 0, &new_pid);
  12679         if (BCM_SUCCESS(rv1)) {
  12680             soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf,
  12681                                      SOC_MEM_FIF_DEST_MYSTA, new_pid);
  12682         } else {
  12683             soc_mem_unlock(unit, mem);
  12684             return rv1;
  12685         }
  12686     }
  12687 
  12688     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry);
  12689 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12690     if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) {
  12691         info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32);
  12692     }
  12693 #endif
  12694 
  12695     soc_mem_unlock(unit, mem);
  12696 
  12697     if (BCM_SUCCESS(rv) &&
  12698         soc_feature(unit, soc_feature_mysta_profile)) {
  12699         bcm_l2_addr_t l2addr;
  12700         sal_memset(&l2addr, 0, sizeof(bcm_l2_addr_t));
  12701         l2addr.vid = vlan;
  12702         sal_memcpy(&l2addr.mac, mac, sizeof(bcm_mac_t));
  12703         rv = bcm_td_l2_myStation_insert(unit, 2, &l2addr);
  12704     }
  12705 
  12706     return rv;
  12707 }
  12708 
  12709 /*
  12710  * Function:
  12711  *    bcm_td_metro_myStation_delete
  12712  * Purpose:
  12713  *     Delete a MY_STATION_TCAM entry added by L2 tunnel API
  12714  *     Shared by MPLS, MIM and TRILL
  12715  * Parameters:
  12716  *     unit              Unit number
  12717  *     mac               MAC address
  12718  *     vlan              VLAN ID
  12719  *     port              Source port number
  12720  *     int               Tunnel (1) or L3 (0) termination
  12721  */
  12722 int
  12723 bcm_td_metro_myStation_delete(int unit, bcm_mac_t mac, bcm_vlan_t vlan,
  12724                               bcm_port_t port, int tunnel_term)
  12725 {
  12726     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  12727     int rv, index, i, entry_words;
  12728     uint32 old_pid = 0;
  12729     uint32 *entry;
  12730     uint32 *mask, *mask_remove;
  12731     soc_mem_t mem = MY_STATION_TCAMm;
  12732     my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow;
  12733     my_station_profile_1_entry_t entry_prof;
  12734 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12735     int delete_flag = 0;
  12736 #endif
  12737 
  12738     if (tunnel_term) {
  12739         mask = info->my_station_l3_mask;
  12740         mask_remove = info->my_station_tunnel_mask;
  12741     } else {
  12742         mask = info->my_station_tunnel_mask;
  12743         mask_remove = info->my_station_l3_mask;
  12744     }
  12745     entry_words = soc_mem_entry_words(unit, mem);
  12746 
  12747     soc_mem_lock(unit, mem);
  12748 
  12749     rv = _bcm_td_my_station_lookup(unit, mem, mac, vlan, port, -1, &index, NULL);
  12750     if (BCM_FAILURE(rv)) {
  12751         soc_mem_unlock(unit, mem);
  12752         return rv;
  12753     }
  12754 
  12755     entry = (uint32 *)&my_station_shadow[index];
  12756 
  12757     if (soc_feature(unit, soc_feature_mysta_profile)) {
  12758         uint32 dest_type;
  12759         old_pid = soc_mem_field32_dest_get(unit, mem, entry,
  12760                                            DESTINATIONf, &dest_type);
  12761         if (dest_type != SOC_MEM_FIF_DEST_MYSTA) {
  12762             soc_mem_unlock(unit, mem);
  12763             return BCM_E_NOT_FOUND;
  12764         }
  12765 
  12766         rv = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, 0, old_pid);
  12767         if (BCM_FAILURE(rv)) {
  12768             soc_mem_unlock(unit, mem);
  12769             return rv;
  12770         }
  12771         entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m);
  12772         entry = entry_prof.entry_data;
  12773     }
  12774 
  12775         /* Check if the entry has tunnel related flag enabled */
  12776         for (i = 0; i < entry_words; i++) {
  12777         if (entry[i] & mask_remove[i]) {
  12778                 break;
  12779             }
  12780         }
  12781         if (i == entry_words) {
  12782             soc_mem_unlock(unit, mem);
  12783             return BCM_E_NOT_FOUND;
  12784         }
  12785 
  12786         /* Check to see if we need to delete or modify the entry */
  12787         for (i = 0; i < entry_words; i++) {
  12788         if (entry[i] & mask[i]) {
  12789                 break;
  12790             }
  12791         }
  12792         if (i == entry_words) {
  12793         if (soc_feature(unit, soc_feature_mysta_profile)) {
  12794             rv = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid);
  12795         }
  12796         entry = (uint32 *)&my_station_shadow[index];
  12797             /* Delete the entry if no L3 related flag is enabled */
  12798         sal_memset(entry, 0, sizeof(my_station_tcam_entry_t));
  12799 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12800         delete_flag = 1;
  12801 #endif
  12802         } else {
  12803             /* Modify the entry if any L3 related flag is enabled */
  12804             for (i = 0; i < entry_words; i++) {
  12805             entry[i] &= ~mask_remove[i];
  12806             }
  12807         entry = (uint32 *)&my_station_shadow[index];
  12808         if (soc_feature(unit, soc_feature_mysta_profile)) {
  12809             uint32 new_pid;
  12810             rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, 0, &new_pid);
  12811             if (BCM_SUCCESS(rv)) {
  12812                 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf,
  12813                                          SOC_MEM_FIF_DEST_MYSTA, new_pid);
  12814                 rv = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid);
  12815         }
  12816     }
  12817     }
  12818     if (BCM_SUCCESS(rv)) {
  12819         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry);
  12820 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12821         if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm) && delete_flag) {
  12822             info->my_station_shadow_mask->buf[index/32] &= ~(1<<(index%32));
  12823         }
  12824 #endif
  12825     }
  12826 
  12827     soc_mem_unlock(unit, mem);
  12828 
  12829 #if defined(BCM_TRIDENT3_SUPPORT)
  12830     if (BCM_SUCCESS(rv) &&
  12831         soc_feature(unit, soc_feature_mysta_profile)) {
  12832         rv = bcm_td_l2_myStation_delete_entry(unit, 2, mac, vlan, NULL);
  12833         if (rv == BCM_E_NOT_FOUND) {
  12834             rv = BCM_E_NONE;
  12835         }
  12836     }
  12837 #endif
  12838 
  12839     return rv;
  12840 }
  12841 
  12842 /*
  12843  * Function:
  12844  *     bcm_td_metro_myStation_delete_all
  12845  * Purpose:
  12846  *     Delete all MY_STATION_TCAM entries added by L2 tunnel API
  12847  *     Shared by MPLS, MIM and TRILL
  12848  * Parameters:
  12849  *     unit              Unit number
  12850  */
  12851 int
  12852 bcm_td_metro_myStation_delete_all(int unit)
  12853 {
  12854     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  12855     int rv, index, i, num_entries, entry_words;
  12856     uint32 old_pid = 0;
  12857     uint32 *entry;
  12858     my_station_tcam_entry_t valid_mask;
  12859     uint32 *l3_mask, *tunnel_mask;
  12860     soc_mem_t mem = MY_STATION_TCAMm;
  12861     soc_memacc_t **memacc_list = NULL;
  12862     my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow;
  12863     my_station_profile_1_entry_t entry_prof;
  12864 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12865     int delete_flag = 0;
  12866 #endif
  12867 
  12868     memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem);
  12869 
  12870     sal_memset(&valid_mask, 0, sizeof(valid_mask));
  12871     _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &valid_mask, VALIDf,
  12872         (1 << soc_mem_field_length(unit, MY_STATION_TCAMm, VALIDf)) - 1);
  12873 
  12874     l3_mask = info->my_station_l3_mask;
  12875     tunnel_mask = info->my_station_tunnel_mask;
  12876     num_entries = soc_mem_index_count(unit, mem);
  12877     entry_words = soc_mem_entry_words(unit, mem);
  12878 
  12879     soc_mem_lock(unit, mem);
  12880 
  12881     rv = BCM_E_NONE;
  12882     for (index = 0; index < num_entries; index++) {
  12883         bcm_mac_t mac;
  12884         bcm_vlan_t vlan;
  12885         entry = (uint32 *)&my_station_shadow[index];
  12886 
  12887         /* Check if the entry is valid */
  12888         for (i = 0; i < entry_words; i++) {
  12889             if (entry[i] & valid_mask.entry_data[i]) {
  12890                 break;
  12891             }
  12892         }
  12893         if (i == entry_words) {
  12894             continue;
  12895         }
  12896 
  12897         /* Valid entries */
  12898         _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(unit, memacc_list, entry, MAC_ADDRf, mac);
  12899         vlan = _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VLAN_IDf);
  12900         if (soc_feature(unit, soc_feature_mysta_profile)) {
  12901             uint32 dest_type;
  12902             old_pid = soc_mem_field32_dest_get(unit, mem, entry,
  12903                                 DESTINATIONf, &dest_type);
  12904             if (dest_type != SOC_MEM_FIF_DEST_MYSTA) {
  12905                 soc_mem_unlock(unit, mem);
  12906                 return BCM_E_NOT_FOUND;
  12907             }
  12908 
  12909             rv = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, 0, old_pid);
  12910             if (BCM_FAILURE(rv)) {
  12911                 soc_mem_unlock(unit, mem);
  12912                 return rv;
  12913             }
  12914             entry = entry_prof.entry_data;
  12915         }
  12916 
  12917         if (soc_feature(unit, soc_feature_mysta_profile)) {
  12918             entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m);
  12919         } else {
  12920             entry_words = soc_mem_entry_words(unit, mem);
  12921         }
  12922         /* Check if the entry has tunnel related flag enabled */
  12923         for (i = 0; i < entry_words; i++) {
  12924             if (entry[i] & tunnel_mask[i]) {
  12925                 break;
  12926             }
  12927         }
  12928         if (i == entry_words) {
  12929             continue;
  12930         }
  12931 
  12932         /* Check to see if we need to delete or modify the entry */
  12933         for (i = 0; i < entry_words; i++) {
  12934             if (entry[i] & l3_mask[i]) {
  12935                 break;
  12936             }
  12937         }
  12938         if (i == entry_words) {
  12939             if (soc_feature(unit, soc_feature_mysta_profile)) {
  12940                 rv = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid);
  12941             }
  12942             entry = (uint32 *)&my_station_shadow[index];
  12943             /* Delete the entry if no L3 related flag is enabled */
  12944             sal_memset(entry, 0, sizeof(my_station_tcam_entry_t));
  12945 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12946             delete_flag = 1;
  12947 #endif
  12948         } else {
  12949             /* Modify the entry if any L3 related flag is enabled */
  12950             for (i = 0; i < entry_words; i++) {
  12951                 entry[i] &= ~tunnel_mask[i];
  12952             }
  12953             entry = (uint32 *)&my_station_shadow[index];
  12954             if (soc_feature(unit, soc_feature_mysta_profile)) {
  12955                 uint32 new_pid;
  12956                 rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, 0, &new_pid);
  12957                 if (BCM_SUCCESS(rv)) {
  12958                     soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf,
  12959                                              SOC_MEM_FIF_DEST_MYSTA, new_pid);
  12960                     rv = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid);
  12961                 }
  12962             }
  12963         }
  12964         if (!SOC_HW_RESET(unit)) {
  12965             rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index,
  12966                                entry);
  12967 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  12968             if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm) && delete_flag) {
  12969                 info->my_station_shadow_mask->buf[index/32] &= ~(1<<(index%32));
  12970             }
  12971 #endif
  12972         }
  12973 
  12974         if (BCM_SUCCESS(rv) &&
  12975             soc_feature(unit, soc_feature_mysta_profile)) {
  12976             rv = bcm_td_l2_myStation_delete_entry(unit, 2, mac, vlan, NULL);
  12977             if (rv == BCM_E_NOT_FOUND) {
  12978                 rv = BCM_E_NONE;
  12979             }
  12980             if (BCM_FAILURE(rv)) {
  12981                 soc_mem_unlock(unit, mem);
  12982                 return rv;
  12983             }
  12984         }
  12985     }
  12986 
  12987     soc_mem_unlock(unit, mem);
  12988 
  12989     return rv;
  12990 }
  12991 #endif /* BCM_TRIDENT_SUPPORT */
  12992 
  12993 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  12994 /*
  12995  * Function:
  12996  *      _bcm_vlan_vfi_membership_profile_entry_op
  12997  * Purpose:
  12998  *      Internal function for adding/deleting an entry to the
  12999  *      ING/EGR_VLAN_VFI_MEMBERSHIP
  13000  *      tables. Adds an entry to the global shared SW copy of the
  13001  *      ING/EGE_VLAN_VFI_MEMBERSHIP tables.
  13002  *      Shared by VLAN, VFI, SOURCE_VP and STM
  13003  * Parameters:
  13004  *      unit    -  (IN) Device number.
  13005  *      entries -  (IN) Array of pointer to table entries set
  13006  *      entries_per_set - (IN)  Number of entries in the set
  13007  *      add     -   (IN)  True if operation is add
  13008  *      egress  -   (IN)  True if direction is egress
  13009  *      index   -  (OUT) Base index for the entires allocated in HW
  13010  * Returns:
  13011  *      BCM_X_XXX
  13012  */
  13013 
  13014 int _bcm_vlan_vfi_membership_profile_entry_op(int unit,
  13015                                               void **entries, 
  13016                                               int entries_per_set,
  13017                                               int add,
  13018                                               int egress,
  13019                                               uint32 *index)
  13020 {
  13021     int rv;
  13022     soc_profile_mem_t *profile = NULL;
  13023 
  13024     LOG_INFO(BSL_LS_BCM_COMMON,
  13025         (BSL_META_U(unit,"!: Add: %d Egress: %d index: %d\n"),
  13026                     add, egress, *index));
  13027 
  13028     COMMON_LOCK(unit);
  13029 
  13030     if(!egress) {
  13031         profile = ING_VLAN_VFI_PROFILE(unit);
  13032     } else {
  13033         profile = EGR_VLAN_VFI_PROFILE(unit);
  13034     }
  13035 
  13036     if(add) {
  13037         rv = soc_profile_mem_add(unit, profile, entries,
  13038                                  entries_per_set, index);
  13039     } else {
  13040         rv = soc_profile_mem_delete(unit, profile, *index);
  13041     }
  13042 
  13043     COMMON_UNLOCK(unit);
  13044     return rv;
  13045 
  13046 }
  13047 
  13048 /*
  13049  * Function:
  13050  *      _bcm_vlan_vfi_membership_profile_mem_reference
  13051  * Purpose:
  13052  *      Update ING/EGR_VLAN_VFI_PROFILE entry reference count
  13053  *      and entries_per_set information for given index.
  13054  * Parameters:
  13055  *      unit            - (IN) Device number
  13056  *      index           - (IN) Base index for entry to update
  13057  *      entries_per_set - (IN) Number of entries in the set
  13058  *      egress          - (IN) True if egress profile
  13059  * Returns:
  13060  *      BCM_E_XXX
  13061  */
  13062 int _bcm_vlan_vfi_membership_profile_mem_reference(int unit,
  13063                                                     int index,
  13064                                                     int entries_per_set,
  13065                                                     int egress)
  13066 {
  13067     int rv;
  13068     soc_profile_mem_t *profile = NULL;
  13069 
  13070     if(!egress) {
  13071         profile = ING_VLAN_VFI_PROFILE(unit);
  13072     } else {
  13073         profile = EGR_VLAN_VFI_PROFILE(unit);
  13074     }
  13075 
  13076     COMMON_LOCK(unit);
  13077 
  13078     rv = soc_profile_mem_reference(unit, profile,
  13079                                    index, entries_per_set);
  13080 
  13081     COMMON_UNLOCK(unit);
  13082     return rv;
  13083 
  13084 }
  13085 
  13086 /*
  13087  * Function:
  13088  *      _bcm_vlan_vfi_mbrship_profile_ref_count
  13089  * Purpose:
  13090  *      Internal function for getting the ref count of a
  13091  *      ING/EGR_VLAN_VFI_MEMBERSHIP table. 
  13092  * Parameters:
  13093  *      unit    -  (IN) Device number.
  13094  *      index   -  (IN) Base index for the entires allocated in HW
  13095  *      egress  -  (IN) True if egress
  13096  *      ref_count  -  (OUT) Ref count of this index
  13097  *      BCM_X_XXX
  13098  */
  13099 int
  13100 _bcm_vlan_vfi_mbrship_profile_ref_count(int unit, int index,
  13101                                         int egress, int *ref_count)
  13102 {
  13103     int rv;
  13104 
  13105     soc_profile_mem_t *profile = NULL;
  13106 
  13107     if(!egress) {
  13108         profile = ING_VLAN_VFI_PROFILE(unit);
  13109     } else {
  13110         profile = EGR_VLAN_VFI_PROFILE(unit);
  13111     }
  13112 
  13113     rv = soc_profile_mem_ref_count_get(unit, profile, index, ref_count);
  13114     return rv;
  13115 }
  13116 #endif
  13117 
  13118 #if defined(BCM_TRIDENT3_SUPPORT)
  13119 /*
  13120  * Function:
  13121  *      _bcm_vlan_vfi_untag_profile_entry_op
  13122  * Purpose:
  13123  *      Internal function for adding/deleting an entry to the
  13124  *      ING/EGR_VLAN_VFI_MEMBERSHIP
  13125  *      tables. Adds an entry to the global shared SW copy of the
  13126  *      ING/EGE_VLAN_VFI_MEMBERSHIP tables.
  13127  *      Shared by VLAN, VFI, SOURCE_VP and STM
  13128  * Parameters:
  13129  *      unit    -  (IN) Device number.
  13130  *      entries -  (IN) Array of pointer to table entries set
  13131  *      entries_per_set - (IN)  Number of entries in the set
  13132  *      add     -   (IN)  True if operation is add
  13133  *      egress  -   (IN)  True if direction is egress 
  13134  *      index   -  (OUT) Base index for the entires allocated in HW
  13135  * Returns:
  13136  *      BCM_X_XXX
  13137  */
  13138 
  13139 int _bcm_vlan_vfi_untag_profile_entry_op(int unit, void **entries, 
  13140                                          int entries_per_set,
  13141                                          int add,
  13142                                          uint32 *index)
  13143 {
  13144     int rv;
  13145     soc_profile_mem_t *profile = NULL;
  13146 
  13147     LOG_INFO(BSL_LS_BCM_COMMON,
  13148         (BSL_META_U(unit,"!: Add: %d index: %d\n"), add, *index));
  13149 
  13150     COMMON_LOCK(unit);
  13151 
  13152     profile = EGR_VLAN_VFI_UNTAG_PROFILE(unit);
  13153 
  13154     if (add) {
  13155         rv = soc_profile_mem_add(unit, profile, entries,
  13156                                  entries_per_set, index);
  13157     } else {
  13158         rv = soc_profile_mem_delete(unit, profile, *index);
  13159     }
  13160 
  13161     COMMON_UNLOCK(unit);
  13162     return rv;
  13163 
  13164 }
  13165 /*
  13166  * Function:
  13167  *      _bcm_vlan_vfi_untag_profile_mem_reference
  13168  * Purpose:
  13169  *      Update ING/EGR_VLAN_VFI_PROFILE entry reference count
  13170  *      and entries_per_set information for given index.
  13171  * Parameters:
  13172  *      unit            - (IN) Device number
  13173  *      index           - (IN) Base index for entry to update
  13174  *      entries_per_set - (IN) Number of entries in the set
  13175  *      egress          - (IN) True if egress profile
  13176  * Returns:
  13177  *      BCM_E_XXX
  13178  */
  13179 int _bcm_vlan_vfi_untag_profile_mem_reference(int unit, int index,
  13180                                               int entries_per_set)
  13181 {
  13182     int rv;
  13183     soc_profile_mem_t *profile = NULL;
  13184 
  13185     profile = EGR_VLAN_VFI_UNTAG_PROFILE(unit);
  13186 
  13187     COMMON_LOCK(unit);
  13188 
  13189     rv = soc_profile_mem_reference(unit, profile,
  13190                                    index, entries_per_set);
  13191 
  13192     COMMON_UNLOCK(unit);
  13193     return rv;
  13194 
  13195 }
  13196 
  13197 /*
  13198  * Function:
  13199  *      _bcm_vlan_vfi_mbrship_profile_ref_count
  13200  * Purpose:
  13201  *      Internal function for getting the ref count of a
  13202  *      ING/EGR_VLAN_VFI_MEMBERSHIP table. 
  13203  * Parameters:
  13204  *      unit    -  (IN) Device number.
  13205  *      index   -  (IN) Base index for the entires allocated in HW
  13206  *      egress  -  (IN) True if egress
  13207  *      ref_count  -  (OUT) Ref count of this index
  13208  *      BCM_X_XXX
  13209  */
  13210 int
  13211 _bcm_vlan_vfi_untag_profile_ref_count(int unit, int index, int *ref_count)
  13212 {
  13213     int rv;
  13214 
  13215     soc_profile_mem_t *profile = NULL;
  13216     profile = EGR_VLAN_VFI_UNTAG_PROFILE(unit);
  13217 
  13218     rv = soc_profile_mem_ref_count_get(unit, profile, index, ref_count);
  13219     return rv;
  13220 }
  13221 #endif /* BCM_TRIDENT3_SUPPORT */
  13222 
  13223 
  13224 #ifdef BCM_FLOWTRACKER_SUPPORT
  13225 
  13226 /*
  13227  * Function:
  13228  *      bcmi_ft_group_age_profile_entry_add
  13229  * Purpose:
  13230  *      Internal function for setting the profile
  13231  *      entry for age out of an entry.
  13232  * Parameters:
  13233  *      unit    -  (IN) Device number.
  13234  *      entries -  (IN) entries to be added
  13235  *      entries_per_set  - (IN) numbe rof entries
  13236  *      index   -  (IN) Base index for the entires allocated in HW
  13237  * Returns:
  13238  *      BCM_X_XXX
  13239  */
  13240 
  13241 int
  13242 bcmi_ft_group_age_profile_entry_add(int unit, void **entries,
  13243                               int entries_per_set, uint32 *index)
  13244 {
  13245     int rv;
  13246     COMMON_LOCK(unit);
  13247     rv = soc_profile_mem_add(unit, FT_AGE_OUT(unit), entries,
  13248                              entries_per_set, index);
  13249     COMMON_UNLOCK(unit);
  13250     return rv;
  13251 }
  13252 
  13253 
  13254 /*
  13255  * Function:
  13256  *      bcmi_ft_group_age_profile_entry_delete
  13257  * Purpose:
  13258  *      Internal function for setting the profile
  13259  *      entry for age out of an entry.
  13260  * Parameters:
  13261  *      unit    -  (IN) Device number.
  13262  *      index   -  (IN) Base index for the entires allocated in HW
  13263  * Returns:
  13264  *      BCM_X_XXX
  13265  */
  13266 int
  13267 bcmi_ft_group_age_profile_entry_delete(int unit, int index)
  13268 {
  13269     int rv;
  13270     COMMON_LOCK(unit);
  13271     rv = soc_profile_mem_delete(unit, FT_AGE_OUT(unit), index);
  13272     COMMON_UNLOCK(unit);
  13273     return rv;
  13274 }
  13275 
  13276 /*
  13277  * Function:
  13278  *      bcmi_ft_group_age_profile_refcount_set
  13279  * Purpose:
  13280  *      Increase ref count on profile index.
  13281  * Parameters:
  13282  *      unit    -  (IN) Device number.
  13283  *      index   -  (IN) Base index for the entires allocated in HW
  13284  * Returns:
  13285  *      BCM_X_XXX
  13286  */
  13287 int
  13288 bcmi_ft_group_age_profile_refcount_set(int unit, uint32 index)
  13289 {
  13290     int rv;
  13291 
  13292     COMMON_LOCK(unit);
  13293     rv = soc_profile_mem_reference(unit, FT_AGE_OUT(unit), index, 1);
  13294     COMMON_UNLOCK(unit);
  13295 
  13296     return rv;
  13297 }
  13298 
  13299 
  13300 /*
  13301  * Function:
  13302  *      bcmi_ft_group_flow_limit_profile_entry_add
  13303  * Purpose:
  13304  *      Internal function for setting the profile
  13305  *      entry for flow limit entry.
  13306  * Parameters:
  13307  *      unit    -  (IN) Device number.
  13308  *      entries -  (IN) entries to be added
  13309  *      entries_per_set  - (IN) numbe rof entries
  13310  *      index   -  (IN) Base index for the entires allocated in HW
  13311  * Returns:
  13312  *      BCM_X_XXX
  13313  */
  13314 
  13315 int
  13316 bcmi_ft_group_flow_limit_profile_entry_add(int unit, void **entries,
  13317                               int entries_per_set, uint32 *index)
  13318 {
  13319     int rv;
  13320     COMMON_LOCK(unit);
  13321     rv = soc_profile_mem_add(unit, FT_FLOW_LIMIT(unit), entries,
  13322                              entries_per_set, index);
  13323     COMMON_UNLOCK(unit);
  13324     return rv;
  13325 }
  13326 
  13327 
  13328 /*
  13329  * Function:
  13330  *      bcmi_ft_group_flow_limit_profile_entry_delete
  13331  * Purpose:
  13332  *      Internal function for removing the profile
  13333  *      entry for flow limit entry.
  13334  * Parameters:
  13335  *      unit    -  (IN) Device number.
  13336  *      index   -  (IN) Base index for the entires allocated in HW
  13337  * Returns:
  13338  *      BCM_X_XXX
  13339  */
  13340 int
  13341 bcmi_ft_group_flow_limit_profile_entry_delete(int unit, int index)
  13342 {
  13343     int rv;
  13344     COMMON_LOCK(unit);
  13345     rv = soc_profile_mem_delete(unit, FT_FLOW_LIMIT(unit), index);
  13346     COMMON_UNLOCK(unit);
  13347     return rv;
  13348 }
  13349 
  13350 /*
  13351  * Function:
  13352  *      bcmi_ft_group_flow_limit_profile_refcount_set
  13353  * Purpose:
  13354  *      Increase ref count on profile index.
  13355  * Parameters:
  13356  *      unit    -  (IN) Device number.
  13357  *      index   -  (IN) Base index for the entires allocated in HW
  13358  * Returns:
  13359  *      BCM_X_XXX
  13360  */
  13361 int
  13362 bcmi_ft_group_flow_limit_profile_refcount_set(int unit, uint32 index)
  13363 {
  13364     int rv;
  13365 
  13366     COMMON_LOCK(unit);
  13367     rv = soc_profile_mem_reference(unit, FT_FLOW_LIMIT(unit), index, 1);
  13368     COMMON_UNLOCK(unit);
  13369 
  13370     return rv;
  13371 }
  13372 
  13373 /*
  13374  * Function:
  13375  *      bcmi_ft_group_collector_copy_profile_entry_add
  13376  * Purpose:
  13377  *      Internal function for setting the profile
  13378  *      entry for collector copies.
  13379  * Parameters:
  13380  *      unit    -  (IN) Device number.
  13381  *      entries -  (IN) entries to be added
  13382  *      entries_per_set  - (IN) numbe rof entries
  13383  *      index   -  (OUT) Base index for the entires allocated in HW
  13384  * Returns:
  13385  *      BCM_X_XXX
  13386  */
  13387 
  13388 int
  13389 bcmi_ft_group_collector_copy_profile_entry_add(int unit, void **entries,
  13390                               int entries_per_set, uint32 *index)
  13391 {
  13392     int rv;
  13393     COMMON_LOCK(unit);
  13394     rv = soc_profile_mem_add(unit, FT_COLLECTOR_COPY(unit), entries,
  13395                              entries_per_set, index);
  13396     COMMON_UNLOCK(unit);
  13397     return rv;
  13398 }
  13399 
  13400 
  13401 /*
  13402  * Function:
  13403  *      bcmi_ft_group_collector_copy_profile_entry_delete
  13404  * Purpose:
  13405  *      Internal function for removing the profile
  13406  *      entry for collector copies.
  13407  * Parameters:
  13408  *      unit    -  (IN) Device number.
  13409  *      index   -  (IN) Base index for the entires allocated in HW
  13410  * Returns:
  13411  *      BCM_X_XXX
  13412  */
  13413 int
  13414 bcmi_ft_group_collector_copy_profile_entry_delete(int unit, int index)
  13415 {
  13416     int rv;
  13417     COMMON_LOCK(unit);
  13418     rv = soc_profile_mem_delete(unit, FT_COLLECTOR_COPY(unit), index);
  13419     COMMON_UNLOCK(unit);
  13420     return rv;
  13421 }
  13422 
  13423 /*
  13424  * Function:
  13425  *      bcmi_ft_group_collector_copy_profile_refcount_set
  13426  * Purpose:
  13427  *      Increase ref count on profile index.
  13428  * Parameters:
  13429  *      unit    -  (IN) Device number.
  13430  *      index   -  (IN) Base index for the entires allocated in HW
  13431  * Returns:
  13432  *      BCM_X_XXX
  13433  */
  13434 int
  13435 bcmi_ft_group_collector_copy_profile_refcount_set(int unit, uint32 index)
  13436 {
  13437     int rv;
  13438 
  13439     COMMON_LOCK(unit);
  13440     rv = soc_profile_mem_reference(unit, FT_COLLECTOR_COPY(unit), index, 1);
  13441     COMMON_UNLOCK(unit);
  13442 
  13443     return rv;
  13444 }
  13445 
  13446 
  13447 /*
  13448  * Function:
  13449  *      bcmi_ft_group_pdd_profile_entry_add
  13450  * Purpose:
  13451  *      Internal function for setting the profile
  13452  *      entry for policy action profile.
  13453  * Parameters:
  13454  *      unit    -  (IN) Device number.
  13455  *      entries -  (IN) entries to be added
  13456  *      entries_per_set  - (IN) numbe rof entries
  13457  *      index   -  (OUT) Base index for the entires allocated in HW
  13458  * Returns:
  13459  *      BCM_X_XXX
  13460  */
  13461 
  13462 int
  13463 bcmi_ft_group_pdd_profile_entry_add(int unit, void **entries,
  13464                               int entries_per_set, uint32 *index)
  13465 {
  13466     int rv;
  13467     COMMON_LOCK(unit);
  13468     rv = soc_profile_mem_add(unit, FT_PDD_PROFILE(unit), entries,
  13469                              entries_per_set, index);
  13470     COMMON_UNLOCK(unit);
  13471     return rv;
  13472 }
  13473 
  13474 /*
  13475  * Function:
  13476  *      bcmi_ft_group_pdd_profile_entry_delete
  13477  * Purpose:
  13478  *      Internal function for removing the profile
  13479  *      entry for policy action profile.
  13480  * Parameters:
  13481  *      unit    -  (IN) Device number.
  13482  *      index   -  (IN) Base index for the entires allocated in HW
  13483  * Returns:
  13484  *      BCM_X_XXX
  13485  */
  13486 int
  13487 bcmi_ft_group_pdd_profile_entry_delete(int unit, int index)
  13488 {
  13489     int rv;
  13490     COMMON_LOCK(unit);
  13491     rv = soc_profile_mem_delete(unit, FT_PDD_PROFILE(unit), index);
  13492     COMMON_UNLOCK(unit);
  13493     return rv;
  13494 }
  13495 
  13496 /*
  13497  * Function:
  13498  *      bcmi_ft_group_pdd_profile_refcount_set
  13499  * Purpose:
  13500  *      Increase ref count on profile index.
  13501  * Parameters:
  13502  *      unit    -  (IN) Device number.
  13503  *      index   -  (IN) Base index for the entires allocated in HW
  13504  * Returns:
  13505  *      BCM_X_XXX
  13506  */
  13507 int
  13508 bcmi_ft_group_pdd_profile_refcount_set(int unit, uint32 index)
  13509 {
  13510     int rv;
  13511 
  13512     COMMON_LOCK(unit);
  13513     rv = soc_profile_mem_reference(unit, FT_PDD_PROFILE(unit), index, 1);
  13514     COMMON_UNLOCK(unit);
  13515 
  13516     return rv;
  13517 }
  13518 
  13519 
  13520 /*
  13521  * Function:
  13522  *      bcmi_ft_group_pdd_profile_ref_count_get
  13523  * Purpose:
  13524  *      Internal function for getting the ref count
  13525  *      for pdd profile entries.
  13526  * Parameters:
  13527  *      unit    -  (IN) Device number.
  13528  *      index   -  (IN) Base index for the entry
  13529  *      ref_cnt -  (OUT) ref count of the entry
  13530  * Returns:
  13531  *      BCM_X_XXX
  13532  */
  13533 int
  13534 bcmi_ft_group_pdd_profile_refcount_get(int unit,
  13535                             int index, int *ref_cnt)
  13536 {
  13537     int rv;
  13538     COMMON_LOCK(unit);
  13539     rv = soc_profile_mem_ref_count_get(unit, FT_PDD_PROFILE(unit), index,
  13540                                        ref_cnt);
  13541     COMMON_UNLOCK(unit);
  13542     return rv;
  13543 }
  13544 
  13545 /*
  13546  * Function:
  13547  *      bcmi_ft_group_meter_profile_entry_add
  13548  * Purpose:
  13549  *      Internal function for setting the profile
  13550  *      entry for meter profile.
  13551  * Parameters:
  13552  *      unit    -  (IN) Device number.
  13553  *      entries -  (IN) entries to be added
  13554  *      entries_per_set  - (IN) numbe rof entries
  13555  *      index   -  (OUT) Base index for the entires allocated in HW
  13556  * Returns:
  13557  *      BCM_X_XXX
  13558  */
  13559 
  13560 int
  13561 bcmi_ft_group_meter_profile_entry_add(int unit, void **entries,
  13562                               int entries_per_set, uint32 *index)
  13563 {
  13564     int rv;
  13565     COMMON_LOCK(unit);
  13566     rv = soc_profile_mem_add(unit, FT_METER_PROFILE(unit), entries,
  13567                              entries_per_set, index);
  13568     COMMON_UNLOCK(unit);
  13569     return rv;
  13570 }
  13571 
  13572 
  13573 /*
  13574  * Function:
  13575  *      bcmi_ft_group_meter_profile_entry_delete
  13576  * Purpose:
  13577  *      Internal function for removing the profile
  13578  *      entry for meter profiles.
  13579  * Parameters:
  13580  *      unit    -  (IN) Device number.
  13581  *      index   -  (IN) Base index for the entires allocated in HW
  13582  * Returns:
  13583  *      BCM_X_XXX
  13584  */
  13585 int
  13586 bcmi_ft_group_meter_profile_entry_delete(int unit, int index)
  13587 {
  13588     int rv;
  13589     COMMON_LOCK(unit);
  13590     rv = soc_profile_mem_delete(unit, FT_METER_PROFILE(unit), index);
  13591     COMMON_UNLOCK(unit);
  13592     return rv;
  13593 }
  13594 
  13595 /*
  13596  * Function:
  13597  *      bcmi_ft_group_meter_profile_refcount_set
  13598  * Purpose:
  13599  *      Increase ref count on profile index.
  13600  * Parameters:
  13601  *      unit    -  (IN) Device number.
  13602  *      index   -  (IN) Base index for the entires allocated in HW
  13603  * Returns:
  13604  *      BCM_X_XXX
  13605  */
  13606 int
  13607 bcmi_ft_group_meter_profile_refcount_set(int unit, uint32 index)
  13608 {
  13609     int rv;
  13610 
  13611     COMMON_LOCK(unit);
  13612     rv = soc_profile_mem_reference(unit, FT_METER_PROFILE(unit), index, 1);
  13613     COMMON_UNLOCK(unit);
  13614 
  13615     return rv;
  13616 }
  13617 
  13618 /*
  13619  * Function:
  13620  *      bcmi_ft_group_timestamp_profile_entry_add
  13621  * Purpose:
  13622  *      Internal function for setting the profile
  13623  *      entry for timestamps.
  13624  * Parameters:
  13625  *      unit    -  (IN) Device number.
  13626  *      entries -  (IN) entries to be added
  13627  *      entries_per_set  - (IN) numbe rof entries
  13628  *      index   -  (OUT) Base index for the entires allocated in HW
  13629  * Returns:
  13630  *      BCM_X_XXX
  13631  */
  13632 
  13633 int
  13634 bcmi_ft_group_timestamp_profile_entry_add(int unit, void **entries,
  13635                               int entries_per_set, uint32 *index)
  13636 {
  13637     int rv;
  13638     COMMON_LOCK(unit);
  13639     rv = soc_profile_mem_add(unit, FT_TS_PROFILE(unit), entries,
  13640                              entries_per_set, index);
  13641     COMMON_UNLOCK(unit);
  13642     return rv;
  13643 }
  13644 
  13645 
  13646 /*
  13647  * Function:
  13648  *      bcmi_ft_group_timestamp_profile_entry_delete
  13649  * Purpose:
  13650  *      Internal function for removing the profile
  13651  *      entry for timestamps.
  13652  * Parameters:
  13653  *      unit    -  (IN) Device number.
  13654  *      index   -  (IN) Base index for the entires allocated in HW
  13655  * Returns:
  13656  *      BCM_X_XXX
  13657  */
  13658 int
  13659 bcmi_ft_group_timestamp_profile_entry_delete(int unit, int index)
  13660 {
  13661     int rv;
  13662     COMMON_LOCK(unit);
  13663     rv = soc_profile_mem_delete(unit, FT_TS_PROFILE(unit), index);
  13664     COMMON_UNLOCK(unit);
  13665     return rv;
  13666 }
  13667 
  13668 /*
  13669  * Function:
  13670  *      bcmi_ft_group_timestamp_profile_refcount_set
  13671  * Purpose:
  13672  *      Increase ref count on profile index.
  13673  * Parameters:
  13674  *      unit    -  (IN) Device number.
  13675  *      index   -  (IN) Base index for the entires allocated in HW
  13676  * Returns:
  13677  *      BCM_X_XXX
  13678  */
  13679 int
  13680 bcmi_ft_group_timestamp_profile_refcount_set(int unit, uint32 index)
  13681 {
  13682     int rv;
  13683 
  13684     COMMON_LOCK(unit);
  13685     rv = soc_profile_mem_reference(unit, FT_TS_PROFILE(unit), index, 1);
  13686     COMMON_UNLOCK(unit);
  13687 
  13688     return rv;
  13689 }
  13690 
  13691 
  13692 #endif /* BCM_FLOWTRACKER_SUPPORT */
  13693 
  13694 
  13695 
  13696 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP
  13697 /*
  13698  * Function:
  13699  *     _bcm_common_sw_dump
  13700  * Purpose:
  13701  *     Displays common data structure information maintained by software.
  13702  * Parameters:
  13703  *     unit - Device unit number
  13704  * Returns:
  13705  *     None
  13706  * Note:
  13707  */
  13708 void
  13709 _bcm_common_sw_dump(int unit)
  13710 {
  13711     _bcm_common_bookkeeping_t *info = COMMON_INFO(unit);
  13712     soc_mem_t        mem;
  13713     int              i, j, rv;
  13714     int              num_entries;
  13715     int              ref_count;
  13716 
  13717     LOG_CLI((BSL_META_U(unit,
  13718                         "\nSW Information Common - Unit %d\n"), unit));
  13719 
  13720     if (!info->initialized) {
  13721         LOG_CLI((BSL_META_U(unit,
  13722                             "  Common data structures uninitialized!\n")));
  13723     }
  13724 
  13725     /* MPLS station hash */
  13726     if (NULL != info->mpls_station_hash) {
  13727         if (SOC_MEM_IS_VALID(unit, MY_STATION_TCAMm)) {
  13728             num_entries = soc_mem_index_count(unit, MY_STATION_TCAMm);
  13729         } else {
  13730             num_entries = soc_mem_index_count(unit, MPLS_STATION_TCAMm);
  13731         }
  13732 
  13733         LOG_CLI((BSL_META_U(unit,
  13734                             "\n  MPLS station index hashes (%d)\n"), num_entries));
  13735         LOG_CLI((BSL_META_U(unit,
  13736                             "    Index     Hash\n")));
  13737         ref_count = 0;
  13738         for (i = 0; i < num_entries; i++) {
  13739             if (0 != MPLS_STATION_HASH(unit, i)){
  13740                 LOG_CLI((BSL_META_U(unit,
  13741                                     "  %3d      0x%04x\n"),
  13742                          i, MPLS_STATION_HASH(unit, i)));
  13743                 ref_count++;
  13744             }
  13745         }
  13746         if (0 == ref_count) {
  13747             LOG_CLI((BSL_META_U(unit,
  13748                                 "    All indexes hash to zero.\n")));
  13749         }
  13750         LOG_CLI((BSL_META_U(unit,
  13751                             "\n")));
  13752     }
  13753 
  13754     /* MAC_DA_PROFILE table */
  13755     if (NULL != info->mac_da_profile) {
  13756         egr_mac_da_profile_entry_t *mac_da_entry_p;
  13757         bcm_mac_t        l2mac;
  13758 
  13759         mem = EGR_MAC_DA_PROFILEm;
  13760         num_entries = soc_mem_index_count(unit, mem);
  13761         LOG_CLI((BSL_META_U(unit,
  13762                             "  MAC DA Profile Mem\n")));
  13763         LOG_CLI((BSL_META_U(unit,
  13764                             "    Number of entries: %d\n"), num_entries));
  13765         LOG_CLI((BSL_META_U(unit,
  13766                             "    Index RefCount - MAC address\n")));
  13767 
  13768         for (i = 0; i < num_entries; i++) {
  13769             rv = soc_profile_mem_ref_count_get(unit,
  13770                                                info->mac_da_profile,
  13771                                                i, &ref_count);
  13772             if (SOC_FAILURE(rv)) {
  13773                 LOG_CLI((BSL_META_U(unit,
  13774                                     " *** Error retrieving profile reference: %d ***\n"),
  13775                          rv));
  13776                 break;
  13777             }
  13778 
  13779             if (ref_count <= 0) {
  13780                 continue;
  13781             }
  13782 
  13783             mac_da_entry_p =
  13784                 SOC_PROFILE_MEM_ENTRY(unit, info->mac_da_profile,
  13785                                       egr_mac_da_profile_entry_t *, i);
  13786 
  13787             soc_mem_mac_addr_get(unit, mem, mac_da_entry_p,
  13788                                  MAC_ADDRESSf, l2mac);
  13789             LOG_CLI((BSL_META_U(unit,
  13790                                 "  %5d %8d    0x%02x%02x%02x%02x%02x%02x\n"),
  13791                      i, ref_count,
  13792                      l2mac[0], l2mac[1], l2mac[2],
  13793                      l2mac[3], l2mac[4], l2mac[5]));
  13794         }
  13795         LOG_CLI((BSL_META_U(unit,
  13796                             "\n")));
  13797     }
  13798 
  13799     /* LPORT_PROFILE table */
  13800     if (NULL != info->lport_profile) {
  13801         lport_tab_entry_t *lport_entry_p;
  13802 
  13803         mem = LPORT_TABm;
  13804         num_entries = soc_mem_index_count(unit, mem);
  13805         LOG_CLI((BSL_META_U(unit,
  13806                             "  LPORT_PROFILE_TABLE Mem\n")));
  13807         LOG_CLI((BSL_META_U(unit,
  13808                             "    Number of entries: %d\n"), num_entries));
  13809         LOG_CLI((BSL_META_U(unit,
  13810                             "    Index RefCount - LPORT_TAB entry\n")));
  13811 
  13812         for (i = 0; i < num_entries; i++) {
  13813             rv = soc_profile_mem_ref_count_get(unit,
  13814                                                info->lport_profile,
  13815                                                i, &ref_count);
  13816             if (SOC_FAILURE(rv)) {
  13817                 LOG_CLI((BSL_META_U(unit,
  13818                                     " *** Error retrieving profile reference: %d ***\n"),
  13819                          rv));
  13820                 break;
  13821             }
  13822 
  13823             if (ref_count <= 0) {
  13824                 continue;
  13825             }
  13826 
  13827             lport_entry_p =
  13828                 SOC_PROFILE_MEM_ENTRY(unit, info->lport_profile,
  13829                                       lport_tab_entry_t *, i);
  13830 
  13831             LOG_CLI((BSL_META_U(unit, "  %5d %8d\n"), i, ref_count));
  13832             
  13833             /* Coverity checks 8k stack size, the diag shell thread
  13834              * uses 128k by default
  13835              */
  13836             /* coverity[stack_use_callee] */  
  13837             /* coverity[stack_use_overflow : FALSE] */
  13838             soc_mem_entry_dump(unit, mem, lport_entry_p, BSL_LSS_CLI);
  13839             LOG_CLI((BSL_META_U(unit, "\n")));
  13840         }
  13841         LOG_CLI((BSL_META_U(unit, "\n")));
  13842     }
  13843 
  13844     /* ING_PRI_CNG_MAP table */
  13845     if (NULL != info->ing_pri_cng_map) {
  13846         ing_pri_cng_map_entry_t *ing_pri_cng_map_entry_p;
  13847         int pri, cng;
  13848         int entries_per_set;
  13849         soc_field_t pri_t;
  13850         soc_profile_mem_t *profile;
  13851         soc_profile_mem_table_t *table;
  13852 
  13853         if (SOC_IS_TRIDENT3X(unit)) {
  13854             mem = PHB_MAPPING_TBL_1m;
  13855             pri_t = INT_PRIf;
  13856         } else {
  13857         mem = ING_PRI_CNG_MAPm;
  13858             pri_t = PRIf;
  13859         }
  13860 
  13861         /*
  13862          * Get num_entries from profile table->index_max since
  13863          * some entries are reserved (see the details in _bcm_common_init).
  13864          */
  13865         profile = ING_PRI_CNG_MAP(unit);
  13866         table = &profile->tables[0];
  13867         num_entries = table->index_max;
  13868 
  13869         LOG_CLI((BSL_META_U(unit,
  13870                             "  ING_PRI_CNG_MAP Mem\n")));
  13871         LOG_CLI((BSL_META_U(unit,
  13872                             "    Number of entries: %d\n"), num_entries));
  13873         LOG_CLI((BSL_META_U(unit,
  13874                             "    Index RefCount EntriesPerSet - PRI CNG\n")));
  13875 
  13876         for (i = 0; i < num_entries; i += _BCM_TR2_PRI_CNG_MAP_SIZE) {
  13877             rv = soc_profile_mem_ref_count_get(unit,
  13878                                                info->ing_pri_cng_map,
  13879                                                i, &ref_count);
  13880             if (SOC_FAILURE(rv)) {
  13881                 LOG_CLI((BSL_META_U(unit,
  13882                                     " *** Error retrieving profile reference: %d ***\n"),
  13883                          rv));
  13884                 break;
  13885             }
  13886 
  13887             if (ref_count <= 0) {
  13888                 continue;
  13889             }
  13890 
  13891             for (j = 0; j < _BCM_TR2_PRI_CNG_MAP_SIZE; j++) {
  13892                 entries_per_set =
  13893                     info->ing_pri_cng_map->tables[0].entries[i + j].entries_per_set;
  13894                 ing_pri_cng_map_entry_p =
  13895                     SOC_PROFILE_MEM_ENTRY(unit, info->ing_pri_cng_map,
  13896                                           ing_pri_cng_map_entry_t *,
  13897                                           i + j);
  13898                 pri = soc_mem_field32_get(unit, mem,
  13899                                           ing_pri_cng_map_entry_p,
  13900                                           pri_t);
  13901                 cng = soc_mem_field32_get(unit, mem,
  13902                                           ing_pri_cng_map_entry_p,
  13903                                           CNGf);
  13904 
  13905                 LOG_CLI((BSL_META_U(unit,
  13906                                     "  %5d %8d %13d     %2d  %2d\n"),
  13907                          i + j, ref_count, entries_per_set,
  13908                          pri, cng));
  13909             }
  13910         }
  13911         LOG_CLI((BSL_META_U(unit,
  13912                             "\n")));
  13913     }
  13914 
  13915 #define _BCM_QOS_PROFILE_ENTRIES_PER_SET 64
  13916 #ifdef BCM_TRIDENT3_SUPPORT
  13917     if (SOC_IS_TRIDENT3X(unit)) {
  13918         bcm_td3_egr_mpls_combo_dump(unit, info->egr_mpls_combo_map);
  13919     } else 
  13920 #endif
  13921     {
  13922     /* EGR_MPLS_PRI_MAPPING & EGR_MPLS_EXP_MAPPING_1 tables */
  13923     if (NULL != info->egr_mpls_combo_map) {
  13924         egr_mpls_pri_mapping_entry_t
  13925             egr_mpls_pri_map_entry[_BCM_QOS_PROFILE_ENTRIES_PER_SET];
  13926         egr_mpls_exp_mapping_1_entry_t
  13927             egr_mpls_exp_map_entry[_BCM_QOS_PROFILE_ENTRIES_PER_SET];
  13928         egr_mpls_exp_mapping_2_entry_t
  13929             egr_mpls_exp_map_2_entry[_BCM_QOS_PROFILE_ENTRIES_PER_SET];
  13930         int pri, new_cfi, cfi, exp;
  13931         int entries_per_set;
  13932         void *entries[3];
  13933 
  13934         mem = EGR_MPLS_PRI_MAPPINGm;
  13935         num_entries = soc_mem_index_count(unit, mem);
  13936         LOG_CLI((BSL_META_U(unit,
  13937                             "  EGR_MPLS_PRI_MAPPING & EGR_MPLS_EXP_MAP Combo Mem\n")));
  13938         LOG_CLI((BSL_META_U(unit,
  13939                             "    Number of entries: %d\n"), num_entries));
  13940         LOG_CLI((BSL_META_U(unit,
  13941                             "    Index RefCount EntriesPerSet - PRI CFI MPLS_EXP\n")));
  13942 
  13943         for (i = 0; i < num_entries;
  13944              i += _BCM_QOS_PROFILE_ENTRIES_PER_SET) {
  13945             rv = soc_profile_mem_ref_count_get(unit,
  13946                                                info->egr_mpls_combo_map,
  13947                                                i, &ref_count);
  13948             if (SOC_FAILURE(rv)) {
  13949                 LOG_CLI((BSL_META_U(unit,
  13950                                     " *** Error retrieving profile reference: %d ***\n"),
  13951                          rv));
  13952                 break;
  13953             }
  13954 
  13955             if (ref_count <= 0) {
  13956                 continue;
  13957             }
  13958 
  13959             entries[0] = &egr_mpls_pri_map_entry;
  13960             entries[1] = &egr_mpls_exp_map_entry;
  13961             entries[2] = &egr_mpls_exp_map_2_entry;
  13962 
  13963             rv = soc_profile_mem_get(unit, info->egr_mpls_combo_map,
  13964                                      i, _BCM_QOS_PROFILE_ENTRIES_PER_SET, entries);
  13965             if (SOC_FAILURE(rv)) {
  13966                 LOG_CLI((BSL_META_U(unit,
  13967                                     " *** Error retrieving profile data: %d ***\n"),
  13968                          rv));
  13969                 break;
  13970             }
  13971 
  13972             for (j = 0; j < _BCM_QOS_PROFILE_ENTRIES_PER_SET; j++) {
  13973                 entries_per_set =
  13974                     info->egr_mpls_combo_map->tables[0].entries[i + j].entries_per_set;
  13975 
  13976                 pri = soc_mem_field32_get(unit, mem,
  13977                                           &(egr_mpls_pri_map_entry[j]),
  13978                                           NEW_PRIf);
  13979                 new_cfi = soc_mem_field32_get(unit, mem,
  13980                                               &(egr_mpls_pri_map_entry[j]),
  13981                                               NEW_CFIf);
  13982                 cfi = -1;
  13983                 exp = -1;
  13984                 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) {
  13985                     cfi = soc_mem_field32_get(unit, EGR_MPLS_EXP_MAPPING_1m,
  13986                                               &(egr_mpls_exp_map_entry[j]),
  13987                                               CFIf);
  13988                     exp = soc_mem_field32_get(unit, EGR_MPLS_EXP_MAPPING_1m,
  13989                                               &(egr_mpls_exp_map_entry[j]),
  13990                                               MPLS_EXPf);
  13991                     LOG_CLI((BSL_META_U(unit,
  13992                                         "  %5d %8d %13d     %2d  %2d    %2d"),
  13993                              i + j, ref_count, entries_per_set,
  13994                              pri, cfi, exp));
  13995                     if (new_cfi != cfi) {
  13996                         LOG_CLI((BSL_META_U(unit,
  13997                                             "   CFI inconsistent!")));
  13998                     }
  13999                 } else {
  14000                     LOG_CLI((BSL_META_U(unit,
  14001                                         "  %5d %8d %13d     %2d  %2d    %2d"),
  14002                              i + j, ref_count, entries_per_set,
  14003                              pri, new_cfi, exp));
  14004                 }
  14005 
  14006                 LOG_CLI((BSL_META_U(unit,
  14007                                     "\n")));
  14008             }
  14009         }
  14010         LOG_CLI((BSL_META_U(unit,
  14011                             "\n")));
  14012     }
  14013     }
  14014 
  14015     /* DSCP_TABLE table */
  14016     if (NULL != info->dscp_table) {
  14017         uint32 *dscp_table_entry_p; /* Not using entry specific types */
  14018         int cng, pri, dscp;
  14019         int entries_per_set;
  14020         soc_field_t pri_t;
  14021 
  14022         if (SOC_IS_TRIDENT3X(unit)) {
  14023             mem = PHB_MAPPING_TBL_2m;
  14024             pri_t = INT_PRIf;
  14025         } else {
  14026         mem = DSCP_TABLEm;
  14027             pri_t = PRIf;
  14028         }
  14029 
  14030         num_entries = soc_mem_index_count(unit, mem);
  14031         LOG_CLI((BSL_META_U(unit,
  14032                             "  DSCP_TABLE Mem\n")));
  14033         LOG_CLI((BSL_META_U(unit,
  14034                             "    Number of entries: %d\n"), num_entries));
  14035         LOG_CLI((BSL_META_U(unit,
  14036                             "    Index RefCount EntriesPerSet - CNG PRI DSCP\n")));
  14037 
  14038         for (i = 0; i < num_entries;
  14039              i += _BCM_QOS_PROFILE_ENTRIES_PER_SET) {
  14040             rv = soc_profile_mem_ref_count_get(unit,
  14041                                                info->dscp_table,
  14042                                                i, &ref_count);
  14043             if (SOC_FAILURE(rv)) {
  14044                 LOG_CLI((BSL_META_U(unit,
  14045                                     " *** Error retrieving profile reference: %d ***\n"),
  14046                          rv));
  14047                 break;
  14048             }
  14049 
  14050             if (ref_count <= 0) {
  14051                 continue;
  14052             }
  14053 
  14054             for (j = 0; j < _BCM_QOS_PROFILE_ENTRIES_PER_SET; j++) {
  14055                 entries_per_set =
  14056                     info->dscp_table->tables[0].entries[i + j].entries_per_set;
  14057                 dscp_table_entry_p =
  14058                     SOC_PROFILE_MEM_ENTRY(unit, info->dscp_table,
  14059                                           uint32 *, i + j);
  14060                 cng = soc_mem_field32_get(unit, mem,
  14061                                           dscp_table_entry_p,
  14062                                           CNGf);
  14063                 pri = soc_mem_field32_get(unit, mem,
  14064                                           dscp_table_entry_p,
  14065                                           pri_t);
  14066                 dscp = soc_mem_field32_get(unit, mem,
  14067                                            dscp_table_entry_p,
  14068                                            DSCPf);
  14069 
  14070                 LOG_CLI((BSL_META_U(unit,
  14071                                     "  %5d %8d %13d     %2d  %2d  %2d\n"),
  14072                          i + j, ref_count, entries_per_set,
  14073                          cng, pri, dscp));
  14074             }
  14075         }
  14076         LOG_CLI((BSL_META_U(unit,
  14077                             "\n")));
  14078     }
  14079 
  14080 #ifdef BCM_TRIDENT_SUPPORT
  14081 #define _BCM_QOS_ING_OUTER_DOT1P_MAPPING_ENTRIES_PER_SET 16
  14082     if (NULL != info->ing_outer_dot1p) {
  14083         int n_cfi, n_dot1p;
  14084         int entries_per_set;
  14085         ing_outer_dot1p_mapping_table_entry_t *dot1p_entry_p;
  14086         mem = ING_OUTER_DOT1P_MAPPING_TABLEm;
  14087 
  14088         num_entries = soc_mem_index_count(unit, mem);
  14089         LOG_CLI((BSL_META_U(unit,
  14090                     "  ING_OUTER_DOT1P_MAPPING_TABLE Mem\n")));
  14091         LOG_CLI((BSL_META_U(unit,
  14092                     "    Number of entries: %d\n"), num_entries));
  14093         LOG_CLI((BSL_META_U(unit,
  14094                     "    Index RefCount EntriesPerSet - NewCFI NewDOT1P\n")));
  14095 
  14096         for (i = 0; i < num_entries;
  14097                 i += _BCM_QOS_ING_OUTER_DOT1P_MAPPING_ENTRIES_PER_SET) {
  14098             rv = soc_profile_mem_ref_count_get(unit,
  14099                                                info->ing_outer_dot1p,
  14100                                                i, &ref_count);
  14101             if (SOC_FAILURE(rv)) {
  14102                 LOG_CLI((BSL_META_U(unit,
  14103                     " *** Error retrieving profile reference: %d ***\n"), rv));
  14104                 break;
  14105             }
  14106 
  14107             if (ref_count <= 0) {
  14108                 continue;
  14109             }
  14110 
  14111             for (j = 0;
  14112                     j < _BCM_QOS_ING_OUTER_DOT1P_MAPPING_ENTRIES_PER_SET; j++) {
  14113                 entries_per_set =
  14114                   info->ing_outer_dot1p->tables[0].entries[i+j].entries_per_set;
  14115                 dot1p_entry_p =
  14116                     SOC_PROFILE_MEM_ENTRY(unit, info->ing_outer_dot1p,
  14117                         ing_outer_dot1p_mapping_table_entry_t *, i + j);
  14118                 n_cfi = soc_mem_field32_get(unit, mem, dot1p_entry_p, NEW_CFIf);
  14119                 n_dot1p =
  14120                     soc_mem_field32_get(unit, mem, dot1p_entry_p, NEW_DOT1Pf);
  14121 
  14122                 LOG_CLI((BSL_META_U(unit,
  14123                         "  %5d %8d %13d      %2d       %2d\n"),
  14124                         i + j, ref_count, entries_per_set, n_cfi, n_dot1p));
  14125             }
  14126         }
  14127         LOG_CLI((BSL_META_U(unit, "\n")));
  14128     }
  14129 #undef _BCM_QOS_ING_OUTER_DOT1P_MAPPING_ENTRIES_PER_SET
  14130 #endif /* BCM_TRIDENT_SUPPORT */
  14131 
  14132     if(soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
  14133         /* EGR_PRI_CNG_MAP & EGR_DSCP_TABLE tables */
  14134         if (NULL != info->egr_qos_profile) {
  14135             egr_pri_cng_map_entry_t
  14136                 egr_pri_cng_map_entry[_BCM_QOS_PROFILE_ENTRIES_PER_SET];
  14137             egr_dscp_table_entry_t
  14138                 egr_dscp_table_entry[_BCM_QOS_PROFILE_ENTRIES_PER_SET];
  14139             int pri, cfi, dscp;
  14140             int entries_per_set;
  14141             void *entries[2];
  14142 
  14143             if (SOC_IS_TRIDENT3X(unit)) {
  14144                 mem = EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m;
  14145             } else {
  14146             mem = EGR_PRI_CNG_MAPm;
  14147             }
  14148             num_entries = soc_mem_index_count(unit, mem);
  14149             LOG_CLI((BSL_META_U(unit,
  14150                                 "  EGR_PRI_CNG_MAP & EGR_DSCP_TABLE Combo Mem\n")));
  14151             LOG_CLI((BSL_META_U(unit,
  14152                                 "    Number of entries: %d\n"), num_entries));
  14153             LOG_CLI((BSL_META_U(unit,
  14154                                 "    Index RefCount EntriesPerSet - PRI CFI DSCP\n")));
  14155 
  14156             for (i = 0; i < num_entries;
  14157                  i += _BCM_QOS_PROFILE_ENTRIES_PER_SET) {
  14158                 rv = soc_profile_mem_ref_count_get(unit,
  14159                                                    info->egr_qos_profile,
  14160                                                    i, &ref_count);
  14161                 if (SOC_FAILURE(rv)) {
  14162                     LOG_CLI((BSL_META_U(unit,
  14163                                         " *** Error retrieving profile reference: %d ***\n"),
  14164                              rv));
  14165                     break;
  14166                 }
  14167 
  14168                 if (ref_count <= 0) {
  14169                     continue;
  14170                 }
  14171 
  14172                 entries[0] = &egr_pri_cng_map_entry;
  14173                 entries[1] = &egr_dscp_table_entry;
  14174 
  14175                 rv = soc_profile_mem_get(unit, info->egr_qos_profile,
  14176                                          i, _BCM_QOS_PROFILE_ENTRIES_PER_SET, entries);
  14177                 if (SOC_FAILURE(rv)) {
  14178                     LOG_CLI((BSL_META_U(unit,
  14179                                         " *** Error retrieving profile data: %d ***\n"),
  14180                              rv));
  14181                     break;
  14182                 }
  14183 
  14184                 for (j = 0; j < _BCM_QOS_PROFILE_ENTRIES_PER_SET; j++) {
  14185                     entries_per_set =
  14186                         info->egr_qos_profile->tables[0].entries[i + j].entries_per_set;
  14187 
  14188                     pri = soc_mem_field32_get(unit, mem,
  14189                                               &(egr_pri_cng_map_entry[j]),
  14190                                               PRIf);
  14191                     cfi = soc_mem_field32_get(unit, mem,
  14192                                                   &(egr_pri_cng_map_entry[j]),
  14193                                                   CFIf);
  14194                     dscp = -1;
  14195                     if (SOC_MEM_IS_VALID(unit, EGR_DSCP_TABLEm)) {
  14196                         dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm,
  14197                                                   &(egr_dscp_table_entry[j]),
  14198                                                   DSCPf);
  14199                         LOG_CLI((BSL_META_U(unit,
  14200                                             "  %5d %8d %13d     %2d  %2d    %2d"),
  14201                                  i + j, ref_count, entries_per_set,
  14202                                  pri, cfi, dscp));
  14203                     } else {
  14204                         LOG_CLI((BSL_META_U(unit,
  14205                                             "  %5d %8d %13d     %2d  %2d    %2d"),
  14206                                  i + j, ref_count, entries_per_set,
  14207                                  pri, cfi, dscp));
  14208                     }
  14209 
  14210                     LOG_CLI((BSL_META_U(unit,
  14211                                         "\n")));
  14212                 }
  14213             }
  14214             LOG_CLI((BSL_META_U(unit,
  14215                                 "\n")));
  14216         }
  14217     }else {
  14218     /* EGR_DSCP_TABLE table */
  14219     if (NULL != info->egr_dscp_table) {
  14220         egr_dscp_table_entry_t *egr_dscp_table_entry_p;
  14221         int entries_per_set;
  14222         int dscp;
  14223 
  14224             if (SOC_IS_TRIDENT3X(unit)) {
  14225                 mem = EGR_ZONE_2_QOS_MAPPING_TABLEm;
  14226             } else {
  14227             mem = EGR_DSCP_TABLEm;
  14228             }
  14229             num_entries = soc_mem_index_count(unit, mem);
  14230             LOG_CLI((BSL_META_U(unit,
  14231                                 "  EGR_DSCP_TABLE Mem\n")));
  14232             LOG_CLI((BSL_META_U(unit,
  14233                                 "    Number of entries: %d\n"), num_entries));
  14234             LOG_CLI((BSL_META_U(unit,
  14235                                 "    Index RefCount EntriesPerSet - DSCP\n")));
  14236 
  14237         for (i = 0; i < num_entries;
  14238              i += _BCM_QOS_PROFILE_ENTRIES_PER_SET) {
  14239             rv = soc_profile_mem_ref_count_get(unit,
  14240                                                info->egr_dscp_table,
  14241                                                i, &ref_count);
  14242             if (SOC_FAILURE(rv)) {
  14243                 LOG_CLI((BSL_META_U(unit,
  14244                                     " *** Error retrieving profile reference: %d ***\n"),
  14245                          rv));
  14246                 break;
  14247             }
  14248 
  14249             if (ref_count <= 0) {
  14250                 continue;
  14251             }
  14252 
  14253 
  14254 
  14255                 for (j = 0; j < _BCM_QOS_PROFILE_ENTRIES_PER_SET; j++) {
  14256                     entries_per_set =
  14257                         info->egr_dscp_table->tables[0].entries[i + j].entries_per_set;
  14258                     egr_dscp_table_entry_p = (egr_dscp_table_entry_t *)
  14259                         SOC_PROFILE_MEM_ENTRY(unit, info->egr_dscp_table,
  14260                                           uint32 *,
  14261                                               i + j);
  14262                     dscp = soc_mem_field32_get(unit, mem,
  14263                                                egr_dscp_table_entry_p,
  14264                                                DSCPf);
  14265 
  14266                 LOG_CLI((BSL_META_U(unit,
  14267                                     "  %5d %8d %13d     %2d\n"),
  14268                          i + j, ref_count, entries_per_set,
  14269                          dscp));
  14270             }
  14271         }
  14272         LOG_CLI((BSL_META_U(unit,
  14273                             "\n")));
  14274     }
  14275     }
  14276     
  14277     if (NULL != info->prot_pkt_ctrl) {
  14278         uint32 prot_pkt_ctrl;
  14279         uint32 igmp_mld_pkt_ctrl;
  14280 
  14281         num_entries = SOC_REG_NUMELS(unit, PROTOCOL_PKT_CONTROLr);
  14282         LOG_CLI((BSL_META_U(unit,
  14283                             "  PROTOCOL_PKT_CONTROL & IGMP_MLD_PKT_CONTROL\n")));
  14284         LOG_CLI((BSL_META_U(unit,
  14285                             "    Number of entries: %d\n"), num_entries));
  14286         LOG_CLI((BSL_META_U(unit,
  14287                             "    Index RefCount -  Protocol    IGMP_MLD\n")));
  14288 
  14289         for (i = 0; i < num_entries; i++) {
  14290             rv = soc_profile_reg_ref_count_get(unit,
  14291                                                info->prot_pkt_ctrl,
  14292                                                i, &ref_count);
  14293             if (SOC_FAILURE(rv)) {
  14294                 LOG_CLI((BSL_META_U(unit,
  14295                                     " *** Error retrieving profile reference: %d ***\n"),
  14296                          rv));
  14297                 break;
  14298             }
  14299             if (ref_count <= 0) {
  14300                 continue;
  14301             }
  14302 
  14303             prot_pkt_ctrl = 0;
  14304             igmp_mld_pkt_ctrl = 0;
  14305             rv = _bcm_prot_pkt_ctrl_get(unit, i, &prot_pkt_ctrl,
  14306                                         &igmp_mld_pkt_ctrl);
  14307             if (SOC_FAILURE(rv)) {
  14308                 LOG_CLI((BSL_META_U(unit,
  14309                                     " *** Error retrieving profile register data: %d ***\n"),
  14310                          rv));
  14311                 break;
  14312             }
  14313 
  14314             LOG_CLI((BSL_META_U(unit,
  14315                                 "  %5d %8d      0x%08x  0x%08x\n"),
  14316                      i, ref_count, prot_pkt_ctrl, igmp_mld_pkt_ctrl));
  14317         }
  14318         LOG_CLI((BSL_META_U(unit,
  14319                             "\n")));
  14320     }
  14321 
  14322 #ifdef BCM_TRIUMPH2_SUPPORT
  14323     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  14324         _bcm_flex_stat_type_t fs_type, hw_type;
  14325         uint32 fs_index;
  14326         _bcm_flex_stat_handle_t fs_handle;
  14327         int list_index, list_size;
  14328         const char *fs_type_string[_bcmFlexStatTypeNum] = {
  14329             "Service",
  14330             "Gport",
  14331             "Field",
  14332             "VRF",
  14333             "Vxlt",
  14334             "EgrVxlt"
  14335         };
  14336 
  14337         LOG_CLI((BSL_META_U(unit,
  14338                             "  Flexible statistics\n")));
  14339         for (hw_type = _bcmFlexStatTypeService;
  14340              hw_type < _bcmFlexStatTypeAllHwNum; hw_type++) {
  14341             
  14342             list_size = FS_HANDLE_LIST_SIZE(unit, hw_type);
  14343 
  14344             LOG_CLI((BSL_META_U(unit,
  14345                                 "    %s type, Mem size %5d, List size %5d\n"),
  14346                      fs_type_string[hw_type],
  14347                      FS_MEM_SIZE(unit, hw_type),
  14348                      list_size));
  14349             if (0 == list_size) {
  14350                 continue;
  14351             }
  14352             LOG_CLI((BSL_META_U(unit,
  14353                                 "       Handle                  Index      Type\n")));
  14354             for (list_index = 0; list_index < list_size; list_index++) {
  14355                 _BCM_FLEX_STAT_HANDLE_ASSIGN(fs_handle,
  14356                           FS_HANDLE_LIST_ELEMENT_HANDLE(unit, hw_type,
  14357                                                         list_index));
  14358                 fs_index = FS_HANDLE_LIST_ELEMENT_INDEX(unit, hw_type,
  14359                                                         list_index);
  14360                 fs_type = FS_HANDLE_LIST_ELEMENT_TYPE(unit, hw_type,
  14361                                                       list_index);
  14362 
  14363                 if (fs_type >= _bcmFlexStatTypeNum) {
  14364                     continue;
  14365                 }
  14366                 LOG_CLI((BSL_META_U(unit,
  14367                                     "       0x%08x 0x%08x %5d        %s\n"),
  14368                          _BCM_FLEX_STAT_HANDLE_WORD_GET(fs_handle, 1),
  14369                          _BCM_FLEX_STAT_HANDLE_WORD_GET(fs_handle, 0),
  14370                          fs_index, fs_type_string[fs_type]));
  14371             }
  14372         }
  14373     }
  14374 #endif /* BCM_TRIUMPH2_SUPPORT */
  14375 
  14376 #ifdef BCM_HURRICANE3_SUPPORT
  14377     /* EGR_HEADER_ENCAP_DATA table */
  14378     if (NULL != info->egr_header_encap_data) {
  14379         egr_header_encap_data_entry_t *egr_header_encap_data_entry_p;
  14380         int  pri_select;
  14381         uint32  map_id;
  14382         uint32  fld_value;
  14383 
  14384         mem = EGR_HEADER_ENCAP_DATAm;
  14385         num_entries = soc_mem_index_count(unit, mem);
  14386         LOG_CLI((BSL_META_U(unit,
  14387                             "  EGR_HEADER_ENCAP_DATA Mem\n")));
  14388         LOG_CLI((BSL_META_U(unit,
  14389                             "    Number of entries: %d\n"), num_entries));
  14390         LOG_CLI((BSL_META_U(unit,
  14391                             "    Index RefCount - VALUE32     PRI_SEL MAP_ID\n")));
  14392 
  14393         for (i = 0; i < num_entries; i++) {
  14394             rv = soc_profile_mem_ref_count_get(unit,
  14395                                                info->egr_header_encap_data,
  14396                                                i, &ref_count);
  14397             if (SOC_FAILURE(rv)) {
  14398                 LOG_CLI((BSL_META_U(unit,
  14399                                     " *** Error retrieving profile reference: %d ***\n"), rv));
  14400                 break;
  14401             }
  14402 
  14403             if (ref_count <= 0) {
  14404                 continue;
  14405             }
  14406 
  14407             egr_header_encap_data_entry_p =
  14408                 SOC_PROFILE_MEM_ENTRY(unit, info->egr_header_encap_data,
  14409                                       egr_header_encap_data_entry_t *, i);
  14410 
  14411             pri_select = soc_mem_field32_get(unit, mem,
  14412                                        egr_header_encap_data_entry_p,
  14413                                        CUSTOM_PRI_SELECTf);
  14414             map_id = soc_mem_field32_get(unit, mem,
  14415                                        egr_header_encap_data_entry_p,
  14416                                        CUSTOM_PRI_MAPPING_PTRf);
  14417             fld_value = soc_mem_field32_get(unit, mem,
  14418                                        egr_header_encap_data_entry_p,
  14419                                        CUSTOM_PACKET_HEADERf);
  14420             LOG_CLI((BSL_META_U(unit,
  14421                                 "  %5d %8d     0x%08x  %5d %5d\n"), 
  14422                                 i, ref_count, fld_value, pri_select, map_id));
  14423         }
  14424         LOG_CLI((BSL_META_U(unit, "\n")));
  14425     }
  14426 
  14427     /* CUSTOM_HEADER_MATCHm table */
  14428     if (NULL != info->custom_header_match) {
  14429         custom_header_match_entry_t *custom_header_match_entry_p;
  14430         int f_valid;
  14431         uint32 f_custom_header;
  14432 
  14433         mem = CUSTOM_HEADER_MATCHm;
  14434         num_entries = soc_mem_index_count(unit, mem);
  14435         LOG_CLI((BSL_META_U(unit,
  14436                             "  CUSTOM_HEADER_MATCH Mem\n")));
  14437         LOG_CLI((BSL_META_U(unit,
  14438                             "  Number of entries: %d\n"), num_entries));
  14439         LOG_CLI((BSL_META_U(unit,
  14440                             "  %10s\t%10s\t%10s\t%-20s\n"),
  14441                             "Index", "RefCount", "VALID", "CUSTOM_HEADER"));
  14442 
  14443         for (i = 0; i < num_entries; i++) {
  14444             rv = soc_profile_mem_ref_count_get(unit,
  14445                                                info->custom_header_match,
  14446                                                i, &ref_count);
  14447             if (SOC_FAILURE(rv)) {
  14448                 LOG_CLI((BSL_META_U(unit,
  14449                                     " *** Error retrieving profile reference: %d ***\n"), rv));
  14450                 break;
  14451             }
  14452 
  14453             if (ref_count <= 0) {
  14454                 continue;
  14455             }
  14456 
  14457             custom_header_match_entry_p =
  14458                 SOC_PROFILE_MEM_ENTRY(unit, info->custom_header_match,
  14459                                       custom_header_match_entry_t *, i);
  14460 
  14461             f_valid = soc_mem_field32_get(unit, mem,
  14462                                        custom_header_match_entry_p,
  14463                                        VALIDf);
  14464             f_custom_header = soc_mem_field32_get(unit, mem,
  14465                                        custom_header_match_entry_p,
  14466                                        CUSTOM_HEADERf);
  14467 
  14468             LOG_CLI((BSL_META_U(unit,
  14469                                 "  %10d\t%10d\t%10d\t0x%-20x\n"), 
  14470                                 i, ref_count, f_valid, f_custom_header));
  14471         }
  14472         LOG_CLI((BSL_META_U(unit, "\n")));
  14473     }
  14474 #endif /* BCM_HURRICANE3_SUPPORT */
  14475 #ifdef BCM_TOMAHAWK_SUPPORT
  14476     if (NULL != info->ing_tunnel_term_map) {
  14477         ing_tunnel_ecn_decap_entry_t *ing_tunnel_ecn_decap_map_p;
  14478         int  inner_ecn;
  14479         int  drop;
  14480         mem = ING_TUNNEL_ECN_DECAPm;
  14481         num_entries = soc_mem_index_count(unit, mem);
  14482         LOG_CLI((BSL_META_U(unit,
  14483                             "  ING_TUNNEL_TERM_MAP Mem\n")));
  14484         LOG_CLI((BSL_META_U(unit,
  14485                             "    Number of entries: %d\n"), num_entries));
  14486         LOG_CLI((BSL_META_U(unit,
  14487                             "    Index RefCount      INNER_ECN DROP\n")));
  14488 
  14489         for (i = 0; i < num_entries; i++) {
  14490             rv = soc_profile_mem_ref_count_get(unit,
  14491                                                info->ing_tunnel_term_map,
  14492                                                i, &ref_count);
  14493             if (SOC_FAILURE(rv)) {
  14494                 LOG_CLI((BSL_META_U(unit,
  14495                                     " *** Error retrieving profile reference: %d ***\n"), rv));
  14496                 break;
  14497             }
  14498 
  14499             if (ref_count <= 0) {
  14500                 continue;
  14501             }
  14502 
  14503             ing_tunnel_ecn_decap_map_p =
  14504                 SOC_PROFILE_MEM_ENTRY(unit, info->ing_tunnel_term_map,
  14505                                       ing_tunnel_ecn_decap_entry_t *, i);
  14506 
  14507             inner_ecn = soc_mem_field32_get(unit, mem,
  14508                                             ing_tunnel_ecn_decap_map_p,
  14509                                             INNER_ECNf);
  14510             drop = soc_mem_field32_get(unit, mem,
  14511                                        ing_tunnel_ecn_decap_map_p,
  14512                                        DROPf);
  14513             LOG_CLI((BSL_META_U(unit,
  14514                                 "  %5d %8d       %5d %5d\n"), 
  14515                                 i, ref_count, inner_ecn, drop));
  14516         }
  14517         LOG_CLI((BSL_META_U(unit, "\n")));
  14518     }
  14519 #endif /* BCM_TOMAHAWK_SUPPORT */
  14520 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
  14521     defined(BCM_TRIDENT3_SUPPORT)
  14522     if (NULL != info->ing_exp_to_ip_ecn_map) {
  14523         ing_exp_to_ip_ecn_mapping_entry_t *ing_exp_to_ip_ecn_map_p;
  14524         int  ecn;
  14525         int  drop;
  14526 
  14527 #if defined(BCM_TRIDENT3_SUPPORT)
  14528         if(soc_feature(unit, soc_feature_td3_style_mpls)) {
  14529             mem = ING_EXP_TO_ECN_MAPPING_1m;
  14530         } else
  14531 #endif
  14532         {
  14533         mem = ING_EXP_TO_IP_ECN_MAPPINGm;
  14534         }
  14535         num_entries = soc_mem_index_count(unit, mem);
  14536         LOG_CLI((BSL_META_U(unit,
  14537                             "  ING_EXP_TO_IP_ECN_MAP Mem\n")));
  14538         LOG_CLI((BSL_META_U(unit,
  14539                             "    Number of entries: %d\n"), num_entries));
  14540         LOG_CLI((BSL_META_U(unit,
  14541                             "    Index RefCount      ECN DROP\n")));
  14542 
  14543         for (i = 0; i < num_entries; i++) {
  14544             rv = soc_profile_mem_ref_count_get(unit,
  14545                                                info->ing_exp_to_ip_ecn_map,
  14546                                                i, &ref_count);
  14547             if (SOC_FAILURE(rv)) {
  14548                 LOG_CLI((BSL_META_U(unit,
  14549                                     " *** Error retrieving profile reference: %d ***\n"), rv));
  14550                 break;
  14551             }
  14552 
  14553             if (ref_count <= 0) {
  14554                 continue;
  14555             }
  14556 
  14557             ing_exp_to_ip_ecn_map_p =
  14558                 SOC_PROFILE_MEM_ENTRY(unit, info->ing_exp_to_ip_ecn_map,
  14559                                       ing_exp_to_ip_ecn_mapping_entry_t *, i);
  14560 
  14561             ecn = soc_mem_field32_get(unit, mem,
  14562                                       ing_exp_to_ip_ecn_map_p,
  14563                                       ECNf);
  14564             drop = soc_mem_field32_get(unit, mem,
  14565                                        ing_exp_to_ip_ecn_map_p,
  14566                                        DROPf);
  14567             LOG_CLI((BSL_META_U(unit,
  14568                                 "  %5d %8d       %5d %5d \n"), 
  14569                                 i, ref_count, ecn, drop));
  14570         }
  14571         LOG_CLI((BSL_META_U(unit, "\n")));
  14572     }
  14573     if (NULL != info->egr_ip_ecn_to_exp_map) {
  14574         egr_ip_ecn_to_exp_mapping_table_entry_t *egr_ip_ecn_to_exp_map_p;
  14575         int  exp;
  14576         int  drop;
  14577         int  mark_enable;
  14578         int  exp_res;
  14579         int  drop_res;
  14580         int  mark_enable_res;
  14581 
  14582 #if defined(BCM_TRIDENT3_SUPPORT)
  14583     if(soc_feature(unit, soc_feature_td3_style_mpls)) {
  14584         mem = EGR_PKT_ECN_TO_EXP_MAPPING_1m;
  14585     } else
  14586 #endif
  14587     {
  14588         mem = EGR_IP_ECN_TO_EXP_MAPPING_TABLEm;
  14589     }
  14590         num_entries = soc_mem_index_count(unit, mem);
  14591         LOG_CLI((BSL_META_U(unit,
  14592                             "  EGR_IP_ECN_TO_EXP_MAP Mem\n")));
  14593         LOG_CLI((BSL_META_U(unit,
  14594                             "    Number of entries: %d\n"), num_entries));
  14595         LOG_CLI((BSL_META_U(unit,
  14596                             "    RESPONSIVE \n")));
  14597         LOG_CLI((BSL_META_U(unit,
  14598                             "    Index RefCount      ECN DROP MARK ECN_RES DROP_RES MARK_RES\n")));
  14599 
  14600         for (i = 0; i < num_entries; i++) {
  14601             rv = soc_profile_mem_ref_count_get(unit,
  14602                                                info->egr_ip_ecn_to_exp_map,
  14603                                                i, &ref_count);
  14604             if (SOC_FAILURE(rv)) {
  14605                 LOG_CLI((BSL_META_U(unit,
  14606                                     " *** Error retrieving profile reference: %d ***\n"), rv));
  14607                 break;
  14608             }
  14609 
  14610             if (ref_count <= 0) {
  14611                 continue;
  14612             }
  14613 
  14614             egr_ip_ecn_to_exp_map_p =
  14615                 SOC_PROFILE_MEM_ENTRY(unit, info->egr_ip_ecn_to_exp_map,
  14616                                       egr_ip_ecn_to_exp_mapping_table_entry_t *, 
  14617                                       i);
  14618 
  14619             exp = soc_mem_field32_get(unit, mem,
  14620                                       egr_ip_ecn_to_exp_map_p,
  14621                                       EXPf);
  14622             drop = soc_mem_field32_get(unit, mem,
  14623                                        egr_ip_ecn_to_exp_map_p,
  14624                                        DROPf);
  14625             mark_enable = soc_mem_field32_get(unit, mem,
  14626                                               egr_ip_ecn_to_exp_map_p,
  14627                                               CHANGE_PACKET_EXPf); 
  14628             exp_res = soc_mem_field32_get(unit, mem,
  14629                                           egr_ip_ecn_to_exp_map_p,
  14630                                           RESPONSIVE_EXPf);
  14631             drop_res = soc_mem_field32_get(unit, mem,
  14632                                            egr_ip_ecn_to_exp_map_p,
  14633                                            RESPONSIVE_DROPf);
  14634             mark_enable_res = soc_mem_field32_get(unit, mem,
  14635                                                   egr_ip_ecn_to_exp_map_p,
  14636                                                   RESPONSIVE_CHANGE_PACKET_EXPf);                 
  14637             LOG_CLI((BSL_META_U(unit,
  14638                                 "  %5d %8d       %5d %5d %5d %5d %5d %5d \n"), 
  14639                                 i, ref_count, exp, drop, mark_enable, 
  14640                                 exp_res, drop_res, mark_enable_res));
  14641         }       
  14642         LOG_CLI((BSL_META_U(unit, "\n")));
  14643     } 
  14644     if (NULL != info->egr_int_cn_to_exp_map) {
  14645         egr_int_cn_to_exp_mapping_table_entry_t *egr_int_cn_to_exp_map_p;
  14646         int  exp;
  14647         int  drop;
  14648         int  mark_enable;
  14649         mem = EGR_INT_CN_TO_EXP_MAPPING_TABLEm;
  14650         num_entries = soc_mem_index_count(unit, mem);
  14651         LOG_CLI((BSL_META_U(unit,
  14652                             "  EGR_INT_CN_TO_EXP_MAP Mem\n")));
  14653         LOG_CLI((BSL_META_U(unit,
  14654                             "    Number of entries: %d\n"), num_entries));
  14655         LOG_CLI((BSL_META_U(unit,
  14656                             "    Index RefCount      ECN DROP MARK \n")));
  14657 
  14658         for (i = 0; i < num_entries; i++) {
  14659             rv = soc_profile_mem_ref_count_get(unit,
  14660                                                info->egr_int_cn_to_exp_map,
  14661                                                i, &ref_count);
  14662             if (SOC_FAILURE(rv)) {
  14663                 LOG_CLI((BSL_META_U(unit,
  14664                                     " *** Error retrieving profile reference: %d ***\n"), rv));
  14665                 break;
  14666             }
  14667 
  14668             if (ref_count <= 0) {
  14669                 continue;
  14670             }
  14671 
  14672             egr_int_cn_to_exp_map_p =
  14673                 SOC_PROFILE_MEM_ENTRY(unit, info->egr_int_cn_to_exp_map,
  14674                                       egr_int_cn_to_exp_mapping_table_entry_t *, 
  14675                                       i);
  14676 
  14677             exp = soc_mem_field32_get(unit, mem,
  14678                                       egr_int_cn_to_exp_map_p,
  14679                                       EXPf);
  14680             drop = soc_mem_field32_get(unit, mem,
  14681                                        egr_int_cn_to_exp_map_p,
  14682                                        DROPf);
  14683             mark_enable = soc_mem_field32_get(unit, mem,
  14684                                               egr_int_cn_to_exp_map_p,
  14685                                               CHANGE_PACKET_EXPf);             
  14686             LOG_CLI((BSL_META_U(unit,
  14687                                 "  %5d %8d       %5d %5d %5d \n"), 
  14688                                 i, ref_count, exp, drop, mark_enable));
  14689         }       
  14690         LOG_CLI((BSL_META_U(unit, "\n")));
  14691     }        
  14692 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */
  14693 #ifdef BCM_TRIDENT2_SUPPORT
  14694     if (NULL != info->l3_iif_profile) {
  14695         mem = L3_IIF_PROFILEm;
  14696         num_entries = soc_mem_index_count(unit, mem);
  14697         LOG_CLI((BSL_META_U(unit,
  14698                             "  L3 IIF PROFILE Mem\n")));
  14699         LOG_CLI((BSL_META_U(unit,
  14700                             "    Number of entries: %d\n"), num_entries));
  14701         LOG_CLI((BSL_META_U(unit,
  14702                             "    Index RefCount      \n")));
  14703 
  14704         for (i = 0; i < num_entries; i++) {
  14705             rv = soc_profile_mem_ref_count_get(unit,
  14706                                                info->l3_iif_profile,
  14707                                                i, &ref_count);
  14708             if (SOC_FAILURE(rv)) {
  14709                 LOG_CLI((BSL_META_U(unit,
  14710                                     " *** Error retrieving profile reference: %d ***\n"), rv));
  14711                 break;
  14712             }
  14713 
  14714             if (ref_count <= 0) {
  14715                 continue;
  14716             }
  14717             
  14718             LOG_CLI((BSL_META_U(unit,
  14719                                 "  %5d %8d       \n"), 
  14720                                 i, ref_count));
  14721         }       
  14722         LOG_CLI((BSL_META_U(unit, "\n")));
  14723     }
  14724 #endif        
  14725     return;
  14726 }
  14727 #endif /* BCM_WARM_BOOT_SUPPORT_SW_DUMP */