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

flex_ctr_common.c (1016663B)


      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:        flex_ctr_common.c
      8  * Purpose:     Manage common functionality for flex counter implementation
      9  */
     10 
     11 #include <shared/bsl.h>
     12 #include <soc/drv.h>
     13 #include <bcm_int/esw/flex_ctr.h>
     14 #include <bcm_int/esw/stat.h>
     15 #include <bcm_int/esw/virtual.h>
     16 #include <bcm_int/esw/field.h>
     17 #if defined (INCLUDE_FLOWTRACKER)
     18 #include <bcm_int/esw/flowtracker.h>
     19 #endif /* INCLUDE_FLOWTRACKER */
     20 #include <shared/idxres_afl.h>
     21 #include <soc/scache.h>
     22 #include <bcm_int/esw/mpls.h>
     23 #if defined (BCM_TRIDENT2PLUS_SUPPORT) && defined (INCLUDE_L3)
     24 #include <bcm_int/esw/triumph.h>
     25 #endif
     26 #ifdef BCM_TOMAHAWK_SUPPORT
     27 #include <soc/tomahawk.h>
     28 #include <bcm_int/esw/tomahawk.h>
     29 #ifdef ALPM_ENABLE
     30 #include <bcm_int/esw/alpm.h>
     31 #include <bcm_int/esw/alpm_util.h>
     32 #endif
     33 #endif
     34 #define _MAX_PIPES_PER_DEV(unit) ((SOC_INFO(unit).num_pipe))
     35 #if defined(BCM_TRIDENT2_SUPPORT)
     36 #include <soc/trident2.h>
     37 #include <bcm_int/esw/triumph2.h>
     38 #endif
     39 #include <soc/format.h>
     40 #if defined(BCM_TRIDENT3_SUPPORT)
     41 #include <soc/esw/flow_db.h>
     42 #include <bcm_int/esw/xgs5.h>
     43 #include <bcm_int/esw/vxlan.h>
     44 #endif
     45 
     46 #include <bcm_int/esw/latency_monitor.h>
     47 
     48 #ifdef ALPM_ENABLE
     49 #ifdef BCM_TOMAHAWK_SUPPORT
     50 extern uint32 *alpm_bkt_node_ptr_arr_get(uint32 idx);
     51 #endif
     52 #endif
     53 
     54 #ifdef ALPM_ENABLE
     55 #ifdef BCM_TOMAHAWK_SUPPORT
     56 extern uint32 *alpm_bkt_node_ptr_arr_get(uint32 idx);
     57 #endif
     58 #endif
     59 
     60 uint8     bcm_stat_flex_packet_attr_type_names_t[][64] = {
     61           "bcmStatFlexPacketAttrTypeUncompressed",
     62           "bcmStatFlexPacketAttrTypeCompressed",
     63           "bcmStatFlexPacketAttrTypeUdf"};
     64 static soc_reg_t _pool_ctr_register[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
     65 #ifndef BCM_TOMAHAWK_SUPPORT
     66                                    [BCM_STAT_FLEX_COUNTER_MAX_POOL] = {
     67 #else
     68                                    [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL] = {
     69 #endif
     70                  {ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_0r,
     71                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_1r,
     72                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_2r,
     73                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_3r,
     74                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_4r,
     75                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_5r,
     76                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_6r,
     77                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_7r,
     78 #ifdef BCM_TRIUMPH3_SUPPORT
     79                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_8r,
     80                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_9r,
     81                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_10r,
     82                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_11r,
     83                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_12r,
     84                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_13r,
     85                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_14r,
     86                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_15r,
     87 #ifdef BCM_TOMAHAWK_SUPPORT
     88                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_16r,
     89                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_17r,
     90                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_18r,
     91                   ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_19r
     92 #endif
     93                   },
     94 #else
     95                   0, 0, 0, 0, 0, 0, 0, 0 /* Kept it for future updates */},
     96 #endif
     97                  {EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_0r,
     98                   EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_1r,
     99                   EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_2r,
    100                   EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_3r,
    101                   EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_4r,
    102                   EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_5r,
    103                   EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_6r,
    104                   EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_7r,
    105                   0, 0, 0, 0, 0, 0, 0, 0 /* Kept it for future updates */}
    106                  };
    107 static soc_mem_t _ctr_offset_table[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    108 #ifndef BCM_TOMAHAWK_SUPPORT
    109                                   [BCM_STAT_FLEX_COUNTER_MAX_POOL] = {
    110 #else
    111                                    [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL] = {
    112 #endif
    113                  {ING_FLEX_CTR_OFFSET_TABLE_0m,
    114                   ING_FLEX_CTR_OFFSET_TABLE_1m,
    115                   ING_FLEX_CTR_OFFSET_TABLE_2m,
    116                   ING_FLEX_CTR_OFFSET_TABLE_3m,
    117                   ING_FLEX_CTR_OFFSET_TABLE_4m,
    118                   ING_FLEX_CTR_OFFSET_TABLE_5m,
    119                   ING_FLEX_CTR_OFFSET_TABLE_6m,
    120                   ING_FLEX_CTR_OFFSET_TABLE_7m,
    121 #ifdef BCM_TRIUMPH3_SUPPORT
    122                   ING_FLEX_CTR_OFFSET_TABLE_8m,
    123                   ING_FLEX_CTR_OFFSET_TABLE_9m,
    124                   ING_FLEX_CTR_OFFSET_TABLE_10m,
    125                   ING_FLEX_CTR_OFFSET_TABLE_11m,
    126                   ING_FLEX_CTR_OFFSET_TABLE_12m,
    127                   ING_FLEX_CTR_OFFSET_TABLE_13m,
    128                   ING_FLEX_CTR_OFFSET_TABLE_14m,
    129                   ING_FLEX_CTR_OFFSET_TABLE_15m,
    130 #ifdef BCM_TOMAHAWK_SUPPORT
    131                   ING_FLEX_CTR_OFFSET_TABLE_16m,
    132                   ING_FLEX_CTR_OFFSET_TABLE_17m,
    133                   ING_FLEX_CTR_OFFSET_TABLE_18m,
    134                   ING_FLEX_CTR_OFFSET_TABLE_19m
    135 #endif
    136                   },
    137 #else
    138                   0, 0, 0, 0, 0, 0, 0, 0 /* Kept it for future updates */},
    139 #endif
    140                  {EGR_FLEX_CTR_OFFSET_TABLE_0m,
    141                   EGR_FLEX_CTR_OFFSET_TABLE_1m,
    142                   EGR_FLEX_CTR_OFFSET_TABLE_2m,
    143                   EGR_FLEX_CTR_OFFSET_TABLE_3m,
    144                   EGR_FLEX_CTR_OFFSET_TABLE_4m,
    145                   EGR_FLEX_CTR_OFFSET_TABLE_5m,
    146                   EGR_FLEX_CTR_OFFSET_TABLE_6m,
    147                   EGR_FLEX_CTR_OFFSET_TABLE_7m,
    148                   0, 0, 0, 0, 0, 0, 0, 0 /* Kept it for future updates */}
    149                  };
    150 static soc_mem_t _ctr_counter_table[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    151                                    [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL] = {
    152                  {ING_FLEX_CTR_COUNTER_TABLE_0m,
    153                   ING_FLEX_CTR_COUNTER_TABLE_1m,
    154                   ING_FLEX_CTR_COUNTER_TABLE_2m,
    155                   ING_FLEX_CTR_COUNTER_TABLE_3m,
    156                   ING_FLEX_CTR_COUNTER_TABLE_4m,
    157                   ING_FLEX_CTR_COUNTER_TABLE_5m,
    158                   ING_FLEX_CTR_COUNTER_TABLE_6m,
    159                   ING_FLEX_CTR_COUNTER_TABLE_7m,
    160 #ifdef BCM_TRIUMPH3_SUPPORT
    161                   ING_FLEX_CTR_COUNTER_TABLE_8m,
    162                   ING_FLEX_CTR_COUNTER_TABLE_9m,
    163                   ING_FLEX_CTR_COUNTER_TABLE_10m,
    164                   ING_FLEX_CTR_COUNTER_TABLE_11m,
    165                   ING_FLEX_CTR_COUNTER_TABLE_12m,
    166                   ING_FLEX_CTR_COUNTER_TABLE_13m,
    167                   ING_FLEX_CTR_COUNTER_TABLE_14m,
    168                   ING_FLEX_CTR_COUNTER_TABLE_15m,
    169 #ifdef BCM_TOMAHAWK_SUPPORT
    170                   ING_FLEX_CTR_COUNTER_TABLE_16m,
    171                   ING_FLEX_CTR_COUNTER_TABLE_17m,
    172                   ING_FLEX_CTR_COUNTER_TABLE_18m,
    173                   ING_FLEX_CTR_COUNTER_TABLE_19m
    174 #endif
    175                   },
    176 #else
    177                   0, 0, 0, 0, 0, 0, 0, 0 /* Kept it for future updates */},
    178 #endif
    179                  {EGR_FLEX_CTR_COUNTER_TABLE_0m,
    180                   EGR_FLEX_CTR_COUNTER_TABLE_1m,
    181                   EGR_FLEX_CTR_COUNTER_TABLE_2m,
    182                   EGR_FLEX_CTR_COUNTER_TABLE_3m,
    183                   EGR_FLEX_CTR_COUNTER_TABLE_4m,
    184                   EGR_FLEX_CTR_COUNTER_TABLE_5m,
    185                   EGR_FLEX_CTR_COUNTER_TABLE_6m,
    186                   EGR_FLEX_CTR_COUNTER_TABLE_7m,
    187                   0, 0, 0, 0, 0, 0, 0, 0 /* Kept it for future updates */}
    188                  };
    189 #ifdef BCM_TOMAHAWK_SUPPORT
    190 static soc_mem_t _per_pipe_ctr_counter_table[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    191                                    [SOC_MAX_NUM_PIPES]
    192                                    [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL] = {
    193                   {{ING_FLEX_CTR_COUNTER_TABLE_0_PIPE0m,
    194                   ING_FLEX_CTR_COUNTER_TABLE_1_PIPE0m,
    195                   ING_FLEX_CTR_COUNTER_TABLE_2_PIPE0m,
    196                   ING_FLEX_CTR_COUNTER_TABLE_3_PIPE0m,
    197                   ING_FLEX_CTR_COUNTER_TABLE_4_PIPE0m,
    198                   ING_FLEX_CTR_COUNTER_TABLE_5_PIPE0m,
    199                   ING_FLEX_CTR_COUNTER_TABLE_6_PIPE0m,
    200                   ING_FLEX_CTR_COUNTER_TABLE_7_PIPE0m,
    201                   ING_FLEX_CTR_COUNTER_TABLE_8_PIPE0m,
    202                   ING_FLEX_CTR_COUNTER_TABLE_9_PIPE0m,
    203                   ING_FLEX_CTR_COUNTER_TABLE_10_PIPE0m,
    204                   ING_FLEX_CTR_COUNTER_TABLE_11_PIPE0m,
    205                   ING_FLEX_CTR_COUNTER_TABLE_12_PIPE0m,
    206                   ING_FLEX_CTR_COUNTER_TABLE_13_PIPE0m,
    207                   ING_FLEX_CTR_COUNTER_TABLE_14_PIPE0m,
    208                   ING_FLEX_CTR_COUNTER_TABLE_15_PIPE0m,
    209                   ING_FLEX_CTR_COUNTER_TABLE_16_PIPE0m,
    210                   ING_FLEX_CTR_COUNTER_TABLE_17_PIPE0m,
    211                   ING_FLEX_CTR_COUNTER_TABLE_18_PIPE0m,
    212                   ING_FLEX_CTR_COUNTER_TABLE_19_PIPE0m
    213                   },
    214                  {ING_FLEX_CTR_COUNTER_TABLE_0_PIPE1m,
    215                   ING_FLEX_CTR_COUNTER_TABLE_1_PIPE1m,
    216                   ING_FLEX_CTR_COUNTER_TABLE_2_PIPE1m,
    217                   ING_FLEX_CTR_COUNTER_TABLE_3_PIPE1m,
    218                   ING_FLEX_CTR_COUNTER_TABLE_4_PIPE1m,
    219                   ING_FLEX_CTR_COUNTER_TABLE_5_PIPE1m,
    220                   ING_FLEX_CTR_COUNTER_TABLE_6_PIPE1m,
    221                   ING_FLEX_CTR_COUNTER_TABLE_7_PIPE1m,
    222                   ING_FLEX_CTR_COUNTER_TABLE_8_PIPE1m,
    223                   ING_FLEX_CTR_COUNTER_TABLE_9_PIPE1m,
    224                   ING_FLEX_CTR_COUNTER_TABLE_10_PIPE1m,
    225                   ING_FLEX_CTR_COUNTER_TABLE_11_PIPE1m,
    226                   ING_FLEX_CTR_COUNTER_TABLE_12_PIPE1m,
    227                   ING_FLEX_CTR_COUNTER_TABLE_13_PIPE1m,
    228                   ING_FLEX_CTR_COUNTER_TABLE_14_PIPE1m,
    229                   ING_FLEX_CTR_COUNTER_TABLE_15_PIPE1m,
    230                   ING_FLEX_CTR_COUNTER_TABLE_16_PIPE1m,
    231                   ING_FLEX_CTR_COUNTER_TABLE_17_PIPE1m,
    232                   ING_FLEX_CTR_COUNTER_TABLE_18_PIPE1m,
    233                   ING_FLEX_CTR_COUNTER_TABLE_19_PIPE1m
    234                   },
    235 #if !defined(BCM_TRIDENT3_SUPPORT)
    236                  {ING_FLEX_CTR_COUNTER_TABLE_0_PIPE2m,
    237                   ING_FLEX_CTR_COUNTER_TABLE_1_PIPE2m,
    238                   ING_FLEX_CTR_COUNTER_TABLE_2_PIPE2m,
    239                   ING_FLEX_CTR_COUNTER_TABLE_3_PIPE2m,
    240                   ING_FLEX_CTR_COUNTER_TABLE_4_PIPE2m,
    241                   ING_FLEX_CTR_COUNTER_TABLE_5_PIPE2m,
    242                   ING_FLEX_CTR_COUNTER_TABLE_6_PIPE2m,
    243                   ING_FLEX_CTR_COUNTER_TABLE_7_PIPE2m,
    244                   ING_FLEX_CTR_COUNTER_TABLE_8_PIPE2m,
    245                   ING_FLEX_CTR_COUNTER_TABLE_9_PIPE2m,
    246                   ING_FLEX_CTR_COUNTER_TABLE_10_PIPE2m,
    247                   ING_FLEX_CTR_COUNTER_TABLE_11_PIPE2m,
    248                   ING_FLEX_CTR_COUNTER_TABLE_12_PIPE2m,
    249                   ING_FLEX_CTR_COUNTER_TABLE_13_PIPE2m,
    250                   ING_FLEX_CTR_COUNTER_TABLE_14_PIPE2m,
    251                   ING_FLEX_CTR_COUNTER_TABLE_15_PIPE2m,
    252                   ING_FLEX_CTR_COUNTER_TABLE_16_PIPE2m,
    253                   ING_FLEX_CTR_COUNTER_TABLE_17_PIPE2m,
    254                   ING_FLEX_CTR_COUNTER_TABLE_18_PIPE2m,
    255                   ING_FLEX_CTR_COUNTER_TABLE_19_PIPE2m
    256                   },
    257                  {ING_FLEX_CTR_COUNTER_TABLE_0_PIPE3m,
    258                   ING_FLEX_CTR_COUNTER_TABLE_1_PIPE3m,
    259                   ING_FLEX_CTR_COUNTER_TABLE_2_PIPE3m,
    260                   ING_FLEX_CTR_COUNTER_TABLE_3_PIPE3m,
    261                   ING_FLEX_CTR_COUNTER_TABLE_4_PIPE3m,
    262                   ING_FLEX_CTR_COUNTER_TABLE_5_PIPE3m,
    263                   ING_FLEX_CTR_COUNTER_TABLE_6_PIPE3m,
    264                   ING_FLEX_CTR_COUNTER_TABLE_7_PIPE3m,
    265                   ING_FLEX_CTR_COUNTER_TABLE_8_PIPE3m,
    266                   ING_FLEX_CTR_COUNTER_TABLE_9_PIPE3m,
    267                   ING_FLEX_CTR_COUNTER_TABLE_10_PIPE3m,
    268                   ING_FLEX_CTR_COUNTER_TABLE_11_PIPE3m,
    269                   ING_FLEX_CTR_COUNTER_TABLE_12_PIPE3m,
    270                   ING_FLEX_CTR_COUNTER_TABLE_13_PIPE3m,
    271                   ING_FLEX_CTR_COUNTER_TABLE_14_PIPE3m,
    272                   ING_FLEX_CTR_COUNTER_TABLE_15_PIPE3m,
    273                   ING_FLEX_CTR_COUNTER_TABLE_16_PIPE3m,
    274                   ING_FLEX_CTR_COUNTER_TABLE_17_PIPE3m,
    275                   ING_FLEX_CTR_COUNTER_TABLE_18_PIPE3m,
    276                   ING_FLEX_CTR_COUNTER_TABLE_19_PIPE3m,
    277                   }
    278 #endif
    279                   },
    280 
    281                  /* GLOBAL view is used for egress counters */
    282                  {{EGR_FLEX_CTR_COUNTER_TABLE_0m,
    283                   EGR_FLEX_CTR_COUNTER_TABLE_1m,
    284                   EGR_FLEX_CTR_COUNTER_TABLE_2m,
    285                   EGR_FLEX_CTR_COUNTER_TABLE_3m,
    286                   EGR_FLEX_CTR_COUNTER_TABLE_4m,
    287                   EGR_FLEX_CTR_COUNTER_TABLE_5m,
    288                   EGR_FLEX_CTR_COUNTER_TABLE_6m,
    289                   EGR_FLEX_CTR_COUNTER_TABLE_7m,
    290                   0, 0, 0, 0, 0, 0, 0, 0 /* Kept it for future updates */},
    291 
    292                   {EGR_FLEX_CTR_COUNTER_TABLE_0m,
    293                   EGR_FLEX_CTR_COUNTER_TABLE_1m,
    294                   EGR_FLEX_CTR_COUNTER_TABLE_2m,
    295                   EGR_FLEX_CTR_COUNTER_TABLE_3m,
    296                   EGR_FLEX_CTR_COUNTER_TABLE_4m,
    297                   EGR_FLEX_CTR_COUNTER_TABLE_5m,
    298                   EGR_FLEX_CTR_COUNTER_TABLE_6m,
    299                   EGR_FLEX_CTR_COUNTER_TABLE_7m,
    300                   0, 0, 0, 0, 0, 0, 0, 0 /* Kept it for future updates */},
    301 
    302 #if !defined(BCM_TRIDENT3_SUPPORT)
    303                   {EGR_FLEX_CTR_COUNTER_TABLE_0m,
    304                   EGR_FLEX_CTR_COUNTER_TABLE_1m,
    305                   EGR_FLEX_CTR_COUNTER_TABLE_2m,
    306                   EGR_FLEX_CTR_COUNTER_TABLE_3m,
    307                   EGR_FLEX_CTR_COUNTER_TABLE_4m,
    308                   EGR_FLEX_CTR_COUNTER_TABLE_5m,
    309                   EGR_FLEX_CTR_COUNTER_TABLE_6m,
    310                   EGR_FLEX_CTR_COUNTER_TABLE_7m,
    311                   0, 0, 0, 0, 0, 0, 0, 0 /* Kept it for future updates */},
    312 
    313                   {EGR_FLEX_CTR_COUNTER_TABLE_0m,
    314                   EGR_FLEX_CTR_COUNTER_TABLE_1m,
    315                   EGR_FLEX_CTR_COUNTER_TABLE_2m,
    316                   EGR_FLEX_CTR_COUNTER_TABLE_3m,
    317                   EGR_FLEX_CTR_COUNTER_TABLE_4m,
    318                   EGR_FLEX_CTR_COUNTER_TABLE_5m,
    319                   EGR_FLEX_CTR_COUNTER_TABLE_6m,
    320                   EGR_FLEX_CTR_COUNTER_TABLE_7m,
    321                   0, 0, 0, 0, 0, 0, 0, 0 /* Kept it for future updates */}
    322 #endif
    323                   }
    324                  };
    325 #endif
    326 
    327 #if defined (BCM_TOMAHAWK3_SUPPORT)
    328     static const soc_reg_t egr_evict_regs[] = {
    329         EGR_FLEX_CTR_EVICTION_CONTROL_POOL_0r,
    330         EGR_FLEX_CTR_EVICTION_CONTROL_POOL_1r,
    331         EGR_FLEX_CTR_EVICTION_CONTROL_POOL_2r,
    332         EGR_FLEX_CTR_EVICTION_CONTROL_POOL_3r,
    333     };
    334 #endif
    335 
    336 #define _CTR_COUNTER_TABLE_IFP(_unit, _dir, _pipe_num, _pool, _mem) {        \
    337     if (!(soc_feature(unit,soc_feature_stat_multi_pipe_support)) ||    \
    338             _bcm_esw_get_fp_mode_global(_unit, bcmFieldQualifyStageIngress) ||   \
    339             (bcmStatFlexDirectionIngress != _dir) ||                         \
    340             (FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE !=                   \
    341                            flex_pool_stat[_unit][bcmStatFlexDirectionIngress]\
    342                                          [0][_pool].used_by_tables)) {       \
    343          _mem = _ctr_counter_table[_dir][_pool];                             \
    344     } else {                                                                 \
    345          _mem = _per_pipe_ctr_counter_table[_dir][_pipe_num][_pool];         \
    346     }                                                                        \
    347 } 
    348 
    349 #define _CTR_COUNTER_TABLE_VFP(_unit, _dir, _pipe_num, _pool, _mem) {        \
    350     if (!(soc_feature(unit,soc_feature_stat_multi_pipe_support)) ||      \
    351             _bcm_esw_get_fp_mode_global(_unit, bcmFieldQualifyStageLookup) ||    \
    352             (bcmStatFlexDirectionIngress != _dir) ||                         \
    353             (FLEX_COUNTER_POOL_USED_BY_VFP_POLICY_TABLE !=                   \
    354                            flex_pool_stat[_unit][bcmStatFlexDirectionIngress]\
    355                                          [0][_pool].used_by_tables)) {       \
    356          _mem = _ctr_counter_table[_dir][_pool];                             \
    357     } else {                                                                 \
    358          _mem = _per_pipe_ctr_counter_table[_dir][_pipe_num][_pool];         \
    359     }                                                                        \
    360 } 
    361 
    362 #define _CTR_COUNTER_TABLE_EM(_unit, _dir, _pipe_num, _pool, _mem) {         \
    363     if (!(soc_feature(unit,soc_feature_stat_multi_pipe_support)) ||    \
    364             _bcm_esw_get_fp_mode_global(_unit,         \
    365                                 bcmFieldQualifyStageIngressExactMatch) ||    \
    366             (bcmStatFlexDirectionIngress != _dir) ||                         \
    367             (FLEX_COUNTER_POOL_USED_BY_EM_POLICY_TABLE !=                   \
    368                            flex_pool_stat[_unit][bcmStatFlexDirectionIngress]\
    369                                          [0][_pool].used_by_tables)) {       \
    370          _mem = _ctr_counter_table[_dir][_pool];                             \
    371     } else {                                                                 \
    372          _mem = _per_pipe_ctr_counter_table[_dir][_pipe_num][_pool];         \
    373     }                                                                        \
    374 } 
    375 
    376 #if defined(BCM_TRIDENT2_SUPPORT)
    377 static soc_mem_t _ctr_counter_table_x[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    378                                      [BCM_STAT_FLEX_COUNTER_MAX_POOL] = {
    379                  {ING_FLEX_CTR_COUNTER_TABLE_0_Xm,
    380                   ING_FLEX_CTR_COUNTER_TABLE_1_Xm,
    381                   ING_FLEX_CTR_COUNTER_TABLE_2_Xm,
    382                   ING_FLEX_CTR_COUNTER_TABLE_3_Xm,
    383                   ING_FLEX_CTR_COUNTER_TABLE_4_Xm,
    384                   ING_FLEX_CTR_COUNTER_TABLE_5_Xm,
    385                   ING_FLEX_CTR_COUNTER_TABLE_6_Xm,
    386                   ING_FLEX_CTR_COUNTER_TABLE_7_Xm},
    387                  {EGR_FLEX_CTR_COUNTER_TABLE_0_Xm,
    388                   EGR_FLEX_CTR_COUNTER_TABLE_1_Xm,
    389                   EGR_FLEX_CTR_COUNTER_TABLE_2_Xm,
    390                   EGR_FLEX_CTR_COUNTER_TABLE_3_Xm}
    391                  };
    392 
    393 static soc_mem_t _ctr_counter_table_y[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    394                                      [BCM_STAT_FLEX_COUNTER_MAX_POOL] = {
    395                  {ING_FLEX_CTR_COUNTER_TABLE_0_Ym,
    396                   ING_FLEX_CTR_COUNTER_TABLE_1_Ym,
    397                   ING_FLEX_CTR_COUNTER_TABLE_2_Ym,
    398                   ING_FLEX_CTR_COUNTER_TABLE_3_Ym,
    399                   ING_FLEX_CTR_COUNTER_TABLE_4_Ym,
    400                   ING_FLEX_CTR_COUNTER_TABLE_5_Ym,
    401                   ING_FLEX_CTR_COUNTER_TABLE_6_Ym,
    402                   ING_FLEX_CTR_COUNTER_TABLE_7_Ym},
    403                  {EGR_FLEX_CTR_COUNTER_TABLE_0_Ym,
    404                   EGR_FLEX_CTR_COUNTER_TABLE_1_Ym,
    405                   EGR_FLEX_CTR_COUNTER_TABLE_2_Ym,
    406                   EGR_FLEX_CTR_COUNTER_TABLE_3_Ym}
    407                  };
    408 #endif  /* BCM_TRIDENT2_SUPPORT */
    409 
    410 static soc_reg_t _pkt_selector_key_reg[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    411 #ifdef BCM_APACHE_SUPPORT
    412                                   [BCM_STAT_AP_FLEX_COUNTER_MAX_PKT_ATTR_SEL] = {
    413 #else
    414 #ifndef BCM_TOMAHAWK_SUPPORT
    415                                   [BCM_STAT_FLEX_COUNTER_MAX_POOL] = {
    416 
    417 #else
    418                                   [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL] = {
    419 #endif
    420 #endif
    421                  {ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_0r,
    422                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_1r,
    423                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_2r,
    424                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_3r,
    425                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_4r,
    426                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_5r,
    427                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_6r,
    428                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_7r,
    429 #if defined(BCM_TOMAHAWK_SUPPORT) || defined (BCM_APACHE_SUPPORT)
    430                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_8r,
    431                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_9r,
    432                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_10r,
    433                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_11r,
    434                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_12r,
    435                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_13r,
    436                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_14r,
    437                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_15r,
    438                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_16r,
    439                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_17r,
    440                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_18r,
    441                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_19r,
    442 #ifdef BCM_APACHE_SUPPORT
    443                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_20r,
    444                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_21r,
    445                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_22r,
    446                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_23r,
    447                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_24r,
    448                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_25r,
    449                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_26r,
    450                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_27r,
    451                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_28r,
    452                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_29r,
    453                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_30r,
    454                   ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_31r,
    455 #endif
    456 #endif /* BCM_TOMAHAWK_SUPPORT */
    457                  },
    458                  {EGR_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_0r,
    459                   EGR_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_1r,
    460                   EGR_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_2r,
    461                   EGR_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_3r,
    462 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
    463                   EGR_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_4r,
    464                   EGR_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_5r,
    465                   EGR_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_6r,
    466                   EGR_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_7r}
    467 #else
    468                   0, 0, 0, 0}
    469 #endif
    470                 };
    471 
    472 static soc_field_t _pkt_selector_x_en_field_name[BCM_STAT_FLEX_COUNTER_MAX_ATTR_SEL_BITS] = {
    473                    SELECTOR_0_ENf,
    474                    SELECTOR_1_ENf,
    475                    SELECTOR_2_ENf,
    476                    SELECTOR_3_ENf,
    477                    SELECTOR_4_ENf,
    478                    SELECTOR_5_ENf,
    479                    SELECTOR_6_ENf,
    480                    SELECTOR_7_ENf,
    481                    };
    482 static soc_field_t _pkt_selector_for_bit_x_field_name[BCM_STAT_FLEX_COUNTER_MAX_ATTR_SEL_BITS] = {
    483                    SELECTOR_FOR_BIT_0f,
    484                    SELECTOR_FOR_BIT_1f,
    485                    SELECTOR_FOR_BIT_2f,
    486                    SELECTOR_FOR_BIT_3f,
    487                    SELECTOR_FOR_BIT_4f,
    488                    SELECTOR_FOR_BIT_5f,
    489                    SELECTOR_FOR_BIT_6f,
    490                    SELECTOR_FOR_BIT_7f,
    491                    };
    492 
    493 #if defined(BCM_TOMAHAWK_SUPPORT) && defined(BCM_WARM_BOOT_SUPPORT)
    494 static soc_mem_t _ifp_mem_arr[] = {
    495                                IFP_POLICY_TABLE_PIPE0m,
    496                                IFP_POLICY_TABLE_PIPE1m,
    497                                IFP_POLICY_TABLE_PIPE2m,
    498                                IFP_POLICY_TABLE_PIPE3m,
    499                                IFP_POLICY_TABLE_PIPE4m,
    500                                IFP_POLICY_TABLE_PIPE5m,
    501                                IFP_POLICY_TABLE_PIPE6m,
    502                                IFP_POLICY_TABLE_PIPE7m
    503                               };
    504 static soc_mem_t _vfp_mem_arr[] = {
    505                                VFP_POLICY_TABLE_PIPE0m,
    506                                VFP_POLICY_TABLE_PIPE1m,
    507                                VFP_POLICY_TABLE_PIPE2m,
    508                                VFP_POLICY_TABLE_PIPE3m,
    509                                VFP_POLICY_TABLE_PIPE4m,
    510                                VFP_POLICY_TABLE_PIPE5m,
    511                                VFP_POLICY_TABLE_PIPE6m,
    512                                VFP_POLICY_TABLE_PIPE7m
    513                               };
    514 #endif
    515 #if (defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)) && defined(BCM_WARM_BOOT_SUPPORT)
    516 static soc_mem_t _efp_mem_arr[] = {
    517                                 EFP_POLICY_TABLEm,
    518                                 EFP_POLICY_TABLE_PIPE0m,
    519                                 EFP_POLICY_TABLE_PIPE1m
    520                               };
    521 #endif
    522 
    523 static bcm_stat_flex_ingress_mode_t *flex_ingress_modes[SOC_MAX_NUM_DEVICES] = {NULL};
    524 static bcm_stat_flex_egress_mode_t  *flex_egress_modes[SOC_MAX_NUM_DEVICES] = {NULL};
    525 static bcm_stat_flex_custom_ingress_mode_t *flex_custom_ingress_modes[SOC_MAX_NUM_DEVICES] = {NULL};
    526 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
    527 static bcm_stat_flex_custom_egress_mode_t *flex_custom_egress_modes[SOC_MAX_NUM_DEVICES] = {NULL};
    528 #endif
    529 
    530 
    531 static shr_aidxres_list_handle_t flex_aidxres_list_handle
    532                                  [SOC_MAX_NUM_DEVICES]
    533                                  [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    534                                  [SOC_MAX_NUM_PIPES]
    535 #ifdef BCM_TOMAHAWK_SUPPORT
    536                                  [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL];
    537 #else
    538                                  [BCM_STAT_FLEX_COUNTER_MAX_POOL];
    539 #endif
    540 
    541 static bcm_stat_flex_pool_stat_t flex_pool_stat
    542                                  [SOC_MAX_NUM_DEVICES]
    543                                  [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    544                                  [SOC_MAX_NUM_PIPES]
    545 #ifdef BCM_TOMAHAWK_SUPPORT
    546                                  [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL];
    547 #else
    548                                  [BCM_STAT_FLEX_COUNTER_MAX_POOL];
    549 #endif
    550 /* For TD2PLUS, Flex counters for OAM is used in Ingress only. Hence pool_group
    551  * database is only maintained on Ingress only. 
    552  */
    553 static bcm_stat_flex_pool_group_t  flex_pool_group
    554                                    [SOC_MAX_NUM_DEVICES]
    555                                    [SOC_MAX_NUM_PIPES]
    556                                    [BCM_STAT_TH_FLEX_COUNTER_MAX_GROUPS];
    557 
    558 static uint16 *flex_base_index_reference_count
    559                                  [SOC_MAX_NUM_DEVICES]
    560                                  [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    561                                  [SOC_MAX_NUM_PIPES]
    562 #ifdef BCM_TOMAHAWK_SUPPORT
    563                                  [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL];
    564 #else
    565                                  [BCM_STAT_FLEX_COUNTER_MAX_POOL];
    566 #endif
    567 #if defined(BCM_TRIDENT2_SUPPORT)
    568 uint8 *_flex_stat_mode_base_map[SOC_MAX_NUM_DEVICES]
    569                                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    570                                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
    571                                [BCM_STAT_FLEX_COUNTER_MAX_MODE];
    572 #endif /* BCM_TRIDENT2_SUPPORT */
    573 #if defined(BCM_TOMAHAWK_SUPPORT)
    574 /* Database to maintain ifp color map per counter */
    575 static uint8 *ifp_color_map[SOC_MAX_NUM_DEVICES]
    576                            [SOC_MAX_NUM_PIPES]
    577                            [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL] = {{{NULL}}};
    578 bcm_error_t _bcm_esw_custom_stat_group_id_retrieve(
    579     int unit,
    580     uint32 offset_mode,
    581     int  pipe,
    582     uint8  pool,
    583     uint32 base_idx,
    584     uint32 *stat_ctr_id);
    585 bcm_error_t _bcm_esw_ifp_wb_color_map_set(
    586         int                   unit,
    587         uint32                pool_number,
    588         uint32                base_index,
    589         uint32                pipe_num,
    590         bcm_stat_flex_mode_t offset_mode,
    591         _bcm_ifp_color_map_t  *color_map);
    592 #endif
    593 
    594 extern 
    595 bcm_error_t _bcm_esw_stat_attr_fill(
    596             int	                  unit,
    597             bcm_stat_group_mode_t group_mode,
    598             bcm_stat_flex_direction_t direction,
    599             bcm_stat_flex_attr_t     *attr,
    600             uint32 *num_counters);
    601 static sal_mutex_t flex_stat_mutex[SOC_MAX_NUM_DEVICES] = {NULL};
    602 
    603 /* Both ing_flex_ctr_counter_table_0_entry_t and egr_flex_ctr_table_0_entry_t
    604    have same contents so using one entry only */
    605 static ing_flex_ctr_counter_table_0_entry_t
    606        *flex_temp_counter[SOC_MAX_NUM_DEVICES]
    607                          [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {{NULL}};
    608 #if defined(BCM_TRIDENT2_SUPPORT)
    609 static ing_flex_ctr_counter_table_0_entry_t
    610        *flex_temp_counter_dual[SOC_MAX_NUM_DEVICES]
    611                               [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {{NULL}};
    612 static uint32 *flex_pkt_counter_x
    613                [BCM_MAX_NUM_UNITS]
    614                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    615                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
    616                [_BCM_FLEX_STAT_BUFFS] = {{{{NULL}}}};
    617 static uint64 *flex_byte_counter_x
    618                [SOC_MAX_NUM_DEVICES]
    619                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    620                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
    621                [_BCM_FLEX_STAT_BUFFS] = {{{{NULL}}}};
    622 
    623 static uint32 *flex_pkt_counter_y
    624                [BCM_MAX_NUM_UNITS]
    625                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    626                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
    627                [_BCM_FLEX_STAT_BUFFS] = {{{{NULL}}}};
    628 static uint64 *flex_byte_counter_y
    629                [SOC_MAX_NUM_DEVICES]
    630                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    631                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
    632                [_BCM_FLEX_STAT_BUFFS] = {{{{NULL}}}};
    633 static uint8 *flex_counter_toggle
    634                [BCM_MAX_NUM_UNITS]
    635                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    636                [BCM_STAT_FLEX_COUNTER_MAX_POOL] = {{{NULL}}};
    637 #endif
    638 
    639 static uint64 *flex_byte_counter
    640                [SOC_MAX_NUM_DEVICES]
    641                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    642                [SOC_MAX_NUM_PIPES]
    643 #ifdef BCM_TOMAHAWK_SUPPORT
    644                [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL]
    645 #else
    646                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
    647 #endif
    648                = {{{{NULL}}}};
    649 static uint32 *flex_packet_counter
    650                [SOC_MAX_NUM_DEVICES]
    651                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    652                [SOC_MAX_NUM_PIPES]
    653 #ifdef BCM_TOMAHAWK_SUPPORT
    654                [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL]
    655 #else
    656                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
    657 #endif
    658                 = {{{{NULL}}}};
    659 static uint64 *flex_packet64_counter
    660                [SOC_MAX_NUM_DEVICES]
    661                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    662                [SOC_MAX_NUM_PIPES]
    663 #ifdef BCM_TOMAHAWK_SUPPORT
    664                [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL]
    665 #else
    666                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
    667 #endif
    668                = {{{{NULL}}}};
    669 
    670 #ifdef BCM_TOMAHAWK_SUPPORT
    671 static uint64 *residual_byte_counter
    672                [BCM_UNITS_MAX]
    673                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    674                [SOC_MAX_NUM_PIPES]
    675 #ifdef BCM_TOMAHAWK_SUPPORT
    676                [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL]
    677 #else
    678                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
    679 #endif
    680                = {{{{NULL}}}};
    681 static uint64 *residual_packet_counter
    682                [BCM_UNITS_MAX]
    683                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    684                [SOC_MAX_NUM_PIPES]
    685 #ifdef BCM_TOMAHAWK_SUPPORT
    686                [BCM_STAT_TH_FLEX_COUNTER_MAX_POOL]
    687 #else
    688                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
    689 #endif
    690                = {{{{NULL}}}};
    691 #endif
    692 
    693 #define BCM_STAT_FLEX_COUNTER_LOCK(unit) \
    694         sal_mutex_take(flex_stat_mutex[unit], sal_mutex_FOREVER);
    695 #define BCM_STAT_FLEX_COUNTER_UNLOCK(unit) \
    696         sal_mutex_give(flex_stat_mutex[unit]);
    697 
    698 static uint8 flex_directions[][8]={
    699              "Ingress",
    700              "Egress" };
    701 #ifdef BCM_WARM_BOOT_SUPPORT
    702 static uint8 _flex_group_mode_total_counters_info
    703               [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
    704               [bcmStatGroupModeCng+1]={
    705                /* #####################################      */
    706                /* INGRESS GROUP MODE ==> Total Counters      */
    707                /* #####################################      */
    708                {/* bcmStatGroupModeSingle */                 1,
    709                 /* bcmStatGroupModeTrafficType */            3,
    710                 /* bcmStatGroupModeDlfAll */                 2,
    711                 /* bcmStatGroupModeDlfIntPri */              17,
    712                 /* bcmStatGroupModeTyped */                  4,
    713                 /* bcmStatGroupModeTypedAll */               5,
    714                 /* bcmStatGroupModeTypedIntPri */            20,
    715                 /* bcmStatGroupModeSingleWithControl */      2,
    716                 /* bcmStatGroupModeTrafficTypeWithControl */ 4,
    717                 /* bcmStatGroupModeDlfAllWithControl */      3,
    718                 /* bcmStatGroupModeDlfIntPriWithControl */   18,
    719                 /* bcmStatGroupModeTypedWithControl */       5,
    720                 /* bcmStatGroupModeTypedAllWithControl */    6,
    721                 /* bcmStatGroupModeTypedIntPriWithControl */ 21,
    722                 /* bcmStatGroupModeDot1P */                  8,
    723                 /* bcmStatGroupModeIntPri */                 16,
    724                 /* bcmStatGroupModeIntPriCng */              64,
    725                 /* bcmStatGroupModeSvpType */                2,
    726                 /* bcmStatGroupModeDscp */                   64,
    727                 /* bcmStatGroupModeDvpType */                0,
    728                 /* bcmStatGroupModeCng */                    4},
    729                /* #####################################      */
    730                /* EGRESS GROUP MODE ==> Total Counters       */
    731                /* #####################################      */
    732                {/* bcmStatGroupModeSingle */                 1,
    733                 /* bcmStatGroupModeTrafficType */            2,
    734                 /* bcmStatGroupModeDlfAll */                 0,
    735                 /* bcmStatGroupModeDlfIntPri */              0,
    736                 /* bcmStatGroupModeTyped */                  0,
    737                 /* bcmStatGroupModeTypedAll */               0,
    738                 /* bcmStatGroupModeTypedIntPri */            18,
    739                 /* bcmStatGroupModeSingleWithControl */      0,
    740                 /* bcmStatGroupModeTrafficTypeWithControl */ 0,
    741                 /* bcmStatGroupModeDlfAllWithControl */      0,
    742                 /* bcmStatGroupModeDlfIntPriWithControl */   0,
    743                 /* bcmStatGroupModeTypedWithControl */       0,
    744                 /* bcmStatGroupModeTypedAllWithControl */    0,
    745                 /* bcmStatGroupModeTypedIntPriWithControl */ 0,
    746                 /* bcmStatGroupModeDot1P */                  8,
    747                 /* bcmStatGroupModeIntPri */                 16,
    748                 /* bcmStatGroupModeIntPriCng */              64,
    749                 /* bcmStatGroupModeSvpType */                2,
    750                 /* bcmStatGroupModeDscp */                   64,
    751                 /* bcmStatGroupModeDvpType */                2,
    752                 /* bcmStatGroupModeCng */                    4},
    753               };
    754 #endif
    755 
    756 typedef struct uncmprsd_attr_bits_selector_s {
    757     uint32 attr_bits;
    758     uint8  attr_name[20];
    759 }uncmprsd_attr_bits_selector_t;
    760 
    761 static uncmprsd_attr_bits_selector_t ing_uncmprsd_attr_bits_selector[]={
    762        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_CNG_ATTR_BITS,           "CNG"},
    763        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_IFP_CNG_ATTR_BITS,       "IFP CNG"},
    764        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_INT_PRI_ATTR_BITS,       "INT PRI"},
    765        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_VLAN_FORMAT_ATTR_BITS,   "VLAN"},
    766        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_OUTER_DOT1P_ATTR_BITS,   "OUTER.1P"},
    767        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_INNER_DOT1P_ATTR_BITS,   "INNER.1P"},
    768        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_INGRESS_PORT_ATTR_BITS,  "PORT"},
    769        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_TOS_DSCP_ATTR_BITS,           "TOS_DSCP"},
    770        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_TOS_ECN_ATTR_BITS,           "TOS_ECN"},
    771        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS,"PktRes"},
    772        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_SVP_TYPE_ATTR_BITS,      "SVP"},
    773        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_DROP_ATTR_BITS,          "DROP"},
    774        {BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_IP_PKT_ATTR_BITS,        "IP"}
    775 };
    776 static uncmprsd_attr_bits_selector_t egr_uncmprsd_attr_bits_selector[]={
    777        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_CNG_ATTR_BITS,           "CNG"},
    778        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_INT_PRI_ATTR_BITS,       "INT PRI"},
    779        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_VLAN_FORMAT_ATTR_BITS,   "VLAN"},
    780        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_OUTER_DOT1P_ATTR_BITS,   "OUTER.1P"},
    781        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_INNER_DOT1P_ATTR_BITS,   "INNER.1P"},
    782        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_EGRESS_PORT_ATTR_BITS,   "PORT"},
    783        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_TOS_DSCP_ATTR_BITS,           "TOS_DSCP"},
    784        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_TOS_ECN_ATTR_BITS,           "TOS_ECN"},
    785        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS,"PktRes"},
    786        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_SVP_TYPE_ATTR_BITS,      "SVP"},
    787        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_DVP_TYPE_ATTR_BITS,      "DVP"},
    788        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_DROP_ATTR_BITS,          "DROP"},
    789        {BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_IP_PKT_ATTR_BITS,        "IP"}
    790 };
    791 
    792 #define _DEFINE_GET_INGRESS_VALUE(field_name,field_value) \
    793 static  uint8 _bcm_esw_get_ing_##field_name##_value( \
    794                 bcm_stat_flex_ing_pkt_attr_bits_t *ing_pkt_attr_bits) { \
    795                    return field_value; \
    796 } \
    797 
    798 #define DEFINE_GET_INGRESS_VALUE(field_name) \
    799         _DEFINE_GET_INGRESS_VALUE(field_name,ing_pkt_attr_bits->field_name)
    800 
    801 #ifdef BCM_APACHE_SUPPORT
    802 DEFINE_GET_INGRESS_VALUE(cng_3)
    803 DEFINE_GET_INGRESS_VALUE(phb_3)
    804 DEFINE_GET_INGRESS_VALUE(cng_2)
    805 DEFINE_GET_INGRESS_VALUE(phb_2)
    806 DEFINE_GET_INGRESS_VALUE(cng_1)
    807 DEFINE_GET_INGRESS_VALUE(phb_1)
    808 #endif
    809 DEFINE_GET_INGRESS_VALUE(cng)
    810 DEFINE_GET_INGRESS_VALUE(ifp_cng)
    811 DEFINE_GET_INGRESS_VALUE(int_pri)
    812 DEFINE_GET_INGRESS_VALUE(vlan_format)
    813 DEFINE_GET_INGRESS_VALUE(outer_dot1p)
    814 DEFINE_GET_INGRESS_VALUE(inner_dot1p)
    815 DEFINE_GET_INGRESS_VALUE(ing_port)
    816 DEFINE_GET_INGRESS_VALUE(tos_dscp)
    817 DEFINE_GET_INGRESS_VALUE(tos_ecn)
    818 DEFINE_GET_INGRESS_VALUE(pkt_resolution)
    819 DEFINE_GET_INGRESS_VALUE(svp_type)
    820 DEFINE_GET_INGRESS_VALUE(drop)
    821 DEFINE_GET_INGRESS_VALUE(ip_pkt)
    822 
    823 typedef struct _bcm_esw_get_ing_func_f {
    824     uint8 (*func)(bcm_stat_flex_ing_pkt_attr_bits_t *ing_pkt_attr_bits);
    825     uint8 func_desc[20];
    826 }_bcm_esw_get_ing_func_t;
    827 static _bcm_esw_get_ing_func_t _bcm_esw_get_ing_func[] = {
    828 #ifdef BCM_APACHE_SUPPORT
    829     {_bcm_esw_get_ing_cng_3_value,"cng_3"},
    830     {_bcm_esw_get_ing_phb_3_value,"phb_3"},
    831     {_bcm_esw_get_ing_cng_2_value,"cng_2"},
    832     {_bcm_esw_get_ing_phb_2_value,"phb_2"},
    833     {_bcm_esw_get_ing_cng_1_value,"cng_1"},
    834     {_bcm_esw_get_ing_phb_1_value,"phb_1"},
    835 #endif
    836     {_bcm_esw_get_ing_cng_value,"cng"},
    837     {_bcm_esw_get_ing_ifp_cng_value,"ifp_cng"},
    838     {_bcm_esw_get_ing_int_pri_value,"int_pri"},
    839     {_bcm_esw_get_ing_vlan_format_value,"vlan_format"},
    840     {_bcm_esw_get_ing_outer_dot1p_value,"outer_dot1p"},
    841     {_bcm_esw_get_ing_inner_dot1p_value,"inner_dot1p"},
    842     {_bcm_esw_get_ing_ing_port_value,"ing_port"},
    843     {_bcm_esw_get_ing_tos_dscp_value,"tos_dscp"},
    844     {_bcm_esw_get_ing_tos_ecn_value,"tos_ecn"},
    845     {_bcm_esw_get_ing_pkt_resolution_value,"pkt_resolutino"},
    846     {_bcm_esw_get_ing_svp_type_value,"svp"},
    847     {_bcm_esw_get_ing_drop_value,"drop"},
    848     {_bcm_esw_get_ing_ip_pkt_value,"ip_pkt"}
    849 };
    850 
    851 #define _DEFINE_GET_EGRESS_VALUE(field_name,field_value) \
    852 static  uint8 _bcm_esw_get_egr_##field_name##_value( \
    853                 bcm_stat_flex_egr_pkt_attr_bits_t *egr_pkt_attr_bits) { \
    854                    return field_value; \
    855 } \
    856 
    857 #define DEFINE_GET_EGRESS_VALUE(field_name) \
    858         _DEFINE_GET_EGRESS_VALUE(field_name,egr_pkt_attr_bits->field_name)
    859 
    860 #ifdef BCM_APACHE_SUPPORT
    861 DEFINE_GET_EGRESS_VALUE(cng_3)
    862 DEFINE_GET_EGRESS_VALUE(phb_3)
    863 DEFINE_GET_EGRESS_VALUE(cng_2)
    864 DEFINE_GET_EGRESS_VALUE(phb_2)
    865 DEFINE_GET_EGRESS_VALUE(cng_1)
    866 DEFINE_GET_EGRESS_VALUE(phb_1)
    867 #endif
    868 DEFINE_GET_EGRESS_VALUE(cng)
    869 DEFINE_GET_EGRESS_VALUE(int_pri)
    870 DEFINE_GET_EGRESS_VALUE(vlan_format)
    871 DEFINE_GET_EGRESS_VALUE(outer_dot1p)
    872 DEFINE_GET_EGRESS_VALUE(inner_dot1p)
    873 DEFINE_GET_EGRESS_VALUE(egr_port)
    874 DEFINE_GET_EGRESS_VALUE(tos_dscp)
    875 DEFINE_GET_EGRESS_VALUE(tos_ecn)
    876 DEFINE_GET_EGRESS_VALUE(pkt_resolution)
    877 DEFINE_GET_EGRESS_VALUE(svp_type)
    878 DEFINE_GET_EGRESS_VALUE(dvp_type)
    879 DEFINE_GET_EGRESS_VALUE(drop)
    880 DEFINE_GET_EGRESS_VALUE(ip_pkt)
    881 
    882 typedef struct _bcm_esw_get_egr_func_f {
    883     uint8 (*func)(bcm_stat_flex_egr_pkt_attr_bits_t *egr_pkt_attr_bits);
    884     uint8 func_desc[20];
    885 }_bcm_esw_get_egr_func_t;
    886 static _bcm_esw_get_egr_func_t _bcm_esw_get_egr_func[] = {
    887 #ifdef BCM_APACHE_SUPPORT
    888     {_bcm_esw_get_egr_cng_3_value,"cng_3"},
    889     {_bcm_esw_get_egr_phb_3_value,"phb_3"},
    890     {_bcm_esw_get_egr_cng_2_value,"cng_2"},
    891     {_bcm_esw_get_egr_phb_2_value,"phb_2"},
    892     {_bcm_esw_get_egr_cng_1_value,"cng_1"},
    893     {_bcm_esw_get_egr_phb_1_value,"phb_1"},
    894 #endif
    895     {_bcm_esw_get_egr_cng_value,"cng"},
    896     {_bcm_esw_get_egr_int_pri_value,"int_pri"},
    897     {_bcm_esw_get_egr_vlan_format_value,"vlan_format"},
    898     {_bcm_esw_get_egr_outer_dot1p_value,"outer_dot1p"},
    899     {_bcm_esw_get_egr_inner_dot1p_value,"inner_dot1p"},
    900     {_bcm_esw_get_egr_egr_port_value,"egr_port"},
    901     {_bcm_esw_get_egr_tos_dscp_value,"tos_dscp"},
    902     {_bcm_esw_get_egr_tos_ecn_value,"tos_ecn"},
    903     {_bcm_esw_get_egr_pkt_resolution_value,"pkt_resolutino"},
    904     {_bcm_esw_get_egr_svp_type_value,"svp"},
    905     {_bcm_esw_get_egr_dvp_type_value,"dvp"},
    906     {_bcm_esw_get_egr_drop_value,"drop"},
    907     {_bcm_esw_get_egr_ip_pkt_value,"ip_pkt"}
    908 };
    909 
    910 typedef struct flex_object_default_f {
    911     char obj_desc[20];
    912     soc_mem_t obj_mem;
    913     uint32 pool_number;
    914     uint32 pool_criteria;
    915 }flex_object_default_t;
    916 
    917 
    918 /* When adding a new object with description contains that of an existing one.
    919 *  Please place the new object before the existing one.
    920 *  For example, "vlanxlatescndlkup" should come before "vlan".
    921 */
    922 static flex_object_default_t ing_flex_object_default[]={
    923     {
    924         "port",
    925         PORT_TABm,
    926         FLEX_COUNTER_DEFAULT_PORT_TABLE_POOL_NUMBER,
    927         FLEX_COUNTER_POOL_USED_BY_PORT_TABLE
    928     },
    929 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    930     {
    931         "vlanxlatescndlkup",
    932         VLAN_XLATEm,
    933         FLEX_COUNTER_DEFAULT_VLAN_XLATE_SCND_LKUP_TABLE_POOL_NUMBER,
    934         FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE_FOR_SCND_LKUP
    935     },
    936 #endif
    937     {
    938         "vlanxlate",
    939         VLAN_XLATEm,
    940         FLEX_COUNTER_DEFAULT_VLAN_XLATE_TABLE_POOL_NUMBER,
    941         FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE
    942     },
    943     {
    944         "vlan",
    945         VLAN_TABm,
    946         FLEX_COUNTER_DEFAULT_VLAN_TABLE_POOL_NUMBER,
    947         FLEX_COUNTER_POOL_USED_BY_VLAN_TABLE
    948     },
    949     {
    950         "vfi",
    951         VFIm,
    952         FLEX_COUNTER_DEFAULT_VFI_TABLE_POOL_NUMBER,
    953         FLEX_COUNTER_POOL_USED_BY_VFI_TABLE
    954     },
    955 #if defined(BCM_METROLITE_SUPPORT)
    956     {
    957         "l3intf",
    958         L3_IIFm,
    959         FLEX_COUNTER_ML_DEFAULT_L3_IIF_TABLE_POOL_NUMBER,
    960         FLEX_COUNTER_POOL_USED_BY_L3_IIF_TABLE
    961     },
    962     {
    963         "vrf",
    964         VRFm,
    965         FLEX_COUNTER_ML_DEFAULT_VRF_TABLE_POOL_NUMBER,
    966         FLEX_COUNTER_POOL_USED_BY_VRF_TABLE
    967     },
    968 #else
    969     {
    970         "l3intf",
    971         L3_IIFm,
    972         FLEX_COUNTER_DEFAULT_L3_IIF_TABLE_POOL_NUMBER,
    973         FLEX_COUNTER_POOL_USED_BY_L3_IIF_TABLE
    974     },
    975     {
    976         "vrf",
    977         VRFm,
    978         FLEX_COUNTER_DEFAULT_VRF_TABLE_POOL_NUMBER,
    979         FLEX_COUNTER_POOL_USED_BY_VRF_TABLE
    980     },
    981 #endif
    982     {
    983         "policy",
    984         VFP_POLICY_TABLEm,
    985         FLEX_COUNTER_DEFAULT_VFP_POLICY_TABLE_POOL_NUMBER,
    986         FLEX_COUNTER_POOL_USED_BY_VFP_POLICY_TABLE
    987     },
    988 #if defined(BCM_METROLITE_SUPPORT)
    989     {
    990         "mplsvclabel",
    991         SOURCE_VPm,
    992         FLEX_COUNTER_ML_DEFAULT_SOURCE_VP_TABLE_POOL_NUMBER,
    993         FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE
    994     },
    995 #else
    996     {
    997         "mplsvclabel",
    998         SOURCE_VPm,
    999         FLEX_COUNTER_DEFAULT_SOURCE_VP_TABLE_POOL_NUMBER,
   1000         FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE
   1001     },
   1002 #endif
   1003     {
   1004         "mplsswitchlabel",
   1005         MPLS_ENTRYm,
   1006         FLEX_COUNTER_DEFAULT_MPLS_ENTRY_TABLE_POOL_NUMBER,
   1007         FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE
   1008     },
   1009 #if defined(BCM_APACHE_SUPPORT)
   1010     {
   1011         "mplsswitchscndlkup",
   1012         MPLS_ENTRYm,
   1013         FLEX_COUNTER_DEFAULT_MPLS_ENTRY_SCND_LKUP_TABLE_POOL_NUMBER,
   1014         FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE_FOR_SCND_LKUP
   1015     },
   1016 #endif
   1017     {
   1018         "mplsfrrlabel",
   1019         L3_TUNNELm,
   1020         FLEX_COUNTER_DEFAULT_VLAN_TABLE_POOL_NUMBER,
   1021         FLEX_COUNTER_POOL_USED_BY_L3_TUNNEL_TABLE
   1022     },
   1023 #if defined(BCM_METROLITE_SUPPORT)
   1024     {
   1025         "l3host",
   1026         EXT_IPV4_UCAST_WIDEm,
   1027         FLEX_COUNTER_ML_DEFAULT_L3_ENTRY_TABLE_POOL_NUMBER,
   1028         FLEX_COUNTER_POOL_USED_BY_L3_ENTRY_TABLE
   1029     },
   1030 #else
   1031     {
   1032         "l3host",
   1033         EXT_IPV4_UCAST_WIDEm,
   1034         FLEX_COUNTER_DEFAULT_L3_ENTRY_TABLE_POOL_NUMBER,
   1035         FLEX_COUNTER_POOL_USED_BY_L3_ENTRY_TABLE
   1036     },
   1037 #endif
   1038 #if defined(BCM_TRIUMPH3_SUPPORT)
   1039     {
   1040         "trill",
   1041         MPLS_ENTRY_EXTDm,
   1042         FLEX_COUNTER_DEFAULT_MPLS_ENTRY_TABLE_POOL_NUMBER,
   1043         FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE
   1044     },
   1045     {
   1046         "mimlookupid",
   1047         MPLS_ENTRY_EXTDm,
   1048         FLEX_COUNTER_DEFAULT_MPLS_ENTRY_TABLE_POOL_NUMBER,
   1049         FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE
   1050     },
   1051 #endif
   1052     {
   1053         "l2gre",
   1054         VLAN_XLATEm,
   1055         FLEX_COUNTER_DEFAULT_VLAN_XLATE_TABLE_POOL_NUMBER,
   1056         FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE
   1057     },
   1058     {
   1059         "extpolicy",
   1060         VFP_POLICY_TABLEm,
   1061         FLEX_COUNTER_DEFAULT_VFP_POLICY_TABLE_POOL_NUMBER,
   1062         FLEX_COUNTER_POOL_USED_BY_VFP_POLICY_TABLE
   1063     },
   1064 #if defined(BCM_METROLITE_SUPPORT)
   1065     {
   1066         "vxlan",
   1067         SOURCE_VPm,
   1068         FLEX_COUNTER_ML_DEFAULT_SOURCE_VP_TABLE_POOL_NUMBER,
   1069         FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE
   1070     },
   1071 #else
   1072     {
   1073         "vxlan",
   1074         SOURCE_VPm,
   1075         FLEX_COUNTER_DEFAULT_SOURCE_VP_TABLE_POOL_NUMBER,
   1076         FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE
   1077     },
   1078 #endif
   1079 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_METROLITE_SUPPORT) 
   1080 #if defined(BCM_METROLITE_SUPPORT)
   1081     {
   1082         "vsan",
   1083         ING_VSANm,
   1084         FLEX_COUNTER_ML_DEFAULT_FCOE_TABLE_POOL_NUMBER,
   1085         FLEX_COUNTER_POOL_USED_BY_VSAN_TABLE
   1086     },
   1087     {
   1088         "fcoe",
   1089         L3_ENTRY_IPV4_MULTICASTm,
   1090         FLEX_COUNTER_ML_DEFAULT_FCOE_TABLE_POOL_NUMBER,
   1091         FLEX_COUNTER_POOL_USED_BY_FCOE_TABLE
   1092     },
   1093     {
   1094         "l3route",
   1095         L3_DEFIPm,
   1096         FLEX_COUNTER_ML_DEFAULT_L3_ROUTE_TABLE_POOL_NUMBER,
   1097         FLEX_COUNTER_POOL_USED_BY_L3_ROUTE_TABLE
   1098     },
   1099 #else 
   1100     {
   1101         "vsan",
   1102         ING_VSANm,
   1103         FLEX_COUNTER_DEFAULT_FCOE_TABLE_POOL_NUMBER,
   1104         FLEX_COUNTER_POOL_USED_BY_VSAN_TABLE
   1105     },
   1106     {
   1107         "fcoe",
   1108         L3_ENTRY_IPV4_MULTICASTm,
   1109         FLEX_COUNTER_DEFAULT_FCOE_TABLE_POOL_NUMBER,
   1110         FLEX_COUNTER_POOL_USED_BY_FCOE_TABLE
   1111     },
   1112     {
   1113         "l3route",
   1114         L3_DEFIPm,
   1115         FLEX_COUNTER_DEFAULT_L3_ROUTE_TABLE_POOL_NUMBER,
   1116         FLEX_COUNTER_POOL_USED_BY_L3_ROUTE_TABLE
   1117     },
   1118 #endif
   1119 #endif
   1120 #if defined(BCM_METROLITE_SUPPORT)
   1121     {
   1122         "niv",
   1123         SOURCE_VPm,
   1124         FLEX_COUNTER_ML_DEFAULT_SOURCE_VP_TABLE_POOL_NUMBER,
   1125         FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE
   1126     },
   1127 #else
   1128     {
   1129         "niv",
   1130         SOURCE_VPm,
   1131         FLEX_COUNTER_DEFAULT_SOURCE_VP_TABLE_POOL_NUMBER,
   1132         FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE
   1133     },
   1134 
   1135 #endif
   1136 #if defined(BCM_METROLITE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
   1137 #if  defined(BCM_METROLITE_SUPPORT)
   1138     {
   1139         "ipmc",
   1140         L3_ENTRY_IPV4_MULTICASTm,
   1141         FLEX_COUNTER_ML_DEFAULT_FCOE_TABLE_POOL_NUMBER,
   1142         FLEX_COUNTER_POOL_USED_BY_FCOE_TABLE
   1143     },
   1144 #else
   1145     {
   1146         "ipmc",
   1147         L3_ENTRY_IPV4_MULTICASTm,
   1148         FLEX_COUNTER_DEFAULT_FCOE_TABLE_POOL_NUMBER,
   1149         FLEX_COUNTER_POOL_USED_BY_FCOE_TABLE
   1150     },
   1151 #endif
   1152 #endif
   1153 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_METROLITE_SUPPORT)
   1154 #if  defined(BCM_METROLITE_SUPPORT)
   1155     {
   1156         "icap",
   1157         IFP_POLICY_TABLEm,
   1158         FLEX_COUNTER_ML_DEFAULT_IFP_POLICY_TABLE_POOL_NUMBER,
   1159         FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE
   1160     },
   1161 #else 
   1162     {
   1163         "icap",
   1164         IFP_POLICY_TABLEm,
   1165         FLEX_COUNTER_DEFAULT_IFP_POLICY_TABLE_POOL_NUMBER,
   1166         FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE
   1167     },
   1168 #endif
   1169 #endif
   1170 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_METROLITE_SUPPORT) 
   1171 #if  defined(BCM_METROLITE_SUPPORT)
   1172     {
   1173         "em",
   1174         EXACT_MATCH_2_ENTRY_ONLYm,
   1175         FLEX_COUNTER_ML_DEFAULT_EM_POLICY_TABLE_POOL_NUMBER,
   1176         FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE
   1177     },
   1178     {
   1179         "agm",
   1180         AGM_MONITOR_TABLEm,
   1181         FLEX_COUNTER_ML_DEFAULT_AGM_MONITOR_TABLE_POOL_NUMBER,
   1182         FLEX_COUNTER_POOL_USED_BY_AGM_MONITOR_TABLE
   1183     }
   1184 #else
   1185     {
   1186         "em",
   1187         EXACT_MATCH_2_ENTRY_ONLYm,
   1188         FLEX_COUNTER_DEFAULT_EM_POLICY_TABLE_POOL_NUMBER,
   1189         FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE
   1190     },
   1191     {
   1192         "agm",
   1193         AGM_MONITOR_TABLEm,
   1194         FLEX_COUNTER_DEFAULT_AGM_MONITOR_TABLE_POOL_NUMBER,
   1195         FLEX_COUNTER_POOL_USED_BY_AGM_MONITOR_TABLE
   1196     }
   1197 #endif
   1198 #endif
   1199 };
   1200 
   1201 static flex_object_default_t egr_flex_object_default[]={
   1202     {
   1203         "port",
   1204         EGR_PORTm,
   1205         FLEX_COUNTER_DEFAULT_EGR_PORT_TABLE_POOL_NUMBER,
   1206         FLEX_COUNTER_POOL_USED_BY_EGR_PORT_TABLE
   1207     },
   1208 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_METROLITE_SUPPORT)
   1209     {
   1210         "vlanxlate",
   1211         EGR_VLAN_XLATEm,
   1212         FLEX_COUNTER_TD2_DEFAULT_EGR_VLAN_XLATE_TABLE_POOL_NUMBER,
   1213         FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE
   1214     },
   1215     {
   1216         "mimlookupid",
   1217         EGR_VLAN_XLATEm,
   1218         FLEX_COUNTER_TD2_DEFAULT_EGR_VLAN_XLATE_TABLE_POOL_NUMBER,
   1219         FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE
   1220     },
   1221     {
   1222         "l2gre",
   1223         EGR_DVP_ATTRIBUTE_1m,
   1224         FLEX_COUNTER_TD2_DEFAULT_EGR_DVP_ATTRIBUTE_1_TABLE_POOL_NUMBER,
   1225         FLEX_COUNTER_POOL_USED_BY_EGR_DVP_ATTRIBUTE_1_TABLE
   1226     },
   1227     {
   1228         "vxlan",
   1229         EGR_DVP_ATTRIBUTE_1m,
   1230         FLEX_COUNTER_TD2_DEFAULT_EGR_DVP_ATTRIBUTE_1_TABLE_POOL_NUMBER,
   1231         FLEX_COUNTER_POOL_USED_BY_EGR_DVP_ATTRIBUTE_1_TABLE
   1232     }, 
   1233     {
   1234         "l3nat",
   1235         EGR_NAT_PACKET_EDIT_INFOm,
   1236         FLEX_COUNTER_TD2_DEFAULT_L3_NAT_TABLE_POOL_NUMBER,
   1237         FLEX_COUNTER_POOL_USED_BY_EGR_L3_NAT_TABLE
   1238     },   
   1239 #else
   1240 #if defined(BCM_APACHE_SUPPORT)
   1241     {
   1242         "vlanxlatescndlkup",
   1243         EGR_VLAN_XLATEm,
   1244         FLEX_COUNTER_DEFAULT_EGR_VLAN_XLATE_SCND_LKUP_POOL_NUMBER,
   1245         FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE_FOR_SCND_LKUP
   1246     },
   1247 #endif
   1248     {
   1249         "vlanxlate",
   1250         EGR_VLAN_XLATEm,
   1251         FLEX_COUNTER_DEFAULT_EGR_VLAN_XLATE_TABLE_POOL_NUMBER,
   1252         FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE
   1253     },
   1254     {
   1255         "mimlookupid",
   1256         EGR_VLAN_XLATEm,
   1257         FLEX_COUNTER_DEFAULT_EGR_VLAN_XLATE_TABLE_POOL_NUMBER,
   1258         FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE
   1259     },
   1260     {
   1261         "l2gre",
   1262         EGR_DVP_ATTRIBUTE_1m,
   1263         FLEX_COUNTER_DEFAULT_EGR_DVP_ATTRIBUTE_1_TABLE_POOL_NUMBER,
   1264         FLEX_COUNTER_POOL_USED_BY_EGR_DVP_ATTRIBUTE_1_TABLE
   1265     },
   1266     {
   1267         "vxlan",
   1268         EGR_DVP_ATTRIBUTE_1m,
   1269         FLEX_COUNTER_DEFAULT_EGR_DVP_ATTRIBUTE_1_TABLE_POOL_NUMBER,
   1270         FLEX_COUNTER_POOL_USED_BY_EGR_DVP_ATTRIBUTE_1_TABLE
   1271     },
   1272     {
   1273         "l3nat",
   1274         EGR_NAT_PACKET_EDIT_INFOm,
   1275         FLEX_COUNTER_DEFAULT_L3_NAT_TABLE_POOL_NUMBER,
   1276         FLEX_COUNTER_POOL_USED_BY_EGR_L3_NAT_TABLE
   1277     },    
   1278 #endif
   1279     {
   1280         "vlan",
   1281         EGR_VLANm,
   1282         FLEX_COUNTER_DEFAULT_EGR_VLAN_TABLE_POOL_NUMBER,
   1283         FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_TABLE
   1284     },
   1285     {
   1286         "vfi",
   1287         EGR_VFIm,
   1288         FLEX_COUNTER_DEFAULT_EGR_VFI_TABLE_POOL_NUMBER,
   1289         FLEX_COUNTER_POOL_USED_BY_EGR_VFI_TABLE
   1290     },
   1291     {
   1292         "l3intf",
   1293         EGR_L3_NEXT_HOPm,
   1294         FLEX_COUNTER_DEFAULT_EGR_L3_NEXT_HOP_TABLE_POOL_NUMBER,
   1295         FLEX_COUNTER_POOL_USED_BY_EGR_L3_NEXT_HOP_TABLE
   1296     },
   1297     {
   1298         "niv",
   1299         EGR_L3_NEXT_HOPm,
   1300         FLEX_COUNTER_DEFAULT_EGR_L3_NEXT_HOP_TABLE_POOL_NUMBER,
   1301         FLEX_COUNTER_POOL_USED_BY_EGR_L3_NEXT_HOP_TABLE
   1302     },    
   1303     {
   1304         "wlan",
   1305         EGR_L3_NEXT_HOPm,
   1306         FLEX_COUNTER_DEFAULT_EGR_L3_NEXT_HOP_TABLE_POOL_NUMBER,
   1307         FLEX_COUNTER_POOL_USED_BY_EGR_L3_NEXT_HOP_TABLE
   1308     },    
   1309     {
   1310         "mim",
   1311         EGR_L3_NEXT_HOPm,
   1312         FLEX_COUNTER_DEFAULT_EGR_L3_NEXT_HOP_TABLE_POOL_NUMBER,
   1313         FLEX_COUNTER_POOL_USED_BY_EGR_L3_NEXT_HOP_TABLE
   1314     },
   1315 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   1316     {
   1317         "ecap",
   1318         EFP_POLICY_TABLEm,
   1319         FLEX_COUNTER_DEFAULT_EGR_EFP_POLICY_TABLE_POOL_NUMBER,
   1320         FLEX_COUNTER_POOL_USED_BY_EGR_EFP_POLICY_TABLE
   1321     },
   1322     {
   1323         "mplstunnel",
   1324         EGR_IP_TUNNEL_MPLSm,
   1325         FLEX_COUNTER_DEFAULT_EGR_IP_TUNNEL_MPLS_POOL_NUMBER,
   1326         FLEX_COUNTER_POOL_USED_BY_EGR_IP_TUNNEL_MPLS_TABLE
   1327     },
   1328     {
   1329         "mplstunnelscnd",
   1330         EGR_IP_TUNNEL_MPLSm,
   1331         FLEX_COUNTER_DEFAULT_EGR_IP_TUNNEL_MPLS_SCND_LBL_POOL_NUMBER,
   1332         FLEX_COUNTER_POOL_USED_BY_EGR_IP_TUNNEL_MPLS_SCND_LBL_TABLE
   1333     }
   1334 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   1335 };
   1336 
   1337 typedef struct flex_object_config_f {
   1338     soc_mem_t obj_mem;
   1339     uint32 config_pool;
   1340     uint32 share_criteria;
   1341     uint32 exclude_criteria;
   1342 }flex_object_config_t;
   1343 
   1344 #define INVALID_CONFIG 0
   1345 
   1346 static flex_object_config_t ing_flex_object_config[]={
   1347     {PORT_TABm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1348     {VFP_POLICY_TABLEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1349     {VLAN_TABm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1350     {VFIm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1351     {VRFm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1352     {MPLS_ENTRYm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1353     {VLAN_XLATEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1354     {L3_IIFm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1355     {L3_TUNNELm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1356     {L3_ENTRY_2m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1357     {L3_DEFIPm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1358     {L3_ENTRY_IPV4_MULTICASTm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1359     {ING_VSANm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1360     {EXT_FP_POLICYm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1361     {SOURCE_VPm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1362     {FP_POLICY_TABLEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1363     {IFP_POLICY_TABLEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1364     {IFP_POLICY_TABLE_PIPE0m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1365     {IFP_POLICY_TABLE_PIPE1m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1366     {IFP_POLICY_TABLE_PIPE2m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1367     {IFP_POLICY_TABLE_PIPE3m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1368     {IFP_POLICY_TABLE_PIPE4m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1369     {IFP_POLICY_TABLE_PIPE5m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1370     {IFP_POLICY_TABLE_PIPE6m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1371     {IFP_POLICY_TABLE_PIPE7m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1372     {AGM_MONITOR_TABLEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1373     {VFP_POLICY_TABLE_PIPE0m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1374     {VFP_POLICY_TABLE_PIPE1m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1375     {VFP_POLICY_TABLE_PIPE2m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1376     {VFP_POLICY_TABLE_PIPE3m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1377     {VFP_POLICY_TABLE_PIPE4m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1378     {VFP_POLICY_TABLE_PIPE5m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1379     {VFP_POLICY_TABLE_PIPE6m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1380     {VFP_POLICY_TABLE_PIPE7m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1381     {EXACT_MATCH_2m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1382     {EXACT_MATCH_2_PIPE0m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1383     {EXACT_MATCH_2_PIPE1m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1384     {EXACT_MATCH_2_PIPE2m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1385     {EXACT_MATCH_2_PIPE3m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1386     {EXACT_MATCH_4m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1387     {EXACT_MATCH_4_PIPE0m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1388     {EXACT_MATCH_4_PIPE1m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1389     {EXACT_MATCH_4_PIPE2m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1390     {EXACT_MATCH_4_PIPE3m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1391     {VLAN_XLATE_1_DOUBLEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1392     {VLAN_XLATE_2_DOUBLEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1393     {LPORT_TABm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1394     {L3_ENTRY_QUADm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1395     {L3_ENTRY_DOUBLEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1396     {VRF_ATTRS_2m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG}
   1397 };
   1398 
   1399 static flex_object_config_t egr_flex_object_config[]={
   1400     {EGR_VLANm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1401     {EGR_VFIm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1402     {EGR_L3_NEXT_HOPm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1403     {EGR_VLAN_XLATEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1404     {EGR_PORTm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1405     {EGR_DVP_ATTRIBUTE_1m, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1406     {EGR_NAT_PACKET_EDIT_INFOm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1407     {EFP_POLICY_TABLEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1408     {EGR_IP_TUNNEL_MPLSm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1409     {EGR_DVP_ATTRIBUTEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1410     {EGR_VLAN_XLATE_1_DOUBLEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1411     {EGR_VLAN_XLATE_2_DOUBLEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1412     {EGR_LPORT_PROFILEm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1413     {EGR_HISTO_MON_0_Q_LATENCY_LIMIT_SELm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1414     {EGR_HISTO_MON_1_Q_LATENCY_LIMIT_SELm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1415     {EGR_HISTO_MON_2_Q_LATENCY_LIMIT_SELm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG},
   1416     {EGR_HISTO_MON_3_Q_LATENCY_LIMIT_SELm, INVALID_CONFIG, INVALID_CONFIG, INVALID_CONFIG}
   1417 };
   1418 
   1419 static uint8 flex_objects[][64]={
   1420              "bcmStatObjectIngPort",
   1421              "bcmStatObjectIngVlan",
   1422              "bcmStatObjectIngVlanXlate",
   1423              "bcmStatObjectIngVfi",
   1424              "bcmStatObjectIngL3Intf",
   1425              "bcmStatObjectIngVrf",
   1426              "bcmStatObjectIngPolicy",
   1427              "bcmStatObjectIngMplsVcLabel",
   1428              "bcmStatObjectIngMplsSwitchLabel",
   1429              "bcmStatObjectEgrPort",
   1430              "bcmStatObjectEgrVlan",
   1431              "bcmStatObjectEgrVlanXlate",
   1432              "bcmStatObjectEgrVfi",
   1433              "bcmStatObjectEgrL3Intf",
   1434              "bcmStatObjectIngMplsFrrLabel",
   1435              "bcmStatObjectIngL3Host",
   1436              "bcmStatObjectIngTrill",
   1437              "bcmStatObjectIngMimLookupId",
   1438              "bcmStatObjectIngL2Gre",
   1439              "bcmStatObjectIngEXTPolicy",
   1440              "bcmStatObjectEgrWlan",
   1441              "bcmStatObjectEgrMim",
   1442              "bcmStatObjectEgrMimLookupId",
   1443              "bcmStatObjectEgrL2Gre",
   1444              "bcmStatObjectIngVxlan",
   1445              "bcmStatObjectIngVsan",
   1446              "bcmStatObjectIngFcoe",
   1447              "bcmStatObjectIngL3Route",
   1448              "bcmStatObjectEgrVxlan",
   1449              "bcmStatObjectEgrL3Nat",
   1450              "bcmStatObjectIngNiv",
   1451              "bcmStatObjectEgrNiv",
   1452              "bcmStatObjectIngIpmc",
   1453              "bcmStatObjectIngVxlanDip",
   1454              "bcmStatObjIngIngressPolicy",
   1455              "bcmStatObjectIngVlanXlateSecondLookup",
   1456              "bcmStatObjectEgrVlanXlateSecondLookup",
   1457              "bcmStatObjectIngMplsSwitchSecondLabel",
   1458              "bcmStatObjectEgrMplsTunnelSecondLabel"};
   1459 
   1460 
   1461 static uint8 flex_group_modes[][48] = {
   1462              "bcmStatGroupModeSingle = 0",
   1463              "bcmStatGroupModeTrafficType = 1",
   1464              "bcmStatGroupModeDlfAll = 2",
   1465              "bcmStatGroupModeDlfIntPri = 3",
   1466              "bcmStatGroupModeTyped = 4",
   1467              "bcmStatGroupModeTypedAll = 5",
   1468              "bcmStatGroupModeTypedIntPri = 6",
   1469              "bcmStatGroupModeSingleWithControl = 7",
   1470              "bcmStatGroupModeTrafficTypeWithControl = 8",
   1471              "bcmStatGroupModeDlfAllWithControl = 9",
   1472              "bcmStatGroupModeDlfIntPriWithControl = 10",
   1473              "bcmStatGroupModeTypedWithControl = 11",
   1474              "bcmStatGroupModeTypedAllWithControl = 12",
   1475              "bcmStatGroupModeTypedIntPriWithControl = 13",
   1476              "bcmStatGroupModeDot1P = 14",
   1477              "bcmStatGroupModeIntPri = 15",
   1478              "bcmStatGroupModeIntPriCng = 16",
   1479              "bcmStatGroupModeSvpType = 17",
   1480              "bcmStatGroupModeDscp = 18",
   1481              "bcmStatGroupModeDvpType = 19",
   1482              "bcmStatGroupModeCng = 20",
   1483              "bcmStatGroupModeFlex1 = 21",
   1484              "bcmStatGroupModeFlex2 = 22",
   1485              "bcmStatGroupModeFlex3 = 23",
   1486              "bcmStatGroupModeFlex4 = 24"};
   1487 
   1488 /* The static array is mapped one to one with the stat objects */
   1489 static uint32 flex_used_by_table[]={
   1490               FLEX_COUNTER_POOL_USED_BY_PORT_TABLE,
   1491               FLEX_COUNTER_POOL_USED_BY_VLAN_TABLE,
   1492               FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE,
   1493               FLEX_COUNTER_POOL_USED_BY_VFI_TABLE,
   1494               FLEX_COUNTER_POOL_USED_BY_L3_IIF_TABLE,
   1495               FLEX_COUNTER_POOL_USED_BY_VRF_TABLE,
   1496               FLEX_COUNTER_POOL_USED_BY_VFP_POLICY_TABLE,
   1497               FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE,
   1498               FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE,
   1499               FLEX_COUNTER_POOL_USED_BY_EGR_PORT_TABLE,
   1500               FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_TABLE,
   1501               FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE,
   1502               FLEX_COUNTER_POOL_USED_BY_EGR_VFI_TABLE,
   1503               FLEX_COUNTER_POOL_USED_BY_EGR_L3_NEXT_HOP_TABLE,
   1504               FLEX_COUNTER_POOL_USED_BY_L3_TUNNEL_TABLE,
   1505               FLEX_COUNTER_POOL_USED_BY_L3_ENTRY_TABLE,
   1506               FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE,
   1507               FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE,
   1508               FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE,
   1509               FLEX_COUNTER_POOL_USED_BY_EXT_FP_POLICY_TABLE,
   1510               0,
   1511               FLEX_COUNTER_POOL_USED_BY_EGR_L3_NEXT_HOP_TABLE,
   1512               FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE,
   1513               FLEX_COUNTER_POOL_USED_BY_EGR_DVP_ATTRIBUTE_1_TABLE,
   1514               FLEX_COUNTER_POOL_USED_BY_EGR_DVP_ATTRIBUTE_1_TABLE,
   1515               FLEX_COUNTER_POOL_USED_BY_VSAN_TABLE,
   1516               FLEX_COUNTER_POOL_USED_BY_FCOE_TABLE,
   1517               FLEX_COUNTER_POOL_USED_BY_L3_ROUTE_TABLE,
   1518               FLEX_COUNTER_POOL_USED_BY_EGR_DVP_ATTRIBUTE_1_TABLE,
   1519               FLEX_COUNTER_POOL_USED_BY_EGR_L3_NAT_TABLE,
   1520               FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE,
   1521               FLEX_COUNTER_POOL_USED_BY_EGR_L3_NEXT_HOP_TABLE,
   1522               FLEX_COUNTER_POOL_USED_BY_FCOE_TABLE,
   1523               FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE,
   1524               FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE,
   1525               FLEX_COUNTER_POOL_USED_BY_EGR_EFP_POLICY_TABLE,
   1526               FLEX_COUNTER_POOL_USED_BY_EGR_IP_TUNNEL_MPLS_TABLE,
   1527               FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE,
   1528               FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE,
   1529               FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE_FOR_SCND_LKUP,
   1530               FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE_FOR_SCND_LKUP,
   1531               FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE_FOR_SCND_LKUP,
   1532               FLEX_COUNTER_POOL_USED_BY_EGR_IP_TUNNEL_MPLS_SCND_LBL_TABLE};
   1533 
   1534 static uint32 *local_scache_ptr[SOC_MAX_NUM_DEVICES]={NULL};
   1535 static uint32 local_scache_size[SOC_MAX_NUM_DEVICES] = {0};
   1536 
   1537 #ifdef BCM_WARM_BOOT_SUPPORT
   1538 #include <bcm_int/esw/switch.h>
   1539 #define BCM_WB_VERSION_1_3                SOC_SCACHE_VERSION(1,3)
   1540 #define BCM_WB_VERSION_1_4                SOC_SCACHE_VERSION(1,4)
   1541 #define BCM_WB_VERSION_1_5                SOC_SCACHE_VERSION(1,5)
   1542 #define BCM_WB_VERSION_1_6                SOC_SCACHE_VERSION(1,6)
   1543 #define BCM_WB_VERSION_1_7                SOC_SCACHE_VERSION(1,7)
   1544 #define BCM_WB_VERSION_1_8                SOC_SCACHE_VERSION(1,8)
   1545 #define BCM_WB_VERSION_1_9                SOC_SCACHE_VERSION(1,9)
   1546 #define BCM_STAT_WB_DEFAULT_VERSION            BCM_WB_VERSION_1_9
   1547 static soc_scache_handle_t handle[SOC_MAX_NUM_DEVICES] = {0};
   1548 static uint32              flex_scache_allocated_size[SOC_MAX_NUM_DEVICES] = {0};
   1549 static uint32              *flex_scache_ptr[SOC_MAX_NUM_DEVICES]={NULL};
   1550 #endif
   1551 
   1552 typedef struct flex_counter_fields {
   1553                uint32    offset_mode;
   1554                uint32    pool_number;
   1555                uint32    base_idx;
   1556 }flex_counter_fields_t;
   1557 
   1558 static flex_counter_fields_t mpls_entry_flex_counter_fields[]={
   1559                              /* MPLS View=0 */
   1560                              {MPLS__FLEX_CTR_OFFSET_MODEf,
   1561                               MPLS__FLEX_CTR_POOL_NUMBERf,
   1562                               MPLS__FLEX_CTR_BASE_COUNTER_IDXf},
   1563                              /* MIM_NVP View=1 */
   1564                              {MIM_NVP__FLEX_CTR_OFFSET_MODEf,
   1565                               MIM_NVP__FLEX_CTR_POOL_NUMBERf,
   1566                               MIM_NVP__FLEX_CTR_BASE_COUNTER_IDXf},
   1567                              /* MIM_ISID   View=2 */
   1568                              {MIM_ISID__FLEX_CTR_OFFSET_MODEf,
   1569                               MIM_ISID__FLEX_CTR_POOL_NUMBERf,
   1570                               MIM_ISID__FLEX_CTR_BASE_COUNTER_IDXf},
   1571 #ifdef BCM_TRIUMPH3_SUPPORT
   1572                              {TRILL__FLEX_CTR_OFFSET_MODEf,
   1573                               TRILL__FLEX_CTR_POOL_NUMBERf,
   1574                               TRILL__FLEX_CTR_BASE_COUNTER_IDXf},
   1575                              {IPV4UC__FLEX_CTR_OFFSET_MODEf,
   1576                               IPV4UC__FLEX_CTR_POOL_NUMBERf,
   1577                               IPV4UC__FLEX_CTR_BASE_COUNTER_IDXf},
   1578                              {IPV6UC__FLEX_CTR_OFFSET_MODEf,
   1579                               IPV6UC__FLEX_CTR_POOL_NUMBERf,
   1580                               IPV6UC__FLEX_CTR_BASE_COUNTER_IDXf} };
   1581 #else
   1582                              {INVALIDf,
   1583                               INVALIDf,
   1584                               INVALIDf},
   1585                              {INVALIDf,
   1586                               INVALIDf,
   1587                               INVALIDf},
   1588                              {INVALIDf,
   1589                               INVALIDf,
   1590                               INVALIDf} };
   1591 #endif
   1592 
   1593 
   1594 static flex_counter_fields_t egr_l3_next_hop_flex_counter_fields[]={
   1595                              /* L3 View=0 */
   1596                              {FLEX_CTR_OFFSET_MODEf,
   1597                               FLEX_CTR_POOL_NUMBERf,
   1598                               FLEX_CTR_BASE_COUNTER_IDXf},
   1599                              {L3__FLEX_CTR_OFFSET_MODEf,
   1600                               L3__FLEX_CTR_POOL_NUMBERf,
   1601                               L3__FLEX_CTR_BASE_COUNTER_IDXf},
   1602 #ifdef BCM_TRIUMPH3_SUPPORT
   1603                              {WLAN__FLEX_CTR_OFFSET_MODEf,
   1604                               WLAN__FLEX_CTR_POOL_NUMBERf,
   1605                               WLAN__FLEX_CTR_BASE_COUNTER_IDXf},
   1606 #else
   1607                              {INVALIDf,
   1608                               INVALIDf,
   1609                               INVALIDf},
   1610 #endif
   1611                              {PROXY__FLEX_CTR_OFFSET_MODEf,
   1612                               PROXY__FLEX_CTR_POOL_NUMBERf,
   1613                               PROXY__FLEX_CTR_BASE_COUNTER_IDXf},
   1614                              /* MPLS View=1 */
   1615                              {MPLS__FLEX_CTR_OFFSET_MODEf,
   1616                               MPLS__FLEX_CTR_POOL_NUMBERf,
   1617                               MPLS__FLEX_CTR_BASE_COUNTER_IDXf},
   1618                              /* SD_TAG View=2 */
   1619                              {SD_TAG__FLEX_CTR_OFFSET_MODEf,
   1620                               SD_TAG__FLEX_CTR_POOL_NUMBERf,
   1621                               SD_TAG__FLEX_CTR_BASE_COUNTER_IDXf},
   1622                              /* MIM View=3 */
   1623                              {MIM__FLEX_CTR_OFFSET_MODEf,
   1624                               MIM__FLEX_CTR_POOL_NUMBERf,
   1625                               MIM__FLEX_CTR_BASE_COUNTER_IDXf},
   1626                              /* L2_OTAG */
   1627                              {L2_OTAG__FLEX_CTR_OFFSET_MODEf,
   1628                               L2_OTAG__FLEX_CTR_POOL_NUMBERf,
   1629                               L2_OTAG__FLEX_CTR_BASE_COUNTER_IDXf},
   1630                              {L3MC__FLEX_CTR_OFFSET_MODEf,
   1631                               L3MC__FLEX_CTR_POOL_NUMBERf,
   1632                               L3MC__FLEX_CTR_BASE_COUNTER_IDXf}};
   1633 
   1634 static flex_counter_fields_t egr_vlan_xlate_flex_counter_fields[]={
   1635                              /* Default VLAN_XLATE,VLAN_XLATE_DVP View=0 */
   1636                              {XLATE__FLEX_CTR_OFFSET_MODEf,
   1637                               XLATE__FLEX_CTR_POOL_NUMBERf,
   1638                               XLATE__FLEX_CTR_BASE_COUNTER_IDXf},
   1639                              /* ISID_DVP_XLATE View=4 */
   1640                              {MIM_ISID__FLEX_CTR_OFFSET_MODEf,
   1641                               MIM_ISID__FLEX_CTR_POOL_NUMBERf,
   1642                               MIM_ISID__FLEX_CTR_BASE_COUNTER_IDXf} };
   1643 
   1644 static flex_counter_fields_t vlan_xlate_flex_counter_fields[]={
   1645                              /* XLATE type = 13 */
   1646                              {XLATE__FLEX_CTR_OFFSET_MODEf,
   1647                               XLATE__FLEX_CTR_POOL_NUMBERf,
   1648                               XLATE__FLEX_CTR_BASE_COUNTER_IDXf},
   1649                              /* L2GRE_DIP type = 13 */
   1650                              {L2GRE_DIP__FLEX_CTR_OFFSET_MODEf,
   1651                               L2GRE_DIP__FLEX_CTR_POOL_NUMBERf,
   1652                               L2GRE_DIP__FLEX_CTR_BASE_COUNTER_IDXf},
   1653                               /* VXLAN_DIP type = 18 */
   1654                              {VXLAN_DIP__FLEX_CTR_OFFSET_MODEf,
   1655                               VXLAN_DIP__FLEX_CTR_POOL_NUMBERf,
   1656                               VXLAN_DIP__FLEX_CTR_BASE_COUNTER_IDXf} };
   1657 
   1658 static flex_counter_fields_t egr_dvp_attribute_counter_fields[]={
   1659                              /* TRILL vp type = 1 */
   1660                              {TRILL__FLEX_CTR_OFFSET_MODEf,
   1661                               TRILL__FLEX_CTR_POOL_NUMBERf,
   1662                               TRILL__FLEX_CTR_BASE_COUNTER_IDXf},
   1663                              /* vxlan type = 2 */
   1664                              {VXLAN__FLEX_CTR_OFFSET_MODEf,
   1665                               VXLAN__FLEX_CTR_POOL_NUMBERf,
   1666                               VXLAN__FLEX_CTR_BASE_COUNTER_IDXf},
   1667                               /* L2Gre vp type = 3 */
   1668                              {L2GRE__FLEX_CTR_OFFSET_MODEf,
   1669                               L2GRE__FLEX_CTR_POOL_NUMBERf,
   1670                               L2GRE__FLEX_CTR_BASE_COUNTER_IDXf} };
   1671 
   1672 #ifdef BCM_TRIDENT2_SUPPORT
   1673 
   1674 static flex_counter_fields_t l3_entry_ipv4_multicast_counter_fields[] = {
   1675                              /* IPV4_UNICAST_EXT, type = 1 */
   1676                              {IPV4UC_EXT__FLEX_CTR_OFFSET_MODEf,
   1677                               IPV4UC_EXT__FLEX_CTR_POOL_NUMBERf,
   1678                               IPV4UC_EXT__FLEX_CTR_BASE_COUNTER_IDXf},
   1679                              /* IPV4_MULTICAST, type = 4 */
   1680                              {IPV4MC__FLEX_CTR_OFFSET_MODEf,
   1681                               IPV4MC__FLEX_CTR_POOL_NUMBERf,
   1682                               IPV4MC__FLEX_CTR_BASE_COUNTER_IDXf},
   1683                              /* FCOE_EXT, type = 13, 15, 17 */
   1684                              {FCOE_EXT__FLEX_CTR_OFFSET_MODEf,
   1685                               FCOE_EXT__FLEX_CTR_POOL_NUMBERf,
   1686                               FCOE_EXT__FLEX_CTR_BASE_COUNTER_IDXf} };
   1687 
   1688 static flex_counter_fields_t l3_entry_ipv6_multicast_counter_fields[] = {
   1689                              /* IPV6_UNICAST_EXT, type = 3 */
   1690                              {IPV6UC_EXT__FLEX_CTR_OFFSET_MODEf,
   1691                               IPV6UC_EXT__FLEX_CTR_POOL_NUMBERf,
   1692                               IPV6UC_EXT__FLEX_CTR_BASE_COUNTER_IDXf},
   1693                              /* IPV6_MULTICAST, type = 5 */
   1694                              {IPV6MC__FLEX_CTR_OFFSET_MODEf,
   1695                               IPV6MC__FLEX_CTR_POOL_NUMBERf,
   1696                               IPV6MC__FLEX_CTR_BASE_COUNTER_IDXf} };
   1697 
   1698 #endif
   1699 
   1700 #if defined (BCM_TRIDENT2PLUS_SUPPORT) && defined (INCLUDE_L3)
   1701 static flex_counter_fields_t ip_tunnel_mpls_entry_counter_fields[] = {
   1702                              /* Label 1 Flex Counter fields */
   1703                              {FLEX_CTR_OFFSET_MODE_0f,
   1704                               FLEX_CTR_POOL_NUMBER_0f,
   1705                               FLEX_CTR_BASE_COUNTER_IDX_0f},
   1706                              /* Label 2 Flex Counter fields */
   1707                              {FLEX_CTR_OFFSET_MODE_1f,
   1708                               FLEX_CTR_POOL_NUMBER_1f,
   1709                               FLEX_CTR_BASE_COUNTER_IDX_1f},
   1710                              /* Label 3 Flex Counter fields */
   1711                              {FLEX_CTR_OFFSET_MODE_2f,
   1712                               FLEX_CTR_POOL_NUMBER_2f,
   1713                               FLEX_CTR_BASE_COUNTER_IDX_2f},
   1714                              /* Label 4 Flex Counter fields */
   1715                              {FLEX_CTR_OFFSET_MODE_3f,
   1716                               FLEX_CTR_POOL_NUMBER_3f,
   1717                               FLEX_CTR_BASE_COUNTER_IDX_3f},
   1718 #ifdef BCM_APACHE_SUPPORT
   1719                              /* Label 5 Flex Counter fields */
   1720                              {FLEX_CTR_OFFSET_MODE_4f,
   1721                               FLEX_CTR_POOL_NUMBER_4f,
   1722                               FLEX_CTR_BASE_COUNTER_IDX_4f},
   1723                              /* Label 6 Flex Counter fields */
   1724                              {FLEX_CTR_OFFSET_MODE_5f,
   1725                               FLEX_CTR_POOL_NUMBER_5f,
   1726                               FLEX_CTR_BASE_COUNTER_IDX_5f},
   1727                              /* Label 7 Flex Counter fields */
   1728                              {FLEX_CTR_OFFSET_MODE_6f,
   1729                               FLEX_CTR_POOL_NUMBER_6f,
   1730                               FLEX_CTR_BASE_COUNTER_IDX_6f},
   1731                              /* Label 8 Flex Counter fields */
   1732                              {FLEX_CTR_OFFSET_MODE_7f,
   1733                               FLEX_CTR_POOL_NUMBER_7f,
   1734                               FLEX_CTR_BASE_COUNTER_IDX_7f}
   1735 #endif /* BCM_APACHE_SUPPORT */
   1736                               };
   1737 static bcm_stat_object_t egr_mpls_tunnel_object[] = {
   1738                          bcmStatObjectEgrMplsTunnelLabel,
   1739                          bcmStatObjectEgrMplsTunnelSecondLabel};
   1740 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   1741 
   1742 
   1743 #define BCM_STAT_FLEX_WARMBOOT_READ_CHUNK 256
   1744 
   1745 #if defined (BCM_TOMAHAWK_SUPPORT) && defined (INCLUDE_FLOWTRACKER)
   1746 static uint32 _bcm_stat_num_rsvd = 0;
   1747 static uint32 _bcm_stat_ing_pools_rsvd = 0;
   1748 static uint32 _bcm_stat_mode_rsvd = -1;
   1749 static bcm_error_t
   1750 _bcm_esw_stat_flex_flowtracker_cleanup(int unit);
   1751 #endif
   1752 
   1753 
   1754 /* Flex counter collect routine periodically invoked by counter thread */
   1755 STATIC void
   1756 _bcm_esw_stat_flex_counter_collect(int                       unit,
   1757                                    bcm_stat_flex_direction_t cnt_direction,
   1758                                    uint32                    flexctr_pool,
   1759                                    uint32                    counter_idx);
   1760 
   1761 STATIC
   1762 int th_flex_counter_set(int unit, bcm_stat_flex_direction_t direction, int pipe_num,
   1763                       int pool_id, uint32 index, bcm_stat_value_t *value_array,
   1764                       int num_entries,  int byte_flag);
   1765 
   1766 #ifdef BCM_TOMAHAWK_SUPPORT
   1767 STATIC
   1768 int th_flex_centralized_counter_set(int unit, bcm_stat_flex_direction_t direction,
   1769                                     int pipe_num, int pool_id, uint32 index,
   1770                                     bcm_stat_value_t *value_array,
   1771                                     int num_entries, int byte_flag);
   1772 #endif /* BCM_TOMAHAWK_SUPPORT */
   1773 
   1774 extern compaction_status_t compaction_info;
   1775 /* Cache used for counter movement */
   1776 static uint64 *flex_byte_counter_compaction
   1777                [SOC_MAX_NUM_DEVICES]
   1778                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
   1779                [SOC_MAX_NUM_PIPES]
   1780                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
   1781                = {{{{NULL}}}};
   1782 static uint32 *flex_packet_counter_compaction
   1783                [SOC_MAX_NUM_DEVICES]
   1784                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
   1785                [SOC_MAX_NUM_PIPES]
   1786                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
   1787                 = {{{{NULL}}}};
   1788 static uint64 *flex_packet64_counter_compaction
   1789                [SOC_MAX_NUM_DEVICES]
   1790                [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]
   1791                [SOC_MAX_NUM_PIPES]
   1792                [BCM_STAT_FLEX_COUNTER_MAX_POOL]
   1793                = {{{{NULL}}}};
   1794 /*
   1795  * Function:
   1796  *     _bcm_esw_get_fp_mode_global 
   1797  * Description:
   1798  *      Helper function to return 1 if configured in Global mode
   1799  */
   1800 #if defined (BCM_TOMAHAWK_SUPPORT)
   1801 int
   1802 _bcm_esw_get_fp_mode_global(int unit, bcm_field_qualify_t stage) {
   1803     bcm_field_group_oper_mode_t oper_mode = bcmFieldGroupOperModeGlobal;
   1804     int rv = BCM_E_NONE;
   1805 
   1806     if (!(soc_feature(unit,soc_feature_stat_multi_pipe_support))) {
   1807         return 1;
   1808     }
   1809 
   1810     if ((stage != bcmFieldQualifyStageIngress) &&
   1811          !soc_feature(unit, soc_feature_field_multi_stage)) {
   1812         /* Do not call Field API for any stage other than Ingress,
   1813          * in low latency modes.
   1814          * Please note soc_feature_field_multi_stage is used to
   1815          * pass latency mode info ONLY!!! .
   1816          */
   1817         return 1;
   1818     }
   1819 
   1820     /* If field module not being initialized, return 1 */
   1821 #if defined(BCM_FIELD_SUPPORT)
   1822     if (BCM_FAILURE(_field_is_inited(unit))) {
   1823         return 1;
   1824     }
   1825 #endif
   1826 
   1827     rv = _bcm_field_th_group_oper_mode_get(unit, stage, &oper_mode);
   1828     if (!BCM_FAILURE(rv)) {
   1829        if (oper_mode != bcmFieldGroupOperModeGlobal) {
   1830            return 0;
   1831        }
   1832     }
   1833     return 1; /*default*/
   1834 }
   1835 #endif
   1836 
   1837 static int 
   1838 _bcm_esw_get_max_pool_groups(int unit) {
   1839     
   1840     return ((SOC_IS_TOMAHAWKX(unit) ||SOC_IS_TRIDENT3X(unit)) ?
   1841                                        BCM_STAT_TH_FLEX_COUNTER_MAX_GROUPS:
   1842                                        BCM_STAT_FLEX_COUNTER_MAX_GROUPS);
   1843 }
   1844 
   1845 #if defined (BCM_TOMAHAWK_SUPPORT)
   1846 void _bcm_esw_stat_dump_info(int  unit,int pipe,uint32  pool_number, uint32 base_index);
   1847 static int
   1848 _bcm_esw_is_fp_table(soc_mem_t ingress_table) {
   1849     switch (ingress_table) {
   1850        case IFP_POLICY_TABLEm:
   1851        case IFP_POLICY_TABLE_WIDEm:
   1852        case VFP_POLICY_TABLEm:
   1853        case IFP_POLICY_TABLE_PIPE0m:
   1854        case IFP_POLICY_TABLE_WIDE_PIPE0m:
   1855        case VFP_POLICY_TABLE_PIPE0m:
   1856        case EXACT_MATCH_2_PIPE0m:
   1857        case EXACT_MATCH_4_PIPE0m:
   1858        case IFP_POLICY_TABLE_PIPE1m:
   1859        case IFP_POLICY_TABLE_WIDE_PIPE1m:
   1860        case VFP_POLICY_TABLE_PIPE1m:
   1861        case EXACT_MATCH_2_PIPE1m:
   1862        case EXACT_MATCH_4_PIPE1m:
   1863        case IFP_POLICY_TABLE_PIPE2m:
   1864        case VFP_POLICY_TABLE_PIPE2m:
   1865        case EXACT_MATCH_2_PIPE2m:
   1866        case EXACT_MATCH_4_PIPE2m:
   1867        case IFP_POLICY_TABLE_PIPE3m:
   1868        case VFP_POLICY_TABLE_PIPE3m:
   1869        case EXACT_MATCH_2_PIPE3m:
   1870        case EXACT_MATCH_4_PIPE3m:
   1871        case IFP_POLICY_TABLE_PIPE4m:
   1872        case VFP_POLICY_TABLE_PIPE4m:
   1873        case IFP_POLICY_TABLE_PIPE5m:
   1874        case VFP_POLICY_TABLE_PIPE5m:
   1875        case IFP_POLICY_TABLE_PIPE6m:
   1876        case VFP_POLICY_TABLE_PIPE6m:
   1877        case IFP_POLICY_TABLE_PIPE7m:
   1878        case VFP_POLICY_TABLE_PIPE7m:
   1879 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   1880        case EFP_POLICY_TABLEm:
   1881        case EFP_POLICY_TABLE_PIPE0m:
   1882        case EFP_POLICY_TABLE_PIPE1m:
   1883 #endif
   1884            return 1;
   1885        default:
   1886            break;
   1887     }
   1888     return 0;
   1889 }
   1890 
   1891 static int
   1892 _bcm_esw_get_fp_pipe_num(int unit, soc_mem_t ingress_table)
   1893 {
   1894     int pipe_num = 0;
   1895 
   1896     switch (ingress_table) {
   1897        case IFP_POLICY_TABLE_PIPE0m:
   1898        case VFP_POLICY_TABLE_PIPE0m:
   1899        case EXACT_MATCH_2_PIPE0m:
   1900        case EXACT_MATCH_4_PIPE0m:
   1901 #if defined(BCM_TRIDENT3_SUPPORT)
   1902        case IFP_POLICY_TABLE_WIDE_PIPE0m:
   1903 #endif
   1904 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   1905        case EFP_POLICY_TABLE_PIPE0m:
   1906 #endif
   1907             pipe_num = 0;
   1908          break;
   1909        case IFP_POLICY_TABLE_PIPE1m:
   1910        case VFP_POLICY_TABLE_PIPE1m:
   1911        case EXACT_MATCH_2_PIPE1m:
   1912        case EXACT_MATCH_4_PIPE1m:
   1913 #if defined(BCM_TRIDENT3_SUPPORT)
   1914        case IFP_POLICY_TABLE_WIDE_PIPE1m:
   1915 #endif
   1916 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   1917        case EFP_POLICY_TABLE_PIPE1m:
   1918 #endif
   1919             pipe_num = 1;
   1920          break;
   1921        case IFP_POLICY_TABLE_PIPE2m:
   1922        case VFP_POLICY_TABLE_PIPE2m:
   1923        case EXACT_MATCH_2_PIPE2m:
   1924        case EXACT_MATCH_4_PIPE2m:
   1925             pipe_num = 2;
   1926          break;
   1927        case IFP_POLICY_TABLE_PIPE3m:
   1928        case VFP_POLICY_TABLE_PIPE3m:
   1929        case EXACT_MATCH_2_PIPE3m:
   1930        case EXACT_MATCH_4_PIPE3m:
   1931             pipe_num = 3;
   1932          break;
   1933        case IFP_POLICY_TABLE_PIPE4m:
   1934        case VFP_POLICY_TABLE_PIPE4m:
   1935             pipe_num = 4;
   1936          break;
   1937        case IFP_POLICY_TABLE_PIPE5m:
   1938        case VFP_POLICY_TABLE_PIPE5m:
   1939             pipe_num = 5;
   1940          break;
   1941        case IFP_POLICY_TABLE_PIPE6m:
   1942        case VFP_POLICY_TABLE_PIPE6m:
   1943             pipe_num = 6;
   1944          break;
   1945        case IFP_POLICY_TABLE_PIPE7m:
   1946        case VFP_POLICY_TABLE_PIPE7m:
   1947             pipe_num = 7;
   1948          break;
   1949        default:
   1950             pipe_num = 0;
   1951             break;
   1952     }
   1953     return pipe_num; 
   1954 }
   1955 
   1956 bcm_error_t
   1957 _bcm_esw_get_fp_pipe_pool_from_mode(int unit, int offset_mode, bcm_field_qualify_t stage,
   1958                                                                int *pipe, int *pool) {
   1959     uint32 hint_val = 0;
   1960     bcm_error_t rv = BCM_E_CONFIG;
   1961     _field_counter_pool_bmp_t pool_bmp;
   1962     *pipe = 0;
   1963     *pool = 0xff;
   1964     if ((offset_mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
   1965         (offset_mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
   1966         offset_mode -= BCM_CUSTOM_INGRESS_MODE_START;
   1967 
   1968         if ((flex_custom_ingress_modes[unit][offset_mode].hint.type 
   1969                                   == bcmStatGroupAllocHintIngressFieldGroup) ||
   1970             (flex_custom_ingress_modes[unit][offset_mode].hint.type
   1971                                   == bcmStatGroupAllocHintExactMatchFieldGroup) || 
   1972             (flex_custom_ingress_modes[unit][offset_mode].hint.type 
   1973                                   == bcmStatGroupAllocHintVlanFieldGroup)) {
   1974             if (!_bcm_esw_get_fp_mode_global(unit, stage)) {
   1975                 hint_val = flex_custom_ingress_modes[unit][offset_mode].hint.value;
   1976                 /* Get Pipe from group */
   1977                 rv = _bcm_field_group_flex_ctr_info_get(unit, hint_val, pipe, &pool_bmp);
   1978                 *pool = flex_custom_ingress_modes[unit][offset_mode].AllocPool;
   1979             }
   1980         }
   1981     }
   1982 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   1983     if ((offset_mode >= BCM_CUSTOM_EGRESS_MODE_START) &&
   1984             (offset_mode < BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE)) {
   1985         offset_mode -= BCM_CUSTOM_EGRESS_MODE_START;
   1986         if (flex_custom_egress_modes[unit][offset_mode].hint.type
   1987                                 == bcmStatGroupAllocHintEgressFieldGroup) {
   1988             if (!_bcm_esw_get_fp_mode_global(unit, stage)) {
   1989                 hint_val =
   1990                     flex_custom_egress_modes[unit][offset_mode].hint.value;
   1991                 rv = _bcm_field_group_flex_ctr_info_get(unit, hint_val,
   1992                                                 pipe, &pool_bmp);
   1993                 *pool = flex_custom_egress_modes[unit][offset_mode].AllocPool;
   1994             }
   1995         }
   1996     }
   1997 #endif
   1998 
   1999     if (*pool == -1) {
   2000        *pool = 0xff;
   2001     }
   2002 
   2003     return rv;
   2004 }
   2005 
   2006 bcm_error_t
   2007 _bcm_esw_get_fp_pipe_from_mode(int unit, int offset_mode, 
   2008                                 bcm_field_qualify_t stage, int *pipe) {
   2009     bcm_error_t rv = BCM_E_CONFIG;
   2010     int pool = 0;
   2011     *pipe = 0;
   2012     rv = _bcm_esw_get_fp_pipe_pool_from_mode(unit, offset_mode, stage, pipe, &pool);
   2013     return rv;
   2014 }
   2015 
   2016 /*
   2017  * Return 1 if the ingress_table is one of the
   2018  * EXACT match tables
   2019  */
   2020 static int 
   2021 _bcm_esw_is_exact_match(soc_mem_t ingress_table) {
   2022     switch(ingress_table) {
   2023         case EXACT_MATCH_2m:
   2024         case EXACT_MATCH_2_PIPE0m:
   2025         case EXACT_MATCH_2_PIPE1m:
   2026         case EXACT_MATCH_2_PIPE2m:
   2027         case EXACT_MATCH_2_PIPE3m:
   2028         case EXACT_MATCH_4m:
   2029         case EXACT_MATCH_4_PIPE0m:
   2030         case EXACT_MATCH_4_PIPE1m:
   2031         case EXACT_MATCH_4_PIPE2m:
   2032         case EXACT_MATCH_4_PIPE3m:
   2033              return 1;
   2034         default:
   2035              return 0;
   2036     }
   2037     return 0;
   2038 }
   2039 /*
   2040  * Return 1 if the ingress_table is one of the
   2041  * ingress policy tables
   2042  */
   2043 static int
   2044 _bcm_esw_is_ifp_table(soc_mem_t ingress_table) {
   2045     switch(ingress_table) {
   2046         case IFP_POLICY_TABLEm:
   2047         case IFP_POLICY_TABLE_PIPE0m:
   2048         case IFP_POLICY_TABLE_PIPE1m:
   2049         case IFP_POLICY_TABLE_WIDEm:
   2050         case IFP_POLICY_TABLE_WIDE_PIPE0m:
   2051         case IFP_POLICY_TABLE_WIDE_PIPE1m:
   2052              return 1;
   2053         default:
   2054              return 0;
   2055     }
   2056     return 0;
   2057 }
   2058 #endif
   2059 
   2060 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   2061 static int _bcm_esw_stat_table_is_profile(int unit, soc_mem_t table) {
   2062     switch(table) {
   2063         case LPORT_TABm:
   2064         case EGR_LPORT_PROFILEm:
   2065              return 1;
   2066         default:
   2067              return 0;
   2068     }
   2069     return 0;
   2070 }
   2071 #endif
   2072 
   2073 #if defined(BCM_TRIDENT3_SUPPORT)
   2074 STATIC
   2075 bcm_error_t  _bcm_esw_get_flex_counter_view_fields_values(
   2076     int       unit,
   2077     soc_mem_t view,
   2078     void      *data,
   2079     bcm_stat_object_t object,
   2080     uint32    *offset_mode,
   2081     uint32    *pool_number,
   2082     uint32    *base_idx)
   2083 
   2084 {
   2085     bcm_stat_flex_direction_t direction;
   2086     int rv = BCM_E_NONE;
   2087     soc_field_t egr_field[2] = {
   2088           EGR_FLEX_CTR_0_ACTION_SETf,
   2089           EGR_FLEX_CTR_1_ACTION_SETf
   2090     };
   2091     int i = 0;
   2092     uint32 action_set = 0;
   2093 
   2094     if ((rv =_bcm_esw_stat_validate_object(unit, object, &direction))
   2095             != BCM_E_NONE) {
   2096          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   2097                 (BSL_META_U(unit,
   2098                             "Flex view invalid stat object %d")
   2099                         ,object));
   2100          return rv;
   2101 
   2102     }
   2103     if (direction == bcmStatFlexDirectionIngress) {
   2104         /* ingress */
   2105         if (SOC_MEM_FIELD_VALID(unit, view, FLEX_CTR_ACTION_SETf)) {
   2106             action_set = soc_mem_field32_get(unit, view, data,
   2107                          FLEX_CTR_ACTION_SETf);
   2108             *base_idx = soc_format_field32_get(unit, FLEX_CTR_ACTION_SETfmt,
   2109                &action_set, FLEX_CTR_BASE_COUNTER_IDXf);
   2110             *pool_number = soc_format_field32_get(unit, FLEX_CTR_ACTION_SETfmt,
   2111                &action_set, FLEX_CTR_POOL_NUMBERf);
   2112             *offset_mode =  soc_format_field32_get(unit, FLEX_CTR_ACTION_SETfmt,
   2113                &action_set, FLEX_CTR_OFFSET_MODEf);
   2114             rv = BCM_E_NONE;
   2115         } else {
   2116             rv = BCM_E_INTERNAL;
   2117         }
   2118     } else {
   2119         /* Egress */
   2120         for (i = 0; i < 2; i++) {
   2121             if (SOC_MEM_FIELD_VALID(unit, view, egr_field[i])) {
   2122                 action_set = soc_mem_field32_get(unit, view, data,
   2123                              egr_field[i]);
   2124                 *base_idx = soc_format_field32_get(unit,
   2125                    EGR_FLEX_CTR_ACTION_SETfmt,
   2126                    &action_set, FLEX_CTR_BASE_COUNTER_IDXf);
   2127                 *pool_number = soc_format_field32_get(unit,
   2128                    EGR_FLEX_CTR_ACTION_SETfmt,
   2129                    &action_set, FLEX_CTR_POOL_NUMBERf);
   2130                 *offset_mode =  soc_format_field32_get(unit,
   2131                    EGR_FLEX_CTR_ACTION_SETfmt,
   2132                    &action_set, FLEX_CTR_OFFSET_MODEf);
   2133                 rv = BCM_E_NONE;
   2134                 break;
   2135             } else {
   2136                 rv = BCM_E_INTERNAL;
   2137             }
   2138         }
   2139     }
   2140     return rv;
   2141 }
   2142 
   2143 STATIC bcm_error_t
   2144 _bcm_esw_set_flex_counter_view_fields_values(
   2145     int       unit,
   2146     soc_mem_t view,
   2147     void      *data,
   2148     bcm_stat_object_t object,
   2149     uint32    offset_mode,
   2150     uint32    pool_number,
   2151     uint32    base_idx)
   2152 {
   2153     bcm_stat_flex_direction_t direction;
   2154     int rv = BCM_E_NONE;
   2155     soc_field_t egr_field[2] = {
   2156         EGR_FLEX_CTR_0_ACTION_SETf,
   2157         EGR_FLEX_CTR_1_ACTION_SETf
   2158     };
   2159     int i = 0;
   2160     uint32 action_set = 0;
   2161 
   2162     if ((rv =_bcm_esw_stat_validate_object(unit, object, &direction))
   2163            != BCM_E_NONE) {
   2164         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   2165                (BSL_META_U(unit,
   2166                            "Flex view invalid stat object %d")
   2167                        ,object));
   2168         return rv;
   2169 
   2170     }
   2171     if (direction == bcmStatFlexDirectionIngress) {
   2172         /* ingress */
   2173         if (SOC_MEM_FIELD_VALID(unit, view, FLEX_CTR_ACTION_SETf)) {
   2174             soc_format_field32_set(unit, FLEX_CTR_ACTION_SETfmt,
   2175                                  &action_set,
   2176                                  FLEX_CTR_BASE_COUNTER_IDXf,
   2177                                  base_idx);
   2178             soc_format_field32_set(unit, FLEX_CTR_ACTION_SETfmt,
   2179                                  &action_set,
   2180                                  FLEX_CTR_POOL_NUMBERf,
   2181                                  pool_number);
   2182             soc_format_field32_set(unit, FLEX_CTR_ACTION_SETfmt,
   2183                                  &action_set,
   2184                                  FLEX_CTR_OFFSET_MODEf,
   2185                                  offset_mode);
   2186             soc_mem_field32_set(unit, view, data,
   2187                         FLEX_CTR_ACTION_SETf, action_set);
   2188             rv = BCM_E_NONE;
   2189         } else {
   2190             rv = BCM_E_INTERNAL;
   2191         }
   2192     } else {
   2193        /* Egress */
   2194         for (i = 0; i < 2; i++) {
   2195             if (SOC_MEM_FIELD_VALID(unit, view, egr_field[i])) {
   2196                 action_set = 0;
   2197                 soc_format_field32_set(unit, EGR_FLEX_CTR_ACTION_SETfmt,
   2198                                      &action_set,
   2199                                      FLEX_CTR_BASE_COUNTER_IDXf,
   2200                                      base_idx);
   2201                 soc_format_field32_set(unit, EGR_FLEX_CTR_ACTION_SETfmt,
   2202                                      &action_set,
   2203                                      FLEX_CTR_POOL_NUMBERf,
   2204                                      pool_number);
   2205                 soc_format_field32_set(unit, EGR_FLEX_CTR_ACTION_SETfmt,
   2206                                      &action_set,
   2207                                      FLEX_CTR_OFFSET_MODEf,
   2208                                      offset_mode);
   2209                 soc_mem_field32_set(unit, view, data,
   2210                             egr_field[i], action_set);
   2211                 rv = BCM_E_NONE;
   2212                 break;
   2213             } else {
   2214                 rv = BCM_E_INTERNAL;
   2215             }
   2216         }
   2217     }
   2218     return rv;
   2219 }
   2220 #endif
   2221 
   2222 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   2223 #ifdef BCM_WARM_BOOT_SUPPORT
   2224 static int _bcm_esw_is_egr_obj(bcm_stat_object_t object) {
   2225     switch (object) {
   2226         case bcmStatObjectEgrPort:
   2227         case bcmStatObjectEgrVlan:
   2228         case bcmStatObjectEgrVlanXlate:
   2229         case bcmStatObjectEgrVfi:
   2230         case bcmStatObjectEgrL3Intf:
   2231         case bcmStatObjectEgrWlan:
   2232         case bcmStatObjectEgrMim:
   2233         case bcmStatObjectEgrMimLookupId:
   2234         case bcmStatObjectEgrL2Gre:
   2235         case bcmStatObjectEgrVxlan:
   2236         case bcmStatObjectEgrL3Nat:
   2237         case bcmStatObjectEgrNiv:
   2238         case bcmStatObjectEgrFieldStageEgress:
   2239         case bcmStatObjectEgrMplsTunnelLabel:
   2240         case bcmStatObjectEgrVlanXlateSecondLookup:
   2241         case bcmStatObjectEgrMplsTunnelSecondLabel:
   2242             return 1;
   2243         default:
   2244             break;
   2245     }
   2246 
   2247     return 0;
   2248 }
   2249 #endif
   2250 #endif
   2251 
   2252 /*
   2253  * Function:
   2254  *      _bcm_esw_get_flex_counter_fields
   2255  * Description:
   2256  *      Gets flex counter fields(FLEX_CTR_OFFSET_MODEf,FLEX_CTR_POOL_NUMBERf
   2257  *      and FLEX_CTR_BASE_COUNTER_IDXf) name for given table.
   2258  *      This is important when a table has several views for flex counter
   2259  *      field and EntryType or KeyType fieled is checked.
   2260  * Parameters:
   2261  *      unit                - (IN) unit number
   2262  *      index               - (IN) Index of the Table
   2263  *      object              - (IN) Accounting Object
   2264  *      table               - (IN) Accounting Table
   2265  *      data                - (IN) Accounting Table Data FLEX_CTR_OFFSET_MODE
   2266  *      offset_mode_field   - (OUT) Field for FLEX_CTR_OFFSET_MODE
   2267  *      pool_number_field   - (OUT) Field for FLEX_CTR_POOL_NUMBER
   2268  *      base_idx_field      - (OUT) Field for FLEX_CTR_BASE_COUNTER_IDX
   2269  * Return Value:
   2270  *      BCM_E_XXX
   2271  * Notes:
   2272  */
   2273 
   2274 static bcm_error_t
   2275 _bcm_esw_get_flex_counter_fields(
   2276     int         unit,
   2277     uint32     index,
   2278     bcm_stat_object_t object,
   2279     soc_mem_t   table,
   2280     void        *data,
   2281     soc_field_t *offset_mode_field,
   2282     soc_field_t *pool_number_field,
   2283     soc_field_t *base_idx_field)
   2284 {
   2285     uint32 key_type=0;
   2286     uint32 key_type_index=0;
   2287     soc_field_t view_field;
   2288     soc_mem_info_t *memp;
   2289 
   2290     int rv = BCM_E_NONE;
   2291 #if defined (BCM_TRIDENT2PLUS_SUPPORT) && defined (INCLUDE_L3)
   2292     int label_count=0;
   2293     int object_index=0;
   2294 #endif
   2295     *offset_mode_field=FLEX_CTR_OFFSET_MODEf;
   2296     *pool_number_field=FLEX_CTR_POOL_NUMBERf;
   2297     *base_idx_field=FLEX_CTR_BASE_COUNTER_IDXf;
   2298     switch(table) {
   2299     case MPLS_ENTRYm:
   2300     case MPLS_ENTRY_EXTDm:
   2301         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2302                   (BSL_META_U(unit,
   2303                               "MPLS_ENTRYm   ")));
   2304          memp = &SOC_MEM_INFO(unit, table);
   2305          if (soc_mem_field_valid(unit,table,KEY_TYPEf)) {
   2306              view_field = KEY_TYPEf;
   2307          } else if (soc_mem_field_valid(unit,table,KEY_TYPE_0f)) {
   2308              view_field = KEY_TYPE_0f;
   2309          } else if (soc_mem_field_valid(unit,table,KEY_TYPE_1f)) {
   2310              view_field = KEY_TYPE_1f;
   2311          } else if (soc_mem_field_valid(unit,table,ENTRY_TYPEf)) {
   2312              view_field = ENTRY_TYPEf;
   2313          } else {
   2314              return BCM_E_CONFIG;
   2315          }
   2316          key_type=soc_mem_field32_get(unit,table,data,view_field);
   2317          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2318                    (BSL_META_U(unit,
   2319                                "key_type %d "),
   2320                     key_type));
   2321          if (sal_strcmp(memp->views[key_type],"MPLS") == 0) {
   2322              key_type_index = 0;
   2323          } else if (sal_strcmp(memp->views[key_type],"MIM_NVP") == 0) {
   2324              key_type_index = 1;
   2325          } else if (sal_strcmp(memp->views[key_type],"MIM_ISID") == 0) {
   2326              key_type_index = 2;
   2327          } else if (sal_strcmp(memp->views[key_type],"TRILL") == 0) {
   2328              key_type_index = 3;
   2329          } else if (sal_strcmp(memp->views[key_type],"IPV4UC") == 0) {
   2330              key_type_index = 4;
   2331          } else if (sal_strcmp(memp->views[key_type],"IPV6UC") == 0) {
   2332              key_type_index = 5;
   2333          } else {
   2334              LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   2335                        (BSL_META_U(unit,
   2336                                    "KEY TYPE NOT OK %d"),
   2337                         key_type));
   2338              return BCM_E_CONFIG;
   2339          }
   2340          *offset_mode_field= mpls_entry_flex_counter_fields[key_type_index].
   2341                              offset_mode;
   2342          *pool_number_field= mpls_entry_flex_counter_fields[key_type_index].
   2343                              pool_number;
   2344          *base_idx_field=    mpls_entry_flex_counter_fields[key_type_index].
   2345                              base_idx;
   2346          break;
   2347     case L3_TUNNELm:
   2348          if (soc_feature(unit, soc_feature_mpls_frr_lookup)) {
   2349          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2350                   (BSL_META_U(unit,
   2351                               "L3_TUNNELm   ")));
   2352          memp = &SOC_MEM_INFO(unit, table);
   2353          if (soc_mem_field_valid(unit,table,MODEf)) {
   2354              view_field = MODEf;
   2355          } else if (soc_mem_field_valid(unit, table, KEY_TYPEf)) {
   2356              view_field = KEY_TYPEf;
   2357          } else {
   2358              return BCM_E_CONFIG;
   2359          }
   2360          key_type=soc_mem_field32_get(unit,table,data,view_field);
   2361          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2362                    (BSL_META_U(unit,
   2363                                "key_type %d "),
   2364                     key_type));
   2365          if ((sal_strcmp(memp->views[key_type+1],"MPLS") == 0) ||
   2366                  (sal_strcmp(memp->views[key_type],"MPLS") == 0)) {
   2367              key_type_index = 0;
   2368          }  else {
   2369              LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   2370                        (BSL_META_U(unit,
   2371                                    "KEY TYPE NOT OK %d"),
   2372                         key_type));
   2373              return BCM_E_CONFIG;
   2374          }
   2375          *offset_mode_field= mpls_entry_flex_counter_fields[key_type_index].
   2376                              offset_mode;
   2377          *pool_number_field= mpls_entry_flex_counter_fields[key_type_index].
   2378                              pool_number;
   2379          *base_idx_field=    mpls_entry_flex_counter_fields[key_type_index].
   2380                              base_idx;
   2381          }
   2382          break;
   2383     case EGR_L3_NEXT_HOPm:
   2384          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2385                    (BSL_META_U(unit,
   2386                                "EGR_L3_NEXT_HOP   =>")));
   2387          memp = &SOC_MEM_INFO(unit, table);
   2388          if (soc_mem_field_valid(unit,table,ENTRY_TYPEf)) {
   2389              view_field = ENTRY_TYPEf;
   2390          }
   2391 #if defined (BCM_TRIDENT3_SUPPORT)
   2392          else if (soc_mem_field_valid(unit,table,DATA_TYPEf)) {
   2393              view_field = DATA_TYPEf;
   2394          }
   2395 #endif
   2396          else {
   2397              return BCM_E_CONFIG;
   2398          }
   2399          key_type=soc_mem_field32_get(unit,table,data,view_field);
   2400 #if defined(BCM_TRIDENT3_SUPPORT)
   2401          if (key_type == _BCM_VXLAN_EGR_NEXT_HOP_L2OTAG_VIEW) {
   2402              key_type_index = 7;
   2403          } else
   2404 #endif
   2405          if (sal_strcmp(memp->views[key_type],"LEGACY") == 0) {
   2406              key_type_index = 0;
   2407          } else if (sal_strcmp(memp->views[key_type],"L3") == 0) {
   2408              key_type_index = 1;
   2409          } else if (sal_strcmp(memp->views[key_type],"WLAN") == 0) {
   2410              key_type_index = 2;
   2411          } else if (sal_strcmp(memp->views[key_type],"PROXY") == 0) {
   2412              key_type_index = 3;
   2413          } else if (sal_strcmp(memp->views[key_type],"MPLS") == 0) {
   2414              key_type_index = 4;
   2415          } else if (sal_strcmp(memp->views[key_type],"SD_TAG") == 0) {
   2416              key_type_index = 5;
   2417          } else if (sal_strcmp(memp->views[key_type],"MIM") == 0) {
   2418              key_type_index = 6;
   2419          } else if (sal_strcmp(memp->views[key_type],"L3MC") == 0) {
   2420              key_type_index = 8;
   2421          } else {
   2422              return BCM_E_CONFIG;
   2423          }
   2424          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2425                    (BSL_META_U(unit,
   2426                                "key_type %d "),
   2427                     key_type));
   2428          *offset_mode_field=egr_l3_next_hop_flex_counter_fields[key_type_index].
   2429                              offset_mode;
   2430          *pool_number_field=egr_l3_next_hop_flex_counter_fields[key_type_index].
   2431                              pool_number;
   2432          *base_idx_field   =egr_l3_next_hop_flex_counter_fields[key_type_index].
   2433                              base_idx;
   2434          break;
   2435     case EGR_VLAN_XLATEm:
   2436 #if defined (BCM_TRIDENT3_SUPPORT)
   2437     case EGR_VLAN_XLATE_1_DOUBLEm:
   2438 #endif
   2439          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2440                    (BSL_META_U(unit,
   2441                                "EGR_VLAN_XLATEm ==")));
   2442          memp = &SOC_MEM_INFO(unit, table);
   2443          if (soc_mem_field_valid(unit,table,ENTRY_TYPEf)) {
   2444              view_field = ENTRY_TYPEf;
   2445          } else if (soc_mem_field_valid(unit,table,KEY_TYPEf)) {
   2446              view_field = KEY_TYPEf;
   2447          } else {
   2448              return BCM_E_CONFIG;
   2449          }
   2450          key_type=soc_mem_field32_get(unit,table,data,view_field);
   2451          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2452                    (BSL_META_U(unit,
   2453                                "key_type %d "),
   2454                     key_type));
   2455          if (sal_strcmp(memp->views[key_type],"XLATE") == 0) {
   2456              key_type_index = 0;
   2457          } else if (sal_strcmp(memp->views[key_type],"MIM_ISID") == 0) {
   2458              key_type_index = 1;
   2459          } else {
   2460              return BCM_E_CONFIG;
   2461          }
   2462          *offset_mode_field= egr_vlan_xlate_flex_counter_fields[key_type_index].
   2463                              offset_mode;
   2464          *pool_number_field= egr_vlan_xlate_flex_counter_fields[key_type_index].
   2465                              pool_number;
   2466          *base_idx_field   = egr_vlan_xlate_flex_counter_fields[key_type_index].
   2467                              base_idx;
   2468          break;
   2469     case VLAN_XLATEm:
   2470 #if defined (BCM_TRIDENT3_SUPPORT)
   2471     case VLAN_XLATE_1_DOUBLEm:
   2472     case VLAN_XLATE_2_DOUBLEm:
   2473 #endif
   2474          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2475                    (BSL_META_U(unit,
   2476                                "VLAN_XLATEm ==")));
   2477          memp = &SOC_MEM_INFO(unit, table);
   2478          if (soc_mem_field_valid(unit,table,ENTRY_TYPEf)) {
   2479              view_field = ENTRY_TYPEf;
   2480          } else if (soc_mem_field_valid(unit,table,KEY_TYPEf)) {
   2481              view_field = KEY_TYPEf;
   2482          } else {
   2483              return BCM_E_CONFIG;
   2484          }
   2485          key_type=soc_mem_field32_get(unit,table,data,view_field);
   2486 
   2487 #if defined(BCM_TRIUMPH3_SUPPORT)
   2488         if (SOC_IS_TRIUMPH3(unit)) {
   2489              /* In TR3, VLAN_XLATE (vlan_xlate_1) has even entry types,
   2490               *  which supports flex counters
   2491               */
   2492              if (key_type & 0x1) {
   2493                 return BCM_E_CONFIG;
   2494              }
   2495         }
   2496 #endif
   2497 
   2498 #if defined(BCM_TRIDENT3_SUPPORT)
   2499         if (SOC_IS_TRIDENT3X(unit)) {
   2500             /* In TD3X, key_type for flex view in VLAN_XLATE_2_DOUBLE starts
   2501              * after 18. Flex view does not have Flex counters.
   2502              */
   2503             if ((table == VLAN_XLATE_2_DOUBLEm) && (key_type > 18)) {
   2504                 return BCM_E_CONFIG;
   2505             }
   2506         }
   2507 #endif
   2508 
   2509          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2510                    (BSL_META_U(unit,
   2511                                "key_type %d "),
   2512                     key_type));
   2513          if (sal_strcmp(memp->views[key_type],"XLATE") == 0) {
   2514              key_type_index = 0;
   2515          } else if (sal_strcmp(memp->views[key_type],"L2GRE_DIP") == 0) {
   2516              key_type_index = 1;
   2517          } else if (sal_strcmp(memp->views[key_type],"VXLAN_DIP") == 0) {
   2518              key_type_index = 2;
   2519          } else {
   2520              return BCM_E_CONFIG;
   2521          }
   2522          *offset_mode_field= vlan_xlate_flex_counter_fields[key_type_index].
   2523                              offset_mode;
   2524          *pool_number_field= vlan_xlate_flex_counter_fields[key_type_index].
   2525                              pool_number;
   2526          *base_idx_field   = vlan_xlate_flex_counter_fields[key_type_index].
   2527                              base_idx;
   2528          break;
   2529     case VLAN_XLATE_EXTDm:
   2530          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2531                    (BSL_META_U(unit,
   2532                                "VLAN_XLATE_EXTDm   ")));
   2533          memp = &SOC_MEM_INFO(unit, table);
   2534          if (soc_mem_field_valid(unit,table,KEY_TYPE_0f)) {
   2535              view_field = KEY_TYPE_0f;
   2536          } else if (soc_mem_field_valid(unit,table,KEY_TYPE_1f)) {
   2537              view_field = KEY_TYPE_1f;
   2538          } else {
   2539              return BCM_E_CONFIG;
   2540          }
   2541          key_type=soc_mem_field32_get(unit,table,data,view_field);
   2542          /* VLAN_XLATE_EXTD has only odd entry types */
   2543          if (!(key_type & 0x1)) {
   2544             return BCM_E_CONFIG;
   2545          }
   2546          break;
   2547     case EGR_DVP_ATTRIBUTE_1m:
   2548 #if defined (BCM_TRIDENT3_SUPPORT)
   2549      case EGR_DVP_ATTRIBUTEm:
   2550 #endif
   2551          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2552                    (BSL_META_U(unit,
   2553                                "EGR_DVP_ATTRIBUTE_1m   ")));
   2554          memp = &SOC_MEM_INFO(unit, table);
   2555          {
   2556             egr_dvp_attribute_entry_t  egr_dvp_attribute;
   2557             int vp_type;
   2558 
   2559             sal_memset(&egr_dvp_attribute, 0, sizeof(egr_dvp_attribute_entry_t));
   2560             rv = soc_mem_read(unit, EGR_DVP_ATTRIBUTEm, MEM_BLOCK_ANY,
   2561                               index, &egr_dvp_attribute);
   2562 #if defined (BCM_TRIDENT3_SUPPORT)
   2563             if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, DATA_TYPEf)) {
   2564                 vp_type = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm,
   2565                                          &egr_dvp_attribute, DATA_TYPEf);
   2566             } else
   2567 #endif
   2568             {
   2569                 vp_type = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm,
   2570                                          &egr_dvp_attribute, VP_TYPEf);
   2571             }
   2572             key_type_index = 0;
   2573             if (vp_type == 2) { /* vxlan */
   2574                 key_type_index = 1;
   2575             } else if (vp_type == 3) { /* l2gre */
   2576                 key_type_index = 2;
   2577             } else {
   2578              /*entry not programmed */
   2579              return BCM_E_CONFIG;
   2580             }
   2581          }
   2582          if (key_type_index) {
   2583              *offset_mode_field= egr_dvp_attribute_counter_fields[key_type_index].
   2584                                  offset_mode;
   2585              *pool_number_field= egr_dvp_attribute_counter_fields[key_type_index].
   2586                                  pool_number;
   2587              *base_idx_field   = egr_dvp_attribute_counter_fields[key_type_index].
   2588                                  base_idx;
   2589         }
   2590         break;
   2591 #if defined(BCM_KATANA2_SUPPORT)
   2592     case EGR_VLANm:
   2593         if (SOC_IS_KATANA2(unit)) {
   2594             *offset_mode_field=EGR_FLEX_CTR_OFFSET_MODEf;
   2595             *pool_number_field=EGR_FLEX_CTR_POOL_NUMBERf;
   2596             *base_idx_field=EGR_FLEX_CTR_BASE_COUNTER_IDXf;
   2597         }
   2598         break;
   2599 #endif
   2600 #ifdef BCM_TRIDENT2_SUPPORT
   2601 
   2602     case L3_ENTRY_IPV4_MULTICASTm:
   2603 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   2604     case L3_ENTRY_DOUBLEm:
   2605 #endif
   2606 
   2607          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2608                    (BSL_META_U(unit,
   2609                                "L3_ENTRY_IPV4_MULTICAST  ")));
   2610          memp = &SOC_MEM_INFO(unit, table);
   2611          if (soc_mem_field_valid(unit,table,KEY_TYPE_0f)) {
   2612              view_field = KEY_TYPE_0f;
   2613          }
   2614 #if defined (BCM_TRIDENT3_SUPPORT)
   2615          else if (soc_mem_field_valid(unit, table, DATA_TYPEf)) {
   2616              view_field = DATA_TYPEf;
   2617          }
   2618 #endif
   2619 #if defined (BCM_TOMAHAWK3_SUPPORT)
   2620          else if (soc_mem_field_valid(unit, table, KEY_TYPEf)) {
   2621              view_field = KEY_TYPEf;
   2622          }
   2623 #endif
   2624          else {
   2625              return BCM_E_CONFIG;
   2626          }
   2627 
   2628          key_type = soc_mem_field32_get(unit, table, data, view_field);
   2629          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2630                    (BSL_META_U(unit,
   2631                                "key_type %d "),
   2632                     key_type));
   2633 
   2634          if (key_type == TD2_L3_HASH_KEY_TYPE_V4UC_EXT) {
   2635              key_type_index = 0;
   2636          } else if ((key_type == TD2_L3_HASH_KEY_TYPE_V4MC) ||
   2637                     (key_type == TD2_L3_HASH_KEY_TYPE_V4L2MC) ||
   2638                     (key_type == TD2_L3_HASH_KEY_TYPE_V4L2VPMC)){
   2639              key_type_index = 1;
   2640          } else if ((key_type == TD2_L3_HASH_KEY_TYPE_FCOE_DOMAIN_EXT) ||
   2641                     (key_type == TD2_L3_HASH_KEY_TYPE_FCOE_HOST_EXT) ||
   2642                     (key_type == TD2_L3_HASH_KEY_TYPE_FCOE_SRC_MAP_EXT)) {
   2643              key_type_index = 2;
   2644          } else {
   2645              return BCM_E_CONFIG;
   2646          }
   2647          *offset_mode_field =
   2648              l3_entry_ipv4_multicast_counter_fields[key_type_index].offset_mode;
   2649          *pool_number_field =
   2650              l3_entry_ipv4_multicast_counter_fields[key_type_index].pool_number;
   2651          *base_idx_field   =
   2652              l3_entry_ipv4_multicast_counter_fields[key_type_index].base_idx;
   2653          break;
   2654 
   2655     case L3_ENTRY_IPV6_MULTICASTm:
   2656 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   2657     case L3_ENTRY_QUADm:
   2658 #endif
   2659 
   2660          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2661                    (BSL_META_U(unit,
   2662                                "L3_ENTRY_IPV6_MULTICAST  ")));
   2663          memp = &SOC_MEM_INFO(unit, table);
   2664          if (soc_mem_field_valid(unit,table,KEY_TYPE_0f)) {
   2665              view_field = KEY_TYPE_0f;
   2666          }
   2667 #if defined (BCM_TRIDENT3_SUPPORT)
   2668          else if (soc_mem_field_valid(unit, table, DATA_TYPEf)) {
   2669              view_field = DATA_TYPEf;
   2670          }
   2671 #endif
   2672 #if defined (BCM_TOMAHAWK3_SUPPORT)
   2673          else if (soc_mem_field_valid(unit, table, KEY_TYPEf)) {
   2674              view_field = KEY_TYPEf;
   2675          }
   2676 #endif
   2677          else {
   2678              return BCM_E_CONFIG;
   2679          }
   2680 
   2681          key_type = soc_mem_field32_get(unit, table, data, view_field);
   2682          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2683                    (BSL_META_U(unit,
   2684                                "key_type %d "),
   2685                     key_type));
   2686 
   2687          if (key_type == TD2_L3_HASH_KEY_TYPE_V6UC_EXT) {
   2688              key_type_index = 0;
   2689          } else if ((key_type == TD2_L3_HASH_KEY_TYPE_V6MC) || 
   2690                     (key_type == TD2_L3_HASH_KEY_TYPE_V6L2MC) ||
   2691                     (key_type == TD2_L3_HASH_KEY_TYPE_V6L2VPMC)){
   2692              key_type_index = 1;
   2693          } else {
   2694              return BCM_E_CONFIG;
   2695          }
   2696          *offset_mode_field =
   2697              l3_entry_ipv6_multicast_counter_fields[key_type_index].offset_mode;
   2698          *pool_number_field =
   2699              l3_entry_ipv6_multicast_counter_fields[key_type_index].pool_number;
   2700          *base_idx_field   =
   2701              l3_entry_ipv6_multicast_counter_fields[key_type_index].base_idx;
   2702          break;
   2703 
   2704     case EGR_NAT_PACKET_EDIT_INFOm:
   2705          if (index & 1) {
   2706              *offset_mode_field = FLEX_CTR_OFFSET_MODE_1f;
   2707              *pool_number_field = FLEX_CTR_POOL_NUMBER_1f;
   2708              *base_idx_field = FLEX_CTR_BASE_COUNTER_IDX_1f;
   2709          } else {
   2710              *offset_mode_field = FLEX_CTR_OFFSET_MODE_0f;
   2711              *pool_number_field = FLEX_CTR_POOL_NUMBER_0f;
   2712              *base_idx_field = FLEX_CTR_BASE_COUNTER_IDX_0f;
   2713          }
   2714          break;
   2715 
   2716 #if defined (BCM_TOMAHAWK3_SUPPORT)
   2717     case L3_DEFIP_LEVEL1m:
   2718     case L3_DEFIP_PAIR_LEVEL1m:
   2719          *offset_mode_field = FLEX_CTR_OFFSET_MODEf;
   2720          *pool_number_field = FLEX_CTR_POOL_NUMBERf;
   2721          *base_idx_field = FLEX_CTR_BASE_COUNTER_IDXf;
   2722          break;
   2723 #endif
   2724     case L3_DEFIPm:
   2725          if (index & 0x1) {
   2726              *offset_mode_field = FLEX_CTR_OFFSET_MODE1f;
   2727              *pool_number_field = FLEX_CTR_POOL_NUMBER1f;
   2728              *base_idx_field = FLEX_CTR_BASE_COUNTER_IDX1f;
   2729          } else {
   2730              *offset_mode_field = FLEX_CTR_OFFSET_MODE0f;
   2731              *pool_number_field = FLEX_CTR_POOL_NUMBER0f;
   2732              *base_idx_field = FLEX_CTR_BASE_COUNTER_IDX0f;
   2733          }
   2734          break;
   2735 #endif
   2736 #if defined (BCM_TRIDENT2PLUS_SUPPORT) && defined (INCLUDE_L3)
   2737     case EGR_IP_TUNNEL_MPLSm:
   2738          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2739                  (BSL_META_U(unit,
   2740                              "EGR_IP_TUNNEL_MPLS")));
   2741 
   2742          rv = _bcm_tr_mpls_tunnel_chain_label_count_get(unit, index,
   2743                  &label_count);
   2744          if (rv < 0) {
   2745              return rv;
   2746          }
   2747          for (object_index=0;object_index < ((sizeof(egr_mpls_tunnel_object)/
   2748                          sizeof(egr_mpls_tunnel_object[0])));object_index++) {
   2749              if (object == egr_mpls_tunnel_object[object_index]) {
   2750                  break;
   2751              }
   2752          }
   2753          if ((object_index >= 1) &&
   2754                  !(soc_feature(unit, soc_feature_multi_tunnel_label_count))) {
   2755              return BCM_E_PARAM;
   2756          }
   2757          if (object_index < label_count) {
   2758              key_type_index = (index % _BCM_MPLS_NUM_MPLS_ENTRIES_PER_INDEX(unit)) +
   2759                                label_count-(object_index+1);
   2760          }
   2761          *offset_mode_field = 
   2762              ip_tunnel_mpls_entry_counter_fields
   2763              [key_type_index].offset_mode;
   2764          *pool_number_field = 
   2765              ip_tunnel_mpls_entry_counter_fields
   2766              [key_type_index].pool_number;
   2767          *base_idx_field = 
   2768              ip_tunnel_mpls_entry_counter_fields
   2769              [key_type_index].base_idx;
   2770          break;
   2771 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   2772 #if defined (BCM_TRIDENT3_SUPPORT) && defined (INCLUDE_L3)
   2773     case EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm:
   2774         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2775                 (BSL_META_U(unit,
   2776                         "EGR_IP_TUNNEL_MPLS_DOUBLE_WIDE")));
   2777         if (SOC_IS_TRIDENT3X(unit) &&
   2778             soc_feature(unit, soc_feature_td3_style_mpls)) {
   2779 
   2780             return BCM_E_NONE;
   2781         }
   2782         break;
   2783 #endif
   2784 #if defined(INCLUDE_L3)
   2785 #if defined (BCM_TRIDENT3_SUPPORT) || defined (BCM_TOMAHAWK3_SUPPORT)
   2786     case MPLS_ENTRY_SINGLEm:
   2787 #if defined(BCM_TOMAHAWK3_SUPPORT)
   2788         if (SOC_IS_TOMAHAWK3(unit)) {
   2789             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2790                      (BSL_META_U(unit,
   2791                                  "MPLS_ENTRY_SINGLEm   ")));
   2792             memp = &SOC_MEM_INFO(unit, table);
   2793             key_type = soc_mem_field32_get(unit, table, data, KEY_TYPEf);
   2794             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   2795                       (BSL_META_U(unit,
   2796                                   "key_type %d "),
   2797                        key_type));
   2798             if (sal_strcmp(memp->views[key_type],"MPLS") == 0) {
   2799                 key_type_index = 0;
   2800             } else if (sal_strcmp(memp->views[key_type],"IPV4UC") == 0) {
   2801                 key_type_index = 4;
   2802             } else if (sal_strcmp(memp->views[key_type],"IPV6UC") == 0) {
   2803                 key_type_index = 5;
   2804             } else {
   2805                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   2806                           (BSL_META_U(unit,
   2807                                       "KEY TYPE NOT OK %d"),
   2808                            key_type));
   2809                 return BCM_E_CONFIG;
   2810             }
   2811             *offset_mode_field= mpls_entry_flex_counter_fields[key_type_index].
   2812                                 offset_mode;
   2813             *pool_number_field= mpls_entry_flex_counter_fields[key_type_index].
   2814                                 pool_number;
   2815             *base_idx_field=    mpls_entry_flex_counter_fields[key_type_index].
   2816                                 base_idx;
   2817         } else
   2818 #endif /* BCM_TOMAHAWK3_SUPPORT */
   2819         {
   2820             /*flex counter is deleted in the view VXLAN_FLEX_IPV4_DIP*/
   2821             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   2822                           (BSL_META_U(unit,
   2823                                       "flex counter not supported in the table")));
   2824             return BCM_E_UNAVAIL;
   2825         }
   2826         break;
   2827 #endif /* TD3 or TH3 */
   2828 #endif /* INCLUDE_L3 */
   2829     default:
   2830          break;
   2831     }
   2832     /* Just a safety check */
   2833     if ((table != L3_DEFIP_LEVEL1m) && (table != L3_DEFIP_PAIR_LEVEL1m) &&
   2834         ((soc_mem_field_valid(unit,table,*offset_mode_field) == FALSE) ||
   2835         (soc_mem_field_valid(unit,table,*pool_number_field) == FALSE) ||
   2836         (soc_mem_field_valid(unit,table,*base_idx_field) == FALSE))) {
   2837         LOG_WARN(BSL_LS_BCM_FLEXCTR,
   2838                  (BSL_META_U(unit,
   2839                              "INTERNAL Error i.e. "
   2840                               "required offset,pool,base_idx fields are not valid in %s \n"
   2841                               ), SOC_MEM_UFNAME(unit, table)));
   2842         return BCM_E_INTERNAL;
   2843     }
   2844     return rv;
   2845 }
   2846 /*
   2847  * Function:
   2848  *      _bcm_esw_get_flex_counter_fields_values
   2849  * Description:
   2850  *      Gets flex counter fields(FLEX_CTR_OFFSET_MODEf,FLEX_CTR_POOL_NUMBERf
   2851  *      and FLEX_CTR_BASE_COUNTER_IDXf) values for given table.
   2852  *      This is important when a table has several views for flex counter
   2853  *      field and EntryType or KeyType fieled is checked.
   2854  * Parameters:
   2855  *      unit                - (IN) unit number
   2856  *      table               - (IN) Accounting Table
   2857  *      data                - (IN) Accounting Table Data FLEX_CTR_OFFSET_MODE
   2858  *      object              - (IN) Accounting Object
   2859  *      offset_mode         - (OUT) FLEX_CTR_OFFSET_MODE field value
   2860  *      pool_number         - (OUT) FLEX_CTR_POOL_NUMBER field value
   2861  *      base_idx            - (OUT) FLEX_CTR_BASE_COUNTER_IDX field value
   2862  *
   2863  * Return Value:
   2864  *      BCM_E_XXX
   2865  * Notes:
   2866  */
   2867 bcm_error_t
   2868 _bcm_esw_get_flex_counter_fields_values(
   2869     int       unit,
   2870     uint32    index,
   2871     soc_mem_t table,
   2872     void      *data,
   2873     bcm_stat_object_t object,
   2874     uint32    *offset_mode,
   2875     uint32    *pool_number,
   2876     uint32    *base_idx)
   2877 {
   2878     soc_field_t fields[] = {
   2879         FLEX_CTR_OFFSET_MODEf,
   2880         FLEX_CTR_POOL_NUMBERf,
   2881         FLEX_CTR_BASE_COUNTER_IDXf
   2882     };
   2883     /* SET defaults */
   2884     *offset_mode = 0;
   2885     *pool_number =  0;
   2886     *base_idx =  0;
   2887 
   2888 #if defined(BCM_TRIDENT3_SUPPORT)
   2889     if ((soc_feature(unit,soc_feature_flex_flow)) &&
   2890         (soc_flow_db_mem_view_is_valid(unit, table))) {
   2891 
   2892         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
   2893                     (BSL_META_U(unit,
   2894                                 "Flex view stat counters\n")));
   2895         return _bcm_esw_get_flex_counter_view_fields_values(unit,
   2896                            table, data, object,
   2897                            offset_mode, pool_number, base_idx);
   2898     } else
   2899 #endif /* BCM_TRIDENT3_SUPPORT */
   2900     {
   2901 #ifdef ALPM_ENABLE
   2902 #if defined(BCM_TOMAHAWK_SUPPORT)
   2903         if (soc_feature(unit, soc_feature_alpm2) &&
   2904             (table == L3_DEFIP_ALPM_RAWm ||
   2905              table == L3_DEFIP_ALPM_LEVEL2m ||
   2906              table == L3_DEFIP_ALPM_LEVEL3m)) {
   2907             _alpm_bkt_node_t *bkt_node;
   2908             bkt_node = (_alpm_bkt_node_t *)alpm_bkt_node_ptr_arr_get(index);
   2909             if (bkt_node != NULL) {
   2910                 *base_idx = bkt_node->adata.defip_flex_ctr_base_id;
   2911                 *offset_mode = bkt_node->adata.defip_flex_ctr_mode;
   2912                 *pool_number = bkt_node->adata.defip_flex_ctr_pool;
   2913                 return BCM_E_NONE;
   2914             } else {
   2915                 return BCM_E_FAIL;
   2916             }
   2917         }
   2918 #endif
   2919 #endif
   2920         BCM_IF_ERROR_RETURN(_bcm_esw_get_flex_counter_fields(
   2921                         unit, index, object, table, data,
   2922                         &fields[0], &fields[1], &fields[2]));
   2923     }
   2924 #if defined(BCM_TRIDENT3_SUPPORT)
   2925     if (SOC_IS_TRIDENT3X(unit) &&
   2926         ((table == LPORT_TABm) || (table == EGR_LPORT_PROFILEm) ||
   2927             (table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm))) {
   2928         uint32 values[3];
   2929         if (table == LPORT_TABm) {
   2930             BCM_IF_ERROR_RETURN(
   2931                 bcm_esw_port_lport_fields_get(unit, index, LPORT_PROFILE_LPORT_TAB,
   2932                                               3, fields, values));
   2933         } else if (table == EGR_LPORT_PROFILEm) {
   2934             BCM_IF_ERROR_RETURN(
   2935                 bcm_esw_port_egr_lport_fields_get(unit, index,
   2936                 EGR_LPORT_PROFILEm, 3, fields, values));
   2937         }
   2938 #if (defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT))
   2939         else if (table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm) {
   2940             int offset = 0;
   2941             uint32 iptun_mpls_entry_format[3] = {0};
   2942 
   2943             offset = index & _BCM_MPLS_EGR_L3_INTF_MPLS_INDEX_OFFSET_MASK(unit);
   2944 
   2945             BCM_IF_ERROR_RETURN(bcmi_egress_tnl_label_entry_get(unit, data,
   2946                 offset, iptun_mpls_entry_format));
   2947             BCM_IF_ERROR_RETURN(bcmi_egr_ip_tnl_mpls_entry_format_get(unit,
   2948                 data, offset, iptun_mpls_entry_format,
   2949                 bcmiFlexCtrBaseCounterIdx, &values[2]));
   2950             BCM_IF_ERROR_RETURN(bcmi_egr_ip_tnl_mpls_entry_format_get(unit,
   2951                 data, offset, iptun_mpls_entry_format, bcmiFlexCtrPoolNumber,
   2952                 &values[1]));
   2953             BCM_IF_ERROR_RETURN(bcmi_egr_ip_tnl_mpls_entry_format_get(unit,
   2954                 data, offset, iptun_mpls_entry_format, bcmiFlexCtrOffsetMode,
   2955                 &values[0]));
   2956         }
   2957 #endif
   2958         *offset_mode = values[0];
   2959         *pool_number = values[1];
   2960         *base_idx    = values[2];
   2961     } else
   2962 #endif
   2963 #if defined(BCM_TOMAHAWK3_SUPPORT)
   2964     if (SOC_IS_TOMAHAWK3(unit) &&
   2965            ((table == L3_DEFIP_LEVEL1m) ||
   2966            (table == L3_DEFIP_PAIR_LEVEL1m))) {
   2967         uint32 _key_data[2];
   2968         soc_field_t assoc_f = ASSOC_DATA0f;
   2969         if (index & 0x1) {
   2970            assoc_f = ASSOC_DATA1f;
   2971         }
   2972         if (table == L3_DEFIP_PAIR_LEVEL1m) {
   2973            assoc_f = LWR_ASSOC_DATA0f;
   2974         }
   2975         soc_mem_field_get(unit, table, data, assoc_f, _key_data);
   2976         *offset_mode = soc_format_field32_get(
   2977                             unit, ASSOC_DATA_FULLfmt, _key_data, fields[0]);
   2978         *pool_number = soc_format_field32_get(
   2979                             unit, ASSOC_DATA_FULLfmt, _key_data, fields[1]);
   2980         *base_idx    = soc_format_field32_get(
   2981                             unit, ASSOC_DATA_FULLfmt, _key_data, fields[2]);
   2982     } else
   2983 #endif
   2984     {
   2985         *offset_mode =  soc_mem_field32_get(unit, table, data, fields[0]);
   2986         *pool_number =  soc_mem_field32_get(unit, table, data, fields[1]);
   2987         *base_idx =  soc_mem_field32_get(unit, table, data, fields[2]);
   2988     }
   2989     return BCM_E_NONE;
   2990 }
   2991 /*
   2992  * Function:
   2993  *      _bcm_esw_set_flex_counter_fields_values
   2994  * Description:
   2995  *      Sets flex counter fields(FLEX_CTR_OFFSET_MODEf,FLEX_CTR_POOL_NUMBERf
   2996  *      and FLEX_CTR_BASE_COUNTER_IDXf) values for given table.
   2997  *      This is important when a table has several views for flex counter
   2998  *      field and EntryType or KeyType fieled is checked.
   2999  * Parameters:
   3000  *      unit                - (IN) unit number
   3001  *      table               - (IN) Accounting Table
   3002  *      data                - (IN) Accounting Table Data FLEX_CTR_OFFSET_MODE
   3003  *      offset_mode         - (IN) FLEX_CTR_OFFSET_MODE field value
   3004  *      pool_number         - (IN) FLEX_CTR_POOL_NUMBER field value
   3005  *      base_idx            - (IN) FLEX_CTR_BASE_COUNTER_IDX field value
   3006  *
   3007  * Parameters:
   3008  *      unit                  - (IN) unit number
   3009  * Return Value:
   3010  *      BCM_E_XXX
   3011  * Notes:
   3012  */
   3013 bcm_error_t
   3014 _bcm_esw_set_flex_counter_fields_values(
   3015     int       unit,
   3016     uint32    index,
   3017     soc_mem_t table,
   3018     void      *data,
   3019     bcm_stat_object_t object,
   3020     uint32    offset_mode,
   3021     uint32    pool_number,
   3022     uint32    base_idx)
   3023 {
   3024     soc_field_t fields[] = {
   3025         FLEX_CTR_OFFSET_MODEf,
   3026         FLEX_CTR_POOL_NUMBERf,
   3027         FLEX_CTR_BASE_COUNTER_IDXf
   3028     };
   3029 #if defined(BCM_TRIDENT3_SUPPORT)
   3030     if ((soc_feature(unit,soc_feature_flex_flow)) &&
   3031        (soc_flow_db_mem_view_is_valid(unit, table))) {
   3032         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
   3033                    (BSL_META_U(unit,
   3034                                "Flex view stat counters\n")));
   3035         return _bcm_esw_set_flex_counter_view_fields_values(unit,
   3036                            table, data, object,
   3037                            offset_mode, pool_number, base_idx);
   3038     } else
   3039 #endif
   3040     {
   3041 #ifdef ALPM_ENABLE
   3042 #if defined(BCM_TOMAHAWK_SUPPORT)
   3043         if (soc_feature(unit, soc_feature_alpm2) &&
   3044             (table == L3_DEFIP_ALPM_RAWm ||
   3045              table == L3_DEFIP_ALPM_LEVEL2m ||
   3046              table == L3_DEFIP_ALPM_LEVEL3m)) {
   3047             _alpm_bkt_node_t *bkt_node;
   3048             bkt_node = (_alpm_bkt_node_t *)alpm_bkt_node_ptr_arr_get(index);
   3049             if (bkt_node != NULL) {
   3050                 bkt_node->adata.defip_flex_ctr_base_id = base_idx;
   3051                 bkt_node->adata.defip_flex_ctr_mode = offset_mode;
   3052                 bkt_node->adata.defip_flex_ctr_pool = pool_number;
   3053                 return BCM_E_NONE;
   3054             } else {
   3055                 return BCM_E_FAIL;
   3056             }
   3057         }
   3058 #endif
   3059 #endif
   3060         BCM_IF_ERROR_RETURN(_bcm_esw_get_flex_counter_fields(
   3061                         unit, index, object, table, data,
   3062                         &fields[0], &fields[1], &fields[2]));
   3063     }
   3064 #if defined(BCM_TRIDENT3_SUPPORT)
   3065     if (SOC_IS_TRIDENT3X(unit) &&
   3066         ((table == LPORT_TABm) || (table == EGR_LPORT_PROFILEm) ||
   3067         (table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm))) {
   3068         uint32 values[3];
   3069         values[0] = offset_mode;
   3070         values[1] = pool_number;
   3071         values[2] = base_idx;
   3072 
   3073         if (table == LPORT_TABm) {
   3074             BCM_IF_ERROR_RETURN(
   3075                 bcm_esw_port_lport_fields_set(unit, index, LPORT_PROFILE_LPORT_TAB,
   3076                                               3, fields, values));
   3077         } else if (table == EGR_LPORT_PROFILEm) {
   3078             BCM_IF_ERROR_RETURN(
   3079                 bcm_esw_port_egr_lport_fields_set(unit, index,
   3080                 EGR_LPORT_PROFILEm, 3, fields, values));
   3081         }
   3082 #if (defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT))
   3083         else if (table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm) {
   3084             int offset = 0;
   3085             uint32 iptun_mpls_entry_format[3] = {0};
   3086 
   3087             offset = index & _BCM_MPLS_EGR_L3_INTF_MPLS_INDEX_OFFSET_MASK(unit);
   3088 
   3089             BCM_IF_ERROR_RETURN(bcmi_egress_tnl_label_entry_get(unit, data,
   3090                 offset, iptun_mpls_entry_format));
   3091             BCM_IF_ERROR_RETURN(bcmi_egr_ip_tnl_mpls_entry_format_set(unit,
   3092                 bcmiFlexCtrBaseCounterIdx, data, offset,
   3093                 iptun_mpls_entry_format, values[2]));
   3094             BCM_IF_ERROR_RETURN(bcmi_egr_ip_tnl_mpls_entry_format_set(unit,
   3095                 bcmiFlexCtrPoolNumber, data, offset, iptun_mpls_entry_format,
   3096                 values[1]));
   3097             BCM_IF_ERROR_RETURN(bcmi_egr_ip_tnl_mpls_entry_format_set(unit,
   3098                 bcmiFlexCtrOffsetMode, data, offset, iptun_mpls_entry_format,
   3099                 values[0]));
   3100 
   3101             BCM_IF_ERROR_RETURN(bcmi_egress_tnl_label_entry_set(unit, data,
   3102                     offset, iptun_mpls_entry_format));
   3103         }
   3104 #endif
   3105     } else
   3106 #endif
   3107 #if defined(BCM_TOMAHAWK3_SUPPORT)
   3108     if ((table == L3_DEFIP_LEVEL1m) ||
   3109            (table == L3_DEFIP_PAIR_LEVEL1m)) {
   3110         uint32 _key_data[2] = {0, 0};
   3111         soc_field_t assoc_f = ASSOC_DATA0f;
   3112         if (index & 0x1) {
   3113            assoc_f = ASSOC_DATA1f;
   3114         }
   3115         if (table == L3_DEFIP_PAIR_LEVEL1m) {
   3116            assoc_f = LWR_ASSOC_DATA0f;
   3117         }
   3118         soc_mem_field_get(unit, table, data, assoc_f, _key_data);
   3119         soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, _key_data, fields[0], offset_mode);
   3120         soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, _key_data, fields[1], pool_number);
   3121         soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, _key_data, fields[2], base_idx);
   3122         soc_mem_field_set(unit, table, data, assoc_f, _key_data);
   3123     } else
   3124 #endif
   3125     {
   3126         soc_mem_field32_set(unit, table, data, fields[0], offset_mode);
   3127         soc_mem_field32_set(unit, table, data, fields[1], pool_number);
   3128         soc_mem_field32_set(unit, table, data, fields[2], base_idx);
   3129     }
   3130     return BCM_E_NONE;
   3131 }
   3132 /*
   3133  * Function:
   3134  *      _bcm_esw_stat_flex_insert_stat_id
   3135  * Description:
   3136  *      Inserts stat id in local scache table. Useful for WARM-BOOT purpose
   3137  * Parameters:
   3138  *      scache_ptr            - (IN) Local scache table pointer
   3139  *      stat_counter_id       - (IN) Flex Stat Counter Id
   3140  * Return Value:
   3141  *      BCM_E_XXX
   3142  * Notes:
   3143  */
   3144 static bcm_error_t
   3145 _bcm_esw_stat_flex_insert_stat_id(int unit, uint32 *scache_ptr,uint32 stat_counter_id)
   3146 {
   3147     uint32 index=0;
   3148     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   3149               (BSL_META("Inserting %d "),
   3150                stat_counter_id));
   3151     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   3152         return BCM_E_NONE;
   3153     }
   3154 
   3155     for (index=0;index<BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE;index++) {
   3156          if (scache_ptr[index] == 0) {
   3157              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   3158                        (BSL_META("Inserted \n")));
   3159              scache_ptr[index] = stat_counter_id;
   3160              break;
   3161          }
   3162     }
   3163     if (index == BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE) {
   3164         return BCM_E_FAIL;
   3165     }
   3166     return BCM_E_NONE;
   3167 }
   3168 /*
   3169  * Function:
   3170  *      _bcm_esw_stat_flex_delete_stat_id
   3171  * Description:
   3172  *      Deletes stat id from local scache table. Useful for WARM-BOOT purpose
   3173  * Parameters:
   3174  *      scache_ptr            - (IN) Local scache table pointer
   3175  *      stat_counter_id       - (IN) Flex Stat Counter Id
   3176  * Return Value:
   3177  *      BCM_E_XXX
   3178  * Notes:
   3179  */
   3180 static bcm_error_t
   3181 _bcm_esw_stat_flex_delete_stat_id(int unit,uint32 *scache_ptr,uint32 stat_counter_id)
   3182 {
   3183     uint32 index=0;
   3184     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   3185               (BSL_META("Deleting ID:%d "),
   3186                stat_counter_id));
   3187 
   3188     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   3189         return BCM_E_NONE;
   3190     }
   3191     for (index=0;index<BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE;index++) {
   3192          if (scache_ptr[index] == stat_counter_id) {
   3193              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   3194                        (BSL_META("Deleted \n")));
   3195              scache_ptr[index] = 0;
   3196              break;
   3197          }
   3198     }
   3199     if (index == BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE) {
   3200         return BCM_E_FAIL;
   3201     }
   3202     return BCM_E_NONE;
   3203 }
   3204 
   3205 /*
   3206  * Function:
   3207  *      _bcm_esw_stat_flex_ingress_group_oam_status
   3208  * Description:
   3209  *      Get the current OAM capability of ingress flex counter pool group.
   3210  * Parameters:
   3211  *      unit                  - (IN) unit number
   3212  *      group                 - (IN) pool group index
   3213  *      enable                - (OUT) status of oam group
   3214  * Return Value:
   3215  *      BCM_E_XXX
   3216  * Notes:
   3217  */
   3218 static bcm_error_t _bcm_esw_stat_flex_ingress_group_oam_status(
   3219             int                       unit,
   3220             uint32                    group,
   3221             uint32                    *enable)
   3222 {
   3223     uint32  flex_ctr_group_lm_config_value=0;
   3224     uint32  enable_value;
   3225 
   3226     if (group >=
   3227              soc_reg_field_length(unit, ING_FLEX_CTR_LM_CONFIGr, LM_ENABLEf)) {
   3228         return BCM_E_PARAM;
   3229     }
   3230 
   3231     if ( enable == NULL) {
   3232         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   3233                   (BSL_META_U(unit,
   3234                               "...Enabling Flex Counter Group:%d for OAM \n"),
   3235                               group));
   3236         return BCM_E_PARAM;
   3237     }
   3238        /* First Get complete value of
   3239        ING_FLEX_CTR_LM_CONFIGr value */
   3240     SOC_IF_ERROR_RETURN(soc_reg32_get(
   3241                         unit,
   3242                         ING_FLEX_CTR_LM_CONFIGr,
   3243                         REG_PORT_ANY, 0,
   3244                         &flex_ctr_group_lm_config_value));
   3245      enable_value = soc_reg_field_get(unit,
   3246                                       ING_FLEX_CTR_LM_CONFIGr,
   3247                                       flex_ctr_group_lm_config_value,
   3248                                       LM_ENABLEf);
   3249      *enable = enable_value & (1 << group);
   3250     return BCM_E_NONE;
   3251 }
   3252 
   3253 #ifdef BCM_WARM_BOOT_SUPPORT
   3254 /*
   3255  * Function:
   3256  *      _bcm_esw_stat_group_mode_attr_recover
   3257  * Description:
   3258  *      Recover stat group mode attr bitmap from H/W.
   3259  * Parameters:
   3260  *      unit                - (IN) unit number
   3261  *      mode              - (IN) Stat flex counter mode
   3262  *      ingress            -(IN) ingress-1, egress-0;
   3263  *      num_selectors  -(IN) number of selectors;
   3264  *      attr_level2       - (IN) attr selector from Level2 WB
   3265  *      attr                 - (OUT) attr selector from Level2 and Level 1 WB
   3266  * Return Value:
   3267  *      BCM_E_XXX
   3268  * Notes:
   3269  */
   3270 static
   3271 bcm_error_t _bcm_esw_stat_group_mode_attr_recover(
   3272              int unit,
   3273              uint32 mode,
   3274              int ingress,
   3275              uint32 num_selectors,
   3276              bcm_stat_group_mode_attr_selector_wb_t* attr_level2,
   3277              bcm_stat_group_mode_attr_selector_t* attr)
   3278 {
   3279     uint64 attr_sel_value;
   3280     int i;
   3281     uint32 bitmap = 0;
   3282     /*currently only ingress support udf*/
   3283     soc_reg_t _ingress_pkt_selector_key_reg[] = {
   3284                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_0r,
   3285                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_1r,
   3286                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_2r,
   3287                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_3r,
   3288                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_4r,
   3289                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_5r,
   3290                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_6r,
   3291                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_7r,
   3292 #if defined(BCM_TOMAHAWK_SUPPORT) || defined (BCM_APACHE_SUPPORT)
   3293                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_8r,
   3294                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_9r,
   3295                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_10r,
   3296                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_11r,
   3297                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_12r,
   3298                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_13r,
   3299                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_14r,
   3300                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_15r,
   3301                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_16r,
   3302                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_17r,
   3303                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_18r,
   3304                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_19r,
   3305                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_20r,
   3306                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_21r,
   3307                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_22r,
   3308                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_23r,
   3309                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_24r,
   3310                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_25r,
   3311                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_26r,
   3312                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_27r,
   3313                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_28r,
   3314                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_29r,
   3315                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_30r,
   3316                      ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_31r
   3317 #endif
   3318                      };
   3319 
   3320     if (ingress && SOC_REG_FIELD_VALID(unit,
   3321                    _ingress_pkt_selector_key_reg[mode], USE_UDF_KEYf)) {
   3322         BCM_IF_ERROR_RETURN(soc_reg_get(unit,
   3323             _ingress_pkt_selector_key_reg[mode],REG_PORT_ANY, 0, &attr_sel_value));
   3324         if (soc_reg64_field32_get(unit, _ingress_pkt_selector_key_reg[mode],
   3325                 attr_sel_value, USE_UDF_KEYf)) {
   3326             for (i = 0; i < 8; i++) {
   3327                 if (soc_reg64_field32_get(unit, _ingress_pkt_selector_key_reg[mode],
   3328                         attr_sel_value, _pkt_selector_x_en_field_name[i])) {
   3329                     bitmap |= (1 << (soc_reg64_field32_get(
   3330                                       unit,
   3331                                       _ingress_pkt_selector_key_reg[mode],
   3332                                       attr_sel_value,
   3333                                       _pkt_selector_for_bit_x_field_name[i])-1));
   3334                 }
   3335             }
   3336         }
   3337     }
   3338 
   3339     for (i=0; i < num_selectors; i++) {
   3340         attr[i].counter_offset = attr_level2[i].counter_offset;
   3341         attr[i].attr = attr_level2[i].attr;
   3342         attr[i].attr_value = attr_level2[i].attr_value;
   3343         if (attr[i].attr == bcmStatGroupModeAttrUdf) {
   3344             attr[i].udf_bitmap = bitmap;
   3345         } else {
   3346             attr[i].udf_bitmap = 0;
   3347         }
   3348      }
   3349     return BCM_E_NONE;
   3350 }
   3351 /*
   3352  * Function:
   3353  *      _bcm_esw_stat_flex_install_stat_id
   3354  * Description:
   3355  *      Install(ie. configures h/w) as per retrieved stat-id.
   3356  *      Useful for WARM-BOOT purpose
   3357  * Parameters:
   3358  *      unit                  - (IN) unit number
   3359  *      scache_ptr            - (IN) Local scache table pointer
   3360  * Return Value:
   3361  *      BCM_E_XXX
   3362  * Notes:
   3363  */
   3364 static
   3365 bcm_error_t _bcm_esw_stat_flex_install_stat_id(int unit,
   3366                 uint32  *scache_ptr, uint32 *per_pipe_mode_ifp,
   3367                 uint32 *per_pipe_mode_vfp, uint32 *per_pipe_mode_efp)
   3368 {
   3369     uint32                    index=0;
   3370     uint32                    stat_counter_id=0;
   3371     uint32                    pool_number=0;
   3372     uint32                    base_index=0;
   3373     bcm_stat_flex_mode_t      offset_mode=0;
   3374     bcm_stat_object_t         object=bcmStatObjectIngPort;
   3375     bcm_stat_group_mode_t     group_mode= bcmStatGroupModeSingle;
   3376     bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress;
   3377     uint32                    total_counters=0;
   3378     uint32 enable = 0, allocate_group_type = 0, pool_group_id = 0;
   3379     bcm_stat_flex_group_mode_related_info_t *flex_group_mode_related_info =
   3380                                  (bcm_stat_flex_group_mode_related_info_t *)
   3381                                  ( scache_ptr +
   3382                                    BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE);
   3383     bcm_stat_flex_group_mode_related_info_old_t *flex_group_mode_related_info_old =
   3384                                  (bcm_stat_flex_group_mode_related_info_old_t *)
   3385                                  ( scache_ptr +
   3386                                    BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE);
   3387     uint32 mode=0;
   3388     uint32 flex_group_mode = 0;
   3389     bcm_stat_group_mode_attr_selector_t *attr_selectors_tmp = NULL;
   3390     uint8 *stat_flex_ptr = NULL;
   3391 #if defined(BCM_TOMAHAWK_SUPPORT)
   3392     uint32 stat_ctr_id;
   3393     bcm_stat_flex_custom_mode_related_info_t *flex_custom_mode_related_info =
   3394                                  NULL;
   3395     bcm_stat_flex_counter_id_related_info_t *flex_stat_ctr_related_info =
   3396                                  NULL;
   3397     bcm_stat_flex_custom_ingress_mode_t flex_custom_ingress_mode;
   3398 #endif
   3399     int pipe_num = 0;
   3400     bcm_error_t rv = BCM_E_NONE;
   3401     *per_pipe_mode_ifp = 0;
   3402     *per_pipe_mode_vfp = 0;
   3403 
   3404     if (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_3)) {
   3405         bcm_stat_flex_attr_t *attr = NULL;
   3406         uint32 ncounters = 0;
   3407         attr_selectors_tmp = sal_alloc(
   3408             sizeof(bcm_stat_group_mode_attr_selector_t) * BCM_STAT_FLEX_MAX_SELECTORS,
   3409             "group mode attr warmboot tmp memory");
   3410         if (NULL == attr_selectors_tmp) {
   3411             return BCM_E_MEMORY;
   3412         }
   3413         attr = sal_alloc(
   3414             sizeof(bcm_stat_flex_attr_t), "attr tmp memory");
   3415         if (NULL == attr) {
   3416             sal_free(attr_selectors_tmp);
   3417             return BCM_E_MEMORY;
   3418         }
   3419         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
   3420                     (BSL_META_U(unit,
   3421                                 "NEW Version\n")));
   3422         for (mode=0; mode < BCM_STAT_FLEX_COUNTER_MAX_MODE ; mode++) {
   3423             rv = _bcm_esw_stat_group_mode_attr_recover(unit, mode, 1,
   3424                             flex_group_mode_related_info->num_selectors,
   3425                             flex_group_mode_related_info->attr_selectors,
   3426                             attr_selectors_tmp);
   3427             if (BCM_FAILURE(rv)) {
   3428                 sal_free(attr_selectors_tmp);
   3429                 sal_free(attr);
   3430                 return rv;
   3431             }
   3432             if (flex_group_mode_related_info->flags != 0) {
   3433                 (void)_bcm_esw_stat_flex_update_ingress_flex_info(unit, mode,
   3434                     flex_group_mode_related_info->flags & 0xffff,
   3435                     flex_group_mode_related_info->num_selectors,
   3436                     attr_selectors_tmp);
   3437                 flex_group_mode = bcmStatGroupModeFlex1 + mode;
   3438                 flex_ingress_modes[unit][mode].total_counters =
   3439                                    flex_group_mode_related_info->total_counters;
   3440                 if (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_6)) {
   3441                     flex_group_mode = (flex_group_mode_related_info->flags >> 16);
   3442                     if (flex_group_mode < bcmStatGroupModeFlex1) {
   3443                 
   3444                         rv = _bcm_esw_stat_attr_fill(unit, flex_group_mode,
   3445                                                 bcmStatFlexDirectionIngress, 
   3446                                                 attr, &ncounters);
   3447                         if (!BCM_FAILURE(rv)) {
   3448                              flex_ingress_modes[unit][mode].ing_attr = attr->ing_attr;
   3449                         }
   3450                     }
   3451                 }
   3452                 _bcm_esw_stat_flex_set_group_mode(
   3453                                  unit,bcmStatFlexDirectionIngress,
   3454                                  mode, flex_group_mode);
   3455             }
   3456 
   3457             if (_bcm_esw_stat_sync_version_below_equal(unit,BCM_WB_VERSION_1_6)) {
   3458                 /* Number of attribute selectors is increased from 256 to 512.
   3459                  * So, to handle wb recovery in upgrade calculate the old
   3460                  * scache offset based on 256 attribute selectors */
   3461                 flex_group_mode_related_info_old++;
   3462                 flex_group_mode_related_info =
   3463                     (bcm_stat_flex_group_mode_related_info_t *)
   3464                     flex_group_mode_related_info_old;
   3465             } else {
   3466                 flex_group_mode_related_info++;
   3467             }
   3468        }
   3469        for (mode=0; mode < BCM_STAT_FLEX_COUNTER_MAX_MODE ; mode++) {
   3470              rv = _bcm_esw_stat_group_mode_attr_recover(unit, mode, 0,
   3471                      flex_group_mode_related_info->num_selectors,
   3472                      flex_group_mode_related_info->attr_selectors,
   3473                      attr_selectors_tmp);
   3474             if (BCM_FAILURE(rv)) {
   3475                 sal_free(attr_selectors_tmp);
   3476                 sal_free(attr);
   3477                 return rv;
   3478             }
   3479             if (flex_group_mode_related_info->flags != 0) {
   3480                 _bcm_esw_stat_flex_update_egress_flex_info(unit, mode,
   3481                     flex_group_mode_related_info->flags & 0xffff,
   3482                     flex_group_mode_related_info->num_selectors,
   3483                     attr_selectors_tmp);
   3484                 flex_group_mode = bcmStatGroupModeFlex1 + mode;
   3485                 flex_egress_modes[unit][mode].total_counters =
   3486                                    flex_group_mode_related_info->total_counters;
   3487                 if (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_6)) {
   3488                     flex_group_mode = (flex_group_mode_related_info->flags >> 16);
   3489                     if (flex_group_mode < bcmStatGroupModeFlex1) {
   3490                         attr->egr_attr = flex_egress_modes[unit][mode].egr_attr;
   3491                         rv = _bcm_esw_stat_attr_fill(unit, flex_group_mode,
   3492                                                 bcmStatFlexDirectionEgress, 
   3493                                                 attr, &ncounters);
   3494                         if (!BCM_FAILURE(rv)) {
   3495                             flex_egress_modes[unit][mode].egr_attr = attr->egr_attr;
   3496                         }
   3497                     }
   3498                 }
   3499                 _bcm_esw_stat_flex_set_group_mode(
   3500                                  unit,bcmStatFlexDirectionEgress,
   3501                                  mode, flex_group_mode);
   3502             }
   3503             if (_bcm_esw_stat_sync_version_below_equal(unit,BCM_WB_VERSION_1_6)) {
   3504                 flex_group_mode_related_info_old++;
   3505                 flex_group_mode_related_info =
   3506                     (bcm_stat_flex_group_mode_related_info_t *)
   3507                     flex_group_mode_related_info_old;
   3508             } else {
   3509                 flex_group_mode_related_info++;
   3510             }
   3511        }
   3512        sal_free(attr_selectors_tmp);
   3513        sal_free(attr);
   3514        if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) && 
   3515            (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_4))) {
   3516 #if defined(BCM_TOMAHAWK_SUPPORT)
   3517            if (_bcm_esw_stat_sync_version_below_equal(unit,BCM_WB_VERSION_1_6)) {
   3518                flex_custom_mode_related_info = (void *)flex_group_mode_related_info_old;
   3519            } else {
   3520                flex_custom_mode_related_info = (void *)flex_group_mode_related_info;
   3521            }
   3522            for (mode=BCM_CUSTOM_INGRESS_MODE_START; 
   3523                 mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE; mode++) {
   3524              if (flex_custom_mode_related_info->custom_mode != 0) {
   3525                  flex_custom_ingress_mode.offset_mode = flex_custom_mode_related_info->offset_mode;
   3526                  flex_custom_ingress_mode.AllocPool = flex_custom_mode_related_info->AllocPool;
   3527                  flex_custom_ingress_mode.used = 1;
   3528                  flex_custom_ingress_mode.hint.value = 0;
   3529                  flex_custom_ingress_mode.hint.type = 0;
   3530  
   3531                  if (flex_custom_mode_related_info->fg_id != 0xffffffff) {
   3532                      flex_custom_ingress_mode.hint.type = bcmStatGroupAllocHintIngressFieldGroup;
   3533                      flex_custom_ingress_mode.hint.value = flex_custom_mode_related_info->fg_id;
   3534                  }
   3535                  flex_custom_ingress_mode.num_selectors = 0;
   3536                  flex_custom_ingress_mode.attr_selectors = NULL;
   3537                  flex_custom_ingress_mode.total_counters = 0;
   3538 
   3539                  _bcm_esw_stat_flex_update_custom_ingress_mode_info(unit, flex_custom_mode_related_info->custom_mode, &flex_custom_ingress_mode);
   3540              }
   3541              flex_custom_mode_related_info++;
   3542            }
   3543            flex_stat_ctr_related_info = (void *)flex_custom_mode_related_info;
   3544            for (stat_ctr_id=1; 
   3545               (stat_ctr_id < BCM_MAX_STAT_COUNTER_IDS) ; stat_ctr_id++, flex_stat_ctr_related_info++) {
   3546                  if (flex_stat_ctr_related_info->used) {
   3547 
   3548                      _bcm_fill_stat_counter_map(unit, stat_ctr_id, flex_stat_ctr_related_info->mode, 
   3549                                        flex_stat_ctr_related_info->pool, 
   3550                                        flex_stat_ctr_related_info->base_idx, 
   3551                                        flex_stat_ctr_related_info->object, 
   3552                                        flex_stat_ctr_related_info->group); 
   3553                      stat_counter_map[unit][stat_ctr_id].pipe = 0;
   3554                      if (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_5)) {
   3555                          if ((flex_stat_ctr_related_info->mode >= BCM_CUSTOM_INGRESS_MODE_START)) {
   3556                              int mode_idx = flex_stat_ctr_related_info->mode - BCM_CUSTOM_INGRESS_MODE_START;
   3557                              /* Top 2 bits encode pipe and remaining 6 bits for total counters */
   3558 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   3559                              if (_bcm_esw_is_egr_obj(flex_stat_ctr_related_info->object)) {
   3560                                 mode_idx = flex_stat_ctr_related_info->mode - BCM_CUSTOM_EGRESS_MODE_START;
   3561                                 flex_custom_egress_modes[unit][mode_idx].total_counters = flex_stat_ctr_related_info->used & 0x3f;
   3562                              } else
   3563 #endif
   3564                              {
   3565                              flex_custom_ingress_modes[unit][mode_idx].total_counters = flex_stat_ctr_related_info->used & 0x3f;
   3566                              }
   3567                              stat_counter_map[unit][stat_ctr_id].pipe = (flex_stat_ctr_related_info->used >> 6);
   3568                          }
   3569                      } else if (flex_stat_ctr_related_info->mode >= BCM_CUSTOM_INGRESS_MODE_START) {
   3570                              int mode_idx = flex_stat_ctr_related_info->mode - BCM_CUSTOM_INGRESS_MODE_START;
   3571                              mode = flex_custom_ingress_modes[unit][mode_idx].offset_mode;
   3572                              flex_custom_ingress_modes[unit][mode_idx].total_counters = flex_ingress_modes[unit][mode].total_counters;
   3573                              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   3574                                      (BSL_META_U(unit, "PREVIOUS SCACHE\n")));
   3575 
   3576                      }
   3577 
   3578                      if (_bcm_esw_stat_validate_object(unit,
   3579                          flex_stat_ctr_related_info->object,
   3580                          &direction) != BCM_E_NONE) {
   3581                          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   3582                                    (BSL_META_U(unit,
   3583                                                "Invalid object %d so skipping it \n"),
   3584                                     object));
   3585                          continue;
   3586                      }
   3587 
   3588                      pool_number = flex_stat_ctr_related_info->pool;
   3589                      base_index = flex_stat_ctr_related_info->base_idx;
   3590 
   3591                      if (flex_stat_ctr_related_info->mode >= BCM_CUSTOM_INGRESS_MODE_START) {
   3592                         int mode_idx = flex_stat_ctr_related_info->mode - BCM_CUSTOM_INGRESS_MODE_START;
   3593                         if (direction == bcmStatFlexDirectionIngress) {
   3594                         total_counters = flex_custom_ingress_modes[unit][mode_idx].total_counters;
   3595                         }
   3596                      } else {
   3597                          int mode_idx = flex_stat_ctr_related_info->mode;
   3598                          if (direction == bcmStatFlexDirectionIngress) {
   3599                             /* INGRESS SIDE */
   3600                             total_counters = flex_ingress_modes[unit][mode_idx].total_counters;
   3601                          } else {
   3602                             /* EGRESS SIDE */
   3603                             total_counters = flex_egress_modes[unit][mode_idx].total_counters;
   3604                          }
   3605                      }
   3606                      if (total_counters) {
   3607                          shr_aidxres_list_reserve_block(
   3608                                  flex_aidxres_list_handle[unit][direction][pipe_num]
   3609                                                          [pool_number],
   3610                                  flex_stat_ctr_related_info->base_idx,
   3611                                  total_counters);
   3612                      }
   3613                  }
   3614            }
   3615            *per_pipe_mode_ifp = *(uint32 *)flex_stat_ctr_related_info;
   3616            *per_pipe_mode_vfp = *((uint32 *)flex_stat_ctr_related_info + 1);
   3617 #endif
   3618        }
   3619     } else {
   3620         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
   3621                     (BSL_META_U(unit,
   3622                                 "OLD Version so skipping NEW FLEX Layout..\n")));
   3623     }
   3624 
   3625     if (!soc_feature(unit, soc_feature_flex_counter_opaque_stat_id)) {
   3626        for (index=0;index<BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE;index++) {
   3627             if (scache_ptr[index] != 0) {
   3628                 stat_counter_id = scache_ptr[index];
   3629                 _bcm_esw_stat_get_counter_id_info(
   3630                          unit, stat_counter_id,&group_mode,&object,
   3631                          &offset_mode,&pool_number,&base_index);
   3632                 if (_bcm_esw_stat_validate_object(unit,object,&direction) !=
   3633                     BCM_E_NONE) {
   3634                     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   3635                               (BSL_META_U(unit,
   3636                                           "Invalid object %d so skipping it \n"),
   3637                                object));
   3638                     continue;
   3639                 }
   3640                 if (direction == bcmStatFlexDirectionIngress) {
   3641                      /* Quite possible..no attachment till now */
   3642                      if (flex_ingress_modes[unit][offset_mode].total_counters
   3643                          == 0) {
   3644                           flex_ingress_modes[unit][offset_mode].total_counters =
   3645                                _flex_group_mode_total_counters_info
   3646                                [bcmStatFlexDirectionIngress][group_mode];
   3647                           flex_ingress_modes[unit][offset_mode].group_mode =
   3648                                group_mode;
   3649                      }
   3650                      total_counters = flex_ingress_modes[unit][offset_mode].
   3651                                       total_counters;
   3652                      flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num]
   3653                                    [pool_number].used_entries   += total_counters;
   3654                      if (object == bcmStatObjectIngFieldStageIngress) {
   3655                          flex_pool_stat[unit][bcmStatFlexDirectionIngress]
   3656                                        [pipe_num][pool_number].used_by_tables|=
   3657                                     FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE;
   3658                      } else {
   3659                           flex_pool_stat[unit][bcmStatFlexDirectionIngress]
   3660                                        [pipe_num][pool_number].used_by_tables|=
   3661                                        flex_used_by_table[object];
   3662                      }
   3663                      SHR_BITSET(flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num]
   3664                                    [pool_number].used_by_objects, object);
   3665                      if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
   3666                          pool_group_id = pool_number/_bcm_esw_get_max_pool_groups(unit);
   3667                          /* Update the Flex flex_pool_group for oam_lm  for TD2Plus*/
   3668                          if (!BCM_FAILURE(_bcm_esw_stat_flex_ingress_group_oam_status
   3669                                      (unit, pool_group_id,
   3670                                       &enable))) {
   3671                              if (enable ) {
   3672                                  allocate_group_type = BCM_FLEX_POOL_GROUP_USED_BY_OAM;
   3673                              } else {
   3674                                  allocate_group_type = BCM_FLEX_POOL_GROUP_USED_BY_OTHER;
   3675                              }
   3676                              /* Update the pool_group type */
   3677                              flex_pool_group[unit][pipe_num][pool_group_id].group_type
   3678                                  = allocate_group_type;
   3679                          }
   3680                      }
   3681 
   3682                 } else {
   3683                      direction = bcmStatFlexDirectionEgress;
   3684                      /* Quite possible..no attachment till now */
   3685                      if (flex_egress_modes[unit][offset_mode].total_counters
   3686                          == 0) {
   3687                           flex_egress_modes[unit][offset_mode].total_counters =
   3688                                _flex_group_mode_total_counters_info
   3689                                [bcmStatFlexDirectionEgress][group_mode];
   3690                           flex_egress_modes[unit][offset_mode].group_mode =
   3691                                group_mode;
   3692                      }
   3693                      total_counters = flex_egress_modes[unit][offset_mode].
   3694                                       total_counters;
   3695                      flex_pool_stat[unit][bcmStatFlexDirectionEgress][0]
   3696                                    [pool_number].used_entries   += total_counters;
   3697                      flex_pool_stat[unit][bcmStatFlexDirectionEgress][0]
   3698                                    [pool_number].used_by_tables |=
   3699                                    flex_used_by_table[object];
   3700                 }
   3701                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   3702                           (BSL_META_U(unit,
   3703                                       "Installing: mode:%d group_mode:%d pool:%d"
   3704                                        "object:%d base:%d\n"),offset_mode,group_mode,
   3705                            pool_number, object,base_index));
   3706                 if (total_counters == 0) {
   3707                     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   3708                               (BSL_META_U(unit,
   3709                                           "Counter=0.Mode not configured in h/w."
   3710                                            "skipping it\n")));
   3711                     continue;
   3712                 }
   3713                 shr_aidxres_list_reserve_block(
   3714                     flex_aidxres_list_handle[unit][direction][pipe_num][pool_number],
   3715                     base_index,
   3716                     total_counters);
   3717                 BCM_STAT_FLEX_COUNTER_LOCK(unit);
   3718                 if (direction == bcmStatFlexDirectionIngress) {
   3719                     /* Skip ref count increment for attached counters
   3720                      * since its already being done by flex_check_ingress_table
   3721                      * and flex_check_egress_table
   3722                      */
   3723                     if (flex_base_index_reference_count[unit]
   3724                         [bcmStatFlexDirectionIngress][pipe_num][pool_number]
   3725                         [base_index] == 0) {
   3726                     flex_ingress_modes[unit][offset_mode].reference_count++;
   3727                     }
   3728                 } else {
   3729                     if (flex_base_index_reference_count[unit]
   3730                         [bcmStatFlexDirectionEgress][pipe_num][pool_number]
   3731                         [base_index] == 0) {
   3732                     flex_egress_modes[unit][offset_mode].reference_count++;
   3733                 }
   3734                 }
   3735                 BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
   3736             }
   3737         }
   3738     }
   3739 
   3740 #if defined(BCM_TRIDENT3_SUPPORT)
   3741     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
   3742         (_bcm_esw_stat_sync_version_above_equal(unit, BCM_WB_VERSION_1_7))
   3743         && SOC_IS_TRIDENT3(unit)) {
   3744 
   3745         bcm_stat_flex_custom_egress_mode_t flex_custom_egress_mode;
   3746         bcm_stat_flex_custom_mode_info_t *flex_egr_custom_mode_info =
   3747                                      NULL;
   3748         bcm_stat_flex_counter_id_info_t *flex_egr_stat_ctr_info =
   3749                                      NULL;
   3750         /* coverity[alias_transfer : FALSE] */
   3751         flex_egr_custom_mode_info = (void *)
   3752             ((uint32 *)flex_stat_ctr_related_info + 2);
   3753         for (mode = BCM_CUSTOM_EGRESS_MODE_START;
   3754             mode < BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE;
   3755             mode++) {
   3756             if (flex_egr_custom_mode_info->custom_mode != 0) {
   3757                 flex_custom_egress_mode.offset_mode =
   3758                 flex_egr_custom_mode_info->offset_mode;
   3759                 flex_custom_egress_mode.AllocPool =
   3760                 flex_egr_custom_mode_info->AllocPool;
   3761                 flex_custom_egress_mode.used = 1;
   3762                 flex_custom_egress_mode.hint.value = 0;
   3763                 flex_custom_egress_mode.hint.type = 0;
   3764 
   3765                 if (flex_egr_custom_mode_info->fg_id != 0xffffffff) {
   3766                     flex_custom_egress_mode.hint.type =
   3767                     bcmStatGroupAllocHintEgressFieldGroup;
   3768                     flex_custom_egress_mode.hint.value =
   3769                     flex_egr_custom_mode_info->fg_id;
   3770                 }
   3771                 flex_custom_egress_mode.num_selectors = 0;
   3772                 flex_custom_egress_mode.attr_selectors = NULL;
   3773 
   3774                 /* Total_counters has already been recovered during
   3775                  * BCM_WB_VERSION_1_5 and keep unchanged.
   3776                  */
   3777                 {
   3778                     bcm_stat_flex_mode_t tmp_mode =
   3779                        flex_egr_custom_mode_info->custom_mode;
   3780                     if(tmp_mode >= BCM_CUSTOM_EGRESS_MODE_START) {
   3781                        tmp_mode -= BCM_CUSTOM_EGRESS_MODE_START;
   3782                     }
   3783                     flex_custom_egress_mode.total_counters =
   3784                        flex_custom_egress_modes[unit][tmp_mode].total_counters;
   3785                 }
   3786 
   3787                 _bcm_esw_stat_flex_update_custom_egress_mode_info(unit,
   3788                     flex_egr_custom_mode_info->custom_mode,
   3789                     &flex_custom_egress_mode);
   3790             }
   3791             flex_egr_custom_mode_info++;
   3792             }
   3793 
   3794         flex_egr_stat_ctr_info = (void *)flex_egr_custom_mode_info;
   3795 
   3796         *per_pipe_mode_efp = *(uint32 *)flex_egr_stat_ctr_info;
   3797     }
   3798 #endif
   3799     stat_flex_ptr = (uint8 *) flex_group_mode_related_info;
   3800     if (BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_8 &&
   3801             soc_feature(unit, soc_feature_flex_stat_compression_share)) {
   3802         _bcm_esw_stat_flex_compressed_attr_flags_recover(unit,&stat_flex_ptr);
   3803     }
   3804 #if defined(BCM_KATANA2_SUPPORT)
   3805     if (BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_8 &&
   3806             soc_feature(unit, soc_feature_flex_stat_attributes_class)) {
   3807        _bcm_esw_stat_flex_compressed_attr_matrix_recover(unit,&stat_flex_ptr);
   3808     }
   3809 #endif
   3810     return BCM_E_NONE;
   3811 }
   3812 #endif
   3813 
   3814 /*
   3815  * Function:
   3816  *      _bcm_esw_stat_flex_table_index_map
   3817  * Description:
   3818  *      Mapped the table index to table entry index on configured h/w.
   3819  *      Useful in those tabe who has multi-items in each entry.
   3820  * Parameters:
   3821  *      unit                  - (IN) unit number
   3822  *      table                 - (IN) Flex Table
   3823  *      index                 - (IN) Flex Table Index
   3824  * Return Value:
   3825  *      index_mapped          - (OUT) Flex Table Entry Index
   3826  * Notes:
   3827  */
   3828 STATIC int
   3829 _bcm_esw_stat_flex_table_index_map(
   3830     int        unit,
   3831     soc_mem_t  table,
   3832     int        index)
   3833 {
   3834 #if defined(BCM_TRIDENT2_SUPPORT)
   3835     if (SOC_IS_TD2_TT2(unit)) {
   3836         /* Two Items in Each Entry */
   3837         if (table == EGR_NAT_PACKET_EDIT_INFOm ||
   3838             table == L3_DEFIPm ||
   3839             table == L3_DEFIP_LEVEL1m) {
   3840             return index >> 1;
   3841         }
   3842     }
   3843 #endif
   3844 
   3845     return index;
   3846 }
   3847 
   3848 /*
   3849  * Function:
   3850  *      _bcm_esw_stat_flex_retrieve_group_mode
   3851  * Description:
   3852  *      Retrieves Flex group mode based on configured h/w.
   3853  *      Useful in warm boot case
   3854  * Parameters:
   3855  *      unit                  - (IN) unit number
   3856  *      direction             - (IN) Flex Data flow direction
   3857  *      offset_mode           - (IN) Flex offset mode
   3858  * Return Value:
   3859  *      BCM_E_XXX
   3860  * Notes:
   3861  */
   3862 static bcm_error_t
   3863 _bcm_esw_stat_flex_retrieve_group_mode(
   3864     int                       unit,
   3865     bcm_stat_flex_direction_t direction,
   3866     uint32                    offset_mode)
   3867 {
   3868     bcm_stat_flex_ing_attr_t                    *ing_attr=NULL;
   3869     bcm_stat_flex_ing_uncmprsd_attr_selectors_t *ing_uncmprsd_attr_selectors =
   3870                                                 NULL;
   3871     bcm_stat_flex_ing_cmprsd_attr_selectors_t   *ing_cmprsd_attr_selectors=NULL;
   3872     bcm_stat_flex_ing_pkt_attr_bits_t           *ing_cmprsd_pkt_attr_bits=NULL;
   3873 
   3874     bcm_stat_flex_egr_attr_t                    *egr_attr=NULL;
   3875     bcm_stat_flex_egr_uncmprsd_attr_selectors_t *egr_uncmprsd_attr_selectors =
   3876                                                 NULL;
   3877     bcm_stat_flex_egr_cmprsd_attr_selectors_t   *egr_cmprsd_attr_selectors=NULL;
   3878     bcm_stat_flex_egr_pkt_attr_bits_t           *egr_cmprsd_pkt_attr_bits=NULL;
   3879 
   3880     uint32 unknown_pkt_val    = _bcm_esw_stat_flex_get_pkt_res_value(
   3881                                 unit,_UNKNOWN_PKT);
   3882     uint32 control_pkt_val    =  _bcm_esw_stat_flex_get_pkt_res_value(
   3883                                 unit,_CONTROL_PKT);
   3884     uint32 l2uc_pkt_val       = _bcm_esw_stat_flex_get_pkt_res_value(
   3885                                 unit,_L2UC_PKT);
   3886     uint32 known_l2mc_pkt_val = _bcm_esw_stat_flex_get_pkt_res_value(
   3887                                 unit,_KNOWN_L2MC_PKT);
   3888 
   3889     if (direction == bcmStatFlexDirectionIngress) {
   3890         if (flex_ingress_modes[unit][offset_mode].available == 0) {
   3891             return BCM_E_NONE;
   3892         }
   3893         ing_attr                    = &(flex_ingress_modes[unit][offset_mode].
   3894                                         ing_attr);
   3895         ing_uncmprsd_attr_selectors = &(ing_attr->uncmprsd_attr_selectors);
   3896         ing_cmprsd_attr_selectors   = &(ing_attr->cmprsd_attr_selectors);
   3897         ing_cmprsd_pkt_attr_bits    = &(ing_cmprsd_attr_selectors->
   3898                                         pkt_attr_bits);
   3899 
   3900         switch(flex_ingress_modes[unit][offset_mode].total_counters) {
   3901         case 1:
   3902              /* bcmStatGroupModeSingle */
   3903              return _bcm_esw_stat_flex_set_group_mode(
   3904                                  unit,bcmStatFlexDirectionIngress,
   3905                                  offset_mode,bcmStatGroupModeSingle);
   3906         case 2:
   3907              /* bcmStatGroupModeDlfAll,bcmStatGroupModeSingleWithControl,
   3908                 bcmStatGroupModeSvpType */
   3909              if (ing_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   3910                  BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_SVP_TYPE_ATTR_BITS) {
   3911                  return _bcm_esw_stat_flex_set_group_mode(
   3912                                  unit,bcmStatFlexDirectionIngress,
   3913                                  offset_mode,bcmStatGroupModeSvpType);
   3914              }
   3915              if (ing_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   3916                  BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS) {
   3917                  if ((ing_uncmprsd_attr_selectors->
   3918                       offset_table_map[unknown_pkt_val].offset == 1) &&
   3919                      (ing_uncmprsd_attr_selectors->
   3920                       offset_table_map[control_pkt_val].offset == 1)) {
   3921                       return _bcm_esw_stat_flex_set_group_mode(
   3922                                  unit,
   3923                                  bcmStatFlexDirectionIngress,
   3924                                  offset_mode,
   3925                                  bcmStatGroupModeDlfAllWithControl);
   3926                  }
   3927                  if ((ing_uncmprsd_attr_selectors->
   3928                       offset_table_map[unknown_pkt_val].offset == 0) &&
   3929                      (ing_uncmprsd_attr_selectors->
   3930                       offset_table_map[control_pkt_val].offset == 1)) {
   3931                       return _bcm_esw_stat_flex_set_group_mode(
   3932                                  unit,
   3933                                  bcmStatFlexDirectionIngress,
   3934                                  offset_mode,
   3935                                  bcmStatGroupModeSingleWithControl);
   3936                  }
   3937              }
   3938              return BCM_E_PARAM;
   3939         case 3:
   3940              /* bcmStatGroupModeTrafficType,bcmStatGroupModeDlfAllWithControl */
   3941              if (ing_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   3942                  BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS) {
   3943                  if (ing_uncmprsd_attr_selectors->
   3944                      offset_table_map[known_l2mc_pkt_val].offset == 2) {
   3945                      return _bcm_esw_stat_flex_set_group_mode(
   3946                                 unit,
   3947                                 bcmStatFlexDirectionIngress,
   3948                                 offset_mode,
   3949                                 bcmStatGroupModeDlfAllWithControl);
   3950                  }
   3951                  if (ing_uncmprsd_attr_selectors->
   3952                      offset_table_map[known_l2mc_pkt_val].offset == 1) {
   3953                      return _bcm_esw_stat_flex_set_group_mode(
   3954                                 unit,
   3955                                 bcmStatFlexDirectionIngress,
   3956                                 offset_mode,
   3957                                 bcmStatGroupModeTrafficType);
   3958                  }
   3959              }
   3960              return BCM_E_PARAM;
   3961         case 4:
   3962              /* bcmStatGroupModeTyped, bcmStatGroupModeTrafficTypeWithControl */
   3963              if (ing_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   3964                  BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS) {
   3965                  if (ing_uncmprsd_attr_selectors->
   3966                      offset_table_map[known_l2mc_pkt_val].offset == 2) {
   3967                      return _bcm_esw_stat_flex_set_group_mode(
   3968                                 unit,
   3969                                 bcmStatFlexDirectionIngress,
   3970                                 offset_mode,
   3971                                 bcmStatGroupModeTyped);
   3972                  }
   3973                  if (ing_uncmprsd_attr_selectors->
   3974                      offset_table_map[known_l2mc_pkt_val].offset == 1) {
   3975                      return _bcm_esw_stat_flex_set_group_mode(
   3976                                 unit,
   3977                                 bcmStatFlexDirectionIngress,
   3978                                 offset_mode,
   3979                                 bcmStatGroupModeTrafficTypeWithControl);
   3980                  }
   3981              } else {
   3982                  if (ing_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   3983                      BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_CNG_ATTR_BITS) {
   3984                      return _bcm_esw_stat_flex_set_group_mode(
   3985                                 unit,
   3986                                 bcmStatFlexDirectionIngress,
   3987                                 offset_mode,
   3988                                 bcmStatGroupModeCng);
   3989                  }
   3990              }
   3991              return BCM_E_PARAM;
   3992         case 5:
   3993              /* bcmStatGroupModeTypedAll , bcmStatGroupModeTypedWithControl */
   3994              if (ing_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   3995                  BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS) {
   3996                  if (ing_uncmprsd_attr_selectors->
   3997                      offset_table_map[l2uc_pkt_val].offset == 1) {
   3998                      return _bcm_esw_stat_flex_set_group_mode(
   3999                                 unit,
   4000                                 bcmStatFlexDirectionIngress,
   4001                                 offset_mode,
   4002                                 bcmStatGroupModeTyped);
   4003                  }
   4004                  if (ing_uncmprsd_attr_selectors->
   4005                      offset_table_map[l2uc_pkt_val].offset == 2) {
   4006                      return _bcm_esw_stat_flex_set_group_mode(
   4007                                 unit,
   4008                                 bcmStatFlexDirectionIngress,
   4009                                 offset_mode,
   4010                                 bcmStatGroupModeTrafficTypeWithControl);
   4011                  }
   4012              }
   4013              return BCM_E_PARAM;
   4014         case 6:
   4015              /* bcmStatGroupModeTypedAllWithControl */
   4016             if (ing_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4017                 BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS) {
   4018                 return _bcm_esw_stat_flex_set_group_mode(
   4019                            unit,
   4020                            bcmStatFlexDirectionIngress,
   4021                            offset_mode,
   4022                            bcmStatGroupModeTypedAllWithControl);
   4023                 }
   4024              return BCM_E_PARAM;
   4025         case 8:
   4026              /* bcmStatGroupModeDot1P */
   4027              if (ing_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4028                  BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_OUTER_DOT1P_ATTR_BITS) {
   4029                  return _bcm_esw_stat_flex_set_group_mode(
   4030                             unit,
   4031                             bcmStatFlexDirectionIngress,
   4032                             offset_mode,
   4033                             bcmStatGroupModeDot1P);
   4034              }
   4035              return BCM_E_PARAM;
   4036         case 16:
   4037              /* bcmStatGroupModeIntPri */
   4038              if (ing_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4039                  BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_INT_PRI_ATTR_BITS) {
   4040                  return _bcm_esw_stat_flex_set_group_mode(
   4041                             unit,
   4042                             bcmStatFlexDirectionIngress,
   4043                             offset_mode,
   4044                             bcmStatGroupModeIntPri);
   4045              }
   4046              return BCM_E_PARAM;
   4047         case 17:
   4048              /* bcmStatGroupModeDlfIntPri */
   4049              if (ing_attr->packet_attr_type ==
   4050                  bcmStatFlexPacketAttrTypeCompressed) {
   4051                  if ((ing_cmprsd_pkt_attr_bits->int_pri == 4) &&
   4052                      (ing_cmprsd_pkt_attr_bits->pkt_resolution == 1)) {
   4053                       return _bcm_esw_stat_flex_set_group_mode(
   4054                                  unit,
   4055                                  bcmStatFlexDirectionIngress,
   4056                                  offset_mode,
   4057                                  bcmStatGroupModeDlfIntPri);
   4058                  }
   4059              }
   4060              return BCM_E_PARAM;
   4061         case 18:
   4062              /* bcmStatGroupModeDlfIntPriWithControl */
   4063              if (ing_attr->packet_attr_type ==
   4064                  bcmStatFlexPacketAttrTypeCompressed) {
   4065                  if ((ing_cmprsd_pkt_attr_bits->int_pri == 4) &&
   4066                      (ing_cmprsd_pkt_attr_bits->pkt_resolution == 2)) {
   4067                       return _bcm_esw_stat_flex_set_group_mode(
   4068                                  unit,
   4069                                  bcmStatFlexDirectionIngress,
   4070                                  offset_mode,
   4071                                  bcmStatGroupModeDlfIntPriWithControl);
   4072                  }
   4073              }
   4074              return BCM_E_PARAM;
   4075         case 20:
   4076              /* bcmStatGroupModeTypedIntPri */
   4077              if (ing_attr->packet_attr_type ==
   4078                  bcmStatFlexPacketAttrTypeCompressed) {
   4079                  if ((ing_cmprsd_pkt_attr_bits->int_pri == 4) &&
   4080                      (ing_cmprsd_pkt_attr_bits->pkt_resolution == 3)) {
   4081                       return _bcm_esw_stat_flex_set_group_mode(
   4082                                  unit,
   4083                                  bcmStatFlexDirectionIngress,
   4084                                  offset_mode,
   4085                                  bcmStatGroupModeTypedIntPri);
   4086                  }
   4087              }
   4088              return BCM_E_PARAM;
   4089         case 21:
   4090              /* bcmStatGroupModeTypedIntPriWithControl */
   4091              if (ing_attr->packet_attr_type ==
   4092                  bcmStatFlexPacketAttrTypeCompressed) {
   4093                  if ((ing_cmprsd_pkt_attr_bits->int_pri == 4) &&
   4094                      (ing_cmprsd_pkt_attr_bits->pkt_resolution == 3)) {
   4095                       return _bcm_esw_stat_flex_set_group_mode(
   4096                                  unit,
   4097                                  bcmStatFlexDirectionIngress,
   4098                                  offset_mode,
   4099                                  bcmStatGroupModeTypedIntPriWithControl);
   4100                  }
   4101              }
   4102              return BCM_E_PARAM;
   4103         case 64:
   4104              /* bcmStatGroupModeIntPriCng , bcmStatGroupModeDscp */
   4105              if (ing_attr->packet_attr_type ==
   4106                  bcmStatFlexPacketAttrTypeUncompressed) {
   4107                  if (ing_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4108                      BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_TOS_DSCP_ATTR_BITS) {
   4109                      return _bcm_esw_stat_flex_set_group_mode(
   4110                                 unit,
   4111                                 bcmStatFlexDirectionIngress,
   4112                                 offset_mode,
   4113                                 bcmStatGroupModeDscp);
   4114                  }
   4115                  if (ing_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4116                      (BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_CNG_ATTR_BITS|
   4117                       BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_INT_PRI_ATTR_BITS)) {
   4118                      return _bcm_esw_stat_flex_set_group_mode(
   4119                                 unit,
   4120                                 bcmStatFlexDirectionIngress,
   4121                                 offset_mode,
   4122                                 bcmStatGroupModeIntPriCng);
   4123                  }
   4124              }
   4125              return BCM_E_PARAM;
   4126         default:
   4127              LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
   4128                          (BSL_META_U(unit,
   4129                                      "INFO:No fixed Counter:%d so probably a FlexGroup\n"),
   4130                                      flex_ingress_modes[unit][offset_mode].total_counters));
   4131              return BCM_E_NONE;
   4132         }
   4133     } else {
   4134         if (flex_egress_modes[unit][offset_mode].available == 0) {
   4135             return BCM_E_NONE;
   4136         }
   4137         egr_attr                    = &(flex_egress_modes[unit][offset_mode].
   4138                                         egr_attr);
   4139         egr_uncmprsd_attr_selectors = &(egr_attr->uncmprsd_attr_selectors);
   4140         egr_cmprsd_attr_selectors   = &(egr_attr->cmprsd_attr_selectors);
   4141         egr_cmprsd_pkt_attr_bits    = &(egr_cmprsd_attr_selectors->
   4142                                         pkt_attr_bits);
   4143         switch(flex_egress_modes[unit][offset_mode].total_counters) {
   4144         case 1:
   4145              /* bcmStatGroupModeSingle, bcmStatGroupModeDlfAll ,
   4146                 bcmStatGroupModeSingleWithControl */
   4147              if ((egr_attr->packet_attr_type ==
   4148                   bcmStatFlexPacketAttrTypeUncompressed) &&
   4149                  (egr_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4150                   BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS)){
   4151                   return _bcm_esw_stat_flex_set_group_mode(
   4152                              unit,
   4153                              bcmStatFlexDirectionEgress,
   4154                              offset_mode,
   4155                              bcmStatGroupModeSingle);
   4156              }
   4157              return BCM_E_PARAM;
   4158         case 2:
   4159              /* bcmStatGroupModeTrafficType, bcmStatGroupModeTyped ,
   4160                 bcmStatGroupModeTypedAll,
   4161                 bcmStatGroupModeTrafficTypeWithControl,
   4162                 bcmStatGroupModeDlfAllWithControl,
   4163                 bcmStatGroupModeTypedWithControl,
   4164                 bcmStatGroupModeTypedAllWithControl, bcmStatGroupModeSvpType ,
   4165                 bcmStatGroupModeDvpType  */
   4166              if (egr_attr->packet_attr_type ==
   4167                  bcmStatFlexPacketAttrTypeUncompressed) {
   4168                  if (egr_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4169                      BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_DVP_TYPE_ATTR_BITS) {
   4170                      return _bcm_esw_stat_flex_set_group_mode(
   4171                                          unit,bcmStatFlexDirectionEgress,
   4172                                          offset_mode,bcmStatGroupModeDvpType);
   4173                     }
   4174                  if (egr_uncmprsd_attr_selectors->
   4175                      uncmprsd_attr_bits_selector ==
   4176                      BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_SVP_TYPE_ATTR_BITS) {
   4177                      return _bcm_esw_stat_flex_set_group_mode(
   4178                                 unit,
   4179                                 bcmStatFlexDirectionEgress,
   4180                                 offset_mode,
   4181                                 bcmStatGroupModeSvpType);
   4182                  }
   4183                  if (egr_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4184                   BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS) {
   4185                      return _bcm_esw_stat_flex_set_group_mode(
   4186                                 unit,
   4187                                 bcmStatFlexDirectionEgress,
   4188                                 offset_mode,
   4189                                 bcmStatGroupModeTrafficType);
   4190                  }
   4191              }
   4192              return BCM_E_PARAM;
   4193         case 4:
   4194              if (egr_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4195                  BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_CNG_ATTR_BITS) {
   4196                      return _bcm_esw_stat_flex_set_group_mode(
   4197                                 unit,
   4198                                 bcmStatFlexDirectionEgress,
   4199                                 offset_mode,
   4200                                 bcmStatGroupModeCng);
   4201              }
   4202              return BCM_E_PARAM;
   4203         case 8:
   4204              /* bcmStatGroupModeDot1P */
   4205              if (egr_attr->packet_attr_type ==
   4206                  bcmStatFlexPacketAttrTypeUncompressed) {
   4207                  if (egr_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4208                      BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_OUTER_DOT1P_ATTR_BITS) {
   4209                      return _bcm_esw_stat_flex_set_group_mode(
   4210                                 unit,
   4211                                 bcmStatFlexDirectionEgress,
   4212                                 offset_mode,
   4213                                 bcmStatGroupModeDot1P);
   4214                  }
   4215              }
   4216              return BCM_E_PARAM;
   4217         case 16:
   4218              /* bcmStatGroupModeIntPri */
   4219              if (egr_attr->packet_attr_type ==
   4220                  bcmStatFlexPacketAttrTypeUncompressed) {
   4221                  if (egr_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4222                      BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_INT_PRI_ATTR_BITS) {
   4223                      return _bcm_esw_stat_flex_set_group_mode(
   4224                                 unit,
   4225                                 bcmStatFlexDirectionEgress,
   4226                                 offset_mode,
   4227                                 bcmStatGroupModeIntPri);
   4228                  }
   4229              }
   4230              return BCM_E_PARAM;
   4231         case 18:
   4232              /* bcmStatGroupModeTypedIntPri */
   4233              if (egr_attr->packet_attr_type ==
   4234                  bcmStatFlexPacketAttrTypeCompressed) {
   4235                  if ((egr_cmprsd_pkt_attr_bits->int_pri == 4) &&
   4236                      (egr_cmprsd_pkt_attr_bits->pkt_resolution == 1)) {
   4237                       return _bcm_esw_stat_flex_set_group_mode(
   4238                                  unit,
   4239                                  bcmStatFlexDirectionEgress,
   4240                                  offset_mode,
   4241                                  bcmStatGroupModeTypedIntPri);
   4242                   }
   4243              }
   4244              return BCM_E_PARAM;
   4245         case 64:
   4246              /* bcmStatGroupModeIntPriCng , bcmStatGroupModeDscp */
   4247              if (egr_attr->packet_attr_type ==
   4248                  bcmStatFlexPacketAttrTypeUncompressed) {
   4249                  if (egr_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4250                      BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_TOS_DSCP_ATTR_BITS) {
   4251                      return _bcm_esw_stat_flex_set_group_mode(
   4252                                 unit,
   4253                                 bcmStatFlexDirectionEgress,
   4254                                 offset_mode,
   4255                                 bcmStatGroupModeDscp);
   4256                  }
   4257                  if (egr_uncmprsd_attr_selectors->uncmprsd_attr_bits_selector ==
   4258                      (BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_CNG_ATTR_BITS|
   4259                       BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_INT_PRI_ATTR_BITS)) {
   4260                      return _bcm_esw_stat_flex_set_group_mode(
   4261                                 unit,
   4262                                 bcmStatFlexDirectionEgress,
   4263                                 offset_mode,
   4264                                 bcmStatGroupModeIntPriCng);
   4265                  }
   4266              }
   4267              return BCM_E_PARAM;
   4268         default:
   4269              LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
   4270                          (BSL_META_U(unit,
   4271                                      "INFO:No fixed Counter:%d so probably a FlexGroup\n"),
   4272                                      flex_ingress_modes[unit][offset_mode].total_counters));
   4273              return BCM_E_NONE;
   4274         }
   4275     }
   4276     return BCM_E_PARAM;
   4277 }
   4278 
   4279 /*
   4280  * Function:
   4281  *      _bcm_esw_stat_flex_oam_enable_ingress_group
   4282  * Description:
   4283  *      Enable/Disable ingress flex counter pool group.
   4284  * Parameters:
   4285  *      unit                  - (IN) unit number
   4286  * Return Value:
   4287  *      BCM_E_XXX
   4288  * Notes:
   4289  */
   4290 static bcm_error_t _bcm_esw_stat_flex_oam_enable_ingress_group(
   4291             int                       unit,
   4292             uint32                    group,
   4293             uint32                    enable)
   4294 {
   4295     uint32  flex_ctr_group_lm_config_value=0;
   4296     uint32  enable_value;
   4297 
   4298     if (group >= 
   4299              soc_reg_field_length(unit, ING_FLEX_CTR_LM_CONFIGr, LM_ENABLEf)) { 
   4300         return BCM_E_PARAM;
   4301     }
   4302     
   4303     if ( enable ) {
   4304         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   4305                   (BSL_META_U(unit,
   4306                               "...Enabling Flex Counter Group:%d for OAM \n"),
   4307                               group));
   4308     } else {
   4309         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   4310                   (BSL_META_U(unit,
   4311                               "...Disabling Flex Counter Group:%d for OAM \n"),
   4312                               group));
   4313     }
   4314     /* First Get complete value of
   4315        ING_FLEX_CTR_LM_CONFIGr value */
   4316     SOC_IF_ERROR_RETURN(soc_reg32_get(
   4317                         unit,
   4318                         ING_FLEX_CTR_LM_CONFIGr,
   4319                         REG_PORT_ANY, 0,
   4320                         &flex_ctr_group_lm_config_value));
   4321      enable_value = soc_reg_field_get(unit,
   4322                                       ING_FLEX_CTR_LM_CONFIGr,
   4323                                       flex_ctr_group_lm_config_value, 
   4324                                       LM_ENABLEf);
   4325     /* Next set field value for
   4326        ING_FLEX_CTR_LM_CONFIGr:LM_ENABLE field*/
   4327     if (enable) {
   4328         enable_value |= 1 << group;
   4329     }else {
   4330         enable_value &= ~(1 << group);
   4331     }
   4332     soc_reg_field_set(unit,
   4333                       ING_FLEX_CTR_LM_CONFIGr,
   4334                       &flex_ctr_group_lm_config_value,
   4335                       LM_ENABLEf,
   4336                       enable_value);
   4337     /* Finally set value for
   4338        ING_FLEX_CTR_LM_CONFIGr:LM_ENABLE field*/
   4339     SOC_IF_ERROR_RETURN(soc_reg32_set(unit,
   4340                                       ING_FLEX_CTR_LM_CONFIGr,
   4341                                       REG_PORT_ANY,
   4342                                       0,
   4343                                       flex_ctr_group_lm_config_value));
   4344     return BCM_E_NONE;
   4345 }
   4346 
   4347 /* Function to enable/disable a pool.
   4348  * Call counter module to program the status in hardware
   4349  */
   4350 static
   4351 soc_error_t soc_counter_pool_status_set(int unit, int direction,
   4352                                         int index, uint32 enable)
   4353 {
   4354     soc_ctr_control_info_t ctrl_info[2];
   4355     soc_ctr_ctrl_config_t ctrl_config[2];
   4356     soc_reg_t ctr_reg_pkt, ctr_reg_byte;
   4357     int i;
   4358 
   4359     for (i = 0; i < 2; i++) {
   4360         ctrl_info[i].instance_type = SOC_CTR_INSTANCE_TYPE_POOL;
   4361         ctrl_info[i].instance = index;
   4362     }
   4363     ctrl_config[0].config_type = SOC_CTR_CTRL_CONFIG_DMA_ENABLE;
   4364     ctrl_config[0].config_val = enable;
   4365 
   4366     ctrl_config[1].config_type = SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_ALL;
   4367     ctrl_config[1].config_val = 1; /* Enable ALL profiles for EFP_PKT */
   4368 
   4369     if (direction == bcmStatFlexDirectionEgress) {
   4370         ctr_reg_pkt = SOC_COUNTER_NON_DMA_EGR_FLEX_PKT;
   4371         ctr_reg_byte = SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE;
   4372     } else {
   4373         ctr_reg_pkt = SOC_COUNTER_NON_DMA_ING_FLEX_PKT;
   4374         ctr_reg_byte = SOC_COUNTER_NON_DMA_ING_FLEX_BYTE;
   4375     }
   4376 
   4377     SOC_IF_ERROR_RETURN
   4378         (soc_counter_config_multi_set(unit, ctr_reg_pkt, 2, ctrl_info,
   4379                                       ctrl_config));
   4380     SOC_IF_ERROR_RETURN
   4381         (soc_counter_config_multi_set(unit, ctr_reg_byte, 2,
   4382                                       ctrl_info, ctrl_config));
   4383 
   4384     return SOC_E_NONE;
   4385 }
   4386 
   4387 /* Function to Inform Counter module to enable DMA for Flex Pools.
   4388  * Notes:
   4389  *      Applicable in warm boot scenario only.
   4390  */
   4391 static
   4392 soc_error_t soc_counter_pool_bmap_status_set(int unit, int direction,
   4393                                              uint32 pool_bmap, uint32 enable)
   4394 {
   4395     int i = 0, max_pools;
   4396     if (!soc_feature(unit, soc_feature_centralized_counter)) {
   4397         return SOC_E_NONE;
   4398     }
   4399 
   4400     if (direction == bcmStatFlexDirectionIngress) {
   4401         max_pools = SOC_INFO(unit).num_flex_ingress_pools;
   4402     } else {
   4403         max_pools = SOC_INFO(unit).num_flex_egress_pools;
   4404     }
   4405 
   4406     for (i = 0; i < max_pools; i++) {
   4407         if (pool_bmap & (1 << i)) {
   4408             SOC_IF_ERROR_RETURN
   4409                 (soc_counter_pool_status_set(unit, direction, i, enable));
   4410         }
   4411     }
   4412 
   4413     return SOC_E_NONE;
   4414 }
   4415 
   4416 /*
   4417  * Function:
   4418  *      _bcm_esw_stat_flex_enable_pool
   4419  * Description:
   4420  *      Enable/Disable ingress/egress flex counter pool.
   4421  * Parameters:
   4422  *      unit                  - (IN) unit number
   4423  * Return Value:
   4424  *      BCM_E_XXX
   4425  * Notes:
   4426  */
   4427 static bcm_error_t _bcm_esw_stat_flex_enable_pool(
   4428             int                       unit,
   4429             bcm_stat_flex_direction_t direction,
   4430             soc_reg_t                 flex_pool_ctr_update_control_reg,
   4431             uint32                    enable)
   4432 {
   4433     uint32  flex_pool_ctr_update_control_reg_value=0;
   4434     uint32  enable_value=1;
   4435     uint32  num_pools[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
   4436     uint32  index=0;
   4437 
   4438     num_pools[bcmStatFlexDirectionIngress]=
   4439              SOC_INFO(unit).num_flex_ingress_pools;
   4440     num_pools[bcmStatFlexDirectionEgress] =
   4441              SOC_INFO(unit).num_flex_egress_pools;
   4442     if (direction >= BCM_STAT_FLEX_COUNTER_MAX_DIRECTION) {
   4443         return BCM_E_PARAM;
   4444     }
   4445     for(index=0;
   4446         index < num_pools[direction];
   4447         index++) {
   4448         if (_pool_ctr_register[direction][index] ==
   4449             flex_pool_ctr_update_control_reg ) {
   4450 #if defined(BCM_TOMAHAWK_SUPPORT) && defined (INCLUDE_FLOWTRACKER)
   4451             if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
   4452                  soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
   4453                  soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
   4454                 if (_bcm_esw_stat_pool_reserved(unit, direction, index)) {
   4455                     return BCM_E_NONE;
   4456                 }
   4457             }
   4458 #endif
   4459             break;
   4460         }
   4461     }
   4462     if (index == num_pools[direction]) {
   4463          return BCM_E_PARAM;
   4464     }
   4465     if ( enable ) {
   4466         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   4467                   (BSL_META_U(unit,
   4468                               "...Enabling pool:%s \n"),
   4469                    SOC_REG_NAME(unit, flex_pool_ctr_update_control_reg)));
   4470     } else {
   4471         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   4472                   (BSL_META_U(unit,
   4473                               "...Disabling pool:%s \n"),
   4474                    SOC_REG_NAME(unit, flex_pool_ctr_update_control_reg)));
   4475     }
   4476     /* First Get complete value of
   4477        EGR/ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_?r value */
   4478     SOC_IF_ERROR_RETURN(soc_reg32_get(
   4479                         unit,
   4480                         flex_pool_ctr_update_control_reg,
   4481                         REG_PORT_ANY, 0,
   4482                         &flex_pool_ctr_update_control_reg_value));
   4483     /* Next set field value for
   4484        EGR/ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_?r:COUNTER_POOL_ENABLE field*/
   4485     if (enable) {
   4486         enable_value=1;
   4487     }else {
   4488         enable_value=0;
   4489     }
   4490     soc_reg_field_set(unit,
   4491                       flex_pool_ctr_update_control_reg,
   4492                       &flex_pool_ctr_update_control_reg_value,
   4493                       COUNTER_POOL_ENABLEf,
   4494                       enable_value);
   4495 
   4496     enable_value = !soc_property_suffix_num_get(
   4497         unit, index, spn_MIRROR_COPY_COUNTING_DISABLE, "pool", 0);
   4498     soc_reg_field_set(unit,
   4499                       flex_pool_ctr_update_control_reg,
   4500                       &flex_pool_ctr_update_control_reg_value,
   4501                       MIRROR_COPY_INCR_ENABLEf,
   4502                       enable_value);
   4503     /* Finally set value for
   4504        EGR/ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_?r:COUNTER_POOL_ENABLE field*/
   4505     SOC_IF_ERROR_RETURN(soc_reg32_set(unit,
   4506                                       flex_pool_ctr_update_control_reg,
   4507                                       REG_PORT_ANY,
   4508                                       0,
   4509                                       flex_pool_ctr_update_control_reg_value));
   4510     /* Call Counter module to program the hardware */
   4511     if (soc_feature(unit, soc_feature_centralized_counter)) {
   4512         return soc_counter_pool_status_set(unit, direction, index, enable);
   4513     }
   4514     return BCM_E_NONE;
   4515 }
   4516 
   4517 /*
   4518  * Function:
   4519  *      _bcm_esw_stat_flex_retrieve_total_counters
   4520  * Description:
   4521  *      Retries total counter based on flex h/w configuration
   4522  * Parameters:
   4523  *      unit                  - (IN) unit number
   4524  * Return Value:
   4525  *      BCM_E_XXX
   4526  * Notes:
   4527  */
   4528 static uint32
   4529 _bcm_esw_stat_flex_retrieve_total_counters(
   4530     int                       unit,
   4531     bcm_stat_flex_direction_t direction,
   4532     uint32                    pool_number,
   4533     uint32                    offset_mode)
   4534 {
   4535     uint32                             index=0;
   4536     ing_flex_ctr_offset_table_0_entry_t *flex_ctr_offset_table_entry=NULL;
   4537     uint32                             count_enable=0;
   4538     bcm_stat_flex_offset_table_entry_t *sw_offset_table=NULL;
   4539     uint32                             offset=0;
   4540     uint32                             total_counters_flag=0;
   4541     uint32                             total_counters=0;
   4542     uint32                             alloc_size=0;
   4543 
   4544 
   4545     /* Actually we need only 256 offsets only but ...*/
   4546     alloc_size =  soc_mem_index_count(unit,ING_FLEX_CTR_OFFSET_TABLE_0m) *
   4547                   sizeof(ing_flex_ctr_offset_table_0_entry_t);
   4548 
   4549     flex_ctr_offset_table_entry = soc_cm_salloc(unit,alloc_size,
   4550                                                 "flex_ctr_offset_table_entry");
   4551     if (flex_ctr_offset_table_entry == NULL) {
   4552         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   4553                   (BSL_META_U(unit,
   4554                               "Memory Allocation failed:flex_ctr_offset_table_entry\n")));
   4555         return  BCM_E_INTERNAL;
   4556     }
   4557     sal_memset(flex_ctr_offset_table_entry, 0, alloc_size);
   4558     /* 0-255,256-511,512-...*/
   4559     if (soc_mem_read_range(unit,
   4560                      _ctr_offset_table[direction][pool_number],
   4561                      MEM_BLOCK_ANY,
   4562                      (offset_mode <<8),
   4563                      (offset_mode <<8)+ (256) - 1,
   4564                      flex_ctr_offset_table_entry) != SOC_E_NONE) {
   4565         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   4566                   (BSL_META_U(unit,
   4567                               "Memory Reading failed:flex_ctr_offset_table_entry \n")));
   4568         soc_cm_sfree(unit,flex_ctr_offset_table_entry);
   4569         return 0;
   4570     }
   4571     if (direction == bcmStatFlexDirectionIngress) {
   4572         switch(flex_ingress_modes[unit][offset_mode].ing_attr.
   4573                packet_attr_type) {
   4574         case bcmStatFlexPacketAttrTypeUncompressed:
   4575              sw_offset_table = &flex_ingress_modes[unit][offset_mode].ing_attr.
   4576                                 uncmprsd_attr_selectors.offset_table_map[0];
   4577              break;
   4578         case bcmStatFlexPacketAttrTypeCompressed:
   4579              sw_offset_table = &flex_ingress_modes[unit][offset_mode].ing_attr.
   4580                                 cmprsd_attr_selectors.offset_table_map[0];
   4581              break;
   4582         case bcmStatFlexPacketAttrTypeUdf:
   4583         default:
   4584              /* With current implemControl must not reach over here */
   4585              soc_cm_sfree(unit,flex_ctr_offset_table_entry);
   4586              return BCM_E_PARAM;
   4587         }
   4588     } else {
   4589         switch(flex_egress_modes[unit][offset_mode].egr_attr.packet_attr_type) {
   4590         case bcmStatFlexPacketAttrTypeUncompressed:
   4591              sw_offset_table = &flex_egress_modes[unit][offset_mode].egr_attr.
   4592                                 uncmprsd_attr_selectors.offset_table_map[0];
   4593              break;
   4594         case bcmStatFlexPacketAttrTypeCompressed:
   4595              sw_offset_table = &flex_egress_modes[unit][offset_mode].egr_attr.
   4596                                 cmprsd_attr_selectors.offset_table_map[0];
   4597              break;
   4598         case bcmStatFlexPacketAttrTypeUdf:
   4599         default:
   4600              /* With current implemControl must not reach over here */
   4601              soc_cm_sfree(unit,flex_ctr_offset_table_entry);
   4602              return BCM_E_PARAM;
   4603         }
   4604     }
   4605     for (index=0;index<(256);index++) {
   4606          count_enable=0;
   4607          /*First Get complete value of EGR/ING_FLEX_CTR_OFFSET_TABLE_?m value */
   4608          soc_mem_field_get(unit,
   4609                            _ctr_offset_table[direction][pool_number],
   4610                            (uint32 *)&flex_ctr_offset_table_entry[index],
   4611                            COUNT_ENABLEf,&count_enable);
   4612          soc_mem_field_get(unit,
   4613                            _ctr_offset_table[direction][pool_number],
   4614                            (uint32 *)&flex_ctr_offset_table_entry[index],
   4615                            OFFSETf,
   4616                            &offset);
   4617          if (count_enable) {
   4618              total_counters_flag=1;
   4619              if (total_counters < offset) {
   4620                  total_counters = offset;
   4621              }
   4622          }
   4623          sw_offset_table[index].offset = offset;
   4624          sw_offset_table[index].count_enable = count_enable;
   4625     }
   4626     soc_cm_sfree(unit,flex_ctr_offset_table_entry);
   4627     return (total_counters+total_counters_flag);
   4628 }
   4629 
   4630 static int
   4631 _bcm_esw_stat_flex_check_invalid_base_idx(
   4632     int       unit,
   4633     soc_mem_t table,
   4634     int       pipe_num,
   4635     int       pool_num,
   4636     int       base_idx)
   4637 {
   4638     int rv = 0;
   4639 
   4640 #ifdef BCM_TOMAHAWK3_SUPPORT
   4641     uint16 dev_id;
   4642     uint8  rev_id;
   4643 
   4644     soc_cm_get_id(unit, &dev_id, &rev_id);
   4645     /* In TH3 56983 SKU, egr_port is addr_split_split and since some
   4646        of the pipes are inactive, we can not access all the base_idx.
   4647        Below code skips the indexes belonging to pipes 2, 3, 4, 5
   4648      */
   4649     if (dev_id == BCM56983_DEVICE_ID &&
   4650         (table == PORT_TABm || table == EGR_PORTm)) {
   4651         if (pipe_num == 0 && base_idx > 19) {
   4652             return 1;
   4653         }
   4654         else if (pipe_num == 1 && (base_idx < 19 || base_idx > 39)) {
   4655             return 1;
   4656         } 
   4657         else if (pipe_num == 6 && (base_idx < 120 || base_idx > 139)) {
   4658             return 1;
   4659         }
   4660         else if (pipe_num == 7 && (base_idx < 139 || base_idx > 159)) {
   4661             return 1;
   4662         }
   4663     }
   4664 #endif
   4665 
   4666     return rv;
   4667 }
   4668 
   4669 
   4670 /*
   4671  * Function:
   4672  *      _bcm_esw_stat_flex_check_egress_table
   4673  * Description:
   4674  *      Checkes flex egress table. If table were configured for flex counter
   4675  *      updates s/w copy accordingly.
   4676  *
   4677  * Parameters:
   4678  *      unit                  - (IN) unit number
   4679  *      egress_table          - (IN) Flex Egress  Table
   4680  *      index                 - (IN) Flex Egress  Table Index
   4681  * Return Value:
   4682  *      None
   4683  * Notes:
   4684  *      Applicable in warm boot scenario only.
   4685  */
   4686 static void
   4687 _bcm_esw_stat_flex_check_egress_table(
   4688     int       unit,
   4689     soc_mem_t egress_table,
   4690     int       min_index,
   4691     int       max_index)
   4692 {
   4693     uint32            offset_mode=0;
   4694     uint32            pool_number=0;
   4695     uint32            base_idx=0;
   4696     uint32            egress_entry_data_size=0;
   4697     void              *egress_entry_data=NULL;
   4698     void              *egress_entry_full_data=NULL;
   4699     bcm_stat_object_t object=bcmStatObjectEgrPort;
   4700     int               index=0;
   4701     uint32            counter_pool_bmap = 0; /* To enable counters */
   4702 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   4703     void              *flex_entry_data = NULL;
   4704     uint32            flex_entry_data_size=0;
   4705 #endif
   4706     int               exact_index = 0;
   4707 #if defined(BCM_TRIDENT3_SUPPORT)
   4708     uint32 key_typef[] = {KEY_TYPEf,
   4709                          KEY_TYPE0f,
   4710                          KEY_TYPE1f};
   4711     uint32 data_typef[] = {DATA_TYPEf,
   4712                           DATA_TYPE0f,
   4713                           DATA_TYPE1f};
   4714     int data_type = 0;
   4715     int key_type = 0;
   4716     uint32 mem_view_id = 0;
   4717     int i = 0;
   4718     soc_mem_t tmp_mem = INVALIDm;
   4719 #endif
   4720     uint32 pipe_num = 0;
   4721     uint32 total_counters = 0;
   4722 
   4723     if (!((egress_table == EGR_VLANm) ||
   4724           (egress_table == EGR_VFIm)  ||
   4725           (egress_table == EGR_L3_NEXT_HOPm)  ||
   4726 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   4727           (egress_table == EGR_IP_TUNNEL_MPLSm) ||
   4728           (egress_table == EFP_POLICY_TABLEm) ||
   4729 #endif
   4730 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
   4731           (egress_table == EGR_DVP_ATTRIBUTE_1m)  ||
   4732 #endif /* BCM_TRIDENT2_SUPPORT || BCM_TRIUMPH3_SUPPORT */
   4733 #if defined(BCM_TRIDENT2_SUPPORT)
   4734           (egress_table == EGR_NAT_PACKET_EDIT_INFOm)  ||
   4735 #endif /* BCM_TRIDENT2_SUPPORT */
   4736 #if defined(BCM_TRIDENT3_SUPPORT)
   4737         (egress_table == EGR_DVP_ATTRIBUTEm)  ||
   4738         (egress_table == EGR_VLAN_XLATE_1_DOUBLEm)  ||
   4739         (egress_table == EGR_VLAN_XLATE_2_DOUBLEm)  ||
   4740         (egress_table == EGR_LPORT_PROFILEm)  ||
   4741         (egress_table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm) ||
   4742         ((SOC_IS_TRIDENT3X(unit)) &&
   4743           ((egress_table == EFP_POLICY_TABLE_PIPE0m)  ||
   4744           (egress_table == EFP_POLICY_TABLE_PIPE1m))) ||
   4745 #endif /* BCM_TRIDENT3_SUPPORT */
   4746           (egress_table == EGR_VLAN_XLATEm)  ||
   4747           (egress_table == EGR_PORTm))) {
   4748            LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   4749                      (BSL_META_U(unit,
   4750                                  "Invalid Flex Counter Egress Memory %s\n"),
   4751                       SOC_MEM_UFNAME(unit, egress_table)));
   4752            return;
   4753     }
   4754 
   4755     if (!SOC_MEM_IS_VALID(unit, egress_table)) {
   4756         /* This check is for low latency mode */
   4757         return;
   4758     }
   4759 
   4760 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   4761     pipe_num = _bcm_esw_get_fp_pipe_num(unit, egress_table);
   4762 #endif
   4763 
   4764     if (max_index > soc_mem_index_max(unit,egress_table)) {
   4765         max_index = soc_mem_index_max(unit,egress_table);
   4766     }
   4767     egress_entry_data_size= WORDS2BYTES(BYTES2WORDS(
   4768                                         SOC_MEM_INFO(unit,egress_table).bytes));
   4769     egress_entry_full_data = soc_cm_salloc(unit,egress_entry_data_size *
   4770                                   (max_index - min_index + 1),"egress_table");
   4771     if (egress_entry_full_data == NULL) {
   4772         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   4773                   (BSL_META_U(unit,
   4774                               "Failed to allocate memory for Table:%s "),
   4775                    SOC_MEM_UFNAME(unit, egress_table)));
   4776         return ;
   4777     }
   4778     sal_memset(egress_entry_full_data,0,(egress_entry_data_size *
   4779                                   (max_index - min_index + 1)));
   4780 
   4781     if (soc_mem_read_range(unit, egress_table, MEM_BLOCK_ANY,
   4782                 min_index,max_index, egress_entry_full_data) != SOC_E_NONE) {
   4783         soc_cm_sfree(unit,egress_entry_full_data);
   4784         return;
   4785     }
   4786 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   4787     if (egress_table == EGR_IP_TUNNEL_MPLSm
   4788 #if defined(BCM_TRIDENT3_SUPPORT)
   4789         || egress_table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm
   4790 #endif
   4791        ) {
   4792         flex_entry_data_size = WORDS2BYTES(BYTES2WORDS(SOC_MEM_INFO(unit,
   4793                         egress_table).bytes));
   4794         flex_entry_data = sal_alloc(flex_entry_data_size,"flex-counter-table");
   4795         if (flex_entry_data == NULL) {
   4796             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   4797                     (BSL_META_U(unit,
   4798                                 "Failed to allocate memory for Table:%s "),
   4799                      SOC_MEM_UFNAME(unit, egress_table)));
   4800             return;
   4801         }
   4802     }
   4803 #endif
   4804     BCM_STAT_FLEX_COUNTER_LOCK(unit);
   4805     for(index=0; index <= (max_index - min_index) ; index++) {
   4806         egress_entry_data = soc_mem_table_idx_to_pointer(unit, egress_table,
   4807                             void *, egress_entry_full_data, index);
   4808         if (soc_mem_field_valid(unit,egress_table,VALIDf)) {
   4809             if (soc_mem_field32_get(unit,egress_table,egress_entry_data,
   4810                 VALIDf)==0) {
   4811                 continue;
   4812             }
   4813         }
   4814 #if defined(BCM_TRIDENT3_SUPPORT)
   4815         if (soc_feature(unit, soc_feature_flex_flow)) {
   4816             key_type = -1;
   4817             for (i = 0; i < SOC_FLOW_DB_MAX_KEY_TYPE; i++) {
   4818                 if (SOC_MEM_FIELD_VALID(unit, egress_table, key_typef[i])) {
   4819                     key_type = soc_mem_field32_get(unit, egress_table,
   4820                                  egress_entry_data, key_typef[i]);
   4821                 }
   4822             }
   4823             data_type = -1;
   4824             for (i = 0; i < SOC_FLOW_DB_MAX_DATA_TYPE; i++) {
   4825                 if (SOC_MEM_FIELD_VALID(unit, egress_table, data_typef[i])) {
   4826                     data_type = soc_mem_field32_get(unit, egress_table,
   4827                                  egress_entry_data, data_typef[i]);
   4828                 }
   4829             }
   4830                 /* find the memory view based on the memory and key type */
   4831             if (soc_flow_db_mem_to_view_id_get (unit, egress_table,
   4832                                  key_type, data_type,
   4833                     0, NULL, (uint32 *)&mem_view_id) != SOC_E_NONE) {
   4834                 tmp_mem = egress_table;
   4835             } else {
   4836                 tmp_mem = mem_view_id;
   4837             }
   4838         }
   4839 #endif
   4840         if (egress_table == EGR_VFIm) {
   4841             object = bcmStatObjectEgrVfi;
   4842         } else if (egress_table == EGR_L3_NEXT_HOPm) {
   4843             object = bcmStatObjectEgrL3Intf;
   4844         } else
   4845 #if defined(BCM_TRIDENT3_SUPPORT)
   4846         if ((soc_feature(unit, soc_feature_flex_flow)) &&
   4847              (mem_view_id)) {
   4848             if (_bcm_esw_stat_flex_get_egress_object(unit, tmp_mem,
   4849                 index+min_index, egress_entry_data, &object)
   4850                 != BCM_E_NONE) {
   4851                 continue;
   4852             }
   4853         } else
   4854 #endif
   4855         {
   4856             if (_bcm_esw_stat_flex_get_egress_object(unit,egress_table,
   4857                 index+min_index,egress_entry_data,&object) != BCM_E_NONE) {
   4858                 continue;
   4859             }
   4860         }
   4861 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   4862         if (egress_table == EGR_IP_TUNNEL_MPLSm
   4863 #if defined(BCM_TRIDENT3_SUPPORT)
   4864             || egress_table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm
   4865 #endif
   4866            ) {
   4867             exact_index = (index + min_index)/
   4868                          _BCM_MPLS_NUM_MPLS_ENTRIES_PER_INDEX(unit);
   4869         } else
   4870 #endif
   4871         {
   4872             exact_index = index + min_index;
   4873         }
   4874 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   4875         if (egress_table == EGR_IP_TUNNEL_MPLSm) {
   4876             sal_memset(flex_entry_data,0,flex_entry_data_size);
   4877             if (soc_mem_read(unit,egress_table,MEM_BLOCK_ANY,
   4878                         _bcm_esw_stat_flex_table_index_map(unit,egress_table,
   4879                             exact_index),flex_entry_data) == SOC_E_NONE) {
   4880                 if (soc_mem_field_valid(unit,egress_table,VALIDf)) {
   4881                     if (soc_mem_field32_get(unit,egress_table,
   4882                                 flex_entry_data,VALIDf)==0) {
   4883                         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
   4884                                 (BSL_META_U(unit,
   4885                                             "Table %s  with index %d is Not valid \n"),
   4886                                  SOC_MEM_UFNAME(unit, egress_table),exact_index));
   4887                         sal_free(flex_entry_data);
   4888                         return;
   4889                     }
   4890                 }
   4891 
   4892                 _bcm_esw_get_flex_counter_fields_values(
   4893                         unit,index+min_index,egress_table,
   4894                         flex_entry_data,object,
   4895                         &offset_mode,&pool_number,&base_idx);
   4896                 if ((offset_mode == 0) && (base_idx == 0)) {
   4897                     continue;
   4898                 }
   4899             }
   4900         } else if (egress_table == EFP_POLICY_TABLEm
   4901 #if defined(BCM_TRIDENT3_SUPPORT)
   4902             || ((SOC_IS_TRIDENT3X(unit))
   4903             &&  (egress_table == EFP_POLICY_TABLE_PIPE0m
   4904             ||   egress_table == EFP_POLICY_TABLE_PIPE1m))
   4905 #endif
   4906             ) {
   4907             uint32 stat_dscp_select = 0;
   4908             if (SOC_MEM_FIELD_VALID(unit, egress_table, FLEX_COUNTER_DSCP_SELf)) {
   4909                soc_mem_field_get(unit, egress_table, egress_entry_data,
   4910                                  FLEX_COUNTER_DSCP_SELf, &stat_dscp_select);
   4911                if (stat_dscp_select == 0) {
   4912                     continue;
   4913                }
   4914             }
   4915             _bcm_esw_get_flex_counter_fields_values(
   4916                     unit, exact_index, egress_table,
   4917                     egress_entry_data, object,
   4918                     &offset_mode, &pool_number, &base_idx);
   4919             if ((offset_mode == 0) && (base_idx == 0)) {
   4920                 continue;
   4921             }
   4922         } else
   4923 #endif
   4924         {
   4925 #if defined(BCM_TRIDENT3_SUPPORT)
   4926             if (egress_table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm) {
   4927                 sal_memset(flex_entry_data, 0, flex_entry_data_size);
   4928                 if (soc_mem_read(unit, egress_table, MEM_BLOCK_ANY,
   4929                             _bcm_esw_stat_flex_table_index_map(unit, egress_table,
   4930                                 exact_index), flex_entry_data) == SOC_E_NONE) {
   4931                     if (soc_mem_field_valid(unit, egress_table, VALIDf)) {
   4932                         if (soc_mem_field32_get(unit, egress_table,
   4933                                     flex_entry_data, VALIDf) == 0) {
   4934                             LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
   4935                                     (BSL_META_U(unit,
   4936                                                 "Table %s  with index %d is Not valid \n"),
   4937                                      SOC_MEM_UFNAME(unit, egress_table), exact_index));
   4938                             sal_free(flex_entry_data);
   4939                             return;
   4940                         }
   4941                     }
   4942                     if (soc_mem_field_valid(unit, egress_table, DATA_TYPEf)) {
   4943                         data_type = soc_mem_field32_get(unit, egress_table,
   4944                                         flex_entry_data, DATA_TYPEf);
   4945                         /* Double Wide DATA_TYPE Check */
   4946                         if (data_type != 0x14) {
   4947                             continue;
   4948                         }
   4949                     }
   4950                 }
   4951                 _bcm_esw_get_flex_counter_fields_values(
   4952                         unit, index+min_index, egress_table,
   4953                         flex_entry_data, object,
   4954                         &offset_mode, &pool_number, &base_idx);
   4955             } else if (soc_feature(unit, soc_feature_flex_flow)) {
   4956                 _bcm_esw_get_flex_counter_fields_values(
   4957                         unit, exact_index, tmp_mem, egress_entry_data, object,
   4958                         &offset_mode, &pool_number, &base_idx);
   4959             } else
   4960 #endif
   4961             {
   4962                 _bcm_esw_get_flex_counter_fields_values(
   4963                     unit,exact_index,egress_table,
   4964                     egress_entry_data,object,
   4965                     &offset_mode,&pool_number,&base_idx);
   4966             }
   4967 
   4968             if ((offset_mode == 0) && (base_idx == 0)) {
   4969                 continue;
   4970             }
   4971         }
   4972         if (_bcm_esw_stat_flex_check_invalid_base_idx(unit,
   4973                                                       egress_table,
   4974                                                       pipe_num,
   4975                                                       pool_number,
   4976                                                       base_idx) != 0) {
   4977             continue;
   4978         }
   4979 
   4980         flex_base_index_reference_count[unit][bcmStatFlexDirectionEgress]
   4981                                        [pipe_num][pool_number][base_idx]++;
   4982 #if defined(BCM_TRIDENT2_SUPPORT)
   4983         if (SOC_IS_TRIDENT2X(unit) &&
   4984             soc_feature(unit, soc_feature_advanced_flex_counter)) {
   4985             _flex_stat_mode_base_map[unit][bcmStatFlexDirectionEgress]
   4986                                   [pool_number][offset_mode][base_idx] = 1;
   4987         }
   4988 #endif
   4989         if (flex_base_index_reference_count[unit][bcmStatFlexDirectionEgress]
   4990                                            [pipe_num][pool_number][base_idx] == 1) {
   4991             flex_egress_modes[unit][offset_mode].reference_count++;
   4992         }
   4993 #ifdef BCM_WARM_BOOT_SUPPORT
   4994 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   4995         if (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_7) &&
   4996             soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
   4997             (_bcm_esw_is_fp_table(egress_table))) {
   4998             uint32 cmode = 0;
   4999             bcm_error_t rv;
   5000             uint32 stat_counter_id = 0;
   5001 
   5002             rv = _bcm_esw_custom_stat_group_id_retrieve(unit, offset_mode,
   5003                         pipe_num, pool_number, base_idx, &stat_counter_id);
   5004             if (rv != BCM_E_NONE) {
   5005                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   5006                       (BSL_META_U(unit,
   5007                                   "Total counters %d\n"),
   5008                        flex_egress_modes[unit][offset_mode].
   5009                        total_counters));
   5010                 total_counters =
   5011                     flex_egress_modes[unit][offset_mode].total_counters;
   5012             } else {
   5013                 cmode = stat_counter_map[unit][stat_counter_id].mode;
   5014                 total_counters = flex_custom_egress_modes[unit]
   5015                     [cmode - BCM_CUSTOM_EGRESS_MODE_START].total_counters;
   5016             }
   5017         }else
   5018 #endif
   5019 #endif
   5020         {
   5021         if (flex_egress_modes[unit][offset_mode].total_counters == 0) {
   5022             flex_egress_modes[unit][offset_mode].total_counters =
   5023                    _bcm_esw_stat_flex_retrieve_total_counters(unit,
   5024                       bcmStatFlexDirectionEgress, pool_number, offset_mode);
   5025             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   5026                       (BSL_META_U(unit,
   5027                                       "Total counters %d\n"),
   5028                        flex_egress_modes[unit][offset_mode].
   5029                        total_counters));
   5030         }
   5031             total_counters =
   5032                 flex_egress_modes[unit][offset_mode].total_counters;
   5033         }
   5034 
   5035         if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
   5036             shr_aidxres_list_reserve(flex_aidxres_list_handle[unit]
   5037                     [bcmStatFlexDirectionEgress][pipe_num][pool_number],
   5038                     base_idx, base_idx + total_counters - 1);
   5039         } else {
   5040             shr_aidxres_list_reserve_block(
   5041                     flex_aidxres_list_handle
   5042                     [unit][bcmStatFlexDirectionEgress][pipe_num][pool_number],
   5043                     base_idx,
   5044                     total_counters);
   5045         }
   5046         flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number].
   5047                       used_entries += total_counters;
   5048         flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number].
   5049                       attached_entries += total_counters;
   5050         flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number].
   5051                       used_by_tables |= flex_used_by_table[object];
   5052         SHR_BITSET(flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num]
   5053                       [pool_number].used_by_objects, object);
   5054         /* Set pool bmap to enable Counters to perform DMA.
   5055          * Used in Centralized Counter model
   5056          */
   5057         counter_pool_bmap |= 1 << pool_number;
   5058         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   5059                   (BSL_META_U(unit,
   5060                               "Table:%s index=%d mode:%d pool_number:%d base_idx:%d\n"),
   5061                    SOC_MEM_UFNAME(unit, egress_table),
   5062                    index+min_index,offset_mode,pool_number,base_idx));
   5063         base_idx = 0, offset_mode = 0;
   5064     }
   5065     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
   5066     soc_cm_sfree(unit,egress_entry_full_data);
   5067 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5068     if (egress_table == EGR_IP_TUNNEL_MPLSm
   5069 #if defined(BCM_TRIDENT3_SUPPORT)
   5070         || egress_table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm
   5071 #endif
   5072     ) {
   5073         sal_free(flex_entry_data);
   5074     }
   5075 #endif
   5076     if (counter_pool_bmap) {
   5077         int rv = SOC_E_NONE;
   5078         rv = soc_counter_pool_bmap_status_set(unit, bcmStatFlexDirectionEgress,
   5079                                               counter_pool_bmap, 1);
   5080         if (rv != SOC_E_NONE) {
   5081            LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   5082                      (BSL_META_U(unit,
   5083                                  "Err when Enabling Pools for Counter DMA. "
   5084                                  "Egress Pool Bmap 0x%x\n"),
   5085                       counter_pool_bmap));
   5086         }
   5087     }
   5088     return;
   5089 }
   5090 #ifdef BCM_WARM_BOOT_SUPPORT
   5091 #if defined (BCM_TOMAHAWK_SUPPORT)
   5092 /*
   5093  * Function:
   5094  *      _bcm_esw_stat_flex_check_ingress_em_table_entry
   5095  * Description:
   5096  *      Checks flex Exact Match ingress table entry. 
   5097  * Parameters:
   5098  *      unit                  - (IN) unit number
   5099  *      ingress_table         - (IN) Flex Ingress  Table
   5100  *      offset_mode           - (IN) Flex offset_mode programmed in this entry
   5101  *      pool_number           - (IN) Flex pool_number programmed in this entry
   5102  *      base_idx              - (IN) Flex base idx programmed in this entry
   5103  * Return Value:
   5104  *      BCM_E_NONE
   5105  *      BCM_E_PARAM
   5106  * Notes:
   5107  *      Applicable in warm boot scenario only.
   5108  */
   5109 bcm_error_t
   5110 _bcm_esw_stat_flex_check_ingress_em_table_entry(
   5111     int               unit,
   5112     soc_mem_t         pipe_num,
   5113     _field_stage_id_t field_stage,
   5114     uint32            offset_mode,
   5115     uint32            pool_number,
   5116     uint32            base_idx)
   5117 {
   5118     bcm_stat_object_t object=bcmStatObjectIngExactMatch;
   5119     int rv = BCM_E_NONE;
   5120     uint32 counter_pool_bmap = 0; /* To enable counters */
   5121     uint32            total_counters = 0;
   5122 
   5123     BCM_STAT_FLEX_COUNTER_LOCK(unit);
   5124 
   5125         if ((offset_mode == 0) && (base_idx == 0)) {
   5126              BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
   5127              return BCM_E_PARAM;
   5128         }
   5129         flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress]
   5130                                        [pipe_num][pool_number][base_idx]++;
   5131         if (flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress]
   5132                                            [pipe_num][pool_number][base_idx] == 1) {
   5133             flex_ingress_modes[unit][offset_mode].reference_count++;
   5134         }
   5135 
   5136         total_counters = flex_ingress_modes[unit][offset_mode].total_counters;
   5137 
   5138         if (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_5) &&
   5139             soc_feature(unit, soc_feature_flex_counter_opaque_stat_id)) {
   5140             uint32 cmode = 0;
   5141             bcm_error_t rv;
   5142             uint32 stat_counter_id = 0;
   5143  
   5144             rv = _bcm_esw_custom_stat_group_id_retrieve(unit, offset_mode, pipe_num, 
   5145                                                         pool_number, base_idx,
   5146                                                         &stat_counter_id);
   5147             if (rv !=BCM_E_NONE) {
   5148                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   5149                       (BSL_META_U(unit,
   5150                                   "Invalid mode value %d %d %d\n"),
   5151                        offset_mode, pool_number, base_idx));
   5152             } else {
   5153                 cmode = stat_counter_map[unit][stat_counter_id].mode;
   5154                 total_counters = flex_custom_ingress_modes[unit][cmode - BCM_CUSTOM_INGRESS_MODE_START].
   5155                                                 total_counters;
   5156             }
   5157         }  else if (total_counters == 0) {
   5158             total_counters =
   5159                    _bcm_esw_stat_flex_retrieve_total_counters(
   5160                     unit, bcmStatFlexDirectionIngress,
   5161                     pool_number, offset_mode)  ;
   5162             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   5163                       (BSL_META_U(unit,
   5164                                   "Max_offset_table_value %d\n"),
   5165                        flex_ingress_modes[unit][offset_mode].
   5166                        total_counters));
   5167         }
   5168 
   5169         shr_aidxres_list_reserve_block(
   5170             flex_aidxres_list_handle[unit][bcmStatFlexDirectionIngress][pipe_num]
   5171                                     [pool_number],
   5172             base_idx,
   5173             total_counters);
   5174         flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num]
   5175                       [pool_number].used_entries +=
   5176                       total_counters;
   5177         flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num]
   5178                       [pool_number].attached_entries +=
   5179                       total_counters;
   5180         if ((_BCM_FIELD_STAGE_INGRESS == field_stage)) {
   5181             flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num][pool_number].
   5182                 used_by_tables |= FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE;
   5183         } else if (_BCM_FIELD_STAGE_EXACTMATCH == field_stage) {
   5184             flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num][pool_number].
   5185                 used_by_tables |= FLEX_COUNTER_POOL_USED_BY_EM_POLICY_TABLE;
   5186         } else {
   5187             return BCM_E_INTERNAL;
   5188         }
   5189         SHR_BITSET(flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num]
   5190                       [pool_number].used_by_objects, object);
   5191         if (pipe_num != 0) {
   5192             if ((_BCM_FIELD_STAGE_INGRESS == field_stage)) {
   5193                flex_pool_stat[unit][bcmStatFlexDirectionIngress][0][pool_number].
   5194                  used_by_tables |= FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE;
   5195             } else {
   5196                flex_pool_stat[unit][bcmStatFlexDirectionIngress][0][pool_number].
   5197                  used_by_tables |= FLEX_COUNTER_POOL_USED_BY_EM_POLICY_TABLE;
   5198             }
   5199             SHR_BITSET(flex_pool_stat[unit][bcmStatFlexDirectionIngress][0]
   5200                           [pool_number].used_by_objects, object);
   5201         }
   5202         /* Set pool bmap to enable Counters to perform DMA.
   5203          * Used in Centralized Counter model
   5204          */
   5205         counter_pool_bmap |= 1 << pool_number;
   5206     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
   5207 
   5208     if (counter_pool_bmap) {
   5209         int rv = SOC_E_NONE;
   5210         rv = soc_counter_pool_bmap_status_set(unit, bcmStatFlexDirectionIngress,
   5211                                               counter_pool_bmap, 1);
   5212         if (rv != SOC_E_NONE) {
   5213            LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   5214                      (BSL_META_U(unit,
   5215                                  "Err when Enabling Pools for Counter DMA. "
   5216                                  "EM Pool Bmap 0x%x\n"),
   5217                       counter_pool_bmap));
   5218         }
   5219     }
   5220     return rv;
   5221 }
   5222 #endif
   5223 #endif
   5224 
   5225 /*
   5226  * Function:
   5227  *      _bcm_esw_stat_flex_check_ingress_table
   5228  * Description:
   5229  *      Checkes flex ingress table. If table were configured for flex counter
   5230  *      updates s/w copy accordingly.
   5231  *
   5232  * Parameters:
   5233  *      unit                  - (IN) unit number
   5234  *      ingress_table         - (IN) Flex Ingress  Table
   5235  *      index                 - (IN) Flex Ingress  Table Index
   5236  * Return Value:
   5237  *      None
   5238  * Notes:
   5239  *      Applicable in warm boot scenario only.
   5240  */
   5241 static void
   5242 _bcm_esw_stat_flex_check_ingress_table(
   5243     int       unit,
   5244     soc_mem_t ingress_table,
   5245     int       min_index,
   5246     int       max_index)
   5247 {
   5248     uint32            offset_mode=0;
   5249     uint32            pool_number=0;
   5250     uint32            base_idx=0;
   5251     uint32            ingress_entry_data_size=0;
   5252     void              *ingress_entry_data=NULL;
   5253     void              *ingress_entry_full_data=NULL;
   5254     bcm_stat_object_t object=bcmStatObjectIngPort;
   5255     int               index=0;
   5256     int               pipe_num = 0;
   5257     uint32            allocate_group_type = BCM_FLEX_POOL_GROUP_USED_BY_NONE;
   5258     int               pool_group_id;
   5259     uint32            enable, used_by_table = 0;
   5260     uint32            counter_pool_bmap = 0; /* To enable counters */
   5261     uint32            total_counters = 0;
   5262 #if defined(BCM_TRIDENT3_SUPPORT)
   5263     uint32 key_typef[] = {KEY_TYPEf,
   5264                          KEY_TYPE0f,
   5265                          KEY_TYPE1f};
   5266     uint32 data_typef[] = {DATA_TYPEf,
   5267                           DATA_TYPE0f,
   5268                           DATA_TYPE1f};
   5269     int data_type = 0;
   5270     int key_type = 0;
   5271     uint32 mem_view_id = 0;
   5272     int i = 0;
   5273     soc_mem_t tmp_mem = INVALIDm;
   5274 #endif
   5275 
   5276 
   5277     if (!((ingress_table == PORT_TABm) ||
   5278           (ingress_table == VLAN_XLATEm)  ||
   5279 #if defined(BCM_TRIUMPH3_SUPPORT)
   5280           (ingress_table == VLAN_XLATE_EXTDm)  ||
   5281           (ingress_table == MPLS_ENTRY_EXTDm)  ||
   5282           (ingress_table == EXT_FP_POLICYm)    ||
   5283 #endif
   5284 #if defined(BCM_TRIDENT2_SUPPORT)
   5285           (ingress_table == ING_VSANm)  ||
   5286           (ingress_table == L3_ENTRY_IPV4_MULTICASTm)  ||
   5287           (ingress_table == L3_ENTRY_IPV6_MULTICASTm)  ||
   5288           (ingress_table == L3_DEFIPm) ||
   5289           (ingress_table == L3_DEFIP_PAIR_128m)  ||
   5290           (ingress_table == L3_DEFIP_ALPM_IPV4_1m) ||
   5291           (ingress_table == L3_DEFIP_ALPM_IPV6_64_1m)  ||
   5292           (ingress_table == L3_DEFIP_ALPM_IPV6_128m) ||
   5293           (ingress_table == L3_DEFIP_ALPM_RAWm) ||
   5294           (ingress_table == L3_DEFIP_LEVEL1m) ||
   5295           (ingress_table == L3_DEFIP_PAIR_LEVEL1m) ||
   5296           (ingress_table == L3_DEFIP_ALPM_LEVEL2m) ||
   5297           (ingress_table == L3_DEFIP_ALPM_LEVEL3m) ||
   5298           (ingress_table == FP_POLICY_TABLEm)  ||
   5299 #endif /* BCM_TRIDENT2_SUPPORT */
   5300 #if defined (BCM_TOMAHAWK_SUPPORT)
   5301           (ingress_table == IFP_POLICY_TABLEm)  ||
   5302           ((SOC_IS_TOMAHAWKX(unit)) &&
   5303             ((ingress_table == IFP_POLICY_TABLE_PIPE0m)  ||
   5304             (ingress_table == IFP_POLICY_TABLE_PIPE1m)  ||
   5305             (ingress_table == IFP_POLICY_TABLE_PIPE2m)  ||
   5306             (ingress_table == IFP_POLICY_TABLE_PIPE3m)  ||
   5307             (ingress_table == VFP_POLICY_TABLE_PIPE0m)  ||
   5308             (ingress_table == VFP_POLICY_TABLE_PIPE1m)  ||
   5309             (ingress_table == VFP_POLICY_TABLE_PIPE2m)  ||
   5310             (ingress_table == VFP_POLICY_TABLE_PIPE3m)  ||
   5311             (ingress_table == IFP_POLICY_TABLE_PIPE4m)  ||
   5312             (ingress_table == IFP_POLICY_TABLE_PIPE5m)  ||
   5313             (ingress_table == IFP_POLICY_TABLE_PIPE6m)  ||
   5314             (ingress_table == IFP_POLICY_TABLE_PIPE7m)  ||
   5315             (ingress_table == VFP_POLICY_TABLE_PIPE4m)  ||
   5316             (ingress_table == VFP_POLICY_TABLE_PIPE5m)  ||
   5317             (ingress_table == VFP_POLICY_TABLE_PIPE6m)  ||
   5318             (ingress_table == VFP_POLICY_TABLE_PIPE7m)  ||
   5319             (ingress_table == AGM_MONITOR_TABLEm)))  ||
   5320 #endif
   5321 #if defined (BCM_TOMAHAWK3_SUPPORT)
   5322         ((SOC_IS_TOMAHAWK3(unit)) &&
   5323           ((ingress_table == LPORT_TABm)  ||
   5324            (ingress_table == L3_ENTRY_QUADm)  ||
   5325            (ingress_table == L3_ENTRY_DOUBLEm)  ||
   5326            (ingress_table == MPLS_ENTRY_SINGLEm)))  ||
   5327 #endif
   5328 #if defined (BCM_TRIDENT3_SUPPORT)
   5329         ((SOC_IS_TRIDENT3X(unit)) &&
   5330           ((ingress_table == VLAN_XLATE_1_DOUBLEm)  ||
   5331           (ingress_table == VLAN_XLATE_2_DOUBLEm)  ||
   5332           (ingress_table == LPORT_TABm)  ||
   5333           (ingress_table == L3_ENTRY_QUADm)  ||
   5334           (ingress_table == L3_ENTRY_DOUBLEm)  ||
   5335           (ingress_table == IFP_POLICY_TABLE_PIPE0m)  ||
   5336           (ingress_table == IFP_POLICY_TABLE_PIPE1m)  ||
   5337           (ingress_table == IFP_POLICY_TABLE_WIDE_PIPE0m)  ||
   5338           (ingress_table == IFP_POLICY_TABLE_WIDE_PIPE1m)  ||
   5339           (ingress_table == IFP_POLICY_TABLE_WIDEm)  ||
   5340           (ingress_table == VFP_POLICY_TABLE_PIPE0m)  ||
   5341           (ingress_table == VFP_POLICY_TABLE_PIPE1m)  ||
   5342           (ingress_table == AGM_MONITOR_TABLEm) ||
   5343           (ingress_table == VRF_ATTRS_2m)))  ||
   5344 #endif
   5345           (ingress_table == VFP_POLICY_TABLEm)  ||
   5346           (ingress_table == MPLS_ENTRYm)  ||
   5347           (ingress_table == SOURCE_VPm)  ||
   5348           (ingress_table == L3_IIFm)  ||
   5349           (ingress_table == VRFm)  ||
   5350           (ingress_table == VFIm)  ||
   5351           (ingress_table == VLAN_TABm))) {
   5352            LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   5353                      (BSL_META_U(unit,
   5354                                  "Invalid Flex Counter Ingress Memory %s\n"),
   5355                       SOC_MEM_UFNAME(unit, ingress_table)));
   5356            return;
   5357     }
   5358 
   5359 #if defined (BCM_TOMAHAWK_SUPPORT)
   5360     pipe_num = _bcm_esw_get_fp_pipe_num(unit, ingress_table);
   5361 #endif
   5362 
   5363     if (!SOC_MEM_IS_VALID(unit, ingress_table)) {
   5364         /* This check is for low latency mode */
   5365         return; 
   5366     }
   5367     if (soc_mem_index_max(unit, ingress_table) < 0) {
   5368         return;
   5369     }
   5370 
   5371     ingress_entry_data_size = WORDS2BYTES(BYTES2WORDS(
   5372                               SOC_MEM_INFO(unit, ingress_table).bytes));
   5373     if (max_index > soc_mem_index_max(unit,ingress_table)) {
   5374         max_index = soc_mem_index_max(unit,ingress_table);
   5375     }
   5376 
   5377     ingress_entry_full_data = soc_cm_salloc(unit,ingress_entry_data_size *
   5378                                   (max_index - min_index + 1),"ingress_table");
   5379     if (ingress_entry_full_data == NULL) {
   5380         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   5381                   (BSL_META_U(unit,
   5382                               "Failed to allocate memory for Table:%s "),
   5383                    SOC_MEM_UFNAME(unit, ingress_table)));
   5384         return ;
   5385     }
   5386     sal_memset(ingress_entry_full_data,0,(ingress_entry_data_size *
   5387                                   (max_index - min_index + 1)));
   5388 
   5389     if (soc_mem_read_range(unit, ingress_table, MEM_BLOCK_ANY,
   5390                 min_index,max_index, ingress_entry_full_data) != SOC_E_NONE) {
   5391         soc_cm_sfree(unit,ingress_entry_full_data);
   5392         return ;
   5393     }
   5394 
   5395     BCM_STAT_FLEX_COUNTER_LOCK(unit);
   5396 
   5397    for(index=0; index <= (max_index - min_index) ; index++) {
   5398        bcm_error_t rv = BCM_E_NONE;
   5399        ingress_entry_data = soc_mem_table_idx_to_pointer(unit, ingress_table,
   5400                             void *, ingress_entry_full_data, index);
   5401         if (soc_mem_field_valid(unit,ingress_table,VALIDf)) {
   5402             if (soc_mem_field32_get(unit,ingress_table,ingress_entry_data,
   5403                 VALIDf)==0) {
   5404                 continue;
   5405             }
   5406         }
   5407 #if defined(BCM_TRIUMPH3_SUPPORT)
   5408         if (SOC_IS_TRIUMPH3(unit)) {
   5409             if (soc_mem_field_valid(unit,ingress_table,VALID_0f)) {
   5410                 if (soc_mem_field32_get(unit,ingress_table,ingress_entry_data,
   5411                     VALID_0f)==0) {
   5412                     continue;
   5413                 }
   5414             }
   5415             if (soc_mem_field_valid(unit,ingress_table,VALID_1f)) {
   5416                 if (soc_mem_field32_get(unit,ingress_table,ingress_entry_data,
   5417                     VALID_1f)==0) {
   5418                     continue;
   5419                 }
   5420             }
   5421         }
   5422 #endif
   5423 #if defined(BCM_TRIDENT3_SUPPORT)
   5424         if (ingress_table == MPLS_ENTRYm &&
   5425             soc_feature(unit, soc_feature_vxlan_decoupled_mode)) {
   5426             key_type = soc_mem_field32_get(unit, ingress_table,
   5427                 ingress_entry_data, KEY_TYPEf);
   5428             if (key_type == _BCM_VXLAN_KEY_TYPE_LOOKUP_DIP_IN_MPLS_ENTRY) {
   5429                 ingress_table = MPLS_ENTRY_SINGLEm;
   5430             }
   5431         }
   5432 
   5433         if (soc_feature(unit, soc_feature_flex_flow)) {
   5434             key_type = -1;
   5435             for (i = 0; i < SOC_FLOW_DB_MAX_KEY_TYPE; i++) {
   5436                 if (SOC_MEM_FIELD_VALID(unit, ingress_table, key_typef[i])) {
   5437                     key_type = soc_mem_field32_get(unit, ingress_table,
   5438                                  ingress_entry_data, key_typef[i]);
   5439                 }
   5440             }
   5441             data_type = -1;
   5442             for (i = 0; i < SOC_FLOW_DB_MAX_DATA_TYPE; i++) {
   5443                 if (SOC_MEM_FIELD_VALID(unit, ingress_table, data_typef[i])) {
   5444                     data_type = soc_mem_field32_get(unit, ingress_table,
   5445                                  ingress_entry_data, data_typef[i]);
   5446                 }
   5447             }
   5448             /* find the memory view based on the memory and key type
   5449              * If not found, try fix view, else try flex view.
   5450              */
   5451             if (soc_flow_db_mem_to_view_id_get (unit, ingress_table,
   5452                                                key_type, data_type,
   5453                     0, NULL, (uint32 *)&mem_view_id) != SOC_E_NONE) {
   5454                 tmp_mem = ingress_table;
   5455             } else {
   5456                 tmp_mem = mem_view_id;
   5457             }
   5458             rv = _bcm_esw_get_flex_counter_fields_values(
   5459                  unit,index+min_index, tmp_mem,ingress_entry_data,0,
   5460                  &offset_mode,&pool_number,&base_idx);
   5461             if (rv != BCM_E_NONE) {
   5462                 continue;
   5463             }
   5464         } else
   5465 #endif
   5466         {
   5467             rv = _bcm_esw_get_flex_counter_fields_values(
   5468                unit,index+min_index,ingress_table,ingress_entry_data,0,
   5469                &offset_mode,&pool_number,&base_idx);
   5470             if (rv != BCM_E_NONE) {
   5471                 continue;
   5472             }
   5473         }
   5474         if ((offset_mode == 0) && (base_idx == 0)) {
   5475              continue;
   5476         }
   5477         if (_bcm_esw_stat_flex_check_invalid_base_idx(unit,
   5478                                                       ingress_table,
   5479                                                       pipe_num,
   5480                                                       pool_number,
   5481                                                       base_idx) != 0) {
   5482             continue;
   5483         }
   5484 
   5485         /* object for these two tables rely on virtual module which is not
   5486          * initialized yet, For the purpose here, just need to find any
   5487          * valid object using the table
   5488          */
   5489         if (ingress_table == SOURCE_VPm) {
   5490             object = bcmStatObjectIngMplsVcLabel;
   5491         } else if (ingress_table == VFIm) {
   5492             object = bcmStatObjectIngVfi;
   5493         } else
   5494 #if defined(BCM_TRIDENT3_SUPPORT)
   5495         if ((soc_feature(unit, soc_feature_flex_flow)) &&
   5496             (mem_view_id)) {
   5497             if (_bcm_esw_stat_flex_get_ingress_object(
   5498                 unit, tmp_mem, index+min_index, ingress_entry_data,
   5499                 &object)
   5500                 !=BCM_E_NONE) {
   5501                 continue;
   5502             }
   5503         } else
   5504 #endif /* BCM_TRIDENT3_SUPPORT */
   5505         {
   5506             if (_bcm_esw_stat_flex_get_ingress_object(
   5507                      unit, ingress_table, index+min_index,
   5508                      ingress_entry_data, &object)
   5509                      !=BCM_E_NONE) {
   5510                 continue;
   5511             }
   5512         }
   5513         flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress]
   5514                                        [pipe_num][pool_number][base_idx]++;
   5515 #if defined(BCM_TRIDENT2_SUPPORT)
   5516         if (SOC_IS_TRIDENT2X(unit) &&
   5517             soc_feature(unit, soc_feature_advanced_flex_counter)) {
   5518             _flex_stat_mode_base_map[unit][bcmStatFlexDirectionIngress]
   5519                                   [pool_number][offset_mode][base_idx] = 1;
   5520         }
   5521 #endif
   5522         if (flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress]
   5523                                            [pipe_num][pool_number][base_idx] == 1) {
   5524             flex_ingress_modes[unit][offset_mode].reference_count++;
   5525         }
   5526 #ifdef BCM_WARM_BOOT_SUPPORT
   5527 #if defined (BCM_TOMAHAWK_SUPPORT)
   5528         if (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_5) &&
   5529             soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
   5530             (_bcm_esw_is_fp_table(ingress_table))) {
   5531             uint32 cmode = 0;
   5532             bcm_error_t rv;
   5533             uint32 stat_counter_id = 0;
   5534  
   5535             rv = _bcm_esw_custom_stat_group_id_retrieve(unit, offset_mode, pipe_num, 
   5536                                                         pool_number, base_idx,
   5537                                                         &stat_counter_id);
   5538             if (rv !=BCM_E_NONE) {
   5539                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   5540                       (BSL_META_U(unit,
   5541                                   "Invalid mode value %d %d %d\n"),
   5542                        offset_mode, pool_number, base_idx));
   5543                 total_counters = flex_ingress_modes[unit][offset_mode].total_counters;
   5544             } else {
   5545                 cmode = stat_counter_map[unit][stat_counter_id].mode;
   5546                 total_counters = flex_custom_ingress_modes[unit][cmode - BCM_CUSTOM_INGRESS_MODE_START].
   5547                                                 total_counters;
   5548             }
   5549         } else
   5550 #endif
   5551 #endif
   5552         {
   5553             if (flex_ingress_modes[unit][offset_mode].total_counters == 0) {
   5554                 flex_ingress_modes[unit][offset_mode].total_counters =
   5555                        _bcm_esw_stat_flex_retrieve_total_counters(
   5556                         unit, bcmStatFlexDirectionIngress,
   5557                         pool_number, offset_mode)  ;
   5558                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   5559                           (BSL_META_U(unit,
   5560                                       "Max_offset_table_value %d\n"),
   5561                            flex_ingress_modes[unit][offset_mode].
   5562                            total_counters));
   5563             }
   5564             total_counters = flex_ingress_modes[unit][offset_mode].total_counters;
   5565         }
   5566 
   5567         if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
   5568             pool_group_id = pool_number/_bcm_esw_get_max_pool_groups(unit);
   5569             /* Update the Flex flex_pool_group for oam_lm  for TD2Plus*/
   5570             enable = 0;
   5571             if (!BCM_FAILURE(_bcm_esw_stat_flex_ingress_group_oam_status
   5572                                               (unit, pool_group_id,
   5573                                               &enable))) {
   5574                 if (enable ) {
   5575                     allocate_group_type = BCM_FLEX_POOL_GROUP_USED_BY_OAM;
   5576                 } else {                                      
   5577                     allocate_group_type = BCM_FLEX_POOL_GROUP_USED_BY_OTHER;
   5578                 }                                             
   5579                 /* Update the pool_group type */      
   5580                 flex_pool_group[unit][pipe_num][pool_group_id].group_type 
   5581                                                      = allocate_group_type;
   5582             }
   5583             if (flex_pool_stat[unit][bcmStatFlexDirectionIngress]
   5584                           [0][pool_number].used_by_tables == 0) {
   5585                 flex_pool_group[unit][pipe_num][pool_group_id].free_pools--;
   5586             }
   5587         }
   5588         if (shr_aidxres_list_elem_state(flex_aidxres_list_handle[unit]
   5589                                          [bcmStatFlexDirectionIngress]
   5590                                          [pipe_num]
   5591                                          [pool_number],
   5592                                          base_idx) != BCM_E_EXISTS) {
   5593             if (total_counters) {
   5594                 if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
   5595                     shr_aidxres_list_reserve(flex_aidxres_list_handle[unit]
   5596                             [bcmStatFlexDirectionIngress][pipe_num][pool_number],
   5597                             base_idx, base_idx + total_counters - 1);
   5598                 } else {
   5599                     shr_aidxres_list_reserve_block(
   5600                             flex_aidxres_list_handle[unit][bcmStatFlexDirectionIngress]
   5601                             [pipe_num]
   5602                             [pool_number],
   5603                             base_idx,
   5604                             total_counters);
   5605                 }
   5606                 flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num]
   5607                     [pool_number].used_entries +=
   5608                     total_counters;
   5609             }
   5610         }
   5611         switch(ingress_table) {
   5612 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   5613             case FP_POLICY_TABLEm:
   5614                  used_by_table = FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE;
   5615                  break;
   5616 #endif
   5617 #if defined(BCM_TOMAHAWK_SUPPORT)
   5618             case VFP_POLICY_TABLEm:
   5619             case VFP_POLICY_TABLE_PIPE0m:
   5620             case VFP_POLICY_TABLE_PIPE1m:
   5621             case VFP_POLICY_TABLE_PIPE2m:
   5622             case VFP_POLICY_TABLE_PIPE3m:
   5623             case VFP_POLICY_TABLE_PIPE4m:
   5624             case VFP_POLICY_TABLE_PIPE5m:
   5625             case VFP_POLICY_TABLE_PIPE6m:
   5626             case VFP_POLICY_TABLE_PIPE7m:
   5627                  used_by_table = FLEX_COUNTER_POOL_USED_BY_VFP_POLICY_TABLE;
   5628                  break;
   5629             case IFP_POLICY_TABLEm:
   5630             case IFP_POLICY_TABLE_PIPE0m:
   5631             case IFP_POLICY_TABLE_PIPE1m:
   5632             case IFP_POLICY_TABLE_PIPE2m:
   5633             case IFP_POLICY_TABLE_PIPE3m:
   5634             case IFP_POLICY_TABLE_PIPE4m:
   5635             case IFP_POLICY_TABLE_PIPE5m:
   5636             case IFP_POLICY_TABLE_PIPE6m:
   5637             case IFP_POLICY_TABLE_PIPE7m:
   5638                  used_by_table = FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE;
   5639                  break;
   5640 #endif
   5641             default:
   5642                  used_by_table = flex_used_by_table[object];
   5643                  break;
   5644         }
   5645         flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num]
   5646                       [pool_number].attached_entries +=
   5647                       total_counters;
   5648         flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num][pool_number].
   5649                       used_by_tables |= used_by_table;
   5650         SHR_BITSET(flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num]
   5651                       [pool_number].used_by_objects, object);
   5652         if (pipe_num != 0) {
   5653             flex_pool_stat[unit][bcmStatFlexDirectionIngress][0][pool_number].
   5654                           used_by_tables |= used_by_table;
   5655             SHR_BITSET(flex_pool_stat[unit][bcmStatFlexDirectionIngress][0]
   5656                           [pool_number].used_by_objects, object);
   5657         }
   5658 
   5659         /* Set pool bmap to enable Counters to perform DMA.
   5660          * Used in Centralized Counter model
   5661          */
   5662         counter_pool_bmap |= 1 << pool_number;
   5663         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   5664                   (BSL_META_U(unit,
   5665                               "Table:%s:index=%d mode:%d pool_number:%d base_idx:%d\n"),
   5666                    SOC_MEM_UFNAME(unit, ingress_table),
   5667                    index+min_index,offset_mode,pool_number, base_idx));
   5668 #if defined(BCM_TOMAHAWK_SUPPORT)
   5669         if (SOC_IS_TOMAHAWKX(unit)) {
   5670             if ((IFP_POLICY_TABLEm == ingress_table) ||
   5671                 (IFP_POLICY_TABLE_PIPE0m == ingress_table) ||
   5672                 (IFP_POLICY_TABLE_PIPE1m == ingress_table) ||
   5673                 (IFP_POLICY_TABLE_PIPE2m == ingress_table) ||
   5674                 (IFP_POLICY_TABLE_PIPE3m == ingress_table) ||
   5675                 (IFP_POLICY_TABLE_PIPE4m == ingress_table) ||
   5676                 (IFP_POLICY_TABLE_PIPE5m == ingress_table) ||
   5677                 (IFP_POLICY_TABLE_PIPE6m == ingress_table) ||
   5678                 (IFP_POLICY_TABLE_PIPE7m == ingress_table)) {
   5679 
   5680 
   5681                 uint32 count, index;
   5682                 _bcm_ifp_color_map_t  color_map;
   5683                 soc_field_t color_fields[BCM_MAX_IFP_COLORS] = {G_COUNTf,
   5684                                                                 Y_COUNTf,
   5685                                                                 R_COUNTf};
   5686                 uint8 color_map_mask[BCM_MAX_IFP_COLORS] = {BCM_STAT_FLEX_COLOR_GREEN,
   5687                                                             BCM_STAT_FLEX_COLOR_YELLOW,
   5688                                                             BCM_STAT_FLEX_COLOR_RED};
   5689                 bcm_error_t rv;
   5690                 sal_memset(&color_map, 0, sizeof(_bcm_ifp_color_map_t));
   5691                 for (index = 0; index < BCM_MAX_IFP_COLORS; index++) {
   5692                      soc_IFP_POLICY_TABLEm_field_get(unit, ingress_entry_data,
   5693                                                      color_fields[index], &count);
   5694                     if (count > 0 && count <= BCM_MAX_IFP_COLOR_COUNTERS) {
   5695                         /* count -1 is used to index the color_map array because
   5696                          * the value 0 is reserved by hardware to indicate "do
   5697                          * not count"
   5698                          */
   5699                         color_map.map[count - 1] |= color_map_mask[index];
   5700                     }
   5701                 }
   5702                 rv = _bcm_esw_ifp_wb_color_map_set(unit, pool_number, base_idx, pipe_num, offset_mode, &color_map);
   5703                 if (BCM_FAILURE(rv)) {
   5704                     LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   5705                               (BSL_META_U(unit,
   5706                                           "Unable to reconstruct ifp color map for"
   5707                                           " policy table index - %d, pool - %d"
   5708                                           " offset_mode - %d, base idx - %d"),
   5709                                index + min_index, pool_number, offset_mode,
   5710                                base_idx));
   5711                 }
   5712             }
   5713     }
   5714 #endif
   5715     }
   5716 
   5717     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
   5718     soc_cm_sfree(unit,ingress_entry_full_data);
   5719 
   5720     if (counter_pool_bmap) {
   5721         int rv = SOC_E_NONE;
   5722         rv = soc_counter_pool_bmap_status_set(unit, bcmStatFlexDirectionIngress,
   5723                                               counter_pool_bmap, 1);
   5724         if (rv != SOC_E_NONE) {
   5725            LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   5726                      (BSL_META_U(unit,
   5727                                  "Err when Enabling Pools for Counter DMA. "
   5728                                  "Ingress Pool Bmap 0x%x\n"),
   5729                       counter_pool_bmap));
   5730         }
   5731     }
   5732     return;
   5733 }
   5734 /*
   5735  * Function:
   5736  *      _bcm_esw_stat_flex_init_uncmprsd_mode
   5737  * Description:
   5738  *      Configures flex hw for uncompressed mode
   5739  * Parameters:
   5740  *      unit                           - (IN) unit number
   5741  *      mode                           - (IN) Flex Offset Mode
   5742  *      direction                      - (IN) Flex Data flow direction(ing/egr)
   5743  *      selector_count                 - (IN) Flex Key selector count
   5744  *      selector_x_en_field_value      - (IN) Flex Key selector fields
   5745  *      selector_for_bit_x_field_value - (IN) Flex Key selector field bits
   5746  *
   5747  * Return Value:
   5748  *      None
   5749  * Notes:
   5750  */
   5751 static void
   5752 _bcm_esw_stat_flex_init_uncmprsd_mode(
   5753     int                       unit,
   5754     int                       mode,
   5755     bcm_stat_flex_direction_t direction,
   5756     uint32                    selector_count,
   5757     uint32                    selector_x_en_field_value[8],
   5758     uint32                    selector_for_bit_x_field_value[8])
   5759 {
   5760     uint32  uncmprsd_attr_bits_selector=0;
   5761     uint32  index=0;
   5762 
   5763     if (direction == bcmStatFlexDirectionIngress) {
   5764         flex_ingress_modes[unit][mode].available=1;
   5765         /*Will be changed WhileReadingTables */
   5766         flex_ingress_modes[unit][mode].reference_count=0;
   5767         /* selector_count can not be used for deciding total counters !!! */
   5768         /* flex_ingress_modes[unit][mode].total_counters=(1<< selector_count);*/
   5769         flex_ingress_modes[unit][mode].ing_attr.packet_attr_type =
   5770             bcmStatFlexPacketAttrTypeUncompressed;
   5771         for (uncmprsd_attr_bits_selector=0,index=0;index<8;index++) {
   5772              if(selector_x_en_field_value[index] != 0) {
   5773                 if ((selector_for_bit_x_field_value[index] >=
   5774                      ing_pkt_attr_uncmprsd_bits_g[unit].ip_pkt_pos) &&
   5775                     (selector_for_bit_x_field_value[index] <=
   5776                       (ing_pkt_attr_uncmprsd_bits_g[unit].ip_pkt_pos+
   5777                        ing_pkt_attr_uncmprsd_bits_g[unit].ip_pkt-1))) { /* 0..0 */
   5778                     uncmprsd_attr_bits_selector |=
   5779                       BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_IP_PKT_ATTR_BITS;
   5780                     continue;
   5781                 }
   5782                 if ((selector_for_bit_x_field_value[index] >=
   5783                      ing_pkt_attr_uncmprsd_bits_g[unit].drop_pos) &&
   5784                     (selector_for_bit_x_field_value[index] <=
   5785                       (ing_pkt_attr_uncmprsd_bits_g[unit].drop_pos+
   5786                        ing_pkt_attr_uncmprsd_bits_g[unit].drop-1))) { /* 1..1 */
   5787                     uncmprsd_attr_bits_selector |=
   5788                       BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_DROP_ATTR_BITS;
   5789                     continue;
   5790                 }
   5791                 if ((selector_for_bit_x_field_value[index] >=
   5792                      ing_pkt_attr_uncmprsd_bits_g[unit].svp_type_pos) &&
   5793                     (selector_for_bit_x_field_value[index] <=
   5794                       (ing_pkt_attr_uncmprsd_bits_g[unit].svp_type_pos+
   5795                        ing_pkt_attr_uncmprsd_bits_g[unit].svp_type-1))) { /* 3..8 */
   5796                     uncmprsd_attr_bits_selector |=
   5797                       BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_SVP_TYPE_ATTR_BITS;
   5798                     continue;
   5799                 }
   5800                 if ((selector_for_bit_x_field_value[index] >=
   5801                      ing_pkt_attr_uncmprsd_bits_g[unit].pkt_resolution_pos) &&
   5802                     (selector_for_bit_x_field_value[index] <=
   5803                       (ing_pkt_attr_uncmprsd_bits_g[unit].pkt_resolution_pos+
   5804                        ing_pkt_attr_uncmprsd_bits_g[unit].pkt_resolution-1))) { /* 3..8 */
   5805                      uncmprsd_attr_bits_selector|=
   5806                    BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS;
   5807                      continue;
   5808                 }
   5809                 if ((selector_for_bit_x_field_value[index] >=
   5810                      ing_pkt_attr_uncmprsd_bits_g[unit].tos_dscp_pos) &&
   5811                     (selector_for_bit_x_field_value[index] <=
   5812                      (ing_pkt_attr_uncmprsd_bits_g[unit].tos_dscp_pos+ing_pkt_attr_uncmprsd_bits_g[unit].tos_dscp-1))) {
   5813                      /* 9..16 */
   5814                      uncmprsd_attr_bits_selector|=
   5815                        BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_TOS_DSCP_ATTR_BITS;
   5816                      continue;
   5817                 }
   5818                 if ((selector_for_bit_x_field_value[index] >=
   5819                      ing_pkt_attr_uncmprsd_bits_g[unit].tos_ecn_pos) &&
   5820                     (selector_for_bit_x_field_value[index] <=
   5821                      (ing_pkt_attr_uncmprsd_bits_g[unit].tos_ecn_pos+ing_pkt_attr_uncmprsd_bits_g[unit].tos_ecn-1))) {
   5822                      /* 9..16 */
   5823                      uncmprsd_attr_bits_selector|=
   5824                        BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_TOS_ECN_ATTR_BITS;
   5825                      continue;
   5826                 }
   5827                 if ((selector_for_bit_x_field_value[index] >=
   5828                      ing_pkt_attr_uncmprsd_bits_g[unit].ing_port_pos) &&
   5829                     (selector_for_bit_x_field_value[index] <=
   5830                      (ing_pkt_attr_uncmprsd_bits_g[unit].ing_port_pos+
   5831                       ing_pkt_attr_uncmprsd_bits_g[unit].ing_port-1))) { /* 17 .. 22 */
   5832                      uncmprsd_attr_bits_selector|=
   5833                       BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_INGRESS_PORT_ATTR_BITS;
   5834                      continue;
   5835                 }
   5836                 if ((selector_for_bit_x_field_value[index] >=
   5837                      ing_pkt_attr_uncmprsd_bits_g[unit].inner_dot1p_pos) &&
   5838                     (selector_for_bit_x_field_value[index] <=
   5839                      (ing_pkt_attr_uncmprsd_bits_g[unit].inner_dot1p_pos +
   5840                       ing_pkt_attr_uncmprsd_bits_g[unit].inner_dot1p - 1))) { /* 23..25 */
   5841                      uncmprsd_attr_bits_selector|=
   5842                        BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_INNER_DOT1P_ATTR_BITS;
   5843                      continue;
   5844                 }
   5845                 if ((selector_for_bit_x_field_value[index] >=
   5846                      ing_pkt_attr_uncmprsd_bits_g[unit].outer_dot1p_pos) &&
   5847                     (selector_for_bit_x_field_value[index] <=
   5848                      (ing_pkt_attr_uncmprsd_bits_g[unit].outer_dot1p_pos +
   5849                       ing_pkt_attr_uncmprsd_bits_g[unit].outer_dot1p - 1))) { /* 26..28 */
   5850                      uncmprsd_attr_bits_selector|=
   5851                        BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_OUTER_DOT1P_ATTR_BITS;
   5852                      continue;
   5853                 }
   5854                 if ((selector_for_bit_x_field_value[index] >=
   5855                      ing_pkt_attr_uncmprsd_bits_g[unit].vlan_format_pos) &&
   5856                     (selector_for_bit_x_field_value[index] <=
   5857                      (ing_pkt_attr_uncmprsd_bits_g[unit].vlan_format_pos +
   5858                       ing_pkt_attr_uncmprsd_bits_g[unit].vlan_format - 1))) { /* 29..30 */
   5859                      uncmprsd_attr_bits_selector|=
   5860                        BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_VLAN_FORMAT_ATTR_BITS;
   5861                      continue;
   5862                 }
   5863                 if ((selector_for_bit_x_field_value[index] >=
   5864                      ing_pkt_attr_uncmprsd_bits_g[unit].int_pri_pos) &&
   5865                     (selector_for_bit_x_field_value[index] <=
   5866                      (ing_pkt_attr_uncmprsd_bits_g[unit].int_pri_pos +
   5867                       ing_pkt_attr_uncmprsd_bits_g[unit].int_pri -1))) { /* 31 .. 34 */
   5868                      uncmprsd_attr_bits_selector|=
   5869                        BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_INT_PRI_ATTR_BITS;
   5870                     continue;
   5871                 }
   5872                 if ((selector_for_bit_x_field_value[index] >=
   5873                      ing_pkt_attr_uncmprsd_bits_g[unit].ifp_cng_pos ) &&
   5874                     (selector_for_bit_x_field_value[index] <=
   5875                      (ing_pkt_attr_uncmprsd_bits_g[unit].ifp_cng_pos +
   5876                      ing_pkt_attr_uncmprsd_bits_g[unit].ifp_cng - 1))) { /* 35..36 */
   5877                      uncmprsd_attr_bits_selector|=
   5878                        BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_IFP_CNG_ATTR_BITS;
   5879                      continue;
   5880                 }
   5881                 if ((selector_for_bit_x_field_value[index] >=
   5882                      ing_pkt_attr_uncmprsd_bits_g[unit].cng_pos) &&
   5883                     (selector_for_bit_x_field_value[index] <=
   5884                      (ing_pkt_attr_uncmprsd_bits_g[unit].cng_pos +
   5885                       ing_pkt_attr_uncmprsd_bits_g[unit].cng - 1))) { /* 37 .. 38 */
   5886                      uncmprsd_attr_bits_selector|=
   5887                        BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_CNG_ATTR_BITS;
   5888                      continue;
   5889                 }
   5890 #ifdef BCM_APACHE_SUPPORT
   5891                 if (soc_feature(unit,soc_feature_flex_ctr_mpls_3_label_count)) {
   5892                     if ((selector_for_bit_x_field_value[index] >=
   5893                                 ing_pkt_attr_uncmprsd_bits_g[unit].phb_1_pos) &&
   5894                             (selector_for_bit_x_field_value[index] <=
   5895                              (ing_pkt_attr_uncmprsd_bits_g[unit].phb_1_pos +
   5896                               ing_pkt_attr_uncmprsd_bits_g[unit].phb_1 - 1))) { /* 42 .. 45 */
   5897                         uncmprsd_attr_bits_selector |=
   5898                             BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_PHB_1_ATTR_BITS;
   5899                         continue;
   5900                     }
   5901                     if ((selector_for_bit_x_field_value[index] >=
   5902                                 ing_pkt_attr_uncmprsd_bits_g[unit].cng_1_pos) &&
   5903                             (selector_for_bit_x_field_value[index] <=
   5904                              (ing_pkt_attr_uncmprsd_bits_g[unit].cng_1_pos +
   5905                               ing_pkt_attr_uncmprsd_bits_g[unit].cng_1 - 1))) { /* 46 .. 47 */
   5906                         uncmprsd_attr_bits_selector |=
   5907                             BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_CNG_1_ATTR_BITS;
   5908                         continue;
   5909                     }
   5910                     if ((selector_for_bit_x_field_value[index] >=
   5911                                 ing_pkt_attr_uncmprsd_bits_g[unit].phb_2_pos) &&
   5912                             (selector_for_bit_x_field_value[index] <=
   5913                              (ing_pkt_attr_uncmprsd_bits_g[unit].phb_2_pos +
   5914                               ing_pkt_attr_uncmprsd_bits_g[unit].phb_2 - 1))) { /* 48 .. 51 */
   5915                         uncmprsd_attr_bits_selector |=
   5916                             BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_PHB_2_ATTR_BITS;
   5917                         continue;
   5918                     }
   5919                     if ((selector_for_bit_x_field_value[index] >=
   5920                                 ing_pkt_attr_uncmprsd_bits_g[unit].cng_2_pos) &&
   5921                             (selector_for_bit_x_field_value[index] <=
   5922                              (ing_pkt_attr_uncmprsd_bits_g[unit].cng_2_pos +
   5923                               ing_pkt_attr_uncmprsd_bits_g[unit].cng_2 - 1))) { /* 52 .. 53 */
   5924                         uncmprsd_attr_bits_selector |=
   5925                             BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_CNG_2_ATTR_BITS;
   5926                         continue ;
   5927                     }
   5928                     if ((selector_for_bit_x_field_value[index] >=
   5929                                 ing_pkt_attr_uncmprsd_bits_g[unit].phb_3_pos) &&
   5930                             (selector_for_bit_x_field_value[index] <=
   5931                              (ing_pkt_attr_uncmprsd_bits_g[unit].phb_3_pos +
   5932                               ing_pkt_attr_uncmprsd_bits_g[unit].phb_3 - 1))) { /* 54 .. 57 */
   5933                         uncmprsd_attr_bits_selector |=
   5934                             BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_PHB_3_ATTR_BITS;
   5935                         continue;
   5936                     }
   5937                     if ((selector_for_bit_x_field_value[index] >=
   5938                                 ing_pkt_attr_uncmprsd_bits_g[unit].cng_3_pos) &&
   5939                             (selector_for_bit_x_field_value[index] <=
   5940                              (ing_pkt_attr_uncmprsd_bits_g[unit].cng_3_pos +
   5941                               ing_pkt_attr_uncmprsd_bits_g[unit].cng_3 - 1))) { /* 58 .. 59 */
   5942                         uncmprsd_attr_bits_selector |=
   5943                             BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_CNG_3_ATTR_BITS;
   5944                         continue;
   5945                     }
   5946                 }
   5947 #endif
   5948              }
   5949         }
   5950         flex_ingress_modes[unit][mode].ing_attr.uncmprsd_attr_selectors.
   5951                      uncmprsd_attr_bits_selector = uncmprsd_attr_bits_selector;
   5952         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   5953                   (BSL_META_U(unit,
   5954                               "uncmprsd_attr_bits_selector:%x \n"),
   5955                    uncmprsd_attr_bits_selector));
   5956         return;
   5957     }
   5958     if (direction == bcmStatFlexDirectionEgress) {
   5959         flex_egress_modes[unit][mode].available=1;
   5960         /* Will be changed WhileReadingTables */
   5961         flex_egress_modes[unit][mode].reference_count=0;
   5962         flex_egress_modes[unit][mode].egr_attr.packet_attr_type =
   5963                                       bcmStatFlexPacketAttrTypeUncompressed;
   5964         for (uncmprsd_attr_bits_selector=0,index=0;index<8;index++) {
   5965              if(selector_x_en_field_value[index] != 0) {
   5966                 if ((selector_for_bit_x_field_value[index] >=
   5967                      egr_pkt_attr_uncmprsd_bits_g[unit].ip_pkt_pos) &&
   5968                     (selector_for_bit_x_field_value[index] <=
   5969                       (egr_pkt_attr_uncmprsd_bits_g[unit].ip_pkt_pos+
   5970                        egr_pkt_attr_uncmprsd_bits_g[unit].ip_pkt-1))) { /* 0..0 */
   5971                     uncmprsd_attr_bits_selector |=
   5972                       BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_IP_PKT_ATTR_BITS;
   5973                     continue;
   5974                 }
   5975                 if ((selector_for_bit_x_field_value[index] >=
   5976                      egr_pkt_attr_uncmprsd_bits_g[unit].drop_pos) &&
   5977                     (selector_for_bit_x_field_value[index] <=
   5978                       (egr_pkt_attr_uncmprsd_bits_g[unit].drop_pos+
   5979                        egr_pkt_attr_uncmprsd_bits_g[unit].drop-1))) { /* 1..1 */
   5980                     uncmprsd_attr_bits_selector |=
   5981                       BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_DROP_ATTR_BITS;
   5982                     continue;
   5983                 }
   5984                 if ((selector_for_bit_x_field_value[index] >=
   5985                      egr_pkt_attr_uncmprsd_bits_g[unit].dvp_type_pos) &&
   5986                     (selector_for_bit_x_field_value[index] <=
   5987                       (egr_pkt_attr_uncmprsd_bits_g[unit].dvp_type_pos+
   5988                        egr_pkt_attr_uncmprsd_bits_g[unit].dvp_type-1))) { /* 3..8 */
   5989                     uncmprsd_attr_bits_selector |=
   5990                       BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_DVP_TYPE_ATTR_BITS;
   5991                     continue;
   5992                 }
   5993                 if ((selector_for_bit_x_field_value[index] >=
   5994                      egr_pkt_attr_uncmprsd_bits_g[unit].svp_type_pos) &&
   5995                     (selector_for_bit_x_field_value[index] <=
   5996                       (egr_pkt_attr_uncmprsd_bits_g[unit].svp_type_pos+
   5997                        egr_pkt_attr_uncmprsd_bits_g[unit].svp_type-1))) { /* 3..8 */
   5998                     uncmprsd_attr_bits_selector |=
   5999                       BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_SVP_TYPE_ATTR_BITS;
   6000                     continue;
   6001                 }
   6002                 if ((selector_for_bit_x_field_value[index] >=
   6003                      egr_pkt_attr_uncmprsd_bits_g[unit].pkt_resolution_pos) &&
   6004                     (selector_for_bit_x_field_value[index] <=
   6005                       (egr_pkt_attr_uncmprsd_bits_g[unit].pkt_resolution_pos+
   6006                        egr_pkt_attr_uncmprsd_bits_g[unit].pkt_resolution-1))) { /* 4..4 */
   6007                     uncmprsd_attr_bits_selector |=
   6008                     BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS;
   6009                     continue;
   6010                 }
   6011                 if ((selector_for_bit_x_field_value[index] >=
   6012                      egr_pkt_attr_uncmprsd_bits_g[unit].tos_dscp_pos) &&
   6013                     (selector_for_bit_x_field_value[index] <=
   6014                      (egr_pkt_attr_uncmprsd_bits_g[unit].tos_dscp_pos+egr_pkt_attr_uncmprsd_bits_g[unit].tos_dscp-1))) {
   6015                      /* 5..12 */
   6016                      uncmprsd_attr_bits_selector |=
   6017                        BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_TOS_DSCP_ATTR_BITS;
   6018                     continue;
   6019                 }
   6020                 if ((selector_for_bit_x_field_value[index] >=
   6021                      egr_pkt_attr_uncmprsd_bits_g[unit].tos_ecn_pos) &&
   6022                     (selector_for_bit_x_field_value[index] <=
   6023                      (egr_pkt_attr_uncmprsd_bits_g[unit].tos_ecn_pos+egr_pkt_attr_uncmprsd_bits_g[unit].tos_ecn-1))) {
   6024                      /* 5..12 */
   6025                      uncmprsd_attr_bits_selector |=
   6026                        BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_TOS_ECN_ATTR_BITS;
   6027                     continue;
   6028                 }
   6029                 if ((selector_for_bit_x_field_value[index] >=
   6030                      egr_pkt_attr_uncmprsd_bits_g[unit].egr_port_pos) &&
   6031                     (selector_for_bit_x_field_value[index] <=
   6032                      (egr_pkt_attr_uncmprsd_bits_g[unit].egr_port_pos+
   6033                       egr_pkt_attr_uncmprsd_bits_g[unit].egr_port-1))) { /* 13..18 */
   6034                      uncmprsd_attr_bits_selector |=
   6035                        BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_EGRESS_PORT_ATTR_BITS;
   6036                      continue;
   6037                 }
   6038                 if ((selector_for_bit_x_field_value[index] >=
   6039                      egr_pkt_attr_uncmprsd_bits_g[unit].inner_dot1p_pos) &&
   6040                     (selector_for_bit_x_field_value[index] <=
   6041                      (egr_pkt_attr_uncmprsd_bits_g[unit].inner_dot1p_pos+
   6042                       egr_pkt_attr_uncmprsd_bits_g[unit].inner_dot1p-1))) { /* 19..21*/
   6043                      uncmprsd_attr_bits_selector |=
   6044                        BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_INNER_DOT1P_ATTR_BITS;
   6045                      continue;
   6046                 }
   6047                 if ((selector_for_bit_x_field_value[index] >=
   6048                      egr_pkt_attr_uncmprsd_bits_g[unit].outer_dot1p_pos) &&
   6049                     (selector_for_bit_x_field_value[index] <=
   6050                      (egr_pkt_attr_uncmprsd_bits_g[unit].outer_dot1p_pos+
   6051                       egr_pkt_attr_uncmprsd_bits_g[unit].outer_dot1p-1))) { /* 22..24*/
   6052                      uncmprsd_attr_bits_selector |=
   6053                        BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_OUTER_DOT1P_ATTR_BITS;
   6054                     continue;
   6055                 }
   6056                 if ((selector_for_bit_x_field_value[index] >=
   6057                      egr_pkt_attr_uncmprsd_bits_g[unit].vlan_format_pos) &&
   6058                     (selector_for_bit_x_field_value[index] <=
   6059                      (egr_pkt_attr_uncmprsd_bits_g[unit].vlan_format_pos+
   6060                       egr_pkt_attr_uncmprsd_bits_g[unit].vlan_format-1))) { /* 25..26 */
   6061                      uncmprsd_attr_bits_selector |=
   6062                        BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_VLAN_FORMAT_ATTR_BITS;
   6063                     continue;
   6064                 }
   6065                 if ((selector_for_bit_x_field_value[index] >=
   6066                      egr_pkt_attr_uncmprsd_bits_g[unit].int_pri_pos) &&
   6067                     (selector_for_bit_x_field_value[index] <=
   6068                      (egr_pkt_attr_uncmprsd_bits_g[unit].int_pri_pos +
   6069                       egr_pkt_attr_uncmprsd_bits_g[unit].int_pri - 1))) { /* 27..30 */
   6070                      uncmprsd_attr_bits_selector |=
   6071                        BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_INT_PRI_ATTR_BITS;
   6072                     continue;
   6073                 }
   6074                 if ((selector_for_bit_x_field_value[index] >=
   6075                      egr_pkt_attr_uncmprsd_bits_g[unit].cng_pos) &&
   6076                     (selector_for_bit_x_field_value[index] <=
   6077                      (egr_pkt_attr_uncmprsd_bits_g[unit].cng_pos +
   6078                       egr_pkt_attr_uncmprsd_bits_g[unit].cng - 1))) { /* 31..32 */
   6079                      uncmprsd_attr_bits_selector |=
   6080                        BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_CNG_ATTR_BITS;
   6081                      continue;
   6082                 }
   6083 #ifdef BCM_APACHE_SUPPORT
   6084                 if (soc_feature(unit,soc_feature_flex_ctr_mpls_3_label_count)) {
   6085                     if ((selector_for_bit_x_field_value[index] >=
   6086                                 egr_pkt_attr_uncmprsd_bits_g[unit].phb_1_pos) &&
   6087                             (selector_for_bit_x_field_value[index] <=
   6088                              (egr_pkt_attr_uncmprsd_bits_g[unit].phb_1_pos +
   6089                               egr_pkt_attr_uncmprsd_bits_g[unit].phb_1 - 1))) { /* 42 .. 45 */
   6090                         uncmprsd_attr_bits_selector |=
   6091                             BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_PHB_1_ATTR_BITS;
   6092                         continue;
   6093                     }
   6094                     if ((selector_for_bit_x_field_value[index] >=
   6095                                 egr_pkt_attr_uncmprsd_bits_g[unit].cng_1_pos) &&
   6096                             (selector_for_bit_x_field_value[index] <=
   6097                              (egr_pkt_attr_uncmprsd_bits_g[unit].cng_1_pos +
   6098                               egr_pkt_attr_uncmprsd_bits_g[unit].cng_1 - 1))) { /* 46 .. 47 */
   6099                         uncmprsd_attr_bits_selector |=
   6100                             BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_CNG_1_ATTR_BITS;
   6101                         continue;
   6102                     }
   6103                     if ((selector_for_bit_x_field_value[index] >=
   6104                                 egr_pkt_attr_uncmprsd_bits_g[unit].phb_2_pos) &&
   6105                             (selector_for_bit_x_field_value[index] <=
   6106                              (egr_pkt_attr_uncmprsd_bits_g[unit].phb_2_pos +
   6107                               egr_pkt_attr_uncmprsd_bits_g[unit].phb_2 - 1))) { /* 48 .. 51 */
   6108                         uncmprsd_attr_bits_selector |=
   6109                             BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_PHB_2_ATTR_BITS;
   6110                         continue;
   6111                     }
   6112                     if ((selector_for_bit_x_field_value[index] >=
   6113                                 egr_pkt_attr_uncmprsd_bits_g[unit].cng_2_pos) &&
   6114                             (selector_for_bit_x_field_value[index] <=
   6115                              (egr_pkt_attr_uncmprsd_bits_g[unit].cng_2_pos +
   6116                               egr_pkt_attr_uncmprsd_bits_g[unit].cng_2 - 1))) { /* 52 .. 53 */
   6117                         uncmprsd_attr_bits_selector |=
   6118                             BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_CNG_2_ATTR_BITS;
   6119                         continue ;
   6120                     }
   6121                     if ((selector_for_bit_x_field_value[index] >=
   6122                                 egr_pkt_attr_uncmprsd_bits_g[unit].phb_3_pos) &&
   6123                             (selector_for_bit_x_field_value[index] <=
   6124                              (egr_pkt_attr_uncmprsd_bits_g[unit].phb_3_pos +
   6125                               egr_pkt_attr_uncmprsd_bits_g[unit].phb_3 - 1))) { /* 54 .. 57 */
   6126                         uncmprsd_attr_bits_selector |=
   6127                             BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_PHB_3_ATTR_BITS;
   6128                         continue;
   6129                     }
   6130                     if ((selector_for_bit_x_field_value[index] >=
   6131                                 egr_pkt_attr_uncmprsd_bits_g[unit].cng_3_pos) &&
   6132                             (selector_for_bit_x_field_value[index] <=
   6133                              (egr_pkt_attr_uncmprsd_bits_g[unit].cng_3_pos +
   6134                               egr_pkt_attr_uncmprsd_bits_g[unit].cng_3 - 1))) { /* 58 .. 59 */
   6135                         uncmprsd_attr_bits_selector |=
   6136                             BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_CNG_3_ATTR_BITS;
   6137                         continue;
   6138                     }
   6139                 }
   6140 #endif
   6141 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   6142                  if (soc_feature(unit, soc_feature_flex_stat_egr_queue_congestion_marked)) {
   6143                      if ((selector_for_bit_x_field_value[index] >=
   6144                                  egr_pkt_attr_uncmprsd_bits_g[unit].congestion_marked) &&
   6145                              (selector_for_bit_x_field_value[index] <=
   6146                               (egr_pkt_attr_uncmprsd_bits_g[unit].congestion_marked_pos +
   6147                                egr_pkt_attr_uncmprsd_bits_g[unit].congestion_marked - 1))) {
   6148                          uncmprsd_attr_bits_selector |=
   6149                              BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_CONGESTION_MARKED_ATTR_BITS;
   6150                          continue;
   6151                      }
   6152                      if ((selector_for_bit_x_field_value[index] >=
   6153                                  egr_pkt_attr_uncmprsd_bits_g[unit].uc_queueing) &&
   6154                              (selector_for_bit_x_field_value[index] <=
   6155                               (egr_pkt_attr_uncmprsd_bits_g[unit].uc_queueing_pos +
   6156                                egr_pkt_attr_uncmprsd_bits_g[unit].uc_queueing - 1))) {
   6157                          uncmprsd_attr_bits_selector |=
   6158                              BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_UC_QUEUEING_ATTR_BITS;
   6159                          continue;
   6160                      }
   6161                      if ((selector_for_bit_x_field_value[index] >=
   6162                                  egr_pkt_attr_uncmprsd_bits_g[unit].mmu_cos) &&
   6163                              (selector_for_bit_x_field_value[index] <=
   6164                               (egr_pkt_attr_uncmprsd_bits_g[unit].mmu_cos_pos +
   6165                                egr_pkt_attr_uncmprsd_bits_g[unit].mmu_cos - 1))) {
   6166                          uncmprsd_attr_bits_selector |=
   6167                              BCM_STAT_FLEX_EGR_UNCOMPRESSED_USE_MMU_COS_ATTR_BITS;
   6168                          continue;
   6169                      }
   6170                  }
   6171 #endif
   6172              }
   6173         }
   6174         flex_egress_modes[unit][mode].egr_attr.uncmprsd_attr_selectors.
   6175                     uncmprsd_attr_bits_selector = uncmprsd_attr_bits_selector;
   6176         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6177                   (BSL_META_U(unit,
   6178                               "uncmprsd_attr_bits_selector:%x \n"),
   6179                    uncmprsd_attr_bits_selector));
   6180         return;
   6181     }
   6182     LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6183               (BSL_META_U(unit,
   6184                           "Ooops. Control Must not reach over here \n")));
   6185 }
   6186 /*
   6187  * Function:
   6188  *      _bcm_esw_stat_flex_init_cmprsd_mode
   6189  * Description:
   6190  *      Configures flex hw for compressed mode
   6191  * Parameters:
   6192  *      unit                           - (IN) unit number
   6193  *      mode                           - (IN) Flex Offset Mode
   6194  *      direction                      - (IN) Flex Data flow direction(ing/egr)
   6195  *      selector_count                 - (IN) Flex Key selector count
   6196  *      selector_x_en_field_value      - (IN) Flex Key selector fields
   6197  *      selector_for_bit_x_field_value - (IN) Flex Key selector field bits
   6198  *
   6199  * Return Value:
   6200  *      None
   6201  * Notes:
   6202  */
   6203 static void
   6204 _bcm_esw_stat_flex_init_cmprsd_mode(
   6205     int                       unit,
   6206     int                       mode,
   6207     bcm_stat_flex_direction_t direction,
   6208     uint32                    selector_count,
   6209     uint32                    selector_x_en_field_value[8],
   6210     uint32                    selector_for_bit_x_field_value[8])
   6211 {
   6212     uint32  index=0;
   6213 
   6214     uint32                            alloc_size=0;
   6215     uint32                            map_value=0;
   6216     ing_flex_ctr_pkt_pri_map_entry_t  *ing_pkt_pri_map_dma=NULL;
   6217     ing_flex_ctr_pkt_res_map_entry_t  *ing_pkt_res_map_dma=NULL;
   6218     ing_flex_ctr_port_map_entry_t     *ing_port_map_dma=NULL;
   6219     ing_flex_ctr_pri_cng_map_entry_t  *ing_pri_cng_map_dma=NULL;
   6220     ing_flex_ctr_tos_map_entry_t      *ing_tos_map_dma=NULL;
   6221     egr_flex_ctr_pkt_pri_map_entry_t  *egr_pkt_pri_map_dma=NULL;
   6222     egr_flex_ctr_pkt_res_map_entry_t  *egr_pkt_res_map_dma=NULL;
   6223     egr_flex_ctr_port_map_entry_t     *egr_port_map_dma=NULL;
   6224     egr_flex_ctr_pri_cng_map_entry_t  *egr_pri_cng_map_dma=NULL;
   6225     egr_flex_ctr_tos_map_entry_t      *egr_tos_map_dma=NULL;
   6226 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   6227     egr_flex_ctr_cos_map_entry_t      *egr_cos_uc_map_dma = NULL;
   6228 #endif
   6229 
   6230     if (direction == bcmStatFlexDirectionIngress) {
   6231        /* memset(&flex_ingress_modes[unit][mode],0,
   6232          sizeof(flex_ingress_modes[unit][mode])); */
   6233        flex_ingress_modes[unit][mode].available=1;
   6234        /*Will be changed WhileReadingTables */
   6235        flex_ingress_modes[unit][mode].reference_count=0;
   6236        flex_ingress_modes[unit][mode].total_counters= 0;
   6237        flex_ingress_modes[unit][mode].ing_attr.packet_attr_type =
   6238             bcmStatFlexPacketAttrTypeCompressed;
   6239        for (index=0;index<8;index++) {
   6240             if(selector_x_en_field_value[index] != 0) {
   6241                if ((selector_for_bit_x_field_value[index] >=
   6242                      ing_pkt_attr_cmprsd_bits_g[unit].ip_pkt_pos) &&
   6243                     (selector_for_bit_x_field_value[index] <=
   6244                       (ing_pkt_attr_cmprsd_bits_g[unit].ip_pkt_pos+
   6245                        ing_pkt_attr_cmprsd_bits_g[unit].ip_pkt-1))) { /* 0..0 */
   6246                    flex_ingress_modes[unit][mode].ing_attr.
   6247                     cmprsd_attr_selectors.pkt_attr_bits.ip_pkt = 1;
   6248                    continue;
   6249                }
   6250                if ((selector_for_bit_x_field_value[index] >=
   6251                      ing_pkt_attr_cmprsd_bits_g[unit].drop_pos) &&
   6252                     (selector_for_bit_x_field_value[index] <=
   6253                       (ing_pkt_attr_cmprsd_bits_g[unit].drop_pos+
   6254                        ing_pkt_attr_cmprsd_bits_g[unit].drop-1))) { /* 1..1 */
   6255                    flex_ingress_modes[unit][mode].ing_attr.
   6256                     cmprsd_attr_selectors.pkt_attr_bits.drop = 1;
   6257                    continue;
   6258                }
   6259                if ((selector_for_bit_x_field_value[index] >=
   6260                      ing_pkt_attr_cmprsd_bits_g[unit].svp_type_pos) &&
   6261                     (selector_for_bit_x_field_value[index] <=
   6262                       (ing_pkt_attr_cmprsd_bits_g[unit].svp_type_pos+
   6263                        ing_pkt_attr_cmprsd_bits_g[unit].svp_type-1))) { /* 1..1 */
   6264                    flex_ingress_modes[unit][mode].ing_attr.
   6265                     cmprsd_attr_selectors.pkt_attr_bits.svp_type = 1;
   6266                    continue;
   6267                }
   6268                if ((selector_for_bit_x_field_value[index] >=
   6269                      ing_pkt_attr_cmprsd_bits_g[unit].pkt_resolution_pos) &&
   6270                     (selector_for_bit_x_field_value[index] <=
   6271                       (ing_pkt_attr_cmprsd_bits_g[unit].pkt_resolution_pos+
   6272                        ing_pkt_attr_cmprsd_bits_g[unit].pkt_resolution-1))) { /* 3..8 */
   6273                     flex_ingress_modes[unit][mode].ing_attr.
   6274                      cmprsd_attr_selectors.pkt_attr_bits.pkt_resolution++;
   6275                     continue;
   6276                }
   6277                if ((selector_for_bit_x_field_value[index] >=
   6278                      ing_pkt_attr_cmprsd_bits_g[unit].tos_dscp_pos) &&
   6279                     (selector_for_bit_x_field_value[index] <=
   6280                       (ing_pkt_attr_cmprsd_bits_g[unit].tos_dscp_pos+
   6281                        ing_pkt_attr_cmprsd_bits_g[unit].tos_dscp-1))) { /* 9..16 */
   6282                     flex_ingress_modes[unit][mode].ing_attr.
   6283                      cmprsd_attr_selectors.pkt_attr_bits.tos_dscp++;
   6284                     continue;
   6285                }
   6286                if ((selector_for_bit_x_field_value[index] >=
   6287                      ing_pkt_attr_cmprsd_bits_g[unit].tos_ecn_pos) &&
   6288                     (selector_for_bit_x_field_value[index] <=
   6289                       (ing_pkt_attr_cmprsd_bits_g[unit].tos_ecn_pos+
   6290                        ing_pkt_attr_cmprsd_bits_g[unit].tos_ecn-1))) { /* 9..16 */
   6291                     flex_ingress_modes[unit][mode].ing_attr.
   6292                      cmprsd_attr_selectors.pkt_attr_bits.tos_ecn++;
   6293                     continue;
   6294                }
   6295                if ((selector_for_bit_x_field_value[index] >=
   6296                      ing_pkt_attr_cmprsd_bits_g[unit].ing_port_pos) &&
   6297                     (selector_for_bit_x_field_value[index] <=
   6298                       (ing_pkt_attr_cmprsd_bits_g[unit].ing_port_pos+
   6299                        ing_pkt_attr_cmprsd_bits_g[unit].ing_port-1))) { /* 17..22 */
   6300                     flex_ingress_modes[unit][mode].ing_attr.
   6301                      cmprsd_attr_selectors.pkt_attr_bits.ing_port++;
   6302                     continue;
   6303                }
   6304                if ((selector_for_bit_x_field_value[index] >=
   6305                      ing_pkt_attr_cmprsd_bits_g[unit].inner_dot1p_pos) &&
   6306                     (selector_for_bit_x_field_value[index] <=
   6307                       (ing_pkt_attr_cmprsd_bits_g[unit].inner_dot1p_pos+
   6308                        ing_pkt_attr_cmprsd_bits_g[unit].inner_dot1p-1))) { /* 23..25 */
   6309                     flex_ingress_modes[unit][mode].ing_attr.
   6310                      cmprsd_attr_selectors.pkt_attr_bits.inner_dot1p++;
   6311                     continue;
   6312                }
   6313                if ((selector_for_bit_x_field_value[index] >=
   6314                      ing_pkt_attr_cmprsd_bits_g[unit].outer_dot1p_pos) &&
   6315                     (selector_for_bit_x_field_value[index] <=
   6316                       (ing_pkt_attr_cmprsd_bits_g[unit].outer_dot1p_pos+
   6317                        ing_pkt_attr_cmprsd_bits_g[unit].outer_dot1p-1))) { /* 26..28 */
   6318                    flex_ingress_modes[unit][mode].ing_attr.
   6319                     cmprsd_attr_selectors.pkt_attr_bits.outer_dot1p++;
   6320                    continue;
   6321                }
   6322                if ((selector_for_bit_x_field_value[index] >=
   6323                      ing_pkt_attr_cmprsd_bits_g[unit].vlan_format_pos) &&
   6324                     (selector_for_bit_x_field_value[index] <=
   6325                       (ing_pkt_attr_cmprsd_bits_g[unit].vlan_format_pos+
   6326                        ing_pkt_attr_cmprsd_bits_g[unit].vlan_format-1))) { /* 29..30 */
   6327                     flex_ingress_modes[unit][mode].ing_attr.
   6328                      cmprsd_attr_selectors.pkt_attr_bits.vlan_format++;
   6329                     continue;
   6330                }
   6331                if ((selector_for_bit_x_field_value[index] >=
   6332                      ing_pkt_attr_cmprsd_bits_g[unit].int_pri_pos) &&
   6333                     (selector_for_bit_x_field_value[index] <=
   6334                       (ing_pkt_attr_cmprsd_bits_g[unit].int_pri_pos+
   6335                        ing_pkt_attr_cmprsd_bits_g[unit].int_pri-1))) { /* 31..34 */
   6336                     flex_ingress_modes[unit][mode].ing_attr.
   6337                      cmprsd_attr_selectors.pkt_attr_bits.int_pri++;
   6338                     continue;
   6339                }
   6340                if ((selector_for_bit_x_field_value[index] >=
   6341                      ing_pkt_attr_cmprsd_bits_g[unit].ifp_cng_pos) &&
   6342                     (selector_for_bit_x_field_value[index] <=
   6343                       (ing_pkt_attr_cmprsd_bits_g[unit].ifp_cng_pos+
   6344                        ing_pkt_attr_cmprsd_bits_g[unit].ifp_cng-1))) { /* 35..36 */
   6345                    flex_ingress_modes[unit][mode].ing_attr.
   6346                     cmprsd_attr_selectors.pkt_attr_bits.ifp_cng++;
   6347                    continue;
   6348                }
   6349                if ((selector_for_bit_x_field_value[index] >=
   6350                      ing_pkt_attr_cmprsd_bits_g[unit].cng_pos) &&
   6351                     (selector_for_bit_x_field_value[index] <=
   6352                       (ing_pkt_attr_cmprsd_bits_g[unit].cng_pos+
   6353                        ing_pkt_attr_cmprsd_bits_g[unit].cng-1))) { /* 37..38 */
   6354                    flex_ingress_modes[unit][mode].ing_attr.
   6355                     cmprsd_attr_selectors.pkt_attr_bits.cng++;
   6356                    continue;
   6357                }
   6358 #ifdef BCM_APACHE_SUPPORT
   6359                if (soc_feature(unit,soc_feature_flex_ctr_mpls_3_label_count)) {
   6360                    if ((selector_for_bit_x_field_value[index] >=
   6361                                ing_pkt_attr_cmprsd_bits_g[unit].phb_1_pos) &&
   6362                            (selector_for_bit_x_field_value[index] <=
   6363                             (ing_pkt_attr_cmprsd_bits_g[unit].phb_1_pos +
   6364                              ing_pkt_attr_cmprsd_bits_g[unit].phb_1 - 1))) { /* 42 .. 45 */
   6365                        flex_ingress_modes[unit][mode].ing_attr.
   6366                            cmprsd_attr_selectors.pkt_attr_bits.phb_1++;
   6367                        continue;
   6368                    }
   6369                    if ((selector_for_bit_x_field_value[index] >=
   6370                                ing_pkt_attr_cmprsd_bits_g[unit].cng_1_pos) &&
   6371                            (selector_for_bit_x_field_value[index] <=
   6372                             (ing_pkt_attr_cmprsd_bits_g[unit].cng_1_pos +
   6373                              ing_pkt_attr_cmprsd_bits_g[unit].cng_1 - 1))) { /* 46 .. 47 */
   6374                        flex_ingress_modes[unit][mode].ing_attr.
   6375                            cmprsd_attr_selectors.pkt_attr_bits.cng_1++;
   6376                        continue;
   6377                    }
   6378                    if ((selector_for_bit_x_field_value[index] >=
   6379                                ing_pkt_attr_cmprsd_bits_g[unit].phb_2_pos) &&
   6380                            (selector_for_bit_x_field_value[index] <=
   6381                             (ing_pkt_attr_cmprsd_bits_g[unit].phb_2_pos +
   6382                              ing_pkt_attr_cmprsd_bits_g[unit].phb_2 - 1))) { /* 48 .. 51 */
   6383                        flex_ingress_modes[unit][mode].ing_attr.
   6384                            cmprsd_attr_selectors.pkt_attr_bits.phb_2++;
   6385                        continue;
   6386                    }
   6387                    if ((selector_for_bit_x_field_value[index] >=
   6388                                ing_pkt_attr_cmprsd_bits_g[unit].cng_2_pos) &&
   6389                            (selector_for_bit_x_field_value[index] <=
   6390                             (ing_pkt_attr_cmprsd_bits_g[unit].cng_2_pos +
   6391                              ing_pkt_attr_cmprsd_bits_g[unit].cng_2 - 1))) { /* 52 .. 53 */
   6392                        flex_ingress_modes[unit][mode].ing_attr.
   6393                            cmprsd_attr_selectors.pkt_attr_bits.cng_2++;
   6394                        continue ;
   6395                    }
   6396                    if ((selector_for_bit_x_field_value[index] >=
   6397                                ing_pkt_attr_cmprsd_bits_g[unit].phb_3_pos) &&
   6398                            (selector_for_bit_x_field_value[index] <=
   6399                             (ing_pkt_attr_cmprsd_bits_g[unit].phb_3_pos +
   6400                              ing_pkt_attr_cmprsd_bits_g[unit].phb_3 - 1))) { /* 54 .. 57 */
   6401                        flex_ingress_modes[unit][mode].ing_attr.
   6402                            cmprsd_attr_selectors.pkt_attr_bits.phb_3++;
   6403                        continue;
   6404                    }
   6405                    if ((selector_for_bit_x_field_value[index] >=
   6406                                ing_pkt_attr_cmprsd_bits_g[unit].cng_3_pos) &&
   6407                            (selector_for_bit_x_field_value[index] <=
   6408                             (ing_pkt_attr_cmprsd_bits_g[unit].cng_3_pos +
   6409                              ing_pkt_attr_cmprsd_bits_g[unit].cng_3 - 1))) { /* 58 .. 59 */
   6410                        flex_ingress_modes[unit][mode].ing_attr.
   6411                            cmprsd_attr_selectors.pkt_attr_bits.cng_3++;
   6412                        continue;
   6413                    }
   6414                }
   6415 #endif
   6416            }
   6417        }
   6418 #ifdef BCM_APACHE_SUPPORT
   6419        if (soc_feature(unit,soc_feature_flex_ctr_mpls_3_label_count)) {
   6420            if (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6421                    pkt_attr_bits.cng_3 ) {
   6422                flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6423                    cng_3 = ing_pkt_attr_cmprsd_bits_g[unit].cng_3;
   6424            }
   6425            if (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6426                    pkt_attr_bits.phb_3 ) {
   6427                flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6428                    phb_3 = ing_pkt_attr_cmprsd_bits_g[unit].phb_3;
   6429            }
   6430            if (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6431                    pkt_attr_bits.cng_2 ) {
   6432                flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6433                    cng_2 = ing_pkt_attr_cmprsd_bits_g[unit].cng_2;
   6434            }
   6435            if (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6436                    pkt_attr_bits.phb_2 ) {
   6437                flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6438                    phb_2 = ing_pkt_attr_cmprsd_bits_g[unit].phb_2;
   6439            }
   6440            if (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6441                    pkt_attr_bits.cng_1 ) {
   6442                flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6443                    cng_1 = ing_pkt_attr_cmprsd_bits_g[unit].cng_1;
   6444            }
   6445            if (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6446                    pkt_attr_bits.phb_1 ) {
   6447                flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6448                    phb_1 = ing_pkt_attr_cmprsd_bits_g[unit].phb_1;
   6449            }
   6450        }
   6451 #endif
   6452        if ((flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6453             pkt_attr_bits.cng ) ||
   6454            (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6455             pkt_attr_bits.ifp_cng ) ||
   6456            (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6457             pkt_attr_bits.int_pri ))         {
   6458             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6459                       (BSL_META_U(unit,
   6460                                   "cng:%d \n"),
   6461                        flex_ingress_modes[unit][mode].ing_attr.
   6462                        cmprsd_attr_selectors.pkt_attr_bits.cng));
   6463             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6464                       (BSL_META_U(unit,
   6465                                   "ifp_cng:%d \n"),
   6466                        flex_ingress_modes[unit][mode].ing_attr.
   6467                        cmprsd_attr_selectors.pkt_attr_bits.ifp_cng));
   6468             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6469                       (BSL_META_U(unit,
   6470                                   "int_pri:%d \n"),
   6471                        flex_ingress_modes[unit][mode].ing_attr.
   6472                        cmprsd_attr_selectors.pkt_attr_bits.int_pri));
   6473             alloc_size = soc_mem_index_count(unit,ING_FLEX_CTR_PRI_CNG_MAPm) *
   6474                          sizeof(ing_flex_ctr_pri_cng_map_entry_t);
   6475             ing_pri_cng_map_dma = soc_cm_salloc( unit, alloc_size,
   6476                                                  "ING_FLEX_CTR_PRI_CNG_MAPm");
   6477             if (ing_pri_cng_map_dma == NULL) {
   6478                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6479                           (BSL_META_U(unit,
   6480                                       "ING_FLEX_CTR_PRI_CNG_MAPm:DMAAllocationFail\n")));
   6481                 return;
   6482             }
   6483             sal_memset(ing_pri_cng_map_dma, 0, alloc_size);
   6484             if (soc_mem_read_range(
   6485                     unit,
   6486                     ING_FLEX_CTR_PRI_CNG_MAPm,
   6487                     MEM_BLOCK_ANY,
   6488                     soc_mem_index_min(unit,ING_FLEX_CTR_PRI_CNG_MAPm),
   6489                     soc_mem_index_max(unit,ING_FLEX_CTR_PRI_CNG_MAPm),
   6490                     ing_pri_cng_map_dma) != SOC_E_NONE) {
   6491                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6492                           (BSL_META_U(unit,
   6493                                       "ING_FLEX_CTR_PRI_CNG_MAPm:Read failure \n")));
   6494                 soc_cm_sfree(unit,ing_pri_cng_map_dma);
   6495                 return;
   6496             }
   6497             for (index=0;
   6498                  index< soc_mem_index_count(unit,ING_FLEX_CTR_PRI_CNG_MAPm);
   6499                  index++) {
   6500                  soc_mem_field_get( unit, ING_FLEX_CTR_PRI_CNG_MAPm,
   6501                       (uint32 *)&ing_pri_cng_map_dma[index], PRI_CNG_FNf,
   6502                       &map_value);
   6503                  flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6504                                    pri_cnf_attr_map[index]=(uint8)map_value;
   6505                  if (map_value) {
   6506                      LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6507                                (BSL_META_U(unit,
   6508                                            "Index:%dValue:%d\n"),
   6509                                 index,map_value));
   6510                  }
   6511             }
   6512             soc_cm_sfree(unit,ing_pri_cng_map_dma);
   6513        }
   6514        if ((flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6515             pkt_attr_bits.vlan_format) ||
   6516            (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6517             pkt_attr_bits.outer_dot1p) ||
   6518            (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6519             pkt_attr_bits.inner_dot1p)) {
   6520             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6521                       (BSL_META_U(unit,
   6522                                   "vlan_format:%d \n"),
   6523                        flex_ingress_modes[unit][mode].ing_attr.
   6524                        cmprsd_attr_selectors.pkt_attr_bits.vlan_format));
   6525             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6526                       (BSL_META_U(unit,
   6527                                   "outer_dot1p:%d \n"),
   6528                        flex_ingress_modes[unit][mode].ing_attr.
   6529                        cmprsd_attr_selectors.pkt_attr_bits.outer_dot1p));
   6530             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6531                       (BSL_META_U(unit,
   6532                                   "inner_dot1p:%d \n"),
   6533                        flex_ingress_modes[unit][mode].ing_attr.
   6534                        cmprsd_attr_selectors.pkt_attr_bits.inner_dot1p));
   6535             alloc_size = soc_mem_index_count(unit,ING_FLEX_CTR_PKT_PRI_MAPm) *
   6536                          sizeof(ing_flex_ctr_pkt_pri_map_entry_t);
   6537             ing_pkt_pri_map_dma = soc_cm_salloc( unit, alloc_size,
   6538                                                  "ING_FLEX_CTR_PKT_PRI_MAPm");
   6539             if (ing_pkt_pri_map_dma == NULL) {
   6540                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6541                           (BSL_META_U(unit,
   6542                                       "ING_FLEX_CTR_PKT_PRI_MAPm:DMAAllocationFail\n")));
   6543                 return;
   6544             }
   6545             sal_memset(ing_pkt_pri_map_dma, 0, alloc_size);
   6546             if (soc_mem_read_range(
   6547                     unit,
   6548                     ING_FLEX_CTR_PKT_PRI_MAPm,
   6549                     MEM_BLOCK_ANY,
   6550                     soc_mem_index_min(unit,ING_FLEX_CTR_PKT_PRI_MAPm),
   6551                     soc_mem_index_max(unit,ING_FLEX_CTR_PKT_PRI_MAPm),
   6552                     ing_pkt_pri_map_dma) != SOC_E_NONE) {
   6553                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6554                           (BSL_META_U(unit,
   6555                                       "ING_FLEX_CTR_PKT_PRI_MAPm:Read failure \n")));
   6556                 soc_cm_sfree(unit,ing_pkt_pri_map_dma);
   6557                 return;
   6558             }
   6559             for (index=0;
   6560                  index< soc_mem_index_count(unit,ING_FLEX_CTR_PKT_PRI_MAPm);
   6561                  index++) {
   6562                  soc_mem_field_get( unit, ING_FLEX_CTR_PKT_PRI_MAPm,
   6563                       (uint32 *)&ing_pkt_pri_map_dma[index], PKT_PRI_FNf,
   6564                       &map_value);
   6565                  flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6566                                    pkt_pri_attr_map[index]=(uint8)map_value;
   6567                  if (map_value){
   6568                      LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6569                                (BSL_META_U(unit,
   6570                                            "Index:%dValue:%d\n"),
   6571                                 index,map_value));
   6572                  }
   6573             }
   6574             soc_cm_sfree(unit,ing_pkt_pri_map_dma);
   6575        }
   6576        if (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6577            pkt_attr_bits.ing_port) {
   6578            LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6579                      (BSL_META_U(unit,
   6580                                  "ing_port:%d \n"),
   6581                       flex_ingress_modes[unit][mode].
   6582                       ing_attr.cmprsd_attr_selectors.
   6583                       pkt_attr_bits.ing_port));
   6584            alloc_size = soc_mem_index_count(unit,ING_FLEX_CTR_PORT_MAPm) *
   6585                          sizeof(ing_flex_ctr_port_map_entry_t);
   6586            ing_port_map_dma = soc_cm_salloc( unit, alloc_size,
   6587                                              "ING_FLEX_CTR_PORT_MAPm");
   6588            if (ing_port_map_dma == NULL) {
   6589                LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6590                          (BSL_META_U(unit,
   6591                                      "ING_FLEX_CTR_PORT_MAPm:DMA Allocation failure\n")));
   6592                return;
   6593            }
   6594            sal_memset(ing_port_map_dma, 0, alloc_size);
   6595            if (soc_mem_read_range(
   6596                    unit,
   6597                    ING_FLEX_CTR_PORT_MAPm,
   6598                    MEM_BLOCK_ANY,
   6599                    soc_mem_index_min(unit,ING_FLEX_CTR_PORT_MAPm),
   6600                    soc_mem_index_max(unit,ING_FLEX_CTR_PORT_MAPm),
   6601                    ing_port_map_dma) != SOC_E_NONE) {
   6602                LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6603                          (BSL_META_U(unit,
   6604                                      "ING_FLEX_CTR_PORT_MAPm:Read failure \n")));
   6605                soc_cm_sfree(unit,ing_port_map_dma);
   6606                return;
   6607            }
   6608            for (index=0;
   6609                 index< soc_mem_index_count(unit,ING_FLEX_CTR_PORT_MAPm);
   6610                 index++) {
   6611                 soc_mem_field_get( unit, ING_FLEX_CTR_PORT_MAPm,
   6612                       (uint32 *)&ing_port_map_dma[index], PORT_FNf,
   6613                       &map_value);
   6614                 flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6615                                   port_attr_map[index]=(uint8)map_value;
   6616                 if (map_value) {
   6617                     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6618                               (BSL_META_U(unit,
   6619                                           "Index:%dValue:%d\n"),
   6620                                index,map_value));
   6621                 }
   6622            }
   6623            soc_cm_sfree(unit,ing_port_map_dma);
   6624        }
   6625        if ((flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6626             pkt_attr_bits.tos_dscp ) ||
   6627            (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6628             pkt_attr_bits.tos_ecn)) {
   6629            LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6630                      (BSL_META_U(unit,
   6631                                  "tos_dscp:%d tos_ecn:%d \n"),
   6632                       flex_ingress_modes[unit][mode].ing_attr.
   6633                       cmprsd_attr_selectors.pkt_attr_bits.tos_dscp,
   6634                       flex_ingress_modes[unit][mode].ing_attr.
   6635                       cmprsd_attr_selectors.pkt_attr_bits.tos_ecn));
   6636            alloc_size = soc_mem_index_count(unit,ING_FLEX_CTR_TOS_MAPm) *
   6637                         sizeof(ing_flex_ctr_tos_map_entry_t);
   6638            ing_tos_map_dma = soc_cm_salloc( unit, alloc_size,
   6639                                             "ING_FLEX_CTR_TOS_MAPm");
   6640            if (ing_tos_map_dma == NULL) {
   6641                LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6642                          (BSL_META_U(unit,
   6643                                      "ING_FLEX_CTR_TOS_MAP:DMA Allocation failure \n")));
   6644                return;
   6645            }
   6646            sal_memset(ing_tos_map_dma, 0, alloc_size);
   6647            if(soc_mem_read_range(
   6648                   unit,
   6649                   ING_FLEX_CTR_TOS_MAPm,
   6650                   MEM_BLOCK_ANY,
   6651                   soc_mem_index_min(unit,ING_FLEX_CTR_TOS_MAPm),
   6652                   soc_mem_index_max(unit,ING_FLEX_CTR_TOS_MAPm),
   6653                   ing_tos_map_dma) != SOC_E_NONE) {
   6654               LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6655                         (BSL_META_U(unit,
   6656                                     "ING_FLEX_CTR_TOS_MAPm:Read failure \n")));
   6657               soc_cm_sfree(unit,ing_tos_map_dma);
   6658               return;
   6659            }
   6660            for (index=0;
   6661                 index< soc_mem_index_count(unit,ING_FLEX_CTR_TOS_MAPm);
   6662                 index++) {
   6663                 soc_mem_field_get( unit, ING_FLEX_CTR_TOS_MAPm,
   6664                       (uint32 *)&ing_tos_map_dma[index], TOS_FNf,
   6665                       &map_value);
   6666                 flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6667                                    tos_attr_map[index]=(uint8)map_value;
   6668                 if (map_value) {
   6669                    LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6670                              (BSL_META_U(unit,
   6671                                          "Index:%dValue:%d\n"),
   6672                               index,map_value));
   6673                 }
   6674             }
   6675             soc_cm_sfree(unit,ing_tos_map_dma);
   6676        }
   6677        if ((flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6678              pkt_attr_bits.pkt_resolution) ||
   6679            (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6680              pkt_attr_bits.svp_type) ||
   6681            (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6682              pkt_attr_bits.drop)) {
   6683             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6684                       (BSL_META_U(unit,
   6685                                   "pkt_resolution:%d \n"),
   6686                        flex_ingress_modes[unit][mode].ing_attr.
   6687                        cmprsd_attr_selectors.pkt_attr_bits.pkt_resolution));
   6688             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6689                       (BSL_META_U(unit,
   6690                                   "svp_type:%d \n"),
   6691                        flex_ingress_modes[unit][mode].ing_attr.
   6692                        cmprsd_attr_selectors.pkt_attr_bits.svp_type));
   6693             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6694                       (BSL_META_U(unit,
   6695                                   "drop:%d \n"),
   6696                        flex_ingress_modes[unit][mode].ing_attr.
   6697                        cmprsd_attr_selectors.pkt_attr_bits.drop));
   6698             alloc_size = soc_mem_index_count(unit,ING_FLEX_CTR_PKT_RES_MAPm) *
   6699                          sizeof(ing_flex_ctr_pkt_res_map_entry_t);
   6700             ing_pkt_res_map_dma = soc_cm_salloc( unit, alloc_size,
   6701                                                  "ING_FLEX_CTR_PKT_RES_MAPm");
   6702             if (ing_pkt_res_map_dma == NULL) {
   6703                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6704                           (BSL_META_U(unit,
   6705                                       "ING_FLEX_CTR_PKT_RES_MAPm:DMA AllocationFail\n")));
   6706                 return;
   6707             }
   6708             sal_memset(ing_pkt_res_map_dma, 0, alloc_size);
   6709             if(soc_mem_read_range(
   6710                    unit,
   6711                    ING_FLEX_CTR_PKT_RES_MAPm,
   6712                    MEM_BLOCK_ANY,
   6713                    soc_mem_index_min(unit,ING_FLEX_CTR_PKT_RES_MAPm),
   6714                    soc_mem_index_max(unit,ING_FLEX_CTR_PKT_RES_MAPm),
   6715                    ing_pkt_res_map_dma) != SOC_E_NONE) {
   6716                LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6717                          (BSL_META_U(unit,
   6718                                      "ING_FLEX_CTR_PKT_RES_MAPm:Read failure \n")));
   6719                soc_cm_sfree(unit,ing_pkt_res_map_dma);
   6720                return;
   6721             }
   6722             for(index=0;
   6723                 index< soc_mem_index_count(unit,ING_FLEX_CTR_PKT_RES_MAPm);
   6724                 index++) {
   6725                 soc_mem_field_get( unit, ING_FLEX_CTR_PKT_RES_MAPm,
   6726                      (uint32 *)&ing_pkt_res_map_dma[index], PKT_RES_FNf,
   6727                      &map_value);
   6728                 flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6729                                    pkt_res_attr_map[index]=(uint8)map_value;
   6730                 if (map_value) {
   6731                     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   6732                               (BSL_META_U(unit,
   6733                                           "Index:%dValue:%d\n"),
   6734                                index,map_value));
   6735                 }
   6736             }
   6737             soc_cm_sfree(unit,ing_pkt_res_map_dma);
   6738        }
   6739        if (flex_ingress_modes[unit][mode].ing_attr.cmprsd_attr_selectors.
   6740            pkt_attr_bits.ip_pkt) {
   6741            LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   6742                      (BSL_META_U(unit,
   6743                                  "ip_pkt:%d \n"),
   6744                       flex_ingress_modes[unit][mode].ing_attr.
   6745                       cmprsd_attr_selectors.pkt_attr_bits.ip_pkt));
   6746        }
   6747        return;
   6748     }
   6749     if (direction == bcmStatFlexDirectionEgress) {
   6750         flex_egress_modes[unit][mode].available=1;
   6751         /*Will be changed WhileReadingTables */
   6752         flex_egress_modes[unit][mode].reference_count=0;
   6753         flex_egress_modes[unit][mode].egr_attr.packet_attr_type =
   6754                                       bcmStatFlexPacketAttrTypeCompressed;
   6755         for (index=0;index<8;index++) {
   6756              if(selector_x_en_field_value[index] != 0) {
   6757                 if ((selector_for_bit_x_field_value[index] >=
   6758                      egr_pkt_attr_cmprsd_bits_g[unit].ip_pkt_pos) &&
   6759                     (selector_for_bit_x_field_value[index] <=
   6760                       (egr_pkt_attr_cmprsd_bits_g[unit].ip_pkt_pos+
   6761                        egr_pkt_attr_cmprsd_bits_g[unit].ip_pkt-1))) { /* 0..0 */
   6762                     flex_egress_modes[unit][mode].egr_attr.
   6763                      cmprsd_attr_selectors.pkt_attr_bits.ip_pkt = 1;
   6764                     continue;
   6765                 }
   6766                 if ((selector_for_bit_x_field_value[index] >=
   6767                      egr_pkt_attr_cmprsd_bits_g[unit].drop_pos) &&
   6768                     (selector_for_bit_x_field_value[index] <=
   6769                       (egr_pkt_attr_cmprsd_bits_g[unit].drop_pos+
   6770                        egr_pkt_attr_cmprsd_bits_g[unit].drop-1))) { /* 1..1 */
   6771                     flex_egress_modes[unit][mode].egr_attr.
   6772                      cmprsd_attr_selectors.pkt_attr_bits.drop = 1;
   6773                     continue;
   6774                 }
   6775                 if ((selector_for_bit_x_field_value[index] >=
   6776                      egr_pkt_attr_cmprsd_bits_g[unit].dvp_type_pos) &&
   6777                     (selector_for_bit_x_field_value[index] <=
   6778                       (egr_pkt_attr_cmprsd_bits_g[unit].dvp_type_pos+
   6779                        egr_pkt_attr_cmprsd_bits_g[unit].dvp_type-1))) { /* 2..2 */
   6780                     flex_egress_modes[unit][mode].egr_attr.
   6781                      cmprsd_attr_selectors.pkt_attr_bits.dvp_type = 1;
   6782                     continue;
   6783                 }
   6784                 if ((selector_for_bit_x_field_value[index] >=
   6785                      egr_pkt_attr_cmprsd_bits_g[unit].svp_type_pos) &&
   6786                     (selector_for_bit_x_field_value[index] <=
   6787                       (egr_pkt_attr_cmprsd_bits_g[unit].svp_type_pos+
   6788                        egr_pkt_attr_cmprsd_bits_g[unit].svp_type-1))) { /* 3..3 */
   6789                     flex_egress_modes[unit][mode].egr_attr.
   6790                      cmprsd_attr_selectors.pkt_attr_bits.svp_type = 1;
   6791                     continue;
   6792                 }
   6793                 if ((selector_for_bit_x_field_value[index] >=
   6794                      egr_pkt_attr_cmprsd_bits_g[unit].pkt_resolution_pos) &&
   6795                     (selector_for_bit_x_field_value[index] <=
   6796                       (egr_pkt_attr_cmprsd_bits_g[unit].pkt_resolution_pos+
   6797                        egr_pkt_attr_cmprsd_bits_g[unit].pkt_resolution-1))) { /* 4..4 */
   6798                     flex_egress_modes[unit][mode].egr_attr.
   6799                      cmprsd_attr_selectors.
   6800                     pkt_attr_bits.pkt_resolution = 1;
   6801                     continue;
   6802                 }
   6803                 if ((selector_for_bit_x_field_value[index] >=
   6804                      egr_pkt_attr_cmprsd_bits_g[unit].tos_dscp_pos) &&
   6805                     (selector_for_bit_x_field_value[index] <=
   6806                       (egr_pkt_attr_cmprsd_bits_g[unit].tos_dscp_pos+
   6807                        egr_pkt_attr_cmprsd_bits_g[unit].tos_dscp-1))) { /* 5..12 */
   6808                     flex_egress_modes[unit][mode].egr_attr.
   6809                      cmprsd_attr_selectors.pkt_attr_bits.tos_dscp++;
   6810                     continue;
   6811                 }
   6812                 if ((selector_for_bit_x_field_value[index] >=
   6813                      egr_pkt_attr_cmprsd_bits_g[unit].tos_ecn_pos) &&
   6814                     (selector_for_bit_x_field_value[index] <=
   6815                       (egr_pkt_attr_cmprsd_bits_g[unit].tos_ecn_pos+
   6816                        egr_pkt_attr_cmprsd_bits_g[unit].tos_ecn-1))) { /* 5..12 */
   6817                     flex_egress_modes[unit][mode].egr_attr.
   6818                      cmprsd_attr_selectors.pkt_attr_bits.tos_ecn++;
   6819                     continue;
   6820                 }
   6821                 if ((selector_for_bit_x_field_value[index] >=
   6822                      egr_pkt_attr_cmprsd_bits_g[unit].egr_port_pos) &&
   6823                     (selector_for_bit_x_field_value[index] <=
   6824                       (egr_pkt_attr_cmprsd_bits_g[unit].egr_port_pos+
   6825                        egr_pkt_attr_cmprsd_bits_g[unit].egr_port-1))) { /* 13..18 */
   6826                     flex_egress_modes[unit][mode].egr_attr.
   6827                      cmprsd_attr_selectors.pkt_attr_bits.egr_port++;
   6828                     continue;
   6829                 }
   6830                 if ((selector_for_bit_x_field_value[index] >=
   6831                      egr_pkt_attr_cmprsd_bits_g[unit].inner_dot1p_pos) &&
   6832                     (selector_for_bit_x_field_value[index] <=
   6833                       (egr_pkt_attr_cmprsd_bits_g[unit].inner_dot1p_pos+
   6834                        egr_pkt_attr_cmprsd_bits_g[unit].inner_dot1p-1))) { /* 19..21 */
   6835                      flex_egress_modes[unit][mode].egr_attr.
   6836                       cmprsd_attr_selectors.pkt_attr_bits.inner_dot1p++;
   6837                      continue;
   6838                 }
   6839                 if ((selector_for_bit_x_field_value[index] >=
   6840                      egr_pkt_attr_cmprsd_bits_g[unit].outer_dot1p_pos) &&
   6841                     (selector_for_bit_x_field_value[index] <=
   6842                       (egr_pkt_attr_cmprsd_bits_g[unit].outer_dot1p_pos+
   6843                        egr_pkt_attr_cmprsd_bits_g[unit].outer_dot1p-1))) { /* 22..24 */
   6844                      flex_egress_modes[unit][mode].egr_attr.
   6845                       cmprsd_attr_selectors.pkt_attr_bits.outer_dot1p++;
   6846                      continue;
   6847                 }
   6848                 if ((selector_for_bit_x_field_value[index] >=
   6849                      egr_pkt_attr_cmprsd_bits_g[unit].vlan_format_pos) &&
   6850                     (selector_for_bit_x_field_value[index] <=
   6851                       (egr_pkt_attr_cmprsd_bits_g[unit].vlan_format_pos+
   6852                        egr_pkt_attr_cmprsd_bits_g[unit].vlan_format-1))) { /* 25..26 */
   6853                      flex_egress_modes[unit][mode].egr_attr.
   6854                       cmprsd_attr_selectors.pkt_attr_bits.vlan_format++;
   6855                      continue;
   6856                 }
   6857                 if ((selector_for_bit_x_field_value[index] >=
   6858                      egr_pkt_attr_cmprsd_bits_g[unit].int_pri_pos) &&
   6859                     (selector_for_bit_x_field_value[index] <=
   6860                       (egr_pkt_attr_cmprsd_bits_g[unit].int_pri_pos+
   6861                        egr_pkt_attr_cmprsd_bits_g[unit].int_pri-1))) { /* 27..30 */
   6862                      flex_egress_modes[unit][mode].egr_attr.
   6863                       cmprsd_attr_selectors.pkt_attr_bits.int_pri++;
   6864                      continue;
   6865                 }
   6866                 if ((selector_for_bit_x_field_value[index] >=
   6867                      egr_pkt_attr_cmprsd_bits_g[unit].cng_pos) &&
   6868                     (selector_for_bit_x_field_value[index] <=
   6869                       (egr_pkt_attr_cmprsd_bits_g[unit].cng_pos+
   6870                        egr_pkt_attr_cmprsd_bits_g[unit].cng-1))) { /* 31..32 */
   6871                      flex_egress_modes[unit][mode].egr_attr.
   6872                       cmprsd_attr_selectors.pkt_attr_bits.cng++;
   6873                      continue;
   6874                 }
   6875 #ifdef BCM_APACHE_SUPPORT
   6876                 if (soc_feature(unit,soc_feature_flex_ctr_mpls_3_label_count)) {
   6877                     if ((selector_for_bit_x_field_value[index] >=
   6878                                 egr_pkt_attr_cmprsd_bits_g[unit].phb_1_pos) &&
   6879                             (selector_for_bit_x_field_value[index] <=
   6880                              (egr_pkt_attr_cmprsd_bits_g[unit].phb_1_pos +
   6881                               egr_pkt_attr_cmprsd_bits_g[unit].phb_1 - 1))) { /* 42 .. 45 */
   6882                         flex_egress_modes[unit][mode].egr_attr.
   6883                             cmprsd_attr_selectors.pkt_attr_bits.phb_1++;
   6884                         continue;
   6885                     }
   6886                     if ((selector_for_bit_x_field_value[index] >=
   6887                                 egr_pkt_attr_cmprsd_bits_g[unit].cng_1_pos) &&
   6888                             (selector_for_bit_x_field_value[index] <=
   6889                              (egr_pkt_attr_cmprsd_bits_g[unit].cng_1_pos +
   6890                               egr_pkt_attr_cmprsd_bits_g[unit].cng_1 - 1))) { /* 46 .. 47 */
   6891                         flex_egress_modes[unit][mode].egr_attr.
   6892                             cmprsd_attr_selectors.pkt_attr_bits.cng_1++;
   6893                         continue;
   6894                     }
   6895                     if ((selector_for_bit_x_field_value[index] >=
   6896                                 egr_pkt_attr_cmprsd_bits_g[unit].phb_2_pos) &&
   6897                             (selector_for_bit_x_field_value[index] <=
   6898                              (egr_pkt_attr_cmprsd_bits_g[unit].phb_2_pos +
   6899                               egr_pkt_attr_cmprsd_bits_g[unit].phb_2 - 1))) { /* 48 .. 51 */
   6900                         flex_egress_modes[unit][mode].egr_attr.
   6901                             cmprsd_attr_selectors.pkt_attr_bits.phb_2++;
   6902                         continue;
   6903                     }
   6904                     if ((selector_for_bit_x_field_value[index] >=
   6905                                 egr_pkt_attr_cmprsd_bits_g[unit].cng_2_pos) &&
   6906                             (selector_for_bit_x_field_value[index] <=
   6907                              (egr_pkt_attr_cmprsd_bits_g[unit].cng_2_pos +
   6908                               egr_pkt_attr_cmprsd_bits_g[unit].cng_2 - 1))) { /* 52 .. 53 */
   6909                         flex_egress_modes[unit][mode].egr_attr.
   6910                             cmprsd_attr_selectors.pkt_attr_bits.cng_2++;
   6911                         continue ;
   6912                     }
   6913                     if ((selector_for_bit_x_field_value[index] >=
   6914                                 egr_pkt_attr_cmprsd_bits_g[unit].phb_3_pos) &&
   6915                             (selector_for_bit_x_field_value[index] <=
   6916                              (egr_pkt_attr_cmprsd_bits_g[unit].phb_3_pos +
   6917                               egr_pkt_attr_cmprsd_bits_g[unit].phb_3 - 1))) { /* 54 .. 57 */
   6918                         flex_egress_modes[unit][mode].egr_attr.
   6919                             cmprsd_attr_selectors.pkt_attr_bits.phb_3++;
   6920                         continue;
   6921                     }
   6922                     if ((selector_for_bit_x_field_value[index] >=
   6923                                 egr_pkt_attr_cmprsd_bits_g[unit].cng_3_pos) &&
   6924                             (selector_for_bit_x_field_value[index] <=
   6925                              (egr_pkt_attr_cmprsd_bits_g[unit].cng_3_pos +
   6926                               egr_pkt_attr_cmprsd_bits_g[unit].cng_3 - 1))) { /* 58 .. 59 */
   6927                         flex_egress_modes[unit][mode].egr_attr.
   6928                             cmprsd_attr_selectors.pkt_attr_bits.cng_3++;
   6929                         continue;
   6930                     }
   6931                 }
   6932 #endif
   6933 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   6934                 if (soc_feature(unit, soc_feature_flex_stat_egr_queue_congestion_marked)) {
   6935                     if ((selector_for_bit_x_field_value[index] >=
   6936                                 egr_pkt_attr_cmprsd_bits_g[unit].congestion_marked_pos) &&
   6937                             (selector_for_bit_x_field_value[index] <=
   6938                              (egr_pkt_attr_cmprsd_bits_g[unit].congestion_marked_pos +
   6939                               egr_pkt_attr_cmprsd_bits_g[unit].congestion_marked - 1))) {
   6940                         flex_egress_modes[unit][mode].egr_attr.
   6941                             cmprsd_attr_selectors.pkt_attr_bits.congestion_marked++;
   6942                         continue;
   6943                     }
   6944                     if ((selector_for_bit_x_field_value[index] >=
   6945                                 egr_pkt_attr_cmprsd_bits_g[unit].uc_queueing_pos) &&
   6946                             (selector_for_bit_x_field_value[index] <=
   6947                              (egr_pkt_attr_cmprsd_bits_g[unit].uc_queueing_pos +
   6948                               egr_pkt_attr_cmprsd_bits_g[unit].uc_queueing - 1))) {
   6949                         flex_egress_modes[unit][mode].egr_attr.
   6950                             cmprsd_attr_selectors.pkt_attr_bits.uc_queueing++;
   6951                         continue;
   6952                     }
   6953                     if ((selector_for_bit_x_field_value[index] >=
   6954                                 egr_pkt_attr_cmprsd_bits_g[unit].mmu_cos_pos) &&
   6955                             (selector_for_bit_x_field_value[index] <=
   6956                              (egr_pkt_attr_cmprsd_bits_g[unit].mmu_cos_pos +
   6957                               egr_pkt_attr_cmprsd_bits_g[unit].mmu_cos - 1))) {
   6958                         flex_egress_modes[unit][mode].egr_attr.
   6959                             cmprsd_attr_selectors.pkt_attr_bits.mmu_cos++;
   6960                         continue;
   6961                     }
   6962                 }
   6963 #endif
   6964 
   6965             }
   6966         }
   6967 #ifdef BCM_APACHE_SUPPORT
   6968         if (soc_feature(unit,soc_feature_flex_ctr_mpls_3_label_count)) {
   6969             if (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6970                     pkt_attr_bits.cng_3 ) {
   6971                 flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6972                     cng_3 = egr_pkt_attr_cmprsd_bits_g[unit].cng_3;
   6973             }
   6974             if (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6975                     pkt_attr_bits.phb_3 ) {
   6976                 flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6977                     phb_3 = egr_pkt_attr_cmprsd_bits_g[unit].phb_3;
   6978             }
   6979             if (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6980                     pkt_attr_bits.cng_2 ) {
   6981                 flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6982                     cng_2 = egr_pkt_attr_cmprsd_bits_g[unit].cng_2;
   6983             }
   6984             if (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6985                     pkt_attr_bits.phb_2 ) {
   6986                 flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6987                     phb_2 = egr_pkt_attr_cmprsd_bits_g[unit].phb_2;
   6988             }
   6989             if (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6990                     pkt_attr_bits.cng_1 ) {
   6991                 flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6992                     cng_1 = egr_pkt_attr_cmprsd_bits_g[unit].cng_1;
   6993             }
   6994             if (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6995                     pkt_attr_bits.phb_1 ) {
   6996                 flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   6997                     phb_1 = egr_pkt_attr_cmprsd_bits_g[unit].phb_1;
   6998             }
   6999         }
   7000 #endif
   7001 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   7002        if (soc_feature(unit, soc_feature_flex_stat_egr_queue_congestion_marked)) {
   7003            if ((flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7004                   pkt_attr_bits.uc_queueing) ||
   7005                 (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7006                   pkt_attr_bits.mmu_cos) ) {
   7007                  LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7008                            (BSL_META_U(unit,
   7009                                        "uc_queueing:%d \n"),
   7010                             flex_egress_modes[unit][mode].egr_attr.
   7011                             cmprsd_attr_selectors.pkt_attr_bits.uc_queueing));
   7012                  LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7013                            (BSL_META_U(unit,
   7014                                        "mmu_cos:%d \n"),
   7015                             flex_egress_modes[unit][mode].
   7016                             egr_attr.cmprsd_attr_selectors.pkt_attr_bits.
   7017                             mmu_cos));
   7018                  alloc_size = soc_mem_index_count(unit, EGR_FLEX_CTR_COS_MAPm) *
   7019                               sizeof(egr_flex_ctr_cos_map_entry_t);
   7020                  egr_cos_uc_map_dma = soc_cm_salloc( unit, alloc_size,
   7021                                                       "EGR_FLEX_CTR_COS_MAPm");
   7022                  if (egr_cos_uc_map_dma == NULL) {
   7023                      LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7024                                (BSL_META_U(unit,
   7025                                            "EGR_FLEX_CTR_COS_MAPm:DMAAllocationFail\n")));
   7026                      return;
   7027                  }
   7028                  sal_memset(egr_cos_uc_map_dma, 0, alloc_size);
   7029                  if (soc_mem_read_range(
   7030                          unit,
   7031                          EGR_FLEX_CTR_COS_MAPm,
   7032                          MEM_BLOCK_ANY,
   7033                          soc_mem_index_min(unit, EGR_FLEX_CTR_COS_MAPm),
   7034                          soc_mem_index_max(unit, EGR_FLEX_CTR_COS_MAPm),
   7035                          egr_cos_uc_map_dma) != SOC_E_NONE) {
   7036                      LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7037                                (BSL_META_U(unit,
   7038                                            "EGR_FLEX_CTR_COS_MAPm:Read failure \n")));
   7039                      soc_cm_sfree(unit, egr_cos_uc_map_dma);
   7040                      return;
   7041                  }
   7042                  for (index = 0;
   7043                       index < soc_mem_index_count(unit, EGR_FLEX_CTR_COS_MAPm);
   7044                       index++) {
   7045                       soc_mem_field_get( unit, EGR_FLEX_CTR_COS_MAPm,
   7046                            (uint32 *)&egr_cos_uc_map_dma[index], COS_FNf,
   7047                            &map_value);
   7048                       flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7049                                       cos_uc_attr_map[index]=(uint8)map_value;
   7050                       if (map_value) {
   7051                           LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7052                                     (BSL_META_U(unit,
   7053                                                 "Index:%dValue:%d\n"),
   7054                                      index, map_value));
   7055                       }
   7056                  }
   7057                  soc_cm_sfree(unit, egr_cos_uc_map_dma);
   7058             }
   7059        }
   7060 #endif
   7061        if ((flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7062               pkt_attr_bits.cng) ||
   7063             (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7064               pkt_attr_bits.int_pri) ) {
   7065              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7066                        (BSL_META_U(unit,
   7067                                    "cng:%d \n"),
   7068                         flex_egress_modes[unit][mode].egr_attr.
   7069                         cmprsd_attr_selectors.pkt_attr_bits.cng));
   7070              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7071                        (BSL_META_U(unit,
   7072                                    "int_pri:%d \n"),
   7073                         flex_egress_modes[unit][mode].
   7074                         egr_attr.cmprsd_attr_selectors.pkt_attr_bits.
   7075                         int_pri));
   7076              alloc_size = soc_mem_index_count(unit,EGR_FLEX_CTR_PRI_CNG_MAPm) *
   7077                           sizeof(egr_flex_ctr_pri_cng_map_entry_t);
   7078              egr_pri_cng_map_dma = soc_cm_salloc( unit, alloc_size,
   7079                                                   "EGR_FLEX_CTR_PRI_CNG_MAPm");
   7080              if (egr_pri_cng_map_dma == NULL) {
   7081                  LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7082                            (BSL_META_U(unit,
   7083                                        "EGR_FLEX_CTR_PRI_CNG_MAPm:DMAAllocationFail\n")));
   7084                  return;
   7085              }
   7086  
   7087              sal_memset(egr_pri_cng_map_dma, 0, alloc_size);
   7088 
   7089              if (soc_mem_read_range(
   7090                      unit,
   7091                      EGR_FLEX_CTR_PRI_CNG_MAPm,
   7092                      MEM_BLOCK_ANY,
   7093                      soc_mem_index_min(unit,EGR_FLEX_CTR_PRI_CNG_MAPm),
   7094                      soc_mem_index_max(unit,EGR_FLEX_CTR_PRI_CNG_MAPm),
   7095                      egr_pri_cng_map_dma) != SOC_E_NONE) {
   7096                  LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7097                            (BSL_META_U(unit,
   7098                                        "EGR_FLEX_CTR_PRI_CNG_MAPm:Read failure \n")));
   7099                  soc_cm_sfree(unit,egr_pri_cng_map_dma);
   7100                  return;
   7101              }
   7102              for (index=0;
   7103                   index< soc_mem_index_count(unit,EGR_FLEX_CTR_PRI_CNG_MAPm);
   7104                   index++) {
   7105                   soc_mem_field_get( unit, EGR_FLEX_CTR_PRI_CNG_MAPm,
   7106                        (uint32 *)&egr_pri_cng_map_dma[index], PRI_CNG_FNf,
   7107                        &map_value);
   7108                   flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7109                                    pri_cnf_attr_map[index]=(uint8)map_value;
   7110                   if (map_value) {
   7111                       LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7112                                 (BSL_META_U(unit,
   7113                                             "Index:%dValue:%d\n"),
   7114                                  index,map_value));
   7115                   }
   7116              }
   7117              soc_cm_sfree(unit,egr_pri_cng_map_dma);
   7118         }
   7119         if ((flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7120              pkt_attr_bits.vlan_format) ||
   7121             (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7122              pkt_attr_bits.outer_dot1p) ||
   7123             (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7124              pkt_attr_bits.inner_dot1p)) {
   7125              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7126                        (BSL_META_U(unit,
   7127                                    "vlan_format:%d \n"),
   7128                         flex_egress_modes[unit][mode].egr_attr.
   7129                         cmprsd_attr_selectors.pkt_attr_bits.vlan_format));
   7130              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7131                        (BSL_META_U(unit,
   7132                                    "outer_dot1p:%d \n"),
   7133                         flex_egress_modes[unit][mode].egr_attr.
   7134                         cmprsd_attr_selectors.pkt_attr_bits.outer_dot1p));
   7135              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7136                        (BSL_META_U(unit,
   7137                                    "inner_dot1p:%d \n"),
   7138                         flex_egress_modes[unit][mode].egr_attr.
   7139                         cmprsd_attr_selectors.pkt_attr_bits.inner_dot1p));
   7140              alloc_size = soc_mem_index_count(unit,EGR_FLEX_CTR_PKT_PRI_MAPm) *
   7141                           sizeof(egr_flex_ctr_pkt_pri_map_entry_t);
   7142              egr_pkt_pri_map_dma = soc_cm_salloc( unit, alloc_size,
   7143                                                  "EGR_FLEX_CTR_PKT_PRI_MAPm");
   7144              if (egr_pkt_pri_map_dma == NULL) {
   7145                  LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7146                            (BSL_META_U(unit,
   7147                                        "EGR_FLEX_CTR_PKT_PRI_MAPm:DMAAllocationFail\n")));
   7148                  return;
   7149              }
   7150              sal_memset(egr_pkt_pri_map_dma, 0, alloc_size);
   7151              if (soc_mem_read_range(
   7152                      unit,
   7153                      EGR_FLEX_CTR_PKT_PRI_MAPm,
   7154                      MEM_BLOCK_ANY,
   7155                      soc_mem_index_min(unit,EGR_FLEX_CTR_PKT_PRI_MAPm),
   7156                      soc_mem_index_max(unit,EGR_FLEX_CTR_PKT_PRI_MAPm),
   7157                      egr_pkt_pri_map_dma) != SOC_E_NONE) {
   7158                  LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7159                            (BSL_META_U(unit,
   7160                                        "EGR_FLEX_CTR_PKT_PRI_MAPm:Read failure \n")));
   7161                  soc_cm_sfree(unit,egr_pkt_pri_map_dma);
   7162                  return;
   7163              }
   7164              for (index=0;
   7165                   index< soc_mem_index_count(unit,EGR_FLEX_CTR_PKT_PRI_MAPm);
   7166                   index++) {
   7167                   soc_mem_field_get( unit, EGR_FLEX_CTR_PKT_PRI_MAPm,
   7168                        (uint32 *)&egr_pkt_pri_map_dma[index], PKT_PRI_FNf,
   7169                        &map_value);
   7170                   flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7171                                    pkt_pri_attr_map[index]=(uint8)map_value;
   7172                   if (map_value) {
   7173                       LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7174                                 (BSL_META_U(unit,
   7175                                             "Index:%dValue:%d\n"),
   7176                                  index,map_value));
   7177                   }
   7178              }
   7179              soc_cm_sfree(unit,egr_pkt_pri_map_dma);
   7180         }
   7181         if (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7182             pkt_attr_bits.egr_port) {
   7183             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7184                       (BSL_META_U(unit,
   7185                                   "egr_port:%d \n"),
   7186                        flex_egress_modes[unit][mode].
   7187                        egr_attr.cmprsd_attr_selectors.
   7188                        pkt_attr_bits.egr_port));
   7189             alloc_size = soc_mem_index_count(unit,EGR_FLEX_CTR_PORT_MAPm) *
   7190                          sizeof(egr_flex_ctr_port_map_entry_t);
   7191             egr_port_map_dma = soc_cm_salloc( unit, alloc_size,
   7192                                               "EGR_FLEX_CTR_PORT_MAPm");
   7193             if (egr_port_map_dma == NULL) {
   7194                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7195                           (BSL_META_U(unit,
   7196                                       "EGR_FLEX_CTR_PORT_MAPm:DMA AllocationFail\n")));
   7197                 return;
   7198             }
   7199             sal_memset(egr_port_map_dma, 0, alloc_size);
   7200             if (soc_mem_read_range(
   7201                     unit,
   7202                     EGR_FLEX_CTR_PORT_MAPm,
   7203                     MEM_BLOCK_ANY,
   7204                     soc_mem_index_min(unit,EGR_FLEX_CTR_PORT_MAPm),
   7205                     soc_mem_index_max(unit,EGR_FLEX_CTR_PORT_MAPm),
   7206                     egr_port_map_dma) != SOC_E_NONE) {
   7207                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7208                           (BSL_META_U(unit,
   7209                                       "EGR_FLEX_CTR_PKT_PRI_MAPm:Read failure \n")));
   7210                 soc_cm_sfree(unit,egr_port_map_dma);
   7211                 return;
   7212             }
   7213             for (index=0;
   7214                  index< soc_mem_index_count(unit,EGR_FLEX_CTR_PORT_MAPm);
   7215                  index++) {
   7216                  soc_mem_field_get( unit, EGR_FLEX_CTR_PORT_MAPm,
   7217                       (uint32 *)&egr_port_map_dma[index], PORT_FNf,
   7218                       &map_value);
   7219                  flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7220                                   port_attr_map[index] = (uint8)map_value;
   7221                  if (map_value) {
   7222                      LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7223                                (BSL_META_U(unit,
   7224                                            "Index:%dValue:%d\n"),
   7225                                 index,map_value));
   7226                  }
   7227             }
   7228             soc_cm_sfree(unit,egr_port_map_dma);
   7229         }
   7230         if ((flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7231              pkt_attr_bits.tos_dscp)  ||
   7232             (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7233              pkt_attr_bits.tos_ecn)) {
   7234             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7235                       (BSL_META_U(unit,
   7236                                   "tos_dscp:%d tos_ecn:%d \n"),
   7237                        flex_egress_modes[unit][mode].egr_attr.
   7238                        cmprsd_attr_selectors.pkt_attr_bits.tos_dscp,
   7239                        flex_egress_modes[unit][mode].egr_attr.
   7240                        cmprsd_attr_selectors.pkt_attr_bits.tos_ecn));
   7241             alloc_size = soc_mem_index_count(unit,EGR_FLEX_CTR_TOS_MAPm) *
   7242                          sizeof(egr_flex_ctr_tos_map_entry_t);
   7243             egr_tos_map_dma = soc_cm_salloc( unit, alloc_size,
   7244                                              "EGR_FLEX_CTR_TOS_MAPm");
   7245             if (egr_tos_map_dma == NULL) {
   7246                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7247                           (BSL_META_U(unit,
   7248                                       "EGR_FLEX_CTR_TOS_MAPm:DMA Allocation failure\n")));
   7249                 return;
   7250             }
   7251             sal_memset(egr_tos_map_dma, 0, alloc_size);
   7252             if(soc_mem_read_range(
   7253                    unit,
   7254                    EGR_FLEX_CTR_TOS_MAPm,
   7255                    MEM_BLOCK_ANY,
   7256                    soc_mem_index_min(unit,EGR_FLEX_CTR_TOS_MAPm),
   7257                    soc_mem_index_max(unit,EGR_FLEX_CTR_TOS_MAPm),
   7258                    egr_tos_map_dma) != SOC_E_NONE) {
   7259                LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7260                          (BSL_META_U(unit,
   7261                                      "EGR_FLEX_CTR_TOS_MAPm:Read failure \n")));
   7262                soc_cm_sfree(unit,egr_tos_map_dma);
   7263                return;
   7264             }
   7265             for (index=0;
   7266                  index< soc_mem_index_count(unit,EGR_FLEX_CTR_TOS_MAPm);
   7267                  index++) {
   7268                  soc_mem_field_get( unit, EGR_FLEX_CTR_TOS_MAPm,
   7269                       (uint32 *)&egr_tos_map_dma[index], TOS_FNf, &map_value);
   7270                  flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7271                                   tos_attr_map[index] = (uint8)map_value;
   7272                  if (map_value) {
   7273                      LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7274                                (BSL_META_U(unit,
   7275                                            "Index:%dValue:%d\n"),
   7276                                 index,map_value));
   7277                  }
   7278             }
   7279             soc_cm_sfree(unit,egr_tos_map_dma);
   7280         }
   7281         if ((flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7282              pkt_attr_bits.pkt_resolution) ||
   7283             (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7284              pkt_attr_bits.svp_type) ||
   7285             (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7286              pkt_attr_bits.dvp_type) ||
   7287             (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7288              pkt_attr_bits.drop) ) {
   7289              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7290                        (BSL_META_U(unit,
   7291                                    "pkt_resolution:%d \n"),
   7292                         flex_egress_modes[unit][mode].egr_attr.
   7293                         cmprsd_attr_selectors.pkt_attr_bits.
   7294                         pkt_resolution));
   7295              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7296                        (BSL_META_U(unit,
   7297                                    "svp_type:%d \n"),
   7298                         flex_egress_modes[unit][mode].egr_attr.
   7299                         cmprsd_attr_selectors.pkt_attr_bits.svp_type));
   7300              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7301                        (BSL_META_U(unit,
   7302                                    "dvp_type:%d \n"),
   7303                         flex_egress_modes[unit][mode].egr_attr.
   7304                         cmprsd_attr_selectors.pkt_attr_bits.dvp_type));
   7305              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7306                        (BSL_META_U(unit,
   7307                                    "drop:%d \n"),
   7308                         flex_egress_modes[unit][mode].egr_attr.
   7309                         cmprsd_attr_selectors.pkt_attr_bits.drop));
   7310              alloc_size = soc_mem_index_count(unit,EGR_FLEX_CTR_PKT_RES_MAPm) *
   7311                           sizeof(egr_flex_ctr_pkt_res_map_entry_t);
   7312              egr_pkt_res_map_dma = soc_cm_salloc( unit, alloc_size,
   7313                                                  "EGR_FLEX_CTR_PKT_RES_MAPm");
   7314              if (egr_pkt_res_map_dma == NULL) {
   7315                  LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7316                            (BSL_META_U(unit,
   7317                                        "EGR_FLEX_CTR_PKT_RES_MAPm:DMAAllocationFail\n")));
   7318                  return;
   7319              }
   7320              sal_memset(egr_pkt_res_map_dma, 0, alloc_size);
   7321              if (soc_mem_read_range(
   7322                      unit,
   7323                      EGR_FLEX_CTR_PKT_RES_MAPm,
   7324                      MEM_BLOCK_ANY,
   7325                      soc_mem_index_min(unit,EGR_FLEX_CTR_PKT_RES_MAPm),
   7326                      soc_mem_index_max(unit,EGR_FLEX_CTR_PKT_RES_MAPm),
   7327                      egr_pkt_res_map_dma) != BCM_E_NONE) {
   7328                  LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7329                            (BSL_META_U(unit,
   7330                                        "EGR_FLEX_CTR_TOS_MAPm:Read failure \n")));
   7331                  soc_cm_sfree(unit,egr_pkt_res_map_dma);
   7332                  return;
   7333              }
   7334              for (index=0;
   7335                   index< soc_mem_index_count(unit,EGR_FLEX_CTR_PKT_RES_MAPm);
   7336                   index++) {
   7337                   soc_mem_field_get( unit, EGR_FLEX_CTR_PKT_RES_MAPm,
   7338                       (uint32 *)&egr_pkt_res_map_dma[index], PKT_RES_FNf,
   7339                       &map_value);
   7340                   flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7341                                    pkt_res_attr_map[index]= (uint8)map_value;
   7342 
   7343                   if (map_value) {
   7344                       LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7345                                 (BSL_META_U(unit,
   7346                                             "Index:%dValue:%d\n"),
   7347                                  index,map_value));
   7348                   }
   7349              }
   7350              soc_cm_sfree(unit,egr_pkt_res_map_dma);
   7351         }
   7352         if (flex_egress_modes[unit][mode].egr_attr.cmprsd_attr_selectors.
   7353             pkt_attr_bits.ip_pkt ) {
   7354             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7355                       (BSL_META_U(unit,
   7356                                   "ip_pkt:%d \n"),
   7357                        flex_egress_modes[unit][mode].
   7358                        egr_attr.cmprsd_attr_selectors.
   7359                        pkt_attr_bits.ip_pkt));
   7360         }
   7361         return;
   7362     }
   7363     LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7364               (BSL_META_U(unit,
   7365                           "Ooops. Control Must not reach over here \n")));
   7366 }
   7367 /*
   7368  * Function:
   7369  *      _bcm_esw_stat_flex_init_udf_mode
   7370  * Description:
   7371  *      Configures flex hw for udf mode
   7372  * Parameters:
   7373  *      unit                           - (IN) unit number
   7374  *      mode                           - (IN) Flex Offset Mode
   7375  *      direction                      - (IN) Flex Data flow direction(ing/egr)
   7376  *      selector_count                 - (IN) Flex Key selector count
   7377  *      selector_x_en_field_value      - (IN) Flex Key selector fields
   7378  *      selector_for_bit_x_field_value - (IN) Flex Key selector field bits
   7379  *
   7380  * Return Value:
   7381  *      None
   7382  * Notes:
   7383  *      Currently not being used!
   7384  */
   7385 static void
   7386 _bcm_esw_stat_flex_init_udf_mode(
   7387     int                       unit,
   7388     int                       mode,
   7389     bcm_stat_flex_direction_t direction,
   7390     uint32                    selector_count,
   7391     uint32                    selector_x_en_field_value[8],
   7392     uint32                    selector_for_bit_x_field_value[8])
   7393 {
   7394     uint16  udf0=0;
   7395     uint16  udf1=0;
   7396     uint32  index=0;
   7397     for (udf0=0,udf1=0,index=0;index<8;index++) {
   7398          if (selector_for_bit_x_field_value[index] != 0) {
   7399              if (selector_for_bit_x_field_value[index] <=16) {
   7400                  udf0 |= (1 << (selector_for_bit_x_field_value[index]-1));
   7401              } else {
   7402                  udf1 |= (1 << (selector_for_bit_x_field_value[index]- 16 - 1));
   7403              }
   7404          }
   7405     }
   7406     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7407               (BSL_META_U(unit,
   7408                           "UDF0 : 0x%04x UDF1 0x%04x \n"),
   7409                udf0,udf1));
   7410     if (direction == bcmStatFlexDirectionIngress) {
   7411         flex_ingress_modes[unit][mode].available=1;
   7412         /*Will be changed WhileReadingTables */
   7413         flex_ingress_modes[unit][mode].reference_count=0;
   7414         flex_ingress_modes[unit][mode].total_counters= ( 1 << selector_count);
   7415         flex_ingress_modes[unit][mode].ing_attr.packet_attr_type =
   7416              bcmStatFlexPacketAttrTypeUdf;
   7417         flex_ingress_modes[unit][mode].ing_attr.udf_pkt_attr_selectors.
   7418              udf_pkt_attr_bits.udf0 = udf0;
   7419         flex_ingress_modes[unit][mode].ing_attr.udf_pkt_attr_selectors.
   7420              udf_pkt_attr_bits.udf1 = udf1;
   7421         return;
   7422     }
   7423     if (direction == bcmStatFlexDirectionEgress) {
   7424         flex_egress_modes[unit][mode].available=1;
   7425         /*Will be changed WhileReadingTables */
   7426         flex_egress_modes[unit][mode].reference_count=0;
   7427         flex_egress_modes[unit][mode].total_counters= ( 1 << selector_count);
   7428         flex_egress_modes[unit][mode].egr_attr.packet_attr_type =
   7429              bcmStatFlexPacketAttrTypeUdf;
   7430         flex_egress_modes[unit][mode].egr_attr.udf_pkt_attr_selectors.
   7431              udf_pkt_attr_bits.udf0 = udf0;
   7432         flex_egress_modes[unit][mode].egr_attr.udf_pkt_attr_selectors.
   7433              udf_pkt_attr_bits.udf1 = udf1;
   7434         return;
   7435     }
   7436     LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   7437               (BSL_META_U(unit,
   7438                           "Ooops. Control Must not reach over here \n")));
   7439 }
   7440 /*
   7441  * Function:
   7442  *      _bcm_esw_stat_flex_check_egress_dvp_1_table
   7443  * Description:
   7444  *      Checks egress_dvp_1 table for flex configuration
   7445  * Parameters:
   7446  *      unit                  - (IN) unit number
   7447  * Return Value:
   7448  *      None
   7449  * Notes:
   7450  *      Applicable in warm boot scenario only!
   7451  */
   7452 static void
   7453 _bcm_esw_stat_flex_check_egress_dvp_1_table(int unit)
   7454 {
   7455     uint32    index=0;
   7456     do {
   7457         _bcm_esw_stat_flex_check_egress_table(unit,EGR_DVP_ATTRIBUTE_1m,
   7458              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7459         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7460     } while (index < soc_mem_index_count(unit,EGR_DVP_ATTRIBUTE_1m));
   7461 
   7462     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7463               (BSL_META_U(unit,
   7464                           "Checked EGRESS:EGR_DVP_ATTRIBUTE_1m %d entries..\n"),
   7465                index-1));
   7466 }
   7467 /*
   7468  * Function:
   7469  *      _bcm_esw_stat_flex_check_egress_l3_next_hop_table
   7470  * Description:
   7471  *      Checks egress_l3_next_hop table for flex configuration
   7472  * Parameters:
   7473  *      unit                  - (IN) unit number
   7474  * Return Value:
   7475  *      None
   7476  * Notes:
   7477  *      Applicable in warm boot scenario only!
   7478  */
   7479 static void
   7480 _bcm_esw_stat_flex_check_egress_l3_next_hop_table(int unit)
   7481 {
   7482     uint32    index=0;
   7483     /*egr_l3_next_hop_entry_t  egr_l3_next_hop_entry_v; */
   7484     do {
   7485         _bcm_esw_stat_flex_check_egress_table(unit,EGR_L3_NEXT_HOPm,
   7486              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7487         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7488     } while (index < soc_mem_index_count(unit,EGR_L3_NEXT_HOPm));
   7489 
   7490     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7491               (BSL_META_U(unit,
   7492                           "Checked EGRESS:EGR_L3_NEXT_HOP %d entries..\n"),
   7493                index-1));
   7494 }
   7495 /*
   7496  * Function:
   7497  *      _bcm_esw_stat_flex_check_egress_mpls_tunnel_table
   7498  * Description:
   7499  *      Checks egress_mpls_tunnel table for flex configuration
   7500  * Parameters:
   7501  *      unit                  - (IN) unit number
   7502  * Return Value:
   7503  *      None
   7504  * Notes:
   7505  *      Applicable in warm boot scenario only!
   7506  */
   7507 void
   7508 _bcm_esw_stat_flex_check_egress_mpls_tunnel_table(int unit)
   7509 {
   7510 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   7511     uint32    index=0;
   7512     soc_mem_t mem = EGR_IP_TUNNEL_MPLSm;
   7513 #ifdef BCM_TRIDENT3_SUPPORT
   7514     if (SOC_IS_TRIDENT3X(unit) && soc_feature(unit, soc_feature_td3_style_mpls)) {
   7515         mem = EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm;
   7516     }
   7517 #endif
   7518     do {
   7519         _bcm_esw_stat_flex_check_egress_table(unit,mem,
   7520              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7521         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7522     } while (index < soc_mem_index_count(unit,mem));
   7523 
   7524     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7525               (BSL_META_U(unit,
   7526                           "Checked EGRESS:EGR_IP_TUNNEL_MPLS %d entries..\n"),
   7527                index-1));
   7528 #endif
   7529 }
   7530 /*
   7531  * Function:
   7532  *      _bcm_esw_stat_flex_check_egress_vlan_table
   7533  * Description:
   7534  *      Checks egress_vlan table for flex configuration
   7535  * Parameters:
   7536  *      unit                  - (IN) unit number
   7537  * Return Value:
   7538  *      None
   7539  * Notes:
   7540  *      Applicable in warm boot scenario only!
   7541  */
   7542 static void
   7543 _bcm_esw_stat_flex_check_egress_vlan_table(int unit)
   7544 {
   7545     uint32    index=0;
   7546     /*egr_vlan_entry_t  egr_vlan_entry_v;*/
   7547     do {
   7548         _bcm_esw_stat_flex_check_egress_table(unit,EGR_VLANm,
   7549              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7550         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7551     } while (index< soc_mem_index_count(unit,EGR_VLANm));
   7552     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7553               (BSL_META_U(unit,
   7554                           "Checked EGRESS:EGR_VLAN %d entries..\n"),
   7555                index-1));
   7556 }
   7557 
   7558 /*
   7559  * Function:
   7560  *      _bcm_esw_stat_flex_check_egress_nat_pkt_edit_table
   7561  * Description:
   7562  *      Checks egress_nat_packet_edit table for flex configuration
   7563  * Parameters:
   7564  *      unit                  - (IN) unit number
   7565  * Return Value:
   7566  *      None
   7567  * Notes:
   7568  *      Applicable in warm boot scenario only!
   7569  */
   7570 static void
   7571 _bcm_esw_stat_flex_check_egress_nat_pkt_edit_table(int unit)
   7572 {
   7573     uint32    index=0;
   7574 
   7575     if (soc_feature(unit, soc_feature_nat)) {
   7576         do {
   7577             _bcm_esw_stat_flex_check_egress_table(unit,EGR_NAT_PACKET_EDIT_INFOm,
   7578                  index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7579             index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7580         } while (index< soc_mem_index_count(unit,EGR_NAT_PACKET_EDIT_INFOm));
   7581         LOG_DEBUG(BSL_LS_BCM_FLEXCTR, (BSL_META_U(unit,
   7582                           "Checked EGRESS: EGR_NAT_PACKET_EDIT_INFO %d entries..\n"),
   7583                index-1));
   7584     }
   7585 }
   7586 
   7587 #if defined(BCM_TRIDENT3_SUPPORT)
   7588 /*
   7589  * Function:
   7590  *      _bcm_esw_stat_flex_check_egress_dvp_table
   7591  * Description:
   7592  *      Checks egress_dvp_attr table for flex configuration
   7593  * Parameters:
   7594  *      unit                  - (IN) unit number
   7595  * Return Value:
   7596  *      None
   7597  * Notes:
   7598  *      Applicable in warm boot scenario only!
   7599  */
   7600 static void
   7601 _bcm_esw_stat_flex_check_egress_dvp_table(int unit)
   7602 {
   7603     uint32    index=0;
   7604     do {
   7605         _bcm_esw_stat_flex_check_egress_table(unit,EGR_DVP_ATTRIBUTEm,
   7606              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7607         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7608     } while (index < soc_mem_index_count(unit,EGR_DVP_ATTRIBUTEm));
   7609 
   7610     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7611               (BSL_META_U(unit,
   7612                           "Checked EGRESS:EGR_DVP_ATTRIBUTEm %d entries..\n"),
   7613                index-1));
   7614 }
   7615 #endif
   7616 
   7617 /*
   7618  * Function:
   7619  *      _bcm_esw_stat_flex_check_ingress_vlan_table
   7620  * Description:
   7621  *      Checks ingress vlan table for flex configuration
   7622  * Parameters:
   7623  *      unit                  - (IN) unit number
   7624  * Return Value:
   7625  *      None
   7626  * Notes:
   7627  *      Applicable in warm boot scenario only!
   7628  */
   7629 static void
   7630 _bcm_esw_stat_flex_check_ingress_vlan_table(int unit)
   7631 {
   7632     uint32    index=0;
   7633     /*vlan_tab_entry_t  vlan_tab_entry_v;*/
   7634     do {
   7635         _bcm_esw_stat_flex_check_ingress_table(unit,VLAN_TABm,
   7636              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7637         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7638     } while(index<soc_mem_index_count(unit,VLAN_TABm));
   7639     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7640               (BSL_META_U(unit,
   7641                           "Checked INGRESS:VLAN_TAB %d entries..\n"),
   7642                index-1));
   7643 }
   7644 
   7645 #ifdef BCM_TOMAHAWK_SUPPORT
   7646 #ifdef BCM_WARM_BOOT_SUPPORT
   7647 static void
   7648 _bcm_esw_stat_flex_check_ingress_agm_table(int unit)
   7649 {
   7650     uint32    index=0;
   7651     do {
   7652         _bcm_esw_stat_flex_check_ingress_table(unit,AGM_MONITOR_TABLEm,
   7653              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7654         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7655     } while(index<soc_mem_index_count(unit,AGM_MONITOR_TABLEm));
   7656     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7657               (BSL_META_U(unit,
   7658                           "Checked INGRESS:Agg Monitor %d entries..\n"),
   7659                index-1));
   7660 }
   7661 #endif
   7662 #endif
   7663 
   7664 /*
   7665  * Function:
   7666  *      _bcm_esw_stat_flex_check_ingress_vrf_table
   7667  * Description:
   7668  *      Checks ingress vrf table for flex configuration
   7669  * Parameters:
   7670  *      unit                  - (IN) unit number
   7671  * Return Value:
   7672  *      None
   7673  * Notes:
   7674  *      Applicable in warm boot scenario only!
   7675  */
   7676 static void
   7677 _bcm_esw_stat_flex_check_ingress_vrf_table(int unit)
   7678 {
   7679     uint32    index=0;
   7680     /*vrf_entry_t  vrf_entry_v;*/
   7681     soc_mem_t ingress_table = VRFm;
   7682 
   7683 #if defined (BCM_TRIDENT3_SUPPORT)
   7684         if (SOC_IS_TRIDENT3X(unit)){
   7685             ingress_table = VRF_ATTRS_2m;
   7686         }
   7687 #endif
   7688 
   7689     if (!SOC_MEM_IS_VALID(unit, ingress_table)) {
   7690         return; 
   7691     }
   7692 
   7693     if (soc_mem_index_count(unit, ingress_table) <= 0) {
   7694         return;
   7695     }
   7696 
   7697     do {
   7698         _bcm_esw_stat_flex_check_ingress_table(unit,ingress_table,
   7699              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7700         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7701     } while (index<soc_mem_index_count(unit,ingress_table));
   7702     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7703               (BSL_META_U(unit,
   7704                           "Checked INGRESS:VRF %d entries..\n"),
   7705                index-1));
   7706 }
   7707 /*
   7708  * Function:
   7709  *      _bcm_esw_stat_flex_check_egress_vfi_table
   7710  * Description:
   7711  *      Checks egress vfi table for flex configuration
   7712  * Parameters:
   7713  *      unit                  - (IN) unit number
   7714  * Return Value:
   7715  *      None
   7716  * Notes:
   7717  *      Applicable in warm boot scenario only!
   7718  */
   7719 static void
   7720 _bcm_esw_stat_flex_check_egress_vfi_table(int unit)
   7721 {
   7722     uint32    index=0;
   7723 
   7724     if (!SOC_MEM_IS_VALID(unit, EGR_VFIm)) {
   7725         return; 
   7726     }
   7727     /*egr_vfi_entry_t  egr_vfi_entry_v;*/
   7728     do {
   7729         _bcm_esw_stat_flex_check_egress_table(unit,EGR_VFIm,
   7730              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7731         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7732     } while (index<soc_mem_index_count(unit,EGR_VFIm));
   7733     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7734               (BSL_META_U(unit,
   7735                           "Checked EGRESS:EGR_VFI %d entries..\n"),
   7736                index-1));
   7737 }
   7738 /*
   7739  * Function:
   7740  *      _bcm_esw_stat_flex_check_ingress_vfi_table
   7741  * Description:
   7742  *      Checks ingress vfi table for flex configuration
   7743  * Parameters:
   7744  *      unit                  - (IN) unit number
   7745  * Return Value:
   7746  *      None
   7747  * Notes:
   7748  *      Applicable in warm boot scenario only!
   7749  */
   7750 static void
   7751  _bcm_esw_stat_flex_check_ingress_vfi_table(int unit)
   7752 {
   7753     uint32    index=0;
   7754 
   7755     if(!soc_mem_is_valid(unit, VFIm)) {
   7756         return;
   7757     }
   7758     /*vfi_entry_t  vfi_entry_v;*/
   7759     do {
   7760         _bcm_esw_stat_flex_check_ingress_table(unit,VFIm,
   7761              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7762         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7763     } while (index<soc_mem_index_count(unit,VFIm));
   7764     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7765               (BSL_META_U(unit,
   7766                           "Checked INGRESS:VFI %d entries..\n"),
   7767                index-1));
   7768 }
   7769 /*
   7770  * Function:
   7771  *      _bcm_esw_stat_flex_check_ingress_l3_iif_table
   7772  * Description:
   7773  *      Checks ingress l3_iif table for flex configuration
   7774  * Parameters:
   7775  *      unit                  - (IN) unit number
   7776  * Return Value:
   7777  *      None
   7778  * Notes:
   7779  *      Applicable in warm boot scenario only!
   7780  */
   7781 static void
   7782 _bcm_esw_stat_flex_check_ingress_l3_iif_table(int unit)
   7783 {
   7784     uint32    index=0;
   7785     /*iif_entry_t  iif_entry_v;*/
   7786     do {
   7787         _bcm_esw_stat_flex_check_ingress_table(unit,L3_IIFm,
   7788              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7789         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7790     } while (index<soc_mem_index_count(unit,L3_IIFm));
   7791     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7792               (BSL_META_U(unit,
   7793                           "Checked INGRESS:L3_IIF %d entries..\n"),
   7794                index-1));
   7795 }
   7796 
   7797 /*
   7798  * Function:
   7799  *      _bcm_esw_stat_flex_check_ingress_l3_routing_table
   7800  * Description:
   7801  *      Checks ingress L3_ENTRY_IPV4_MULTICAST table for flex configuration
   7802  * Parameters:
   7803  *      unit                  - (IN) unit number
   7804  * Return Value:
   7805  *      None
   7806  * Notes:
   7807  *      Applicable in warm boot scenario only!
   7808  */
   7809 #ifdef BCM_TRIDENT2_SUPPORT
   7810 static void
   7811 _bcm_esw_stat_flex_check_ingress_l3_routing_table(int unit)
   7812 {
   7813     uint32    index=0;
   7814     soc_mem_t ingress_table = L3_ENTRY_IPV4_MULTICASTm;
   7815 #if defined (BCM_TRIDENT3_SUPPORT)
   7816     if (SOC_IS_TRIDENT3X(unit)){
   7817         ingress_table = L3_ENTRY_DOUBLEm;
   7818     }
   7819 #endif
   7820 #if defined (BCM_TOMAHAWK3_SUPPORT)
   7821     if (SOC_IS_TOMAHAWK3(unit)){
   7822         ingress_table = L3_ENTRY_DOUBLEm;
   7823     }
   7824 #endif
   7825 
   7826     if(!soc_mem_is_valid(unit, ingress_table)) {
   7827         return;
   7828     }
   7829 
   7830     /*iif_entry_t  iif_entry_v;*/
   7831     do {
   7832         _bcm_esw_stat_flex_check_ingress_table(unit, ingress_table,
   7833             index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7834         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7835     } while (index<soc_mem_index_count(unit, ingress_table));
   7836     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7837               (BSL_META_U(unit,
   7838                           "Checked INGRESS: L3_ROUTING_TABLE %d entries..\n"),
   7839                index-1));
   7840 }
   7841 #endif
   7842 
   7843 /*
   7844  * Function:
   7845  *      _bcm_esw_stat_flex_check_ingress_source_vp_table
   7846  * Description:
   7847  *      Checks ingress source_vp table for flex configuration
   7848  * Parameters:
   7849  *      unit                  - (IN) unit number
   7850  * Return Value:
   7851  *      None
   7852  * Notes:
   7853  *      Applicable in warm boot scenario only!
   7854  */
   7855 static void
   7856 _bcm_esw_stat_flex_check_ingress_source_vp_table(int unit)
   7857 {
   7858     uint32    index=0;
   7859     
   7860     if(!soc_mem_is_valid(unit, SOURCE_VPm)) {
   7861         return;
   7862     }
   7863     
   7864     /*source_vp_entry_t  source_vp_entry_v;*/
   7865     do {
   7866         _bcm_esw_stat_flex_check_ingress_table(unit,SOURCE_VPm,
   7867              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7868         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7869     } while (index<soc_mem_index_count(unit,SOURCE_VPm));
   7870     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7871               (BSL_META_U(unit,
   7872                           "Checked INGRESS:SOURCE_VP %d entries..\n"),
   7873                index-1));
   7874 }
   7875 /*
   7876  * Function:
   7877  *      _bcm_esw_stat_flex_check_ingress_mpls_entry_table
   7878  * Description:
   7879  *      Checks ingress mpls_entry table for flex configuration
   7880  * Parameters:
   7881  *      unit                  - (IN) unit number
   7882  * Return Value:
   7883  *      None
   7884  * Notes:
   7885  *      Applicable in warm boot scenario only!
   7886  */
   7887 static void
   7888 _bcm_esw_stat_flex_check_ingress_mpls_entry_table(int unit)
   7889 {
   7890     uint32    index=0;
   7891     /*mpls_entry_entry_t  mpls_entry_entry_v;*/
   7892     soc_mem_t egress_table = MPLS_ENTRYm;
   7893 #if defined (BCM_TRIUMPH3_SUPPORT)
   7894     if (SOC_IS_TRIUMPH3(unit)){
   7895         egress_table = MPLS_ENTRY_EXTDm;
   7896     }
   7897 #endif
   7898 #if defined(BCM_TOMAHAWK3_SUPPORT)
   7899     if (SOC_IS_TOMAHAWK3(unit)){
   7900         egress_table = MPLS_ENTRY_SINGLEm;
   7901     }
   7902 #endif
   7903     do {
   7904         _bcm_esw_stat_flex_check_ingress_table(unit,egress_table,
   7905              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7906         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7907     } while (index<soc_mem_index_count(unit,egress_table));
   7908 
   7909     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7910               (BSL_META_U(unit,
   7911                           "Checked INGRESS:MPLS_ENTRY %d entries..\n"),
   7912                index-1));
   7913 }
   7914 
   7915 #ifdef BCM_WARM_BOOT_SUPPORT
   7916 /*
   7917  * Function:
   7918  *      _bcm_esw_stat_flex_check_ingress_vfp_policy_table
   7919  * Description:
   7920  *      Checks ingress vfp_policy table for flex configuration
   7921  * Parameters:
   7922  *      unit                  - (IN) unit number
   7923  * Return Value:
   7924  *      None
   7925  * Notes:
   7926  *      Applicable in warm boot scenario only!
   7927  */
   7928 static void
   7929 _bcm_esw_stat_flex_check_ingress_vfp_policy_table(int unit, uint32 per_pipe_mode)
   7930 {
   7931     uint32    index=0;
   7932     uint32    max_index;
   7933 #ifdef BCM_TOMAHAWK_SUPPORT
   7934     int       pipe_num = 0;
   7935 #endif
   7936     max_index = soc_mem_index_count(unit, VFP_POLICY_TABLEm);
   7937 
   7938     /*vfp_policy_table_entry_t  vfp_policy_table_entry_v;*/
   7939     if (!per_pipe_mode) {
   7940         do {
   7941             _bcm_esw_stat_flex_check_ingress_table(unit,VFP_POLICY_TABLEm,
   7942                  index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7943             index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7944         } while (index < max_index);
   7945         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   7946                   (BSL_META_U(unit,
   7947                               "Checked INGRESS:VFP_POLICY_TABLE %d entries..\n"),
   7948                    index-1));
   7949         return;
   7950     }
   7951 #ifdef BCM_TOMAHAWK_SUPPORT
   7952     if (soc_feature(unit,soc_feature_stat_multi_pipe_support)) {
   7953        /* Per-pipe mode */
   7954        for(pipe_num =0; pipe_num < NUM_PIPE(unit); ++pipe_num) {
   7955           index = 0;
   7956           do {
   7957              _bcm_esw_stat_flex_check_ingress_table(unit,_vfp_mem_arr[pipe_num],
   7958                  index, index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   7959              index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   7960           } while (index < max_index);
   7961 
   7962           LOG_DEBUG(BSL_LS_BCM_FLEXCTR, (BSL_META_U(unit,
   7963                   "Checked INGRESS:VFP_POLICY_TABLE %d entries..\n"), index-1));
   7964        }
   7965     }
   7966 #endif
   7967 }
   7968 #endif
   7969 
   7970 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) \
   7971     || defined(BCM_APACHE_SUPPORT)
   7972 #ifdef BCM_WARM_BOOT_SUPPORT
   7973 
   7974 #define BCM_FLEX_CHECK_INGRESS_TABLE(_unit, _mem, _index) {                    \
   7975     _index=0;                                                                       \
   7976     do {                                                                            \
   7977         _bcm_esw_stat_flex_check_ingress_table(_unit, _mem,                         \
   7978              _index, _index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);               \
   7979         _index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;                                \
   7980     } while (_index < soc_mem_index_count(_unit, IFP_POLICY_TABLEm));               \
   7981     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,                                                   \
   7982               (BSL_META_U(_unit,                                                    \
   7983                           "Checked INGRESS:IFP_POLICY_TABLE %d entries..\n"),       \
   7984                           _index-1));                                               \
   7985 }
   7986 
   7987 /*
   7988  * Function:
   7989  *      _bcm_esw_stat_flex_check_ingress_ifp_policy_table
   7990  * Description:
   7991  *      Checks ifp_policy table for flex configuration
   7992  * Parameters:
   7993  *      unit                  - (IN) unit number
   7994  * Return Value:
   7995  *      None
   7996  * Notes:
   7997  *      Applicable in warm boot scenario only!
   7998  */
   7999 static void
   8000 _bcm_esw_stat_flex_check_ingress_ifp_policy_table(int unit, uint32 per_pipe_mode)
   8001 {
   8002     uint32    index=0;
   8003 #if defined(BCM_TOMAHAWK_SUPPORT)
   8004     if (soc_feature(unit,soc_feature_stat_multi_pipe_support)) {
   8005 
   8006     int                    pipe_num = 0;
   8007 
   8008     if (!per_pipe_mode) {
   8009         BCM_FLEX_CHECK_INGRESS_TABLE(unit, IFP_POLICY_TABLEm, index);
   8010        return;
   8011     }
   8012 
   8013         /* Per-pipe mode */
   8014         for(pipe_num =0; pipe_num < NUM_PIPE(unit); ++pipe_num) {
   8015             BCM_FLEX_CHECK_INGRESS_TABLE(unit, _ifp_mem_arr[pipe_num], index);
   8016         }
   8017     } else
   8018 #endif
   8019     {
   8020         do {
   8021             _bcm_esw_stat_flex_check_ingress_table(unit, FP_POLICY_TABLEm,
   8022                 index, index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   8023              index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   8024         } while (index < soc_mem_index_count(unit, FP_POLICY_TABLEm));
   8025         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   8026                  (BSL_META_U(unit,
   8027                             "Checked INGRESS:FP_POLICY_TABLE %d entries..\n"),
   8028                             index-1));
   8029     }
   8030 
   8031     return;
   8032 
   8033 }
   8034 #endif
   8035 #endif
   8036 
   8037 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
   8038 #ifdef BCM_WARM_BOOT_SUPPORT
   8039 /*
   8040  * Function:
   8041  *      _bcm_esw_stat_flex_check_egress_efp_policy_table
   8042  * Description:
   8043  *      Checks efp_policy table for flex configuration
   8044  * Parameters:
   8045  *      unit                  - (IN) unit number
   8046  * Return Value:
   8047  *      None
   8048  * Notes:
   8049  *      Applicable in warm boot scenario only!
   8050  */
   8051 static void
   8052 _bcm_esw_stat_flex_check_egress_efp_policy_table(int unit,
   8053         uint32 per_pipe_mode)
   8054 {
   8055     uint32 start_idx = 0, end_idx = 1;
   8056     uint32    index=0;
   8057     uint32    mem_idx = 0;
   8058 
   8059     if(per_pipe_mode) {
   8060         start_idx = 1;
   8061         end_idx = NUM_PIPE(unit) + 1;
   8062     }
   8063 
   8064     for( mem_idx = start_idx; mem_idx < end_idx; mem_idx++) {
   8065         index = 0;
   8066     do {
   8067             _bcm_esw_stat_flex_check_egress_table(unit, _efp_mem_arr[mem_idx],
   8068                 index, index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   8069         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   8070         } while (index < soc_mem_index_count(unit, _efp_mem_arr[mem_idx]));
   8071 
   8072     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   8073             (BSL_META_U(unit,
   8074                         "Checked EGRESS:EFP_POLICY_TABLE %d entries..\n"),
   8075              index-1));
   8076     }
   8077 
   8078     return;
   8079 }
   8080 #endif
   8081 #endif
   8082 
   8083 
   8084 /*
   8085  * Function:
   8086  *      _bcm_esw_stat_flex_check_egress_vlan_xlate_table
   8087  * Description:
   8088  *      Checks egress vlan_xlate table for flex configuration
   8089  * Parameters:
   8090  *      unit                  - (IN) unit number
   8091  * Return Value:
   8092  *      None
   8093  * Notes:
   8094  *      Applicable in warm boot scenario only!
   8095  */
   8096 static void
   8097 _bcm_esw_stat_flex_check_egress_vlan_xlate_table(int unit)
   8098 {
   8099     uint32    index=0;
   8100     soc_mem_t egress_table = EGR_VLAN_XLATEm;
   8101 #if defined (BCM_TRIDENT3_SUPPORT)
   8102     if (SOC_IS_TRIDENT3X(unit)){
   8103         egress_table = EGR_VLAN_XLATE_1_DOUBLEm;
   8104     }
   8105 #endif
   8106 
   8107     if (!SOC_MEM_IS_VALID(unit, egress_table)) {
   8108         return; 
   8109     }
   8110 
   8111     /*egr_vlan_xlate_entry_t  egr_vlan_xlate_entry_v;*/
   8112     do {
   8113         _bcm_esw_stat_flex_check_egress_table(unit,egress_table,
   8114              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   8115         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   8116     } while (index<soc_mem_index_count(unit,egress_table));
   8117     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   8118               (BSL_META_U(unit,
   8119                           "Checked EGRESS:EGR_VLAN_XLATE %d entries..\n"),
   8120                index-1));
   8121 #if defined (BCM_TRIDENT3_SUPPORT)
   8122     if (soc_feature(unit, soc_feature_flex_flow)) {
   8123         /*egr_vlan_xlate_entry_t  egr_vlan_xlate_entry_v;*/
   8124         index = 0;
   8125         egress_table = EGR_VLAN_XLATE_2_DOUBLEm;
   8126         do {
   8127             _bcm_esw_stat_flex_check_egress_table(unit,egress_table,
   8128                  index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   8129             index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   8130         } while (index<soc_mem_index_count(unit,egress_table));
   8131         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   8132                   (BSL_META_U(unit,
   8133                               "Checked EGRESS:EGR_VLAN_XLATE %d entries..\n"),
   8134                    index-1));
   8135 
   8136     }
   8137 #endif
   8138 }
   8139 /*
   8140  * Function:
   8141  *      _bcm_esw_stat_flex_check_ingress_vlan_xlate_table
   8142  * Description:
   8143  *      Checks ingress vlan_xlate table for flex configuration
   8144  * Parameters:
   8145  *      unit                  - (IN) unit number
   8146  * Return Value:
   8147  *      None
   8148  * Notes:
   8149  *      Applicable in warm boot scenario only!
   8150  */
   8151 static void
   8152 _bcm_esw_stat_flex_check_ingress_vlan_xlate_table(int unit)
   8153 {
   8154     uint32    index = 0;
   8155     /*vlan_xlate_entry_t  vlan_xlate_entry_v;*/
   8156     soc_mem_t ingress_table[3] = {VLAN_XLATEm, INVALIDm, INVALIDm};
   8157     uint32 tab_idx = 0;
   8158 
   8159 #if defined (BCM_TRIUMPH3_SUPPORT)
   8160     if (SOC_IS_TRIUMPH3(unit)){
   8161         ingress_table[0] = VLAN_XLATE_EXTDm;
   8162     }
   8163 #endif
   8164 #if defined (BCM_TRIDENT3_SUPPORT)
   8165     if (SOC_IS_TRIDENT3X(unit)){
   8166         ingress_table[0] = VLAN_XLATE_1_DOUBLEm;
   8167         ingress_table[1] = VLAN_XLATE_2_DOUBLEm;
   8168     }
   8169 #endif
   8170 
   8171         while (INVALIDm != ingress_table[tab_idx]){
   8172             if(soc_mem_is_valid(unit, ingress_table[tab_idx])) {
   8173                 do {
   8174                     _bcm_esw_stat_flex_check_ingress_table(unit,ingress_table[tab_idx],
   8175                          index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   8176                     index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   8177                 } while (index<soc_mem_index_count(unit,ingress_table[tab_idx]));
   8178             }
   8179             tab_idx++;
   8180             index = 0;
   8181         }
   8182     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   8183               (BSL_META_U(unit,
   8184                           "Checked INGRESS:VLAN_XLATE_TABLE %d entries..\n"),
   8185                index-1));
   8186 }
   8187 /*
   8188  * Function:
   8189  *      _bcm_esw_stat_flex_check_egress_port_table
   8190  * Description:
   8191  *      Checks egress port table for flex configuration
   8192  * Parameters:
   8193  *      unit                  - (IN) unit number
   8194  * Return Value:
   8195  *      None
   8196  * Notes:
   8197  *      Applicable in warm boot scenario only!
   8198  */
   8199 static void
   8200 _bcm_esw_stat_flex_check_egress_port_table(int unit)
   8201 {
   8202     uint32    index=0;
   8203     /*egr_port_entry_t  egr_port_entry_v;*/
   8204     soc_mem_t egress_table = EGR_PORTm;
   8205 #if defined (BCM_TRIDENT3_SUPPORT)
   8206     if (SOC_IS_TRIDENT3X(unit)){
   8207         egress_table = EGR_LPORT_PROFILEm;
   8208     }
   8209 #endif
   8210     do {
   8211         _bcm_esw_stat_flex_check_egress_table(unit,egress_table,
   8212              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   8213         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   8214     } while (index<soc_mem_index_count(unit,egress_table));
   8215     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   8216               (BSL_META_U(unit,
   8217                           "Checked EGRESS:EGR_PORT %d entries..\n"),
   8218                index-1));
   8219 }
   8220 /*
   8221  * Function:
   8222  *      _bcm_esw_stat_flex_check_ingress_port_table
   8223  * Description:
   8224  *      Checks ingress port table for flex configuration
   8225  * Parameters:
   8226  *      unit                  - (IN) unit number
   8227  * Return Value:
   8228  *      None
   8229  * Notes:
   8230  *      Applicable in warm boot scenario only!
   8231  */
   8232 static void
   8233 _bcm_esw_stat_flex_check_ingress_port_table(int unit)
   8234 {
   8235     uint32    index=0;
   8236     /*port_tab_entry_t  port_tab_entry_v;*/
   8237     soc_mem_t ingress_table = PORT_TABm;
   8238 #if defined (BCM_TRIDENT3_SUPPORT)
   8239     if (SOC_IS_TRIDENT3X(unit)){
   8240         ingress_table = LPORT_TABm;
   8241     }
   8242 #endif
   8243     do {
   8244         _bcm_esw_stat_flex_check_ingress_table(unit,ingress_table,
   8245              index,index + BCM_STAT_FLEX_WARMBOOT_READ_CHUNK - 1);
   8246         index += BCM_STAT_FLEX_WARMBOOT_READ_CHUNK;
   8247     } while(index<soc_mem_index_count(unit,ingress_table));
   8248     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   8249               (BSL_META_U(unit,
   8250                           "Checked INGRESS:PORT_TABLE %d entries..\n"),
   8251                index-1));
   8252 }
   8253 
   8254 /* Helper function for _bcm_esw_stat_flex_set */
   8255 STATIC int
   8256 _bcm_esw_stat_flex_set_mem_update(int unit, soc_mem_t table, int pipe_num, uint32 index,
   8257                                   soc_mem_t mem, uint32 start, uint32 entry_cnt,
   8258                                   void *entry, int dir, uint32 pool_id, int byte_flag
   8259                                   )
   8260 {
   8261     int i;
   8262     uint32 zero=0;
   8263     uint32 one=1;
   8264     uint32 max_packet_mask = 0;
   8265     uint64 max_byte_mask;
   8266     uint32 hw_val[2];
   8267     bcm_stat_flex_counter_value_t flex_values  = {0};
   8268 #if defined(BCM_TRIDENT2_SUPPORT)
   8269     soc_mem_t mem_dual = 0;
   8270 #endif
   8271 
   8272     COMPILER_64_ZERO(max_byte_mask);
   8273     COMPILER_64_SET(max_byte_mask, zero, one);
   8274     COMPILER_64_SHL(max_byte_mask,soc_mem_field_length(unit, mem, BYTE_COUNTERf));
   8275     COMPILER_64_SUB_32(max_byte_mask, one);
   8276     if (pipe_num < 0) {
   8277         pipe_num = 0;
   8278     }
   8279 
   8280     max_packet_mask = (1 << soc_mem_field_length(unit, mem, PACKET_COUNTERf));
   8281     max_packet_mask -= 1;
   8282 
   8283 #define FLEX_SET_BYTE_COUNTER_UPDATE \
   8284     do { \
   8285         /* Mask to possible max values */ \
   8286         COMPILER_64_AND(flex_values.byte_counter_value, max_byte_mask); \
   8287         /* Update Soft Copy */ \
   8288         COMPILER_64_SET(flex_byte_counter[unit][dir][pipe_num][pool_id][start+i], \
   8289                         COMPILER_64_HI(flex_values.byte_counter_value), \
   8290                         COMPILER_64_LO(flex_values.byte_counter_value)); \
   8291         /* Change Read Hw Copy */ \
   8292         hw_val[0] = COMPILER_64_HI(flex_values.byte_counter_value); \
   8293         hw_val[1] = COMPILER_64_LO(flex_values.byte_counter_value); \
   8294         soc_mem_field_set(unit, mem, (uint32 *)&entry_temp[i], \
   8295                           BYTE_COUNTERf, hw_val); \
   8296         LOG_DEBUG(BSL_LS_BCM_FLEXCTR, \
   8297                   (BSL_META_U(unit, \
   8298                               "Byte Count Value\t:TABLE:%sINDEX:%d COUTER-%d" \
   8299                                "(@Pool:%dDirection:%dActualOffset%d)" \
   8300                                " : %x:%x \n"),SOC_MEM_UFNAME(unit, table), \
   8301                    index, i, pool_id, dir, start + i, \
   8302                    COMPILER_64_HI(flex_values.byte_counter_value), \
   8303                    COMPILER_64_LO(flex_values.byte_counter_value))); \
   8304     } while (0)
   8305 
   8306 #define FLEX_SET_BYTE_COUNTER_UPDATE_TD2 \
   8307     if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) { \
   8308         int j; \
   8309         for (j = 0; j < _BCM_FLEX_STAT_BUFFS; j++) { \
   8310             COMPILER_64_SET(flex_byte_counter_x[unit][dir][pool_id][j][start+i], \
   8311                             COMPILER_64_HI(flex_values.byte_counter_value), \
   8312                             COMPILER_64_LO(flex_values.byte_counter_value)); \
   8313             COMPILER_64_ZERO(flex_byte_counter_y[unit][dir][pool_id][j][start+i]); \
   8314         } \
   8315     }
   8316 
   8317 #define FLEX_SET_PACKET_COUNTER_UPDATE \
   8318     do { \
   8319         flex_values.pkt_counter_value &= max_packet_mask; \
   8320         /* Update Soft 64-bits Copy */ \
   8321         COMPILER_64_SET(flex_packet64_counter[unit][dir][pipe_num][pool_id][start+i], \
   8322                     0, flex_values.pkt_counter_value); \
   8323         /* Update Soft Copy */ \
   8324         flex_packet_counter[unit][dir][pipe_num][pool_id][start+i] = \
   8325                     flex_values.pkt_counter_value; \
   8326         /* Change Read Hw Copy */ \
   8327         soc_mem_field_set(unit, mem, (uint32 *)&entry_temp[i], \
   8328                           PACKET_COUNTERf, &flex_values.pkt_counter_value); \
   8329         LOG_DEBUG(BSL_LS_BCM_FLEXCTR, \
   8330                   (BSL_META_U(unit, \
   8331                               "Packet Count Value\t:TABLE:%sINDEX:%d" \
   8332                                "COUTER-%d (@Pool:%dDirection:%d" \
   8333                                "ActualOffset%d) : %x \n"), SOC_MEM_UFNAME(unit, table), \
   8334                    index, i, pool_id, dir, start + i, \
   8335                    flex_values.pkt_counter_value)); \
   8336     } while (0)
   8337 
   8338 #define FLEX_SET_PACKET_COUNTER_UPDATE_TD2 \
   8339     if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) { \
   8340         int j; \
   8341         for (j = 0; j < _BCM_FLEX_STAT_BUFFS; j++) { \
   8342             flex_pkt_counter_x[unit][dir][pool_id][j][start+i] \
   8343                 = flex_values.pkt_counter_value; \
   8344             flex_pkt_counter_y[unit][dir][pool_id][j][start+i] = 0; \
   8345         } \
   8346     }
   8347 
   8348     /* Type of entry is ing_flex_ctr_counter_table_0_entry_t, and entry also
   8349      * could be used for egress flex counter whose type should be
   8350      * egr_flex_ctr_counter_table_0_entry_t, but since their entry size is the
   8351      * same, so we don't need to distinguish them */
   8352 
   8353     /* If entry_cnt less than 8, memory range operation is not efficient */
   8354     if (entry_cnt <= 8) {
   8355         for (i = 0 ; i < entry_cnt ; i++) {
   8356             ing_flex_ctr_counter_table_0_entry_t *entry_temp = entry;
   8357             if (byte_flag != -1) {
   8358                 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   8359                                                  start + i, &entry_temp[i]));
   8360             }
   8361 
   8362             /* Bytes Counter update */
   8363             if (byte_flag == 1 || byte_flag == -1) {
   8364                 FLEX_SET_BYTE_COUNTER_UPDATE;
   8365 #if defined(BCM_TRIDENT2_SUPPORT)
   8366                 FLEX_SET_BYTE_COUNTER_UPDATE_TD2;
   8367 #endif
   8368             }
   8369 
   8370             /* Packet Counter update */
   8371             if (byte_flag == 0 || byte_flag == -1) {
   8372                 FLEX_SET_PACKET_COUNTER_UPDATE;
   8373 #if defined(BCM_TRIDENT2_SUPPORT)
   8374                 FLEX_SET_PACKET_COUNTER_UPDATE_TD2;
   8375 #endif
   8376             }
   8377 
   8378             /* TD2 counter value is set in X memory, clear Y memory */
   8379 #if defined(BCM_TRIDENT2_SUPPORT)
   8380             if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
   8381                 mem = _ctr_counter_table_x[dir][pool_id];
   8382             }
   8383 #endif
   8384             BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ANY,
   8385                                               start + i, &entry_temp[i]));
   8386 #if defined(BCM_TRIDENT2_SUPPORT)
   8387             if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
   8388                 mem_dual =_ctr_counter_table_y[dir][pool_id];
   8389                 sal_memset(&entry_temp[i], 0,
   8390                         sizeof(ing_flex_ctr_counter_table_0_entry_t));
   8391                 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem_dual, MEM_BLOCK_ANY,
   8392                                                   start + i, &entry_temp[i]));
   8393             }
   8394 #endif
   8395         }
   8396         return BCM_E_NONE;
   8397     }
   8398 
   8399     /* If we want to update both byte and packet fields,
   8400      * we don't need to read the original value */
   8401     if (byte_flag != -1) {
   8402         if (soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, start,
   8403                                start+entry_cnt-1, entry) != BCM_E_NONE) {
   8404             return BCM_E_INTERNAL;
   8405         }
   8406     }
   8407 
   8408     for (i = 0 ; i < entry_cnt ; i++) {
   8409         ing_flex_ctr_counter_table_0_entry_t *entry_temp = entry;
   8410         /* Bytes Counter update */
   8411         if (byte_flag == 1 || byte_flag == -1) {
   8412             FLEX_SET_BYTE_COUNTER_UPDATE;
   8413 #if defined(BCM_TRIDENT2_SUPPORT)
   8414             FLEX_SET_BYTE_COUNTER_UPDATE_TD2;
   8415 #endif
   8416         }
   8417 
   8418         /* Packet Counter update */
   8419         if (byte_flag == 0 || byte_flag == -1) {
   8420             FLEX_SET_PACKET_COUNTER_UPDATE;
   8421 #if defined(BCM_TRIDENT2_SUPPORT)
   8422             FLEX_SET_PACKET_COUNTER_UPDATE_TD2;
   8423 #endif
   8424         }
   8425     }
   8426 
   8427     /* TD2 counter value is set in X memory, clear Y memory */
   8428 #if defined(BCM_TRIDENT2_SUPPORT)
   8429     if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
   8430         mem = _ctr_counter_table_x[dir][pool_id];
   8431     }
   8432 #endif
   8433     /* Update Hw Copy */
   8434     if (soc_mem_write_range(unit, mem, MEM_BLOCK_ALL, start, start+entry_cnt-1,
   8435                             entry) != BCM_E_NONE) {
   8436         return BCM_E_INTERNAL;
   8437     }
   8438 
   8439 #if defined(BCM_TRIDENT2_SUPPORT)
   8440     if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
   8441         mem_dual =_ctr_counter_table_y[dir][pool_id];
   8442         /* Update Hw Copy */
   8443         sal_memset(entry, 0, entry_cnt * sizeof(ing_flex_ctr_counter_table_0_entry_t));
   8444         if (soc_mem_write_range(unit, mem_dual, MEM_BLOCK_ALL, start, start+entry_cnt-1,
   8445                                 entry) != BCM_E_NONE) {
   8446             return BCM_E_INTERNAL;
   8447         }
   8448     }
   8449 #endif
   8450     return BCM_E_NONE;
   8451 }
   8452 
   8453 /*
   8454  * Function:
   8455  *      _bcm_esw_stat_flex_set
   8456  * Description:
   8457  *      Set flex counter values
   8458  * Parameters:
   8459  *      unit                  - (IN) unit number
   8460  *      index                 - (IN) Flex Accounting Table Index
   8461  *      table                 - (IN) Flex Accounting Table
   8462  *      byte_flag             - (IN) Byte/Packet Flag
   8463  *      flex_ctr_offset_info  - (IN) Information about flex counter values
   8464  *      flex_entries          - (IN) Information about flex entries
   8465  *      offset_mode           - (IN) FLEX_CTR_OFFSET_MODE field value
   8466  *      pool_number           - (IN) FLEX_CTR_POOL_NUMBER field value
   8467  *      base_idx              - (IN) FLEX_CTR_BASE_COUNTER_IDX field value
   8468  *      direction             - (IN) Flex Data flow direction
   8469  * Return Value:
   8470  *      BCM_E_XXX
   8471  * Notes:
   8472  */
   8473 static bcm_error_t
   8474 _bcm_esw_stat_flex_set(
   8475     int                             unit,
   8476     uint32                          index,
   8477     soc_mem_t                       table,
   8478     uint32                          byte_flag,
   8479     bcm_stat_flex_ctr_offset_info_t flex_ctr_offset_info,
   8480     uint32                          *flex_entries,
   8481     uint32                          offset_mode,
   8482     uint32                          pool_number,
   8483     uint32                          base_idx ,
   8484     bcm_stat_flex_direction_t       direction)
   8485 {
   8486     soc_mem_t                 mem;
   8487     uint32                    total_entries=0;
   8488     uint32                    offset_index=0;
   8489     int                       pipe_num = 0;
   8490     int                       custom_mode = 0;
   8491 
   8492     if (flex_temp_counter[unit][direction] == NULL) {
   8493         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   8494                   (BSL_META_U(unit,
   8495                               "Not initilized or attached yet\n")));
   8496         return BCM_E_CONFIG;
   8497     }
   8498 
   8499 #if defined (BCM_TOMAHAWK_SUPPORT)
   8500         pipe_num = _bcm_esw_get_fp_pipe_num(unit, table);
   8501         if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
   8502             (_bcm_esw_is_fp_table(table))) {
   8503             uint32 cmode = 0;
   8504             bcm_error_t rv;
   8505             uint32 stat_counter_id;
   8506 
   8507             rv = _bcm_esw_custom_stat_group_id_retrieve(unit, offset_mode, pipe_num,
   8508                 pool_number, base_idx,&stat_counter_id);
   8509             if (rv == BCM_E_NONE) {
   8510             custom_mode = 1;
   8511                 cmode = stat_counter_map[unit][stat_counter_id].mode;
   8512 
   8513 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   8514             if(cmode > BCM_CUSTOM_EGRESS_MODE_START) {
   8515                 cmode -= BCM_CUSTOM_EGRESS_MODE_START;
   8516                 total_entries =
   8517                     flex_custom_egress_modes[unit][cmode].total_counters;
   8518         } else
   8519 #endif
   8520             if (cmode > BCM_CUSTOM_INGRESS_MODE_START) {
   8521                 cmode -= BCM_CUSTOM_INGRESS_MODE_START;
   8522                 total_entries =
   8523                     flex_custom_ingress_modes[unit][cmode].total_counters;
   8524         }
   8525         }
   8526     }
   8527 #endif
   8528     if(0x0 == custom_mode) {
   8529         if (direction == bcmStatFlexDirectionIngress) {
   8530             total_entries =
   8531                 flex_ingress_modes[unit][offset_mode].total_counters;
   8532     } else {
   8533             total_entries =
   8534                 flex_egress_modes[unit][offset_mode].total_counters;
   8535         }
   8536     }
   8537     offset_index = 0;
   8538 
   8539     *flex_entries = total_entries;
   8540 
   8541     if (SOC_IS_TOMAHAWKX(unit) ||SOC_IS_TRIDENT3X(unit)) {
   8542         return th_flex_counter_set(unit, direction, pipe_num, pool_number,
   8543                                    base_idx+offset_index,
   8544                                    (bcm_stat_value_t *)NULL,
   8545                                    total_entries, byte_flag);
   8546     }
   8547 
   8548     BCM_STAT_FLEX_COUNTER_LOCK(unit);
   8549     mem = _ctr_counter_table[direction][pool_number];
   8550     if (_bcm_esw_stat_flex_check_invalid_base_idx(unit,
   8551                                                   table,
   8552                                                   pipe_num,
   8553                                                   pool_number,
   8554                                                   base_idx) != 0) {
   8555         return BCM_E_NONE;
   8556     }
   8557     if (BCM_FAILURE(_bcm_esw_stat_flex_set_mem_update(unit, table, pipe_num, index,
   8558                             mem, base_idx+offset_index, total_entries,
   8559                             flex_temp_counter[unit][direction], direction,
   8560                             pool_number, byte_flag))) {
   8561         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
   8562         return BCM_E_INTERNAL;
   8563     }
   8564 
   8565     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
   8566 
   8567     return BCM_E_NONE;
   8568 }
   8569 
   8570 /*
   8571  * Function:
   8572  *      _bcm_esw_ext_stat_flex_set
   8573  * Description:
   8574  *      Set flex counter values for external fp policy
   8575  * Parameters:
   8576  *      unit                  - (IN) unit number
   8577  *      pool_number           - (IN) Flex Pool Number for Accounting Object
   8578  *      base_idx              - (IN) Flex Base Index for Accounting Object
   8579  *      offset_mode           - (IN) Flex offset mode for Accounting Object
   8580  *      table                 - (IN) Flex Accounting Table
   8581  *      byte_flag             - (IN) Byte/Packet Flag
   8582  *      flex_ctr_offset_info  - (IN) Information about flex counter values
   8583  *      flex_entries          - (IN) Information about flex entries
   8584  *      flex_values           - (IN) Information about flex entries values
   8585  * Return Value:
   8586  *      BCM_E_XXX
   8587  * Notes:
   8588  */
   8589 static bcm_error_t
   8590 _bcm_esw_ext_stat_flex_set(
   8591     int                             unit,
   8592     uint32                          pool_number,
   8593     uint32                          base_idx,
   8594     bcm_stat_flex_mode_t            offset_mode,
   8595     soc_mem_t                       table,
   8596     uint32                          byte_flag,
   8597     bcm_stat_flex_ctr_offset_info_t flex_ctr_offset_info,
   8598     uint32                          *flex_entries,
   8599     bcm_stat_flex_counter_value_t   *flex_values)
   8600 {
   8601     soc_mem_t                 mem;
   8602     uint32                    loop=0;
   8603     bcm_stat_flex_direction_t direction = bcmStatFlexDirectionIngress;
   8604     uint32                    total_entries=0;
   8605     uint32                    offset_index=0;
   8606     uint32                    zero=0;
   8607     uint32                    one=1;
   8608     uint32                    max_packet_mask=0;
   8609     uint64                    max_byte_mask;
   8610     uint32                    hw_val[2];
   8611 
   8612     mem = _ctr_counter_table[direction][0];
   8613     COMPILER_64_SET(max_byte_mask, zero, one);
   8614     COMPILER_64_SHL(max_byte_mask,soc_mem_field_length(unit,mem,BYTE_COUNTERf));
   8615     COMPILER_64_SUB_32(max_byte_mask,one);
   8616 
   8617     max_packet_mask = (1 << soc_mem_field_length(unit,mem,PACKET_COUNTERf));
   8618     max_packet_mask -= 1;
   8619 
   8620     if ((offset_mode == 0) && (base_idx == 0)) {
   8621          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   8622                    (BSL_META_U(unit,
   8623                                "EXT_FP_POLICY table: pool_number:%d: IsNotConfigured"
   8624                                 " for flex counter \n"),
   8625                     pool_number));
   8626          /* Either Not configured or deallocated before */
   8627          return BCM_E_NOT_FOUND;
   8628     }
   8629 
   8630     /* EXT Stat's are currently supported on EXT_FP_POLICYm (Ingress Direction)
   8631  */
   8632     if (direction == bcmStatFlexDirectionIngress) {
   8633         total_entries= flex_ingress_modes[unit][offset_mode].total_counters;
   8634     } 
   8635 
   8636     if (flex_ctr_offset_info.all_counters_flag) {
   8637         offset_index = 0;
   8638     } else {
   8639         offset_index = flex_ctr_offset_info.offset_index;
   8640         if (offset_index >= total_entries) {
   8641             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   8642                       (BSL_META_U(unit,
   8643                                   "Wrong OFFSET_INDEX.Must be <Total Counters %d \n"),
   8644                        total_entries));
   8645             return BCM_E_PARAM;
   8646         }
   8647         total_entries = 1;
   8648     }
   8649 
   8650     *flex_entries = total_entries;
   8651 
   8652     BCM_STAT_FLEX_COUNTER_LOCK(unit);
   8653     mem = _ctr_counter_table[direction][pool_number];
   8654     if (soc_mem_read_range(unit,
   8655                            mem,
   8656                            MEM_BLOCK_ANY,
   8657                            base_idx+offset_index,
   8658                            base_idx+offset_index+total_entries-1,
   8659                            flex_temp_counter[unit][direction]) != BCM_E_NONE) {
   8660         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
   8661         return BCM_E_INTERNAL;
   8662     }
   8663 
   8664     for (loop = 0 ; loop < total_entries ; loop++) {
   8665          if (byte_flag == 1) {
   8666              /* Mask to possible max values */
   8667              COMPILER_64_AND(flex_values[loop].byte_counter_value,
   8668                                  max_byte_mask);
   8669              /* Update Soft Copy */
   8670              COMPILER_64_SET(flex_byte_counter[unit][direction][0]
   8671                                  [pool_number][base_idx+offset_index+loop],
   8672                                  COMPILER_64_HI(flex_values[loop].
   8673                                                 byte_counter_value),
   8674                                  COMPILER_64_LO(flex_values[loop].
   8675                                                 byte_counter_value));
   8676              /* Change Read Hw Copy */
   8677              hw_val[0] = COMPILER_64_HI(flex_values[loop].
   8678                                             byte_counter_value);
   8679              hw_val[1] = COMPILER_64_LO(flex_values[loop].
   8680                                             byte_counter_value);
   8681              soc_mem_field_set(
   8682                          unit,mem,
   8683                          (uint32 *)&flex_temp_counter[unit][direction][loop],
   8684                          BYTE_COUNTERf, hw_val);
   8685              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   8686                        (BSL_META_U(unit,
   8687                                    "Byte Count Value\t:TABLE:EXT_FP_POLICY COUNTER-%d"
   8688                                     "(@ Pool:%d Direction:%d ActualOffset%d)"
   8689                                     " : %x:%x \n"),
   8690                         loop, pool_number, direction,
   8691                         base_idx+offset_index+loop,
   8692                         COMPILER_64_HI(flex_values[loop].
   8693                         byte_counter_value),
   8694                         COMPILER_64_LO(flex_values[loop].
   8695                         byte_counter_value)));
   8696         } else {
   8697             flex_values[loop].pkt_counter_value &= max_packet_mask;
   8698             /* Update Soft Copy 64-bit */
   8699             COMPILER_64_SET(flex_packet64_counter[unit][direction][0]
   8700                             [pool_number][base_idx+offset_index+loop],
   8701                             0,
   8702                             flex_values[loop].
   8703                             pkt_counter_value);
   8704 
   8705             /* Update Soft Copy */
   8706             flex_packet_counter[unit][direction][0][pool_number]
   8707                                    [base_idx+offset_index+loop] =
   8708                                    flex_values[loop].pkt_counter_value;
   8709             /* Change Read Hw Copy */
   8710             soc_mem_field_set(
   8711                             unit,
   8712                             mem,
   8713                             (uint32 *)&flex_temp_counter[unit][direction][loop],
   8714                             PACKET_COUNTERf,
   8715                             &flex_values[loop].pkt_counter_value);
   8716                     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   8717                               (BSL_META_U(unit,
   8718                                           "Packet Count Value\t:TABLE:EXT_FP_POLICY "
   8719                                            "COUNTER-%d (@ Pool:%d Direction:%d "
   8720                                            "ActualOffset%d) : %x \n"),
   8721                                loop, pool_number,direction,
   8722                                base_idx+offset_index+loop,
   8723                                flex_values[loop].pkt_counter_value));
   8724                 }
   8725         }
   8726 
   8727     /* Update Hw Copy */
   8728     if (soc_mem_write_range(unit,mem,MEM_BLOCK_ALL,
   8729                     base_idx+offset_index,
   8730                     base_idx+offset_index+total_entries-1,
   8731                     flex_temp_counter[unit][direction]) != BCM_E_NONE) {
   8732         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
   8733         return BCM_E_INTERNAL;
   8734     }
   8735     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
   8736     return BCM_E_NONE;
   8737 }
   8738 
   8739 
   8740 #ifdef BCM_WARM_BOOT_SUPPORT
   8741 STATIC
   8742 int _bcm_flex_stat_compression_share_wb_size(int unit) {
   8743     int temp_size = 0;
   8744 
   8745     if (soc_feature(unit, soc_feature_flex_stat_compression_share)) {
   8746         temp_size += sizeof(uint32);    /* combine_int_pri_flags */
   8747         temp_size += sizeof(uint32);    /* combine_vlan_format_flags */
   8748         temp_size += sizeof(uint32);    /* combine_outer_dot1p_flags */
   8749         temp_size += sizeof(uint32);    /* combine_inner_dot1p_flags */
   8750         temp_size += sizeof(uint32);    /* combine_pkt_res_flags */
   8751         temp_size += sizeof(uint32);    /* combine_drop_flags */
   8752         temp_size += sizeof(uint32);    /* combine_ip_pkt_flags */
   8753         /* Attributes which are Array */
   8754         temp_size += sizeof(uint32);    /* Array Size */
   8755         temp_size += sizeof(uint32) * BCM_STAT_FLEX_BIT_ARRAY_SIZE;
   8756         /* _bcmPolicerAttrPort */
   8757         temp_size += sizeof(uint32);    /* Array Size */
   8758         temp_size += sizeof(uint32) * BCM_STAT_FLEX_BIT_ARRAY_SIZE;
   8759         /* _bcmPolicerAttrTosDscp */
   8760         temp_size += sizeof(uint32);    /* Array Size */
   8761         temp_size += sizeof(uint32) * BCM_STAT_FLEX_BIT_ARRAY_SIZE;
   8762         /* _bcmPolicerAttrTosEcn */
   8763         temp_size += sizeof(uint32);    /* Array Size */
   8764         temp_size += sizeof(uint32) * BCM_STAT_FLEX_BIT_ARRAY_SIZE;
   8765         /* _bcmPolicerAttrSvpType */
   8766         temp_size += sizeof(uint32);    /* Array Size */
   8767         temp_size += sizeof(uint32) * BCM_STAT_FLEX_BIT_ARRAY_SIZE;
   8768         /* Egress */
   8769         temp_size += sizeof(uint32);    /* combine_int_pri_flags */
   8770         temp_size += sizeof(uint32);    /* combine_vlan_format_flags */
   8771         temp_size += sizeof(uint32);    /* combine_outer_dot1p_flags */
   8772         temp_size += sizeof(uint32);    /* combine_inner_dot1p_flags */
   8773         temp_size += sizeof(uint32);    /* combine_pkt_res_flags */
   8774         temp_size += sizeof(uint32);    /* combine_drop_flags */
   8775         temp_size += sizeof(uint32);    /* combine_ip_pkt_flags */
   8776         /* Attributes which are Array */
   8777         temp_size += sizeof(uint32);    /* Array Size */
   8778         temp_size += sizeof(uint32) * BCM_STAT_FLEX_BIT_ARRAY_SIZE;
   8779         /* _bcmPolicerAttrPort */
   8780         temp_size += sizeof(uint32);    /* Array Size */
   8781         temp_size += sizeof(uint32) * BCM_STAT_FLEX_BIT_ARRAY_SIZE;
   8782         /* _bcmPolicerAttrTosDscp */
   8783         temp_size += sizeof(uint32);    /* Array Size */
   8784         temp_size += sizeof(uint32) * BCM_STAT_FLEX_BIT_ARRAY_SIZE;
   8785         /* _bcmPolicerAttrTosEcn */
   8786         temp_size += sizeof(uint32);    /* Array Size */
   8787         temp_size += sizeof(uint32) * BCM_STAT_FLEX_BIT_ARRAY_SIZE;
   8788         /* _bcmPolicerAttrSvpType */
   8789         temp_size += sizeof(uint32);    /* Array Size */
   8790         temp_size += sizeof(uint32) * BCM_STAT_FLEX_BIT_ARRAY_SIZE;
   8791         /* _bcmPolicerAttrDvpType */
   8792         temp_size += sizeof(uint32);    /* Array Size */
   8793         temp_size += sizeof(uint32) * BCM_STAT_FLEX_BIT_ARRAY_SIZE;
   8794     }
   8795     return temp_size;
   8796 }
   8797 
   8798 /*
   8799  * Function:
   8800  *      _bcm_esw_stat_flex_scache_size_get
   8801  * Description:
   8802  *      Get stat flex scache size
   8803  * Parameters:
   8804  *      unit                  - (IN) unit number
   8805  * Return Value:
   8806  *      scache size
   8807  * Notes:
   8808  */
   8809 int _bcm_esw_stat_flex_scache_size_get(int unit)
   8810 {
   8811     int size = sizeof(uint32) * BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE;
   8812     size += sizeof(bcm_stat_flex_group_mode_related_info_t) *
   8813         BCM_STAT_FLEX_COUNTER_MAX_MODE *
   8814         BCM_STAT_FLEX_COUNTER_MAX_DIRECTION;
   8815 
   8816     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
   8817         (BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_4)) {
   8818             size +=  sizeof(bcm_stat_flex_custom_mode_related_info_t) *
   8819                         (BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE -
   8820                         BCM_CUSTOM_INGRESS_MODE_START) + 2 * sizeof(uint32);
   8821             size += sizeof(bcm_stat_flex_counter_id_related_info_t) *
   8822                         (BCM_MAX_STAT_COUNTER_IDS - 1);
   8823     }
   8824 
   8825 #ifdef BCM_TRIDENT3_SUPPORT
   8826     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
   8827         soc_feature(unit, soc_feature_stat_egr_multi_pipe_support) &&
   8828         (BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_7)) {
   8829         size += sizeof(uint32) + sizeof(bcm_stat_flex_custom_mode_info_t) *
   8830                     (BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE - BCM_CUSTOM_EGRESS_MODE_START);
   8831     }
   8832 #endif
   8833 
   8834     if (BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_8) {
   8835         if (soc_feature(unit, soc_feature_flex_stat_compression_share)) {
   8836             size += _bcm_flex_stat_compression_share_wb_size(unit);
   8837         }
   8838 #if defined(BCM_KATANA2_SUPPORT)
   8839         if (soc_feature(unit, soc_feature_flex_stat_attributes_class)) {
   8840             int combination_attr_matrix_size = 0;
   8841 
   8842             BCM_IF_ERROR_RETURN(_bcm_esw_stat_combine_attr_matrix_init(unit,
   8843                         &combination_attr_matrix_size));
   8844             size += (combination_attr_matrix_size*
   8845                         combination_attr_matrix_size*sizeof(uint32));
   8846         }
   8847 #endif
   8848     }
   8849 
   8850     return size;
   8851 }
   8852 
   8853 /*
   8854  * Function:
   8855  *      _bcm_esw_stat_flex_sync
   8856  * Description:
   8857  *      Sync flex s/w copy to h/w copy
   8858  * Parameters:
   8859  *      unit                  - (IN) unit number
   8860  * Return Value:
   8861  *      BCM_E_XXX
   8862  * Notes:
   8863  */
   8864 bcm_error_t _bcm_esw_stat_flex_sync(int unit)
   8865 {
   8866     int rv = 0;
   8867     uint32 mode=0;
   8868     int scache_size = 0;
   8869     int additional_scache_size = 0;
   8870     bcm_stat_flex_group_mode_related_info_t *flex_group_mode_related_info = NULL;
   8871 #ifdef BCM_TOMAHAWK_SUPPORT
   8872     uint32 stat_ctr_id = 1;
   8873     bcm_stat_flex_custom_mode_related_info_t *flex_custom_mode_related_info =
   8874                                  NULL;
   8875     bcm_stat_flex_counter_id_related_info_t *flex_stat_ctr_related_info =
   8876                                  NULL;
   8877     uint32 *per_pipe_mode = NULL;
   8878 #endif
   8879     uint32 sel=0;
   8880     uint8 *stat_flex_scache_ptr = NULL;
   8881 
   8882     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   8883               (BSL_META_U(unit,
   8884                           "_bcm_esw_stat_flex_sync \n")));
   8885     if (local_scache_ptr[unit]  == NULL) {
   8886         return BCM_E_INIT;
   8887     }
   8888     if ((handle[unit] == 0) ||
   8889         (flex_scache_allocated_size[unit] == 0) ||
   8890         (flex_scache_ptr[unit] == NULL)) {
   8891          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   8892                    (BSL_META_U(unit,
   8893                                "Scache memory was not allocate in init!! \n")));
   8894          return BCM_E_CONFIG;
   8895     }
   8896 
   8897     scache_size = _bcm_esw_stat_flex_scache_size_get(unit);
   8898     if (flex_scache_allocated_size[unit] < scache_size){
   8899         additional_scache_size = scache_size -
   8900             flex_scache_allocated_size[unit];
   8901         rv = soc_scache_realloc(unit, handle[unit], additional_scache_size);
   8902         if (rv != BCM_E_NONE) {
   8903             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   8904                     (BSL_META_U(unit,
   8905                                 "Realloc in sync failed:%s\n"),
   8906                                 bcm_errmsg(rv)));
   8907             return rv;
   8908         }
   8909         SOC_IF_ERROR_RETURN(soc_scache_ptr_get(unit, handle[unit],
   8910             (uint8 **)&flex_scache_ptr[unit],
   8911             &flex_scache_allocated_size[unit]));
   8912     }
   8913     flex_group_mode_related_info = (bcm_stat_flex_group_mode_related_info_t*)
   8914         (&flex_scache_ptr[unit][0] + BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE);
   8915 
   8916     sal_memcpy(&flex_scache_ptr[unit][0],
   8917                &local_scache_ptr[unit][0],
   8918                BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE);
   8919     for (mode=0; mode < BCM_STAT_FLEX_COUNTER_MAX_MODE ; mode++) {
   8920          if (flex_ingress_modes[unit][mode].flags != 0) {
   8921              flex_group_mode_related_info->flags = flex_ingress_modes[unit]
   8922                                                    [mode].flags;
   8923              flex_group_mode_related_info->num_selectors =
   8924                                                    flex_ingress_modes[unit]
   8925                                                    [mode].num_selectors;
   8926              flex_group_mode_related_info->total_counters =
   8927                                                    flex_ingress_modes[unit]
   8928                                                    [mode].total_counters;
   8929              flex_group_mode_related_info->flags |= (flex_ingress_modes[unit]
   8930                                                    [mode].group_mode << 16);
   8931              for (sel=0;
   8932                   sel < flex_group_mode_related_info->num_selectors;
   8933                   sel++) {
   8934                   flex_group_mode_related_info->attr_selectors[sel].counter_offset =
   8935                       flex_ingress_modes[unit][mode].attr_selectors[sel].counter_offset;
   8936                   flex_group_mode_related_info->attr_selectors[sel].attr =
   8937                       flex_ingress_modes[unit][mode].attr_selectors[sel].attr;
   8938                   flex_group_mode_related_info->attr_selectors[sel].attr_value =
   8939                       flex_ingress_modes[unit][mode].attr_selectors[sel].attr_value;
   8940               }
   8941          }
   8942          flex_group_mode_related_info++;
   8943     }
   8944     for (mode=0; mode < BCM_STAT_FLEX_COUNTER_MAX_MODE ; mode++) {
   8945          if (flex_egress_modes[unit][mode].flags != 0) {
   8946              flex_group_mode_related_info->flags = flex_egress_modes[unit]
   8947                                                    [mode].flags;
   8948              flex_group_mode_related_info->num_selectors =
   8949                                                    flex_egress_modes[unit]
   8950                                                    [mode].num_selectors;
   8951              flex_group_mode_related_info->total_counters =
   8952                                                    flex_egress_modes[unit]
   8953                                                    [mode].total_counters;
   8954              flex_group_mode_related_info->flags |= (flex_egress_modes[unit]
   8955                                                    [mode].group_mode << 16);
   8956              for (sel=0;
   8957                   sel < flex_group_mode_related_info->num_selectors;
   8958                   sel++) {
   8959                   flex_group_mode_related_info->attr_selectors[sel].counter_offset=
   8960                       flex_egress_modes[unit][mode].attr_selectors[sel].counter_offset;
   8961                   flex_group_mode_related_info->attr_selectors[sel].attr=
   8962                       flex_egress_modes[unit][mode].attr_selectors[sel].attr;
   8963                   flex_group_mode_related_info->attr_selectors[sel].attr_value=
   8964                       flex_egress_modes[unit][mode].attr_selectors[sel].attr_value;
   8965               }
   8966          }
   8967          flex_group_mode_related_info++;
   8968     }
   8969 
   8970     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
   8971                    (BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_4)) {
   8972 #ifdef BCM_TOMAHAWK_SUPPORT
   8973         flex_custom_mode_related_info = (void *)flex_group_mode_related_info;
   8974         for (mode=BCM_CUSTOM_INGRESS_MODE_START; 
   8975            (mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE) ; mode++) {
   8976              int mode_idx = mode - BCM_CUSTOM_INGRESS_MODE_START;
   8977              if (flex_custom_ingress_modes[unit][mode_idx].used != 0) {
   8978                  int mode_idx = mode - BCM_CUSTOM_INGRESS_MODE_START;
   8979                  flex_custom_mode_related_info->custom_mode = mode;
   8980                  flex_custom_mode_related_info->offset_mode = 
   8981                              flex_custom_ingress_modes[unit][mode_idx].offset_mode;
   8982 
   8983                  flex_custom_mode_related_info->AllocPool = 0;
   8984                  flex_custom_mode_related_info->fg_id = 0xffffffff;
   8985                  if ((flex_custom_ingress_modes[unit][mode_idx].hint.type == 
   8986                                      bcmStatGroupAllocHintIngressFieldGroup) ||
   8987                      (flex_custom_ingress_modes[unit][mode_idx].hint.type == 
   8988                                      bcmStatGroupAllocHintExactMatchFieldGroup) ||
   8989                      (flex_custom_ingress_modes[unit][mode_idx].hint.type == 
   8990                                      bcmStatGroupAllocHintVlanFieldGroup)) {
   8991                      flex_custom_mode_related_info->AllocPool = 
   8992                               flex_custom_ingress_modes[unit][mode_idx].AllocPool;
   8993                      flex_custom_mode_related_info->fg_id = 
   8994                               flex_custom_ingress_modes[unit][mode_idx].hint.value;
   8995 
   8996                  }
   8997              } else {
   8998                  flex_custom_mode_related_info->custom_mode = 0;
   8999              }
   9000              flex_custom_mode_related_info++;
   9001         }
   9002         flex_stat_ctr_related_info = (void *)flex_custom_mode_related_info;
   9003         for (stat_ctr_id=1; 
   9004            (stat_ctr_id < BCM_MAX_STAT_COUNTER_IDS) ; stat_ctr_id++, flex_stat_ctr_related_info++) {
   9005              bcm_stat_counter_map_t stat_ctr_map;
   9006              _bcm_get_stat_counter_map(unit, stat_ctr_id, &stat_ctr_map);
   9007              flex_stat_ctr_related_info->used = stat_ctr_map.used;
   9008              if (stat_ctr_map.used != 0) {
   9009                  flex_stat_ctr_related_info->mode = stat_ctr_map.mode;
   9010                  flex_stat_ctr_related_info->base_idx = stat_ctr_map.base_idx;
   9011                  flex_stat_ctr_related_info->object = stat_ctr_map.object;
   9012                  flex_stat_ctr_related_info->group = stat_ctr_map.group;
   9013                  flex_stat_ctr_related_info->pool = stat_ctr_map.pool;
   9014                  if ((stat_ctr_map.mode >= BCM_CUSTOM_INGRESS_MODE_START) && 
   9015                      (stat_ctr_map.mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
   9016                       flex_stat_ctr_related_info->used = (stat_ctr_map.pipe << 6) |
   9017                            (flex_custom_ingress_modes[unit][stat_ctr_map.mode - BCM_CUSTOM_INGRESS_MODE_START].total_counters);
   9018 
   9019                  } else if (stat_ctr_map.mode < BCM_STAT_FLEX_COUNTER_MAX_MODE){
   9020                       bcm_stat_flex_direction_t direction;
   9021                       BCM_IF_ERROR_RETURN(
   9022                             _bcm_esw_stat_validate_object(unit, stat_ctr_map.object, &direction));
   9023                       if (direction == bcmStatFlexDirectionIngress) {
   9024                           /* INGRESS SIDE */
   9025                           flex_stat_ctr_related_info->used =
   9026                              (flex_ingress_modes[unit][stat_ctr_map.mode].total_counters);
   9027                       } else {
   9028                           /* EGRESS SIDE */
   9029                           flex_stat_ctr_related_info->used =
   9030                              (flex_egress_modes[unit][stat_ctr_map.mode].total_counters);
   9031                       }
   9032                  }
   9033              }
   9034         }
   9035         per_pipe_mode = (uint32 *)flex_stat_ctr_related_info;
   9036         *per_pipe_mode = !_bcm_esw_get_fp_mode_global(unit, bcmFieldQualifyStageIngress);
   9037         per_pipe_mode = ((uint32 *)flex_stat_ctr_related_info)+1;
   9038         *per_pipe_mode = !_bcm_esw_get_fp_mode_global(unit, bcmFieldQualifyStageLookup);
   9039 #endif
   9040     }
   9041 #ifdef BCM_TRIDENT3_SUPPORT
   9042     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
   9043         soc_feature(unit, soc_feature_stat_egr_multi_pipe_support) &&
   9044                    (BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_7)) {
   9045        bcm_stat_flex_custom_mode_info_t *flex_egr_custom_mode_info =
   9046                                     NULL;
   9047        bcm_stat_flex_counter_id_info_t *flex_egr_stat_ctr_info =
   9048                                     NULL;
   9049 
   9050         flex_egr_custom_mode_info = (void *)(per_pipe_mode + 1);
   9051         for (mode = BCM_CUSTOM_EGRESS_MODE_START;
   9052            (mode < BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE) ; mode++) {
   9053              int mode_idx = mode - BCM_CUSTOM_EGRESS_MODE_START;
   9054              if (flex_custom_egress_modes[unit][mode_idx].used != 0) {
   9055                  flex_egr_custom_mode_info->custom_mode = mode;
   9056                  flex_egr_custom_mode_info->offset_mode =
   9057                          flex_custom_egress_modes[unit][mode_idx].offset_mode;
   9058 
   9059                  flex_egr_custom_mode_info->AllocPool = 0;
   9060                  flex_egr_custom_mode_info->fg_id = 0xffffffff;
   9061                  if (flex_custom_egress_modes[unit][mode_idx].hint.type ==
   9062                                      bcmStatGroupAllocHintEgressFieldGroup){
   9063                      flex_egr_custom_mode_info->AllocPool =
   9064                           flex_custom_egress_modes[unit][mode_idx].AllocPool;
   9065                      flex_egr_custom_mode_info->fg_id =
   9066                           flex_custom_egress_modes[unit][mode_idx].hint.value;
   9067                  }
   9068              } else {
   9069                  flex_egr_custom_mode_info->custom_mode = 0;
   9070              }
   9071              flex_egr_custom_mode_info++;
   9072         }
   9073         flex_egr_stat_ctr_info = (void *)flex_egr_custom_mode_info;
   9074 
   9075         per_pipe_mode = (uint32 *)flex_egr_stat_ctr_info;
   9076         *per_pipe_mode = !_bcm_esw_get_fp_mode_global(unit,
   9077             bcmFieldQualifyStageEgress);
   9078     }
   9079 #endif
   9080 
   9081     stat_flex_scache_ptr = (uint8 *)flex_group_mode_related_info;
   9082 
   9083     if ((BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_8) &&
   9084             (soc_feature(unit, soc_feature_flex_stat_compression_share))) {
   9085         _bcm_esw_stat_flex_compressed_attr_flags_sync(unit,&stat_flex_scache_ptr);
   9086     }
   9087 #if defined(BCM_KATANA2_SUPPORT)
   9088     if ((BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_8) &&
   9089             (soc_feature(unit, soc_feature_flex_stat_attributes_class))) {
   9090         _bcm_esw_stat_flex_compressed_attr_matrix_sync(unit,&stat_flex_scache_ptr);
   9091     }
   9092 #endif
   9093     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   9094               (BSL_META_U(unit,
   9095                           "OK \n")));
   9096     return BCM_E_NONE;
   9097 }
   9098 #endif
   9099 
   9100 #define CONFIG_ING_OBJECT 0
   9101 #define CONFIG_EGR_OBJECT 1
   9102 
   9103 /*
   9104  * Function:
   9105  *      _bcm_esw_stat_flex_cleanup
   9106  * Description:
   9107  *      Clean and free all allocated  flex resources in the specified pipe
   9108  * Parameters:
   9109  *      unit                  - (IN) unit number
   9110  * Return Value:
   9111  *      BCM_E_XXX
   9112  * Notes:
   9113  */
   9114 bcm_error_t _bcm_esw_stat_flex_cleanup_pipe(int unit, int pipe_num, 
   9115                                             bcm_stat_flex_direction_t direction)
   9116 {
   9117     uint32      pool_id=0;
   9118 
   9119     uint32      num_pools[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
   9120 #if defined(BCM_TRIDENT2_SUPPORT)
   9121     int         buffer_id;
   9122     bcm_stat_flex_mode_t offset_mode;
   9123 #endif /* BCM_TRIDENT2_SUPPORT */
   9124     int         pool_group_id;
   9125 #ifdef BCM_TOMAHAWK3_SUPPORT
   9126     uint16 dev_id;
   9127     uint8  rev_id;
   9128     soc_mem_t mem;
   9129 
   9130     soc_cm_get_id(unit, &dev_id, &rev_id);
   9131 #endif
   9132     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   9133               (BSL_META_U(unit,
   9134                           "_bcm_esw_stat_flex_cleanup \n")));
   9135     num_pools[bcmStatFlexDirectionIngress]=SOC_INFO(unit).
   9136                                            num_flex_ingress_pools;
   9137     num_pools[bcmStatFlexDirectionEgress] =SOC_INFO(unit).
   9138                                            num_flex_egress_pools;
   9139     if (flex_stat_mutex[unit] != NULL) {
   9140         BCM_STAT_FLEX_COUNTER_LOCK(unit);
   9141         soc_counter_extra_unregister(unit, _bcm_esw_stat_flex_callback);
   9142         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
   9143         sal_mutex_destroy(flex_stat_mutex[unit]);
   9144         flex_stat_mutex[unit] = NULL;
   9145     }
   9146 
   9147 
   9148 #if defined(BCM_TRIDENT2_SUPPORT)
   9149     if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
   9150         if (flex_temp_counter_dual[unit][direction] != NULL){
   9151             soc_cm_sfree(unit,flex_temp_counter_dual[unit][direction]);
   9152             flex_temp_counter_dual[unit][direction]=NULL;
   9153         }
   9154     }
   9155 #endif /* BCM_TRIDENT2_SUPPORT*/
   9156 
   9157     if (flex_temp_counter[unit][direction] != NULL){
   9158         soc_cm_sfree(unit,flex_temp_counter[unit][direction]);
   9159         flex_temp_counter[unit][direction]=NULL;
   9160     }
   9161     if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
   9162         if (direction == bcmStatFlexDirectionIngress) {
   9163             for (pool_group_id=0;
   9164                  pool_group_id < _bcm_esw_get_max_pool_groups(unit);
   9165                  pool_group_id++) {
   9166                 if (BCM_E_PARAM ==  
   9167                     _bcm_esw_stat_flex_oam_enable_ingress_group(unit,
   9168                                                               pool_group_id,
   9169                                                               0)) {
   9170                     continue;
   9171                 }
   9172                 flex_pool_group[unit][pipe_num][pool_group_id].group_type =
   9173                      BCM_FLEX_POOL_GROUP_USED_BY_NONE;
   9174                 flex_pool_group[unit][pipe_num][pool_group_id].free_pools  =
   9175                      BCM_STAT_FLEX_COUNTER_POOLS_PER_GROUP;
   9176                 flex_pool_group[unit][pipe_num][pool_group_id].base_pool = 
   9177                      pool_group_id * BCM_STAT_FLEX_COUNTER_POOLS_PER_GROUP;
   9178             }
   9179         }
   9180     }
   9181     for (pool_id=0;pool_id<num_pools[direction];pool_id++) {
   9182          _bcm_esw_stat_flex_enable_pool(
   9183                   unit,
   9184                   direction,
   9185                   _pool_ctr_register[direction][pool_id],
   9186                   0);
   9187          if (flex_aidxres_list_handle[unit][direction][pipe_num][pool_id] != 0) {
   9188              shr_aidxres_list_destroy(flex_aidxres_list_handle[unit]
   9189                                       [direction][pipe_num][pool_id]);
   9190              flex_aidxres_list_handle[unit][direction][pipe_num][pool_id] = 0;
   9191          }
   9192          flex_pool_stat[unit][direction][pipe_num][pool_id].used_by_tables = 0;
   9193          flex_pool_stat[unit][direction][pipe_num][pool_id].used_entries = 0;
   9194          flex_pool_stat[unit][direction][pipe_num][pool_id].attached_entries = 0;
   9195          SHR_BITCLR_RANGE(flex_pool_stat[unit][direction][pipe_num][pool_id].used_by_objects, 0, bcmIntStatObjectMaxValue);
   9196          if (flex_byte_counter[unit][direction][pipe_num][pool_id] != NULL) {
   9197              soc_cm_sfree(unit,
   9198                           flex_byte_counter[unit][direction][pipe_num][pool_id]);
   9199              flex_byte_counter[unit][direction][pipe_num][pool_id] = NULL;
   9200          }
   9201          if (flex_packet_counter[unit][direction][pipe_num][pool_id] != NULL) {
   9202              soc_cm_sfree(unit,
   9203                           flex_packet_counter[unit][direction][pipe_num][pool_id]);
   9204              flex_packet_counter[unit][direction][pipe_num][pool_id] = NULL;
   9205          }
   9206          if (flex_packet64_counter[unit][direction][pipe_num][pool_id] != NULL) {
   9207              soc_cm_sfree(unit,
   9208                           flex_packet64_counter[unit][direction][pipe_num][pool_id]);
   9209              flex_packet64_counter[unit][direction][pipe_num][pool_id] = NULL;
   9210          }
   9211 
   9212          if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
   9213              if (flex_byte_counter_compaction[unit][direction][pipe_num][pool_id] != NULL) {
   9214                  soc_cm_sfree(unit,
   9215                          flex_byte_counter_compaction[unit][direction][pipe_num][pool_id]);
   9216                  flex_byte_counter_compaction[unit][direction][pipe_num][pool_id] = NULL;
   9217              }
   9218              if (flex_packet_counter_compaction[unit][direction][pipe_num][pool_id] != NULL) {
   9219                  soc_cm_sfree(unit,
   9220                          flex_packet_counter_compaction[unit][direction][pipe_num][pool_id]);
   9221                  flex_packet_counter_compaction[unit][direction][pipe_num][pool_id] = NULL;
   9222              }
   9223              if (flex_packet64_counter_compaction[unit][direction][pipe_num][pool_id] != NULL) {
   9224                  soc_cm_sfree(unit,
   9225                          flex_packet64_counter_compaction[unit][direction][pipe_num][pool_id]);
   9226                  flex_packet64_counter_compaction[unit][direction][pipe_num][pool_id] = NULL;
   9227              }
   9228          }
   9229 #ifdef BCM_TOMAHAWK_SUPPORT
   9230          if (SOC_IS_TOMAHAWKX(unit) ||SOC_IS_TRIDENT3X(unit)) {
   9231              if (residual_byte_counter[unit][direction][pipe_num][pool_id] != NULL) {
   9232                  soc_cm_sfree(unit,
   9233                               residual_byte_counter[unit][direction][pipe_num]
   9234                               [pool_id]);
   9235                  residual_byte_counter[unit][direction][pipe_num][pool_id] = NULL;
   9236              }
   9237              if (residual_packet_counter[unit][direction][pipe_num][pool_id] !=
   9238                  NULL) {
   9239                  soc_cm_sfree(unit,
   9240                          residual_packet_counter[unit][direction]
   9241                          [pipe_num][pool_id]);
   9242                  residual_packet_counter[unit][direction][pipe_num][pool_id] = NULL;
   9243              }
   9244              if (bcmStatFlexDirectionIngress == direction) {
   9245                  if (NULL != ifp_color_map[unit][pipe_num][pool_id]) {
   9246                      soc_cm_sfree(unit, ifp_color_map[unit][pipe_num][pool_id]);
   9247                      ifp_color_map[unit][pipe_num][pool_id] = NULL;
   9248                  }
   9249              }
   9250          }
   9251 #endif
   9252 #ifdef BCM_TOMAHAWK3_SUPPORT
   9253          mem = _ctr_counter_table[direction][pool_id];
   9254          if ((mem == EGR_PORTm || mem == PORT_TABm) &&
   9255                                 dev_id == BCM56983_DEVICE_ID) {
   9256             continue;
   9257          }
   9258 #endif
   9259          if(flex_base_index_reference_count[unit][direction][pipe_num][pool_id]
   9260             != NULL) {
   9261             sal_free(flex_base_index_reference_count[unit][direction][pipe_num]
   9262                      [pool_id]);
   9263             flex_base_index_reference_count[unit][direction][pipe_num][pool_id]=NULL;
   9264          }
   9265 #if defined(BCM_TRIDENT2_SUPPORT)
   9266     if (SOC_IS_TRIDENT2X(unit) &&
   9267         soc_feature(unit, soc_feature_advanced_flex_counter)) {
   9268         for (offset_mode = 0; offset_mode < BCM_STAT_FLEX_COUNTER_MAX_MODE;
   9269              offset_mode++) {
   9270             if(_flex_stat_mode_base_map[unit][direction][pool_id][offset_mode]
   9271                                                                     != NULL) {
   9272                 sal_free(_flex_stat_mode_base_map[unit][direction][pool_id]
   9273                     [offset_mode]);
   9274                 _flex_stat_mode_base_map[unit][direction][pool_id]
   9275                     [offset_mode] = NULL;
   9276             }
   9277         }
   9278     }
   9279 #endif
   9280 #if defined(BCM_TRIDENT2_SUPPORT)
   9281        if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
   9282            for (buffer_id = 0; buffer_id < _BCM_FLEX_STAT_BUFFS;
   9283                 buffer_id++) {
   9284                if (flex_byte_counter_x[unit][direction][pool_id][buffer_id]
   9285                                                                  != NULL) {
   9286                    soc_cm_sfree(unit,
   9287                                 flex_byte_counter_x[unit][direction]
   9288                                 [pool_id][buffer_id]);
   9289                    flex_byte_counter_x[unit][direction][pool_id][buffer_id]
   9290                        = NULL;
   9291                }
   9292                if (flex_byte_counter_y[unit][direction][pool_id][buffer_id]
   9293                                                                  != NULL) {
   9294                    soc_cm_sfree(unit,
   9295                                 flex_byte_counter_y[unit][direction]
   9296                                 [pool_id][buffer_id]);
   9297                    flex_byte_counter_y[unit][direction][pool_id][buffer_id]
   9298                        = NULL;
   9299                }
   9300                if (flex_pkt_counter_x[unit][direction][pool_id][buffer_id]
   9301                                                                  != NULL) {
   9302                    soc_cm_sfree(unit,
   9303                                 flex_pkt_counter_x[unit][direction]
   9304                                 [pool_id][buffer_id]);
   9305                    flex_pkt_counter_x[unit][direction][pool_id][buffer_id]
   9306                        = NULL;
   9307                }
   9308                if (flex_pkt_counter_y[unit][direction][pool_id][buffer_id]
   9309                                                                  != NULL) {
   9310                    soc_cm_sfree(unit,
   9311                                 flex_pkt_counter_y[unit][direction]
   9312                                 [pool_id][buffer_id]);
   9313                    flex_pkt_counter_y[unit][direction][pool_id][buffer_id]
   9314                        = NULL;
   9315                }
   9316            }
   9317            if (flex_counter_toggle[unit][direction][pool_id] != NULL) {
   9318                    soc_cm_sfree(unit,
   9319                             flex_counter_toggle[unit][direction]
   9320                             [pool_id]);
   9321                    flex_counter_toggle[unit][direction][pool_id] = NULL;
   9322            }
   9323        }
   9324 #endif /* BCM_TRIDENT2_SUPPORT*/
   9325     }
   9326     if (local_scache_ptr[unit] != NULL) {
   9327         sal_free(local_scache_ptr[unit]);
   9328         local_scache_ptr[unit] = NULL;
   9329     }
   9330     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
   9331               (BSL_META_U(unit,
   9332                           "OK \n")));
   9333     return BCM_E_NONE;
   9334 }
   9335 
   9336 bcm_error_t _bcm_esw_stat_flex_cleanup(int unit)
   9337 {
   9338 #ifdef BCM_TOMAHAWK_SUPPORT
   9339    int pipe_num = 0;
   9340 #endif
   9341 
   9342 #if defined (BCM_TOMAHAWK_SUPPORT) && defined (INCLUDE_FLOWTRACKER)
   9343     if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
   9344          soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
   9345          soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
   9346        (void)_bcm_esw_stat_flex_flowtracker_cleanup(unit);
   9347     }
   9348 #endif
   9349 
   9350 #ifdef BCM_TOMAHAWK_SUPPORT
   9351    if (soc_feature(unit,soc_feature_stat_multi_pipe_support)) {
   9352       for(pipe_num = 0; pipe_num < _MAX_PIPES_PER_DEV(unit); ++pipe_num) {
   9353           _bcm_esw_stat_flex_cleanup_pipe(unit, pipe_num, bcmStatFlexDirectionIngress);
   9354          if(SOC_IS_TRIDENT3X(unit)) {
   9355              _bcm_esw_stat_flex_cleanup_pipe(unit, pipe_num,
   9356                  bcmStatFlexDirectionEgress);
   9357          }
   9358       }
   9359      if(!SOC_IS_TRIDENT3X(unit)) {
   9360          _bcm_esw_stat_flex_cleanup_pipe(unit, 0, bcmStatFlexDirectionEgress);
   9361       }
   9362    } else {
   9363 #endif
   9364       _bcm_esw_stat_flex_cleanup_pipe(unit, 0, bcmStatFlexDirectionIngress);
   9365       _bcm_esw_stat_flex_cleanup_pipe(unit, 0, bcmStatFlexDirectionEgress);
   9366 
   9367 #ifdef BCM_TOMAHAWK_SUPPORT
   9368    }
   9369 #endif
   9370     if (flex_ingress_modes[unit] != NULL) {
   9371         sal_free(flex_ingress_modes[unit]);
   9372         flex_ingress_modes[unit] = NULL;
   9373     }
   9374     if (flex_custom_ingress_modes[unit] != NULL) {
   9375         sal_free(flex_custom_ingress_modes[unit]);
   9376         flex_custom_ingress_modes[unit] = NULL;
   9377     }
   9378     if (flex_egress_modes[unit] != NULL) {
   9379         sal_free(flex_egress_modes[unit]);
   9380         flex_egress_modes[unit] = NULL;
   9381     }
   9382 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   9383     if (flex_custom_egress_modes[unit] != NULL) {
   9384         sal_free(flex_custom_egress_modes[unit]);
   9385         flex_custom_egress_modes[unit] = NULL;
   9386     }
   9387 #endif
   9388 
   9389 #if defined(BCM_TOMAHAWK_SUPPORT)
   9390     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id)) {
   9391         stat_ctr_map_deinit(unit);
   9392     }
   9393 #endif
   9394     if (soc_feature(unit, soc_feature_flex_stat_compression_share)) {
   9395         if (_bcm_esw_stat_flex_compressed_shared_attr_map_init(unit,FALSE) !=
   9396                 BCM_E_NONE)
   9397             return BCM_E_MEMORY;
   9398     }
   9399 
   9400     /* Reset compaction info */
   9401     if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
   9402         sal_memset(&compaction_info, 0x0, sizeof(compaction_status_t));
   9403     }
   9404 
   9405     /* Cleanup Customized Stat class identifier related structures. */
   9406 #if defined(BCM_KATANA2_SUPPORT)
   9407     if (soc_feature(unit, soc_feature_flex_stat_attributes_class)) {
   9408         _bcm_esw_stat_group_mode_attr_class_id_cleanup(unit);
   9409     }
   9410 #endif
   9411     return BCM_E_NONE;
   9412 }
   9413 
   9414 
   9415 
   9416 STATIC bcm_error_t _bcm_esw_stat_flex_object_config_init(int unit, int flag)
   9417 {
   9418     int i;
   9419     int count1 = COUNTOF(ing_flex_object_config);
   9420     int count2 = COUNTOF(egr_flex_object_config);
   9421 
   9422     if (flag == CONFIG_ING_OBJECT) {
   9423         for (i = 0; i < count1; i++) {
   9424             ing_flex_object_config[i].config_pool = INVALID_CONFIG;
   9425             ing_flex_object_config[i].share_criteria = INVALID_CONFIG;
   9426             ing_flex_object_config[i].exclude_criteria = INVALID_CONFIG;
   9427         }
   9428     } else {
   9429         for (i = 0; i < count2; i++) {
   9430             egr_flex_object_config[i].config_pool = INVALID_CONFIG;
   9431             egr_flex_object_config[i].share_criteria = INVALID_CONFIG;
   9432             egr_flex_object_config[i].exclude_criteria = INVALID_CONFIG;
   9433         }    
   9434     }
   9435 
   9436     return BCM_E_NONE;
   9437 }
   9438 
   9439 
   9440 STATIC bcm_error_t _bcm_esw_stat_flex_object_config_get(
   9441                 int unit,
   9442                 soc_mem_t mem,
   9443                 flex_object_config_t *object_config
   9444                 )
   9445 {
   9446     int i;
   9447     soc_mem_t config_mem = mem;
   9448     int count_ing = COUNTOF(ing_flex_object_config);
   9449     int count_egr = COUNTOF(egr_flex_object_config);
   9450     int rv1, rv2;
   9451 
   9452     switch(mem) {
   9453         case MPLS_ENTRYm:
   9454 #if defined(BCM_TRIUMPH3_SUPPORT)
   9455         case MPLS_ENTRY_EXTDm:
   9456 #endif
   9457             config_mem = MPLS_ENTRYm;
   9458             break;
   9459 #if defined(BCM_TOMAHAWK3_SUPPORT)
   9460         case MPLS_ENTRY_SINGLEm:
   9461             config_mem = MPLS_ENTRY_SINGLEm;
   9462             break;
   9463 #endif
   9464         case VLAN_XLATEm:
   9465 #if defined(BCM_TRIUMPH3_SUPPORT)
   9466         case VLAN_XLATE_EXTDm:
   9467 #endif
   9468 #if defined (BCM_TRIDENT3_SUPPORT)
   9469             if (SOC_IS_TRIDENT3X(unit)){
   9470                 config_mem = VLAN_XLATE_1_DOUBLEm;
   9471             } else
   9472 #endif
   9473             {
   9474                 config_mem = VLAN_XLATEm;
   9475             }
   9476             break;
   9477         case L3_ENTRY_2m:
   9478         case L3_ENTRY_4m:
   9479         case EXT_IPV4_UCAST_WIDEm:
   9480         case EXT_IPV6_128_UCAST_WIDEm:
   9481 #if defined (BCM_TRIDENT3_SUPPORT)
   9482             if (SOC_IS_TRIDENT3X(unit)){
   9483                 config_mem = L3_ENTRY_DOUBLEm;
   9484             } else
   9485 #endif
   9486             {
   9487             config_mem = L3_ENTRY_2m;
   9488             }
   9489             break;
   9490 #if defined(BCM_TRIDENT2_SUPPORT)
   9491         case L3_DEFIPm:
   9492         case L3_DEFIP_PAIR_128m:
   9493         case L3_DEFIP_ALPM_RAWm:
   9494         case L3_DEFIP_ALPM_IPV4_1m:
   9495         case L3_DEFIP_ALPM_IPV6_64_1m:
   9496         case L3_DEFIP_ALPM_IPV6_128m:
   9497         case L3_DEFIP_LEVEL1m:
   9498         case L3_DEFIP_PAIR_LEVEL1m:
   9499         case L3_DEFIP_ALPM_LEVEL2m:
   9500         case L3_DEFIP_ALPM_LEVEL3m:
   9501             config_mem = L3_DEFIPm;
   9502             break;
   9503         case L3_ENTRY_IPV4_MULTICASTm:
   9504         case L3_ENTRY_IPV6_MULTICASTm:
   9505 #if defined (BCM_TRIDENT3_SUPPORT)
   9506             if (SOC_IS_TRIDENT3X(unit)){
   9507                 config_mem = L3_ENTRY_DOUBLEm;
   9508             } else
   9509 #endif
   9510 #if defined (BCM_TOMAHAWK3_SUPPORT)
   9511             if (SOC_IS_TOMAHAWK3(unit)){
   9512                 config_mem = L3_ENTRY_DOUBLEm;
   9513             } else
   9514 #endif
   9515             {
   9516                 config_mem = L3_ENTRY_IPV4_MULTICASTm;
   9517             }
   9518             break;
   9519 #endif
   9520 #if defined(BCM_TRIDENT3_SUPPORT)
   9521         case PORT_TABm:
   9522             if (SOC_IS_TRIDENT3X(unit)){
   9523                 config_mem = LPORT_TABm;
   9524             }
   9525             break;
   9526         case EGR_DVP_ATTRIBUTE_1m:
   9527             if (SOC_IS_TRIDENT3X(unit)){
   9528                 config_mem = EGR_DVP_ATTRIBUTEm;
   9529             }
   9530             break;
   9531         case EGR_VLAN_XLATEm:
   9532         case EGR_VLAN_XLATE_2_DOUBLEm:
   9533             if (SOC_IS_TRIDENT3X(unit)){
   9534                 config_mem = EGR_VLAN_XLATE_1_DOUBLEm;
   9535             }
   9536             break;
   9537         case EGR_PORTm:
   9538             if (SOC_IS_TRIDENT3X(unit)){
   9539                 config_mem = EGR_LPORT_PROFILEm;
   9540             }
   9541             break;
   9542 #endif
   9543 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
   9544         case EFP_POLICY_TABLE_PIPE0m:
   9545         case EFP_POLICY_TABLE_PIPE1m:
   9546             config_mem = EFP_POLICY_TABLEm;
   9547             break;
   9548 #endif
   9549         default:
   9550             config_mem = mem;
   9551             break;
   9552     }
   9553 
   9554     for (i = 0; i < count_ing; i++) {
   9555         if (config_mem == ing_flex_object_config[i].obj_mem) {
   9556             *object_config = ing_flex_object_config[i];
   9557             rv1 = BCM_E_NONE;
   9558             break;
   9559         }
   9560     }
   9561 
   9562     if (i >= count_ing) {
   9563         rv1 = BCM_E_NOT_FOUND;
   9564     }
   9565 
   9566     for (i = 0; i < count_egr; i++) {
   9567         if (config_mem == egr_flex_object_config[i].obj_mem) {
   9568             *object_config = egr_flex_object_config[i];
   9569             rv2 = BCM_E_NONE;
   9570             break;
   9571         }
   9572     }
   9573 
   9574     if (i >= count_egr) {
   9575         rv2 = BCM_E_NOT_FOUND;
   9576     }
   9577 
   9578     if ((rv1 == BCM_E_NOT_FOUND) && (rv2 == BCM_E_NOT_FOUND)) {
   9579         object_config = NULL;
   9580         return BCM_E_NOT_FOUND;
   9581     }
   9582 
   9583     return BCM_E_NONE;
   9584 }
   9585 
   9586 STATIC bcm_error_t _bcm_esw_stat_flex_object_config_set(
   9587                 int unit,
   9588                 soc_mem_t mem,
   9589                 flex_object_config_t object_config
   9590                 )
   9591 {
   9592     int i;
   9593     soc_mem_t config_mem = mem;
   9594     int count_ing = COUNTOF(ing_flex_object_config);
   9595     int count_egr = COUNTOF(egr_flex_object_config);
   9596     int rv1, rv2;
   9597 
   9598     switch(mem) {
   9599         case MPLS_ENTRYm:
   9600 #if defined(BCM_TRIUMPH3_SUPPORT)
   9601         case MPLS_ENTRY_EXTDm:
   9602 #endif
   9603             config_mem = MPLS_ENTRYm;
   9604             break;
   9605 #if defined(BCM_TOMAHAWK3_SUPPORT)
   9606         case MPLS_ENTRY_SINGLEm:
   9607             config_mem = MPLS_ENTRY_SINGLEm;
   9608             break;
   9609 #endif
   9610         case VLAN_XLATEm:
   9611 #if defined(BCM_TRIUMPH3_SUPPORT)
   9612         case VLAN_XLATE_EXTDm:
   9613 #endif
   9614 #if defined (BCM_TRIDENT3_SUPPORT)
   9615             if (SOC_IS_TRIDENT3X(unit)){
   9616                 config_mem = VLAN_XLATE_1_DOUBLEm;
   9617             } else
   9618 #endif
   9619             {
   9620                 config_mem = VLAN_XLATEm;
   9621             }
   9622             break;
   9623         case L3_ENTRY_2m:
   9624         case L3_ENTRY_4m:
   9625         case EXT_IPV4_UCAST_WIDEm:
   9626         case EXT_IPV6_128_UCAST_WIDEm:
   9627 #if defined (BCM_TRIDENT3_SUPPORT)
   9628             if (SOC_IS_TRIDENT3X(unit)){
   9629                 config_mem = L3_ENTRY_DOUBLEm;
   9630             } else
   9631 #endif
   9632             {
   9633                 config_mem = L3_ENTRY_2m;
   9634             }
   9635             break;
   9636 #if defined(BCM_TRIDENT2_SUPPORT)
   9637         case L3_DEFIPm:
   9638         case L3_DEFIP_PAIR_128m:
   9639         case L3_DEFIP_ALPM_RAWm:
   9640         case L3_DEFIP_ALPM_IPV4_1m:
   9641         case L3_DEFIP_ALPM_IPV6_64_1m:
   9642         case L3_DEFIP_ALPM_IPV6_128m:
   9643         case L3_DEFIP_LEVEL1m:
   9644         case L3_DEFIP_PAIR_LEVEL1m:
   9645         case L3_DEFIP_ALPM_LEVEL2m:
   9646         case L3_DEFIP_ALPM_LEVEL3m:
   9647             config_mem = L3_DEFIPm;
   9648             break;
   9649         case L3_ENTRY_IPV4_MULTICASTm:
   9650         case L3_ENTRY_IPV6_MULTICASTm:
   9651 #if defined (BCM_TRIDENT3_SUPPORT)
   9652             if (SOC_IS_TRIDENT3X(unit)){
   9653                 config_mem = L3_ENTRY_DOUBLEm;
   9654             } else
   9655 #endif
   9656 #if defined (BCM_TOMAHAWK3_SUPPORT)
   9657             if (SOC_IS_TOMAHAWK3(unit)){
   9658                 config_mem = L3_ENTRY_DOUBLEm;
   9659             } else
   9660 #endif      
   9661             {
   9662                 config_mem = L3_ENTRY_IPV4_MULTICASTm;
   9663             }
   9664             break;
   9665 #endif
   9666 #if defined(BCM_TRIDENT3_SUPPORT)
   9667         case PORT_TABm:
   9668             if (SOC_IS_TRIDENT3X(unit)){
   9669                 config_mem = LPORT_TABm;
   9670             }
   9671             break;
   9672         case EGR_DVP_ATTRIBUTE_1m:
   9673             if (SOC_IS_TRIDENT3X(unit)){
   9674                 config_mem = EGR_DVP_ATTRIBUTEm;
   9675             }
   9676             break;
   9677         case EGR_VLAN_XLATEm:
   9678         case EGR_VLAN_XLATE_2_DOUBLEm:
   9679             if (SOC_IS_TRIDENT3X(unit)){
   9680                 config_mem = EGR_VLAN_XLATE_1_DOUBLEm;
   9681             }
   9682             break;
   9683         case EGR_PORTm:
   9684             if (SOC_IS_TRIDENT3X(unit)){
   9685                 config_mem = EGR_LPORT_PROFILEm;
   9686             }
   9687             break;
   9688 #endif
   9689         default:
   9690             config_mem = mem;
   9691             break;
   9692     }
   9693 
   9694     for (i = 0; i < count_ing; i++) {
   9695         if (config_mem == ing_flex_object_config[i].obj_mem) {
   9696             ing_flex_object_config[i] = object_config;
   9697             rv1 = BCM_E_NONE;
   9698             break;
   9699         }
   9700     }
   9701 
   9702     if (i >= count_ing) {
   9703         rv1 = BCM_E_NOT_FOUND;
   9704     }
   9705 
   9706     for (i = 0; i < count_egr; i++) {
   9707         if (config_mem == egr_flex_object_config[i].obj_mem) {
   9708             egr_flex_object_config[i] = object_config;
   9709             rv2 = BCM_E_NONE;
   9710             break;
   9711         }
   9712     }
   9713 
   9714     if (i >= count_egr) {
   9715         rv2 = BCM_E_NOT_FOUND;
   9716     }    
   9717 
   9718     if ((rv1 == BCM_E_NOT_FOUND) && (rv2 == BCM_E_NOT_FOUND)) {
   9719         return BCM_E_NOT_FOUND;
   9720     }
   9721     
   9722     return BCM_E_NONE;
   9723 }
   9724 
   9725 STATIC bcm_error_t _bcm_esw_stat_flex_object_update(
   9726                 int unit,
   9727                 SHR_BITDCL *object_bmp,
   9728                 int share,
   9729                 int flag)
   9730 {
   9731     int i, j, num = 0;
   9732     uint32 config_criteria, config_pool = 0;
   9733     soc_mem_t mem;
   9734     int count;
   9735     flex_object_default_t object_default[bcmStatObjectMaxValue];
   9736     flex_object_config_t object_config = {0};
   9737 
   9738     if (flag == CONFIG_ING_OBJECT) {
   9739         count = COUNTOF(ing_flex_object_default);
   9740         sal_memcpy(object_default, ing_flex_object_default, 
   9741                    count * sizeof(flex_object_default_t));
   9742     } else if (flag == CONFIG_EGR_OBJECT) {
   9743         count = COUNTOF(egr_flex_object_default);
   9744         sal_memcpy(object_default, egr_flex_object_default, 
   9745                    count * sizeof(flex_object_default_t));
   9746     } else {
   9747         return BCM_E_PARAM;
   9748     }
   9749 
   9750     for (i = 0; i < count; i++) {
   9751         if (SHR_BITGET(object_bmp, i)) {
   9752             num++;
   9753             /*set config pool for sharing*/
   9754             config_pool = object_default[i].pool_number;
   9755 
   9756             BCM_IF_ERROR_RETURN(
   9757                 _bcm_esw_stat_flex_object_config_get(unit,
   9758                                                      object_default[i].obj_mem, 
   9759                                                      &object_config));
   9760 
   9761             /*already set*/
   9762             if ((share && (object_config.share_criteria != 0)) ||
   9763                 (!share && (object_config.exclude_criteria != 0))) {
   9764                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   9765                           (BSL_META_U(unit,
   9766                                       "\"%s\" has already been set or "
   9767                                       "duplicated object in HW\n"), 
   9768                                       object_default[i].obj_desc));
   9769                 return BCM_E_INTERNAL;
   9770             }
   9771         }
   9772     }
   9773 
   9774     if (num <= 1) {
   9775         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   9776                   (BSL_META_U(unit,
   9777                               "Too little objects in the property string. "
   9778                               "Object count %d\n"), 
   9779                               num));
   9780         return BCM_E_INTERNAL;
   9781     }
   9782 
   9783     for (i = 0; i < count; i++) {
   9784         config_criteria = 0;
   9785         if (SHR_BITGET(object_bmp, i)) {
   9786             mem = object_default[i].obj_mem;
   9787             for (j = 0; j < count; j++) {
   9788                 if (j == i) {
   9789                     continue;
   9790                 }
   9791 
   9792                 if (SHR_BITGET(object_bmp, j) &&
   9793                     (mem != object_default[j].obj_mem)) {
   9794                     config_criteria |= object_default[j].pool_criteria;
   9795                 }
   9796             }
   9797 
   9798             BCM_IF_ERROR_RETURN(
   9799                 _bcm_esw_stat_flex_object_config_get(unit,
   9800                                                      mem, &object_config));
   9801 
   9802             if (share) {
   9803                 object_config.share_criteria |= config_criteria;
   9804                 object_config.config_pool = config_pool;
   9805             }
   9806             else {
   9807                 object_config.exclude_criteria |= config_criteria;
   9808             }
   9809 
   9810             BCM_IF_ERROR_RETURN(
   9811                 _bcm_esw_stat_flex_object_config_set(unit,
   9812                                                      mem, object_config));
   9813 
   9814         }
   9815     }
   9816 
   9817     return BCM_E_NONE;
   9818 }
   9819 
   9820 
   9821 STATIC bcm_error_t _bcm_esw_stat_flex_property_get(
   9822                 int unit,
   9823                 char *property_str,
   9824                 int flag)
   9825 {
   9826     char *sub_str = property_str;
   9827     int i, j, share, str_len, share_len, split_len;
   9828     int count;
   9829     flex_object_default_t flex_obj[bcmStatObjectMaxValue];
   9830     SHR_BITDCL *object_bmp = NULL, *object_share = NULL, *object_exclude = NULL;
   9831     int rv = BCM_E_NONE;
   9832 
   9833     if (flag == CONFIG_ING_OBJECT) {
   9834         count = COUNTOF(ing_flex_object_default);
   9835         sal_memcpy(flex_obj, ing_flex_object_default, 
   9836                    count * sizeof(flex_object_default_t));
   9837     } else if (flag == CONFIG_EGR_OBJECT) {
   9838         count = COUNTOF(egr_flex_object_default);
   9839         sal_memcpy(flex_obj, egr_flex_object_default, 
   9840                    count * sizeof(flex_object_default_t));
   9841     } else {
   9842         rv = BCM_E_PARAM;
   9843         goto cleanup;
   9844     }
   9845 
   9846     object_bmp = sal_alloc(SHR_BITALLOCSIZE(count), "object");
   9847     if (object_bmp == NULL) {
   9848         rv = BCM_E_MEMORY;
   9849         goto cleanup;
   9850     }
   9851     object_share = sal_alloc(SHR_BITALLOCSIZE(count), "object_share");
   9852     if (object_share == NULL) {
   9853         rv = BCM_E_MEMORY;
   9854         goto cleanup;
   9855     }    
   9856     object_exclude = sal_alloc(SHR_BITALLOCSIZE(count), "object_exclude");
   9857     if (object_exclude == NULL) {
   9858         rv = BCM_E_MEMORY;
   9859         goto cleanup;
   9860     }    
   9861     
   9862     sal_memset(object_share, 0, _SHR_BITDCLSIZE(count) * sizeof(SHR_BITDCL));
   9863     sal_memset(object_exclude, 0, _SHR_BITDCLSIZE(count) * sizeof(SHR_BITDCL));
   9864 
   9865     share_len = sal_strlen("share");
   9866     split_len = sal_strlen("split");
   9867 
   9868     /*initialize the object config*/
   9869     BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_object_config_init(unit, flag));
   9870 
   9871     /*share(vlan,vfi);split(vlan,ipmc)
   9872      *Specifies ingress objects sharing same pool or using exclusive pool.
   9873      *example:
   9874      *ing_share_flex_counter_pool=split(vlan,vfi) make vlan, vfi use exclusive pool.
   9875      *ing_share_flex_counter_pool=share(vlan,vfi) make vlan, vfi use same pool.
   9876      *an object can appear in both share case and split case.
   9877      *but in each case it can appear one time at most.
   9878      *use token between each groups and use comma between each objects.
   9879      *eg: ing_share_flex_counter_pool=split(A,B,C);share(C,D);
   9880      *some objects may use the same HW table, so only the first one will take effect.
   9881      *all valid object name: ',
   9882      *port, vlan, vlanxlate, vfi, l3intf, vrf, policy, mplsvclabel, mplsswitchlabel, mplsfrrlabel,
   9883      *l3host, trill, mimlookupid, l2gre, extpolicy, vxlan, vsan, fcoe, l3route, niv, ipmc.
   9884      */
   9885 
   9886     /*Parse the property syntex*/
   9887     while (*sub_str != '\0') {
   9888         if (*sub_str == ';' || *sub_str == ' ') {
   9889             sub_str ++;
   9890             continue;
   9891         }
   9892 
   9893         /*Initialization*/
   9894         sal_memset(object_bmp, 0, _SHR_BITDCLSIZE(count) * sizeof(SHR_BITDCL));
   9895         i = 0;
   9896 
   9897         if (!sal_memcmp(sub_str, "share", share_len)) {
   9898             share = TRUE;
   9899             sub_str += share_len;
   9900         }
   9901         else if (!sal_memcmp(sub_str, "split", split_len)) {
   9902             share = FALSE;
   9903             sub_str += split_len;
   9904         }
   9905         else {
   9906             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   9907                       (BSL_META_U(unit,
   9908                                   "ERROR! Missing share information. "
   9909                                   "Soc property \"%s\"\n"), 
   9910                                   property_str));
   9911             rv = BCM_E_FAIL;
   9912             goto cleanup;
   9913         }
   9914 
   9915         if (*sub_str == '(') {
   9916             sub_str++;
   9917         }
   9918         else {
   9919             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   9920                       (BSL_META_U(unit,
   9921                                   "ERROR! Illegal syntax. Soc property \"%s\"\n"), 
   9922                                   property_str)); 
   9923             rv = BCM_E_FAIL;
   9924             goto cleanup;
   9925         }
   9926 
   9927         while (i < count) {
   9928             str_len = sal_strlen(flex_obj[i].obj_desc);
   9929             if (!sal_memcmp(sub_str,
   9930                     flex_obj[i].obj_desc, str_len)) {
   9931                 SHR_BITSET(object_bmp, i);
   9932                 sub_str += str_len;
   9933 
   9934                 if (*sub_str == ')') {
   9935                     /*Check if there are duplicated objects*/
   9936                     for (j = 0; j < count; j++) {
   9937                         if (share) {
   9938                             if (SHR_BITGET(object_bmp, j) &&
   9939                                 SHR_BITGET(object_share, j)) {
   9940                                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   9941                                           (BSL_META_U(unit,
   9942                                                       "ERROR! Duplicated object. "
   9943                                                       "Soc property \"%s\"\n"), 
   9944                                                       property_str)); 
   9945                                  rv = BCM_E_FAIL;
   9946                                  goto cleanup;
   9947                             }
   9948                         }
   9949                         else {
   9950                             if (SHR_BITGET(object_bmp, j) &&
   9951                                 SHR_BITGET(object_exclude, j)) {
   9952                                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   9953                                           (BSL_META_U(unit,
   9954                                                       "ERROR! Duplicated object. "
   9955                                                       "Soc property \"%s\"\n"), 
   9956                                                       property_str)); 
   9957                                  rv = BCM_E_FAIL;
   9958                                  goto cleanup;
   9959                             }
   9960                         }
   9961                     }
   9962 
   9963                     /*Do the further process*/
   9964                     rv = _bcm_esw_stat_flex_object_update(unit, object_bmp, 
   9965                                                           share, flag);
   9966                     if (BCM_FAILURE(rv)) {
   9967                         goto cleanup;
   9968                     }
   9969 
   9970                     /*save the configuration stat*/
   9971                     if (share) {
   9972                         SHR_BITOR_RANGE
   9973                             (object_bmp, object_share, 0, count, object_share);
   9974                     }
   9975                     else {
   9976                         SHR_BITOR_RANGE
   9977                             (object_bmp, object_exclude, 0, count, object_exclude);
   9978                     }
   9979                     sub_str++;
   9980                     break;
   9981                 }
   9982                 else if (*sub_str == ',') {
   9983                     /*parse next object*/
   9984                     sub_str ++;
   9985                     i = 0;
   9986                     continue;
   9987                 }
   9988                 else {
   9989                     LOG_ERROR(BSL_LS_BCM_FLEXCTR,
   9990                               (BSL_META_U(unit,
   9991                                           "ERROR! Illegal string information. "
   9992                                           "Soc property \"%s\"\n"), 
   9993                                           property_str));
   9994                     rv = BCM_E_FAIL;
   9995                     goto cleanup;
   9996                 }
   9997             }
   9998             i++;
   9999         }
  10000 
  10001         if(i >= count) {
  10002             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10003                       (BSL_META_U(unit,
  10004                                   "ERROR! Object not found. Soc property \"%s\" \"%s\"\n"),
  10005                                   property_str, sub_str));
  10006             rv = BCM_E_NOT_FOUND;
  10007             goto cleanup;
  10008         }
  10009     }
  10010 
  10011 cleanup:
  10012     if (object_bmp != NULL) {
  10013         sal_free(object_bmp);
  10014     }
  10015     if (object_share != NULL) {
  10016         sal_free(object_share);
  10017     }     
  10018     if (object_exclude != NULL) {
  10019         sal_free(object_exclude);
  10020     }     
  10021     return rv;
  10022 }
  10023 
  10024 #ifdef BCM_TOMAHAWK_SUPPORT
  10025 /*
  10026  * Function:
  10027  *      is_legacy_ifp_color_mode_configured
  10028  * Description:
  10029  *      Determine whether a "legacy" IFP color based counter has
  10030  *      been configured. When configured, such a mode uses
  10031  *      0 selectors because counter offsets are provided directly
  10032  *      by the IFP_POLICY_TABLE. However the COUNT_ENABLEf in the
  10033  *      ING_FLEX_CTR_OFFSET_TABLE_* table will be set.
  10034  * Parameters:
  10035  *      unit                  - (IN) unit number
  10036  *      mode                  - (IN) offset mode
  10037  *      is_configured         - (OUT) set to TRUE/FALSE based on
  10038  *                              whether legacy color based counter
  10039  *                              mode is configured or not
  10040  * Return Value:
  10041  *      BCM_E_XXX
  10042  * Notes:
  10043  */
  10044 static bcm_error_t is_legacy_ifp_color_mode_configured(int unit, uint32 mode,
  10045                                                        uint8 *is_configured) {
  10046     uint32 index = 0, count_enable = 0, alloc_size = 0;
  10047     ing_flex_ctr_offset_table_0_entry_t *flex_ctr_offset_table_entry = NULL;
  10048 
  10049 
  10050     if (NULL == is_configured) {
  10051         return BCM_E_PARAM;
  10052     }
  10053     *is_configured = FALSE;
  10054     alloc_size =  BCM_STAT_FLEX_MAX_COUNTER *
  10055                   sizeof(ing_flex_ctr_offset_table_0_entry_t);
  10056     flex_ctr_offset_table_entry = soc_cm_salloc(unit, alloc_size,
  10057                                                 "flex_ctr_offset_table_entry");
  10058     if (NULL == flex_ctr_offset_table_entry) {
  10059         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10060                   (BSL_META_U(unit,
  10061                               "Memory Allocation failed:flex_ctr_offset_table_entry\n")));
  10062         return BCM_E_MEMORY;
  10063     }
  10064     sal_memset(flex_ctr_offset_table_entry, 0, alloc_size);
  10065     /* Since all pools have their corresponding counter offset tables
  10066      * programmed identically, we can examine pool 0 to see if any
  10067      * counters have their COUNT_ENABLEf set, for the given mode.
  10068      */
  10069     if (soc_mem_read_range(unit,
  10070                            _ctr_offset_table[bcmStatFlexDirectionIngress][0],
  10071                            MEM_BLOCK_ANY,
  10072                            (mode << BCM_STAT_FLEX_MAX_PKT_ATTR_SEL_KEY_SIZE),
  10073                            (mode << BCM_STAT_FLEX_MAX_PKT_ATTR_SEL_KEY_SIZE) +
  10074                            BCM_STAT_FLEX_MAX_COUNTER - 1,
  10075                            flex_ctr_offset_table_entry) != SOC_E_NONE) {
  10076         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10077                   (BSL_META_U(unit,
  10078                               "Memory Reading failed:flex_ctr_offset_table_entry \n")));
  10079         soc_cm_sfree(unit, flex_ctr_offset_table_entry);
  10080         return BCM_E_INTERNAL;
  10081     }
  10082 
  10083     for (index = 0; index < BCM_STAT_FLEX_MAX_COUNTER; index++) {
  10084          count_enable = 0;
  10085          soc_mem_field_get(unit,
  10086                            _ctr_offset_table[bcmStatFlexDirectionIngress][0],
  10087                            (uint32 *)&flex_ctr_offset_table_entry[index],
  10088                            COUNT_ENABLEf, &count_enable);
  10089          if (count_enable) {
  10090              soc_cm_sfree(unit, flex_ctr_offset_table_entry);
  10091              flex_ctr_offset_table_entry = NULL;
  10092              *is_configured = TRUE;
  10093              break;
  10094          }
  10095     }
  10096     if (NULL != flex_ctr_offset_table_entry) {
  10097         soc_cm_sfree(unit, flex_ctr_offset_table_entry);
  10098     }
  10099     return BCM_E_NONE;
  10100 }
  10101 
  10102 #if defined (INCLUDE_FLOWTRACKER)
  10103 int _bcm_esw_stat_pool_reserved(int unit,
  10104     bcm_stat_flex_direction_t direction, int pool_id) {
  10105     if((0 == _bcm_stat_ing_pools_rsvd) ||
  10106         (direction != bcmStatFlexDirectionIngress) ) {
  10107         return 0;
  10108     }
  10109     if ((1<<pool_id) & _bcm_stat_ing_pools_rsvd ){
  10110         return 0x1;
  10111     }
  10112 
  10113     return 0;
  10114 }
  10115 
  10116 int _bcm_esw_stat_mod_reserved(
  10117     int unit,
  10118     int mode_id) {
  10119 
  10120     return (_bcm_stat_mode_rsvd == mode_id);
  10121 }
  10122 
  10123 uint32 _bcm_esw_stat_reserved_pools_get(int unit, uint32 num) {
  10124     uint32 reserved_pools = 0;
  10125     bcm_stat_flex_direction_t dir = bcmStatFlexDirectionIngress;
  10126     uint8 pool = 0;
  10127     uint32 entries = 0;
  10128     uint32 smaller_pool_size = 0;
  10129     uint32 smaller_pool_def = 0;
  10130     uint32 index0_skip_num_entry = 1;
  10131 
  10132     /* index0 need not be skipped for maverick2 */
  10133     if (soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
  10134         index0_skip_num_entry = 0;
  10135     }
  10136 
  10137     if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
  10138          soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
  10139          soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
  10140         if(SOC_IS_TOMAHAWKX(unit)) {
  10141             smaller_pool_size = 512;
  10142             smaller_pool_def = FLEX_COUNTER_DEFAULT_EM_POLICY_TABLE_POOL_NUMBER;
  10143         } else if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) {
  10144             smaller_pool_size = 1536;
  10145             smaller_pool_def = FLEX_COUNTER_DEFAULT_EM_POLICY_TABLE_POOL_NUMBER;
  10146         } else {
  10147             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10148                         (BSL_META_U(unit,
  10149                             "Double check pool size\n")));
  10150         }
  10151 
  10152         for(pool = 0; pool < BCM_STAT_TH_FLEX_COUNTER_MAX_POOL; pool++) {
  10153             /* index 0 can not trigger counter update */
  10154             entries =
  10155                 soc_mem_index_count(unit, _ctr_counter_table[dir][pool]) - 
  10156                                                      index0_skip_num_entry;
  10157             if( num > entries) {
  10158                 reserved_pools |= (1<<pool);
  10159                 num = num - entries;
  10160             } else {
  10161                 if (num > 0x0) {
  10162                     if( num <= (smaller_pool_size - 1)) {
  10163                         reserved_pools |= (1<<smaller_pool_def);
  10164                     } else {
  10165                         reserved_pools |= (1<<pool);
  10166                     }
  10167                 }
  10168                 break;
  10169             }
  10170         }
  10171     }
  10172 
  10173     return reserved_pools;
  10174 }
  10175 
  10176 uint32 _bcm_esw_stat_reserved_num_get(int unit) {
  10177     uint32 num_counters = 0;
  10178 #if defined(BCM_MAVERICK2_SUPPORT)
  10179     uint32 num_counters_per_flow = 0;
  10180 #endif
  10181     uint8 ft_enable = 0;
  10182     uint32 pipe_flow_limit;
  10183     uint8 pipe = 0;
  10184     char max_flows_pipe_soc_prop_str[50];
  10185 
  10186     ft_enable = soc_property_get(unit, spn_FLOWTRACKER_ENABLE, 0);
  10187     if(ft_enable) {
  10188 
  10189         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
  10190             sal_snprintf(max_flows_pipe_soc_prop_str, 50, "%s%d",
  10191                          "flowtracker_max_flows_pipe", pipe);
  10192             pipe_flow_limit = soc_property_get(unit, max_flows_pipe_soc_prop_str, 0);
  10193             if (pipe_flow_limit > num_counters) {
  10194                 /* Counters have to be reserved equally among all the pools, set
  10195                  * num_counters to the pipe having the maximum number of flows.
  10196                  */
  10197                 num_counters = pipe_flow_limit;
  10198             }
  10199         }
  10200 
  10201         if (num_counters == 0) {
  10202             /* Per pipe limit is not configured, check for global and divide
  10203              * equally
  10204              */
  10205             num_counters = soc_property_get(unit,
  10206                                             spn_FLOWTRACKER_MAX_FLOWS,
  10207                                             BCM_INT_FT_DEF_MAX_FLOWS) /
  10208                                             NUM_PIPE(unit);
  10209         }
  10210     }
  10211 
  10212 #if defined(BCM_MAVERICK2_SUPPORT)
  10213     if (soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
  10214         num_counters_per_flow = soc_property_get(unit,
  10215                                                  spn_FLOWTRACKER_MAX_COUNTERS_PER_FLOW,
  10216                                                  BCM_INT_FT_DEF_MAX_COUNTERS_PER_FLOW);
  10217         num_counters = num_counters * num_counters_per_flow;
  10218     }
  10219 #endif
  10220     return num_counters;
  10221 }
  10222 
  10223 static bcm_error_t _bcm_esw_stat_flex_flowtracker_cfg(
  10224     int unit, int cleanup) {
  10225     bcm_error_t rv = BCM_E_NONE;
  10226     int idx = 0;
  10227     bcm_stat_flex_direction_t dir = bcmStatFlexDirectionIngress;
  10228     soc_reg_t reg = INVALIDr;
  10229     uint32 reg_val = 0;
  10230     int pipe = 0;
  10231     static const soc_reg_t ing_evict_regs[] = {
  10232         ING_FLEX_CTR_EVICTION_CONTROL_POOL_0r,
  10233         ING_FLEX_CTR_EVICTION_CONTROL_POOL_1r,
  10234         ING_FLEX_CTR_EVICTION_CONTROL_POOL_2r,
  10235         ING_FLEX_CTR_EVICTION_CONTROL_POOL_3r,
  10236         ING_FLEX_CTR_EVICTION_CONTROL_POOL_4r,
  10237         ING_FLEX_CTR_EVICTION_CONTROL_POOL_5r,
  10238         ING_FLEX_CTR_EVICTION_CONTROL_POOL_6r,
  10239         ING_FLEX_CTR_EVICTION_CONTROL_POOL_7r,
  10240         ING_FLEX_CTR_EVICTION_CONTROL_POOL_8r,
  10241         ING_FLEX_CTR_EVICTION_CONTROL_POOL_9r,
  10242         ING_FLEX_CTR_EVICTION_CONTROL_POOL_10r,
  10243         ING_FLEX_CTR_EVICTION_CONTROL_POOL_11r,
  10244         ING_FLEX_CTR_EVICTION_CONTROL_POOL_12r,
  10245         ING_FLEX_CTR_EVICTION_CONTROL_POOL_13r,
  10246         ING_FLEX_CTR_EVICTION_CONTROL_POOL_14r,
  10247         ING_FLEX_CTR_EVICTION_CONTROL_POOL_15r,
  10248         ING_FLEX_CTR_EVICTION_CONTROL_POOL_16r,
  10249         ING_FLEX_CTR_EVICTION_CONTROL_POOL_17r,
  10250         ING_FLEX_CTR_EVICTION_CONTROL_POOL_18r,
  10251         ING_FLEX_CTR_EVICTION_CONTROL_POOL_19r
  10252         };
  10253     /* enable pool, disable eviction, enable clear_on_read */
  10254     uint32 clr_on_read = 1;
  10255     uint32 pool_enable = 1;
  10256     uint32 eviction_mode = 0;
  10257 
  10258     if (cleanup) {
  10259         pool_enable = 0;
  10260         if(soc_feature(unit, soc_feature_counter_eviction)
  10261             && soc_property_get(unit, "ctr_evict_enable", 1)) {
  10262             clr_on_read = 1;
  10263             if (soc_feature(unit, soc_feature_th_a0_sw_war)) {
  10264                 eviction_mode = 2;
  10265             } else {
  10266                 eviction_mode = 1;
  10267             }
  10268         } else {
  10269             clr_on_read = 0;
  10270             eviction_mode = 0;
  10271         }
  10272     }
  10273 
  10274     if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
  10275          soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
  10276          soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
  10277         for(idx = 0; idx < BCM_STAT_TH_FLEX_COUNTER_MAX_POOL; idx++) {
  10278             if (_bcm_esw_stat_pool_reserved(unit, dir, idx)) {
  10279                 reg = _pool_ctr_register[dir][idx];
  10280 
  10281                 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY,
  10282                     0, &reg_val));
  10283                 soc_reg_field_set(unit, reg, &reg_val,
  10284                     COUNTER_POOL_ENABLEf, pool_enable);
  10285                 soc_reg_field_set(unit, reg, &reg_val, CLR_ON_READf, clr_on_read);
  10286                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY,
  10287                     0, reg_val));
  10288                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
  10289                     reg = SOC_REG_UNIQUE_ACC(unit, ing_evict_regs[idx])[pipe];
  10290                     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY,
  10291                         0, &reg_val));
  10292                     soc_reg_field_set(unit, reg, &reg_val, MODEf, eviction_mode);
  10293                     SOC_IF_ERROR_RETURN
  10294                         (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, reg_val));
  10295                 }
  10296             }
  10297         }
  10298     }
  10299 
  10300     return rv;
  10301 }
  10302 
  10303 static bcm_error_t _bcm_esw_stat_flex_flowtracker_init(int unit) {
  10304     bcm_error_t rv = BCM_E_NONE;
  10305 
  10306     if (soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
  10307         soc_feature(unit, soc_feature_uc_flowtracker_export)) {
  10308         if (_bcm_stat_ing_pools_rsvd) {
  10309             /* create default mode */
  10310             bcm_stat_group_mode_attr_selector_t attr_selectors;
  10311             sal_memset(&attr_selectors, 0x0, sizeof(attr_selectors));
  10312 
  10313             attr_selectors.attr = bcmStatGroupModeAttrPktType;
  10314             attr_selectors.attr_value = BCM_STAT_GROUP_MODE_ATTR_ALL_VALUES;
  10315             attr_selectors.counter_offset = 0;
  10316 
  10317             rv = _bcm_esw_stat_group_mode_id_create(unit,
  10318                 BCM_STAT_GROUP_MODE_INGRESS, 0x1, 0x1, &attr_selectors,
  10319                 &_bcm_stat_mode_rsvd);
  10320             if((BCM_E_NONE != rv) && (BCM_E_EXISTS != rv)) {
  10321                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10322                     (BSL_META_U(unit,
  10323                     "Failed to reserve mode for flowtracker: %s\n"), bcm_errmsg(rv)));
  10324                 _bcm_stat_mode_rsvd = -1;
  10325             } else {
  10326                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  10327                     (BSL_META_U(unit,
  10328                     "Mode(%d) reserved for flowtracker\n"),
  10329                         _bcm_stat_mode_rsvd));
  10330             }
  10331 
  10332             _bcm_esw_stat_flex_flowtracker_cfg(unit, 0);
  10333         }
  10334     } else if (soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
  10335             _bcm_esw_stat_flex_flowtracker_cfg(unit, 0); 
  10336     }
  10337 
  10338     return rv;
  10339 }
  10340 
  10341 static bcm_error_t _bcm_esw_stat_flex_flowtracker_cleanup(int unit) {
  10342     bcm_error_t rv = BCM_E_NONE;
  10343 
  10344     if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
  10345          soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
  10346          soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
  10347 
  10348         if (_bcm_stat_mode_rsvd != -1) {
  10349             uint32 tmp_mode_id = _bcm_stat_mode_rsvd;
  10350 
  10351             _bcm_stat_mode_rsvd = -1;
  10352             _bcm_esw_stat_group_mode_id_destroy(unit, tmp_mode_id);
  10353         }
  10354 
  10355         _bcm_esw_stat_flex_flowtracker_cfg(unit, 0x1);
  10356 
  10357         _bcm_stat_num_rsvd = 0;
  10358         _bcm_stat_ing_pools_rsvd = 0;
  10359     }
  10360     return rv;
  10361 }
  10362 
  10363 /*
  10364  * Function:
  10365  *	_bcm_stat_flex_flowtracker_counter_info_get
  10366  * Description:
  10367  *	Get counter resource reserved for flowtracker
  10368  * Parameters:
  10369  *
  10370  *  unit : (IN)  UNIT number
  10371  *  info : (OUT)  Returns pool id and counter index range
  10372  *
  10373  * Returns:
  10374  *	BCM_E_*
  10375  */
  10376 bcm_error_t _bcm_stat_flex_flowtracker_counter_info_get(int unit,
  10377                             bcm_stat_flex_flowtracker_counter_info_t *info){
  10378     int idx = 0;
  10379     bcm_stat_flex_direction_t dir = bcmStatFlexDirectionIngress;
  10380     uint8 pool_num = 0;
  10381     sal_memset(info, 0, sizeof(bcm_stat_flex_flowtracker_counter_info_t));
  10382     if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
  10383          soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
  10384          soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
  10385         if(_bcm_stat_ing_pools_rsvd && ((_bcm_stat_mode_rsvd != -1) || 
  10386                         soc_feature(unit, soc_feature_mv2_style_flowtracker))) {
  10387             info->offset_mode = _bcm_stat_mode_rsvd;
  10388             for(idx = 0; idx < BCM_STAT_TH_FLEX_COUNTER_MAX_POOL; idx++) {
  10389                 if (_bcm_esw_stat_pool_reserved(unit, dir, idx)) {
  10390                     info->pool_info[pool_num].pool_id = idx;
  10391                     /* index 0 can not trigger counter update */
  10392                     info->pool_info[pool_num].start_idx = 0x1;
  10393                     info->pool_info[pool_num].end_idx =
  10394                         soc_mem_index_max(unit, _ctr_counter_table[dir][idx]);
  10395                     pool_num++;
  10396                 }
  10397             }
  10398         }
  10399     }
  10400     info->pool_num = pool_num;
  10401 
  10402     return BCM_E_NONE;
  10403 }
  10404 #endif /* INCLUDE_FLOWTRACKER */
  10405 #endif
  10406 
  10407 /*
  10408  * Function:
  10409  *      _bcm_esw_stat_flex_init
  10410  * Description:
  10411  *      Initialize and allocate all required flex resources
  10412  * Parameters:
  10413  *      unit                  - (IN) unit number
  10414  * Return Value:
  10415  *      BCM_E_XXX
  10416  * Notes:
  10417  */
  10418 bcm_error_t _bcm_esw_stat_flex_init(int unit)
  10419 {
  10420     bcm_stat_flex_direction_t    direction=bcmStatFlexDirectionIngress;
  10421     /* sal_usecs_t stime; */
  10422     uint32    mode=0;
  10423 
  10424     uint32    selector_count=0;
  10425     uint32    index=0;
  10426     uint32    selector_x_en_field_value[8]={0};
  10427     uint32    selector_for_bit_x_field_value[8]={0};
  10428     uint32    IsAnyModeConfigured=0;
  10429     uint32    pool_id=0;
  10430 
  10431     uint32    num_pools[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  10432     uint32    size_pool[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  10433     uint32    alloc_size=0;
  10434     uint64    selector_key_value;
  10435     int       num_ctr;
  10436 #ifdef BCM_WARM_BOOT_SUPPORT
  10437     int       stable_size=0;
  10438     int       stable_used_size=0;
  10439 #endif
  10440     bcm_error_t rv=BCM_E_NONE;
  10441     int num_pipes = 1, pipe_num;
  10442 #ifdef BCM_WARM_BOOT_SUPPORT
  10443     uint32     per_pipe_mode_ifp = 0, per_pipe_mode_vfp = 0;
  10444 #endif
  10445 
  10446 #if defined(BCM_TRIDENT2_SUPPORT)
  10447     int       buffer_id = 0;
  10448     bcm_stat_flex_mode_t offset_mode;
  10449 #endif /* BCM_TRIDENT2_SUPPORT*/
  10450   char *config_str;
  10451     uint32 pool_group_id;
  10452 
  10453 #ifdef BCM_WARM_BOOT_SUPPORT
  10454     int used_pool = 0;
  10455     uint32     per_pipe_mode_efp = 0;
  10456     int compression_wb_size = 0;
  10457     int additional_scache_size = 0;
  10458 #endif
  10459 
  10460 #if defined(BCM_KATANA2_SUPPORT)
  10461     int combination_attr_matrix_size = 0;
  10462 #endif
  10463 
  10464     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  10465               (BSL_META_U(unit,
  10466                           "_bcm_esw_stat_flex_init \n")));
  10467 
  10468     _bcm_esw_stat_flex_init_pkt_attr_bits(unit);
  10469     _bcm_esw_stat_flex_init_pkt_res_fields(unit);
  10470 
  10471     _bcm_esw_stat_flex_cleanup(unit);
  10472 
  10473     COMPILER_64_ZERO(selector_key_value);
  10474 
  10475     if (soc_feature(unit, soc_feature_flex_stat_compression_share)) {
  10476         if (_bcm_esw_stat_flex_compressed_shared_attr_map_init(unit,TRUE) !=
  10477                 BCM_E_NONE)
  10478             return BCM_E_MEMORY;
  10479     }
  10480 
  10481 #if defined (BCM_TOMAHAWK_SUPPORT) && defined (INCLUDE_FLOWTRACKER)
  10482     if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
  10483          soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
  10484          soc_feature(unit, soc_feature_mv2_style_flowtracker)){
  10485         (void)_bcm_esw_stat_flex_flowtracker_cleanup(unit);
  10486 
  10487         _bcm_stat_num_rsvd = _bcm_esw_stat_reserved_num_get(unit);
  10488         _bcm_stat_ing_pools_rsvd = _bcm_esw_stat_reserved_pools_get(unit,
  10489                                                                     _bcm_stat_num_rsvd);
  10490     }
  10491 #endif
  10492 
  10493 #if defined(BCM_TOMAHAWK_SUPPORT)
  10494     /*IFP supports dynamic switching of modes.
  10495       Always allocate memory for 4 pipes. 
  10496      */
  10497     if (soc_feature(unit,soc_feature_stat_multi_pipe_support)) {
  10498         num_pipes = SOC_INFO(unit).num_pipe;
  10499     }
  10500 
  10501 #endif
  10502     num_pools[bcmStatFlexDirectionIngress]= SOC_INFO(unit).
  10503                                             num_flex_ingress_pools;
  10504     num_pools[bcmStatFlexDirectionEgress] = SOC_INFO(unit).
  10505                                             num_flex_egress_pools;
  10506     size_pool[bcmStatFlexDirectionIngress]= SOC_INFO(unit).
  10507                                             size_flex_ingress_pool;
  10508     size_pool[bcmStatFlexDirectionEgress] = SOC_INFO(unit).
  10509                                             size_flex_egress_pool;
  10510 
  10511     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  10512               (BSL_META_U(unit,
  10513                           "INFO: ingress_pools:%d num_flex_egress_pools:%di "
  10514                           "size_flex_ingress_pool:%d size_flex_egress_pool:%d"
  10515                           "MAX_DIRECTION %d MAX_MODE %d MAX_POOL %d\n"),
  10516                num_pools[bcmStatFlexDirectionIngress],
  10517                num_pools[bcmStatFlexDirectionEgress],
  10518                size_pool[bcmStatFlexDirectionIngress],
  10519                size_pool[bcmStatFlexDirectionEgress],
  10520                BCM_STAT_FLEX_COUNTER_MAX_DIRECTION,
  10521                BCM_STAT_FLEX_COUNTER_MAX_MODE,
  10522                BCM_STAT_FLEX_COUNTER_MAX_POOL));
  10523     if ((num_pools[bcmStatFlexDirectionIngress] == 0) ||
  10524         (num_pools[bcmStatFlexDirectionEgress] == 0)) {
  10525          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10526                    (BSL_META_U(unit,
  10527                                "INFO:Number of CounterPools missing.PleaseDefine it\n")));
  10528          return BCM_E_INTERNAL;
  10529     }
  10530     if ((num_pools[bcmStatFlexDirectionIngress] >
  10531                           ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit))?
  10532                                                     BCM_STAT_TH_FLEX_COUNTER_MAX_POOL:
  10533                                                     BCM_STAT_FLEX_COUNTER_MAX_POOL)) ||
  10534         (num_pools[bcmStatFlexDirectionEgress] >
  10535          BCM_STAT_FLEX_COUNTER_MAX_POOL)) {
  10536          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10537                    (BSL_META_U(unit,
  10538                                "INFO: Number of pools exceeding its max value %d \n"),
  10539                     BCM_STAT_FLEX_COUNTER_MAX_POOL));
  10540          return BCM_E_INTERNAL;
  10541     }
  10542     if (flex_stat_mutex[unit] == NULL) {
  10543         flex_stat_mutex[unit]= sal_mutex_create("Advanced flex counter mutex");
  10544         if (flex_stat_mutex[unit] == NULL) {
  10545             _bcm_esw_stat_flex_cleanup(unit);
  10546             return BCM_E_MEMORY;
  10547         }
  10548     }
  10549     flex_ingress_modes[unit] = (bcm_stat_flex_ingress_mode_t *) sal_alloc(
  10550                                 sizeof(bcm_stat_flex_ingress_mode_t) *
  10551                                 BCM_STAT_FLEX_COUNTER_MAX_MODE,
  10552                                 "flex_ingress_modes");
  10553     if (flex_ingress_modes[unit] == NULL) {
  10554         _bcm_esw_stat_flex_cleanup(unit);
  10555         return BCM_E_MEMORY;
  10556     }
  10557     flex_custom_ingress_modes[unit] = (bcm_stat_flex_custom_ingress_mode_t *) sal_alloc(
  10558                                 sizeof(bcm_stat_flex_custom_ingress_mode_t) *
  10559                                 BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE,
  10560                                 "flex_ingress_modes");
  10561     if (flex_custom_ingress_modes[unit] == NULL) {
  10562         _bcm_esw_stat_flex_cleanup(unit);
  10563         return BCM_E_MEMORY;
  10564     }
  10565     flex_egress_modes[unit] = (bcm_stat_flex_egress_mode_t *) sal_alloc(
  10566                                 sizeof(bcm_stat_flex_egress_mode_t) *
  10567                                 BCM_STAT_FLEX_COUNTER_MAX_MODE,
  10568                                 "flex_egress_modes");
  10569     if (flex_egress_modes[unit] == NULL) {
  10570         _bcm_esw_stat_flex_cleanup(unit);
  10571         return BCM_E_MEMORY;
  10572     }
  10573 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  10574     flex_custom_egress_modes[unit] =
  10575         (bcm_stat_flex_custom_egress_mode_t *) sal_alloc(
  10576             sizeof(bcm_stat_flex_custom_egress_mode_t) *
  10577             BCM_CUSTOM_EGRESS_MODE_MAX_COUNT,
  10578             "flex_custom_egress_modes");
  10579     if (flex_custom_egress_modes[unit] == NULL) {
  10580         _bcm_esw_stat_flex_cleanup(unit);
  10581         return BCM_E_MEMORY;
  10582     }
  10583 #endif
  10584 
  10585 #if defined(BCM_TOMAHAWK_SUPPORT)
  10586     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id)) {
  10587         stat_ctr_map_init(unit);
  10588     }
  10589 #endif
  10590 #ifdef BCM_TRIDENT3_SUPPORT
  10591    if (SOC_IS_TRIDENT3X(unit)) {
  10592        soc_mem_t mem = FLEX_CTR_ACTION_MASK_PROFILEm;
  10593        soc_field_t field = POOL_ENABLEf;
  10594        if (SOC_MEM_FIELD_VALID(unit, mem, field )){
  10595            uint32 value =  (1 << soc_mem_field_length(unit, mem, field)) - 1;
  10596            (void)soc_mem_fields32_modify(unit, mem, 0, 1, &field, &value);
  10597        }
  10598    }
  10599 #endif
  10600 
  10601     /* Initialize Ingress Mode structures*/
  10602     for (mode = 0; mode < BCM_STAT_FLEX_COUNTER_MAX_MODE; mode++) {
  10603          sal_memset(&flex_ingress_modes[unit][mode],0,
  10604                     sizeof(bcm_stat_flex_ingress_mode_t));
  10605     }
  10606     /* Initialize Custom Ingress Mode structures*/
  10607     for (mode = 0; mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE-BCM_CUSTOM_INGRESS_MODE_START; mode++) {
  10608          sal_memset(&flex_custom_ingress_modes[unit][mode],0,
  10609                     sizeof(bcm_stat_flex_custom_ingress_mode_t));
  10610          flex_custom_ingress_modes[unit][mode].AllocPool = -1;
  10611     }
  10612     /* Initialize Egress Mode structures*/
  10613     for (mode = 0; mode < BCM_STAT_FLEX_COUNTER_MAX_MODE; mode++) {
  10614          sal_memset(&flex_egress_modes[unit][mode],0,
  10615                     sizeof(bcm_stat_flex_egress_mode_t));
  10616     }
  10617 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  10618     /* Initialize Custom Egress Mode structures*/
  10619     for (mode = 0; mode < BCM_CUSTOM_EGRESS_MODE_MAX_COUNT; mode++) {
  10620          sal_memset(&flex_custom_egress_modes[unit][mode],0,
  10621                     sizeof(bcm_stat_flex_custom_egress_mode_t));
  10622          flex_custom_egress_modes[unit][mode].AllocPool = -1;
  10623     }
  10624 #endif
  10625     for (direction = bcmStatFlexDirectionIngress;
  10626          direction < bcmStatFlexDirectionCount;
  10627          direction++) {
  10628          alloc_size = sizeof(ing_flex_ctr_counter_table_0_entry_t) *
  10629                              size_pool[direction];
  10630 #if defined(BCM_TRIDENT2_SUPPORT)
  10631          if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
  10632              if (flex_temp_counter_dual[unit][direction] != NULL){
  10633                  LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10634                           (BSL_META_U(unit,
  10635                                       "WARN:Freeing flex_temp_counter AllocatedMemory\n")));
  10636                  soc_cm_sfree(unit,flex_temp_counter_dual[unit][direction]);
  10637              }
  10638              flex_temp_counter_dual[unit][direction] = soc_cm_salloc(
  10639                                                 unit,
  10640                                                 alloc_size,
  10641                                                 "Advanced FlexTemp packet counter");
  10642              if (flex_temp_counter_dual[unit][direction] == NULL) {
  10643                  LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10644                           (BSL_META_U(unit,
  10645                                       "Advanced Flex current PacketCounterAllocationFail"
  10646                                       "for unit:%d, dir:%d pool:%d\n"),
  10647                            unit,direction,pool_id));
  10648                  _bcm_esw_stat_flex_cleanup(unit);
  10649                  return BCM_E_MEMORY;
  10650              }
  10651              sal_memset(flex_temp_counter_dual[unit][direction], 0, alloc_size);
  10652          }
  10653 #endif /* BCM_TRIDENT2_SUPPORT*/
  10654 
  10655          if (flex_temp_counter[unit][direction] != NULL){
  10656              LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10657                       (BSL_META_U(unit,
  10658                                   "WARN:Freeing flex_temp_counter AllocatedMemory\n")));
  10659              soc_cm_sfree(unit,flex_temp_counter[unit][direction]);
  10660          }
  10661          flex_temp_counter[unit][direction] = soc_cm_salloc(
  10662                                             unit,
  10663                                             alloc_size,
  10664                                             "Advanced FlexTemp packet counter");
  10665          if (flex_temp_counter[unit][direction] == NULL) {
  10666              LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10667                       (BSL_META_U(unit,
  10668                                   "Advanced Flex current PacketCounterAllocationFail"
  10669                                   "for unit:%d, dir:%d pool:%d\n"),
  10670                        unit,direction,pool_id));
  10671              _bcm_esw_stat_flex_cleanup(unit);
  10672              return BCM_E_MEMORY;
  10673          }
  10674          sal_memset(flex_temp_counter[unit][direction], 0, alloc_size);
  10675          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  10676                    (BSL_META_U(unit,
  10677                                "Temp counter size:%d \n"),
  10678                     alloc_size));
  10679          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  10680                    (BSL_META_U(unit,
  10681                                "Byte counter size:%d \n"),
  10682                     (int)sizeof(uint64)*size_pool[direction]));
  10683          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  10684                    (BSL_META_U(unit,
  10685                                "Packet counter size:%d\n"),
  10686                     (int)sizeof(uint32)*size_pool[direction]));
  10687          /* Initialize the Flex Counter Group Database */
  10688          if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
  10689              if (direction == bcmStatFlexDirectionIngress) {
  10690                  for (pool_group_id=0;
  10691                       pool_group_id < _bcm_esw_get_max_pool_groups(unit);
  10692                       pool_group_id++) {
  10693                      if (BCM_E_PARAM == 
  10694                              _bcm_esw_stat_flex_oam_enable_ingress_group(
  10695                                                                 unit,
  10696                                                                 pool_group_id,
  10697                                                                 0)) {
  10698                           continue;
  10699                       }
  10700                      for(pipe_num = 0; pipe_num < num_pipes; ++pipe_num) {
  10701                          flex_pool_group[unit][pipe_num][pool_group_id].group_type =
  10702                                        BCM_FLEX_POOL_GROUP_USED_BY_NONE;
  10703                          flex_pool_group[unit][pipe_num][pool_group_id].free_pools  =
  10704                                        BCM_STAT_FLEX_COUNTER_POOLS_PER_GROUP;
  10705                          flex_pool_group[unit][pipe_num][pool_group_id].base_pool =
  10706                               pool_group_id * BCM_STAT_FLEX_COUNTER_POOLS_PER_GROUP;
  10707                      }
  10708                  }
  10709              }
  10710          }
  10711          for (pool_id = 0; pool_id < num_pools[direction]; pool_id++) {
  10712              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  10713                        (BSL_META_U(unit,
  10714                                    ".")));
  10715              /* Disable all counter pools */
  10716              _bcm_esw_stat_flex_enable_pool(
  10717                      unit,
  10718                      direction,
  10719                      _pool_ctr_register[direction][pool_id],
  10720                  0);
  10721 if (!SOC_IS_MONTEREY(unit)) {
  10722              for(pipe_num = 0; pipe_num < num_pipes; ++pipe_num) {
  10723                  if ((pipe_num > 0) &&
  10724                     ((direction != bcmStatFlexDirectionIngress)
  10725 #if defined(BCM_TRIDENT3_SUPPORT)
  10726                     && (!SOC_IS_TRIDENT3X(unit))
  10727 #endif
  10728                     )) {
  10729                     break;
  10730                  }
  10731                   /* Destroy if any exist */
  10732                   shr_aidxres_list_destroy(flex_aidxres_list_handle[unit]
  10733                                            [direction][pipe_num][pool_id]);
  10734 
  10735                   /* use the least one of the configured pool size and mem table */
  10736                   num_ctr = soc_mem_index_count(unit,
  10737                                    _ctr_counter_table[direction][pool_id]);
  10738                   if (size_pool[direction] < num_ctr) {
  10739                       num_ctr = size_pool[direction];
  10740                   }
  10741 
  10742                   /* Create it */
  10743                   if (shr_aidxres_list_create(
  10744                          &flex_aidxres_list_handle[unit][direction][pipe_num][pool_id],
  10745                          0,num_ctr-1,
  10746                          0,num_ctr-1,
  10747                          8, /* Max 256 counters */
  10748                          "flex-counter") != BCM_E_NONE) {
  10749                       LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10750                                 (BSL_META_U(unit,
  10751                                             "Unrecoverable error. "
  10752                                             "Couldn'tCreate AllignedList:FlexCounter\n")));
  10753                       _bcm_esw_stat_flex_cleanup(unit);
  10754                       return BCM_E_INTERNAL;
  10755                   }
  10756                   /* Reserver first two counters entries i.e. not to be used. */
  10757                   /* Flexible counter updates only if counter_base_index is != 0 */
  10758                   /* Refer: Arch-spec section 4.1 */
  10759                   shr_aidxres_list_reserve_block(
  10760                               flex_aidxres_list_handle[unit][direction][pipe_num][pool_id],
  10761                               0,
  10762                               (1 << 1));
  10763                   flex_pool_stat[unit][direction][pipe_num][pool_id].used_by_tables = 0;
  10764                   flex_pool_stat[unit][direction][pipe_num][pool_id].used_entries = 0;
  10765                   flex_pool_stat[unit][direction][pipe_num][pool_id].attached_entries = 0;
  10766                   SHR_BITCLR_RANGE(flex_pool_stat[unit][direction][pipe_num][pool_id].used_by_objects,
  10767                                    0, bcmStatObjectMaxValue);
  10768 #if defined(BCM_TOMAHAWK_SUPPORT)
  10769                   if (SOC_IS_TOMAHAWKX(unit) ||SOC_IS_TRIDENT3X(unit)) {
  10770                       /* Ingress pools 12 - 20 are reserved for use by IFP only.
  10771                        * Update pool attributes to reflect the same.
  10772                        */
  10773                       if (bcmStatFlexDirectionIngress == direction &&
  10774                           (pool_id >= BCM_FLEX_STAT_TH_RSVD_IFP_POOL_MIN &&
  10775                            pool_id <= BCM_FLEX_STAT_TH_RSVD_IFP_POOL_MAX)) {
  10776                           flex_pool_stat[unit][direction][pipe_num][pool_id].used_by_tables =
  10777                           FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE;
  10778                           SHR_BITSET(flex_pool_stat[unit][direction][pipe_num][pool_id].used_by_objects,
  10779                                       bcmStatObjectIngFieldStageIngress);
  10780                       }
  10781                       /* Allocate memory for the ifp color map database
  10782                        * for the unit being initialized. This color map
  10783                        * database is referred to at the time of attaching
  10784                        * flex counters to IFP_POLICY_TABLE, in order to
  10785                        * determine how to program the color based offset
  10786                        * fields
  10787                        */
  10788                       if (bcmStatFlexDirectionIngress == direction) {
  10789                           if (ifp_color_map[unit][pipe_num][pool_id] != NULL) {
  10790                               LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10791                                        (BSL_META_U(unit,
  10792                                                    "WARN:Freeing Allocated IFP"
  10793                                                    " color map database\n")));
  10794                               soc_cm_sfree(unit, ifp_color_map[unit][pipe_num][pool_id]);
  10795                           }
  10796                           ifp_color_map[unit][pipe_num][pool_id] =
  10797                                soc_cm_salloc(unit, sizeof(uint8) * num_ctr,
  10798                                              "IFP Color map database");
  10799                           if (NULL == ifp_color_map[unit][pipe_num][pool_id]) {
  10800                               LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10801                                         (BSL_META_U(unit,
  10802                                                     "Allocation failed for IFP"
  10803                                                     " color map database\n")));
  10804                               _bcm_esw_stat_flex_cleanup(unit);
  10805                               return BCM_E_MEMORY;
  10806                           }
  10807                           sal_memset(ifp_color_map[unit][pipe_num][pool_id], 0,
  10808                                      sizeof(uint8) * num_ctr);
  10809                       }
  10810                   }
  10811 #endif
  10812                   if (flex_byte_counter[unit][direction][pipe_num][pool_id] != NULL) {
  10813                       LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10814                                (BSL_META_U(unit,
  10815                                            "WARN:Freeing AllocatedByteCountersMemory\n")));
  10816                       soc_cm_sfree(unit,
  10817                                    flex_byte_counter[unit][direction][pipe_num][pool_id]);
  10818                   }
  10819                   flex_byte_counter[unit][direction][pipe_num][pool_id] =
  10820                        soc_cm_salloc(unit, sizeof(uint64) * num_ctr,
  10821                                      "Advanced Flex byte counter");
  10822                   if (flex_byte_counter[unit][direction][pipe_num][pool_id] == NULL) {
  10823                       LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10824                                 (BSL_META_U(unit,
  10825                                             "Advanced Flex ByteCounterAllocationFailed for"
  10826                                             "unit:%d,dir:%d pool:%d:pipe:%d\n"),
  10827                                  unit, direction, pool_id,pipe_num));
  10828                       _bcm_esw_stat_flex_cleanup(unit);
  10829                       return BCM_E_MEMORY;
  10830                   }
  10831                   sal_memset(flex_byte_counter[unit][direction][pipe_num][pool_id], 0,
  10832                              sizeof(uint64) * num_ctr);
  10833     
  10834                   if (flex_packet_counter[unit][direction][pipe_num][pool_id] != NULL) {
  10835                       LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10836                                (BSL_META_U(unit,
  10837                                            "WARN:FreeingAllocatedPacketCountersMemory\n")));
  10838                       soc_cm_sfree(unit,
  10839                                    flex_packet_counter[unit][direction][pipe_num][pool_id]);
  10840                   }
  10841                   flex_packet_counter[unit][direction][pipe_num][pool_id] =
  10842                        soc_cm_salloc(unit, sizeof(uint32) * num_ctr,
  10843                                      "Advanced Flex packet counter");
  10844                   if (flex_packet_counter[unit][direction][pipe_num][pool_id] == NULL) {
  10845                       LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10846                                 (BSL_META_U(unit,
  10847                                             "Advanced Flex ByteCounterAllocation failed for"
  10848                                             "unit:%d, dir:%d pool:%d\n"),
  10849                                  unit, direction, pool_id));
  10850                       _bcm_esw_stat_flex_cleanup(unit);
  10851                       return BCM_E_MEMORY;
  10852                   }
  10853                   sal_memset(flex_packet_counter[unit][direction][pipe_num][pool_id], 0,
  10854                              sizeof(uint32) * num_ctr);
  10855     
  10856                   if (flex_packet64_counter[unit][direction][pipe_num][pool_id] != NULL) {
  10857                       LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10858                                (BSL_META_U(unit,
  10859                                            "WARN:FreeingAllocatedPacketCountersMemory\n")));
  10860                       soc_cm_sfree(unit,
  10861                                    flex_packet64_counter[unit][direction][pipe_num][pool_id]);
  10862                   }
  10863                   flex_packet64_counter[unit][direction][pipe_num][pool_id] =
  10864                        soc_cm_salloc(unit, sizeof(uint64) * num_ctr,
  10865                                      "Advanced Flex packet counter");
  10866                   if (flex_packet64_counter[unit][direction][pipe_num][pool_id] == NULL) {
  10867                       LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10868                                 (BSL_META_U(unit,
  10869                                             "Advanced Flex ByteCounterAllocation failed for"
  10870                                             "unit:%d, dir:%d pool:%d\n"),
  10871                                  unit, direction, pool_id));
  10872                       _bcm_esw_stat_flex_cleanup(unit);
  10873                       return BCM_E_MEMORY;
  10874                   }
  10875                   sal_memset(flex_packet64_counter[unit][direction][pipe_num][pool_id], 0,
  10876                              sizeof(uint64) * num_ctr);
  10877                   /* Cache used for compaction */
  10878                   if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  10879                       if (flex_byte_counter_compaction[unit][direction][pipe_num][pool_id] != NULL) {
  10880                           LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10881                                   (BSL_META_U(unit,
  10882                                               "WARN:Freeing AllocatedByteCountersMemory\n")));
  10883                           soc_cm_sfree(unit,
  10884                                   flex_byte_counter_compaction[unit][direction][pipe_num][pool_id]);
  10885                       }
  10886                       flex_byte_counter_compaction[unit][direction][pipe_num][pool_id] =
  10887                           soc_cm_salloc(unit, sizeof(uint64) * num_ctr,
  10888                                   "Advanced Flex byte counter");
  10889                       if (flex_byte_counter_compaction[unit][direction][pipe_num][pool_id] == NULL) {
  10890                           LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10891                                   (BSL_META_U(unit,
  10892                                               "Advanced Flex ByteCounterAllocationFailed for"
  10893                                               "unit:%d,dir:%d pool:%d:pipe:%d\n"),
  10894                                    unit, direction, pool_id,pipe_num));
  10895                           _bcm_esw_stat_flex_cleanup(unit);
  10896                           return BCM_E_MEMORY;
  10897                       }
  10898                       sal_memset(flex_byte_counter_compaction[unit][direction][pipe_num][pool_id], 0,
  10899                               sizeof(uint64) * num_ctr);
  10900 
  10901                       if (flex_packet_counter_compaction[unit][direction][pipe_num][pool_id] != NULL) {
  10902                           LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10903                                   (BSL_META_U(unit,
  10904                                               "WARN:FreeingAllocatedPacketCountersMemory\n")));
  10905                           soc_cm_sfree(unit,
  10906                                   flex_packet_counter_compaction[unit][direction][pipe_num][pool_id]);
  10907                       }
  10908                       flex_packet_counter_compaction[unit][direction][pipe_num][pool_id] =
  10909                           soc_cm_salloc(unit, sizeof(uint32) * num_ctr,
  10910                                   "Advanced Flex packet counter");
  10911                       if (flex_packet_counter_compaction[unit][direction][pipe_num][pool_id] == NULL) {
  10912                           LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10913                                   (BSL_META_U(unit,
  10914                                               "Advanced Flex ByteCounterAllocation failed for"
  10915                                               "unit:%d, dir:%d pool:%d\n"),
  10916                                    unit, direction, pool_id));
  10917                           _bcm_esw_stat_flex_cleanup(unit);
  10918                           return BCM_E_MEMORY;
  10919                       }
  10920                       sal_memset(flex_packet_counter_compaction[unit][direction][pipe_num][pool_id], 0,
  10921                               sizeof(uint32) * num_ctr);
  10922 
  10923                       if (flex_packet64_counter_compaction[unit][direction][pipe_num][pool_id] != NULL) {
  10924                           LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10925                                   (BSL_META_U(unit,
  10926                                               "WARN:FreeingAllocatedPacketCountersMemory\n")));
  10927                           soc_cm_sfree(unit,
  10928                                   flex_packet64_counter_compaction[unit][direction][pipe_num][pool_id]);
  10929                       }
  10930                       flex_packet64_counter_compaction[unit][direction][pipe_num][pool_id] =
  10931                           soc_cm_salloc(unit, sizeof(uint64) * num_ctr,
  10932                                   "Advanced Flex packet counter");
  10933                       if (flex_packet64_counter_compaction[unit][direction][pipe_num][pool_id] == NULL) {
  10934                           LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10935                                   (BSL_META_U(unit,
  10936                                               "Advanced Flex ByteCounterAllocation failed for"
  10937                                               "unit:%d, dir:%d pool:%d\n"),
  10938                                    unit, direction, pool_id));
  10939                           _bcm_esw_stat_flex_cleanup(unit);
  10940                           return BCM_E_MEMORY;
  10941                       }
  10942                       sal_memset(flex_packet64_counter_compaction[unit][direction][pipe_num][pool_id], 0,
  10943                               sizeof(uint64) * num_ctr);
  10944                   }
  10945 #ifdef BCM_TOMAHAWK_SUPPORT
  10946                   if (SOC_IS_TOMAHAWKX(unit) ||SOC_IS_TRIDENT3X(unit)) {
  10947                       if (residual_packet_counter[unit][direction][pipe_num][pool_id] !=
  10948                           NULL) {
  10949                           LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10950                                    (BSL_META_U(unit,
  10951                                                "WARN:Free residual pkt counter mem\n")));
  10952                           soc_cm_sfree(unit,
  10953                                        residual_packet_counter[unit][direction][pipe_num][pool_id]);
  10954                       }
  10955                       residual_packet_counter[unit][direction][pipe_num][pool_id] =
  10956                            soc_cm_salloc(unit, sizeof(uint64) * num_ctr,
  10957                                          "Advanced Flex packet counter");
  10958                       if (residual_packet_counter[unit][direction][pipe_num][pool_id] ==
  10959                           NULL) {
  10960                           LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10961                                     (BSL_META_U(unit,
  10962                                                 "residual pkt counter Allocation failed for"
  10963                                                 "unit:%d, dir:%d pool:%d\n"),
  10964                                      unit,direction, pool_id));
  10965                           _bcm_esw_stat_flex_cleanup(unit);
  10966                           return BCM_E_MEMORY;
  10967                       }
  10968                       sal_memset(residual_packet_counter[unit][direction][pipe_num][pool_id],
  10969                                  0, sizeof(uint64) * num_ctr);
  10970 
  10971                       if (residual_byte_counter[unit][direction][pipe_num][pool_id] != NULL) {
  10972                           LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10973                                    (BSL_META_U(unit,
  10974                                                "WARN:Free residual byte counter mem\n")));
  10975                           soc_cm_sfree(unit,
  10976                                        residual_byte_counter[unit][direction]
  10977                                        [pipe_num][pool_id]);
  10978                       }
  10979                       residual_byte_counter[unit][direction][pipe_num][pool_id] =
  10980                            soc_cm_salloc(unit,sizeof(uint64) * num_ctr,
  10981                                          "residual byte counter");
  10982                       if (residual_byte_counter[unit][direction][pipe_num][pool_id] == NULL) {
  10983                           LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  10984                                     (BSL_META_U(unit,
  10985                                                 "residual ByteCounterAllocationFailed for"
  10986                                                 "unit:%d,dir:%d pool:%d:\n"),
  10987                                      unit, direction, pool_id));
  10988                           _bcm_esw_stat_flex_cleanup(unit);
  10989                           return BCM_E_MEMORY;
  10990                       }
  10991                       sal_memset(residual_byte_counter[unit][direction][pipe_num][pool_id], 0,
  10992                                  sizeof(uint64) * num_ctr);
  10993                   }
  10994 #endif
  10995 
  10996                   if (flex_base_index_reference_count[unit][direction]
  10997                                                      [pipe_num][pool_id] != NULL) {
  10998                       LOG_WARN(BSL_LS_BCM_FLEXCTR,
  10999                                (BSL_META_U(unit,
  11000                                            "WARN:Freeing Allocated"
  11001                                             "flex_base_index_reference_count memory\n")));
  11002                       sal_free(flex_base_index_reference_count[unit]
  11003                                                               [direction][pipe_num][pool_id]);
  11004                   }
  11005                   flex_base_index_reference_count[unit][direction][pipe_num][pool_id] =
  11006                        sal_alloc(sizeof(uint16) * num_ctr,
  11007                                  "BaseIndexAllocation");
  11008                   if (flex_base_index_reference_count[unit][direction][pipe_num][pool_id] == NULL){
  11009                       LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  11010                                 (BSL_META_U(unit,
  11011                                             "BaseIndex allocation failed for"
  11012                                             "unit:%d, dir:%d pool:%d\n"),
  11013                                  unit,direction, pool_id));
  11014                       _bcm_esw_stat_flex_cleanup(unit);
  11015                       return BCM_E_MEMORY;
  11016                   }
  11017                   sal_memset(flex_base_index_reference_count[unit][direction]
  11018                              [pipe_num][pool_id], 0, sizeof(uint16) * num_ctr);
  11019 
  11020 #if defined(BCM_TRIDENT2_SUPPORT)
  11021                   if (SOC_IS_TRIDENT2X(unit) &&
  11022                       soc_feature(unit, soc_feature_advanced_flex_counter)) {
  11023                       for (offset_mode = 0; offset_mode < BCM_STAT_FLEX_COUNTER_MAX_MODE;
  11024                            offset_mode++) {
  11025                           if (_flex_stat_mode_base_map[unit][direction]
  11026                               [pool_id][offset_mode] != NULL) {
  11027                               LOG_WARN(BSL_LS_BCM_FLEXCTR,
  11028                                        (BSL_META_U(unit, "WARN:Freeing Allocated"
  11029                                             "_flex_stat_mode_base_map memory\n")));
  11030                               sal_free(_flex_stat_mode_base_map[unit][direction]
  11031                                        [pool_id][offset_mode]);
  11032                           }
  11033                           _flex_stat_mode_base_map[unit][direction]
  11034                               [pool_id][offset_mode] = sal_alloc(sizeof(uint8) * num_ctr,
  11035                               "ModeBaseMapAllocation");
  11036                           if (_flex_stat_mode_base_map[unit][direction]
  11037                                   [pool_id][offset_mode] == NULL){
  11038                               LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  11039                                         (BSL_META_U(unit,
  11040                                                     "ModeBaseMap allocation failed for"
  11041                                                     "unit:%d, dir:%d pool:%d\n"),
  11042                                                     unit,direction, pool_id));
  11043                               _bcm_esw_stat_flex_cleanup(unit);
  11044                               return BCM_E_MEMORY;
  11045                           }
  11046                           sal_memset(_flex_stat_mode_base_map[unit][direction]
  11047                                      [pool_id][offset_mode], 0, sizeof(uint8) * num_ctr);
  11048                       }
  11049                   }
  11050 #endif
  11051              } /* PIPE */
  11052 }
  11053 #if defined(BCM_TRIDENT2_SUPPORT)
  11054                 if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
  11055                     for (buffer_id = 0; buffer_id < _BCM_FLEX_STAT_BUFFS;
  11056                          buffer_id++) {
  11057                         if (flex_byte_counter_x[unit][direction][pool_id][buffer_id]
  11058                                                                           != NULL) {
  11059                             LOG_WARN(BSL_LS_BCM_FLEXCTR,
  11060                                      (BSL_META_U(unit,
  11061                                                  "WARN:Freeing Allocated Byte Counters"
  11062                                                  " Memory\n")));
  11063                             soc_cm_sfree(unit,
  11064                                          flex_byte_counter_x[unit][direction]
  11065                                          [pool_id][buffer_id]);
  11066                         }
  11067                         flex_byte_counter_x[unit][direction][pool_id][buffer_id] =
  11068                              soc_cm_salloc(unit, sizeof(uint64) * size_pool[direction],
  11069                                            "Advanced Flex byte counter x");
  11070                         if (flex_byte_counter_x[unit][direction][pool_id][buffer_id]
  11071                                                                           == NULL) {
  11072                              LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  11073                                        (BSL_META_U(unit,
  11074                                                    "Advanced Flex ByteCounterAllocation"
  11075                                                    " Failed "
  11076                                                    "for unit:%d,dir:%d pool:%d buff:%d:\n"),
  11077                                         unit, direction, pool_id, buffer_id));
  11078                              _bcm_esw_stat_flex_cleanup(unit);
  11079                              return BCM_E_MEMORY;
  11080                         }
  11081                         sal_memset(flex_byte_counter_x[unit][direction][pool_id]
  11082                                    [buffer_id], 0, sizeof(uint64) * size_pool[direction]);
  11083     
  11084                         if (flex_byte_counter_y[unit][direction][pool_id][buffer_id]
  11085                                                                           != NULL) {
  11086                             LOG_WARN(BSL_LS_BCM_FLEXCTR,
  11087                                      (BSL_META_U(unit,
  11088                                                  "WARN:Freeing Allocated Byte Counters"
  11089                                                  " Memory\n")));
  11090                             soc_cm_sfree(unit,
  11091                              flex_byte_counter_y[unit][direction][pool_id][buffer_id]);
  11092                         }
  11093                         flex_byte_counter_y[unit][direction][pool_id][buffer_id] =
  11094                               soc_cm_salloc(unit, sizeof(uint64) * size_pool[direction],
  11095                                             "Advanced Flex byte counter y");
  11096                         if (flex_byte_counter_y[unit][direction][pool_id][buffer_id]
  11097                                                                           == NULL) {
  11098                             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  11099                                       (BSL_META_U(unit,
  11100                                                   "Advanced Flex ByteCounterAllocationFailed"
  11101                                                   " for unit:%d,dir:%d pool:%d: buff:%d:\n"),
  11102                                        unit, direction, pool_id, buffer_id));
  11103                             _bcm_esw_stat_flex_cleanup(unit);
  11104                             return BCM_E_MEMORY;
  11105                         }
  11106                         sal_memset(flex_byte_counter_y[unit][direction][pool_id]
  11107                                    [buffer_id], 0, sizeof(uint64) * size_pool[direction]);
  11108     
  11109                         if (flex_pkt_counter_x[unit][direction][pool_id][buffer_id]
  11110                                                                           != NULL) {
  11111                             LOG_WARN(BSL_LS_BCM_FLEXCTR,
  11112                                      (BSL_META_U(unit,
  11113                                                  "WARN:Freeing AllocatedByteCountersMemory"
  11114                                                  "\n")));
  11115                             soc_cm_sfree(unit,
  11116                                          flex_pkt_counter_x[unit][direction]
  11117                                          [pool_id][buffer_id]);
  11118                         }
  11119                         flex_pkt_counter_x[unit][direction][pool_id][buffer_id] =
  11120                              soc_cm_salloc(unit, sizeof(uint32) * size_pool[direction],
  11121                                            "Advanced Flex packet counter x");
  11122                         if (flex_pkt_counter_x[unit][direction][pool_id][buffer_id]
  11123                                                                           == NULL) {
  11124                             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  11125                                       (BSL_META_U(unit,
  11126                                                   "Advanced Flex ByteCounterAllocationFailed"
  11127                                                   " for unit:%d,dir:%d pool:%d: buff:%d:\n"),
  11128                                        unit, direction, pool_id, buffer_id));
  11129                             _bcm_esw_stat_flex_cleanup(unit);
  11130                             return BCM_E_MEMORY;
  11131                         }
  11132                         sal_memset(flex_pkt_counter_x[unit][direction][pool_id]
  11133                                    [buffer_id], 0, sizeof(uint32) * size_pool[direction]);
  11134     
  11135                         if (flex_pkt_counter_y[unit][direction][pool_id][buffer_id]
  11136                                                                           != NULL) {
  11137                             LOG_WARN(BSL_LS_BCM_FLEXCTR,
  11138                                      (BSL_META_U(unit,
  11139                                                  "WARN:Freeing AllocatedByteCountersMemory"
  11140                                                  "\n")));
  11141                             soc_cm_sfree(unit,
  11142                                          flex_pkt_counter_y[unit][direction]
  11143                                          [pool_id][buffer_id]);
  11144                         }
  11145                         flex_pkt_counter_y[unit][direction][pool_id][buffer_id] =
  11146                              soc_cm_salloc(unit, sizeof(uint32) * size_pool[direction],
  11147                                            "Advanced Flex packet counter y");
  11148                         if (flex_pkt_counter_y[unit][direction][pool_id][buffer_id]
  11149                                                                           == NULL) {
  11150                             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  11151                                       (BSL_META_U(unit,
  11152                                                   "Advanced Flex ByteCounterAllocationFailed"
  11153                                                   " for unit:%d,dir:%d pool:%d: buff:%d:\n"),
  11154                                        unit, direction, pool_id, buffer_id));
  11155                             _bcm_esw_stat_flex_cleanup(unit);
  11156                             return BCM_E_MEMORY;
  11157                         }
  11158                         sal_memset(flex_pkt_counter_y[unit][direction][pool_id]
  11159                                    [buffer_id], 0, sizeof(uint32) * size_pool[direction]);
  11160                     }
  11161 
  11162                     if (flex_counter_toggle[unit][direction][pool_id] != NULL) {
  11163                         LOG_WARN(BSL_LS_BCM_FLEXCTR,
  11164                             (BSL_META_U(unit,
  11165                                 "WARN:Freeing AllocatedToggleMemory"
  11166                                 "\n")));
  11167                         soc_cm_sfree(unit,
  11168                           flex_counter_toggle[unit][direction][pool_id]);
  11169                     }
  11170                     flex_counter_toggle[unit][direction][pool_id] =
  11171                         soc_cm_salloc(unit, sizeof(uint8) * size_pool[direction],
  11172                             "Advanced Flex counter toggle");
  11173                     if (flex_counter_toggle[unit][direction][pool_id]== NULL) {
  11174                         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  11175                             (BSL_META_U(unit,
  11176                                 "Advanced Flex Counter Toggle AllocationFailed"
  11177                                 " for unit:%d,dir:%d pool:%d:\n"),
  11178                                 unit, direction, pool_id));
  11179                         _bcm_esw_stat_flex_cleanup(unit);
  11180                         return BCM_E_MEMORY;
  11181                     }
  11182                     sal_memset(flex_counter_toggle[unit][direction][pool_id],
  11183                         0, sizeof(uint8) * size_pool[direction]);
  11184                 }
  11185 #endif /* BCM_TRIDENT2_SUPPORT*/
  11186          }
  11187          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11188                    (BSL_META_U(unit,
  11189                                "\n")));
  11190     }
  11191 
  11192 #if defined (BCM_TOMAHAWK_SUPPORT) && defined (INCLUDE_FLOWTRACKER)
  11193     if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
  11194          soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
  11195          soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
  11196         rv = _bcm_esw_stat_flex_flowtracker_init(unit);
  11197         if (rv != BCM_E_NONE) {
  11198             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  11199                       (BSL_META_U(unit,
  11200                                   "ERR: flex flowtracker init")));
  11201             _bcm_esw_stat_flex_cleanup(unit);
  11202             return rv;
  11203         }
  11204 
  11205     }
  11206 #endif
  11207 
  11208 
  11209     /* First retrieve mode related information */
  11210     if (SOC_WARM_BOOT(unit)) {
  11211         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11212                   (BSL_META_U(unit,
  11213                               "WARM booting...")));
  11214         for (direction = bcmStatFlexDirectionIngress;
  11215              direction < bcmStatFlexDirectionCount;
  11216              direction++) {
  11217              for (mode = 0; mode < BCM_STAT_FLEX_COUNTER_MAX_MODE; mode++) {
  11218                 if (SOC_REG_IS_64(unit,
  11219                                   _pkt_selector_key_reg[direction][mode])) {
  11220                     SOC_IF_ERROR_RETURN(soc_reg64_get(
  11221                       unit,
  11222                       _pkt_selector_key_reg[direction][mode],
  11223                       REG_PORT_ANY,
  11224                       0,
  11225                                 &selector_key_value));
  11226                  for (selector_count=0,index=0;index<8;index++) {
  11227                       selector_x_en_field_value[index]=
  11228                                  soc_reg64_field32_get(
  11229                                      unit,
  11230                                     _pkt_selector_key_reg[direction][mode],
  11231                                      selector_key_value,
  11232                                      _pkt_selector_x_en_field_name[index]);
  11233                       selector_count +=selector_x_en_field_value[index];
  11234                       selector_for_bit_x_field_value[index]=0;
  11235                       if (selector_x_en_field_value[index] != 0) {
  11236                           selector_for_bit_x_field_value[index]=
  11237                           soc_reg64_field32_get(
  11238                               unit,
  11239                               _pkt_selector_key_reg[direction][mode],
  11240                               selector_key_value,
  11241                               _pkt_selector_for_bit_x_field_name[index]);
  11242                       }
  11243                  }
  11244                  if (selector_count > 0) {
  11245                      LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11246                                (BSL_META_U(unit,
  11247                                            "Selector count :%d .. "),
  11248                                 selector_count));
  11249                      IsAnyModeConfigured=1;
  11250                      if (soc_reg64_field32_get(
  11251                              unit,
  11252                              _pkt_selector_key_reg[direction][mode],
  11253                              selector_key_value,USE_UDF_KEYf) == 1) {
  11254                          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11255                                    (BSL_META_U(unit,
  11256                                                "Direction:%d-Mode:%d UDF MODE is "
  11257                                                 "configured \n"),direction,mode));
  11258                          _bcm_esw_stat_flex_init_udf_mode(
  11259                                   unit,
  11260                                   mode,
  11261                                   direction,
  11262                                   selector_count,
  11263                                   selector_x_en_field_value,
  11264                                   selector_for_bit_x_field_value);
  11265                      } else {
  11266                          if ((soc_reg_field_valid(unit, 
  11267                               _pkt_selector_key_reg[direction][mode], 
  11268                               USE_COMPRESSED_PKT_KEYf)) &&
  11269                              (soc_reg64_field32_get(
  11270                               unit,
  11271                               _pkt_selector_key_reg[direction][mode],
  11272                               selector_key_value,USE_COMPRESSED_PKT_KEYf) == 1)) {
  11273                              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11274                                        (BSL_META_U(unit,
  11275                                                    "Direction:%d-Mode:%d"
  11276                                                     "COMPRESSED MODE is "
  11277                                                     "configured \n"),direction,mode));
  11278                              _bcm_esw_stat_flex_init_cmprsd_mode(
  11279                                       unit,
  11280                                       mode,
  11281                                       direction,
  11282                                       selector_count,
  11283                                       selector_x_en_field_value,
  11284                                       selector_for_bit_x_field_value);
  11285                          } else {
  11286                              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11287                                        (BSL_META_U(unit,
  11288                                                    "Direction:%d-Mode:%d"
  11289                                                     "UNCOMPRESSED MODE is "
  11290                                                     "configured \n"),direction,mode));
  11291                              _bcm_esw_stat_flex_init_uncmprsd_mode(
  11292                                       unit,
  11293                                       mode,
  11294                                       direction,
  11295                                       selector_count,
  11296                                       selector_x_en_field_value,
  11297                                       selector_for_bit_x_field_value);
  11298                          }
  11299                      }
  11300                  } else {
  11301 #ifdef BCM_TOMAHAWK_SUPPORT
  11302                      /* Ensure current mode is not being used for "legacy" IFP
  11303                       * color based counters where packet attribute selectors are
  11304                       * not used and counter offsets are provided directly by the
  11305                       * ifp_policy_table
  11306                       */
  11307                      if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
  11308                          if (bcmStatFlexDirectionIngress == direction) {
  11309                              bcm_error_t rv;
  11310                              uint8 is_configured;
  11311 
  11312                              rv = is_legacy_ifp_color_mode_configured(unit, mode,
  11313                                                                       &is_configured);
  11314                              if ((BCM_E_NONE == rv) && (TRUE == is_configured)) {
  11315                                  IsAnyModeConfigured = 1;
  11316                                  _bcm_esw_stat_flex_init_uncmprsd_mode(
  11317                                           unit,
  11318                                           mode,
  11319                                           direction,
  11320                                           selector_count,
  11321                                           selector_x_en_field_value,
  11322                                           selector_for_bit_x_field_value);
  11323                              }
  11324                          }
  11325                      }
  11326 #endif
  11327                      LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11328                                (BSL_META_U(unit,
  11329                                            "Direction:%d-Mode:%d is unconfigured \n"),
  11330                                 direction,mode));
  11331                  }
  11332              }
  11333         }
  11334     }
  11335     }
  11336     /* stime = sal_time_usecs(); */
  11337     if (IsAnyModeConfigured) {
  11338         /* Get Ingress table info */
  11339 
  11340         /* 1) Ingress: Port Table */
  11341         _bcm_esw_stat_flex_check_ingress_port_table(unit);
  11342         /* LOG_CLI((BSL_META_U(unit,
  11343                                "FLEX: 1.Taken Time: %10d usec\n "),
  11344                     SAL_USECS_SUB(sal_time_usecs(), stime))); */
  11345 
  11346         /* 2) Ingress: VLAN_XLATE Table */
  11347         _bcm_esw_stat_flex_check_ingress_vlan_xlate_table(unit);
  11348         /* 4) Ingress: MPLS_ENTRY Table */
  11349         _bcm_esw_stat_flex_check_ingress_mpls_entry_table(unit);
  11350         /* 5) Ingress: SOURCE_VP Table */
  11351         _bcm_esw_stat_flex_check_ingress_source_vp_table(unit);
  11352         /* 6) Ingress: L3_IIF */
  11353         _bcm_esw_stat_flex_check_ingress_l3_iif_table(unit);
  11354         /* 7) Ingress: VFI */
  11355         _bcm_esw_stat_flex_check_ingress_vfi_table(unit);
  11356         /* 8) Ingress: VRF */
  11357         _bcm_esw_stat_flex_check_ingress_vrf_table(unit);
  11358         /* 9) Ingress: VLAN */
  11359         _bcm_esw_stat_flex_check_ingress_vlan_table(unit);
  11360 #if defined(BCM_TRIDENT2_SUPPORT)
  11361         if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
  11362             /* 10) Ingress: L3 Routing Table */
  11363             _bcm_esw_stat_flex_check_ingress_l3_routing_table(unit);
  11364         }
  11365 #endif
  11366 
  11367         /* Get Egress table info */
  11368 
  11369         /* 1) EGR_L3_NEXT_HOP */
  11370         _bcm_esw_stat_flex_check_egress_l3_next_hop_table(unit);
  11371         /* 2) EGR_VFI */
  11372         _bcm_esw_stat_flex_check_egress_vfi_table(unit);
  11373         /* 3) EGR_PORT */
  11374         _bcm_esw_stat_flex_check_egress_port_table(unit);
  11375         /* 4) EGR_VLAN */
  11376         _bcm_esw_stat_flex_check_egress_vlan_table(unit);
  11377         /* 5) EGR_VLAN_XLATE */
  11378         _bcm_esw_stat_flex_check_egress_vlan_xlate_table(unit);
  11379         /* 6) EGR_NAT_PACKET_EDIT_INFO */
  11380         _bcm_esw_stat_flex_check_egress_nat_pkt_edit_table(unit);
  11381         /* 7) EGR_DVP_1 */
  11382         if (soc_mem_is_valid(unit, EGR_DVP_ATTRIBUTE_1m)) {
  11383             _bcm_esw_stat_flex_check_egress_dvp_1_table(unit);
  11384         }
  11385 #if defined(BCM_TRIDENT3_SUPPORT)
  11386         if (SOC_IS_TRIDENT3X(unit) && soc_mem_is_valid(unit, EGR_DVP_ATTRIBUTEm)) {
  11387             _bcm_esw_stat_flex_check_egress_dvp_table(unit);
  11388         }
  11389 #endif
  11390    
  11391         for (direction=bcmStatFlexDirectionIngress;direction<2;direction++) {
  11392              for (mode=0;mode<BCM_STAT_FLEX_COUNTER_MAX_MODE;mode++) {
  11393                   _bcm_esw_stat_flex_retrieve_group_mode(unit, direction,mode);
  11394              }
  11395         }
  11396     }
  11397 #if defined(BCM_KATANA2_SUPPORT)
  11398     if (!SOC_WARM_BOOT(unit) &&
  11399         soc_feature(unit, soc_feature_flex_stat_attributes_class)) {
  11400         BCM_IF_ERROR_RETURN(_bcm_esw_stat_combine_attr_matrix_init(unit,
  11401                 &combination_attr_matrix_size));
  11402     }
  11403 #endif
  11404 
  11405 
  11406     if (!soc_feature(unit, soc_feature_centralized_counter)) {
  11407         /* Do Callback registration only for Legacy counter collection model
  11408          * and not for centralized counter collection model.
  11409          * In centralized model, Counter module takes care of collection
  11410          */
  11411         rv = soc_counter_extra_register(unit, _bcm_esw_stat_flex_callback);
  11412         if (BCM_FAILURE(rv)) {
  11413             _bcm_esw_stat_flex_cleanup(unit);
  11414             return rv;
  11415         }
  11416     }
  11417 
  11418     config_str = soc_property_get_str(unit, spn_ING_SHARE_FLEX_COUNTER_POOL);
  11419     if (config_str != NULL) {
  11420         rv = _bcm_esw_stat_flex_property_get(unit, config_str, CONFIG_ING_OBJECT);
  11421         if (rv != BCM_E_NONE) {
  11422             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  11423                       (BSL_META_U(unit,
  11424                                   "ERR: Parsing property string(ing) failed")));
  11425             _bcm_esw_stat_flex_cleanup(unit);
  11426             return rv;
  11427         }
  11428     }
  11429     config_str = soc_property_get_str(unit, spn_EGR_SHARE_FLEX_COUNTER_POOL);
  11430     if (config_str != NULL) {
  11431         rv = _bcm_esw_stat_flex_property_get(unit, config_str, CONFIG_EGR_OBJECT);
  11432         if (rv != BCM_E_NONE) {
  11433             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  11434                       (BSL_META_U(unit,
  11435                                   "ERR: Parsing property string(egr) failed")));
  11436             _bcm_esw_stat_flex_cleanup(unit);
  11437             return rv;
  11438         }
  11439     }
  11440 
  11441     if(local_scache_ptr[unit] != NULL) {
  11442        LOG_WARN(BSL_LS_BCM_FLEXCTR,
  11443                 (BSL_META_U(unit,
  11444                             "WARN: Freeing flex_scache_ptr existing memory")));
  11445        sal_free(local_scache_ptr[unit]);
  11446     }
  11447     local_scache_size[unit] = sizeof(uint32)*BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE;
  11448     local_scache_ptr[unit] = sal_alloc(local_scache_size[unit],"Flex scache memory");
  11449     if (local_scache_ptr[unit]  == NULL) {
  11450         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  11451                   (BSL_META_U(unit,
  11452                               "ERR: Couldnot allocate flex_scache_ptr existing memory")));
  11453         _bcm_esw_stat_flex_cleanup(unit);
  11454         return BCM_E_MEMORY;
  11455     }
  11456     sal_memset(local_scache_ptr[unit], 0, local_scache_size[unit]);
  11457 #ifdef BCM_WARM_BOOT_SUPPORT
  11458     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11459               (BSL_META_U(unit,
  11460                           "WARM Booting... \n")));
  11461     /* rv = soc_scache_recover(unit); */
  11462     flex_scache_allocated_size[unit] = 0;
  11463     SOC_SCACHE_HANDLE_SET(handle[unit], unit, BCM_MODULE_STAT,
  11464                           _BCM_STAT_WARM_BOOT_CHUNK_FLEX);
  11465     SOC_SCACHE_MODULE_MAX_PARTITIONS_SET(unit, BCM_MODULE_STAT, 1);
  11466     if (!SOC_WARM_BOOT(unit)) {
  11467         local_scache_size[unit] +=  sizeof(bcm_stat_flex_group_mode_related_info_t) *
  11468                               BCM_STAT_FLEX_COUNTER_MAX_MODE *
  11469                               BCM_STAT_FLEX_COUNTER_MAX_DIRECTION;
  11470 
  11471         if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  11472                     (BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_4)) {
  11473             local_scache_size[unit] +=  sizeof(bcm_stat_flex_custom_mode_related_info_t) *
  11474                                   (BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE - 
  11475                                    BCM_CUSTOM_INGRESS_MODE_START) + 2*sizeof(uint32);
  11476             local_scache_size[unit] +=
  11477                               sizeof(bcm_stat_flex_counter_id_related_info_t) *
  11478                               (BCM_MAX_STAT_COUNTER_IDS-1);
  11479         }
  11480 #ifdef BCM_TRIDENT3_SUPPORT
  11481         if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  11482             soc_feature(unit, soc_feature_stat_egr_multi_pipe_support) &&
  11483             (BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_7)) {
  11484             local_scache_size[unit] +=
  11485                 sizeof(bcm_stat_flex_custom_mode_info_t) *
  11486                 (BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE - BCM_CUSTOM_EGRESS_MODE_START)
  11487                 + sizeof(uint32);
  11488         }
  11489 #endif
  11490 
  11491         if (BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_8) {
  11492             /* Alloc space to save compression shared mode flags
  11493              * for ingress/egress direction */
  11494             if (soc_feature(unit, soc_feature_flex_stat_compression_share)) {
  11495                 compression_wb_size =
  11496                     _bcm_flex_stat_compression_share_wb_size(unit);
  11497                 local_scache_size[unit] += compression_wb_size;
  11498             }
  11499 #if defined(BCM_KATANA2_SUPPORT)
  11500             if (soc_feature(unit, soc_feature_flex_stat_attributes_class)) {
  11501                 local_scache_size[unit] += (combination_attr_matrix_size*
  11502                             combination_attr_matrix_size*sizeof(uint32));
  11503             }
  11504 #endif
  11505         }
  11506         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11507                   (BSL_META_U(unit,
  11508                               "ColdBoot: Modified Local Scache Size %d \n"),
  11509                    local_scache_size[unit]));
  11510         SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
  11511         if (stable_size == 0) {
  11512             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11513                       (BSL_META_U(unit,
  11514                                   "STABLE size is zero.Probably NotConfigured yet\n")));
  11515             return BCM_E_NONE;
  11516         }
  11517 
  11518         /* Check if scache already allocated */
  11519         rv = soc_scache_ptr_get(unit,
  11520                                 handle[unit],
  11521                                 (uint8 **)&flex_scache_ptr[unit],
  11522                                 &flex_scache_allocated_size[unit]);
  11523         switch (rv) {
  11524             case SOC_E_NOT_FOUND:
  11525                 /* We have not allocated scache, continue with allocation */
  11526                 SOC_IF_ERROR_RETURN(soc_stable_used_get(unit, &stable_used_size));
  11527                 if ((stable_size - stable_used_size) < local_scache_size[unit]) {
  11528                      LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11529                                (BSL_META_U(unit,
  11530                                            "Not enough scache memory left.\n")));
  11531                      _bcm_esw_stat_flex_cleanup(unit);
  11532                      return BCM_E_CONFIG;
  11533                 }
  11534                 rv = soc_scache_alloc(unit, handle[unit], local_scache_size[unit]);
  11535                 if (!((rv == BCM_E_NONE) || (rv == BCM_E_EXISTS))) {
  11536                      LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11537                                (BSL_META_U(unit,
  11538                                          "Seems to be some internal problem.\n")));
  11539                      _bcm_esw_stat_flex_cleanup(unit);
  11540                      return rv;
  11541                 }
  11542                 SOC_IF_ERROR_RETURN(soc_scache_ptr_get(
  11543                                     unit,
  11544                                     handle[unit],
  11545                                     (uint8 **)&flex_scache_ptr[unit],
  11546                                     &flex_scache_allocated_size[unit]));
  11547                 break;
  11548             case SOC_E_NONE:
  11549                 /* We have already allocated scache(reload case) confirm size */
  11550                 if (flex_scache_allocated_size[unit] != local_scache_size[unit])
  11551                 {
  11552                     if(BCM_STAT_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_9) {
  11553                         /* scache is increased due to increase in attribute
  11554                          * selectors.So realloc size to accomodate wb sync */
  11555                         additional_scache_size = local_scache_size[unit] -
  11556                             flex_scache_allocated_size[unit];
  11557                         rv = soc_scache_realloc(unit, handle[unit], additional_scache_size);
  11558                         if (!((rv == BCM_E_NONE) || (rv == BCM_E_EXISTS))) {
  11559                             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11560                                     (BSL_META_U(unit,
  11561                                                 "Seems to be some internal problem.\n")));
  11562                             _bcm_esw_stat_flex_cleanup(unit);
  11563                             return rv;
  11564                         }
  11565                         SOC_IF_ERROR_RETURN(soc_scache_ptr_get(
  11566                                     unit,
  11567                                     handle[unit],
  11568                                     (uint8 **)&flex_scache_ptr[unit],
  11569                                     &flex_scache_allocated_size[unit]));
  11570                     } else {
  11571                         LOG_WARN(BSL_LS_BCM_FLEXCTR,
  11572                                 (BSL_META_U(unit,
  11573                                             "Scache size mismatch\n")));
  11574                         _bcm_esw_stat_flex_cleanup(unit);
  11575                         return BCM_E_INTERNAL;
  11576                     }
  11577                 }
  11578                 break;
  11579             default:
  11580                 LOG_WARN(BSL_LS_BCM_FLEXCTR,
  11581                          (BSL_META_U(unit,
  11582                                      "Error getting scache handle\n")));
  11583                 _bcm_esw_stat_flex_cleanup(unit);
  11584                 return rv;
  11585                 break;
  11586         }
  11587     } else {
  11588         rv = soc_scache_ptr_get(
  11589                             unit,
  11590                             handle[unit],
  11591                             (uint8 **)&flex_scache_ptr[unit],
  11592                             &flex_scache_allocated_size[unit]);
  11593         /* You may get  BCM_E_NOT_FOUND for level 1 warm boot */
  11594         if (rv == BCM_E_NOT_FOUND) {
  11595              LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  11596                          (BSL_META_U(unit,
  11597                                      "Seems to be Level-1 Warm boot...continuing..\n")));
  11598              return BCM_E_NONE;
  11599         }
  11600         if (rv != BCM_E_NONE) {
  11601              LOG_WARN(BSL_LS_BCM_FLEXCTR,
  11602                       (BSL_META_U(unit,
  11603                                   "Seems to be some internal problem:.\n")));
  11604              _bcm_esw_stat_flex_cleanup(unit);
  11605              return rv;
  11606         }
  11607 
  11608         if (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_3)) {
  11609             local_scache_size[unit] +=
  11610                               sizeof(bcm_stat_flex_group_mode_related_info_t) *
  11611                               BCM_STAT_FLEX_COUNTER_MAX_MODE *
  11612                               BCM_STAT_FLEX_COUNTER_MAX_DIRECTION;
  11613         }
  11614 
  11615         if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  11616            (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_4))) {
  11617             local_scache_size[unit] +=
  11618                               sizeof(bcm_stat_flex_counter_id_related_info_t) *
  11619                               (BCM_MAX_STAT_COUNTER_IDS-1);
  11620 
  11621             local_scache_size[unit] +=
  11622                               sizeof(bcm_stat_flex_custom_mode_related_info_t) *
  11623                               (BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE - BCM_CUSTOM_INGRESS_MODE_START)
  11624                               + 2*sizeof(uint32);
  11625 
  11626             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11627                       (BSL_META_U(unit,
  11628                                   "WarmBoot: Modified Local Scache Size %d\n"),
  11629                        local_scache_size[unit]));
  11630         }
  11631 #ifdef BCM_TRIDENT3_SUPPORT
  11632         if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  11633             soc_feature(unit, soc_feature_stat_egr_multi_pipe_support) &&
  11634             (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_7))) {
  11635             local_scache_size[unit] +=
  11636                 sizeof(bcm_stat_flex_custom_mode_info_t) *
  11637                 (BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE - BCM_CUSTOM_EGRESS_MODE_START)
  11638                 + sizeof(uint32);
  11639         }
  11640 #endif
  11641 
  11642         if (_bcm_esw_stat_sync_version_above_equal(unit,BCM_WB_VERSION_1_8)) {
  11643             /* Recover space for compression shared mode flags
  11644              * for ingress/egress directions */
  11645             if (soc_feature(unit, soc_feature_flex_stat_compression_share)) {
  11646                 compression_wb_size =
  11647                     _bcm_flex_stat_compression_share_wb_size(unit);
  11648                 local_scache_size[unit] += compression_wb_size;
  11649             }
  11650 #if defined(BCM_KATANA2_SUPPORT)
  11651             if (soc_feature(unit, soc_feature_flex_stat_attributes_class)) {
  11652                 BCM_IF_ERROR_RETURN(_bcm_esw_stat_combine_attr_matrix_init(unit,
  11653                             &combination_attr_matrix_size));
  11654                 local_scache_size[unit] += (combination_attr_matrix_size*
  11655                             combination_attr_matrix_size*sizeof(uint32));
  11656             }
  11657 #endif
  11658         }
  11659         sal_memcpy(&local_scache_ptr[unit][0],
  11660                    &flex_scache_ptr[unit][0],
  11661                    BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE);
  11662     }
  11663     if (flex_scache_ptr[unit] == NULL) {
  11664            _bcm_esw_stat_flex_cleanup(unit);
  11665            return BCM_E_MEMORY;
  11666     }
  11667     if ((!SOC_WARM_BOOT(unit)) &&
  11668         (flex_scache_allocated_size[unit] != local_scache_size[unit])) {
  11669         _bcm_esw_stat_flex_cleanup(unit);
  11670         return BCM_E_INTERNAL;
  11671     }
  11672     if (SOC_WARM_BOOT(unit)) {
  11673         BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_install_stat_id(
  11674                                      unit,flex_scache_ptr[unit],
  11675                                      &per_pipe_mode_ifp, &per_pipe_mode_vfp,
  11676                                      &per_pipe_mode_efp));
  11677         /* 3) Ingress: VFP_POLICY_TABLE Table */
  11678         _bcm_esw_stat_flex_check_ingress_vfp_policy_table(unit, per_pipe_mode_vfp);
  11679 
  11680 #if defined(BCM_TOMAHAWK_SUPPORT)
  11681         if (IsAnyModeConfigured &&
  11682             (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit))) {
  11683         /* 10) Ingress: IFP_POLICY_TABLE Table */
  11684            if(SOC_IS_TOMAHAWKX(unit)) {
  11685                 _bcm_esw_stat_flex_check_ingress_ifp_policy_table(unit,
  11686                                             per_pipe_mode_ifp);
  11687            }
  11688         /* 11) Ingress: AGM */
  11689             _bcm_esw_stat_flex_check_ingress_agm_table(unit);
  11690         }
  11691 #endif
  11692 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  11693         if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
  11694             _bcm_esw_stat_flex_check_ingress_ifp_policy_table(unit,
  11695                                                 per_pipe_mode_ifp);
  11696             _bcm_esw_stat_flex_check_egress_efp_policy_table(unit, 0);
  11697         }
  11698 #endif
  11699 #if defined(BCM_TRIDENT3_SUPPORT)
  11700         if (SOC_IS_TRIDENT3X(unit)) {
  11701             _bcm_esw_stat_flex_check_egress_efp_policy_table(unit,
  11702                         per_pipe_mode_ifp);
  11703         }
  11704 #endif
  11705 
  11706 
  11707         for (direction = bcmStatFlexDirectionIngress;
  11708              direction < bcmStatFlexDirectionCount;
  11709              direction++) {
  11710             for (pool_id = 0; pool_id < num_pools[direction]; pool_id++) {
  11711                 used_pool = 0;
  11712                 for(pipe_num = 0; pipe_num < num_pipes; pipe_num++) {
  11713                     if (flex_pool_stat[unit][direction][pipe_num]
  11714                             [pool_id].attached_entries != 0) {
  11715                         used_pool = 1;
  11716                         break;
  11717                     }
  11718                 }
  11719                 if (used_pool) {
  11720                     _bcm_esw_stat_flex_enable_pool(unit, direction,
  11721                             _pool_ctr_register[direction][pool_id], 1);
  11722                 }
  11723             }
  11724         }
  11725     }
  11726     /* soc_scache_commit(unit); */
  11727 #else
  11728     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11729               (BSL_META_U(unit,
  11730                           "COLD Booting... \n")));
  11731 #endif
  11732     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11733               (BSL_META_U(unit,
  11734                           "OK \n")));
  11735 
  11736     /* Just an Info */
  11737     if (SOC_CONTROL(unit)->tdma_enb == 0) { /* enabled */
  11738         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11739                   (BSL_META_U(unit,
  11740                               "WARNING:DMA will not be used for BulkMemoryReading\n")));
  11741     }
  11742     return BCM_E_NONE;
  11743 }
  11744 
  11745 /*
  11746  * Function:
  11747  *      _bcm_esw_stat_flex_update_udf_selector_keys
  11748  * Description:
  11749  *      Update UDF selector keys
  11750  * Parameters:
  11751  *      unit                      - (IN) unit number
  11752  *      direction                 - (IN) Flex Data Flow Direction
  11753  *      pkt_attr_selector_key_reg - (IN) Flex Packet Attribute Seletor Key Reg
  11754  *      udf_pkt_attr_selectors    - (IN) Flex Udf Packet Seletors
  11755  *      total_udf_bits            - (OUT) Flex Udf Reserved bits
  11756  * Return Value:
  11757  *      BCM_E_XXX
  11758  * Notes:
  11759  *      Currently not being used
  11760  */
  11761 bcm_error_t _bcm_esw_stat_flex_update_udf_selector_keys(
  11762             int                                    unit,
  11763             bcm_stat_flex_direction_t              direction,
  11764             soc_reg_t                              pkt_attr_selector_key_reg,
  11765             bcm_stat_flex_udf_pkt_attr_selectors_t *udf_pkt_attr_selectors,
  11766             uint32                                 *total_udf_bits)
  11767 {
  11768     uint32 udf_valid_bits=0;
  11769     uint8  udf_value_bit_position=0;
  11770     uint8  key_bit_selector_position=0;
  11771     uint16 udf_value=0;
  11772     uint64 pkt_attr_selector_key_reg_value;
  11773     uint32 index=0;
  11774 
  11775     COMPILER_64_ZERO(pkt_attr_selector_key_reg_value);
  11776 
  11777     (*total_udf_bits)=0;
  11778     if (direction >= BCM_STAT_FLEX_COUNTER_MAX_DIRECTION) {
  11779         return BCM_E_PARAM;
  11780     }
  11781     for(index=0; index < 8; index++) {
  11782         if (_pkt_selector_key_reg[direction][index] ==
  11783             pkt_attr_selector_key_reg ) {
  11784             break;
  11785         }
  11786     }
  11787     if (index == 8) {
  11788          return BCM_E_PARAM;
  11789     }
  11790 
  11791     /* Sanity Check: Get total number of udf bits */
  11792     udf_value = udf_pkt_attr_selectors->udf_pkt_attr_bits.udf0;
  11793     for (udf_value_bit_position=0;
  11794          udf_value_bit_position<16;
  11795          udf_value_bit_position++) {
  11796          if (udf_value & 0x1) {
  11797              (*total_udf_bits)++;
  11798          }
  11799          udf_value = udf_value >> 1;
  11800     }
  11801     if (*total_udf_bits > 8) {
  11802         return BCM_E_PARAM;
  11803     }
  11804     udf_value = udf_pkt_attr_selectors->udf_pkt_attr_bits.udf1;
  11805     for (udf_value_bit_position=0;
  11806          udf_value_bit_position<16;
  11807          udf_value_bit_position++) {
  11808          if(udf_value & 0x1) {
  11809             (*total_udf_bits)++;
  11810          }
  11811          udf_value = udf_value >> 1;
  11812     }
  11813 
  11814     /*First Get complete value of ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_?r value */
  11815     SOC_IF_ERROR_RETURN(soc_reg_get(
  11816                         unit,
  11817                         pkt_attr_selector_key_reg,
  11818                         REG_PORT_ANY,
  11819                         0,
  11820                         &pkt_attr_selector_key_reg_value));
  11821 
  11822     /* Next set field value for
  11823        ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_?r:SELECTOR_KEY field*/
  11824     soc_reg64_field32_set(unit, pkt_attr_selector_key_reg,
  11825                           &pkt_attr_selector_key_reg_value, USE_UDF_KEYf, 1);
  11826     if (udf_pkt_attr_selectors->udf_pkt_attr_bits.udf0 != 0) {
  11827         udf_valid_bits |= 0x1;
  11828     }
  11829     if (udf_pkt_attr_selectors->udf_pkt_attr_bits.udf1 != 0) {
  11830         udf_valid_bits |= 0x2;
  11831     }
  11832     soc_reg64_field32_set(unit, pkt_attr_selector_key_reg,
  11833                           &pkt_attr_selector_key_reg_value,
  11834                           USER_SPECIFIED_UDF_VALIDf, udf_valid_bits);
  11835 
  11836     /* Now update selector keys */
  11837     if (udf_pkt_attr_selectors->drop_enable) {
  11838        (*total_udf_bits)++;
  11839        BCM_IF_ERROR_RETURN(
  11840                _bcm_esw_stat_flex_update_selector_keys_enable_fields(
  11841                         unit,
  11842                         pkt_attr_selector_key_reg,
  11843                         &pkt_attr_selector_key_reg_value,
  11844                         0,
  11845                         1,     /* Total Bits */
  11846                         0x1,     /* MASK */
  11847                         &key_bit_selector_position));
  11848     }
  11849     if ((*total_udf_bits) > 8) {
  11850          return BCM_E_PARAM;
  11851     }
  11852 
  11853     udf_value = udf_pkt_attr_selectors->udf_pkt_attr_bits.udf0;
  11854     for (udf_value_bit_position=0;
  11855          udf_value_bit_position<16;
  11856          udf_value_bit_position++) {
  11857          if (udf_value & 0x1) {
  11858            BCM_IF_ERROR_RETURN(
  11859                _bcm_esw_stat_flex_update_selector_keys_enable_fields(
  11860                         unit,
  11861                         pkt_attr_selector_key_reg,
  11862                         &pkt_attr_selector_key_reg_value,
  11863                         udf_value_bit_position+1,
  11864                         1,     /* Total Bits */
  11865                         0x1,     /* MASK */
  11866                         &key_bit_selector_position));
  11867          }
  11868          udf_value = udf_value >> 1;
  11869     }
  11870     udf_value = udf_pkt_attr_selectors->udf_pkt_attr_bits.udf1;
  11871     for (;udf_value_bit_position<32; udf_value_bit_position++) {
  11872          if(udf_value & 0x1) {
  11873             BCM_IF_ERROR_RETURN(
  11874                _bcm_esw_stat_flex_update_selector_keys_enable_fields(
  11875                         unit,
  11876                         pkt_attr_selector_key_reg,
  11877                         &pkt_attr_selector_key_reg_value,
  11878                         udf_value_bit_position+1,
  11879                         1,    /* Total Bits */
  11880                         0x1,    /* MASK */
  11881                         &key_bit_selector_position));
  11882          }
  11883          udf_value = udf_value >> 1;
  11884     }
  11885     /* Finally set value for ING_FLEX_CTR_PKT_ATTR_SELECTOR_KEY_?r */
  11886     SOC_IF_ERROR_RETURN(soc_reg_set(unit, pkt_attr_selector_key_reg,
  11887                                     REG_PORT_ANY, 0,
  11888                                     pkt_attr_selector_key_reg_value));
  11889     return BCM_E_NONE;
  11890 }
  11891 /*
  11892  * Function:
  11893  *      _bcm_esw_stat_flex_update_offset_table
  11894  * Description:
  11895  *      Update flex Offset table
  11896  * Parameters:
  11897  *      unit                      - (IN) unit number
  11898  *      direction                 - (IN) Flex Data Flow Direction
  11899  *      flex_ctr_offset_table_mem - (IN) Flex Offset Table
  11900  *      mode                      - (IN) Flex Mode
  11901  *      total_counters            - (IN) Flex Total Counters
  11902  * Return Value:
  11903  *      BCM_E_XXX
  11904  * Notes:
  11905  */
  11906 bcm_error_t _bcm_esw_stat_flex_update_offset_table(
  11907             int                                unit,
  11908             bcm_stat_flex_direction_t          direction,
  11909             soc_mem_t                          flex_ctr_offset_table_mem,
  11910             bcm_stat_flex_mode_t               mode,
  11911             uint32                             total_counters,
  11912             bcm_stat_flex_offset_table_entry_t offset_table_map[256])
  11913 {
  11914     uint32                              index=0;
  11915     uint32                              zero=0;
  11916     uint32                              count_enable=1;
  11917     uint32                              offset_value=0;
  11918     ing_flex_ctr_offset_table_0_entry_t *offset_table_entry_v=NULL;
  11919     uint32                              num_pools[
  11920                                         BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  11921 
  11922     num_pools[bcmStatFlexDirectionIngress] = SOC_INFO(unit).
  11923                                              num_flex_ingress_pools;
  11924     num_pools[bcmStatFlexDirectionEgress]  = SOC_INFO(unit).
  11925                                              num_flex_egress_pools;
  11926 
  11927     if (direction >= BCM_STAT_FLEX_COUNTER_MAX_DIRECTION) {
  11928         return BCM_E_PARAM;
  11929     }
  11930     for(index = 0; index < num_pools[direction]; index++) {
  11931         if (_ctr_offset_table[direction][index] == flex_ctr_offset_table_mem ) {
  11932             break;
  11933         }
  11934     }
  11935     if (index == num_pools[direction]) {
  11936          return BCM_E_PARAM;
  11937     }
  11938     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  11939               (BSL_META_U(unit,
  11940                           "...Updating offset_table:%s:%d \n"),
  11941                SOC_MEM_UFNAME(unit,flex_ctr_offset_table_mem),
  11942                (int)sizeof(ing_flex_ctr_offset_table_0_entry_t)));
  11943     offset_table_entry_v = soc_cm_salloc(unit,
  11944                                sizeof(ing_flex_ctr_offset_table_0_entry_t)*
  11945                                BCM_STAT_FLEX_MAX_COUNTERS_PER_MODE,
  11946                                "offset_table_entry");
  11947     if (offset_table_entry_v == NULL) {
  11948         return BCM_E_MEMORY;
  11949     }
  11950     sal_memset(offset_table_entry_v, 0, (sizeof(ing_flex_ctr_offset_table_0_entry_t)*
  11951                                BCM_STAT_FLEX_MAX_COUNTERS_PER_MODE));
  11952     if (soc_mem_read_range(unit,
  11953                            flex_ctr_offset_table_mem,
  11954                            MEM_BLOCK_ANY,
  11955                            (mode << 8),
  11956                            (mode << 8) + BCM_STAT_FLEX_MAX_COUNTERS_PER_MODE - 1,
  11957                            offset_table_entry_v ) != BCM_E_NONE){
  11958         soc_cm_sfree(unit,offset_table_entry_v);
  11959         return BCM_E_INTERNAL;
  11960     }
  11961     /*for(index=0;index<255;index++) */
  11962     for (index = 0; index < total_counters; index++) {
  11963          /* Set OFFSETf */
  11964          if (offset_table_map == NULL) {
  11965              offset_value = index;
  11966              count_enable = 1;
  11967          } else {
  11968              offset_value = offset_table_map[index].offset;
  11969              count_enable = offset_table_map[index].count_enable;
  11970          }
  11971          soc_mem_field_set(
  11972                  unit,
  11973                  flex_ctr_offset_table_mem,
  11974                  (uint32 *)&offset_table_entry_v[index],
  11975                  OFFSETf,
  11976                  &offset_value);
  11977          /* Set COUNT_ENABLEf */
  11978          soc_mem_field_set(
  11979                  unit,
  11980                  flex_ctr_offset_table_mem,
  11981                  (uint32 *)&offset_table_entry_v[index],
  11982                  COUNT_ENABLEf,
  11983                  &count_enable);
  11984     }
  11985     /* Clear remaining entries */
  11986     for (; index < BCM_STAT_FLEX_MAX_COUNTERS_PER_MODE; index++) {
  11987          /* Set OFFSETf=zero */
  11988          soc_mem_field_set(
  11989                  unit,
  11990                  flex_ctr_offset_table_mem,
  11991                  (uint32 *)&offset_table_entry_v[index],
  11992                  OFFSETf,
  11993                  &zero);
  11994          /* Set COUNT_ENABLEf=zero */
  11995          soc_mem_field_set(
  11996                  unit,
  11997                  flex_ctr_offset_table_mem,
  11998                  (uint32 *)&offset_table_entry_v[index],
  11999                  COUNT_ENABLEf,
  12000                  &zero);
  12001     }
  12002     if (soc_mem_write_range(    unit,
  12003                 flex_ctr_offset_table_mem,
  12004                 MEM_BLOCK_ALL,
  12005                 (mode << 8),
  12006                 (mode << 8) + BCM_STAT_FLEX_MAX_COUNTERS_PER_MODE - 1,
  12007                 offset_table_entry_v ) != BCM_E_NONE){
  12008         soc_cm_sfree(unit,offset_table_entry_v);
  12009         return BCM_E_INTERNAL;
  12010     }
  12011     soc_cm_sfree(unit,offset_table_entry_v);
  12012     return BCM_E_NONE;
  12013 }
  12014 /*
  12015  * Function:
  12016  *      _bcm_esw_stat_flex_update_selector_keys_enable_fields
  12017  * Description:
  12018  *      Enable flex selector keys fields
  12019  * Parameters:
  12020  * unit                              - (IN) unit number
  12021  * pkt_attr_selector_key_reg         - (IN) Flex Packet Attribute Selector
  12022  * pkt_attr_selector_key_reg_value   - (IN) Flex Packet Attribute SelectorVal
  12023  * ctr_pkt_attr_bit_position         - (IN) Flex Packet CounterAttr Bit Position
  12024  * ctr_pkt_attr_total_bits           - (IN) Flex Packet Counter Attr Total Bits
  12025  * pkt_attr_field_mask_v             - (IN) Flex Packet Attr Field Mask
  12026  * ctr_current_bit_selector_position - (IN/OUT) Current BitSelector Position
  12027  *
  12028  * Return Value:
  12029  *      BCM_E_XXX
  12030  * Notes:
  12031  */
  12032 bcm_error_t _bcm_esw_stat_flex_update_selector_keys_enable_fields(
  12033            int       unit,
  12034            soc_reg_t pkt_attr_selector_key_reg,
  12035            uint64    *pkt_attr_selector_key_reg_value,
  12036            uint32    ctr_pkt_attr_bit_position,
  12037            uint32    ctr_pkt_attr_total_bits,
  12038            uint8     pkt_attr_field_mask_v,
  12039            uint8     *ctr_current_bit_selector_position)
  12040 {
  12041     uint32 index=0;
  12042     uint8  field_mask=0;
  12043     uint8  total_field_bits=0;
  12044     uint8  field_index[8]={0};
  12045 
  12046     if ((*ctr_current_bit_selector_position) + ctr_pkt_attr_total_bits > 8) {
  12047          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12048                    (BSL_META_U(unit,
  12049                                "Total bits exceeding 8 \n")));
  12050          return BCM_E_INTERNAL;
  12051     }
  12052     field_mask = pkt_attr_field_mask_v;
  12053     total_field_bits = 0;
  12054 
  12055     for (index=0;index < 8 ; index++) {
  12056         if (field_mask & 0x1) {
  12057             field_index[index] = index;
  12058             total_field_bits++;
  12059         }
  12060         field_mask = field_mask >> 1;
  12061     }
  12062     if (total_field_bits != ctr_pkt_attr_total_bits ) {
  12063         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12064                   (BSL_META_U(unit,
  12065                               "Total bits exceeding not matching with mask bits \n")));
  12066         return BCM_E_INTERNAL;
  12067     }
  12068 
  12069     for (index=0;index<ctr_pkt_attr_total_bits;index++) {
  12070          soc_reg64_field32_set(
  12071                    unit,
  12072                    pkt_attr_selector_key_reg,
  12073                    pkt_attr_selector_key_reg_value,
  12074                    _pkt_selector_x_en_field_name[
  12075                     *ctr_current_bit_selector_position],
  12076                    1);
  12077          soc_reg64_field32_set(
  12078                    unit,
  12079                    pkt_attr_selector_key_reg,
  12080                    pkt_attr_selector_key_reg_value,
  12081                    _pkt_selector_for_bit_x_field_name[
  12082                     *ctr_current_bit_selector_position],
  12083                    ctr_pkt_attr_bit_position+field_index[index]);
  12084          /*ctr_pkt_attr_bit_position+index); */
  12085          (*ctr_current_bit_selector_position) +=1;
  12086     }
  12087     return BCM_E_NONE;
  12088 }
  12089 /*
  12090  * Function:
  12091  *      _bcm_esw_stat_flex_egress_reserve_mode
  12092  * Description:
  12093  *      Reserve flex egress mode
  12094  * Parameters:
  12095  *      unit                  - (IN) unit number
  12096  *      mode                  - (IN) Flex Offset Mode
  12097  *      total_counters        - (IN) Flex Total Counters for given mode
  12098  *      egr_attr              - (IN) Flex Egress Attributes
  12099  * Return Value:
  12100  *      BCM_E_XXX
  12101  * Notes:
  12102  */
  12103 bcm_error_t _bcm_esw_stat_flex_egress_reserve_mode(
  12104             int                      unit,
  12105             bcm_stat_flex_mode_t     mode,
  12106             uint32                   total_counters,
  12107             bcm_stat_flex_egr_attr_t *egr_attr)
  12108 {
  12109     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  12110         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12111                   (BSL_META_U(unit,
  12112                               "Invalid flex counter mode value %d \n"),
  12113                    mode));
  12114         return BCM_E_PARAM;
  12115     }
  12116     flex_egress_modes[unit][mode].available=1;
  12117     flex_egress_modes[unit][mode].total_counters=total_counters;
  12118     flex_egress_modes[unit][mode].egr_attr=*egr_attr;
  12119     flex_egress_modes[unit][mode].flags |= BCM_STAT_GROUP_MODE_EGRESS;
  12120     return BCM_E_NONE;
  12121 }
  12122 /*
  12123  * Function:
  12124  *      _bcm_esw_stat_flex_ingress_reserve_mode
  12125  * Description:
  12126  *      Reserve flex ingress mode
  12127  * Parameters:
  12128  *      unit                  - (IN) unit number
  12129  *      mode                  - (IN) Flex Offset Mode
  12130  *      total_counters        - (IN) Flex Total Counters for given mode
  12131  *      ing_attr              - (IN) Flex Ingress Attributes
  12132  * Return Value:
  12133  *      BCM_E_XXX
  12134  * Notes:
  12135  */
  12136 bcm_error_t _bcm_esw_stat_flex_ingress_reserve_mode(
  12137             int                      unit,
  12138             bcm_stat_flex_mode_t     mode,
  12139             uint32                   total_counters,
  12140             bcm_stat_flex_ing_attr_t *ing_attr)
  12141 {
  12142     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  12143         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12144                   (BSL_META_U(unit,
  12145                               "Invalid flex counter mode value %d \n"),
  12146                    mode));
  12147         return BCM_E_PARAM;
  12148     }
  12149     flex_ingress_modes[unit][mode].available=1;
  12150     flex_ingress_modes[unit][mode].total_counters=total_counters;
  12151     flex_ingress_modes[unit][mode].ing_attr=*ing_attr;
  12152         flex_ingress_modes[unit][mode].flags |= BCM_STAT_GROUP_MODE_INGRESS;
  12153     return BCM_E_NONE;
  12154 }
  12155 
  12156 /*
  12157  * Function:
  12158  *      _bcm_esw_stat_flex_unreserve_flags
  12159  * Description:
  12160  *      UnReserve flex (ingress/egress) flags
  12161  * Parameters:
  12162  *      unit                  - (IN) unit number
  12163  *      direction             - (IN) Flex Data Flow Direction
  12164  *      mode                  - (IN) Flex Offset Mode
  12165  *      flags                 - (IN) Flags
  12166  * Return Value:
  12167  *      BCM_E_XXX
  12168  * Notes:
  12169  */
  12170 bcm_error_t _bcm_esw_stat_flex_unreserve_flags(
  12171             int                       unit, 
  12172             bcm_stat_flex_mode_t      mode,
  12173             uint32                    flags)
  12174 {
  12175     if (flags & BCM_STAT_GROUP_MODE_CAPABILITY_OAM) {
  12176         flex_ingress_modes[unit][mode].oam_flags = 0;
  12177     } else {
  12178         flex_ingress_modes[unit][mode].flags = 0;
  12179     }
  12180     return BCM_E_NONE;
  12181 }
  12182 
  12183 /*
  12184  * Function:
  12185  *      _bcm_esw_stat_flex_unreserve_mode
  12186  * Description:
  12187  *      UnReserve flex (ingress/egress) mode
  12188  * Parameters:
  12189  *      unit                  - (IN) unit number
  12190  *      direction             - (IN) Flex Data Flow Direction
  12191  *      mode                  - (IN) Flex Offset Mode
  12192  * Return Value:
  12193  *      BCM_E_XXX
  12194  * Notes:
  12195  */
  12196 bcm_error_t _bcm_esw_stat_flex_unreserve_mode(
  12197             int                       unit,
  12198             bcm_stat_flex_direction_t direction,
  12199             bcm_stat_flex_mode_t      mode)
  12200 {
  12201     uint32                                    index=0;
  12202     bcm_stat_flex_packet_attr_type_t          packet_attr_type;
  12203     bcm_stat_flex_ing_cmprsd_attr_selectors_t *ing_cmprsd_attr_selectors= NULL;
  12204     bcm_stat_flex_ing_pkt_attr_bits_t         ing_pkt_attr_bits={0};
  12205     bcm_stat_flex_egr_cmprsd_attr_selectors_t *egr_cmprsd_attr_selectors= NULL;
  12206     bcm_stat_flex_egr_pkt_attr_bits_t         egr_pkt_attr_bits={0};
  12207     uint32                                    zero=0;
  12208     uint64                                    pkt_attr_selector_key_reg_value;
  12209     uint32 num_pools[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  12210     uint8 counter_group_num = BCM_STAT_DEF_FLEX_COUNTER_MAX_GROUPS;
  12211 
  12212     COMPILER_64_ZERO(pkt_attr_selector_key_reg_value);
  12213 
  12214     num_pools[bcmStatFlexDirectionIngress] = SOC_INFO(unit).
  12215                                              num_flex_ingress_pools;
  12216     num_pools[bcmStatFlexDirectionEgress] = SOC_INFO(unit).
  12217                                              num_flex_egress_pools;
  12218 
  12219     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  12220         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12221                   (BSL_META_U(unit,
  12222                               "Invalid flex counter mode value %d \n"),
  12223                    mode));
  12224         return BCM_E_PARAM;
  12225     }
  12226     switch(direction) {
  12227     case bcmStatFlexDirectionIngress:
  12228          if (flex_ingress_modes[unit][mode].available == 0) {
  12229              LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12230                        (BSL_META_U(unit,
  12231                                    "flex counter mode %d not configured yet\n"),
  12232                         mode));
  12233              return BCM_E_NOT_FOUND;
  12234          }
  12235          if (flex_ingress_modes[unit][mode].reference_count != 0) {
  12236              /* not an error in case two or more counters are created before
  12237               * deleting one.
  12238               */
  12239              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12240                        (BSL_META_U(unit,
  12241                                    "FlexCounterMode:%d:IsBeingUsed.ReferenceCount:%d:\n"),
  12242                         mode,flex_ingress_modes[unit][mode].reference_count));
  12243              return BCM_E_BUSY;
  12244          } else {
  12245                 if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
  12246                    if (_bcm_esw_stat_flex_delete_ingress_flags(
  12247                                   unit, mode,
  12248                                   BCM_STAT_GROUP_MODE_INGRESS) != BCM_E_NONE) {
  12249                        return BCM_E_INTERNAL;
  12250                    }
  12251                }
  12252          }
  12253 
  12254          if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
  12255              if (flex_ingress_modes[unit][mode].flags  ||
  12256                  flex_ingress_modes[unit][mode].oam_flags) {
  12257                  /* Delete the mode only if no flags exist.
  12258                   */
  12259                  LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12260                            (BSL_META_U(unit,
  12261                                        "FlexCounterMode:%d:IsBeingUsed.Flags:%d::IsBeingUsed.OamFlags:%d\n"),
  12262                                         mode,flex_ingress_modes[unit][mode].flags,
  12263                                         flex_ingress_modes[unit][mode].oam_flags));
  12264                  return BCM_E_EXISTS;
  12265              }
  12266          } 
  12267          /* Step2:  Reset selector keys */
  12268 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12269         if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) {
  12270             counter_group_num = BCM_STAT_TR3_FLEX_COUNTER_MAX_GROUPS;
  12271         }
  12272 #endif
  12273 #ifdef BCM_TOMAHAWK_SUPPORT
  12274         if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
  12275             counter_group_num = BCM_STAT_TH_FLEX_COUNTER_MAX_GROUPS;
  12276         }
  12277 #endif
  12278 #ifdef BCM_METROLITE_SUPPORT
  12279         if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  12280             counter_group_num = BCM_STAT_DEF_FLEX_COUNTER_MAX_GROUPS;
  12281         }
  12282 #endif
  12283 #ifdef BCM_TRIDENT2_SUPPORT
  12284         if (SOC_IS_TRIDENT2(unit)) {
  12285             counter_group_num = BCM_STAT_TD2_FLEX_COUNTER_MAX_GROUPS;
  12286         }
  12287 #endif
  12288 #ifdef BCM_APACHE_SUPPORT
  12289         if (SOC_IS_APACHE(unit)) {
  12290             counter_group_num = BCM_STAT_AP_FLEX_COUNTER_MAX_GROUPS;
  12291         }
  12292 #endif
  12293         for ( index = 0; index < counter_group_num; index++) {
  12294             SOC_IF_ERROR_RETURN(soc_reg_set(
  12295                         unit,
  12296                         _pkt_selector_key_reg[bcmStatFlexDirectionIngress]
  12297                         [mode + index*BCM_STAT_FLEX_COUNTER_MAX_MODE],
  12298                         REG_PORT_ANY,
  12299                         0,
  12300                         pkt_attr_selector_key_reg_value));
  12301         }
  12302 
  12303          /* Step3: Reset Offset table filling */
  12304          for (index=0;index<num_pools[bcmStatFlexDirectionIngress]; index++) {
  12305               BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_update_offset_table(
  12306                                   unit,
  12307                                   bcmStatFlexDirectionIngress,
  12308                                   _ctr_offset_table
  12309                                     [bcmStatFlexDirectionIngress][index],
  12310                                   mode,
  12311                                   0,
  12312                                   NULL));
  12313          }
  12314          /* Step4: Cleanup based on mode */
  12315          packet_attr_type= flex_ingress_modes[unit][mode].
  12316                             ing_attr.packet_attr_type;
  12317          switch(packet_attr_type) {
  12318          case bcmStatFlexPacketAttrTypeUncompressed:
  12319               LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12320                         (BSL_META_U(unit,
  12321                                     "\n Unreserving Ingress uncmprsd mode \n")));
  12322               break;
  12323          case bcmStatFlexPacketAttrTypeUdf:
  12324               LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12325                         (BSL_META_U(unit,
  12326                                     "\n Unreserving Ingress udf mode \n")));
  12327               break;
  12328          case bcmStatFlexPacketAttrTypeCompressed:
  12329               ing_cmprsd_attr_selectors= &(flex_ingress_modes[unit][mode].
  12330                                            ing_attr.cmprsd_attr_selectors);
  12331               ing_pkt_attr_bits=ing_cmprsd_attr_selectors->pkt_attr_bits;
  12332               zero=0;
  12333 
  12334               LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12335                         (BSL_META_U(unit,
  12336                                     "\n Unreserving Ingress cmprsd mode \n")));
  12337 
  12338               /* Step3: Cleanup map array */
  12339               if (soc_feature(unit, soc_feature_flex_stat_compression_share)) {
  12340                   /* update compression tables refrence counts */
  12341                   if(_bcm_stat_flex_compressed_attr_tbl_clear(unit,
  12342                               direction,
  12343                               ing_cmprsd_attr_selectors,NULL) != BCM_E_NONE) {
  12344                       return BCM_E_FAIL;
  12345                   }
  12346               } else {
  12347                   if ((ing_pkt_attr_bits.cng != 0) ||
  12348                           (ing_pkt_attr_bits.ifp_cng)  ||
  12349                           (ing_pkt_attr_bits.int_pri)) {
  12350                       for (index=0;
  12351                               index< soc_mem_index_count(unit,ING_FLEX_CTR_PRI_CNG_MAPm);
  12352                               index++) {
  12353                           soc_mem_write(unit,ING_FLEX_CTR_PRI_CNG_MAPm,
  12354                                   MEM_BLOCK_ALL, index, &zero);
  12355                       }
  12356                   }
  12357                   if ((ing_pkt_attr_bits.vlan_format != 0) ||
  12358                           (ing_pkt_attr_bits.outer_dot1p) ||
  12359                           (ing_pkt_attr_bits.inner_dot1p)) {
  12360                       for (index=0;
  12361                               index< soc_mem_index_count(unit,ING_FLEX_CTR_PKT_PRI_MAPm);
  12362                               index++) {
  12363                           soc_mem_write(unit, ING_FLEX_CTR_PKT_PRI_MAPm,
  12364                                   MEM_BLOCK_ALL, index, &zero);
  12365                       }
  12366                   }
  12367                   if (ing_pkt_attr_bits.ing_port != 0) {
  12368                       for (index=0;
  12369                               index< soc_mem_index_count(unit,ING_FLEX_CTR_PORT_MAPm);
  12370                               index++) {
  12371                           soc_mem_write(unit, ING_FLEX_CTR_PORT_MAPm,
  12372                                   MEM_BLOCK_ALL, index, &zero);
  12373                       }
  12374                   }
  12375                   if ((ing_pkt_attr_bits.tos_dscp != 0) ||
  12376                           (ing_pkt_attr_bits.tos_ecn != 0)) {
  12377                       for (index=0;
  12378                               index< soc_mem_index_count(unit,ING_FLEX_CTR_TOS_MAPm);
  12379                               index++) {
  12380                           soc_mem_write(unit, ING_FLEX_CTR_TOS_MAPm,
  12381                                   MEM_BLOCK_ALL, index, &zero);
  12382                       }
  12383                   }
  12384                   if ((ing_pkt_attr_bits.pkt_resolution != 0) ||
  12385                           (ing_pkt_attr_bits.svp_type) ||
  12386                           (ing_pkt_attr_bits.drop)) {
  12387                       for (index=0;
  12388                               index< soc_mem_index_count(unit,ING_FLEX_CTR_PKT_RES_MAPm);
  12389                               index++) {
  12390                           soc_mem_write(unit, ING_FLEX_CTR_PKT_RES_MAPm,
  12391                                   MEM_BLOCK_ALL, index, &zero);
  12392                       }
  12393                   }
  12394               }
  12395               break;
  12396          }
  12397          flex_ingress_modes[unit][mode].available=0;
  12398          flex_ingress_modes[unit][mode].total_counters=0;
  12399          flex_ingress_modes[unit][mode].flags = 0;
  12400          if (flex_ingress_modes[unit][mode].attr_selectors  != NULL) {
  12401              sal_free(flex_ingress_modes[unit][mode].attr_selectors);
  12402              flex_ingress_modes[unit][mode].num_selectors = 0;
  12403              flex_ingress_modes[unit][mode].attr_selectors = NULL;
  12404              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12405                        (BSL_META_U(unit,
  12406                                    "Ingress: Freed Attr Selectors \n")));
  12407          }
  12408          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12409                    (BSL_META_U(unit,
  12410                                "\n Done \n")));
  12411          break;
  12412     case bcmStatFlexDirectionEgress:
  12413          if (flex_egress_modes[unit][mode].available==0) {
  12414              return BCM_E_NOT_FOUND;
  12415          }
  12416          if (flex_egress_modes[unit][mode].reference_count != 0) {
  12417              return BCM_E_INTERNAL;
  12418          }
  12419 
  12420          /* Step2:  Reset selector keys */
  12421          SOC_IF_ERROR_RETURN(soc_reg_set(unit,
  12422                              _pkt_selector_key_reg[bcmStatFlexDirectionEgress]
  12423                                                   [mode],
  12424                              REG_PORT_ANY,
  12425                              0,
  12426                              pkt_attr_selector_key_reg_value));
  12427 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12428          if (!SOC_IS_METROLITE(unit) &&
  12429              (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit))) {
  12430              SOC_IF_ERROR_RETURN(soc_reg_set(unit,
  12431                                  _pkt_selector_key_reg[bcmStatFlexDirectionEgress]
  12432                                  [mode+BCM_STAT_FLEX_COUNTER_MAX_MODE],
  12433                                  REG_PORT_ANY,
  12434                                  0,
  12435                                  pkt_attr_selector_key_reg_value));
  12436           }
  12437 #endif
  12438          /* Step3: Reset Offset table filling */
  12439          for (index=0; index < num_pools[bcmStatFlexDirectionEgress]; index++) {
  12440               BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_update_offset_table(
  12441                                    unit,bcmStatFlexDirectionEgress,
  12442                                    _ctr_offset_table[bcmStatFlexDirectionEgress]
  12443                                                     [index],
  12444                                    mode,
  12445                                    0,
  12446                                    NULL));
  12447          }
  12448          /* Step4: Cleanup based on mode */
  12449          packet_attr_type = flex_egress_modes[unit][mode].egr_attr.
  12450                             packet_attr_type;
  12451          switch(packet_attr_type) {
  12452          case bcmStatFlexPacketAttrTypeUncompressed:
  12453               LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12454                         (BSL_META_U(unit,
  12455                                     "\nUnreserving Egress uncmprsd mode \n")));
  12456               break;
  12457          case bcmStatFlexPacketAttrTypeUdf:
  12458               LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12459                         (BSL_META_U(unit,
  12460                                     "\n Unreserving Egress UDF mode \n")));
  12461               break;
  12462          case bcmStatFlexPacketAttrTypeCompressed:
  12463               egr_cmprsd_attr_selectors= &(flex_egress_modes[unit][mode].
  12464                                            egr_attr.cmprsd_attr_selectors);
  12465               egr_pkt_attr_bits= egr_cmprsd_attr_selectors->pkt_attr_bits;
  12466               LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12467                         (BSL_META_U(unit,
  12468                                     "\n Unreserving Egress cmprsd mode \n")));
  12469 
  12470               /* Step3: Cleanup map array */
  12471               /* update refrence count of compression tabels in egress direction */
  12472               if (soc_feature(unit, soc_feature_flex_stat_compression_share)) {
  12473                   /* update compression tables refrence counts */
  12474                   if(_bcm_stat_flex_compressed_attr_tbl_clear(unit,
  12475                               direction,NULL,
  12476                               egr_cmprsd_attr_selectors) != BCM_E_NONE) {
  12477                       return BCM_E_FAIL;
  12478                   }
  12479               } else {
  12480 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  12481                   if (soc_feature(unit, soc_feature_flex_stat_egr_queue_congestion_marked)) {
  12482                       if ((egr_pkt_attr_bits.mmu_cos != 0) ||
  12483                               (egr_pkt_attr_bits.uc_queueing)) {
  12484                           for(index = 0;
  12485                               index < soc_mem_index_count(unit, EGR_FLEX_CTR_COS_MAPm);
  12486                               index++) {
  12487                               soc_mem_write(unit, EGR_FLEX_CTR_COS_MAPm,
  12488                                       MEM_BLOCK_ALL, index, &zero);
  12489                           }
  12490                       }
  12491                   }
  12492 #endif
  12493                   if ((egr_pkt_attr_bits.cng != 0) ||
  12494                           (egr_pkt_attr_bits.int_pri)) {
  12495                       for(index=0;
  12496                               index< soc_mem_index_count(unit,EGR_FLEX_CTR_PRI_CNG_MAPm);
  12497                               index++) {
  12498                           soc_mem_write(unit, EGR_FLEX_CTR_PRI_CNG_MAPm,
  12499                                   MEM_BLOCK_ALL, index, &zero);
  12500                       }
  12501                   }
  12502                   if ((egr_pkt_attr_bits.vlan_format != 0) ||
  12503                           (egr_pkt_attr_bits.outer_dot1p) ||
  12504                           (egr_pkt_attr_bits.inner_dot1p)) {
  12505                       for(index=0;
  12506                               index< soc_mem_index_count(unit,EGR_FLEX_CTR_PKT_PRI_MAPm);
  12507                               index++) {
  12508                           soc_mem_write(unit, EGR_FLEX_CTR_PKT_PRI_MAPm,
  12509                                   MEM_BLOCK_ALL, index, &zero);
  12510                       }
  12511                   }
  12512                   if (egr_pkt_attr_bits.egr_port != 0) {
  12513                       for(index=0;
  12514                               index< soc_mem_index_count(unit,EGR_FLEX_CTR_PORT_MAPm);
  12515                               index++) {
  12516                           soc_mem_write(unit, EGR_FLEX_CTR_PORT_MAPm,
  12517                                   MEM_BLOCK_ALL, index, &zero);
  12518                       }
  12519                   }
  12520                   if ((egr_pkt_attr_bits.tos_dscp != 0) ||
  12521                           (egr_pkt_attr_bits.tos_ecn != 0)) {
  12522                       for(index=0;
  12523                               index< soc_mem_index_count(unit,EGR_FLEX_CTR_TOS_MAPm);
  12524                               index++) {
  12525                           soc_mem_write(
  12526                                   unit,
  12527                                   EGR_FLEX_CTR_TOS_MAPm,
  12528                                   MEM_BLOCK_ALL,
  12529                                   index,
  12530                                   &zero);
  12531                       }
  12532                   }
  12533                   if ((egr_pkt_attr_bits.pkt_resolution != 0) ||
  12534                           (egr_pkt_attr_bits.svp_type) ||
  12535                           (egr_pkt_attr_bits.dvp_type) ||
  12536                           (egr_pkt_attr_bits.drop)) {
  12537                       for(index=0;
  12538                               index< soc_mem_index_count(unit,EGR_FLEX_CTR_PKT_RES_MAPm);
  12539                               index++) {
  12540                           soc_mem_write(unit, EGR_FLEX_CTR_PKT_RES_MAPm,
  12541                                   MEM_BLOCK_ALL, index, &zero);
  12542                       }
  12543                   }
  12544                   /* update refrence count of compression tabels in egress direction */
  12545               }
  12546               break;
  12547          }
  12548          flex_egress_modes[unit][mode].available=0;
  12549          flex_egress_modes[unit][mode].total_counters=0;
  12550          if (flex_egress_modes[unit][mode].attr_selectors  != NULL) {
  12551              sal_free(flex_egress_modes[unit][mode].attr_selectors);
  12552              flex_egress_modes[unit][mode].flags = 0;
  12553              flex_egress_modes[unit][mode].num_selectors = 0;
  12554              flex_egress_modes[unit][mode].attr_selectors = NULL;
  12555              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12556                        (BSL_META_U(unit,
  12557                                    "Egress: Freed Attr Selectors \n")));
  12558          }
  12559          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12560                    (BSL_META_U(unit,
  12561                                "\n Done \n")));
  12562          break;
  12563     default:
  12564          return BCM_E_PARAM;
  12565     }
  12566     return BCM_E_NONE;
  12567 }
  12568 bcm_error_t _bcm_esw_stat_flex_update_ingress_flex_info(
  12569             int                                 unit,
  12570             bcm_stat_flex_mode_t                mode,
  12571             uint32                              flags,
  12572             uint32                              num_selectors,
  12573             bcm_stat_group_mode_attr_selector_t *attr_selectors)
  12574 {
  12575     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  12576         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12577                   (BSL_META_U(unit,
  12578                               "Invalid flex counter mode value %d \n"),
  12579                    mode));
  12580         return BCM_E_PARAM;
  12581     }
  12582     if (flex_ingress_modes[unit][mode].available==0) {
  12583         return BCM_E_NOT_FOUND;
  12584     }
  12585     flex_ingress_modes[unit][mode].flags = flags;
  12586     if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
  12587         if (flags & BCM_STAT_GROUP_MODE_CAPABILITY_OAM) {
  12588             flex_ingress_modes[unit][mode].oam_flags = flags;
  12589         }
  12590     }   
  12591     if ((NULL == flex_ingress_modes[unit][mode].attr_selectors) &&
  12592          (flex_ingress_modes[unit][mode].attr_selectors =
  12593          sal_alloc(num_selectors*sizeof(bcm_stat_group_mode_attr_selector_t),
  12594                   "attr_selectors")) == NULL) {
  12595          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12596                    (BSL_META_U(unit,
  12597                                "Memory allocation failed \n")));
  12598          return BCM_E_MEMORY;
  12599     }
  12600     flex_ingress_modes[unit][mode].num_selectors = num_selectors;
  12601 
  12602     sal_memset(flex_ingress_modes[unit][mode].attr_selectors, 0,
  12603                num_selectors * sizeof(bcm_stat_group_mode_attr_selector_t));
  12604     sal_memcpy(flex_ingress_modes[unit][mode].attr_selectors,
  12605                attr_selectors,
  12606                num_selectors * sizeof(bcm_stat_group_mode_attr_selector_t));
  12607     return BCM_E_NONE;
  12608 }
  12609 bcm_error_t _bcm_esw_stat_flex_update_egress_flex_info(
  12610             int                                 unit,
  12611             bcm_stat_flex_mode_t                mode,
  12612             uint32                              flags,
  12613             uint32                              num_selectors,
  12614             bcm_stat_group_mode_attr_selector_t *attr_selectors)
  12615 {
  12616     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  12617         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12618                   (BSL_META_U(unit,
  12619                               "Invalid flex counter mode value %d \n"),
  12620                    mode));
  12621         return BCM_E_PARAM;
  12622     }
  12623     if (flex_egress_modes[unit][mode].available==0) {
  12624         return BCM_E_NOT_FOUND;
  12625     }
  12626     flex_egress_modes[unit][mode].flags = flags;
  12627     flex_egress_modes[unit][mode].num_selectors = num_selectors;
  12628     if ((flex_egress_modes[unit][mode].attr_selectors =
  12629          sal_alloc(num_selectors*sizeof(bcm_stat_group_mode_attr_selector_t),
  12630                   "attr_selectors")) == NULL) {
  12631          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12632                    (BSL_META_U(unit,
  12633                                "Memory allocation failed \n")));
  12634          return BCM_E_MEMORY;
  12635     }
  12636     sal_memset(flex_egress_modes[unit][mode].attr_selectors, 0,
  12637                num_selectors * sizeof(bcm_stat_group_mode_attr_selector_t));
  12638     sal_memcpy(flex_egress_modes[unit][mode].attr_selectors,
  12639                attr_selectors,
  12640                num_selectors * sizeof(bcm_stat_group_mode_attr_selector_t));
  12641     return BCM_E_NONE;
  12642 }
  12643 
  12644 /*
  12645  * Function:
  12646  *      _bcm_esw_stat_flex_get_ingress_mode_info
  12647  * Description:
  12648  *      Get Ingress Mode related information
  12649  * Parameters:
  12650  *      unit                  - (IN) unit number
  12651  *      mode                  - (IN) Flex Offset Mode
  12652  *      flex_ingress_mode     - (OUT) Flex Ingress Mode Info
  12653  * Return Value:
  12654  *      BCM_E_XXX
  12655  * Notes:
  12656  */
  12657 bcm_error_t _bcm_esw_stat_flex_get_ingress_mode_info(
  12658             int                          unit,
  12659             bcm_stat_flex_mode_t         mode,
  12660             bcm_stat_flex_ingress_mode_t *flex_ingress_mode)
  12661 {
  12662     if (mode <= (BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE-1) &&
  12663        (mode >= BCM_CUSTOM_INGRESS_MODE_START)) {
  12664         mode = flex_custom_ingress_modes[unit][mode - BCM_CUSTOM_INGRESS_MODE_START].offset_mode;
  12665     } else if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  12666         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12667                   (BSL_META_U(unit,
  12668                               "Invalid flex counter mode value %d \n"),
  12669                    mode));
  12670         return BCM_E_PARAM;
  12671     }
  12672     if (flex_ingress_modes[unit][mode].available==0) {
  12673         return BCM_E_NOT_FOUND;
  12674     }
  12675     *flex_ingress_mode= flex_ingress_modes[unit][mode];
  12676     return BCM_E_NONE;
  12677 }
  12678 
  12679 
  12680 #if defined (BCM_TOMAHAWK_SUPPORT)
  12681 
  12682 bcm_error_t _bcm_esw_custom_stat_group_id_retrieve(
  12683     int unit,
  12684     uint32 offset_mode,
  12685     int  pipe,
  12686     uint8  pool,
  12687     uint32 base_idx,
  12688     uint32 *stat_ctr_id)
  12689 {
  12690     
  12691     int mode = 0, i;
  12692     bcm_error_t rv=BCM_E_NOT_FOUND;
  12693     uint32 max_mode = BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE;
  12694 
  12695     *stat_ctr_id = 0;
  12696     if (!soc_feature(unit, soc_feature_flex_counter_opaque_stat_id)) {
  12697         return BCM_E_CONFIG;
  12698     }
  12699 #if defined(BCM_TRIDENT3_SUPPORT)
  12700     if(SOC_IS_TRIDENT3X(unit) ){
  12701         max_mode = BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE;
  12702     }
  12703 #endif
  12704 
  12705     for(i = 1; i < BCM_MAX_STAT_COUNTER_IDS; ++i) {
  12706         if (!(stat_counter_map[unit]) || (stat_counter_map[unit][i].mode >=
  12707                               max_mode) ||
  12708             (stat_counter_map[unit][i].mode < BCM_CUSTOM_INGRESS_MODE_START)) {
  12709             continue;
  12710         }
  12711         mode = stat_counter_map[unit][i].mode;
  12712 
  12713         if (offset_mode < BCM_CUSTOM_INGRESS_MODE_START) {
  12714 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  12715             if(mode >= BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE) {
  12716                 mode = mode - BCM_CUSTOM_EGRESS_MODE_START;
  12717                 mode = flex_custom_egress_modes[unit][mode].offset_mode;
  12718             } else
  12719 #endif
  12720             {
  12721                 mode = mode - BCM_CUSTOM_INGRESS_MODE_START;
  12722                 mode = flex_custom_ingress_modes[unit][mode].offset_mode;
  12723             }
  12724         }
  12725 
  12726         if (stat_counter_map[unit] && stat_counter_map[unit][i].used) {
  12727 
  12728             if ((mode == offset_mode) &&
  12729                 (stat_counter_map[unit][i].pool == pool) && 
  12730                 (stat_counter_map[unit][i].base_idx == base_idx)) {
  12731 
  12732                     if (pipe != stat_counter_map[unit][i].pipe) {
  12733                         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12734                                   (BSL_META_U(unit,
  12735                                               "pipes %d %d %x %x for stat ctr %x"),
  12736                                    pipe, stat_counter_map[unit][i].pipe, base_idx, pool, *stat_ctr_id));
  12737                         continue;
  12738                     }
  12739                 *stat_ctr_id = i;
  12740                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  12741                           (BSL_META_U(unit,
  12742                                       "reconstructed id for mode - %d, pool - %d"
  12743                                       " mode - %d, base idx - %d stat ctr %x"),
  12744                            mode, pool, offset_mode,
  12745                            base_idx, *stat_ctr_id));
  12746                 return BCM_E_NONE;
  12747             }
  12748             continue;
  12749         }
  12750     }
  12751 
  12752     return rv;
  12753 }
  12754 #endif
  12755 
  12756 /*
  12757  * Function:
  12758  *      _bcm_esw_stat_flex_get_ingress_mode_info
  12759  * Description:
  12760  *      Get Ingress Mode related information
  12761  * Parameters:
  12762  *      unit                  - (IN) unit number
  12763  *      mode                  - (IN) Flex Offset Mode
  12764  *      flex_ingress_mode     - (OUT) Flex Ingress Mode Info
  12765  * Return Value:
  12766  *      BCM_E_XXX
  12767  * Notes:
  12768  */
  12769 bcm_error_t _bcm_esw_stat_flex_get_custom_ingress_mode_info(
  12770             int                          unit,
  12771             bcm_stat_flex_mode_t         mode,
  12772             bcm_stat_flex_custom_ingress_mode_t *flex_ingress_mode)
  12773 {
  12774     if (mode > (BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE-1) ||
  12775        (mode <BCM_CUSTOM_INGRESS_MODE_START)) {
  12776         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12777                   (BSL_META_U(unit,
  12778                               "Invalid flex counter ingress mode value %d \n"),
  12779                    mode));
  12780         return BCM_E_PARAM;
  12781     }
  12782 
  12783     mode -= BCM_CUSTOM_INGRESS_MODE_START;
  12784 
  12785     *flex_ingress_mode= flex_custom_ingress_modes[unit][mode];
  12786     if (flex_custom_ingress_modes[unit][mode].used==0) {
  12787         return BCM_E_NOT_FOUND;
  12788     }
  12789     return BCM_E_NONE;
  12790 }
  12791 
  12792 /*
  12793  * Function:
  12794  *      _bcm_esw_stat_flex_get_ingress_mode_info
  12795  * Description:
  12796  *      Get Ingress Mode related information
  12797  * Parameters:
  12798  *      unit                  - (IN) unit number
  12799  *      mode                  - (IN) Flex Offset Mode
  12800  *      flex_ingress_mode     - (OUT) Flex Ingress Mode Info
  12801  * Return Value:
  12802  *      BCM_E_XXX
  12803  * Notes:
  12804  */
  12805 bcm_error_t _bcm_esw_stat_flex_update_custom_ingress_mode_info(
  12806             int                          unit,
  12807             bcm_stat_flex_mode_t         mode,
  12808             bcm_stat_flex_custom_ingress_mode_t *flex_ingress_mode)
  12809 {
  12810     if ((!flex_ingress_mode) || (mode > (BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE-1)) ||
  12811        (mode <BCM_CUSTOM_INGRESS_MODE_START)) {
  12812         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12813                   (BSL_META_U(unit,
  12814                               "Invalid flex counter ingress mode value %d \n"),
  12815                    mode));
  12816         return BCM_E_PARAM;
  12817     }
  12818 
  12819     mode -= BCM_CUSTOM_INGRESS_MODE_START;
  12820     flex_custom_ingress_modes[unit][mode] = *flex_ingress_mode;
  12821     return BCM_E_NONE;
  12822 }
  12823 
  12824 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  12825 /*
  12826  * Function:
  12827  *      _bcm_esw_stat_flex_get_custom_egress_mode_info
  12828  * Description:
  12829  *      Get Egress custom Mode related information
  12830  * Parameters:
  12831  *      unit                  - (IN) unit number
  12832  *      mode                  - (IN) Flex Offset Mode
  12833  *      flex_egress_mode     - (OUT) Flex Egress Mode Info
  12834  * Return Value:
  12835  *      BCM_E_XXX
  12836  * Notes:
  12837  */
  12838 bcm_error_t _bcm_esw_stat_flex_get_custom_egress_mode_info(
  12839             int                          unit,
  12840             bcm_stat_flex_mode_t         mode,
  12841             bcm_stat_flex_custom_egress_mode_t *flex_egress_mode)
  12842 {
  12843     if (mode > (BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE-1) ||
  12844        (mode < BCM_CUSTOM_EGRESS_MODE_START)) {
  12845         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12846                   (BSL_META_U(unit,
  12847                               "Invalid flex counter egress mode value %d \n"),
  12848                    mode));
  12849         return BCM_E_PARAM;
  12850     }
  12851     if(mode >= BCM_CUSTOM_EGRESS_MODE_START){
  12852         mode -= BCM_CUSTOM_EGRESS_MODE_START;
  12853     }
  12854 
  12855     *flex_egress_mode = flex_custom_egress_modes[unit][mode];
  12856     if (flex_custom_egress_modes[unit][mode].used == 0) {
  12857         return BCM_E_NOT_FOUND;
  12858     }
  12859     return BCM_E_NONE;
  12860 }
  12861 
  12862 /*
  12863  * Function:
  12864  *      _bcm_esw_stat_flex_update_custom_egress_mode_info
  12865  * Description:
  12866  *      Update Egress Mode related information
  12867  * Parameters:
  12868  *      unit                  - (IN) unit number
  12869  *      mode                  - (IN) Flex Offset Mode
  12870  *      flex_ingress_mode     - (OUT) Flex Egress Mode Info
  12871  * Return Value:
  12872  *      BCM_E_XXX
  12873  * Notes:
  12874  */
  12875 bcm_error_t _bcm_esw_stat_flex_update_custom_egress_mode_info(
  12876             int                          unit,
  12877             bcm_stat_flex_mode_t         mode,
  12878             bcm_stat_flex_custom_egress_mode_t *flex_egress_mode)
  12879 {
  12880     if ((!flex_egress_mode) || (mode > (BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE-1)) ||
  12881        (mode < BCM_CUSTOM_EGRESS_MODE_START)) {
  12882         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12883                   (BSL_META_U(unit,
  12884                               "Invalid flex counter egress mode value %d \n"),
  12885                    mode));
  12886         return BCM_E_PARAM;
  12887     }
  12888 
  12889     mode -= BCM_CUSTOM_EGRESS_MODE_START;
  12890     flex_custom_egress_modes[unit][mode] = *flex_egress_mode;
  12891     return BCM_E_NONE;
  12892 }
  12893 
  12894 #endif
  12895 
  12896 /*
  12897  * Function:
  12898  *      _bcm_esw_stat_flex_get_egress_mode_info
  12899  * Description:
  12900  *      Get Egress Mode related information
  12901  * Parameters:
  12902  *      unit                  - (IN) unit number
  12903  *      mode                  - (IN) Flex Offset Mode
  12904  *      flex_egress_mode      - (OUT) Flex Egress Mode Info
  12905  *
  12906  * Return Value:
  12907  *      BCM_E_XXX
  12908  * Notes:
  12909  */
  12910 bcm_error_t _bcm_esw_stat_flex_get_egress_mode_info(
  12911             int                         unit,
  12912             bcm_stat_flex_mode_t        mode,
  12913             bcm_stat_flex_egress_mode_t *flex_egress_mode)
  12914 {
  12915 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  12916     if (mode <= (BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE-1) &&
  12917         (mode >= BCM_CUSTOM_EGRESS_MODE_START)) {
  12918         mode = flex_custom_egress_modes[unit]
  12919                     [mode - BCM_CUSTOM_EGRESS_MODE_START].offset_mode;
  12920     }
  12921 #endif
  12922 
  12923     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  12924         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  12925                   (BSL_META_U(unit,
  12926                               "Invalid flex counter egress mode value %d \n"),
  12927                    mode));
  12928         return BCM_E_PARAM;
  12929     }
  12930     if (flex_egress_modes[unit][mode].available==0) {
  12931         return BCM_E_NOT_FOUND;
  12932     }
  12933     *flex_egress_mode = flex_egress_modes[unit][mode];
  12934     return BCM_E_NONE;
  12935 }
  12936 /*
  12937  * Function:
  12938  *      _bcm_esw_stat_flex_get_available_mode
  12939  * Description:
  12940  *      Get Free available Offset Mode
  12941  * Parameters:
  12942  *      unit                  - (IN) unit number
  12943  *      direction             - (IN) Flex Data Flow Direction
  12944  *      mode                  - (OUT) Flex Offset Mode
  12945  * Return Value:
  12946  *      BCM_E_XXX
  12947  * Notes:
  12948  */
  12949 bcm_error_t _bcm_esw_stat_flex_get_available_mode(
  12950             int                       unit,
  12951             bcm_stat_flex_direction_t direction,
  12952             bcm_stat_flex_mode_t      *mode)
  12953 {
  12954     uint32 mode_index=1;
  12955     switch(direction) {
  12956     case bcmStatFlexDirectionIngress:
  12957          for (mode_index=0;
  12958               mode_index < BCM_STAT_FLEX_COUNTER_MAX_MODE ;
  12959               mode_index++) {
  12960               if (flex_ingress_modes[unit][mode_index].available==0) {
  12961                   *mode=mode_index;
  12962                   return BCM_E_NONE;
  12963               }
  12964          }
  12965          break;
  12966     case bcmStatFlexDirectionEgress:
  12967          for (mode_index=0;
  12968               mode_index < BCM_STAT_FLEX_COUNTER_MAX_MODE ;
  12969               mode_index++) {
  12970               if (flex_egress_modes[unit][mode_index].available==0) {
  12971                   *mode=mode_index;
  12972                   return BCM_E_NONE;
  12973               }
  12974          }
  12975          break;
  12976     default:
  12977          return BCM_E_PARAM;
  12978     }
  12979     return BCM_E_FULL;
  12980 }
  12981 
  12982 #define BCM_TH_LOCAL_PIPE_MODE(_unit_, _pool_id_) \
  12983          ((!_bcm_esw_get_fp_mode_global(_unit_, bcmFieldQualifyStageIngress) &&   \
  12984                  (FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE ==                   \
  12985                            flex_pool_stat[_unit_][bcmStatFlexDirectionIngress]    \
  12986                                          [0][_pool_id_].used_by_tables)) ||       \
  12987          (!_bcm_esw_get_fp_mode_global(_unit_, bcmFieldQualifyStageLookup) &&     \
  12988                  (FLEX_COUNTER_POOL_USED_BY_VFP_POLICY_TABLE ==                   \
  12989                            flex_pool_stat[_unit_][bcmStatFlexDirectionIngress]    \
  12990                                          [0][_pool_id_].used_by_tables))     ||   \
  12991          (!_bcm_esw_get_fp_mode_global(_unit_, bcmFieldQualifyStageIngressExactMatch) && \
  12992                  (FLEX_COUNTER_POOL_USED_BY_EM_POLICY_TABLE ==                    \
  12993                            flex_pool_stat[_unit_][bcmStatFlexDirectionIngress]    \
  12994                                          [0][_pool_id_].used_by_tables)))
  12995    
  12996 
  12997 /*
  12998  * Function:
  12999  *      th_flex_counter_set
  13000  * Description:
  13001  *      Program the given value to the counter specified by the parameters
  13002  *      direction, pool_id and index in both software and hardware locations.
  13003  *      This function only applies to Tomahawk device.
  13004  * Parameters:
  13005  *      unit                  - (IN) unit number
  13006  *      direction             - (IN) ingress or egress
  13007  *      pool_id               - (IN) the flex counter table pool id
  13008  *      index                 - (IN) the flex counter table index
  13009  *      value                 - (IN) the given value
  13010  *
  13011  * Return Value:
  13012  *      BCM_E_XXX
  13013  * Notes:
  13014  */
  13015 
  13016 STATIC
  13017 int th_flex_counter_set(int unit, bcm_stat_flex_direction_t direction, int pipe_num,
  13018                       int pool_id, uint32 index, bcm_stat_value_t *value_array,
  13019                       int num_entries,  int byte_flag)
  13020 {
  13021 #ifdef BCM_TOMAHAWK_SUPPORT
  13022     soc_mem_t mem;
  13023     int mem_id;
  13024     int pipe;
  13025     soc_control_t *soc;
  13026     soc_counter_evict_t *evict;
  13027     uint32 evt_pkt_base;
  13028     uint32 evt_byte_base;
  13029     int cnt;
  13030     uint32                    hw_val[2];
  13031     uint32                    max_packet_mask=0;
  13032     uint64                    max_byte_mask;
  13033     uint32                    zero=0;
  13034     uint32                    one=1;
  13035     bcm_stat_value_t value;
  13036     bcm_stat_value_t *value_ptr;
  13037     uint32                    hw_val_zero[2] = {0,0};
  13038     bcm_stat_value_t value_zero;
  13039     int pipe_local_mode  = 0;
  13040 
  13041 #if defined(BCM_TOMAHAWK_SUPPORT) && defined (INCLUDE_FLOWTRACKER)
  13042     if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
  13043          soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
  13044          soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
  13045         if (_bcm_esw_stat_pool_reserved(unit, direction, pool_id)) {
  13046             return BCM_E_NONE;
  13047         }
  13048     }
  13049 #endif
  13050 
  13051     if (soc_feature(unit, soc_feature_centralized_counter)) {
  13052         /* For Centralized Counter model, call the new function */
  13053         if (!BCM_TH_LOCAL_PIPE_MODE(unit, pool_id)) {
  13054             /* Pass pipe_num as -1 if in Global mode */
  13055             pipe_num = -1;
  13056         }
  13057         return th_flex_centralized_counter_set(unit, direction, pipe_num,
  13058                                                pool_id, index, value_array,
  13059                                                num_entries, byte_flag);
  13060     }
  13061 
  13062     if (num_entries < 1) {
  13063         return BCM_E_NONE;
  13064     }
  13065 
  13066     if ( (direction == bcmStatFlexDirectionIngress) &&
  13067            (BCM_TH_LOCAL_PIPE_MODE(unit, pool_id))) {
  13068         pipe_local_mode = 1;
  13069     }
  13070 
  13071     sal_memset(&value_zero,0,sizeof(bcm_stat_value_t));
  13072 
  13073     soc = SOC_CONTROL(unit);
  13074     if (direction == bcmStatFlexDirectionIngress) {
  13075         mem_id = pool_id + 1;
  13076     } else {
  13077         mem_id = pool_id + 1 + SOC_TH_STAT_ING_FLEX_POOL_MAX;
  13078     }
  13079     /* During unit detach, counter thread is shutdown prior to
  13080      * flexstat module being detached. Modules such as field that
  13081      * use flexstats call this function after counter thread is
  13082      * shutdown. In this scenario, evict is NULL. Check for this.
  13083      */
  13084     if (NULL == soc->counter_evict) {
  13085         return BCM_E_INTERNAL;
  13086     }
  13087     evict = &soc->counter_evict[mem_id];
  13088     mem = evict->mem[pipe_num];
  13089     COMPILER_64_SET(max_byte_mask, zero, one);
  13090     COMPILER_64_SHL(max_byte_mask,soc_mem_field_length(unit,mem,BYTE_COUNTERf));
  13091     COMPILER_64_SUB_32(max_byte_mask,one);
  13092 
  13093     max_packet_mask = (1 << soc_mem_field_length(unit,mem,PACKET_COUNTERf));
  13094     max_packet_mask -= 1;
  13095 
  13096     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  13097 
  13098     /* set the software copy */
  13099     /* Clear residual packet and byte counters in addition to flex database.
  13100      * When counter eviction is enabled, residual counters could be non-zero,
  13101      * hence if they are not cleared, counters in flex database will be incorrectly
  13102      * updated during the next polling cycle to include residuals from before
  13103      * the set operation was performed
  13104      */
  13105     for (cnt = 0; cnt < num_entries; cnt++) {
  13106         value_ptr = value_array == NULL? &value_zero: value_array+cnt;
  13107         /* byte_flag = 1  => Update byte counter only
  13108          * byte_flag = -1 => Update byte and packet counter
  13109          */
  13110         if (1 == byte_flag || -1 == byte_flag) {
  13111             COMPILER_64_SET(value.bytes,
  13112                             COMPILER_64_HI(value_ptr->bytes),
  13113                             COMPILER_64_LO(value_ptr->bytes)); 
  13114             COMPILER_64_SET(flex_byte_counter[unit][direction][pipe_num][pool_id]
  13115                                              [index + cnt],
  13116                             COMPILER_64_HI(value.bytes),
  13117                             COMPILER_64_LO(value.bytes));
  13118             COMPILER_64_ZERO(residual_byte_counter[unit][direction][pipe_num][pool_id]
  13119                                                   [index + cnt]);
  13120             /* Mask count value prior to writing hardware */
  13121             COMPILER_64_AND(value.bytes, max_byte_mask);
  13122         }
  13123         /* byte_flag = 0  => Update packet counter only
  13124          * byte_flag = -1 => Update byte and packet counter
  13125          */
  13126         if (0 == byte_flag || -1 == byte_flag) {
  13127             value.packets = value_ptr->packets; 
  13128             flex_packet_counter[unit][direction][pipe_num][pool_id]
  13129                                [index + cnt] = value.packets;
  13130             COMPILER_64_SET(flex_packet64_counter[unit][direction][pipe_num][pool_id]
  13131                                                  [index + cnt],0,
  13132                             value.packets);
  13133             COMPILER_64_ZERO(residual_packet_counter[unit][direction][pipe_num][pool_id]
  13134                                                     [index + cnt]);
  13135             /* Mask count value prior to writing hardware */
  13136             value.packets &= max_packet_mask;
  13137         }
  13138     }
  13139 
  13140     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
  13141          if (pipe_local_mode && (pipe != pipe_num)) {
  13142              continue;
  13143          }
  13144 
  13145          mem = evict->mem[pipe];
  13146 
  13147         if (num_entries > 1) {
  13148             if (soc_mem_read_range(unit,
  13149                                mem,
  13150                                MEM_BLOCK_ANY,
  13151                                index,
  13152                                index+num_entries-1,
  13153                           flex_temp_counter[unit][direction]) != BCM_E_NONE) {
  13154                 BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  13155                 return BCM_E_INTERNAL;
  13156             }
  13157         } else {
  13158             if (soc_mem_read( unit, mem, MEM_BLOCK_ANY, index,
  13159                     flex_temp_counter[unit][direction]) != BCM_E_NONE){
  13160                 BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  13161                 return BCM_E_INTERNAL;
  13162             }
  13163         }
  13164 
  13165         evt_pkt_base =
  13166            soc->counter_non_dma[evict->pkt_counter_id -
  13167               SOC_COUNTER_NON_DMA_START].base_index +
  13168                      evict->offset[pipe];
  13169 
  13170         evt_byte_base =
  13171            soc->counter_non_dma[evict->byte_counter_id -
  13172               SOC_COUNTER_NON_DMA_START].base_index +
  13173                           evict->offset[pipe];
  13174 
  13175         for (cnt = 0; cnt < num_entries; cnt++) {
  13176             value_ptr = value_array == NULL? &value_zero: value_array+cnt;
  13177             /* byte_flag = 0  => Update packet counter only
  13178              * byte_flag = -1 => Update byte and packet counter
  13179              */
  13180             if (1 == byte_flag || -1 == byte_flag) {
  13181                 COMPILER_64_ZERO(soc->counter_sw_val[evt_byte_base+index+cnt]);
  13182                 if ((pipe == 0) || pipe_local_mode) {
  13183                     /* Change Hw Copy */
  13184                     COMPILER_64_SET(value.bytes,
  13185                                     COMPILER_64_HI(value_ptr->bytes),
  13186                                     COMPILER_64_LO(value_ptr->bytes));
  13187                     COMPILER_64_AND(value.bytes, max_byte_mask);
  13188                     hw_val[0] = COMPILER_64_LO(value.bytes);
  13189                     hw_val[1] = COMPILER_64_HI(value.bytes);
  13190                     soc_mem_field_set(unit, mem,
  13191                         (uint32 *)&flex_temp_counter[unit][direction][cnt],
  13192                         BYTE_COUNTERf, hw_val);
  13193                 } else {
  13194                     soc_mem_field_set(unit, mem,
  13195                         (uint32 *)&flex_temp_counter[unit][direction][cnt],
  13196                         BYTE_COUNTERf, hw_val_zero);
  13197                 }
  13198             }
  13199             /* byte_flag = 0  => Update packet counter only
  13200              * byte_flag = -1 => Update byte and packet counter
  13201              */
  13202             if (0 == byte_flag || -1 == byte_flag) {
  13203                 COMPILER_64_ZERO(soc->counter_sw_val[evt_pkt_base+index+cnt]);
  13204                 if ((pipe == 0) || pipe_local_mode) {
  13205                     value.packets = value_ptr->packets;
  13206                     value.packets &= max_packet_mask;
  13207                     soc_mem_field_set(unit, mem,
  13208                         (uint32 *)&flex_temp_counter[unit][direction][cnt],
  13209                         PACKET_COUNTERf, &(value.packets));
  13210                 } else {
  13211                     soc_mem_field_set(unit, mem,
  13212                         (uint32 *)&flex_temp_counter[unit][direction][cnt],
  13213                         PACKET_COUNTERf, &hw_val_zero[0]);
  13214                 }
  13215             }
  13216         }
  13217         if (num_entries > 1) {
  13218             if (soc_mem_write_range(unit,mem,MEM_BLOCK_ALL,
  13219                     index,
  13220                     index+num_entries-1,
  13221                     flex_temp_counter[unit][direction]) != BCM_E_NONE) {
  13222                 BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  13223                 return BCM_E_INTERNAL;
  13224             }
  13225         } else {
  13226             if (soc_mem_write(unit,mem,MEM_BLOCK_ALL, index,
  13227                         flex_temp_counter[unit][direction]) != BCM_E_NONE){
  13228                 BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  13229                 return BCM_E_INTERNAL;
  13230             }
  13231         }
  13232     }
  13233     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  13234     return BCM_E_NONE;
  13235 #else
  13236     return BCM_E_UNAVAIL;
  13237 #endif
  13238 }
  13239 
  13240 /*
  13241  * Function:
  13242  *      th_flex_centralized_counter_set
  13243  * Description:
  13244  *      Program the given value to the counter specified by the parameters
  13245  *      direction, pool_id and index in both software and hardware locations.
  13246  *      This function only applies to Tomahawk device.
  13247  *
  13248  *      Note: In the centralized counter model, counters are set/get from
  13249  *      counter module using soc_counter_generic_get/_set api.
  13250  * Parameters:
  13251  *      unit                  - (IN) unit number
  13252  *      direction             - (IN) ingress or egress
  13253  *      pool_id               - (IN) the flex counter table pool id
  13254  *      index                 - (IN) the flex counter table index
  13255  *      value                 - (IN) the given value
  13256  *
  13257  * Return Value:
  13258  *      BCM_E_XXX
  13259  * Notes:
  13260  */
  13261 #ifdef BCM_TOMAHAWK_SUPPORT
  13262 STATIC
  13263 int th_flex_centralized_counter_set(int unit,
  13264                                     bcm_stat_flex_direction_t direction,
  13265                                     int pipe_num,
  13266                                     int pool_id, uint32 index,
  13267                                     bcm_stat_value_t *value_array,
  13268                                     int num_entries, int byte_flag)
  13269 {
  13270     soc_control_t *soc;
  13271     int cnt, rv;
  13272     bcm_stat_value_t value;
  13273     bcm_stat_value_t *value_ptr;
  13274     bcm_stat_value_t value_zero;
  13275     soc_counter_non_dma_id_t  pkt_ctr_id, byte_ctr_id;
  13276     soc_ctr_control_info_t ctrl_info[2], ctrl_info_out;
  13277 
  13278     if (num_entries < 1) {
  13279         return BCM_E_NONE;
  13280     }
  13281 
  13282     ctrl_info[0].instance_type = SOC_CTR_INSTANCE_TYPE_POOL;
  13283     ctrl_info[0].instance = pool_id;
  13284 
  13285     if (pipe_num == -1) {
  13286         ctrl_info_out = ctrl_info[0];
  13287     } else {
  13288         ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PIPE;
  13289         ctrl_info[1].instance = pipe_num;
  13290         soc_counter_instance_encode(ctrl_info, 2, &ctrl_info_out);
  13291     }
  13292 
  13293     if (direction == bcmStatFlexDirectionEgress) {
  13294         pkt_ctr_id = SOC_COUNTER_NON_DMA_EGR_FLEX_PKT;
  13295         byte_ctr_id = SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE;
  13296     } else {
  13297         pkt_ctr_id = SOC_COUNTER_NON_DMA_ING_FLEX_PKT;
  13298         byte_ctr_id = SOC_COUNTER_NON_DMA_ING_FLEX_BYTE;
  13299     }
  13300 
  13301     /* During unit detach, counter thread is shutdown prior to
  13302      * flexstat module being detached. Modules such as field that
  13303      * use flexstats call this function after counter thread is
  13304      * shutdown. In this scenario, evict is NULL. Check for this.
  13305      */
  13306     soc = SOC_CONTROL(unit);
  13307     if (NULL == soc->counter_evict) {
  13308         return BCM_E_INTERNAL;
  13309     }
  13310 
  13311     sal_memset(&value_zero, 0, sizeof(bcm_stat_value_t));
  13312     for (cnt = 0; cnt < num_entries; cnt++) {
  13313         value_ptr = value_array == NULL? &value_zero: value_array+cnt;
  13314 
  13315         if ((byte_flag == 1) || (byte_flag == -1)) { /* byte only */
  13316             COMPILER_64_SET(value.bytes, COMPILER_64_HI(value_ptr->bytes),
  13317                           COMPILER_64_LO(value_ptr->bytes));
  13318             rv = soc_counter_generic_set(unit, byte_ctr_id, ctrl_info_out,
  13319                                          0, index + cnt, value.bytes);
  13320             if (rv != SOC_E_NONE) {
  13321                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  13322                         (BSL_META_U(unit, "Unable to set byte counter values unit - %d,"
  13323                                            " pool - %d, counter index - %d cnt - %d\n"),
  13324                                    unit, pool_id, index, cnt));
  13325                 return BCM_E_FAIL;
  13326             }
  13327         }
  13328         if ((byte_flag == 0) || (byte_flag == -1)) { /* packet only */
  13329             uint64 temp64;
  13330             /* If packests64 is not zero, assuming packets64 is used to pass packet value */
  13331             if (COMPILER_64_IS_ZERO(value_ptr->packets64)) {
  13332                 COMPILER_64_SET(temp64, 0, value_ptr->packets);
  13333             } else {
  13334                 COMPILER_64_SET(temp64, COMPILER_64_HI(value_ptr->packets64),
  13335                     COMPILER_64_LO(value_ptr->packets64));
  13336             }
  13337             rv = soc_counter_generic_set(unit, pkt_ctr_id, ctrl_info_out,
  13338                                          0, index + cnt, temp64);
  13339             if (rv != SOC_E_NONE) {
  13340                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  13341                 (BSL_META_U(unit, "Unable to set packet counter values unit - %d,"
  13342                                       " pool - %d, counter index - %d cnt - %d\n"),
  13343                                unit, pool_id, index, cnt ));
  13344                 return BCM_E_FAIL;
  13345             }
  13346         }
  13347     }
  13348 
  13349     return BCM_E_NONE;
  13350 }
  13351 #endif
  13352 
  13353 /*
  13354  * Function:
  13355  *      _bcm_esw_stat_counter_set
  13356  * Description:
  13357  *      Set Flex Counter Values
  13358  * Parameters:
  13359  *      unit                  - (IN) unit number
  13360  *      index                 - (IN) Flex Accounting Table Index
  13361  *      table                 - (IN) Flex Accounting Table
  13362  *      byte_flag             - (IN) Byte/Packet Flag
  13363  *      counter               - (IN) Counter Index
  13364  *      values                - (IN) Counter Value
  13365  * Return Value:
  13366  *      BCM_E_XXX
  13367  * Notes:
  13368  */
  13369 bcm_error_t _bcm_esw_stat_counter_set(
  13370             int              unit,
  13371             uint32           index,
  13372             soc_mem_t        table,
  13373             bcm_stat_object_t object,
  13374             uint32           byte_flag,
  13375             uint32           counter_index,
  13376             bcm_stat_value_t *value)
  13377 {
  13378     soc_mem_t                 mem;
  13379 #if defined(BCM_TRIDENT2_SUPPORT)
  13380     soc_mem_t                 mem_dual = 0;
  13381     int                       buffer_id = 0;
  13382 #endif /* BCM_TRIDENT2_SUPPORT*/
  13383     uint32                    offset_mode=0;
  13384     int                       pool_number=0;
  13385     uint32                    base_idx=0;
  13386     bcm_stat_flex_direction_t direction = bcmStatFlexDirectionIngress;
  13387     uint32                    total_entries=0;
  13388     uint32                    offset_index=0;
  13389     uint32                    zero=0;
  13390     uint32                    one=1;
  13391     uint32                    entry_data_size=0;
  13392     void                      *entry_data=NULL;
  13393     uint32                    max_packet_mask=0;
  13394     uint64                    max_byte_mask;
  13395     uint32                    hw_val[2];
  13396     int                       pipe_num = 0;
  13397     uint32                    exact_index=0;
  13398 
  13399     COMPILER_64_ZERO(max_byte_mask);
  13400     exact_index = index;
  13401 
  13402     switch(table) {
  13403     case PORT_TABm:
  13404     case VLAN_XLATEm:
  13405 #if defined(BCM_TRIUMPH3_SUPPORT)
  13406     case VLAN_XLATE_EXTDm:
  13407     case MPLS_ENTRY_EXTDm:
  13408     case L3_TUNNELm:
  13409     case L3_ENTRY_2m:
  13410     case L3_ENTRY_4m:
  13411     case EXT_IPV4_UCAST_WIDEm:
  13412     case EXT_IPV6_128_UCAST_WIDEm:
  13413     case EXT_FP_POLICYm:
  13414 #endif
  13415 #if defined(BCM_TRIDENT2_SUPPORT)
  13416     case ING_VSANm:
  13417     case L3_ENTRY_IPV4_MULTICASTm:
  13418     case L3_ENTRY_IPV6_MULTICASTm:
  13419     case L3_DEFIPm:
  13420     case L3_DEFIP_PAIR_128m:
  13421     case L3_DEFIP_LEVEL1m:
  13422     case L3_DEFIP_PAIR_LEVEL1m:
  13423     case L3_DEFIP_ALPM_LEVEL2m:
  13424     case L3_DEFIP_ALPM_LEVEL3m:
  13425     case L3_DEFIP_ALPM_RAWm:
  13426     case L3_DEFIP_ALPM_IPV4_1m:
  13427     case L3_DEFIP_ALPM_IPV6_64_1m:
  13428     case L3_DEFIP_ALPM_IPV6_128m:
  13429 #endif
  13430     case VFP_POLICY_TABLEm:
  13431 #if defined (BCM_TOMAHAWK_SUPPORT)
  13432     case VFP_POLICY_TABLE_PIPE0m:
  13433     case VFP_POLICY_TABLE_PIPE1m:
  13434     case VFP_POLICY_TABLE_PIPE2m:
  13435     /* coverity[UNTERMINATED_CASE] */
  13436     case VFP_POLICY_TABLE_PIPE3m:
  13437     case VFP_POLICY_TABLE_PIPE4m:
  13438     case VFP_POLICY_TABLE_PIPE5m:
  13439     case VFP_POLICY_TABLE_PIPE6m:
  13440     case VFP_POLICY_TABLE_PIPE7m:
  13441          pipe_num = _bcm_esw_get_fp_pipe_num(unit, table);
  13442 #endif
  13443     /* coverity[FALLTHROUGH] */
  13444     case MPLS_ENTRYm:
  13445 #if defined(BCM_TOMAHAWK3_SUPPORT)
  13446     case MPLS_ENTRY_SINGLEm:
  13447 #endif
  13448     case SOURCE_VPm:
  13449     case L3_IIFm:
  13450     case VRFm:
  13451     case VFIm:
  13452     case VLAN_TABm:
  13453 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  13454     case LPORT_TABm:
  13455     case L3_ENTRY_QUADm:
  13456     case L3_ENTRY_DOUBLEm:
  13457 #endif
  13458 #if defined (BCM_TRIDENT3_SUPPORT)
  13459     case VLAN_XLATE_1_DOUBLEm:
  13460     case VLAN_XLATE_2_DOUBLEm:
  13461     case VRF_ATTRS_2m:
  13462 #endif
  13463          direction= bcmStatFlexDirectionIngress;
  13464          break;
  13465     case EGR_VLANm:
  13466     case EGR_VFIm:
  13467     case EGR_L3_NEXT_HOPm:
  13468     case EGR_VLAN_XLATEm:
  13469     case EGR_PORTm:
  13470 #if defined(BCM_TRIUMPH3_SUPPORT)
  13471     case EGR_DVP_ATTRIBUTE_1m:
  13472 #endif
  13473 #if defined(BCM_TRIDENT2_SUPPORT)
  13474     case EGR_NAT_PACKET_EDIT_INFOm:
  13475 #endif
  13476 #if defined (BCM_TRIDENT3_SUPPORT)
  13477     case EGR_DVP_ATTRIBUTEm:
  13478     case EGR_VLAN_XLATE_1_DOUBLEm:
  13479     case EGR_VLAN_XLATE_2_DOUBLEm:
  13480     case EGR_LPORT_PROFILEm:
  13481 #endif
  13482          direction= bcmStatFlexDirectionEgress;
  13483          break;
  13484     case EGR_IP_TUNNEL_MPLSm:
  13485          direction= bcmStatFlexDirectionEgress;
  13486          index = index / _BCM_MPLS_NUM_MPLS_ENTRIES_PER_INDEX(unit);
  13487          break;
  13488 #if defined (BCM_TRIDENT3_SUPPORT)
  13489     case EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm:
  13490          direction = bcmStatFlexDirectionEgress;
  13491          index = index / _BCM_MPLS_NUM_MPLS_ENTRIES_PER_INDEX(unit);
  13492          break;
  13493 #endif
  13494     case IFP_POLICY_TABLEm:
  13495 #if defined (BCM_TOMAHAWK_SUPPORT)
  13496     case IFP_POLICY_TABLE_PIPE0m:
  13497     case IFP_POLICY_TABLE_PIPE1m:
  13498     case IFP_POLICY_TABLE_PIPE2m:
  13499     case IFP_POLICY_TABLE_PIPE3m:
  13500     case IFP_POLICY_TABLE_PIPE4m:
  13501     case IFP_POLICY_TABLE_PIPE5m:
  13502     case IFP_POLICY_TABLE_PIPE6m:
  13503     case IFP_POLICY_TABLE_PIPE7m:
  13504          pipe_num = _bcm_esw_get_fp_pipe_num(unit, table);
  13505 #endif
  13506          direction= bcmStatFlexDirectionIngress;
  13507          break;
  13508     case AGM_MONITOR_TABLEm:
  13509          direction= bcmStatFlexDirectionIngress;
  13510          break;
  13511     default:
  13512          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  13513                    (BSL_META_U(unit,
  13514                                "Invalid Flex Counter Memory %s\n"),
  13515                     SOC_MEM_UFNAME(unit, table)));
  13516          return BCM_E_PARAM;
  13517     }
  13518 
  13519 #if defined (BCM_TOMAHAWK_SUPPORT)
  13520     _CTR_COUNTER_TABLE_IFP(unit, direction, pipe_num, 0, mem);
  13521 #else
  13522     mem = _ctr_counter_table[direction][0];
  13523 #endif
  13524 
  13525     COMPILER_64_SET(max_byte_mask, zero, one);
  13526     COMPILER_64_SHL(max_byte_mask,soc_mem_field_length(unit,mem,BYTE_COUNTERf));
  13527     COMPILER_64_SUB_32(max_byte_mask,one);
  13528 
  13529     max_packet_mask = (1 << soc_mem_field_length(unit,mem,PACKET_COUNTERf));
  13530     max_packet_mask -= 1;
  13531 
  13532     entry_data_size = WORDS2BYTES(BYTES2WORDS(SOC_MEM_INFO(unit,table).bytes));
  13533     entry_data = sal_alloc(entry_data_size,"flex-counter-table");
  13534     if (entry_data == NULL) {
  13535         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  13536                   (BSL_META_U(unit,
  13537                               "Failed to allocate memory for Table:%s "),
  13538                    SOC_MEM_UFNAME(unit, table)));
  13539         return BCM_E_INTERNAL;
  13540     }
  13541     if (flex_temp_counter[unit][direction] == NULL) {
  13542         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  13543                   (BSL_META_U(unit,
  13544                               "Not initilized or attached yet\n")));
  13545         sal_free(entry_data);
  13546         return BCM_E_CONFIG;
  13547     }
  13548     sal_memset(entry_data,0,entry_data_size);
  13549 
  13550     if (soc_mem_read(unit,table,MEM_BLOCK_ANY,
  13551                 _bcm_esw_stat_flex_table_index_map(unit,table,index),
  13552                 entry_data) == SOC_E_NONE) {
  13553         if (soc_mem_field_valid(unit,table,VALIDf)) {
  13554             if (soc_mem_field32_get(unit,table,entry_data,VALIDf)==0) {
  13555                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  13556                           (BSL_META_U(unit,
  13557                                       "Table %s  with index %d is Not valid \n"),
  13558                            SOC_MEM_UFNAME(unit, table),index));
  13559                 sal_free(entry_data);
  13560                 return BCM_E_PARAM;
  13561             }
  13562         }
  13563         _bcm_esw_get_flex_counter_fields_values(
  13564                 unit,exact_index,table,entry_data,object,&offset_mode,
  13565                 (uint32 *)&pool_number,&base_idx);
  13566         if ((offset_mode == 0) && (base_idx == 0)) {
  13567              LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  13568                        (BSL_META_U(unit,
  13569                                    "Table:%s:Index:%d:IsNotConfiguredForFlexCounter \n"),
  13570                         SOC_MEM_UFNAME(unit, table),index));
  13571              sal_free(entry_data);
  13572              /* Either Not configured or deallocated before */
  13573              return BCM_E_NOT_FOUND;
  13574         }
  13575         if (direction == bcmStatFlexDirectionIngress) {
  13576             total_entries= flex_ingress_modes[unit][offset_mode].total_counters;
  13577         } else {
  13578             total_entries = flex_egress_modes[unit][offset_mode].total_counters;
  13579         }
  13580         offset_index = counter_index;
  13581         if (offset_index >= total_entries) {
  13582             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  13583                       (BSL_META_U(unit,
  13584                                   "Wrong OFFSET_INDEX. Must be < Total Counters %d \n"),
  13585                        total_entries));
  13586             sal_free(entry_data);
  13587             return BCM_E_PARAM;
  13588         }
  13589 
  13590         if (SOC_IS_TOMAHAWKX(unit) ||SOC_IS_TRIDENT3X(unit)) {
  13591             sal_free(entry_data);
  13592             return th_flex_counter_set(unit, direction, pipe_num, pool_number,
  13593                       base_idx+offset_index, value, 1, byte_flag);
  13594         }
  13595 
  13596         BCM_STAT_FLEX_COUNTER_LOCK(unit);
  13597         mem = _ctr_counter_table[direction][pool_number];
  13598 #if defined(BCM_TRIDENT2_SUPPORT)
  13599         if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
  13600             mem = _ctr_counter_table_x[direction][pool_number];
  13601             mem_dual = _ctr_counter_table_y[direction][pool_number];
  13602         } else
  13603 #endif
  13604         {
  13605 #if defined (BCM_TOMAHAWK_SUPPORT)
  13606             _CTR_COUNTER_TABLE_IFP(unit, direction, pipe_num, pool_number, mem);
  13607 #endif
  13608         }
  13609         if (soc_mem_read(
  13610                     unit,
  13611                     mem,
  13612                     MEM_BLOCK_ANY,
  13613                     base_idx+offset_index,
  13614                     flex_temp_counter[unit][direction]) != BCM_E_NONE){
  13615             BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  13616             sal_free(entry_data);
  13617             return BCM_E_INTERNAL;
  13618         }
  13619 #if defined(BCM_TRIDENT2_SUPPORT)
  13620         if (mem_dual) {
  13621             if (soc_mem_read(
  13622                     unit,
  13623                     mem_dual,
  13624                     MEM_BLOCK_ANY,
  13625                     base_idx+offset_index,
  13626                     flex_temp_counter_dual[unit][direction]) != BCM_E_NONE) {
  13627                 BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  13628                 sal_free(entry_data);
  13629                 return BCM_E_INTERNAL;
  13630             }
  13631         }
  13632 #endif /* BCM_TRIDENT2_SUPPORT*/
  13633 
  13634         if (byte_flag == 1) {
  13635             /* Mask to possible max values */
  13636             COMPILER_64_AND(value->bytes, max_byte_mask);
  13637             /* Update Soft Copy */
  13638             COMPILER_64_SET(flex_byte_counter[unit][direction][pipe_num][pool_number]
  13639                                              [base_idx+offset_index],
  13640                             COMPILER_64_HI(value->bytes),
  13641                             COMPILER_64_LO(value->bytes));
  13642             /* Change Read Hw Copy */
  13643             hw_val[0] = COMPILER_64_LO(value->bytes);
  13644             hw_val[1] = COMPILER_64_HI(value->bytes);
  13645             soc_mem_field_set(
  13646                     unit,
  13647                     mem,
  13648                     (uint32 *)&flex_temp_counter[unit][direction][0],
  13649                     BYTE_COUNTERf,
  13650                     hw_val);
  13651 #if defined(BCM_TRIDENT2_SUPPORT)
  13652             if (mem_dual) {
  13653                 /* assume total counter value are set in X pipe hardware counter
  13654                  * table. Clear the Y pipe table
  13655                  */
  13656                 for (buffer_id = 0; buffer_id < _BCM_FLEX_STAT_BUFFS;
  13657                      buffer_id++) {
  13658                     COMPILER_64_SET(flex_byte_counter_x[unit][direction]
  13659                                     [pool_number][buffer_id]
  13660                                     [base_idx+offset_index],
  13661                                     COMPILER_64_HI(value->bytes),
  13662                                     COMPILER_64_LO(value->bytes));
  13663                     COMPILER_64_ZERO(flex_byte_counter_y[unit][direction]
  13664                                      [pool_number][buffer_id]
  13665                                      [base_idx+offset_index]);
  13666                 }
  13667                 hw_val[0] = 0;
  13668                 hw_val[1] = 0;
  13669                 soc_mem_field_set(
  13670                     unit,
  13671                     mem_dual,
  13672                     (uint32 *)&flex_temp_counter_dual[unit][direction][0],
  13673                     BYTE_COUNTERf,
  13674                     hw_val);
  13675             }
  13676 #endif /* BCM_TRIDENT2_SUPPORT*/
  13677             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  13678                       (BSL_META_U(unit,
  13679                                   "Byte Count Value\t:TABLE:%sINDEX:%d "
  13680                                    "(@Pool:%dDirection:%dActualOffset%d) : %x:%x \n"),
  13681                        SOC_MEM_UFNAME(unit, table),
  13682                        index,
  13683                        pool_number,
  13684                        direction,
  13685                        base_idx+offset_index,
  13686                        COMPILER_64_HI(value->bytes),
  13687                        COMPILER_64_LO(value->bytes)));
  13688         } else {
  13689             value->packets &= max_packet_mask;
  13690             /* Update Soft Copy */
  13691             flex_packet_counter[unit][direction][pipe_num][pool_number]
  13692                                [base_idx+offset_index] = value->packets;
  13693 
  13694             /* Update Soft Copy */
  13695             COMPILER_64_SET(flex_packet64_counter[unit][direction][pipe_num][pool_number]
  13696                                              [base_idx+offset_index],0,
  13697                              value->packets);
  13698             /* Change Read Hw Copy */
  13699             soc_mem_field_set(
  13700                     unit,
  13701                     mem,
  13702                     (uint32 *)&flex_temp_counter[unit][direction][0],
  13703                     PACKET_COUNTERf,
  13704                     &(value->packets));
  13705 #if defined(BCM_TRIDENT2_SUPPORT)
  13706             if (mem_dual) {
  13707                 for (buffer_id = 0; buffer_id < _BCM_FLEX_STAT_BUFFS;
  13708                      buffer_id++) {
  13709                     flex_pkt_counter_x[unit][direction][pool_number]
  13710                                       [buffer_id][base_idx+offset_index]
  13711                                       = value->packets;
  13712                     flex_pkt_counter_y[unit][direction][pool_number]
  13713                                       [buffer_id][base_idx+offset_index]
  13714                                       = 0;
  13715                 }
  13716                 hw_val[0] = 0;
  13717                 soc_mem_field_set(
  13718                     unit,
  13719                     mem_dual,
  13720                     (uint32 *)&flex_temp_counter_dual[unit][direction][0],
  13721                     PACKET_COUNTERf,
  13722                     &hw_val[0]);
  13723             }
  13724 #endif /* BCM_TRIDENT2_SUPPORT*/
  13725             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  13726                       (BSL_META_U(unit,
  13727                                   "Packet Count Value\t:TABLE:%sINDEX:%d "
  13728                                    "(@Pool:%dDirection:%dActualOffset%d) : %x \n"),
  13729                        SOC_MEM_UFNAME(unit, table),
  13730                        index,
  13731                        pool_number,
  13732                        direction,
  13733                        base_idx+offset_index,
  13734                        value->packets));
  13735         }
  13736         /* Update Hw Copy */
  13737         if (soc_mem_write(unit,mem,MEM_BLOCK_ALL,
  13738                     base_idx+offset_index,
  13739                     &(flex_temp_counter[unit][direction][0])) != BCM_E_NONE){
  13740             BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  13741             sal_free(entry_data);
  13742             return BCM_E_INTERNAL;
  13743         }
  13744 #if defined(BCM_TRIDENT2_SUPPORT)
  13745         if (mem_dual) {
  13746             if (soc_mem_write(unit,mem_dual,MEM_BLOCK_ALL,
  13747                     base_idx+offset_index,
  13748                     &(flex_temp_counter_dual[unit][direction][0])) != BCM_E_NONE){
  13749             BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  13750             sal_free(entry_data);
  13751             return BCM_E_INTERNAL;
  13752         }
  13753     }
  13754 #endif /* BCM_TRIDENT2_SUPPORT*/
  13755         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  13756         sal_free(entry_data);
  13757         return BCM_E_NONE;
  13758     }
  13759     sal_free(entry_data);
  13760     return BCM_E_FAIL;
  13761 }
  13762 
  13763 #if defined (BCM_TOMAHAWK_SUPPORT)
  13764 STATIC
  13765 bcm_error_t th_flex_centralized_counter_get(int unit,
  13766                                             int sync_mode,
  13767                                             bcm_stat_flex_direction_t  direction,
  13768                                             uint32       pool_number,
  13769                                             int         pipe_num,
  13770                                             uint32           index,
  13771                                             uint32           byte_flag,
  13772                                             bcm_stat_value_t *value)
  13773 {
  13774     soc_ctr_control_info_t     ctrl_info[2], ctrl_info_out;
  13775     soc_counter_non_dma_id_t  pkt_ctr_id, byte_ctr_id;
  13776     uint64 pkt_ctr_new, byte_ctr_new;
  13777     int rv;
  13778     uint32 flags = 0;
  13779 
  13780 #if defined(BCM_TOMAHAWK_SUPPORT) && defined (INCLUDE_FLOWTRACKER)
  13781     if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
  13782          soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
  13783          soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
  13784         if (_bcm_esw_stat_pool_reserved(unit, direction, pool_number)) {
  13785             return BCM_E_NONE;
  13786         }
  13787     }
  13788 #endif
  13789 
  13790     ctrl_info[0].instance_type = SOC_CTR_INSTANCE_TYPE_POOL;
  13791     ctrl_info[0].instance = pool_number;
  13792 
  13793     if (pipe_num == -1) {
  13794         ctrl_info_out = ctrl_info[0];
  13795     } else {
  13796         ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PIPE;
  13797         ctrl_info[1].instance = pipe_num;
  13798         soc_counter_instance_encode(ctrl_info, 2, &ctrl_info_out);
  13799     }
  13800 
  13801     if (direction == bcmStatFlexDirectionEgress) {
  13802         pkt_ctr_id = SOC_COUNTER_NON_DMA_EGR_FLEX_PKT;
  13803         byte_ctr_id = SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE;
  13804     } else {
  13805         pkt_ctr_id = SOC_COUNTER_NON_DMA_ING_FLEX_PKT;
  13806         byte_ctr_id = SOC_COUNTER_NON_DMA_ING_FLEX_BYTE;
  13807     }
  13808 
  13809     if (sync_mode) {
  13810         flags |= SOC_COUNTER_SYNC_ENABLE;
  13811     }
  13812 
  13813     if (byte_flag == 1) {
  13814         rv = soc_counter_generic_get(unit, byte_ctr_id, ctrl_info_out,
  13815                                      flags, index, &byte_ctr_new);
  13816         if (rv != SOC_E_NONE) {
  13817             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  13818                 (BSL_META_U(unit, "Unable to retrieve byte counter values unit - %d,"
  13819                     " pool - %d, counter index - %d\n"),
  13820                     unit, pool_number, index));
  13821             return BCM_E_FAIL;
  13822         }
  13823         COMPILER_64_SET(value->bytes, COMPILER_64_HI(byte_ctr_new),
  13824         COMPILER_64_LO(byte_ctr_new));
  13825     } else {
  13826         rv = soc_counter_generic_get(unit, pkt_ctr_id, ctrl_info_out,
  13827                                      flags, index, &pkt_ctr_new);
  13828         if (rv != SOC_E_NONE) {
  13829             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  13830                 (BSL_META_U(unit, "Unable to retrieve packet counter values unit - %d,"
  13831                     " pool - %d, counter index - %d\n"),
  13832                     unit, pool_number, index));
  13833             return BCM_E_FAIL;
  13834         }
  13835         value->packets = COMPILER_64_LO(pkt_ctr_new); /* 32 bit for */
  13836         COMPILER_64_SET(value->packets64, COMPILER_64_HI(pkt_ctr_new),
  13837         COMPILER_64_LO(pkt_ctr_new));
  13838     }
  13839     return BCM_E_NONE;
  13840 }
  13841 #endif /* BCM_TOMAHAWK_SUPPORT */
  13842 
  13843 
  13844 /*
  13845  * Function:
  13846  *      _bcm_esw_stat_counter_get
  13847  * Description:
  13848  *      Get Flex Counter Values
  13849  *      if sync_mode is set, sync the sw accumulated count
  13850  *      with hw count value first, else return sw count.
  13851  *
  13852  * Parameters:
  13853  *      unit                  - (IN) unit number
  13854  *      sync_mode             - (IN) hwcount is to be synced to sw count
  13855  *      index                 - (IN) Flex Accounting Table Index
  13856  *      table                 - (IN) Flex Accounting Table
  13857  *      byte_flag             - (IN) Byte/Packet Flag
  13858  *      counter               - (IN) Counter Index
  13859  *      values                - (OUT) Counter Value
  13860  *
  13861  * Return Value:
  13862  *      BCM_E_XXX
  13863  * Notes:
  13864  */
  13865 bcm_error_t _bcm_esw_stat_counter_get(
  13866             int              unit,
  13867             int              sync_mode,
  13868             uint32           index,
  13869             soc_mem_t        table,
  13870             bcm_stat_object_t object,
  13871             uint32           byte_flag,
  13872             uint32           counter_index,
  13873             bcm_stat_value_t *value)
  13874 {
  13875     uint32                    loop=0;
  13876     uint32                    offset_mode=0;
  13877     uint32                    pool_number=0;
  13878     uint32                    base_idx=0;
  13879     bcm_stat_flex_direction_t direction = bcmStatFlexDirectionIngress;
  13880     uint32                    total_entries=0;
  13881     uint32                    offset_index=0;
  13882     uint32                    entry_data_size=0;
  13883     void                      *entry_data=NULL;
  13884     int                       pipe_num = 0;
  13885     uint32                    exact_index=0;
  13886 
  13887     exact_index = index;
  13888 
  13889     switch(table) {
  13890     case PORT_TABm:
  13891     case VLAN_XLATEm:
  13892 #if defined(BCM_TRIUMPH3_SUPPORT)
  13893     case VLAN_XLATE_EXTDm:
  13894     case MPLS_ENTRY_EXTDm:
  13895     case L3_TUNNELm:
  13896     case L3_ENTRY_2m:
  13897     case L3_ENTRY_4m:
  13898     case EXT_IPV4_UCAST_WIDEm:
  13899     case EXT_IPV6_128_UCAST_WIDEm:
  13900     case EXT_FP_POLICYm:
  13901 #endif
  13902 #if defined(BCM_TRIDENT2_SUPPORT)
  13903     case ING_VSANm:
  13904     case L3_ENTRY_IPV4_MULTICASTm:
  13905     case L3_ENTRY_IPV6_MULTICASTm:
  13906     case L3_DEFIPm:
  13907     case L3_DEFIP_PAIR_128m:
  13908     case L3_DEFIP_LEVEL1m:
  13909     case L3_DEFIP_PAIR_LEVEL1m:
  13910     case L3_DEFIP_ALPM_LEVEL2m:
  13911     case L3_DEFIP_ALPM_LEVEL3m:
  13912     case L3_DEFIP_ALPM_RAWm:
  13913     case L3_DEFIP_ALPM_IPV4_1m:
  13914     case L3_DEFIP_ALPM_IPV6_64_1m:
  13915     case L3_DEFIP_ALPM_IPV6_128m:
  13916 #endif
  13917     case VFP_POLICY_TABLEm:
  13918 #if defined (BCM_TOMAHAWK_SUPPORT)
  13919     case VFP_POLICY_TABLE_PIPE0m:
  13920     case VFP_POLICY_TABLE_PIPE1m:
  13921     case VFP_POLICY_TABLE_PIPE2m:
  13922     /* coverity[UNTERMINATED_CASE] */
  13923     case VFP_POLICY_TABLE_PIPE3m:
  13924     case VFP_POLICY_TABLE_PIPE4m:
  13925     case VFP_POLICY_TABLE_PIPE5m:
  13926     case VFP_POLICY_TABLE_PIPE6m:
  13927     case VFP_POLICY_TABLE_PIPE7m:
  13928          pipe_num = _bcm_esw_get_fp_pipe_num(unit, table);
  13929 #endif
  13930     /* coverity[FALLTHROUGH] */
  13931     case MPLS_ENTRYm:
  13932     case SOURCE_VPm:
  13933     case L3_IIFm:
  13934     case VRFm:
  13935     case VFIm:
  13936     case VLAN_TABm:
  13937 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  13938     case LPORT_TABm:
  13939     case L3_ENTRY_QUADm:
  13940     case L3_ENTRY_DOUBLEm:
  13941 #endif
  13942 #if defined (BCM_TRIDENT3_SUPPORT)
  13943     case VLAN_XLATE_1_DOUBLEm:
  13944     case VLAN_XLATE_2_DOUBLEm:
  13945     case VRF_ATTRS_2m:
  13946 #endif /* BCM_TRIDENT3_SUPPORT */
  13947 #if defined (BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  13948     case MPLS_ENTRY_SINGLEm:
  13949 #endif
  13950          direction= bcmStatFlexDirectionIngress;
  13951          break;
  13952     case EGR_VLANm:
  13953     case EGR_VFIm:
  13954     case EGR_L3_NEXT_HOPm:
  13955     case EGR_VLAN_XLATEm:
  13956     case EGR_PORTm:
  13957 #if defined(BCM_TRIUMPH3_SUPPORT)
  13958     case EGR_DVP_ATTRIBUTE_1m:
  13959 #endif
  13960 #if defined(BCM_TRIDENT2_SUPPORT)
  13961     case EGR_NAT_PACKET_EDIT_INFOm:
  13962 #endif
  13963 #if defined (BCM_TRIDENT3_SUPPORT)
  13964      case EGR_DVP_ATTRIBUTEm:
  13965      case EGR_VLAN_XLATE_1_DOUBLEm:
  13966      case EGR_VLAN_XLATE_2_DOUBLEm:
  13967      case EGR_LPORT_PROFILEm:
  13968 #endif
  13969          direction= bcmStatFlexDirectionEgress;
  13970          break;
  13971 #if defined (BCM_TOMAHAWK_SUPPORT)
  13972     case IFP_POLICY_TABLE_PIPE0m:
  13973     case IFP_POLICY_TABLE_PIPE1m:
  13974     case IFP_POLICY_TABLE_PIPE2m:
  13975     /* coverity[UNTERMINATED_CASE] */
  13976     case IFP_POLICY_TABLE_PIPE3m:
  13977     case IFP_POLICY_TABLE_PIPE4m:
  13978     case IFP_POLICY_TABLE_PIPE5m:
  13979     case IFP_POLICY_TABLE_PIPE6m:
  13980     case IFP_POLICY_TABLE_PIPE7m:
  13981          pipe_num = _bcm_esw_get_fp_pipe_num(unit, table);
  13982 #endif
  13983     /* coverity[FALLTHROUGH] */
  13984     case IFP_POLICY_TABLEm:
  13985          direction= bcmStatFlexDirectionIngress;
  13986          break;
  13987     case AGM_MONITOR_TABLEm:
  13988          direction= bcmStatFlexDirectionIngress;
  13989          break;
  13990 #if defined (BCM_TRIDENT2PLUS_SUPPORT)
  13991     case EGR_IP_TUNNEL_MPLSm:
  13992          direction= bcmStatFlexDirectionEgress;
  13993          index = index / _BCM_MPLS_NUM_MPLS_ENTRIES_PER_INDEX(unit);
  13994          break;
  13995 #endif
  13996 #if defined (BCM_TRIDENT3_SUPPORT)
  13997         case EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm:
  13998              direction = bcmStatFlexDirectionEgress;
  13999              index = index / _BCM_MPLS_NUM_MPLS_ENTRIES_PER_INDEX(unit);
  14000              break;
  14001 #endif
  14002     default:
  14003          LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  14004                      (BSL_META_U(unit,
  14005                                  "Invalid Flex Counter Memory %s\n"),
  14006                       SOC_MEM_UFNAME(unit, table)));
  14007          return BCM_E_PARAM;
  14008     }
  14009     entry_data_size = WORDS2BYTES(BYTES2WORDS(SOC_MEM_INFO(unit,table).bytes));
  14010     entry_data = sal_alloc(entry_data_size,"flex-counter-table");
  14011     if (entry_data == NULL) {
  14012         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  14013                   (BSL_META_U(unit,
  14014                               "Failed to allocate memory for Table:%s "),
  14015                    SOC_MEM_UFNAME(unit, table)));
  14016         return BCM_E_INTERNAL;
  14017     }
  14018     sal_memset(entry_data,0,entry_data_size);
  14019 
  14020     if (soc_mem_read(unit,table,MEM_BLOCK_ANY,
  14021                 _bcm_esw_stat_flex_table_index_map(unit,table,index),
  14022                 entry_data) == SOC_E_NONE) {
  14023         soc_field_t vld_fld = INVALIDf;
  14024 
  14025         if (soc_mem_field_valid(unit, table, VALIDf)) {
  14026             vld_fld = VALIDf;
  14027         }
  14028         if (soc_mem_field_valid(unit, table, BASE_VALID_0f)) {
  14029             vld_fld = BASE_VALID_0f;
  14030         }
  14031 
  14032         if (vld_fld != INVALIDf) {
  14033             if (soc_mem_field32_get(unit,table,entry_data,vld_fld)==0) {
  14034                 LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  14035                             (BSL_META_U(unit,
  14036                             "Table %s  with index %d is Not valid \n"),
  14037                             SOC_MEM_UFNAME(unit, table),index));
  14038                 sal_free(entry_data);
  14039                 return BCM_E_PARAM;
  14040             }
  14041         }
  14042 
  14043         _bcm_esw_get_flex_counter_fields_values(
  14044                  unit,
  14045                  exact_index,
  14046                  table,
  14047                  entry_data,
  14048                  object,
  14049                  &offset_mode,
  14050                  &pool_number,
  14051                  &base_idx);
  14052         if ((offset_mode == 0) && (base_idx == 0)) {
  14053              LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  14054                          (BSL_META_U(unit,
  14055                                      "Table:%s:Index:%d:is NotConfiguredForFlexCounter \n"),
  14056                           SOC_MEM_UFNAME(unit, table),index));
  14057              sal_free(entry_data);
  14058              /* Either Not configured or deallocated before */
  14059              return BCM_E_NOT_FOUND;
  14060          }
  14061          if (direction == bcmStatFlexDirectionIngress) {
  14062              total_entries = flex_ingress_modes[unit][offset_mode].
  14063                              total_counters;
  14064          } else {
  14065              total_entries = flex_egress_modes[unit][offset_mode].
  14066                              total_counters;
  14067          }
  14068          offset_index = counter_index;
  14069          if (offset_index >= total_entries) {
  14070              LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  14071                          (BSL_META_U(unit,
  14072                                      "Invalid offset_index[%d]. total_entries[%d]\n"),
  14073                           offset_index, total_entries));
  14074              sal_free(entry_data);
  14075              return BCM_E_PARAM;
  14076          }
  14077 
  14078 #if defined(BCM_TOMAHAWK_SUPPORT)
  14079         if (soc_feature(unit, soc_feature_centralized_counter)) {
  14080             if(!BCM_TH_LOCAL_PIPE_MODE(unit, pool_number)) {
  14081                 pipe_num = -1;
  14082             }
  14083             sal_free(entry_data);
  14084             return th_flex_centralized_counter_get(unit, sync_mode, direction,
  14085                                                    pool_number, pipe_num,
  14086                                                    base_idx + offset_index,
  14087                                                    byte_flag, value);
  14088         }
  14089 #endif /* BCM_TOMAHAWK_SUPPORT */
  14090 
  14091          BCM_STAT_FLEX_COUNTER_LOCK(unit);
  14092 
  14093          /* sync the software counter with hardware counter */
  14094          if (sync_mode == 1) {
  14095              _bcm_esw_stat_flex_counter_collect(unit, direction,
  14096                                                 pool_number,
  14097                                                 base_idx + offset_index + loop);
  14098          }
  14099 
  14100          bcm_stat_value_t_init(value);
  14101          if (byte_flag == 1) {
  14102              COMPILER_64_SET(value->bytes,
  14103                       COMPILER_64_HI(flex_byte_counter[unit]
  14104                                      [direction][pipe_num][pool_number]
  14105                                      [base_idx+offset_index+loop]),
  14106                       COMPILER_64_LO(flex_byte_counter[unit]
  14107                                      [direction][pipe_num][pool_number]
  14108                                      [base_idx+offset_index+loop]));
  14109 
  14110              if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  14111                  COMPILER_64_ADD_64(value->bytes,
  14112                          flex_byte_counter_compaction[unit]
  14113                          [direction][pipe_num][pool_number]
  14114                          [base_idx+offset_index+loop]);
  14115              }
  14116              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  14117                        (BSL_META_U(unit,
  14118                                    "Byte Count Value\t:TABLE:%sINDEX:%d COUTER-%d"
  14119                                     "(@Pool:%dDirection:%dActualOffset%d) : %x:%x \n"),
  14120                         SOC_MEM_UFNAME(unit, table),
  14121                         index,
  14122                         loop,
  14123                         pool_number,
  14124                         direction,
  14125                         base_idx+offset_index+loop,
  14126                         COMPILER_64_HI(value->bytes),
  14127                         COMPILER_64_LO(value->bytes)));
  14128          } else {
  14129              value->packets= flex_packet_counter[unit][direction][pipe_num][pool_number]
  14130                                                 [base_idx+offset_index+loop];
  14131 
  14132              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  14133                        (BSL_META_U(unit,
  14134                                    "Packet Count Value\t:TABLE:%sINDEX:%d COUTER-%d"
  14135                                     "(@Pool:%dDirection:%dActualOffset%d) : %x \n"),
  14136                         SOC_MEM_UFNAME(unit, table),
  14137                         index,
  14138                         loop,
  14139                         pool_number,
  14140                         direction,
  14141                         base_idx+offset_index+loop,
  14142                         value->packets));
  14143              COMPILER_64_SET(value->packets64,
  14144                       COMPILER_64_HI(flex_packet64_counter[unit]
  14145                                      [direction][pipe_num][pool_number]
  14146                                      [base_idx+offset_index+loop]),
  14147                       COMPILER_64_LO(flex_packet64_counter[unit]
  14148                                      [direction][pipe_num][pool_number]
  14149                                      [base_idx+offset_index+loop]));
  14150 
  14151              if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  14152                  value->packets+= flex_packet_counter_compaction[unit]
  14153                      [direction][pipe_num][pool_number][base_idx+offset_index+loop];
  14154                  COMPILER_64_ADD_64(value->packets64,
  14155                          flex_packet64_counter_compaction[unit]
  14156                          [direction][pipe_num][pool_number]
  14157                          [base_idx+offset_index+loop]);
  14158              }
  14159              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  14160                        (BSL_META_U(unit,
  14161                                    "Packet64 Count Value\t:TABLE:%sINDEX:%d COUNTER-%d"
  14162                                     "(@Pool:%dDirection:%dActualOffset%d) : %x:%x \n"),
  14163                         SOC_MEM_UFNAME(unit, table),
  14164                         index,
  14165                         loop,
  14166                         pool_number,
  14167                         direction,
  14168                         base_idx+offset_index+loop,
  14169                         COMPILER_64_HI(value->packets64),
  14170                         COMPILER_64_LO(value->packets64)));
  14171          }
  14172          BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  14173          sal_free(entry_data);
  14174          return BCM_E_NONE;
  14175     }
  14176     sal_free(entry_data);
  14177     return BCM_E_FAIL;
  14178 }
  14179 
  14180 /*
  14181  * Function:
  14182  *      _bcm_esw_stat_counter_raw_get
  14183  * Description:
  14184  *      Get Flex Counter Values
  14185  * Parameters:
  14186  *      unit                  - (IN) unit number
  14187  *      stat_counter_id       - (IN) Stat Counter Id
  14188  *      byte_flag             - (IN) Byte/Packet Flag
  14189  *      counter               - (IN) Counter Index
  14190  *      values                - (OUT) Counter Value
  14191  *
  14192  * Return Value:
  14193  *      BCM_E_XXX
  14194  * Notes: Must be called carefully.
  14195  *        Preference should be given to _bcm_esw_stat_counter_get()
  14196  */
  14197 bcm_error_t _bcm_esw_stat_counter_raw_get(
  14198             int              unit,
  14199             int              sync_mode,
  14200             uint32           stat_counter_id,
  14201             uint32           byte_flag,
  14202             uint32           counter_index,
  14203             bcm_stat_value_t *value)
  14204 {
  14205     uint32                    offset_mode=0;
  14206     uint32                    pool_number=0;
  14207     uint32                    base_idx=0;
  14208     uint32                    total_entries=0;
  14209     uint32                    offset_index=0;
  14210     bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress;
  14211     bcm_stat_object_t         object=bcmStatObjectIngPort;
  14212     bcm_stat_group_mode_t     group_mode= bcmStatGroupModeSingle;
  14213     int                       pipe_num = 0;
  14214 #if defined (BCM_TOMAHAWK_SUPPORT)
  14215     bcm_field_qualify_t       stage;
  14216     uint32                    cmode  = 0;
  14217 #endif
  14218 
  14219     _bcm_esw_stat_get_counter_id_info(unit, stat_counter_id, &group_mode,&object,
  14220                                       &offset_mode,&pool_number,&base_idx);
  14221 
  14222 #if defined (BCM_TOMAHAWK_SUPPORT)
  14223     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id)) {
  14224         stage = _bcm_esw_stat_get_field_stage_from_stat_ctr(unit, stat_counter_id);
  14225         _bcm_esw_get_fp_pipe_from_mode(unit, offset_mode, stage, &pipe_num);
  14226         if ((offset_mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  14227             (offset_mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  14228             cmode = offset_mode - BCM_CUSTOM_INGRESS_MODE_START;
  14229             offset_mode = flex_custom_ingress_modes[unit][cmode].
  14230                                                 offset_mode;
  14231             total_entries = flex_custom_ingress_modes[unit][cmode].
  14232                                           total_counters;
  14233         }
  14234 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  14235         if ((offset_mode >= BCM_CUSTOM_EGRESS_MODE_START) &&
  14236             (offset_mode < BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE)) {
  14237             cmode = offset_mode - BCM_CUSTOM_EGRESS_MODE_START;
  14238             offset_mode = flex_custom_egress_modes[unit][cmode].offset_mode;
  14239             total_entries =
  14240                 flex_custom_egress_modes[unit][cmode].total_counters;
  14241         }
  14242 #endif
  14243     }
  14244 #endif
  14245 
  14246     /* Validate object id first */
  14247     if (_bcm_esw_stat_validate_object(unit,object,&direction) != BCM_E_NONE) {
  14248         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  14249                   (BSL_META_U(unit,
  14250                               "Invalid bcm_stat_object_t passed %d \n"),
  14251                    object));
  14252         return BCM_E_PARAM;
  14253     }
  14254     /* Validate group_mode */
  14255     if (_bcm_esw_stat_validate_group(unit,group_mode) != BCM_E_NONE) {
  14256         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  14257                   (BSL_META_U(unit,
  14258                               "Invalid bcm_stat_group_mode_t passed %d \n"),
  14259                    group_mode));
  14260         return BCM_E_PARAM;
  14261     }
  14262     if (flex_base_index_reference_count[unit][direction]
  14263                                        [pipe_num][pool_number][base_idx] == 0) {
  14264         return BCM_E_PARAM;
  14265     }
  14266     if (direction == bcmStatFlexDirectionIngress) {
  14267         if (total_entries == 0) {
  14268             total_entries = flex_ingress_modes[unit][offset_mode].
  14269                                           total_counters;
  14270         }
  14271     } else {
  14272         total_entries = flex_egress_modes[unit][offset_mode].
  14273                                          total_counters;
  14274     }
  14275 
  14276     offset_index = counter_index;
  14277     if (offset_index >= total_entries) {
  14278         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  14279                   (BSL_META_U(unit,
  14280                               "Wrong OFFSET_INDEX.Must be < Total Counters %d \n"),
  14281                    total_entries));
  14282         return BCM_E_PARAM;
  14283     }
  14284 
  14285 #if defined(BCM_TOMAHAWK_SUPPORT)
  14286     if (soc_feature(unit, soc_feature_centralized_counter)) {
  14287         if (!BCM_TH_LOCAL_PIPE_MODE(unit, pool_number)) {
  14288             /* Pass pipe_num as -1 if in Global mode */
  14289             pipe_num = -1;
  14290         }
  14291         return th_flex_centralized_counter_get(unit, sync_mode, direction,
  14292                                                pool_number, pipe_num,
  14293                                                base_idx + offset_index,
  14294                                                byte_flag, value);
  14295     }
  14296 #endif /* BCM_TOMAHAWK_SUPPORT */
  14297 
  14298     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  14299 
  14300     /* sync the software counter with hardware counter */
  14301     if (sync_mode == 1) {
  14302             _bcm_esw_stat_flex_counter_collect(unit, direction,
  14303                                                pool_number, base_idx + offset_index);
  14304     }
  14305     if (byte_flag == 1) {
  14306         COMPILER_64_SET(value->bytes,
  14307                  COMPILER_64_HI(flex_byte_counter[unit]
  14308                                 [direction][pipe_num][pool_number]
  14309                                 [base_idx+offset_index]),
  14310                  COMPILER_64_LO(flex_byte_counter[unit]
  14311                                 [direction][pipe_num][pool_number]
  14312                                 [base_idx+offset_index]));
  14313         if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  14314             COMPILER_64_ADD_64(value->bytes,
  14315                     flex_byte_counter_compaction[unit]
  14316                     [direction][pipe_num][pool_number]
  14317                     [base_idx+offset_index]);
  14318         }
  14319         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  14320                   (BSL_META_U(unit,
  14321                               "Byte Count Value\t:COUTER-%d"
  14322                                "(@Pool:%dDirection:%dActualOffset%d) : %x:%x \n"),
  14323                    offset_index,
  14324                    pool_number,
  14325                    direction,
  14326                    base_idx+offset_index,
  14327                    COMPILER_64_HI(value->bytes),
  14328                    COMPILER_64_LO(value->bytes)));
  14329     } else {
  14330         value->packets= flex_packet_counter[unit][direction][pipe_num][pool_number]
  14331                                            [base_idx+offset_index];
  14332 
  14333         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  14334                   (BSL_META_U(unit,
  14335                               "Packet Count Value\t:COUTER-%d"
  14336                                "(@Pool:%dDirection:%dActualOffset%d) : %x \n"),
  14337                    offset_index,
  14338                    pool_number,
  14339                    direction,
  14340                    base_idx+offset_index,
  14341                    value->packets));
  14342         COMPILER_64_SET(value->packets64,
  14343                  COMPILER_64_HI(flex_packet64_counter[unit]
  14344                                 [direction][pipe_num][pool_number]
  14345                                 [base_idx+offset_index]),
  14346                  COMPILER_64_LO(flex_packet64_counter[unit]
  14347                                 [direction][pipe_num][pool_number]
  14348                                 [base_idx+offset_index]));
  14349         if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  14350             value->packets+= flex_packet_counter_compaction[unit]
  14351                 [direction][pipe_num][pool_number][base_idx+offset_index];
  14352             COMPILER_64_ADD_64(value->packets64,
  14353                     flex_packet64_counter_compaction[unit]
  14354                     [direction][pipe_num][pool_number]
  14355                     [base_idx+offset_index]);
  14356         }
  14357         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  14358                   (BSL_META_U(unit,
  14359                               "Byte Count Value\t:COUNTER-%d"
  14360                                "(@Pool:%dDirection:%dActualOffset%d) : %x:%x \n"),
  14361                    offset_index,
  14362                    pool_number,
  14363                    direction,
  14364                    base_idx+offset_index,
  14365                    COMPILER_64_HI(value->packets64),
  14366                    COMPILER_64_LO(value->packets64)));
  14367 
  14368     }
  14369     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  14370     return BCM_E_NONE;
  14371 }
  14372 
  14373 /*
  14374  * Function:
  14375  *      _bcm_esw_stat_counter_raw_set
  14376  * Description:
  14377  *      Set Flex Counter Values
  14378  * Parameters:
  14379  *      unit                  - (IN) unit number
  14380  *      stat_counter_id       - (IN) Stat Counter Id
  14381  *      byte_flag             - (IN) Byte/Packet Flag
  14382  *      counter               - (IN) Counter Index
  14383  *      values                - (IN) Counter Value
  14384  *
  14385  * Return Value:
  14386  *      BCM_E_XXX
  14387  * Notes: Must be called carefully.
  14388  *        Preference should be given to _bcm_esw_stat_counter_set()
  14389  */
  14390 bcm_error_t _bcm_esw_stat_counter_raw_set(
  14391             int              unit,
  14392             uint32           stat_counter_id,
  14393             uint32           byte_flag,
  14394             uint32           counter_index,
  14395             bcm_stat_value_t *value)
  14396 {
  14397     soc_mem_t                 mem;
  14398 #if defined(BCM_TRIDENT2_SUPPORT)
  14399     soc_mem_t                 mem_dual = 0;
  14400     int                       buffer_id = 0;
  14401 #endif /* BCM_TRIDENT2_SUPPORT*/
  14402 
  14403     uint32                    zero=0;
  14404     uint32                    one=1;
  14405     uint32                    offset_mode=0;
  14406     uint32                    pool_number=0;
  14407     uint32                    base_idx=0;
  14408     uint32                    total_entries=0;
  14409     uint32                    offset_index=0;
  14410     uint32                    max_packet_mask=0;
  14411     uint64                    max_byte_mask;
  14412     uint32                    hw_val[2];
  14413     bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress;
  14414     bcm_stat_object_t         object=bcmStatObjectIngPort;
  14415     bcm_stat_group_mode_t     group_mode= bcmStatGroupModeSingle;
  14416     int                       pipe_num = 0;
  14417 #if defined (BCM_TOMAHAWK_SUPPORT)
  14418     bcm_field_qualify_t       stage;
  14419     uint32                    cmode = 0;
  14420 #endif
  14421 
  14422     _bcm_esw_stat_get_counter_id_info(unit, stat_counter_id, &group_mode,&object,
  14423                                       &offset_mode,&pool_number,&base_idx);
  14424     /* Validate object id first */
  14425     if (_bcm_esw_stat_validate_object(unit,object,&direction) != BCM_E_NONE) {
  14426         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  14427                   (BSL_META_U(unit,
  14428                               "Invalid bcm_stat_object_t passed %d \n"),
  14429                    object));
  14430         return BCM_E_PARAM;
  14431     }
  14432 
  14433     if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  14434         /* Handle FP object ctr reset in StatIdMove */
  14435         if ((compaction_info.base_idx == base_idx) &&
  14436                 (compaction_info.pool_number == pool_number) &&
  14437                 (compaction_info.in_progress == TRUE) &&
  14438                 (object == bcmStatObjectIngFieldStageLookup)) {
  14439             return BCM_E_NONE;
  14440         }
  14441     }
  14442 
  14443     /* Validate group_mode */
  14444     if (_bcm_esw_stat_validate_group(unit,group_mode) != BCM_E_NONE) {
  14445         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  14446                   (BSL_META_U(unit,
  14447                               "Invalid bcm_stat_group_mode_t passed %d \n"),
  14448                    group_mode));
  14449         return BCM_E_PARAM;
  14450     }
  14451     if (direction == bcmStatFlexDirectionIngress) {
  14452         if (offset_mode < BCM_STAT_FLEX_COUNTER_MAX_MODE) {
  14453             total_entries = flex_ingress_modes[unit][offset_mode].
  14454                                           total_counters;
  14455         }
  14456 #ifdef BCM_TOMAHAWK_SUPPORT
  14457         if (soc_feature(unit,soc_feature_stat_multi_pipe_support)) {
  14458             stage = _bcm_esw_stat_get_field_stage_from_stat_ctr(unit, stat_counter_id);
  14459             _bcm_esw_get_fp_pipe_from_mode(unit, offset_mode, stage, &pipe_num);
  14460             if ((offset_mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  14461                 (offset_mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  14462                 cmode = offset_mode - BCM_CUSTOM_INGRESS_MODE_START;
  14463                 offset_mode = flex_custom_ingress_modes[unit][cmode].offset_mode;
  14464                 total_entries = flex_custom_ingress_modes[unit][cmode].
  14465                                           total_counters;
  14466 
  14467             }
  14468         }
  14469 #endif
  14470     } else {
  14471         if (offset_mode < BCM_STAT_FLEX_COUNTER_MAX_MODE) {
  14472         total_entries = flex_egress_modes[unit][offset_mode].
  14473                                          total_counters;
  14474     }
  14475 #ifdef BCM_TRIDENT3_SUPPORT
  14476         if (soc_feature(unit,soc_feature_stat_egr_multi_pipe_support)) {
  14477             stage = _bcm_esw_stat_get_field_stage_from_stat_ctr(unit,
  14478                 stat_counter_id);
  14479             _bcm_esw_get_fp_pipe_from_mode(unit, offset_mode, stage,
  14480                 &pipe_num);
  14481             if ((offset_mode >= BCM_CUSTOM_EGRESS_MODE_START) &&
  14482                 (offset_mode < BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE)) {
  14483                 cmode = offset_mode - BCM_CUSTOM_EGRESS_MODE_START;
  14484                 offset_mode = flex_custom_egress_modes[unit][cmode].offset_mode;
  14485                 total_entries =
  14486                     flex_custom_egress_modes[unit][cmode].total_counters;
  14487             }
  14488         }
  14489 #endif
  14490     }
  14491     if (flex_base_index_reference_count[unit][direction][pipe_num]
  14492                                        [pool_number][base_idx] == 0) {
  14493         return BCM_E_PARAM;
  14494     }
  14495     offset_index = counter_index;
  14496     if (offset_index >= total_entries) {
  14497         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  14498                   (BSL_META_U(unit,
  14499                               "Wrong OFFSET_INDEX.Must be < Total Counters %d \n"),
  14500                    total_entries));
  14501         return BCM_E_PARAM;
  14502     }
  14503     if (flex_temp_counter[unit][direction] == NULL) {
  14504         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  14505                   (BSL_META_U(unit,
  14506                               "Not initilized or attached yet\n")));
  14507         return BCM_E_CONFIG;
  14508     }
  14509 
  14510     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
  14511         return th_flex_counter_set(unit, direction, pipe_num, pool_number,
  14512                   base_idx+offset_index, value, 1, byte_flag);
  14513     }
  14514 
  14515     /* NOT Tomahawk */
  14516     mem = _ctr_counter_table[direction][0];
  14517     COMPILER_64_SET(max_byte_mask, zero, one);
  14518     COMPILER_64_SHL(max_byte_mask,soc_mem_field_length(unit,mem,BYTE_COUNTERf));
  14519     COMPILER_64_SUB_32(max_byte_mask,one);
  14520 
  14521     max_packet_mask = (1 << soc_mem_field_length(unit,mem,PACKET_COUNTERf));
  14522     max_packet_mask -= 1;
  14523 
  14524     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  14525 #if defined(BCM_TRIDENT2_SUPPORT)
  14526     if (soc_feature(unit, soc_feature_advanced_flex_counter)
  14527         && soc_feature(unit, soc_feature_two_ingress_pipes)) {
  14528         mem = _ctr_counter_table_x[direction][pool_number];
  14529         mem_dual = _ctr_counter_table_y[direction][pool_number];
  14530     } else
  14531 #endif
  14532     {
  14533         mem = _ctr_counter_table[direction][pool_number];
  14534     }
  14535     if (soc_mem_read(
  14536                     unit,
  14537                     mem,
  14538                     MEM_BLOCK_ANY,
  14539                     base_idx+offset_index,
  14540                     flex_temp_counter[unit][direction]) != BCM_E_NONE){
  14541             BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  14542             return BCM_E_INTERNAL;
  14543     }
  14544 #if defined(BCM_TRIDENT2_SUPPORT)
  14545     if (mem_dual) {
  14546         if (soc_mem_read(
  14547                     unit,
  14548                     mem_dual,
  14549                     MEM_BLOCK_ANY,
  14550                     base_idx+offset_index,
  14551                     flex_temp_counter_dual[unit][direction]) != BCM_E_NONE) {
  14552             BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  14553             return BCM_E_INTERNAL;
  14554         }
  14555     }
  14556 #endif /* BCM_TRIDENT2_SUPPORT*/
  14557     if (byte_flag == 1) {
  14558         /* Mask to possible max values */
  14559         COMPILER_64_AND(value->bytes, max_byte_mask);
  14560         /* Update Soft Copy */
  14561         COMPILER_64_SET(flex_byte_counter[unit][direction][pipe_num][pool_number]
  14562                                          [base_idx+offset_index],
  14563                         COMPILER_64_HI(value->bytes),
  14564                          COMPILER_64_LO(value->bytes));
  14565         /* Change Read Hw Copy */
  14566         hw_val[0] = COMPILER_64_LO(value->bytes);
  14567         hw_val[1] = COMPILER_64_HI(value->bytes);
  14568         soc_mem_field_set(
  14569                 unit,
  14570                 mem,
  14571                 (uint32 *)&flex_temp_counter[unit][direction][0],
  14572                 BYTE_COUNTERf,
  14573                 hw_val);
  14574 
  14575 #if defined(BCM_TRIDENT2_SUPPORT)
  14576         if (mem_dual) {
  14577             /* Set the Y-pipe value to 0 so that it does not contribute
  14578                to the sum value or the global view */
  14579             for (buffer_id = 0; buffer_id < _BCM_FLEX_STAT_BUFFS;
  14580                      buffer_id++) {
  14581                 COMPILER_64_SET(flex_byte_counter_x[unit][direction]
  14582                                 [pool_number][buffer_id]
  14583                                 [base_idx+offset_index],
  14584                                 COMPILER_64_HI(value->bytes),
  14585                                 COMPILER_64_LO(value->bytes));
  14586                 COMPILER_64_ZERO(flex_byte_counter_y[unit][direction]
  14587                                  [pool_number][buffer_id]
  14588                                  [base_idx+offset_index]);
  14589             }
  14590             hw_val[0] = 0;
  14591             hw_val[1] = 0;
  14592             soc_mem_field_set(
  14593                 unit,
  14594                 mem_dual,
  14595                 (uint32 *)&flex_temp_counter_dual[unit][direction][0],
  14596                 BYTE_COUNTERf,
  14597                 hw_val);
  14598         }
  14599 #endif /* BCM_TRIDENT2_SUPPORT */
  14600         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  14601                   (BSL_META_U(unit,
  14602                               "Byte Count Value\t:COUTER-%d"
  14603                                "(@Pool:%dDirection:%dActualOffset%d) : %x:%x \n"),
  14604                    offset_index,
  14605                    pool_number,
  14606                    direction,
  14607                    base_idx+offset_index,
  14608                    COMPILER_64_HI(value->bytes),
  14609                    COMPILER_64_LO(value->bytes)));
  14610     } else {
  14611         value->packets &= max_packet_mask;
  14612         /* Update Soft Copy */
  14613         flex_packet_counter[unit][direction][pipe_num][pool_number]
  14614                            [base_idx+offset_index] = value->packets;
  14615         /* Update Soft Copy */
  14616         COMPILER_64_SET(flex_packet64_counter[unit][direction][pipe_num][pool_number]
  14617                                          [base_idx+offset_index],0,
  14618                          value->packets);
  14619 
  14620         /* Change Read Hw Copy */
  14621         soc_mem_field_set(
  14622                 unit,
  14623                 mem,
  14624                 (uint32 *)&flex_temp_counter[unit][direction][0],
  14625                 PACKET_COUNTERf,
  14626                 &(value->packets));
  14627 #if defined(BCM_TRIDENT2_SUPPORT)
  14628         if (mem_dual) {
  14629             /* Set the Y-pipe value to 0 so that it does not contribute
  14630                to the sum value or the global view */
  14631             for (buffer_id = 0; buffer_id < _BCM_FLEX_STAT_BUFFS;
  14632                      buffer_id++) {
  14633                 flex_pkt_counter_x[unit][direction][pool_number]
  14634                                   [buffer_id][base_idx+offset_index]
  14635                                   = value->packets;
  14636                 flex_pkt_counter_y[unit][direction][pool_number]
  14637                                   [buffer_id][base_idx+offset_index]
  14638                                   = 0;
  14639             }
  14640             hw_val[0] = 0;
  14641             soc_mem_field_set(
  14642                 unit,
  14643                 mem_dual,
  14644                 (uint32 *)&flex_temp_counter_dual[unit][direction][0],
  14645                 PACKET_COUNTERf,
  14646                 &hw_val[0]);
  14647         }
  14648 #endif /* BCM_TRIDENT2_SUPPORT */
  14649         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  14650                   (BSL_META_U(unit,
  14651                               "Packet Count Value\t:COUTER-%d"
  14652                                "(@Pool:%dDirection:%dActualOffset%d) : %x \n"),
  14653                    offset_index,
  14654                    pool_number,
  14655                    direction,
  14656                    base_idx+offset_index,
  14657                    value->packets));
  14658     }
  14659     /* Update Hw Copy */
  14660     if (soc_mem_write(unit,mem,MEM_BLOCK_ALL,
  14661                 base_idx+offset_index,
  14662                 flex_temp_counter[unit][direction]) != BCM_E_NONE){
  14663         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  14664         return BCM_E_INTERNAL;
  14665     }
  14666 #if defined(BCM_TRIDENT2_SUPPORT)
  14667     if (mem_dual) {
  14668         if (soc_mem_write(unit,mem_dual,MEM_BLOCK_ALL,
  14669                     base_idx+offset_index,
  14670                     flex_temp_counter_dual[unit][direction]) != BCM_E_NONE){
  14671             BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  14672             return BCM_E_INTERNAL;
  14673         }
  14674     }
  14675 #endif /* BCM_TRIDENT2_SUPPORT*/
  14676     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  14677     return BCM_E_NONE;
  14678 }
  14679 
  14680 /*
  14681  * Function:
  14682  *      tomahawk_stat_flex_callback
  14683  * Description:
  14684         This is the tomahawk specific version of stat flex callback function
  14685  * Parameters:
  14686  *      unit                  - (IN) unit number
  14687  *
  14688  * Return Value:
  14689  *      none
  14690  * Notes:
  14691  *
  14692  * This function updates packet, byte counter values maintained in the flex
  14693  * counter software database. The ASCII diagram below illustrates how this
  14694  * accumulation is carried out
  14695  *
  14696  * packet_count, byte_count
  14697  *  .----------.
  14698  *  | H/W Flex |
  14699  *  | counter  |------------------        flex_packet_counter
  14700  *  | Residual |                  |         ------------
  14701  *  | Value    |                  |        | Flex       |
  14702  *  .----------.                  \/       | counter    |
  14703  *                                +------->| pkt, byte  |
  14704  *  .----------.                  /\       | software   |
  14705  *  | S/W Cache|                  |        | database   |
  14706  *  | evicted  |                  |         ------------
  14707  *  | counter  |------------------        flex_packet64_counter
  14708  *  | Value    |                          flex_byte_counter
  14709  *  .----------.                          residual_packet_counter
  14710  * pkt_ctr_new, byte_ctr_new              residual_byte_counter
  14711  *
  14712  * For each invocation of this function, the following happens
  14713  * a) Residual counter values are DMA'd from H/W for all pipes into
  14714  *    ctr_tbl_hw.
  14715  * b) pkt_ctr_new and byte_ctr_new are computed as the sum of all evicted
  14716  *    counter values across all pipes. Evicted counter values are stored
  14717  *    in soc->counter_sw_val[].
  14718  * c) packet_count and byte_count are computed as the sum of all residual
  14719  *    counter values across all pipes. These are the values that have been
  14720  *    DMA'd in step (a).
  14721  * d) The next step is dependent on whether counter eviction is enabled or not,
  14722  *    both scenarios are described below
  14723  *
  14724  *  Counter eviction is DISABLED
  14725  *  ----------------------------
  14726  *  For this case, packet_count, byte_count completely contain the current count
  14727  *  value and hence they can be assigned to the flex counter database fields
  14728  *  flex_packet_counter, flex_packet64_counter and flex_byte_counter. Since the
  14729  *  hardware counters are < 64 bits, software also handles wrap around correction.
  14730  *
  14731  *  Counter eviction is ENABLED
  14732  *  ---------------------------
  14733  *  For this case, packet_count, byte_count only contain the residual counter values,
  14734  *  post eviction. pkt_ctr_new and byte_ctr_new contain the evicted values. Hence the
  14735  *  total pkt/byte counter value is computed as a sum of pkt_ctr_new, packet_count and
  14736  *  byte_ctr_new, byte_count respectively. When counter eviction is enabled, software
  14737  *  has to accumulate the value of count, because H/W is cleared after every read.
  14738  *  The residual_packet_counter and residual_byte_counter databases are also updated
  14739  *  appropriately based on the residual counter values that were read during the iteration.
  14740  */
  14741 
  14742 STATIC
  14743 void tomahawk_stat_flex_callback (int unit)
  14744 {
  14745 #ifdef BCM_TOMAHAWK_SUPPORT
  14746     int alloc_size;
  14747     soc_mem_t mem=INVALIDm;
  14748     int mem_id;
  14749     int pipe;
  14750     uint64 pkt_ctr_new[SOC_MAX_NUM_PIPES];
  14751     uint64 byte_ctr_new[SOC_MAX_NUM_PIPES];
  14752     uint32 pkt_ctr_hw;
  14753     uint64 byte_ctr_hw, max_byte_count;
  14754     uint32 num_pools[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  14755     uint32 pool_id;
  14756     uint32 packet_count[4], old_pkt_count;
  14757     uint32 index, max_packet_count = 0;
  14758     uint32 byte_count_read[2];
  14759     uint32 flex_ctr_update_control_reg_value=0;
  14760     uint64 byte_count[4], old_byte_count, temp_count;
  14761     soc_control_t *soc;
  14762     soc_counter_evict_t *evict;
  14763     bcm_stat_flex_direction_t direction;
  14764     ing_flex_ctr_counter_table_0_entry_t *ctr_tbl_hw
  14765                     [BCM_STAT_FLEX_COUNTER_MAX_DIRECTION][SOC_MAX_NUM_PIPES];
  14766     int pipe_dma_done[SOC_MAX_NUM_PIPES];
  14767     uint32 size_pool[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  14768     soc_ctr_control_info_t ctrl_info;
  14769     soc_counter_non_dma_id_t pkt_ctr_id;
  14770     soc_counter_non_dma_id_t byte_ctr_id;
  14771     int rv, maxpipe = 1; /*maxpipe is > 1 only for multipipe devices */
  14772     size_pool[bcmStatFlexDirectionIngress]= SOC_INFO(unit).
  14773                                             size_flex_ingress_pool;
  14774     size_pool[bcmStatFlexDirectionEgress] = SOC_INFO(unit).
  14775                                             size_flex_egress_pool;
  14776 
  14777     soc = SOC_CONTROL(unit);
  14778 
  14779     for (direction = bcmStatFlexDirectionIngress;
  14780          direction < bcmStatFlexDirectionCount;
  14781          direction++) {
  14782         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
  14783             alloc_size= sizeof(ing_flex_ctr_counter_table_0_entry_t)*size_pool
  14784                            [direction];
  14785             ctr_tbl_hw[direction][pipe] = soc_cm_salloc(unit, alloc_size,
  14786                                  "flex counter table dma");
  14787             if (NULL == ctr_tbl_hw[direction][pipe]) {
  14788                 goto cleanup;
  14789             }
  14790             sal_memset(ctr_tbl_hw[direction][pipe], 0, alloc_size);
  14791         }
  14792     }
  14793 
  14794     num_pools[bcmStatFlexDirectionIngress]= SOC_INFO(unit).
  14795                                             num_flex_ingress_pools;
  14796     num_pools[bcmStatFlexDirectionEgress] = SOC_INFO(unit).
  14797                                             num_flex_egress_pools;
  14798 
  14799     COMPILER_64_ZERO(max_byte_count);
  14800     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  14801     for (direction = bcmStatFlexDirectionIngress;
  14802          direction < bcmStatFlexDirectionCount;
  14803          direction++) {
  14804          if (flex_temp_counter[unit][direction] == NULL) {
  14805              LOG_WARN(BSL_LS_BCM_FLEXCTR,
  14806                       (BSL_META_U(unit,
  14807                                   "Not Initilized or attached \n")));
  14808              continue;
  14809          }
  14810          for (pool_id = 0; pool_id < num_pools[direction]; pool_id++) {
  14811              maxpipe = 1;
  14812              if (BCM_TH_LOCAL_PIPE_MODE(unit, pool_id)) {
  14813                  /* In this mode, counters must be collected independently for each pipe. */
  14814                  maxpipe = NUM_PIPE(unit);
  14815              }
  14816              if (soc_reg32_get(
  14817                             unit,
  14818                             _pool_ctr_register[direction][pool_id],
  14819                             REG_PORT_ANY,
  14820                             0,
  14821                             &flex_ctr_update_control_reg_value) != SOC_E_NONE) {
  14822                  continue;
  14823              }
  14824              if (soc_reg_field_get(
  14825                                 unit,
  14826                                 _pool_ctr_register[direction][pool_id],
  14827                                 flex_ctr_update_control_reg_value,
  14828                                 COUNTER_POOL_ENABLEf) == 0) {
  14829                  continue;
  14830              }
  14831              /* read from eviction counter data base */
  14832              ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_POOL;
  14833              ctrl_info.instance = pool_id;
  14834              if (direction == bcmStatFlexDirectionEgress) {
  14835                  mem_id = pool_id + 1 + SOC_TH_STAT_ING_FLEX_POOL_MAX;
  14836                  pkt_ctr_id = SOC_COUNTER_NON_DMA_EGR_FLEX_PKT;
  14837                  byte_ctr_id = SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE;
  14838              } else {
  14839                  mem_id = pool_id + 1;
  14840                  pkt_ctr_id = SOC_COUNTER_NON_DMA_ING_FLEX_PKT;
  14841                  byte_ctr_id = SOC_COUNTER_NON_DMA_ING_FLEX_BYTE;
  14842                  if (maxpipe > 1) {
  14843                      ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_POOL_PIPE;
  14844                      ctrl_info.instance = pool_id << 4;
  14845                  }
  14846              }
  14847 
  14848              if (NULL == soc->counter_evict) {
  14849                  return;
  14850              }
  14851              evict = &soc->counter_evict[mem_id];
  14852 
  14853              for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
  14854                   mem = evict->mem[pipe];
  14855                   pipe_dma_done[pipe] = FALSE;
  14856                   max_packet_count = (1 << soc_mem_field_length(unit, mem,
  14857                                                                PACKET_COUNTERf));
  14858                   max_packet_count -= 1;
  14859                   COMPILER_64_SET(max_byte_count, 0, 1);
  14860                   COMPILER_64_SHL(max_byte_count, soc_mem_field_length(unit, mem,
  14861                                                                        BYTE_COUNTERf));
  14862                   COMPILER_64_SUB_32(max_byte_count, 1);
  14863 
  14864                  /* dma the current hw counter value which is not accounted for
  14865                   * in counter eviction processing.
  14866                   */
  14867                  if (soc_mem_read_range(
  14868                           unit,
  14869                           mem,
  14870                           MEM_BLOCK_ANY,
  14871                           soc_mem_index_min(unit,mem),
  14872                           soc_mem_index_max(unit,mem),
  14873                           ctr_tbl_hw[direction][pipe]) == BCM_E_NONE) {
  14874                      pipe_dma_done[pipe] = TRUE;
  14875                  }
  14876               }
  14877 
  14878               for (index = soc_mem_index_min(unit,mem);
  14879                    index <= soc_mem_index_max(unit,mem);
  14880                    index++) {
  14881                   for (pipe = 0; pipe < maxpipe; pipe++) {
  14882                        COMPILER_64_ZERO(pkt_ctr_new[pipe]);
  14883                        COMPILER_64_ZERO(byte_ctr_new[pipe]);
  14884 
  14885                        if (maxpipe > 1) {
  14886                            ctrl_info.instance = ((pool_id << 4) | pipe);
  14887                        }
  14888                        rv = soc_counter_generic_get(unit, pkt_ctr_id, ctrl_info,
  14889                                                     0, index, &pkt_ctr_new[pipe]);
  14890                        if (rv != SOC_E_NONE) {
  14891                            LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  14892                                      (BSL_META_U(unit,
  14893                                                  "Unable to retrieve evicted"
  14894                                                  " packet counter values unit - %d,"
  14895                                                  " pool - %d, counter index - %d\n"),
  14896                                       unit, pool_id, index));
  14897                            continue;
  14898                        }
  14899                        rv = soc_counter_generic_get(unit, byte_ctr_id, ctrl_info,
  14900                                                     0, index, &byte_ctr_new[pipe]);
  14901                        if (rv != SOC_E_NONE) {
  14902                            LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  14903                                      (BSL_META_U(unit,
  14904                                                  "Unable to retrieve evicted"
  14905                                                  " byte counter values unit - %d,"
  14906                                                  " pool - %d, counter index - %d\n"),
  14907                                       unit, pool_id, index));
  14908                            continue;
  14909                        }
  14910                    }
  14911 
  14912                    COMPILER_64_ZERO(byte_count[0]);
  14913                    packet_count[0] = 0;
  14914                    /* add up all pipes for hw counter */
  14915                    /* If the pool is allocated to IFP, and IFP is in pipe local mode
  14916                       store it in individual counters instead of adding up.
  14917                     */
  14918                    for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
  14919                        mem = evict->mem[pipe];
  14920                        /*coverity[uninit_use : FALSE] */
  14921                        if (pipe_dma_done[pipe] == FALSE) {
  14922                            continue;
  14923                        }
  14924 
  14925                        soc_mem_field_get(
  14926                                unit,
  14927                                mem,
  14928                                (uint32 *)&ctr_tbl_hw[direction][pipe][index],
  14929                                PACKET_COUNTERf,
  14930                                &pkt_ctr_hw);
  14931 
  14932                        if (BCM_TH_LOCAL_PIPE_MODE(unit, pool_id)) {
  14933                            packet_count[pipe] = pkt_ctr_hw;
  14934                        } else {
  14935                            packet_count[0] += pkt_ctr_hw;
  14936                        }
  14937 
  14938 
  14939                        soc_mem_field_get(
  14940                              unit,
  14941                              mem,
  14942                              (uint32 *)&ctr_tbl_hw[direction][pipe][index],
  14943                              BYTE_COUNTERf,
  14944                              byte_count_read);
  14945                        COMPILER_64_SET(byte_ctr_hw, byte_count_read[1],
  14946                                        byte_count_read[0]);
  14947                        if (BCM_TH_LOCAL_PIPE_MODE(unit, pool_id)) {
  14948                            COMPILER_64_SET(byte_count[pipe], byte_count_read[1],
  14949                                            byte_count_read[0]);
  14950                        } else {
  14951                            COMPILER_64_ADD_64(byte_count[0],byte_ctr_hw);
  14952                        }
  14953                    }
  14954 
  14955                    /* Device can operate in a mode with counter eviction
  14956                     * enabled or counter eviction disabled. When counter
  14957                     * eviction is disabled, accumulation occurs in hardware.
  14958                     * When counter eviction is enabled, CLEAR_ON_READ is set,
  14959                     * which causes h/w to be cleared on every read. Hence
  14960                     * software has to accumalate residual values. Total counter
  14961                     * value is then computed as the sum of accumulated residuals
  14962                     * and evicted value obtained from counter module.
  14963                     */
  14964                    if (0 == soc->ctr_evict_interval) {
  14965                        /* Account for possibility of overflow when
  14966                         * counter eviction is disabled
  14967                         */
  14968 
  14969                        for (pipe = 0; pipe < maxpipe; pipe++) {
  14970                            COMPILER_64_ZERO(temp_count);
  14971                            COMPILER_64_ADD_64(temp_count, flex_packet64_counter[unit]
  14972                                              [direction][pipe][pool_id][index]);
  14973                            COMPILER_64_SUB_64(temp_count, pkt_ctr_new[pipe]);
  14974                            COMPILER_64_SUB_64(temp_count, residual_packet_counter[unit]
  14975                                               [direction][pipe][pool_id][index]);
  14976                            old_pkt_count = COMPILER_64_LO(temp_count);
  14977                            if (old_pkt_count > packet_count[pipe]) {
  14978                                packet_count[pipe] += (max_packet_count - old_pkt_count);
  14979                            }
  14980 
  14981                            COMPILER_64_ZERO(temp_count);
  14982                            COMPILER_64_ADD_64(temp_count, flex_byte_counter[unit]
  14983                                              [direction][pipe][pool_id][index]);
  14984                            COMPILER_64_SUB_64(temp_count, byte_ctr_new[pipe]);
  14985                            COMPILER_64_SUB_64(temp_count, residual_byte_counter[unit]
  14986                                               [direction][pipe][pool_id][index]);
  14987                            COMPILER_64_ZERO(old_byte_count);
  14988                            COMPILER_64_ADD_64(old_byte_count, temp_count);
  14989                            if (COMPILER_64_GT(old_byte_count, byte_count[pipe])) {
  14990                                COMPILER_64_ZERO(temp_count);
  14991                                COMPILER_64_ADD_64(temp_count, max_byte_count);
  14992                                COMPILER_64_SUB_64(temp_count, old_byte_count);
  14993                                COMPILER_64_ADD_64(byte_count[pipe], temp_count);
  14994                            }
  14995                        }
  14996                     }
  14997                    /* The counter value is comprised of two parts, evicted value
  14998                     * plus the residual value in the hardware table. Here we
  14999                     * retrieve these two value at the same time, add up
  15000                     * and save to the global counter array
  15001                     */
  15002                    for (pipe = 0; pipe < maxpipe; pipe++) {
  15003                        COMPILER_64_ZERO(flex_packet64_counter[unit]
  15004                                         [direction][pipe][pool_id][index]);
  15005                        COMPILER_64_ADD_64(flex_packet64_counter[unit]
  15006                                           [direction][pipe][pool_id][index],
  15007                                           pkt_ctr_new[pipe]);
  15008                        COMPILER_64_ADD_64(flex_packet64_counter[unit]
  15009                                           [direction][pipe][pool_id][index],
  15010                                           residual_packet_counter[unit]
  15011                                           [direction][pipe][pool_id][index]);
  15012                        COMPILER_64_ADD_32(flex_packet64_counter[unit]
  15013                                           [direction][pipe][pool_id][index],
  15014                                           packet_count[pipe]);
  15015                        flex_packet_counter[unit][direction][pipe][pool_id][index]
  15016                            = COMPILER_64_LO(flex_packet64_counter[unit]
  15017                                             [direction][pipe][pool_id][index]);
  15018                        COMPILER_64_ZERO(flex_byte_counter[unit]
  15019                                         [direction][pipe][pool_id][index]);
  15020                        COMPILER_64_ADD_64(flex_byte_counter[unit]
  15021                                           [direction][pipe][pool_id][index],
  15022                                           byte_ctr_new[pipe]);
  15023                        COMPILER_64_ADD_64(flex_byte_counter[unit]
  15024                                           [direction][pipe][pool_id][index],
  15025                                           residual_byte_counter[unit]
  15026                                           [direction][pipe][pool_id][index]);
  15027                        COMPILER_64_ADD_64(flex_byte_counter[unit]
  15028                                           [direction][pipe][pool_id][index],
  15029                                           byte_count[pipe]);
  15030                        if (soc->ctr_evict_interval) {
  15031                            /* Update packet and byte counter residuals only
  15032                             * if counter eviction is enabled
  15033                             */
  15034                            COMPILER_64_ADD_32(residual_packet_counter[unit]
  15035                                               [direction][pipe][pool_id][index],
  15036                                               packet_count[pipe]);
  15037                            COMPILER_64_ADD_64(residual_byte_counter[unit]
  15038                                               [direction][pipe][pool_id][index],
  15039                                               byte_count[pipe]);
  15040                        }
  15041                   }
  15042             }
  15043          }
  15044     }
  15045     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  15046 
  15047 cleanup:    
  15048     for (direction = bcmStatFlexDirectionIngress;
  15049          direction < bcmStatFlexDirectionCount;
  15050          direction++) {
  15051         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
  15052             if (ctr_tbl_hw[direction][pipe] != NULL) {
  15053                 soc_cm_sfree(unit, ctr_tbl_hw[direction][pipe]);
  15054             }
  15055         }
  15056     }
  15057 #endif
  15058     return;
  15059 }
  15060 
  15061 /*      _bcm_flex_stat_data32_rollover
  15062  * Description:
  15063  *      deal with the n-bits(n <= 32) data rollover case
  15064  *      and add the diff to the 64-bits data.
  15065  * Parameters:
  15066  *      pre                  - (IN) previous n-bits data
  15067  *      cur                  - (IN) current n-bits data
  15068  *      roll_size          - (IN) the size when n-bits data rollovers
  15069  *      sum                - (OUT) the summary of diff between pre and cur.
  15070  * Return Value:
  15071  *      None
  15072  * Notes:
  15073  *      None
  15074  */
  15075 STATIC void
  15076 _bcm_flex_stat_data32_rollover(uint32 pre, uint32 cur,
  15077                                uint64 roll_size, uint64 *sum)
  15078 {
  15079     uint64  cur64, pre64;
  15080 
  15081     if (cur == pre) {
  15082         return;
  15083     } else if (cur > pre) {
  15084         COMPILER_64_SET(cur64, 0, (cur - pre));
  15085     } else {
  15086         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15087                     (BSL_META("Roll over  happend \n")));
  15088         COMPILER_64_SET(cur64, 0, cur);
  15089         COMPILER_64_SET(pre64, 0, pre);
  15090         COMPILER_64_ADD_64(cur64, roll_size);
  15091         COMPILER_64_SUB_64(cur64, pre64);
  15092     }
  15093 
  15094     COMPILER_64_ADD_64(*sum, cur64);
  15095     return;
  15096 }
  15097 
  15098 /*
  15099  * Function:
  15100  *      _bcm_flex_stat_data64_rollover
  15101  * Description:
  15102  *      deal with the n-bits(32< n < 64) data rollover case
  15103  *      and add the diff to the 64-bits data.
  15104  * Parameters:
  15105  *      pre                  - (IN) previous n-bits data
  15106  *      cur                  - (IN) current n-bits data
  15107  *      roll_size          - (IN) the size when n-bits data rollovers
  15108  *      sum                - (OUT) the summary of diff between pre and cur.
  15109  * Return Value:
  15110  *      None
  15111  * Notes:
  15112  *      None
  15113  */
  15114 STATIC void
  15115 _bcm_flex_stat_data64_rollover(uint64 pre, uint64 cur,
  15116                                uint64 roll_size, uint64 *sum)
  15117 {
  15118     uint64  max_byte_mask;
  15119 
  15120     if (sum == NULL) {
  15121         return;
  15122     }
  15123 
  15124     COMPILER_64_ZERO(max_byte_mask);
  15125     COMPILER_64_SET(max_byte_mask,
  15126                     COMPILER_64_HI(roll_size),
  15127                     COMPILER_64_LO(roll_size));
  15128 
  15129     COMPILER_64_SUB_32(max_byte_mask,1);
  15130 
  15131     COMPILER_64_AND(pre, max_byte_mask);
  15132     COMPILER_64_AND(cur, max_byte_mask);
  15133     if (COMPILER_64_GT(pre, cur)) {
  15134         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15135                     (BSL_META("Roll over  happend \n")));
  15136         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15137                     (BSL_META("...Read Byte Count    : %x:%x\n"),
  15138                      COMPILER_64_HI(cur),
  15139                      COMPILER_64_LO(cur)));
  15140         COMPILER_64_ADD_64(cur, roll_size);
  15141         COMPILER_64_SUB_64(cur,pre);
  15142         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15143                     (BSL_META("...Diffed Byte Count    : %x:%x\n"),
  15144                      COMPILER_64_HI(cur),
  15145                      COMPILER_64_LO(cur)));
  15146     } else {
  15147         COMPILER_64_SUB_64(cur, pre);
  15148     }
  15149     /* Add difference (if it is) */
  15150     if (!COMPILER_64_IS_ZERO(cur)) {
  15151         COMPILER_64_ADD_64(*sum, cur);
  15152         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15153                     (BSL_META("New Byte Count Value : %x:%x\n"),
  15154                      COMPILER_64_HI(*sum),
  15155                      COMPILER_64_LO(*sum)));
  15156     }
  15157     return;
  15158 }
  15159 
  15160 /*
  15161  * Function:
  15162  *      _bcm_esw_stat_flex_counter_collect
  15163  * Description:
  15164  *      Flex Counter accumulation routine called periodically
  15165  *      to sync s/w copy with h/w copy.
  15166  * Parameters:
  15167  *      unit                  - (IN) unit number
  15168  *      cnt_direction         - (IN) counter direction
  15169  *                                   if -1 accumulate for all counters
  15170  *                                      for ingress and egress else
  15171  *                                   retrieve a specific counter
  15172  *      flexctr_poll          - (IN) Ingress or Egress flex counter pool
  15173  *                                   if -1 Both Ingress and Egress pools
  15174  *                                   else Ingress or Egress pool.
  15175  *      counter_idx           - (IN) counter index.
  15176  *                                   if -1 accumulate for all counters
  15177  *                                   else retrieve a specific counter.
  15178  * Return Value:
  15179  *      None
  15180  * Notes:
  15181  *       This routine accumulates all the flex counters and
  15182  *       update the software copy of the flex counters.
  15183  *       Counter thread invokes periodically this routine.
  15184  *       If counter index is not -1 then only a specific counter
  15185  *       value is read from harware and synced to the software copy.
  15186  *       used by all the counter_sync_get API's
  15187  */
  15188 STATIC void
  15189 _bcm_esw_stat_flex_counter_collect(int                       unit,
  15190                                    bcm_stat_flex_direction_t cnt_direction,
  15191                                    uint32                    flexctr_pool,
  15192                                    uint32                    counter_idx)
  15193 {
  15194     soc_mem_t mem;
  15195 #if defined(BCM_TRIDENT2_SUPPORT)
  15196     soc_mem_t mem_dual = 0;
  15197 #endif /* BCM_TRIDENT2_SUPPORT*/
  15198 
  15199     uint32    num_pools[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  15200     uint32    pool_id = 0;
  15201     bcm_stat_flex_direction_t direction = bcmStatFlexDirectionIngress;
  15202     uint32    packet_count=0;
  15203     uint32    index;
  15204     uint32    zero=0;
  15205     uint32    one=1;
  15206     uint32    flex_ctr_update_control_reg_value=0;
  15207     uint64    byte_count;
  15208     uint64    prev_masked_byte_count;
  15209     uint64    max_byte_size;
  15210     uint64    max_byte_mask;
  15211     soc_memacc_t memacc_pkt_x;
  15212     soc_memacc_t memacc_byte_x;
  15213 #if defined(BCM_TRIDENT2_SUPPORT)
  15214     soc_memacc_t memacc_pkt_y;
  15215     soc_memacc_t memacc_byte_y;
  15216     uint64       *byte_cur_ptr_x, *byte_cur_ptr_y;
  15217     uint32       *pkt_cur_ptr_x, *pkt_cur_ptr_y;
  15218     uint8     toggle = 0;
  15219 #endif
  15220     uint64    packet64_count;
  15221     uint64    prev_masked_packet64_count;
  15222     uint64    max_packet64_size;
  15223     uint64    max_packet64_mask;
  15224     uint32    mem_index_min;
  15225     uint32    mem_index_max;
  15226     uint32    max_directions = BCM_STAT_FLEX_COUNTER_MAX_DIRECTION;
  15227     int pipe_num = 0;
  15228 
  15229     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
  15230         tomahawk_stat_flex_callback(unit);
  15231         return;
  15232     }
  15233 
  15234     COMPILER_64_ZERO(byte_count);
  15235     COMPILER_64_ZERO(prev_masked_byte_count);
  15236     COMPILER_64_ZERO(max_byte_size);
  15237     COMPILER_64_ZERO(max_byte_mask);
  15238 
  15239     COMPILER_64_ZERO(packet64_count);
  15240     COMPILER_64_ZERO(prev_masked_packet64_count);
  15241     COMPILER_64_ZERO(max_packet64_size);
  15242     COMPILER_64_ZERO(max_packet64_mask);
  15243 
  15244 
  15245     num_pools[bcmStatFlexDirectionIngress]= SOC_INFO(unit).
  15246                                             num_flex_ingress_pools;
  15247     num_pools[bcmStatFlexDirectionEgress] = SOC_INFO(unit).
  15248                                             num_flex_egress_pools;
  15249     /*
  15250     size_pool[bcmStatFlexDirectionIngress]= SOC_INFO(unit).
  15251                                             size_flex_ingress_pool;
  15252     size_pool[bcmStatFlexDirectionEgress] = SOC_INFO(unit).
  15253                                             size_flex_egress_pool;
  15254      */
  15255 
  15256     /*
  15257      * if counter_idx != -1, request is to sync
  15258      * sw count with hw count of a specific counter
  15259      */
  15260     if (counter_idx != -1) {
  15261         if ((cnt_direction < bcmStatFlexDirectionIngress) ||
  15262             (cnt_direction > bcmStatFlexDirectionEgress)) {
  15263             return;
  15264         }
  15265 
  15266         direction = cnt_direction;
  15267         max_directions = direction + 1;
  15268 
  15269         /* coverity[unsigned_compare : FALSE] */
  15270         if ((flexctr_pool > num_pools[direction]) || (flexctr_pool < 0)) {
  15271             return;
  15272         }
  15273         pool_id = flexctr_pool;
  15274         num_pools[direction] = pool_id + 1;
  15275     } else {
  15276         flexctr_pool = 0;
  15277     }
  15278 
  15279     /*Not Tomahawk */
  15280     mem = _ctr_counter_table[direction][pool_id];
  15281 
  15282     COMPILER_64_SET(max_byte_size, zero, one);
  15283     COMPILER_64_SHL(max_byte_size,soc_mem_field_length(unit,mem,BYTE_COUNTERf));
  15284 
  15285     COMPILER_64_SET(max_byte_mask,
  15286                     COMPILER_64_HI(max_byte_size),
  15287                     COMPILER_64_LO(max_byte_size));
  15288     COMPILER_64_SUB_32(max_byte_mask,one);
  15289 
  15290 
  15291     COMPILER_64_SET(max_packet64_size, zero, one);
  15292     COMPILER_64_SHL(max_packet64_size,soc_mem_field_length(unit,mem,PACKET_COUNTERf));
  15293 
  15294     COMPILER_64_SET(max_packet64_mask,
  15295                     COMPILER_64_HI(max_packet64_size),
  15296                     COMPILER_64_LO(max_packet64_size));
  15297     COMPILER_64_SUB_32(max_packet64_mask,one);
  15298 
  15299     for ( ; direction < max_directions; direction++) {
  15300         if (flex_temp_counter[unit][direction] == NULL) {
  15301             LOG_WARN(BSL_LS_BCM_FLEXCTR,
  15302                      (BSL_META_U(unit,
  15303                                  "Not Initilized or attached \n")));
  15304             continue;
  15305         }
  15306 #if defined(BCM_TRIDENT2_SUPPORT)
  15307         if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
  15308             if (flex_temp_counter_dual[unit][direction] == NULL) {
  15309                 LOG_WARN(BSL_LS_BCM_FLEXCTR,
  15310                          (BSL_META_U(unit,
  15311                                      "Not Initilized or attached \n")));
  15312                 continue;
  15313             }
  15314          }
  15315 #endif
  15316         for (pool_id = flexctr_pool; pool_id < num_pools[direction]; pool_id++){
  15317             if (soc_reg32_get(
  15318                             unit,
  15319                             _pool_ctr_register[direction][pool_id],
  15320                             REG_PORT_ANY,
  15321                             0,
  15322                             &flex_ctr_update_control_reg_value) != SOC_E_NONE) {
  15323                 continue;
  15324             }
  15325             if (soc_reg_field_get(
  15326                             unit,
  15327                             _pool_ctr_register[direction][pool_id],
  15328                             flex_ctr_update_control_reg_value,
  15329                             COUNTER_POOL_ENABLEf) == 0) {
  15330                 continue;
  15331             }
  15332 #if defined(BCM_TRIDENT2_SUPPORT)
  15333             if (!(SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit))
  15334                    && soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
  15335                 mem = _ctr_counter_table_x[direction][pool_id];
  15336                 mem_dual = _ctr_counter_table_y[direction][pool_id];
  15337 
  15338             } else
  15339 #endif
  15340             {
  15341 #if defined(BCM_TOMAHAWK_SUPPORT)
  15342                 _CTR_COUNTER_TABLE_IFP(unit, direction, pipe_num, pool_id, mem);
  15343 #else
  15344                 mem = _ctr_counter_table[direction][pool_id];
  15345 #endif
  15346             }
  15347 
  15348             mem_index_min = soc_mem_index_min(unit, mem);
  15349             mem_index_max = soc_mem_index_max(unit, mem);
  15350 
  15351             /*
  15352              * if counter_idx != -1, retrieve specific
  15353              * counter index from the flex counter memory pool.
  15354              */
  15355             if (counter_idx != -1) {
  15356                 if ((counter_idx < mem_index_min) ||
  15357                     (counter_idx > mem_index_max)) {
  15358                     return;
  15359                 }
  15360                 mem_index_min = mem_index_max = counter_idx;
  15361             }
  15362 
  15363             /* read all the counters or a specific counter from memory */
  15364             if (counter_idx == -1 ) {
  15365                 if (soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
  15366                                        mem_index_min, mem_index_max,
  15367                                        flex_temp_counter[unit][direction])
  15368                                        != BCM_E_NONE) {
  15369                     return;
  15370                 }
  15371             } else {
  15372                 if (soc_mem_read(unit, mem, MEM_BLOCK_ANY,
  15373                                  counter_idx,
  15374                                 &flex_temp_counter[unit][direction][counter_idx])
  15375                                  != BCM_E_NONE) {
  15376                     return;
  15377                 }
  15378             }
  15379 
  15380             if (((soc_memacc_init(unit, mem, PACKET_COUNTERf, &memacc_pkt_x))) ||
  15381                 ((soc_memacc_init(unit, mem, BYTE_COUNTERf, &memacc_byte_x)))) {
  15382                   return;
  15383             }
  15384 
  15385 #if defined(BCM_TRIDENT2_SUPPORT)
  15386             if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
  15387                 /* read all the counters or a specific counter from memory */
  15388                 if (counter_idx == -1 ) {
  15389                     if (soc_mem_read_range(
  15390                                        unit, mem_dual, MEM_BLOCK_ANY,
  15391                                        mem_index_min, mem_index_max,
  15392                                        flex_temp_counter_dual[unit][direction])
  15393                                        != BCM_E_NONE) {
  15394                         return;
  15395                     }
  15396                 } else {
  15397                     if (soc_mem_read(unit, mem_dual, MEM_BLOCK_ANY,
  15398                           counter_idx,
  15399                           &flex_temp_counter_dual[unit][direction][counter_idx])
  15400                                  != BCM_E_NONE) {
  15401                         return;
  15402                     }
  15403                 }
  15404 
  15405                 if (((soc_memacc_init(unit, mem_dual, PACKET_COUNTERf, &memacc_pkt_y))) ||
  15406                     ((soc_memacc_init(unit, mem_dual, BYTE_COUNTERf, &memacc_byte_y)))) {
  15407                     return;
  15408                 }
  15409 
  15410                 if (flex_byte_counter_x[unit][direction][pool_id][0] == NULL) {
  15411                     LOG_WARN(BSL_LS_BCM_FLEXCTR,
  15412                              (BSL_META_U(unit,
  15413                                          "Not Initilized or attached \n")));
  15414                     continue;
  15415                 }
  15416 
  15417                 if (flex_pkt_counter_x[unit][direction][pool_id][0] == NULL) {
  15418                     LOG_WARN(BSL_LS_BCM_FLEXCTR,
  15419                              (BSL_META_U(unit,
  15420                                          "Not Initilized or attached \n")));
  15421                     continue;
  15422                 }
  15423 
  15424                 if (flex_byte_counter_y[unit][direction][pool_id][0] == NULL) {
  15425                     LOG_WARN(BSL_LS_BCM_FLEXCTR,
  15426                              (BSL_META_U(unit,
  15427                                          "Not Initilized or attached \n")));
  15428                     continue;
  15429                 }
  15430 
  15431                 if (flex_pkt_counter_y[unit][direction][pool_id][0] == NULL) {
  15432                     LOG_WARN(BSL_LS_BCM_FLEXCTR,
  15433                              (BSL_META_U(unit,
  15434                                          "Not Initilized or attached \n")));
  15435                     continue;
  15436                 }
  15437             }
  15438 #endif /* BCM_TRIDENT2_SUPPORT*/
  15439 
  15440             for (index = mem_index_min; index <= mem_index_max; index++) {
  15441                 packet_count = soc_memacc_field32_get(&memacc_pkt_x,
  15442                             (uint32 *)&flex_temp_counter[unit][direction][index]);
  15443 #if defined(BCM_TRIDENT2_SUPPORT)
  15444                 if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
  15445                     uint32 dual_packet_count;
  15446                     toggle = flex_counter_toggle[unit][direction][pool_id][index];
  15447                     pkt_cur_ptr_x =
  15448                         flex_pkt_counter_x[unit][direction][pool_id][toggle]
  15449                         + index;
  15450                     *pkt_cur_ptr_x = packet_count;
  15451                     _bcm_flex_stat_data32_rollover(flex_pkt_counter_x[unit]
  15452                                                    [direction][pool_id][!toggle]
  15453                                                    [index],
  15454                                                    *pkt_cur_ptr_x,
  15455                                                    max_packet64_size,
  15456                                                    flex_packet64_counter[unit]
  15457                                                    [direction][pipe_num][pool_id] + index
  15458                                                    );
  15459 
  15460                     dual_packet_count = soc_memacc_field32_get(&memacc_pkt_y,
  15461                                 (uint32 *)&flex_temp_counter_dual[unit][direction][index]);
  15462                     pkt_cur_ptr_y =
  15463                         flex_pkt_counter_y[unit][direction][pool_id][toggle]
  15464                         + index;
  15465                     *pkt_cur_ptr_y = dual_packet_count;
  15466                     _bcm_flex_stat_data32_rollover(flex_pkt_counter_y[unit]
  15467                                                    [direction][pool_id]
  15468                                                    [!toggle][index],
  15469                                                    *pkt_cur_ptr_y,
  15470                                                    max_packet64_size,
  15471                                                    flex_packet64_counter[unit]
  15472                                                    [direction][pipe_num][pool_id] + index
  15473                                                    );
  15474                     packet_count += dual_packet_count;
  15475                 }
  15476 #endif /* BCM_TRIDENT2_SUPPORT*/
  15477                 if (flex_packet_counter[unit][direction][pipe_num][pool_id][index]
  15478                     != packet_count) {
  15479                     LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15480                                 (BSL_META_U(unit,
  15481                                             "Direction:%dPool:%d==>"
  15482                                              "Old Packet Count Value\t:"
  15483                                              "Index:%d %x\tNew Packet Count Value %x\n"),
  15484                                  direction,
  15485                                  pool_id,
  15486                                  index,
  15487                                  flex_packet_counter[unit]
  15488                                  [direction][pipe_num][pool_id][index],
  15489                                  packet_count));
  15490                     flex_packet_counter[unit][direction][pipe_num][pool_id][index] =
  15491                                packet_count;
  15492                 }
  15493 
  15494                 soc_memacc_field64_get(&memacc_byte_x,
  15495                             (uint32 *)&flex_temp_counter[unit][direction][index],
  15496                             &byte_count);
  15497 
  15498 #if defined(BCM_TRIDENT2_SUPPORT)
  15499                 if (soc_feature(unit, soc_feature_advanced_flex_counter_dual_pipe)) {
  15500                     uint64 dual_byte_count;
  15501 
  15502                     byte_cur_ptr_x =
  15503                         flex_byte_counter_x[unit][direction][pool_id][toggle]
  15504                         + index;
  15505                     COMPILER_64_SET(*byte_cur_ptr_x,
  15506                                     COMPILER_64_HI(byte_count),
  15507                                     COMPILER_64_LO(byte_count));
  15508                     _bcm_flex_stat_data64_rollover(flex_byte_counter_x[unit]
  15509                                                    [direction][pool_id]
  15510                                                    [!toggle][index],
  15511                                                    *byte_cur_ptr_x,
  15512                                                    max_byte_size,
  15513                                                    flex_byte_counter[unit]
  15514                                                    [direction][0][pool_id] + index
  15515                                                    );
  15516 
  15517                     soc_memacc_field64_get(&memacc_byte_y,
  15518                         (uint32 *)&flex_temp_counter_dual[unit][direction][index],
  15519                         &dual_byte_count);
  15520                     byte_cur_ptr_y =
  15521                         flex_byte_counter_y[unit][direction][pool_id][toggle]
  15522                         + index;
  15523                     COMPILER_64_SET(*byte_cur_ptr_y,
  15524                                     COMPILER_64_HI(dual_byte_count),
  15525                                     COMPILER_64_LO(dual_byte_count));
  15526                     _bcm_flex_stat_data64_rollover(flex_byte_counter_y[unit]
  15527                                                    [direction][pool_id]
  15528                                                    [!toggle][index],
  15529                                                    *byte_cur_ptr_y,
  15530                                                    max_byte_size,
  15531                                                    flex_byte_counter[unit]
  15532                                                    [direction][0][pool_id] + index
  15533                                                    );
  15534                     flex_counter_toggle[unit][direction][pool_id][index]= !toggle;
  15535                     continue;
  15536                 }
  15537 #endif /* BCM_TRIDENT2_SUPPORT*/
  15538 
  15539 
  15540                    COMPILER_64_SET(packet64_count,0, packet_count);
  15541                    COMPILER_64_SET(prev_masked_packet64_count,
  15542                                    COMPILER_64_HI(flex_packet64_counter[unit]
  15543                                                   [direction][pipe_num][pool_id][index]),
  15544                                    COMPILER_64_LO(flex_packet64_counter[unit]
  15545                                                   [direction][pipe_num][pool_id][index]));
  15546                    COMPILER_64_AND(prev_masked_packet64_count,max_packet64_mask);
  15547                    if (COMPILER_64_GT(prev_masked_packet64_count, packet64_count)) {
  15548                        LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15549                                    (BSL_META_U(unit,
  15550                                                "Roll over  happend \n")));
  15551                        LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15552                                    (BSL_META_U(unit,
  15553                                                "...Read Packet64 Count    : %x:%x\n"),
  15554                                     COMPILER_64_HI(packet64_count),
  15555                                     COMPILER_64_LO(packet64_count)));
  15556                        COMPILER_64_ADD_64(packet64_count,max_packet64_size);
  15557                        COMPILER_64_SUB_64(packet64_count,prev_masked_packet64_count);
  15558                        LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15559                                    (BSL_META_U(unit,
  15560                                                "...Diffed 64-Packet Count    : %x:%x\n"),
  15561                                     COMPILER_64_HI(packet64_count),
  15562                                     COMPILER_64_LO(packet64_count)));
  15563                    } else {
  15564                        COMPILER_64_SUB_64(packet64_count,prev_masked_packet64_count);
  15565                    }
  15566                    /* Add difference (if it is) */
  15567                    if (!COMPILER_64_IS_ZERO(packet64_count)) {
  15568                        LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15569                                    (BSL_META_U(unit,
  15570                                                "Direction:%dPool:%d==>"
  15571                                                 "Old 64-Packet Count Value\t"
  15572                                                 ":Index:%d %x:%x\t"),
  15573                                     direction,pool_id,index,
  15574                                     COMPILER_64_HI(flex_packet64_counter[unit]
  15575                                     [direction][pipe_num][pool_id][index]),
  15576                                     COMPILER_64_LO(flex_packet64_counter[unit]
  15577                                     [direction][pipe_num][pool_id][index])));
  15578                        COMPILER_64_ADD_64(flex_packet64_counter[unit]
  15579                                           [direction][pipe_num][pool_id][index],
  15580                                           packet64_count);
  15581                        LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15582                                    (BSL_META_U(unit,
  15583                                                "New 64-Packet Value : %x:%x\n"),
  15584                                     COMPILER_64_HI(flex_packet64_counter[unit]
  15585                                     [direction][pipe_num][pool_id][index]),
  15586                                     COMPILER_64_LO(flex_packet64_counter[unit][direction]
  15587                                     [pipe_num][pool_id][index])));
  15588                    }
  15589 
  15590 
  15591 
  15592                    COMPILER_64_SET(prev_masked_byte_count,
  15593                                    COMPILER_64_HI(flex_byte_counter[unit]
  15594                                                   [direction][pipe_num][pool_id][index]),
  15595                                    COMPILER_64_LO(flex_byte_counter[unit]
  15596                                                   [direction][pipe_num][pool_id][index]));
  15597                    COMPILER_64_AND(prev_masked_byte_count,max_byte_mask);
  15598                    if (COMPILER_64_GT(prev_masked_byte_count, byte_count)) {
  15599                        LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15600                                    (BSL_META_U(unit,
  15601                                                "Roll over  happend \n")));
  15602                        LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15603                                    (BSL_META_U(unit,
  15604                                                "...Read Byte Count    : %x:%x\n"),
  15605                                     COMPILER_64_HI(byte_count),
  15606                                     COMPILER_64_LO(byte_count)));
  15607                        COMPILER_64_ADD_64(byte_count,max_byte_size);
  15608                        COMPILER_64_SUB_64(byte_count,prev_masked_byte_count);
  15609                        LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15610                                    (BSL_META_U(unit,
  15611                                                "...Diffed Byte Count    : %x:%x\n"),
  15612                                     COMPILER_64_HI(byte_count),
  15613                                     COMPILER_64_LO(byte_count)));
  15614                    } else {
  15615                        COMPILER_64_SUB_64(byte_count,prev_masked_byte_count);
  15616                    }
  15617                    /* Add difference (if it is) */
  15618                    if (!COMPILER_64_IS_ZERO(byte_count)) {
  15619                        LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15620                                    (BSL_META_U(unit,
  15621                                                "Direction:%dPool:%d==>"
  15622                                                 "Old Byte Count Value\t"
  15623                                                 ":Index:%d %x:%x\t"),
  15624                                     direction,pool_id,index,
  15625                                     COMPILER_64_HI(flex_byte_counter[unit]
  15626                                     [direction][pipe_num][pool_id][index]),
  15627                                     COMPILER_64_LO(flex_byte_counter[unit]
  15628                                     [direction][pipe_num][pool_id][index])));
  15629                        COMPILER_64_ADD_64(flex_byte_counter[unit]
  15630                                           [direction][pipe_num][pool_id][index],
  15631                                           byte_count);
  15632                        LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  15633                                    (BSL_META_U(unit,
  15634                                                "New Byte Count Value : %x:%x\n"),
  15635                                     COMPILER_64_HI(flex_byte_counter[unit]
  15636                                     [direction][pipe_num][pool_id][index]),
  15637                                     COMPILER_64_LO(flex_byte_counter[unit][direction]
  15638                                     [pipe_num][pool_id][index])));
  15639                    }
  15640               }
  15641          }
  15642     }
  15643     return;
  15644 }
  15645 /*
  15646  * Function:
  15647  *      _bcm_esw_stat_flex_callback
  15648  * Description:
  15649  *      Flex Counter threads callback function. It is called periodically
  15650  *      to sync s/w copy with h/w copy.
  15651  * Parameters:
  15652  *      unit                  - (IN) unit number
  15653  * Return Value:
  15654  *      BCM_E_XXX
  15655  * Notes:
  15656  */
  15657 void _bcm_esw_stat_flex_callback(int unit)
  15658 {
  15659     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  15660     _bcm_esw_stat_flex_counter_collect(unit, -1, -1, -1);
  15661     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  15662 
  15663     return;
  15664 }
  15665 
  15666 /*
  15667  * Function:
  15668  *      _bcm_esw_stat_flex_get_table_info
  15669  * Description:
  15670  *      Get Table related Information based on accounting object value
  15671  * Parameters:
  15672  *      object                - (IN) Flex Accounting Object
  15673  *      table                 - (OUT) Flex Accounting Table
  15674  *      direction             - (OUT) Flex Data flow direction
  15675  * Return Value:
  15676  *      BCM_E_XXX
  15677  * Notes:
  15678  */
  15679 bcm_error_t _bcm_esw_stat_flex_get_table_info(
  15680             int                       unit,
  15681             bcm_stat_object_t         object,
  15682             uint32                    expected_num_tables,
  15683             uint32                    *actual_num_tables,
  15684             soc_mem_t                 *table,
  15685             bcm_stat_flex_direction_t *direction)
  15686 {
  15687     if (expected_num_tables < 1) {
  15688         return BCM_E_PARAM;
  15689     }
  15690     switch((int32)object) {
  15691     case bcmStatObjectIngPort:
  15692 #if defined(BCM_TRIDENT3_SUPPORT)
  15693          if (SOC_IS_TRIDENT3X(unit)) {
  15694              *table = LPORT_TABm;
  15695              *direction= bcmStatFlexDirectionIngress;
  15696          } else
  15697 #endif
  15698          {
  15699              *table=PORT_TABm;
  15700              *direction= bcmStatFlexDirectionIngress;
  15701          }
  15702          break;
  15703     case bcmStatObjectIngVlan:
  15704          *table=VLAN_TABm;
  15705          *direction= bcmStatFlexDirectionIngress;
  15706          break;
  15707     case bcmStatObjectIngVlanXlate:
  15708     case bcmStatObjectIngVlanXlateSecondLookup:
  15709 #if defined(BCM_TRIUMPH3_SUPPORT)
  15710          if (SOC_IS_TRIUMPH3(unit)) {
  15711              *table=VLAN_XLATE_EXTDm;
  15712              *direction= bcmStatFlexDirectionIngress;
  15713          } else
  15714 #endif
  15715 #if defined(BCM_TRIDENT3_SUPPORT)
  15716       if (SOC_IS_TRIDENT3X(unit)) {
  15717           if ((*actual_num_tables) < expected_num_tables) {
  15718               table[(*actual_num_tables)++] = VLAN_XLATE_1_DOUBLEm;
  15719           }
  15720           if ((*actual_num_tables) < expected_num_tables) {
  15721               table[(*actual_num_tables)] = VLAN_XLATE_2_DOUBLEm;
  15722           }
  15723           *direction= bcmStatFlexDirectionIngress;
  15724       } else
  15725 #endif
  15726          {
  15727              *table=VLAN_XLATEm;
  15728              *direction= bcmStatFlexDirectionIngress;
  15729          }
  15730          break;
  15731     case bcmStatObjectIngVfi:
  15732          *table=VFIm;
  15733          *direction= bcmStatFlexDirectionIngress;
  15734          break;
  15735     case bcmStatObjectIngL3Intf:
  15736          *table=L3_IIFm;
  15737          *direction= bcmStatFlexDirectionIngress;
  15738          break;
  15739     case bcmStatObjectIngVrf:
  15740 #if defined(BCM_TRIDENT3_SUPPORT)
  15741          if (SOC_IS_TRIDENT3X(unit)) {
  15742              *table = VRF_ATTRS_2m;
  15743          } else
  15744 #endif
  15745          {
  15746              *table=VRFm;
  15747          }
  15748          *direction= bcmStatFlexDirectionIngress;
  15749          break;
  15750     case bcmStatObjectIngPolicy:
  15751          *table=VFP_POLICY_TABLEm;
  15752          *direction= bcmStatFlexDirectionIngress;
  15753          break;
  15754     case bcmStatObjectIngNiv:
  15755     case bcmStatObjectIngMplsVcLabel:
  15756     case bcmStatObjectIngGport:
  15757          *table=SOURCE_VPm;
  15758          *direction= bcmStatFlexDirectionIngress;
  15759          break;
  15760     case bcmStatObjectIngMplsSwitchLabel:
  15761     case bcmStatObjectIngMplsSwitchSecondLabel:
  15762 #if defined(BCM_TRIUMPH3_SUPPORT)
  15763          if (SOC_IS_TRIUMPH3(unit)) {
  15764              *table=MPLS_ENTRY_EXTDm;
  15765              *direction= bcmStatFlexDirectionIngress;
  15766          } else
  15767 #endif
  15768          {
  15769              *table=MPLS_ENTRYm;
  15770 #if defined(BCM_TOMAHAWK3_SUPPORT)
  15771              if (SOC_IS_TOMAHAWK3(unit)){
  15772                  *table= MPLS_ENTRY_SINGLEm;
  15773              }
  15774 #endif
  15775              *direction= bcmStatFlexDirectionIngress;
  15776          }
  15777          break;
  15778 #if defined(BCM_TRIUMPH3_SUPPORT)
  15779     case bcmStatObjectIngMplsFrrLabel:
  15780          *table=L3_TUNNELm;
  15781          *direction= bcmStatFlexDirectionIngress;
  15782          break;
  15783     case bcmStatObjectIngL3Host:
  15784 
  15785         if (!soc_feature(unit, soc_feature_l3_extended_host_entry)) {
  15786             return BCM_E_PARAM;
  15787         }
  15788          if (SOC_IS_TD2_TT2(unit)) {
  15789 #if defined(BCM_TRIDENT3_SUPPORT)
  15790             if (SOC_IS_TRIDENT3X(unit)) {
  15791                if ((*actual_num_tables) < expected_num_tables) {
  15792                    table[(*actual_num_tables)++] = L3_ENTRY_DOUBLEm;
  15793                }
  15794                if ((*actual_num_tables) < expected_num_tables) {
  15795                    table[(*actual_num_tables)++] = L3_ENTRY_QUADm;
  15796                }
  15797             } else
  15798 #endif
  15799             {
  15800                  if ((*actual_num_tables) < expected_num_tables) {
  15801                      table[(*actual_num_tables)++]=L3_ENTRY_IPV4_MULTICASTm;
  15802                  }
  15803                  if ((*actual_num_tables) < expected_num_tables) {
  15804                      table[(*actual_num_tables)]=L3_ENTRY_IPV6_MULTICASTm;
  15805                  }
  15806             }
  15807          } else {
  15808              if ((*actual_num_tables) < expected_num_tables) {
  15809                  table[(*actual_num_tables)++]=EXT_IPV4_UCAST_WIDEm;
  15810              }
  15811              if ((*actual_num_tables) < expected_num_tables) {
  15812                  table[(*actual_num_tables)++]=EXT_IPV6_128_UCAST_WIDEm;
  15813              }
  15814              if ((*actual_num_tables) < expected_num_tables) {
  15815                  table[(*actual_num_tables)++]=L3_ENTRY_2m;
  15816              }
  15817              if ((*actual_num_tables) < expected_num_tables) {
  15818                  table[(*actual_num_tables)]=L3_ENTRY_4m;
  15819              }
  15820          }
  15821          *direction= bcmStatFlexDirectionIngress;
  15822          break;
  15823     case bcmStatObjectIngTrill:
  15824          *table=MPLS_ENTRY_EXTDm;
  15825          *direction= bcmStatFlexDirectionIngress;
  15826          break;
  15827     case bcmStatObjectIngMimLookupId:
  15828 #if defined(BCM_TRIUMPH3_SUPPORT)
  15829          if (SOC_IS_TRIUMPH3(unit)) {
  15830              *table=MPLS_ENTRY_EXTDm;
  15831              *direction= bcmStatFlexDirectionIngress;
  15832          } else
  15833 #endif
  15834          {
  15835              *table=MPLS_ENTRYm;
  15836              *direction= bcmStatFlexDirectionIngress;
  15837          }
  15838          break;
  15839     case bcmStatObjectIngL2Gre:
  15840          if ((*actual_num_tables) < expected_num_tables) {
  15841               table[(*actual_num_tables)++]=SOURCE_VPm;
  15842          }
  15843          if ((*actual_num_tables) < expected_num_tables) {
  15844               table[(*actual_num_tables)]=VFIm;
  15845          }
  15846          *direction= bcmStatFlexDirectionIngress;
  15847          break;
  15848     case bcmStatObjectIngEXTPolicy:
  15849          *table=EXT_FP_POLICYm;
  15850          *direction= bcmStatFlexDirectionIngress;
  15851          break;
  15852 #endif
  15853 #if defined(BCM_TRIDENT2_SUPPORT)
  15854     case  bcmStatObjectIngVxlan:
  15855         if (SOC_IS_TD2_TT2(unit)) {
  15856              if ((*actual_num_tables) < expected_num_tables) {
  15857                   table[(*actual_num_tables)++]=SOURCE_VPm;
  15858              }
  15859              if ((*actual_num_tables) < expected_num_tables) {
  15860                  table[(*actual_num_tables)]=VFIm;
  15861              }
  15862              *direction= bcmStatFlexDirectionIngress;
  15863         }
  15864          break;
  15865     case  bcmStatObjectIngVsan:
  15866          if (!SOC_IS_TOMAHAWKX(unit) && SOC_IS_TD2_TT2(unit)) {
  15867              *table=ING_VSANm;
  15868              *direction= bcmStatFlexDirectionIngress;
  15869         }
  15870          break;
  15871     case  bcmStatObjectIngFcoe:
  15872         if (SOC_IS_TD2_TT2(unit)) {
  15873 #if defined(BCM_TRIDENT3_SUPPORT)
  15874             if (SOC_IS_TRIDENT3X(unit)) {
  15875                 *table = L3_ENTRY_DOUBLEm;
  15876                 *direction = bcmStatFlexDirectionIngress;
  15877             } else
  15878 #endif
  15879             {
  15880                 *table=L3_ENTRY_IPV4_MULTICASTm;
  15881                 *direction= bcmStatFlexDirectionIngress;
  15882             }
  15883         }
  15884          break;
  15885     case  bcmStatObjectIngL3Route:
  15886         if (SOC_IS_TD2_TT2(unit)) {
  15887             if ((*actual_num_tables) < expected_num_tables) {
  15888                 if (SOC_MEM_IS_VALID(unit, L3_DEFIPm)) {
  15889                     table[(*actual_num_tables)++] = L3_DEFIPm;
  15890                 } else {
  15891                     table[(*actual_num_tables)++] = L3_DEFIP_LEVEL1m;
  15892                 }
  15893             }
  15894             if ((*actual_num_tables) < expected_num_tables) {
  15895                 if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_128m)) {
  15896                     table[(*actual_num_tables)++] = L3_DEFIP_PAIR_128m;
  15897                 } else {
  15898                     table[(*actual_num_tables)++] = L3_DEFIP_PAIR_LEVEL1m;
  15899                 }
  15900             }
  15901 #ifdef ALPM_ENABLE
  15902 #ifdef BCM_TOMAHAWK_SUPPORT
  15903             if (soc_feature(unit, soc_feature_alpm2)) {
  15904                 if ((*actual_num_tables) < expected_num_tables) {
  15905                     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_ALPM_RAWm)) {
  15906                         table[(*actual_num_tables)] = L3_DEFIP_ALPM_RAWm;
  15907                     } else {
  15908                         if (soc_property_get(unit, "l3_alpm2_level", 3) == 2) {
  15909                             table[(*actual_num_tables)] = L3_DEFIP_ALPM_LEVEL2m;
  15910                         } else {
  15911                             table[(*actual_num_tables)] = L3_DEFIP_ALPM_LEVEL3m;
  15912                         }
  15913                     }
  15914                 }
  15915             } else
  15916 #endif
  15917 #endif
  15918             {
  15919                  if ((*actual_num_tables) < expected_num_tables) {
  15920                      table[(*actual_num_tables)++]=L3_DEFIP_ALPM_IPV4_1m;
  15921                  }
  15922                  if ((*actual_num_tables) < expected_num_tables) {
  15923                      table[(*actual_num_tables)++]=L3_DEFIP_ALPM_IPV6_64_1m;
  15924                  }
  15925                  if ((*actual_num_tables) < expected_num_tables) {
  15926                      table[(*actual_num_tables)]=L3_DEFIP_ALPM_IPV6_128m;
  15927                  }
  15928             }
  15929              *direction= bcmStatFlexDirectionIngress;
  15930         }
  15931          break;
  15932     case bcmStatObjectIngIpmc:
  15933          if (SOC_IS_TD2_TT2(unit)) {
  15934 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  15935             if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) {
  15936                 if ((*actual_num_tables) < expected_num_tables) {
  15937                     table[(*actual_num_tables)++] = L3_ENTRY_DOUBLEm;
  15938                 }
  15939                 if ((*actual_num_tables) < expected_num_tables) {
  15940                     table[(*actual_num_tables)] = L3_ENTRY_QUADm;
  15941                 }
  15942             } else
  15943 #endif
  15944             {
  15945                  if ((*actual_num_tables) < expected_num_tables) {
  15946                      table[(*actual_num_tables)++]=L3_ENTRY_IPV4_MULTICASTm;
  15947                  }
  15948                  if ((*actual_num_tables) < expected_num_tables) {
  15949                      table[(*actual_num_tables)]=L3_ENTRY_IPV6_MULTICASTm;
  15950                  }
  15951             }
  15952          }
  15953          *direction= bcmStatFlexDirectionIngress;
  15954          break;
  15955     case bcmStatObjectIngVxlanDip:
  15956          if (SOC_IS_TD2_TT2(unit)) {
  15957 #if defined(BCM_TRIDENT3_SUPPORT)
  15958             if (SOC_IS_TRIDENT3X(unit)) {
  15959                 if ((*actual_num_tables) < expected_num_tables) {
  15960                     table[(*actual_num_tables)++] = MPLS_ENTRY_SINGLEm;
  15961                 }
  15962                 if ((*actual_num_tables) < expected_num_tables) {
  15963                     table[(*actual_num_tables)] = MPLS_ENTRY_SINGLEm;
  15964                 }
  15965             } else
  15966 #endif
  15967             {
  15968                  if ((*actual_num_tables) < expected_num_tables) {
  15969                      table[(*actual_num_tables)++]=VLAN_XLATEm;
  15970                  }
  15971             }
  15972              *direction= bcmStatFlexDirectionIngress;
  15973          }
  15974          break;
  15975 #endif /* BCM_TRIDENT2_SUPPORT */
  15976     case bcmIntStatObjectIngAgm:
  15977     case bcmIntStatObjectIngAgmSecondLookup:
  15978          *table=AGM_MONITOR_TABLEm;
  15979          *direction= bcmStatFlexDirectionIngress;
  15980          break;
  15981 
  15982     case bcmStatObjectEgrPort:
  15983 #if defined(BCM_TRIDENT3_SUPPORT)
  15984         if (SOC_IS_TRIDENT3X(unit)) {
  15985             *table = EGR_LPORT_PROFILEm;
  15986             *direction = bcmStatFlexDirectionEgress;
  15987         } else
  15988 #endif
  15989         {
  15990              *table=EGR_PORTm;
  15991              *direction= bcmStatFlexDirectionEgress;
  15992         }
  15993          break;
  15994     case bcmStatObjectEgrVlan:
  15995          *table=EGR_VLANm;
  15996          *direction= bcmStatFlexDirectionEgress;
  15997          break;
  15998     case bcmStatObjectEgrVlanXlate:
  15999 #if defined(BCM_TRIDENT3_SUPPORT)
  16000          if (SOC_IS_TRIDENT3X(unit)) {
  16001              if ((*actual_num_tables) < expected_num_tables) {
  16002                  table[(*actual_num_tables)++] = EGR_VLAN_XLATE_1_DOUBLEm;
  16003              }
  16004              if (soc_feature(unit, soc_feature_flex_flow) &&
  16005                  (*actual_num_tables) < expected_num_tables) {
  16006                  table[(*actual_num_tables)] = EGR_VLAN_XLATE_2_DOUBLEm;
  16007              }
  16008              *direction = bcmStatFlexDirectionEgress;
  16009          } else
  16010 #endif
  16011          {
  16012               *table=EGR_VLAN_XLATEm;
  16013               *direction= bcmStatFlexDirectionEgress;
  16014          }
  16015          break;
  16016     case bcmStatObjectEgrVlanXlateSecondLookup:
  16017 #if defined(BCM_TRIDENT3_SUPPORT)
  16018          if (SOC_IS_TRIDENT3X(unit)) {
  16019              *table = EGR_VLAN_XLATE_1_DOUBLEm;
  16020          } else
  16021 #endif
  16022          {
  16023              *table = EGR_VLAN_XLATEm;
  16024          }
  16025          *direction= bcmStatFlexDirectionEgress;
  16026          break;
  16027     case bcmStatObjectEgrVfi:
  16028          *table=EGR_VFIm;
  16029          *direction= bcmStatFlexDirectionEgress;
  16030          break;
  16031     case bcmStatObjectEgrNiv:
  16032     case bcmStatObjectEgrL3Intf:
  16033          *table=EGR_L3_NEXT_HOPm;
  16034          *direction= bcmStatFlexDirectionEgress;
  16035          break;
  16036     case bcmStatObjectEgrWlan:
  16037          *table=EGR_L3_NEXT_HOPm;
  16038          *direction= bcmStatFlexDirectionEgress;
  16039          break;
  16040     case bcmStatObjectEgrMim:
  16041          *table=EGR_L3_NEXT_HOPm;
  16042          *direction= bcmStatFlexDirectionEgress;
  16043          break;
  16044     case bcmStatObjectEgrMimLookupId:
  16045 #if defined(BCM_TRIDENT3_SUPPORT)
  16046         if (SOC_IS_TRIDENT3X(unit)) {
  16047             *table = EGR_VLAN_XLATE_1_DOUBLEm;
  16048             *direction = bcmStatFlexDirectionEgress;
  16049         } else
  16050 #endif
  16051         {
  16052              *table=EGR_VLAN_XLATEm;
  16053              *direction= bcmStatFlexDirectionEgress;
  16054         }
  16055          break;
  16056     case bcmStatObjectEgrL2Gre:
  16057          if ((*actual_num_tables) < expected_num_tables) {
  16058 #if defined(BCM_TRIDENT3_SUPPORT)
  16059             if (SOC_IS_TRIDENT3X(unit)) {
  16060                 table[(*actual_num_tables)++] = EGR_DVP_ATTRIBUTEm;
  16061             } else
  16062 #endif
  16063             {
  16064                   table[(*actual_num_tables)++]=EGR_DVP_ATTRIBUTE_1m;
  16065             }
  16066          }
  16067          if ((*actual_num_tables) < expected_num_tables) {
  16068               table[(*actual_num_tables)]=EGR_VFIm;
  16069          }
  16070          *direction= bcmStatFlexDirectionEgress;
  16071          break;
  16072 #if defined(BCM_TRIDENT2_SUPPORT)
  16073     case  bcmStatObjectEgrVxlan:
  16074         if (SOC_IS_TD2_TT2(unit)) {
  16075          if ((*actual_num_tables) < expected_num_tables) {
  16076 #if defined(BCM_TRIDENT3_SUPPORT)
  16077             if (SOC_IS_TRIDENT3X(unit)) {
  16078                 table[(*actual_num_tables)++] = EGR_DVP_ATTRIBUTEm;
  16079             } else
  16080 #endif
  16081             {
  16082                 table[(*actual_num_tables)++]=EGR_DVP_ATTRIBUTE_1m;
  16083             }
  16084          }
  16085          if ((*actual_num_tables) < expected_num_tables) {
  16086               table[(*actual_num_tables)++]=EGR_L3_NEXT_HOPm;
  16087          }
  16088          if ((*actual_num_tables) < expected_num_tables) {
  16089              table[(*actual_num_tables)]=EGR_VFIm;
  16090          }
  16091          *direction= bcmStatFlexDirectionEgress;
  16092         }
  16093          break;
  16094     case  bcmStatObjectEgrL3Nat:
  16095         if (SOC_IS_TD2_TT2(unit)) {
  16096             *table=EGR_NAT_PACKET_EDIT_INFOm;
  16097             *direction= bcmStatFlexDirectionEgress;
  16098         }
  16099          break;
  16100 #endif /* BCM_TRIDENT2_SUPPORT */
  16101 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  16102     case  bcmStatObjectEgrFieldStageEgress:
  16103         if (SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit) ||
  16104             SOC_IS_TRIDENT3X(unit)) {
  16105             *table=EFP_POLICY_TABLEm;
  16106             *direction= bcmStatFlexDirectionEgress;
  16107         }
  16108     break;
  16109     case  bcmStatObjectEgrMplsTunnelLabel:
  16110     case  bcmStatObjectEgrMplsTunnelSecondLabel:
  16111         if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
  16112             *table=EGR_IP_TUNNEL_MPLSm;
  16113             *direction= bcmStatFlexDirectionEgress;
  16114         }
  16115 #if defined(BCM_TRIDENT3_SUPPORT)
  16116         if (SOC_IS_TRIDENT3X(unit)) {
  16117             if (soc_feature(unit, soc_feature_td3_style_mpls)) {
  16118                 *table = EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm;
  16119             } else {
  16120                 *table = EGR_IP_TUNNEL_MPLSm;
  16121             }
  16122             *direction = bcmStatFlexDirectionEgress;
  16123         }
  16124 #endif
  16125     break;
  16126 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  16127     default:
  16128          switch((int32)object) {
  16129          case bcmIntStatObjectEgrLatencyMonitor0:
  16130             *table = EGR_HISTO_MON_0_Q_LATENCY_LIMIT_SELm;
  16131             *direction = bcmStatFlexDirectionEgress;
  16132             break;
  16133          case bcmIntStatObjectEgrLatencyMonitor1:
  16134             *table = EGR_HISTO_MON_1_Q_LATENCY_LIMIT_SELm;
  16135             *direction = bcmStatFlexDirectionEgress;
  16136             break;
  16137          case bcmIntStatObjectEgrLatencyMonitor2:
  16138             *table = EGR_HISTO_MON_2_Q_LATENCY_LIMIT_SELm;
  16139             *direction = bcmStatFlexDirectionEgress;
  16140             break;
  16141          case bcmIntStatObjectEgrLatencyMonitor3:
  16142             *table = EGR_HISTO_MON_3_Q_LATENCY_LIMIT_SELm;
  16143             *direction = bcmStatFlexDirectionEgress;
  16144             break;
  16145          default:
  16146             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16147                 (BSL_META_U(unit,
  16148                             "Invalid Object is passed %d\n"),
  16149                             object));
  16150             return BCM_E_PARAM;
  16151         }
  16152         break;
  16153     }
  16154     (*actual_num_tables)++;
  16155     return BCM_E_NONE;
  16156 }
  16157 /*
  16158  * Function:
  16159  *      _bcm_esw_stat_flex_detach_egress_table_counters
  16160  * B
  16161  * Description:
  16162  *      Detach i.e. Disable Egresss accounting table's statistics
  16163  * Parameters:
  16164  *      unit                  - (IN) unit number
  16165  *      egress_table          - (IN) Flex Accounting Table
  16166  *      index                 - (IN) Flex Accounting Table's Index
  16167  * Return Value:
  16168  *      BCM_E_XXX
  16169  * Notes:
  16170  */
  16171 bcm_error_t _bcm_esw_stat_flex_detach_egress_table_counters(
  16172             int       unit,
  16173             bcm_stat_object_t object_id,
  16174             soc_mem_t egress_table,
  16175             uint32    index)
  16176 {
  16177     uint32                          offset_mode=0;
  16178     uint32                          pool_number=0;
  16179     uint32                          base_idx=0;
  16180     uint32                          egress_entry_data_size=0;
  16181     uint32                          flex_entries=0;
  16182     bcm_stat_flex_ctr_offset_info_t flex_ctr_offset_info={0};
  16183     void                            *egress_entry_data=NULL;
  16184     bcm_stat_object_t               object=bcmStatObjectEgrPort;
  16185     uint32                          stat_counter_id=0;
  16186     uint32                          exact_index=0;
  16187 #if defined(BCM_TRIDENT3_SUPPORT)
  16188     soc_flow_db_mem_view_info_t mem_view_info;
  16189 #endif
  16190     uint32 is_view = 0;
  16191     uint32 width = 0;
  16192     soc_mem_t egress_view_table = egress_table; /* memory view or memory */
  16193     int pipe_num = 0;
  16194     uint32 total_counters = 0;
  16195 
  16196 #if defined(BCM_TRIDENT3_SUPPORT)
  16197     if ((soc_feature(unit,soc_feature_flex_flow)) &&
  16198         (soc_flow_db_mem_view_is_valid(unit, egress_table))) {
  16199         /* when egress_table is view_id perform below else
  16200          */
  16201         BCM_IF_ERROR_RETURN(soc_flow_db_mem_view_info_get(unit, egress_table,
  16202                                       &mem_view_info));
  16203         is_view = 1;
  16204         egress_table = mem_view_info.mem;
  16205         width = BITS2BYTES(mem_view_info.width);
  16206         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  16207                     (BSL_META_U(unit,
  16208                     "View ID %d mem_id %d\n"),
  16209                      egress_view_table, egress_table));
  16210 
  16211     }
  16212 #endif  /* BCM_TRIDENT3_SUPPORT */
  16213 
  16214     if (!((egress_table == EGR_VLANm) ||
  16215           (egress_table == EGR_VFIm)  ||
  16216           (egress_table == EGR_L3_NEXT_HOPm) ||
  16217           (egress_table == EGR_VLAN_XLATEm)  ||
  16218 #if defined(BCM_TRIUMPH3_SUPPORT)
  16219           (egress_table == EGR_DVP_ATTRIBUTE_1m) ||
  16220 #endif
  16221 #if defined(BCM_TRIDENT2_SUPPORT)
  16222           (egress_table == EGR_NAT_PACKET_EDIT_INFOm) ||
  16223 #endif
  16224 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  16225           (egress_table == EFP_POLICY_TABLEm) ||
  16226           (egress_table == EGR_IP_TUNNEL_MPLSm) ||
  16227 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  16228 #if defined(BCM_TRIDENT3_SUPPORT)
  16229           (egress_table == EGR_DVP_ATTRIBUTEm) ||
  16230           (egress_table == EGR_VLAN_XLATE_1_DOUBLEm) ||
  16231           (egress_table == EGR_VLAN_XLATE_2_DOUBLEm) ||
  16232           (egress_table == EGR_LPORT_PROFILEm) ||
  16233           (egress_table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm) ||
  16234 #endif
  16235 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  16236           (egress_table == EFP_POLICY_TABLE_PIPE0m) ||
  16237           (egress_table == EFP_POLICY_TABLE_PIPE1m) ||
  16238 #endif
  16239           (egress_table == EGR_PORTm))) {
  16240            LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16241                      (BSL_META_U(unit,
  16242                                  "Invalid Flex Counter Egress Memory %s\n"),
  16243                       SOC_MEM_UFNAME(unit, egress_table)));
  16244            return BCM_E_PARAM;
  16245     }
  16246 
  16247     exact_index = index;
  16248     if ((egress_table == EGR_IP_TUNNEL_MPLSm)
  16249 #if defined (BCM_TRIDENT3_SUPPORT)
  16250         || (egress_table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm)
  16251 #endif
  16252         ) {
  16253         index = index / _BCM_MPLS_NUM_MPLS_ENTRIES_PER_INDEX(unit);
  16254     }
  16255     if (!is_view) {
  16256         width =  SOC_MEM_INFO(unit, egress_table).bytes;
  16257     }
  16258 
  16259 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  16260     pipe_num = _bcm_esw_get_fp_pipe_num(unit, egress_table);
  16261 #endif
  16262     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16263               (BSL_META_U(unit,
  16264                           "Deallocating EGRESS counter for Table %s with index %d \n"),
  16265                SOC_MEM_UFNAME(unit, egress_table),index));
  16266     egress_entry_data_size = WORDS2BYTES(BYTES2WORDS(width));
  16267     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16268               (BSL_META_U(unit,
  16269                           "Deallocating EgressCounter Table:%s:with"
  16270                            "index:%d:ENTRY_BYTES:%d\n"),
  16271                SOC_MEM_UFNAME(unit, egress_table),
  16272                index,egress_entry_data_size));
  16273     egress_entry_data = sal_alloc(egress_entry_data_size,"egress_table");
  16274     if (egress_entry_data == NULL) {
  16275         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16276                   (BSL_META_U(unit,
  16277                               "Failed to allocate memory for Table:%s "),
  16278                    SOC_MEM_UFNAME(unit, egress_table)));
  16279          return BCM_E_INTERNAL;
  16280     }
  16281     sal_memset(egress_entry_data,0,egress_entry_data_size);
  16282 
  16283     if (soc_mem_read(unit, egress_view_table, MEM_BLOCK_ANY,
  16284                  _bcm_esw_stat_flex_table_index_map(unit,egress_table,index),
  16285                  egress_entry_data) == SOC_E_NONE) {
  16286 #if defined(BCM_TRIDENT3_SUPPORT)
  16287         if (is_view) {
  16288             if (soc_flow_db_mem_view_entry_is_valid(unit,
  16289                                         egress_view_table,
  16290                                         egress_entry_data) == FALSE) {
  16291                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16292                           (BSL_META_U(unit,
  16293                                       "Table %s  with index %d is Not valid \n"),
  16294                            SOC_MEM_UFNAME(unit, egress_table), index));
  16295                 sal_free(egress_entry_data);
  16296                 return BCM_E_PARAM;
  16297             }
  16298         } else
  16299 #endif
  16300         {
  16301         if (soc_mem_field_valid(unit, egress_table, VALIDf)) {
  16302             if (soc_mem_field32_get(unit, egress_table, egress_entry_data,
  16303                                     VALIDf)==0) {
  16304                     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16305                           (BSL_META_U(unit,
  16306                                       "Table %s  with index %d is Not valid \n"),
  16307                            SOC_MEM_UFNAME(unit, egress_table), index));
  16308                 sal_free(egress_entry_data);
  16309                 return BCM_E_PARAM;
  16310             }
  16311 
  16312             }
  16313         }
  16314         _bcm_esw_get_flex_counter_fields_values(
  16315                  unit,exact_index,egress_view_table,egress_entry_data,object_id,
  16316                  &offset_mode,&pool_number,&base_idx);
  16317         if ((offset_mode == 0) && (base_idx == 0)) {
  16318              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16319                        (BSL_META_U(unit,
  16320                                    "Table:%s:Index:%d:is NotConfiguredForFlexCtrYet\n"),
  16321                         SOC_MEM_UFNAME(unit, egress_table), index));
  16322              sal_free(egress_entry_data);
  16323              return BCM_E_NOT_FOUND;/*Either NotConfigured/DeallocatedBefore */
  16324         }
  16325 
  16326 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  16327         if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  16328             (_bcm_esw_is_fp_table(egress_table))) {
  16329             uint32 cmode = 0;
  16330             bcm_error_t rv;
  16331 
  16332             rv = _bcm_esw_custom_stat_group_id_retrieve(unit, offset_mode, pipe_num,
  16333                                                         pool_number, base_idx,
  16334                                                         &stat_counter_id);
  16335             if (rv !=BCM_E_NONE) {
  16336                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16337                       (BSL_META_U(unit,
  16338                                   "pipe %x Invalid mode value %d %d %d\n"),
  16339                        pipe_num, offset_mode, pool_number, base_idx));
  16340                 _bcm_esw_stat_get_counter_id(
  16341                               unit, flex_egress_modes[unit][offset_mode].group_mode,
  16342                               object,offset_mode,pool_number,base_idx,&stat_counter_id);
  16343                 total_counters = flex_egress_modes[unit][offset_mode].total_counters;
  16344             } else {
  16345                 cmode = stat_counter_map[unit][stat_counter_id].mode;
  16346                 total_counters = flex_custom_egress_modes[unit][cmode - BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE].
  16347                                                 total_counters;
  16348             }
  16349         } else
  16350 #endif
  16351         {
  16352             _bcm_esw_stat_get_counter_id(
  16353                           unit, flex_egress_modes[unit][offset_mode].group_mode,
  16354                           object,offset_mode,pool_number,base_idx,&stat_counter_id);
  16355             total_counters = flex_egress_modes[unit][offset_mode].total_counters;
  16356         }
  16357 
  16358         /* Decrement reference counts */
  16359         BCM_STAT_FLEX_COUNTER_LOCK(unit);
  16360         flex_base_index_reference_count[unit][bcmStatFlexDirectionEgress][pipe_num]
  16361                                        [pool_number][base_idx]--;
  16362         flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number].
  16363                        attached_entries -= total_counters;
  16364         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  16365 
  16366 
  16367         /* Clear Counter Values when reference count is zero */
  16368         if ((flex_base_index_reference_count[unit]
  16369                 [bcmStatFlexDirectionEgress][pipe_num] [pool_number][base_idx]) == 0 ) {
  16370             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16371                       (BSL_META_U(unit,
  16372                                   "Clearing Counter Tables %s contents:Offset:%d Len:%d\n"),
  16373                        SOC_MEM_UFNAME(unit, egress_table),
  16374                        base_idx,
  16375                        total_counters));
  16376 
  16377             if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  16378                 /*
  16379                  * To maintain legacy behaviour of detach and to handle refrence count
  16380                  * out of sync issues, when compaction is in progress for a base index,
  16381                  * counter values need to be explicitly cleared in bcmStatBaseIdxMove
  16382                  * compaction sequence. 
  16383                  */
  16384                 if (compaction_info.base_idx != base_idx &&
  16385                         compaction_info.pool_number != pool_number) {
  16386                     flex_ctr_offset_info.all_counters_flag =  1;
  16387                     _bcm_esw_stat_flex_set(unit, index, egress_table, -1,
  16388                             flex_ctr_offset_info,
  16389                             &flex_entries,
  16390                             offset_mode,pool_number,base_idx,
  16391                             bcmStatFlexDirectionEgress);
  16392                 }
  16393             } else {
  16394                 flex_ctr_offset_info.all_counters_flag =  1;
  16395                 _bcm_esw_stat_flex_set(unit, index, egress_table, -1,
  16396                         flex_ctr_offset_info,
  16397                         &flex_entries,
  16398                         offset_mode,pool_number,base_idx,
  16399                         bcmStatFlexDirectionEgress);
  16400             }
  16401         }
  16402 
  16403         /* Reset flex fields */
  16404         _bcm_esw_set_flex_counter_fields_values(unit,
  16405                                                 exact_index,
  16406                                                 egress_view_table,
  16407                                                 egress_entry_data,
  16408                                                 object_id,0,0,0);
  16409         if (
  16410 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  16411             (!_bcm_esw_stat_table_is_profile(unit, egress_table)) &&
  16412 #endif
  16413             soc_mem_write(unit, egress_view_table, MEM_BLOCK_ALL,
  16414                       _bcm_esw_stat_flex_table_index_map(unit,egress_table,index),
  16415                       egress_entry_data) != SOC_E_NONE) {
  16416             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16417                       (BSL_META_U(unit,
  16418                                   "Table:%s:Index:%d: encounter some problem \n"),
  16419                        SOC_MEM_UFNAME(unit, egress_table), index));
  16420             sal_free(egress_entry_data);
  16421             return    BCM_E_INTERNAL;
  16422         }
  16423         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16424                   (BSL_META_U(unit,
  16425                               "Deallocated Table:%s:Index:%d:mode:%d"
  16426                                "reference_count %d \n"),
  16427                    SOC_MEM_UFNAME(unit, egress_table),index,offset_mode,
  16428                    flex_base_index_reference_count[unit]
  16429                    [bcmStatFlexDirectionEgress][pipe_num][pool_number][base_idx]));
  16430         if (object_id != bcmStatObjectEgrMplsTunnelSecondLabel) {
  16431             if(_bcm_esw_stat_flex_get_egress_object(unit,egress_view_table,
  16432            index,egress_entry_data,&object) != BCM_E_NONE) {
  16433            sal_free(egress_entry_data);
  16434            return BCM_E_INTERNAL;
  16435         }
  16436         } else {
  16437             object = object_id;
  16438         }
  16439         sal_free(egress_entry_data);
  16440 
  16441         /* Disable flex pool for this stat on no flex entries */
  16442         if (flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number].
  16443                            attached_entries  == 0) {
  16444             _bcm_esw_stat_flex_enable_pool(
  16445                     unit,bcmStatFlexDirectionEgress,
  16446                     _pool_ctr_register[bcmStatFlexDirectionEgress][pool_number],
  16447                     0);
  16448         }
  16449 
  16450         if (flex_base_index_reference_count[unit][bcmStatFlexDirectionEgress]
  16451                                            [pipe_num][pool_number][base_idx] == 0) {
  16452             if (_bcm_esw_stat_flex_insert_stat_id(unit,
  16453                         local_scache_ptr[unit],stat_counter_id) != BCM_E_NONE) {
  16454                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16455                          (BSL_META_U(unit,
  16456                                      "WARMBOOT:Couldnot add entry in scache memory."
  16457                                       "Attach it\n")));
  16458             }
  16459         }
  16460         return BCM_E_NONE;
  16461     }
  16462     sal_free(egress_entry_data);
  16463     return    BCM_E_NOT_FOUND;
  16464 }
  16465 
  16466 
  16467 /*
  16468  * Function:
  16469  *      _bcm_esw_stat_flex_destroy_egress_table_counters
  16470  * Description:
  16471  *      Destroy Egresss accounting table's statistics completely
  16472  * Parameters:
  16473  *      unit                  - (IN) unit number
  16474  *      egress_table          - (IN) Flex Accounting Table
  16475  *      offset_mode           - (IN) Flex offset mode for Accounting Object
  16476  *      base_idx              - (IN) Flex Base Index for Accounting Object
  16477  *      pool_number           - (IN) Flex Pool Number for Accounting Object
  16478  *
  16479  * Return Value:
  16480  *      BCM_E_XXX
  16481  * Notes:
  16482  */
  16483 bcm_error_t _bcm_esw_stat_flex_destroy_egress_table_counters(
  16484             int                  unit,
  16485             soc_mem_t            egress_table,
  16486             int                  lookup,
  16487             bcm_stat_object_t    object,
  16488             bcm_stat_flex_mode_t offset_mode,
  16489             uint32               base_idx,
  16490             uint32               pool_number)
  16491 {
  16492     uint32                          free_count=0;
  16493     uint32                          alloc_count=0;
  16494     uint32                          largest_free;
  16495     uint32                          used_by_table=0;
  16496     uint32                          stat_counter_id=0;
  16497     int pipe_num = 0;
  16498     int total_counters = 0;
  16499     uint32 temp_base_idx = 0;
  16500 #ifdef BCM_TOMAHAWK3_SUPPORT
  16501     uint32      num_ctr;
  16502     soc_reg_t   reg = INVALIDr;
  16503     uint32      reg_val = 0;
  16504     uint32      clr_on_read = 0;
  16505     uint32      eviction_mode = 0;
  16506 #endif /* BCM_TOMAHAWK3_SUPPORT */
  16507 
  16508 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  16509     pipe_num = _bcm_esw_get_fp_pipe_num(unit, egress_table);
  16510     if ((offset_mode >= BCM_CUSTOM_EGRESS_MODE_START)  &&
  16511         (offset_mode < BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE)) {
  16512         total_counters = flex_custom_egress_modes[unit]
  16513             [offset_mode - BCM_CUSTOM_EGRESS_MODE_START].total_counters;
  16514         offset_mode = flex_custom_egress_modes[unit]
  16515             [offset_mode - BCM_CUSTOM_EGRESS_MODE_START].offset_mode;
  16516     } else
  16517 #endif
  16518     {
  16519         total_counters = flex_egress_modes[unit][offset_mode].total_counters;
  16520     }
  16521 
  16522     if (flex_egress_modes[unit][offset_mode].available==0) {
  16523         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16524                   (BSL_META_U(unit,
  16525                               "flex CounterMode:%d:Not configured yet\n"),
  16526                    offset_mode));
  16527         return BCM_E_NOT_FOUND;
  16528     }
  16529     if (shr_aidxres_list_elem_state(flex_aidxres_list_handle
  16530                                     [unit][bcmStatFlexDirectionEgress][pipe_num]
  16531                                     [pool_number],base_idx) != BCM_E_EXISTS) {
  16532         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16533                   (BSL_META_U(unit,
  16534                               "Wrong base index %u \n"),
  16535                    base_idx));
  16536         return BCM_E_NOT_FOUND;
  16537     }
  16538     if (flex_base_index_reference_count[unit]
  16539         [bcmStatFlexDirectionEgress][pipe_num][pool_number][base_idx] != 0) {
  16540         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16541                   (BSL_META_U(unit,
  16542                               "Reference count is  %d.. Please detach entries first..\n"),
  16543                    flex_base_index_reference_count[unit]
  16544                    [bcmStatFlexDirectionEgress][pipe_num][pool_number][base_idx]));
  16545         return BCM_E_BUSY;
  16546     }
  16547     switch(egress_table) {
  16548     case EGR_VLANm:
  16549          used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_TABLE;
  16550          break;
  16551     case EGR_VFIm:
  16552          used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_VFI_TABLE;
  16553          break;
  16554     case EGR_L3_NEXT_HOPm:
  16555          used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_L3_NEXT_HOP_TABLE;
  16556          break;
  16557     case EGR_VLAN_XLATEm:
  16558 #if defined (BCM_TRIDENT3_SUPPORT)
  16559     case EGR_VLAN_XLATE_1_DOUBLEm:
  16560     case EGR_VLAN_XLATE_2_DOUBLEm:
  16561 #endif
  16562          used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE;
  16563          if (lookup == 1) {
  16564              used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE;
  16565          } else if (lookup == 2) {
  16566              used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE_FOR_SCND_LKUP;
  16567          }
  16568          break;
  16569     case EGR_PORTm:
  16570 #if defined (BCM_TRIDENT3_SUPPORT)
  16571     case EGR_LPORT_PROFILEm:
  16572 #endif
  16573          used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_PORT_TABLE;
  16574          break;
  16575     case EGR_HISTO_MON_0_Q_LATENCY_LIMIT_SELm:
  16576     case EGR_HISTO_MON_1_Q_LATENCY_LIMIT_SELm:
  16577     case EGR_HISTO_MON_2_Q_LATENCY_LIMIT_SELm:
  16578     case EGR_HISTO_MON_3_Q_LATENCY_LIMIT_SELm:
  16579         used_by_table=FLEX_COUNTER_POOL_USED_BY_LATENCY_MONITOR_TABLE;
  16580         break;
  16581 #if defined(BCM_TRIUMPH3_SUPPORT)
  16582     case EGR_DVP_ATTRIBUTE_1m:
  16583 #if defined (BCM_TRIDENT3_SUPPORT)
  16584     case EGR_DVP_ATTRIBUTEm:
  16585 #endif
  16586          used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_DVP_ATTRIBUTE_1_TABLE;
  16587          break;
  16588 #endif
  16589 #if defined(BCM_TRIDENT2_SUPPORT)
  16590     case EGR_NAT_PACKET_EDIT_INFOm:
  16591          used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_L3_NAT_TABLE;
  16592          break;
  16593 #endif
  16594 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  16595 #if defined(BCM_TRIDENT3_SUPPORT)
  16596     case EFP_POLICY_TABLE_PIPE0m:
  16597     case EFP_POLICY_TABLE_PIPE1m:
  16598 #endif
  16599     case EFP_POLICY_TABLEm:
  16600          used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_EFP_POLICY_TABLE;
  16601          break;
  16602      case EGR_IP_TUNNEL_MPLSm:
  16603          if (lookup == 1) {
  16604          used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_IP_TUNNEL_MPLS_TABLE;
  16605          } else if (lookup == 2) {
  16606          used_by_table=FLEX_COUNTER_POOL_USED_BY_EGR_IP_TUNNEL_MPLS_SCND_LBL_TABLE;
  16607          }
  16608          break;
  16609 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 
  16610     default:
  16611          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16612                    (BSL_META_U(unit,
  16613                                "Invalid Flex Counter Egress Memory %s\n"),
  16614                     SOC_MEM_UFNAME(unit, egress_table)));
  16615          return BCM_E_PARAM;
  16616     }
  16617 
  16618     /* Free pool list */
  16619     if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  16620         for (temp_base_idx =  base_idx;
  16621                 temp_base_idx <= (base_idx + total_counters - 1);
  16622                 temp_base_idx++) {
  16623             if (shr_aidxres_list_free(flex_aidxres_list_handle
  16624                         [unit][bcmStatFlexDirectionEgress][pipe_num][pool_number],
  16625                         temp_base_idx) != BCM_E_NONE) {
  16626                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16627                         (BSL_META_U(unit,
  16628                                     "Freeing memory Table:%s:encounter problem due entry not found or due to some other issue used_by_table %x \n"),
  16629                          SOC_MEM_UFNAME(unit, egress_table), used_by_table));
  16630                 return BCM_E_NOT_FOUND;
  16631             }
  16632         }
  16633     } else {
  16634         if (shr_aidxres_list_free(flex_aidxres_list_handle
  16635                     [unit][bcmStatFlexDirectionEgress][pipe_num][pool_number],
  16636                     base_idx) != BCM_E_NONE) {
  16637             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16638                     (BSL_META_U(unit,
  16639                                 "Freeing memory Table:%s:encounter problem due entry not found or due to some other issue used_by_table %x \n"),
  16640                      SOC_MEM_UFNAME(unit, egress_table), used_by_table));
  16641             return BCM_E_NOT_FOUND;
  16642         }
  16643     }
  16644     _bcm_esw_stat_get_counter_id(
  16645                   unit, flex_egress_modes[unit][offset_mode].group_mode,
  16646                   object,offset_mode,pool_number,base_idx,&stat_counter_id);
  16647     if (_bcm_esw_stat_flex_delete_stat_id(unit,
  16648                  local_scache_ptr[unit],stat_counter_id) != BCM_E_NONE) {
  16649         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16650                  (BSL_META_U(unit,
  16651                              "WARMBOOT: Couldnot Delete entry in scache memory.\n")));
  16652     }
  16653     shr_aidxres_list_state(flex_aidxres_list_handle
  16654                            [unit][bcmStatFlexDirectionEgress][pipe_num][pool_number],
  16655                            NULL,NULL,NULL,NULL,
  16656                            &free_count,&alloc_count,&largest_free,NULL);
  16657     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16658               (BSL_META_U(unit,
  16659                           "Pool status free_count:%d alloc_count:%d largest_free:%d"
  16660                            "used_by_tables:%d used_entries:%d\n"),
  16661                free_count,alloc_count,largest_free,
  16662                flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num]
  16663                [pool_number].used_by_tables,
  16664                flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num]
  16665                [pool_number].used_entries));
  16666     flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number].
  16667                   used_entries -= total_counters;
  16668     if (flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number].
  16669         used_entries == 0) {
  16670         /* None of the entries are used.*/
  16671         flex_pool_stat[unit][bcmStatFlexDirectionEgress]
  16672                       [pipe_num][pool_number].used_by_tables &= ~used_by_table;
  16673         SHR_BITCLR(flex_pool_stat[unit][bcmStatFlexDirectionEgress]
  16674                       [pipe_num][pool_number].used_by_objects, object);
  16675 
  16676 #ifdef BCM_TOMAHAWK3_SUPPORT
  16677         if  ((SOC_IS_TOMAHAWK3(unit)) && 
  16678              ((bcmIntStatObjectEgrLatencyMonitor0 == (bcm_int_stat_object_t)object) ||
  16679               (bcmIntStatObjectEgrLatencyMonitor1 == (bcm_int_stat_object_t)object) ||
  16680               (bcmIntStatObjectEgrLatencyMonitor2 == (bcm_int_stat_object_t)object) ||
  16681               (bcmIntStatObjectEgrLatencyMonitor3 == (bcm_int_stat_object_t)object))) {
  16682             shr_aidxres_list_destroy(flex_aidxres_list_handle
  16683                 [unit][bcmStatFlexDirectionEgress][pipe_num][pool_number]);
  16684             num_ctr = SOC_INFO(unit).size_flex_egress_pool;
  16685             if (shr_aidxres_list_create(
  16686                 &flex_aidxres_list_handle[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number],
  16687                 0,num_ctr-1,
  16688                 0,num_ctr-1,
  16689                 8, /* Max 256 counters */
  16690                 "flex-counter") != BCM_E_NONE) {
  16691                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16692                             (BSL_META_U(unit,
  16693                             "Unrecoverable error. Couldn'tCreate "
  16694                             "AllignedList:FlexCounter\n")));
  16695                 return BCM_E_INTERNAL;
  16696             }
  16697 
  16698             if(soc_feature(unit, soc_feature_counter_eviction)
  16699                 && soc_property_get(unit, "ctr_evict_enable", 1)) {
  16700                 clr_on_read = 1;
  16701                 if (soc_feature(unit, soc_feature_th_a0_sw_war)) {
  16702                     eviction_mode = 2;
  16703                 } else {
  16704                     eviction_mode = 1;
  16705                 }
  16706             }
  16707 
  16708             /* Recover the previous state for clear on read. */
  16709             reg = _pool_ctr_register[bcmStatFlexDirectionEgress][pool_number];
  16710             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY,0, &reg_val));
  16711             soc_reg_field_set(unit, reg, &reg_val, CLR_ON_READf, clr_on_read);
  16712             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, reg_val));
  16713 
  16714             /* Recover the previous mode for counter eviction */
  16715             reg = egr_evict_regs[pool_number];
  16716             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY,
  16717                                0, &reg_val));
  16718             soc_reg_field_set(unit, reg, &reg_val, MODEf, eviction_mode);
  16719             SOC_IF_ERROR_RETURN
  16720                    (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, reg_val));
  16721        }
  16722 #endif /* BCM_TOMAHAWK3_SUPPORT */
  16723 
  16724     }
  16725     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  16726     flex_egress_modes[unit][offset_mode].reference_count--;
  16727     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  16728 
  16729     if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  16730         flex_packet_counter_compaction[unit]
  16731             [bcmStatFlexDirectionEgress][pipe_num][pool_number]
  16732             [base_idx] = 0;
  16733         COMPILER_64_SET(flex_packet64_counter_compaction[unit]
  16734                 [bcmStatFlexDirectionEgress][pipe_num][pool_number]
  16735                 [base_idx],0,0);
  16736         COMPILER_64_SET(flex_byte_counter_compaction[unit]
  16737                 [bcmStatFlexDirectionEgress][pipe_num][pool_number]
  16738                 [base_idx],0,0);
  16739     }
  16740     return BCM_E_NONE;
  16741 }
  16742 
  16743 /*
  16744  * Function:
  16745  *      _bcm_esw_stat_flex_detach_ingress_table_counters1
  16746  * Description:
  16747  *      Detach i.e. Disable Igresss accounting table's statistics
  16748  * Parameters:
  16749  *      unit                  - (IN) unit number
  16750  *      ingress_table         - (IN) Flex Accounting Table
  16751  *      index                 - (IN) Flex Accounting Table's Index
  16752  *
  16753  * Return Value:
  16754  *      BCM_E_XXX
  16755  * Notes:
  16756  */
  16757 bcm_error_t _bcm_esw_stat_flex_detach_ingress_table_counters1(
  16758             int                 unit,
  16759             soc_mem_t           ingress_table,
  16760             uint32              index,
  16761             bcm_stat_object_t   object)
  16762 {
  16763     uint32                          offset_mode = 0;
  16764     uint32                          pool_number = 0;
  16765     uint32                          base_idx = 0;
  16766     uint32                          ingress_entry_data_size = 0;
  16767     uint32                          flex_entries = 0;
  16768     bcm_stat_flex_ctr_offset_info_t flex_ctr_offset_info = {0};
  16769     void                            *ingress_entry_data = NULL;
  16770     uint32                          stat_counter_id = 0;
  16771     int                             pipe_num = 0;
  16772     int                             pipe = 0, maxpipe = 1, unused_pool;
  16773     uint32                          total_counters = 0;
  16774     if (!((ingress_table == PORT_TABm) ||
  16775          (ingress_table == VLAN_XLATEm)  ||
  16776 #if defined(BCM_TRIUMPH3_SUPPORT)
  16777          (ingress_table == VLAN_XLATE_EXTDm)  ||
  16778          (ingress_table == MPLS_ENTRY_EXTDm)  ||
  16779          (ingress_table == L3_TUNNELm)  ||
  16780          (ingress_table == L3_ENTRY_2m)  ||
  16781          (ingress_table == L3_ENTRY_4m)  ||
  16782          (ingress_table == EXT_IPV4_UCAST_WIDEm)  ||
  16783          (ingress_table == EXT_IPV6_128_UCAST_WIDEm)  ||
  16784          (ingress_table == EXT_FP_POLICYm)  ||
  16785 #endif
  16786 #if defined(BCM_TRIDENT2_SUPPORT)
  16787          (ingress_table == ING_VSANm) ||
  16788          (ingress_table == L3_ENTRY_IPV4_MULTICASTm) ||
  16789          (ingress_table == L3_ENTRY_IPV6_MULTICASTm) ||
  16790          (ingress_table == L3_DEFIPm) ||
  16791          (ingress_table == L3_DEFIP_PAIR_128m) ||
  16792          (ingress_table == L3_DEFIP_LEVEL1m) ||
  16793          (ingress_table == L3_DEFIP_PAIR_LEVEL1m) ||
  16794          (ingress_table == L3_DEFIP_ALPM_LEVEL2m) ||
  16795          (ingress_table == L3_DEFIP_ALPM_LEVEL3m) ||
  16796          (ingress_table == L3_DEFIP_ALPM_RAWm) ||
  16797          (ingress_table == L3_DEFIP_ALPM_IPV4_1m) ||
  16798          (ingress_table == L3_DEFIP_ALPM_IPV6_64_1m) ||
  16799          (ingress_table == L3_DEFIP_ALPM_IPV6_128m) ||
  16800 #endif
  16801 #if  defined (BCM_TRIDENT2PLUS_SUPPORT)
  16802          (ingress_table == FP_POLICY_TABLEm)          ||
  16803 #endif
  16804 #if defined(BCM_TOMAHAWK_SUPPORT) 
  16805          (ingress_table == IFP_POLICY_TABLEm)          ||
  16806          (SOC_IS_TOMAHAWKX(unit) &&
  16807          ((ingress_table == IFP_POLICY_TABLE_PIPE0m)   ||
  16808           (ingress_table == IFP_POLICY_TABLE_PIPE1m)   ||
  16809           (ingress_table == IFP_POLICY_TABLE_PIPE2m)   ||
  16810           (ingress_table == IFP_POLICY_TABLE_PIPE3m)   ||
  16811           (ingress_table == IFP_POLICY_TABLE_PIPE4m)   ||
  16812           (ingress_table == IFP_POLICY_TABLE_PIPE5m)   ||
  16813           (ingress_table == IFP_POLICY_TABLE_PIPE6m)   ||
  16814           (ingress_table == IFP_POLICY_TABLE_PIPE7m)   ||
  16815           (ingress_table == AGM_MONITOR_TABLEm))) ||
  16816 #endif
  16817          (ingress_table == VFP_POLICY_TABLEm)  ||
  16818 #if defined(BCM_TOMAHAWK_SUPPORT) 
  16819         (SOC_IS_TOMAHAWKX(unit) &&
  16820          ((ingress_table == VFP_POLICY_TABLE_PIPE0m)   ||
  16821           (ingress_table == VFP_POLICY_TABLE_PIPE1m)   ||
  16822           (ingress_table == VFP_POLICY_TABLE_PIPE2m)   ||
  16823           (ingress_table == VFP_POLICY_TABLE_PIPE3m)   ||
  16824           (ingress_table == VFP_POLICY_TABLE_PIPE4m)   ||
  16825           (ingress_table == VFP_POLICY_TABLE_PIPE5m)   ||
  16826           (ingress_table == VFP_POLICY_TABLE_PIPE6m)   ||
  16827           (ingress_table == VFP_POLICY_TABLE_PIPE7m))) ||
  16828 #endif
  16829 #if defined(BCM_TOMAHAWK3_SUPPORT)
  16830         (SOC_IS_TOMAHAWK3(unit) &&
  16831         ((ingress_table == LPORT_TABm)  ||
  16832         (ingress_table == L3_ENTRY_QUADm)  ||
  16833         (ingress_table == L3_ENTRY_DOUBLEm)))  ||
  16834 #endif
  16835 #if defined(BCM_TRIDENT3_SUPPORT)
  16836         (SOC_IS_TRIDENT3X(unit) &&
  16837         ((ingress_table == VLAN_XLATE_1_DOUBLEm)   ||
  16838         (ingress_table == VLAN_XLATE_2_DOUBLEm)   ||
  16839         (ingress_table == LPORT_TABm)   ||
  16840         (ingress_table == L3_ENTRY_QUADm)   ||
  16841         (ingress_table == L3_ENTRY_DOUBLEm)   ||
  16842         (ingress_table == VFP_POLICY_TABLE_PIPE0m)   ||
  16843         (ingress_table == VFP_POLICY_TABLE_PIPE1m)   ||
  16844         (ingress_table == IFP_POLICY_TABLE_PIPE0m)   ||
  16845         (ingress_table == IFP_POLICY_TABLE_PIPE1m) ||
  16846         (ingress_table == IFP_POLICY_TABLE_PIPE1m)   ||
  16847         (ingress_table == IFP_POLICY_TABLE_WIDEm)    ||
  16848         (ingress_table == IFP_POLICY_TABLE_WIDE_PIPE0m) ||
  16849         (ingress_table == IFP_POLICY_TABLE_WIDE_PIPE1m) ||
  16850         (ingress_table == AGM_MONITOR_TABLEm) ||
  16851         (ingress_table == VRF_ATTRS_2m))) ||
  16852 #endif
  16853          (ingress_table == MPLS_ENTRYm)  ||
  16854 #if defined(BCM_TOMAHAWK3_SUPPORT)
  16855          (ingress_table == MPLS_ENTRY_SINGLEm) ||
  16856 #endif
  16857          (ingress_table == SOURCE_VPm)  ||
  16858          (ingress_table == L3_IIFm)  ||
  16859          (ingress_table == VRFm)  ||
  16860          (ingress_table == VFIm)  ||
  16861          (ingress_table == VLAN_TABm))) {
  16862           LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16863                     (BSL_META_U(unit,
  16864                                 "Invalid Flex Counter Ingress Memory %s\n"),
  16865                      SOC_MEM_UFNAME(unit, ingress_table)));
  16866           return BCM_E_PARAM;
  16867     }
  16868 #if defined (BCM_TOMAHAWK_SUPPORT)
  16869     pipe_num = _bcm_esw_get_fp_pipe_num(unit, ingress_table);
  16870 #endif
  16871     ingress_entry_data_size = WORDS2BYTES(BYTES2WORDS(
  16872                               SOC_MEM_INFO(unit, ingress_table).bytes));
  16873     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16874               (BSL_META_U(unit,
  16875                           "Deallocating IngressCounter Table:%s:Index:%d:"
  16876                            " ENTRY_BYTES:%d \n"),
  16877                SOC_MEM_UFNAME(unit, ingress_table),
  16878                index,ingress_entry_data_size));
  16879     ingress_entry_data = sal_alloc(ingress_entry_data_size,"ingress_table");
  16880     if (ingress_entry_data == NULL) {
  16881         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  16882                   (BSL_META_U(unit,
  16883                               "Failed to allocate memory for Table:%s "),
  16884                    SOC_MEM_UFNAME(unit, ingress_table)));
  16885         return BCM_E_INTERNAL;
  16886     }
  16887     sal_memset(ingress_entry_data,0,ingress_entry_data_size);
  16888 #if defined (BCM_TOMAHAWK_SUPPORT)
  16889     if (soc_th_ifp_mem_read(unit, ingress_table, MEM_BLOCK_ANY,
  16890                  _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  16891                  ingress_entry_data) == SOC_E_NONE) {
  16892 #else
  16893     if (soc_mem_read(unit, ingress_table, MEM_BLOCK_ANY,
  16894                  _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  16895                  ingress_entry_data) == SOC_E_NONE) {
  16896 #endif /* BCM_TOMAHAWK_SUPPORT */
  16897         if (soc_mem_field_valid(unit,ingress_table,VALIDf)) {
  16898             if (soc_mem_field32_get(unit,ingress_table,ingress_entry_data,
  16899                                     VALIDf) == 0) {
  16900                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16901                           (BSL_META_U(unit,
  16902                                       "Table %s  with index %d is Not valid \n"),
  16903                            SOC_MEM_UFNAME(unit, ingress_table),index));
  16904                 sal_free(ingress_entry_data);
  16905                 return BCM_E_PARAM;
  16906             }
  16907         }
  16908         _bcm_esw_get_flex_counter_fields_values(
  16909                  unit,index,ingress_table,ingress_entry_data, object,
  16910                  &offset_mode,&pool_number,&base_idx);
  16911         if ((offset_mode == 0) && (base_idx == 0)) {
  16912              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16913                        (BSL_META_U(unit,
  16914                                    "Table:%s:Index %d IsNotConfiguredForFlexCounter\n"),
  16915                         SOC_MEM_UFNAME(unit, ingress_table),index));
  16916              sal_free(ingress_entry_data);
  16917              return BCM_E_NOT_FOUND;/*Either NotConfigured/deallocated before*/
  16918         }
  16919 
  16920 #if defined (BCM_TOMAHAWK_SUPPORT)
  16921     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  16922         (_bcm_esw_is_fp_table(ingress_table))) {
  16923         uint32 cmode = 0;
  16924         bcm_error_t rv;
  16925  
  16926         rv = _bcm_esw_custom_stat_group_id_retrieve(unit, offset_mode, pipe_num, 
  16927                                                     pool_number, base_idx,
  16928                                                     &stat_counter_id);
  16929         if (rv !=BCM_E_NONE) {
  16930             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16931                   (BSL_META_U(unit,
  16932                               "pipe %x Invalid mode value %d %d %d\n"),
  16933                    pipe_num, offset_mode, pool_number, base_idx));
  16934             _bcm_esw_stat_get_counter_id(
  16935                           unit, flex_ingress_modes[unit][offset_mode].group_mode,
  16936                           object,offset_mode,pool_number,base_idx,&stat_counter_id);
  16937             total_counters = flex_ingress_modes[unit][offset_mode].total_counters;
  16938         } else {
  16939             cmode = stat_counter_map[unit][stat_counter_id].mode;
  16940             total_counters = flex_custom_ingress_modes[unit][cmode - BCM_CUSTOM_INGRESS_MODE_START].
  16941                                             total_counters;
  16942         }
  16943     } else
  16944 #endif
  16945     {
  16946     _bcm_esw_stat_get_counter_id(
  16947                   unit, flex_ingress_modes[unit][offset_mode].group_mode,
  16948                   object,offset_mode,pool_number,base_idx,&stat_counter_id);
  16949     total_counters = flex_ingress_modes[unit][offset_mode].total_counters;
  16950     }
  16951 
  16952 
  16953         /* Decrement reference count */
  16954         BCM_STAT_FLEX_COUNTER_LOCK(unit);
  16955         flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress][pipe_num]
  16956                                        [pool_number][base_idx]--;
  16957         flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num][pool_number].
  16958                        attached_entries -= total_counters;
  16959         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  16960 
  16961         /* Clear Counter Values */
  16962         if ((flex_base_index_reference_count[unit]
  16963                     [bcmStatFlexDirectionIngress][pipe_num][pool_number][base_idx]) == 0 ) {
  16964             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  16965                     (BSL_META_U(unit,
  16966                                 "Clearing Counter Tables %s contents:Offset:%d Len:%d\n"),
  16967                      SOC_MEM_UFNAME(unit, ingress_table),
  16968                      base_idx,
  16969                      total_counters));
  16970             flex_ctr_offset_info.all_counters_flag =  1;
  16971             _bcm_esw_stat_flex_set(unit,index,ingress_table, -1,
  16972                     flex_ctr_offset_info,&flex_entries,
  16973                     offset_mode,pool_number,base_idx,
  16974                     bcmStatFlexDirectionIngress);
  16975         }
  16976 
  16977         /* Reset Table Values */
  16978         _bcm_esw_set_flex_counter_fields_values(
  16979                  unit,index,ingress_table,ingress_entry_data,object,0,0,0);
  16980 #if defined(BCM_TOMAHAWK_SUPPORT)
  16981         if ((SOC_IS_TOMAHAWKX(unit)) &&
  16982             ((IFP_POLICY_TABLEm == ingress_table) ||
  16983              (IFP_POLICY_TABLE_PIPE0m == ingress_table) ||
  16984              (IFP_POLICY_TABLE_PIPE1m == ingress_table) ||
  16985              (IFP_POLICY_TABLE_PIPE2m == ingress_table) ||
  16986              (IFP_POLICY_TABLE_PIPE3m == ingress_table) ||
  16987              (IFP_POLICY_TABLE_PIPE4m == ingress_table) ||
  16988              (IFP_POLICY_TABLE_PIPE5m == ingress_table) ||
  16989              (IFP_POLICY_TABLE_PIPE6m == ingress_table) ||
  16990              (IFP_POLICY_TABLE_PIPE7m == ingress_table))) {
  16991             uint32 zero = 0;
  16992 
  16993             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data,
  16994                                             G_COUNTf, &zero);
  16995             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data,
  16996                                             Y_COUNTf, &zero);
  16997             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data,
  16998                                             R_COUNTf, &zero);
  16999         }
  17000 #endif
  17001 #if defined(BCM_TOMAHAWK_SUPPORT)
  17002         if (
  17003 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  17004             (!_bcm_esw_stat_table_is_profile(unit, ingress_table)) &&
  17005 #endif
  17006             soc_th_ifp_mem_write(unit,ingress_table, MEM_BLOCK_ALL,
  17007                           _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  17008                           ingress_entry_data) != SOC_E_NONE) {
  17009 #else
  17010         if (soc_mem_write(unit,ingress_table, MEM_BLOCK_ALL,
  17011                           _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  17012                           ingress_entry_data) != SOC_E_NONE) {
  17013 #endif /* BCM_TOMAHAWK_SUPPORT */
  17014             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17015                       (BSL_META_U(unit,
  17016                                   "Table:%s:Index %d encounter some problem \n"),
  17017                        SOC_MEM_UFNAME(unit, ingress_table),index));
  17018             sal_free(ingress_entry_data);
  17019             return    BCM_E_INTERNAL;
  17020         }
  17021 
  17022        LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17023                  (BSL_META_U(unit,
  17024                              "Deallocated for Table:%sIndex:%d:"
  17025                               "mode %d reference_count %d\n"),
  17026                   SOC_MEM_UFNAME(unit, ingress_table),index,offset_mode,
  17027                   flex_base_index_reference_count[unit]
  17028                   [bcmStatFlexDirectionIngress][pipe_num][pool_number][base_idx]));
  17029         sal_free(ingress_entry_data);
  17030 
  17031 #if defined(BCM_TOMAHAWK_SUPPORT)
  17032         if (BCM_TH_LOCAL_PIPE_MODE(unit, pool_number)) {
  17033             /* In this mode, counters must be collected independently for each pipe. */
  17034             maxpipe = NUM_PIPE(unit);
  17035         }
  17036 
  17037 #endif
  17038         unused_pool = 1;
  17039         for(pipe = 0; pipe < maxpipe; ++pipe) {
  17040             if (flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe][pool_number].
  17041                            attached_entries != 0) {
  17042                 unused_pool = 0;
  17043                 break;
  17044             }
  17045         }
  17046 
  17047         /* Disable flex pool for this stat on no flex entries */
  17048         if (unused_pool) {
  17049             _bcm_esw_stat_flex_enable_pool(
  17050                      unit,
  17051                      bcmStatFlexDirectionIngress,
  17052                      _pool_ctr_register[bcmStatFlexDirectionIngress]
  17053                                        [pool_number],
  17054                      0);
  17055         }
  17056         if (flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress]
  17057                                            [pipe_num][pool_number][base_idx] == 0) {
  17058             if (_bcm_esw_stat_flex_insert_stat_id(unit,
  17059                         local_scache_ptr[unit],stat_counter_id) != BCM_E_NONE) {
  17060                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17061                          (BSL_META_U(unit,
  17062                                      "WARMBOOT: Couldnot add entry in scache memory."
  17063                                       "Attach it\n")));
  17064             }
  17065         }
  17066         return BCM_E_NONE;
  17067     }
  17068     sal_free(ingress_entry_data);
  17069     return    BCM_E_NOT_FOUND;
  17070 }
  17071 /*
  17072  * Function:
  17073  *      _bcm_esw_stat_flex_detach_ingress_table_counters
  17074  * Description:
  17075  *      Detach i.e. Disable Igresss accounting table's statistics
  17076  * Parameters:
  17077  *      unit                  - (IN) unit number
  17078  *      ingress_table         - (IN) Flex Accounting Table
  17079  *      index                 - (IN) Flex Accounting Table's Index
  17080  *
  17081  * Return Value:
  17082  *      BCM_E_XXX
  17083  * Notes:
  17084  */
  17085 bcm_error_t _bcm_esw_stat_flex_detach_ingress_table_counters(
  17086             int       unit,
  17087             soc_mem_t ingress_table,
  17088             uint32    index)
  17089 {
  17090     uint32                          offset_mode = 0;
  17091     uint32                          pool_number = 0;
  17092     uint32                          base_idx = 0;
  17093     uint32                          ingress_entry_data_size = 0;
  17094     uint32                          flex_entries = 0;
  17095     bcm_stat_flex_ctr_offset_info_t flex_ctr_offset_info = {0};
  17096     void                            *ingress_entry_data = NULL;
  17097     bcm_stat_object_t               object=bcmStatObjectIngPort;
  17098     uint32                          stat_counter_id = 0;
  17099     int                             pipe_num = 0;
  17100     int                             pipe = 0, maxpipe = 1, unused_pool;
  17101     uint32                          total_counters = 0;
  17102 #if defined(BCM_TRIDENT3_SUPPORT)
  17103     soc_flow_db_mem_view_info_t mem_view_info;
  17104 #endif
  17105     uint32 is_view = 0;
  17106     uint32 width = 0;
  17107     soc_mem_t ingress_view_table = ingress_table; /* memory view or memory */
  17108 
  17109 #if defined(BCM_TRIDENT3_SUPPORT)
  17110     if ((soc_feature(unit,soc_feature_flex_flow)) &&
  17111         (soc_flow_db_mem_view_is_valid(unit, ingress_table))) {
  17112         /* when ingress_table is view_id perform below else
  17113          */
  17114         BCM_IF_ERROR_RETURN(soc_flow_db_mem_view_info_get(unit,
  17115                                       ingress_table,
  17116                                       &mem_view_info));
  17117         is_view = 1;
  17118         ingress_table = mem_view_info.mem;
  17119         width = BITS2BYTES(mem_view_info.width);
  17120         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17121                     (BSL_META_U(unit,
  17122                     "View ID %d mem_id %d\n"),
  17123                      ingress_view_table, ingress_table));
  17124 
  17125     }
  17126 #endif  /* BCM_TRIDENT3_SUPPORT */
  17127 
  17128     if (!((ingress_table == PORT_TABm) ||
  17129          (ingress_table == VLAN_XLATEm)  ||
  17130 #if defined(BCM_TRIUMPH3_SUPPORT)
  17131          (ingress_table == VLAN_XLATE_EXTDm)  ||
  17132          (ingress_table == MPLS_ENTRY_EXTDm)  ||
  17133          (ingress_table == L3_TUNNELm)  ||
  17134          (ingress_table == L3_ENTRY_2m)  ||
  17135          (ingress_table == L3_ENTRY_4m)  ||
  17136          (ingress_table == EXT_IPV4_UCAST_WIDEm)  ||
  17137          (ingress_table == EXT_IPV6_128_UCAST_WIDEm)  ||
  17138          (ingress_table == EXT_FP_POLICYm)  ||
  17139 #endif
  17140 #if defined(BCM_TRIDENT2_SUPPORT)
  17141          (ingress_table == ING_VSANm) ||
  17142          (ingress_table == L3_ENTRY_IPV4_MULTICASTm) ||
  17143          (ingress_table == L3_ENTRY_IPV6_MULTICASTm) ||
  17144          (ingress_table == L3_DEFIPm) ||
  17145          (ingress_table == L3_DEFIP_PAIR_128m) ||
  17146          (ingress_table == L3_DEFIP_LEVEL1m) ||
  17147          (ingress_table == L3_DEFIP_PAIR_LEVEL1m) ||
  17148          (ingress_table == L3_DEFIP_ALPM_LEVEL2m) ||
  17149          (ingress_table == L3_DEFIP_ALPM_LEVEL3m) ||
  17150          (ingress_table == L3_DEFIP_ALPM_RAWm) ||
  17151          (ingress_table == L3_DEFIP_ALPM_IPV4_1m) ||
  17152          (ingress_table == L3_DEFIP_ALPM_IPV6_64_1m) ||
  17153          (ingress_table == L3_DEFIP_ALPM_IPV6_128m) ||
  17154 #endif
  17155 #if  defined (BCM_TRIDENT2PLUS_SUPPORT)
  17156          (ingress_table == FP_POLICY_TABLEm)          ||
  17157 #endif
  17158 #if defined(BCM_TOMAHAWK_SUPPORT) 
  17159          (ingress_table == IFP_POLICY_TABLEm)          ||
  17160          (SOC_IS_TOMAHAWKX(unit) &&
  17161          ((ingress_table == IFP_POLICY_TABLE_PIPE0m)   ||
  17162           (ingress_table == IFP_POLICY_TABLE_PIPE1m)   ||
  17163           (ingress_table == IFP_POLICY_TABLE_PIPE2m)   ||
  17164           (ingress_table == IFP_POLICY_TABLE_PIPE3m)   ||
  17165           (ingress_table == IFP_POLICY_TABLE_PIPE4m)   ||
  17166           (ingress_table == IFP_POLICY_TABLE_PIPE5m)   ||
  17167           (ingress_table == IFP_POLICY_TABLE_PIPE6m)   ||
  17168           (ingress_table == IFP_POLICY_TABLE_PIPE7m)   ||
  17169           (ingress_table == AGM_MONITOR_TABLEm))) ||
  17170 #endif
  17171          (ingress_table == VFP_POLICY_TABLEm)  ||
  17172 #if defined(BCM_TOMAHAWK_SUPPORT) 
  17173         (SOC_IS_TOMAHAWKX(unit) &&
  17174          ((ingress_table == VFP_POLICY_TABLE_PIPE0m)   ||
  17175           (ingress_table == VFP_POLICY_TABLE_PIPE1m)   ||
  17176           (ingress_table == VFP_POLICY_TABLE_PIPE2m)   ||
  17177           (ingress_table == VFP_POLICY_TABLE_PIPE3m)   ||
  17178           (ingress_table == VFP_POLICY_TABLE_PIPE4m)   ||
  17179           (ingress_table == VFP_POLICY_TABLE_PIPE5m)   ||
  17180           (ingress_table == VFP_POLICY_TABLE_PIPE6m)   ||
  17181           (ingress_table == VFP_POLICY_TABLE_PIPE7m))) ||
  17182 #endif
  17183 #if defined(BCM_TOMAHAWK3_SUPPORT)
  17184         (SOC_IS_TOMAHAWK3(unit) &&
  17185         ((ingress_table == LPORT_TABm)  ||
  17186         (ingress_table == L3_ENTRY_QUADm)  ||
  17187         (ingress_table == L3_ENTRY_DOUBLEm)))  ||
  17188 #endif
  17189 #if defined(BCM_TRIDENT3_SUPPORT)
  17190         (SOC_IS_TRIDENT3X(unit) &&
  17191         ((ingress_table == VLAN_XLATE_1_DOUBLEm)   ||
  17192         (ingress_table == VLAN_XLATE_2_DOUBLEm)   ||
  17193         (ingress_table == LPORT_TABm)   ||
  17194         (ingress_table == L3_ENTRY_QUADm)   ||
  17195         (ingress_table == L3_ENTRY_DOUBLEm)   ||
  17196         (ingress_table == VFP_POLICY_TABLE_PIPE0m)   ||
  17197         (ingress_table == VFP_POLICY_TABLE_PIPE1m)   ||
  17198         (ingress_table == IFP_POLICY_TABLE_PIPE0m)   ||
  17199         (ingress_table == IFP_POLICY_TABLE_PIPE1m) ||
  17200         (ingress_table == IFP_POLICY_TABLE_PIPE1m)   ||
  17201         (ingress_table == IFP_POLICY_TABLE_WIDEm)    ||
  17202         (ingress_table == IFP_POLICY_TABLE_WIDE_PIPE0m) ||
  17203         (ingress_table == IFP_POLICY_TABLE_WIDE_PIPE1m) ||
  17204         (ingress_table == AGM_MONITOR_TABLEm) ||
  17205         (ingress_table == MPLS_ENTRY_SINGLEm) ||
  17206         (ingress_table == VRF_ATTRS_2m))) ||
  17207 #endif
  17208          (ingress_table == MPLS_ENTRYm)  ||
  17209 #if defined(BCM_TOMAHAWK3_SUPPORT)
  17210          (ingress_table == MPLS_ENTRY_SINGLEm) ||
  17211 #endif
  17212          (ingress_table == SOURCE_VPm)  ||
  17213          (ingress_table == L3_IIFm)  ||
  17214          (ingress_table == VRFm)  ||
  17215          (ingress_table == VFIm)  ||
  17216          (ingress_table == VLAN_TABm))) {
  17217           LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17218                     (BSL_META_U(unit,
  17219                                 "Invalid Flex Counter Ingress Memory %s\n"),
  17220                      SOC_MEM_UFNAME(unit, ingress_table)));
  17221           return BCM_E_PARAM;
  17222     }
  17223 
  17224     if (!is_view)
  17225     {
  17226         width =  SOC_MEM_INFO(unit, ingress_table).bytes;
  17227     }
  17228 
  17229 
  17230 #if defined (BCM_TOMAHAWK_SUPPORT)
  17231     pipe_num = _bcm_esw_get_fp_pipe_num(unit, ingress_table);
  17232 #endif
  17233     ingress_entry_data_size = WORDS2BYTES(BYTES2WORDS(width));
  17234     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17235               (BSL_META_U(unit,
  17236                           "Deallocating IngressCounter Table:%s:Index:%d:"
  17237                            " ENTRY_BYTES:%d \n"),
  17238                SOC_MEM_UFNAME(unit, ingress_table),
  17239                index,ingress_entry_data_size));
  17240     ingress_entry_data = sal_alloc(ingress_entry_data_size,"ingress_table");
  17241     if (ingress_entry_data == NULL) {
  17242         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17243                   (BSL_META_U(unit,
  17244                               "Failed to allocate memory for Table:%s "),
  17245                    SOC_MEM_UFNAME(unit, ingress_table)));
  17246         return BCM_E_INTERNAL;
  17247     }
  17248     sal_memset(ingress_entry_data,0,ingress_entry_data_size);
  17249 #if defined (BCM_TOMAHAWK_SUPPORT)
  17250     if (soc_th_ifp_mem_read(unit, ingress_table, MEM_BLOCK_ANY,
  17251                  _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  17252                  ingress_entry_data) == SOC_E_NONE)
  17253 #else
  17254     if (soc_mem_read(unit, ingress_view_table, MEM_BLOCK_ANY,
  17255                  _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  17256                  ingress_entry_data) == SOC_E_NONE)
  17257 #endif /* BCM_TOMAHAWK_SUPPORT */
  17258     {
  17259 #if defined(BCM_TRIDENT3_SUPPORT)
  17260         if (is_view) {
  17261             if (soc_flow_db_mem_view_entry_is_valid(unit,
  17262                                         ingress_view_table,
  17263                                         ingress_entry_data) == FALSE) {
  17264                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17265                           (BSL_META_U(unit,
  17266                                       "Table %s  with index %d is Not valid \n"),
  17267                            SOC_MEM_UFNAME(unit, ingress_table),index));
  17268                 sal_free(ingress_entry_data);
  17269                 return BCM_E_PARAM;
  17270             }
  17271         } else
  17272 #endif
  17273         {
  17274         if (soc_mem_field_valid(unit,ingress_table,VALIDf)) {
  17275             if (soc_mem_field32_get(unit,ingress_table,ingress_entry_data,
  17276                                     VALIDf) == 0) {
  17277                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17278                           (BSL_META_U(unit,
  17279                                       "Table %s  with index %d is Not valid \n"),
  17280                            SOC_MEM_UFNAME(unit, ingress_table),index));
  17281                 sal_free(ingress_entry_data);
  17282                 return BCM_E_PARAM;
  17283             }
  17284         }
  17285         }
  17286         _bcm_esw_get_flex_counter_fields_values(
  17287                  unit,index,ingress_view_table,ingress_entry_data,0,
  17288                  &offset_mode,&pool_number,&base_idx);
  17289         if ((offset_mode == 0) && (base_idx == 0)) {
  17290              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17291                        (BSL_META_U(unit,
  17292                                    "Table:%s:Index %d IsNotConfiguredForFlexCounter\n"),
  17293                         SOC_MEM_UFNAME(unit, ingress_table),index));
  17294              sal_free(ingress_entry_data);
  17295              return BCM_E_NOT_FOUND;/*Either NotConfigured/deallocated before*/
  17296         }
  17297 
  17298         if(_bcm_esw_stat_flex_get_ingress_object(
  17299            unit,ingress_view_table,index,ingress_entry_data,&object) != BCM_E_NONE) {
  17300            sal_free(ingress_entry_data);
  17301            return BCM_E_INTERNAL;
  17302         }
  17303 #if defined (BCM_TOMAHAWK_SUPPORT)
  17304     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  17305         (_bcm_esw_is_fp_table(ingress_table))) {
  17306         uint32 cmode = 0;
  17307         bcm_error_t rv;
  17308  
  17309         rv = _bcm_esw_custom_stat_group_id_retrieve(unit, offset_mode, pipe_num, 
  17310                                                     pool_number, base_idx,
  17311                                                     &stat_counter_id);
  17312         if (rv !=BCM_E_NONE) {
  17313             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17314                   (BSL_META_U(unit,
  17315                               "pipe %x Invalid mode value %d %d %d\n"),
  17316                    pipe_num, offset_mode, pool_number, base_idx));
  17317             _bcm_esw_stat_get_counter_id(
  17318                           unit, flex_ingress_modes[unit][offset_mode].group_mode,
  17319                           object,offset_mode,pool_number,base_idx,&stat_counter_id);
  17320             total_counters = flex_ingress_modes[unit][offset_mode].total_counters;
  17321         } else {
  17322             cmode = stat_counter_map[unit][stat_counter_id].mode;
  17323             total_counters = flex_custom_ingress_modes[unit][cmode - BCM_CUSTOM_INGRESS_MODE_START].
  17324                                             total_counters;
  17325         }
  17326     } else
  17327 #endif
  17328     {
  17329     _bcm_esw_stat_get_counter_id(
  17330                   unit, flex_ingress_modes[unit][offset_mode].group_mode,
  17331                   object,offset_mode,pool_number,base_idx,&stat_counter_id);
  17332     total_counters = flex_ingress_modes[unit][offset_mode].total_counters;
  17333     }
  17334 
  17335 
  17336         /* Decrement reference count */
  17337         BCM_STAT_FLEX_COUNTER_LOCK(unit);
  17338         flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress][pipe_num]
  17339                                        [pool_number][base_idx]--;
  17340         flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num][pool_number].
  17341                        attached_entries -= total_counters;
  17342         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  17343 
  17344         /* Clear Counter Values */
  17345         if ((flex_base_index_reference_count[unit]
  17346                     [bcmStatFlexDirectionIngress][pipe_num][pool_number][base_idx]) == 0 ) {
  17347             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17348                     (BSL_META_U(unit,
  17349                                 "Clearing Counter Tables %s contents:Offset:%d Len:%d\n"),
  17350                      SOC_MEM_UFNAME(unit, ingress_table),
  17351                      base_idx,
  17352                      total_counters));
  17353 
  17354             if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  17355                 if(ingress_view_table == VFP_POLICY_TABLEm) {
  17356                     /* Handle FP object ctr reset in StatIdMove*/
  17357                     if (compaction_info.base_idx != base_idx &&
  17358                             compaction_info.pool_number != pool_number &&
  17359                             compaction_info.in_progress == FALSE) {
  17360                         flex_ctr_offset_info.all_counters_flag =  1;
  17361                         _bcm_esw_stat_flex_set(unit,index,ingress_table, -1,
  17362                                 flex_ctr_offset_info,&flex_entries,
  17363                                 offset_mode,pool_number,base_idx,
  17364                                 bcmStatFlexDirectionIngress);
  17365                     }
  17366                 } else {
  17367                     flex_ctr_offset_info.all_counters_flag =  1;
  17368                     _bcm_esw_stat_flex_set(unit,index,ingress_table, -1,
  17369                             flex_ctr_offset_info,&flex_entries,
  17370                             offset_mode,pool_number,base_idx,
  17371                             bcmStatFlexDirectionIngress);
  17372                 }
  17373             } else {
  17374                 flex_ctr_offset_info.all_counters_flag =  1;
  17375                 _bcm_esw_stat_flex_set(unit,index,ingress_table, -1,
  17376                         flex_ctr_offset_info,&flex_entries,
  17377                         offset_mode,pool_number,base_idx,
  17378                         bcmStatFlexDirectionIngress);
  17379             }
  17380         }
  17381 
  17382         if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  17383             if(ingress_view_table == VFP_POLICY_TABLEm) {
  17384                 /* Handle FP object ctr reset in StatIdMove*/
  17385                 if (compaction_info.base_idx != base_idx &&
  17386                         compaction_info.pool_number != pool_number &&
  17387                         compaction_info.in_progress == FALSE) {
  17388                     /* Reset Table Values */
  17389                     _bcm_esw_set_flex_counter_fields_values(
  17390                             unit,index,ingress_view_table,ingress_entry_data,0,0,0,0);
  17391                 }
  17392             } else {
  17393                 /* Reset Table Values */
  17394                 _bcm_esw_set_flex_counter_fields_values(
  17395                         unit,index,ingress_view_table,ingress_entry_data,0,0,0,0);
  17396             }
  17397         } else {
  17398             /* Reset Table Values */
  17399             _bcm_esw_set_flex_counter_fields_values(
  17400                     unit,index,ingress_view_table,ingress_entry_data,0,0,0,0);
  17401         }
  17402 #if defined(BCM_TOMAHAWK_SUPPORT)
  17403         if (SOC_IS_TOMAHAWKX(unit) &&
  17404             ((IFP_POLICY_TABLEm == ingress_table) ||
  17405              (IFP_POLICY_TABLE_PIPE0m == ingress_table) ||
  17406              (IFP_POLICY_TABLE_PIPE1m == ingress_table) ||
  17407              (IFP_POLICY_TABLE_PIPE2m == ingress_table) ||
  17408              (IFP_POLICY_TABLE_PIPE3m == ingress_table) ||
  17409              (IFP_POLICY_TABLE_PIPE4m == ingress_table) ||
  17410              (IFP_POLICY_TABLE_PIPE5m == ingress_table) ||
  17411              (IFP_POLICY_TABLE_PIPE6m == ingress_table) ||
  17412              (IFP_POLICY_TABLE_PIPE7m == ingress_table))) {
  17413             uint32 zero = 0;
  17414 
  17415             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data,
  17416                                             G_COUNTf, &zero);
  17417             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data,
  17418                                             Y_COUNTf, &zero);
  17419             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data,
  17420                                             R_COUNTf, &zero);
  17421         }
  17422 #endif
  17423 #if defined(BCM_TOMAHAWK_SUPPORT)
  17424         if (soc_th_ifp_mem_write(unit,ingress_table, MEM_BLOCK_ALL,
  17425                           _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  17426                           ingress_entry_data) != SOC_E_NONE)
  17427 #else
  17428         if (soc_mem_write(unit,ingress_view_table, MEM_BLOCK_ALL,
  17429                           _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  17430                           ingress_entry_data) != SOC_E_NONE)
  17431 #endif /* BCM_TOMAHAWK_SUPPORT */
  17432         {
  17433             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17434                       (BSL_META_U(unit,
  17435                                   "Table:%s:Index %d encounter some problem \n"),
  17436                        SOC_MEM_UFNAME(unit, ingress_table),index));
  17437             sal_free(ingress_entry_data);
  17438             return    BCM_E_INTERNAL;
  17439         }
  17440 
  17441        LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17442                  (BSL_META_U(unit,
  17443                              "Deallocated for Table:%sIndex:%d:"
  17444                               "mode %d reference_count %d\n"),
  17445                   SOC_MEM_UFNAME(unit, ingress_table),index,offset_mode,
  17446                   flex_base_index_reference_count[unit]
  17447                   [bcmStatFlexDirectionIngress][pipe_num][pool_number][base_idx]));
  17448         sal_free(ingress_entry_data);
  17449 
  17450 #if defined(BCM_TOMAHAWK_SUPPORT)
  17451         if (BCM_TH_LOCAL_PIPE_MODE(unit, pool_number)) {
  17452             /* In this mode, counters must be collected independently for each pipe. */
  17453             maxpipe = NUM_PIPE(unit);
  17454         }
  17455 
  17456 #endif
  17457         unused_pool = 1;
  17458         for(pipe = 0; pipe < maxpipe; ++pipe) {
  17459             if (flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe][pool_number].
  17460                            attached_entries != 0) {
  17461                 unused_pool = 0;
  17462                 break;
  17463             }
  17464         }
  17465 
  17466         /* Disable flex pool for this stat on no flex entries */
  17467         if (unused_pool) {
  17468             _bcm_esw_stat_flex_enable_pool(
  17469                      unit,
  17470                      bcmStatFlexDirectionIngress,
  17471                      _pool_ctr_register[bcmStatFlexDirectionIngress]
  17472                                        [pool_number],
  17473                      0);
  17474         }
  17475         if (flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress]
  17476                                            [pipe_num][pool_number][base_idx] == 0) {
  17477             if (_bcm_esw_stat_flex_insert_stat_id(unit,
  17478                         local_scache_ptr[unit],stat_counter_id) != BCM_E_NONE) {
  17479                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17480                          (BSL_META_U(unit,
  17481                                      "WARMBOOT: Couldnot add entry in scache memory."
  17482                                       "Attach it\n")));
  17483             }
  17484         }
  17485         return BCM_E_NONE;
  17486     }
  17487     sal_free(ingress_entry_data);
  17488     return    BCM_E_NOT_FOUND;
  17489 }
  17490 
  17491 #if defined (BCM_TOMAHAWK_SUPPORT)
  17492 /*
  17493  * Function:
  17494  *      _bcm_esw_stat_flex_detach_ingress_table_counters_sw
  17495  * Description:
  17496  *      Detach i.e. Disable Ingress accounting table's statistics.
  17497  *      This function is used for Exact Match entries 
  17498  * Parameters:
  17499  *      unit                  - (IN) unit number
  17500  *      ingress_table         - (IN) Flex Accounting Table
  17501  *      index                 - (IN) Flex Accounting Table's Index
  17502  *
  17503  * Return Value:
  17504  *      BCM_E_XXX
  17505  * Notes:
  17506  */
  17507 bcm_error_t _bcm_esw_stat_flex_detach_ingress_table_counters_sw(
  17508             int       unit,
  17509             soc_mem_t ingress_table,
  17510             uint32    index,
  17511             bcm_stat_flex_mode_t offset_mode,
  17512             uint32    base_idx,
  17513             uint32    pool_number)
  17514 {
  17515     uint32                          flex_entries = 0;
  17516     bcm_stat_flex_ctr_offset_info_t flex_ctr_offset_info = {0};
  17517     uint32                          stat_counter_id = 0;
  17518     bcm_stat_object_t               object;
  17519     int                             pipe_num = 0;
  17520     bcm_stat_flex_custom_ingress_mode_t cmode;
  17521     uint32 mode_id = 0;
  17522     int                             pipe = 0, maxpipe = 1, unused_pool;
  17523     int total_counters = 0;
  17524     if (!(_bcm_esw_is_exact_match(ingress_table)
  17525         || (SOC_IS_TRIDENT3X(unit) && _bcm_esw_is_ifp_table(ingress_table)))) {
  17526           LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17527                     (BSL_META_U(unit,
  17528                                 "This function is for detaching SW data structures only: table %s\n"),
  17529                      SOC_MEM_UFNAME(unit, ingress_table)));
  17530           return BCM_E_PARAM;
  17531     }
  17532 
  17533     if (offset_mode >= BCM_CUSTOM_INGRESS_MODE_START) {
  17534         if(_bcm_esw_stat_flex_get_custom_ingress_mode_info(unit, offset_mode, &cmode)
  17535                                                                 == BCM_E_NONE) {
  17536             total_counters = flex_custom_ingress_modes[unit][offset_mode - BCM_CUSTOM_INGRESS_MODE_START].
  17537                                                 total_counters;
  17538             mode_id = cmode.offset_mode;
  17539         }
  17540     } else {
  17541         mode_id = offset_mode;
  17542         total_counters = flex_ingress_modes[unit][mode_id].total_counters;
  17543     }
  17544 
  17545     object = bcmStatObjectIngExactMatch;
  17546 
  17547     pipe_num = _bcm_esw_get_fp_pipe_num(unit, ingress_table);
  17548     if (((mode_id == 0) && (base_idx == 0)) ||
  17549           (flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress][pipe_num]
  17550                                    [pool_number][base_idx] <= 0)) {
  17551          LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17552                    (BSL_META_U(unit,
  17553                                "Table:%s:Index %d IsNotConfiguredForFlexCounter\n"),
  17554                     SOC_MEM_UFNAME(unit, ingress_table),index));
  17555          return BCM_E_NOT_FOUND;/*Either NotConfigured/deallocated before*/
  17556     }
  17557 
  17558     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  17559         (_bcm_esw_is_fp_table(ingress_table))) {
  17560         bcm_error_t rv;
  17561 
  17562         rv = _bcm_esw_custom_stat_group_id_retrieve(unit, mode_id, pipe_num,
  17563                                                     pool_number, base_idx,
  17564                                                     &stat_counter_id);
  17565         if (rv !=BCM_E_NONE) {
  17566             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17567                   (BSL_META_U(unit,
  17568                               "pipe %x Invalid mode value %d %d %d\n"),
  17569                    pipe_num, mode_id, pool_number, base_idx));
  17570             _bcm_esw_stat_get_counter_id(
  17571                           unit, flex_ingress_modes[unit][mode_id].group_mode,
  17572                           object,mode_id,pool_number,base_idx,&stat_counter_id);
  17573         }
  17574     } else {
  17575         _bcm_esw_stat_get_counter_id(
  17576                       unit, flex_ingress_modes[unit][mode_id].group_mode,
  17577                       object,mode_id,pool_number,base_idx,&stat_counter_id);
  17578     }
  17579 
  17580     /* Decrement reference count */
  17581     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  17582     flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress][pipe_num]
  17583                                    [pool_number][base_idx]--;
  17584     flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num][pool_number].
  17585                    attached_entries -= total_counters;
  17586     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  17587 
  17588     /* Clear Counter Values */
  17589     if ((flex_base_index_reference_count[unit]
  17590             [bcmStatFlexDirectionIngress][pipe_num][pool_number][base_idx]) == 0 ) {
  17591         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17592                   (BSL_META_U(unit,
  17593                               "Clearing Counter Tables %s contents:Offset:%d Len:%d\n"),
  17594                    SOC_MEM_UFNAME(unit, ingress_table),
  17595                    base_idx,
  17596                    total_counters));
  17597         flex_ctr_offset_info.all_counters_flag =  1;
  17598         _bcm_esw_stat_flex_set(unit,index,ingress_table, -1,
  17599                                flex_ctr_offset_info,&flex_entries,
  17600                                mode_id,pool_number,base_idx,
  17601                                bcmStatFlexDirectionIngress);
  17602     }
  17603 
  17604    LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17605              (BSL_META_U(unit,
  17606                          "Deallocated for Table:%sIndex:%d:"
  17607                           "mode %d reference_count %d\n"),
  17608               SOC_MEM_UFNAME(unit, ingress_table),index,offset_mode,
  17609               flex_base_index_reference_count[unit]
  17610               [bcmStatFlexDirectionIngress][pipe_num][pool_number][base_idx]));
  17611 
  17612     if (BCM_TH_LOCAL_PIPE_MODE(unit, pool_number)) {
  17613         /* In this mode, counters must be collected independently for each pipe. */
  17614         maxpipe = NUM_PIPE(unit);
  17615     }
  17616 
  17617     unused_pool = 1;
  17618 
  17619     for(pipe = 0; pipe < maxpipe; ++pipe) {
  17620         if (flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe][pool_number].
  17621                        attached_entries != 0) {
  17622             unused_pool = 0;
  17623             break;
  17624         }
  17625     }
  17626 
  17627     /* Disable flex pool for this stat on no flex entries */
  17628     if (unused_pool) {
  17629         _bcm_esw_stat_flex_enable_pool(
  17630                  unit,
  17631                  bcmStatFlexDirectionIngress,
  17632                  _pool_ctr_register[bcmStatFlexDirectionIngress]
  17633                                    [pool_number],
  17634                  0);
  17635     }
  17636     if (flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress]
  17637                                        [pipe_num][pool_number][base_idx] == 0) {
  17638         if (_bcm_esw_stat_flex_insert_stat_id(unit,
  17639                     local_scache_ptr[unit],stat_counter_id) != BCM_E_NONE) {
  17640             LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  17641                      (BSL_META_U(unit,
  17642                                      "WARMBOOT: Couldnot add entry in scache memory."
  17643                                       "Attach it\n")));
  17644         }
  17645     }
  17646     return BCM_E_NONE;
  17647 }
  17648 #endif
  17649 
  17650 /*
  17651  * Function:
  17652  *      _bcm_esw_stat_flex_destroy_ingress_table_counters
  17653  * Description:
  17654  *      Destroy Igresss accounting table's statistics completely
  17655  * Parameters:
  17656  *      unit                  - (IN) unit number
  17657  *      ingress_table         - (IN) Flex Accounting Table
  17658  *      offset_mode           - (IN) Flex offset mode for Accounting Object
  17659  *      base_idx              - (IN) Flex Base Index for Accounting Object
  17660  *      pool_number           - (IN) Flex Pool Number for Accounting Object
  17661  *
  17662  * Return Value:
  17663  *      BCM_E_XXX
  17664  * Notes:
  17665  */
  17666 bcm_error_t _bcm_esw_stat_flex_destroy_ingress_table_counters(
  17667             int                  unit,
  17668             soc_mem_t            ingress_table,
  17669             int                  lookup,
  17670             bcm_stat_object_t    object,
  17671             bcm_stat_flex_mode_t offset_mode,
  17672             uint32               base_idx,
  17673             uint32               pool_number)
  17674 {
  17675     uint32 free_count = 0, alloc_count = 0, largest_free = 0;
  17676     uint32 used_by_table = 0, stat_counter_id = 0;
  17677     uint32 pool_group_id;
  17678     int pipe_num = 0;    
  17679     uint32 orig_mode = offset_mode;
  17680     int total_counters = 0;
  17681     uint32 temp_base_idx = 0;
  17682 
  17683 #if defined (BCM_TOMAHAWK_SUPPORT)
  17684     pipe_num = _bcm_esw_get_fp_pipe_num(unit, ingress_table);
  17685     if ((offset_mode >= BCM_CUSTOM_INGRESS_MODE_START)  &&
  17686         (offset_mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  17687         total_counters = flex_custom_ingress_modes[unit][offset_mode - BCM_CUSTOM_INGRESS_MODE_START].
  17688                                                 total_counters;
  17689         offset_mode = flex_custom_ingress_modes[unit][offset_mode - 
  17690                                  BCM_CUSTOM_INGRESS_MODE_START].offset_mode;
  17691     } else {
  17692 #endif
  17693         total_counters = flex_ingress_modes[unit][offset_mode].total_counters;
  17694 #if defined(BCM_TOMAHAWK_SUPPORT)
  17695     }
  17696 #endif
  17697 
  17698     if (flex_ingress_modes[unit][offset_mode].available==0) {
  17699         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17700                   (BSL_META_U(unit,
  17701                               "flex counter mode %d not configured yet\n"),
  17702                    offset_mode));
  17703         return BCM_E_NOT_FOUND;
  17704     }
  17705 
  17706     if (shr_aidxres_list_elem_state(
  17707             flex_aidxres_list_handle[unit][bcmStatFlexDirectionIngress]
  17708             [pipe_num][pool_number],
  17709             base_idx) != BCM_E_EXISTS) {
  17710         if (BCM_SUCCESS(_field_is_inited(unit))) {
  17711             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17712                       (BSL_META_U(unit, "Wrong base index %u \n"),
  17713                         base_idx));
  17714         }
  17715         return BCM_E_NOT_FOUND;
  17716     }
  17717     if (flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress]
  17718                                        [pipe_num][pool_number][base_idx] != 0) {
  17719         if (BCM_SUCCESS(_field_is_inited(unit))) {
  17720             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17721                   (BSL_META_U(unit,
  17722                               "Reference count is  %d.. Please detach entries first..\n"),
  17723                    flex_base_index_reference_count[unit]
  17724                         [bcmStatFlexDirectionIngress][pipe_num][pool_number][base_idx]));
  17725         }
  17726         return BCM_E_BUSY;
  17727     }
  17728     switch(ingress_table) {
  17729     case PORT_TABm:
  17730 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  17731     case LPORT_TABm:
  17732 #endif
  17733          used_by_table = FLEX_COUNTER_POOL_USED_BY_PORT_TABLE;
  17734          break;
  17735     case VFP_POLICY_TABLEm:
  17736 #if defined(BCM_TOMAHAWK_SUPPORT)
  17737         case VFP_POLICY_TABLE_PIPE0m:
  17738         case VFP_POLICY_TABLE_PIPE1m:
  17739         case VFP_POLICY_TABLE_PIPE2m:
  17740         case VFP_POLICY_TABLE_PIPE3m:
  17741         case VFP_POLICY_TABLE_PIPE4m:
  17742         case VFP_POLICY_TABLE_PIPE5m:
  17743         case VFP_POLICY_TABLE_PIPE6m:
  17744         case VFP_POLICY_TABLE_PIPE7m:
  17745 #endif
  17746          used_by_table = FLEX_COUNTER_POOL_USED_BY_VFP_POLICY_TABLE;
  17747          break;
  17748          /* VLAN and VFI shares same pool */
  17749     case VLAN_TABm:
  17750          used_by_table = FLEX_COUNTER_POOL_USED_BY_VLAN_TABLE;
  17751          break;
  17752     case VFIm:
  17753          used_by_table = FLEX_COUNTER_POOL_USED_BY_VFI_TABLE;
  17754          break;
  17755          /* VRF and MPLS_VC_LABEL shares same pool */
  17756     case VRFm:
  17757 #if defined(BCM_TRIUMPH3_SUPPORT)
  17758     case VRF_ATTRS_2m:
  17759 #endif
  17760          used_by_table = FLEX_COUNTER_POOL_USED_BY_VRF_TABLE;
  17761          break;
  17762     case MPLS_ENTRYm:
  17763 #if defined(BCM_TRIUMPH3_SUPPORT)
  17764     case MPLS_ENTRY_EXTDm:
  17765 #endif
  17766 #if defined(BCM_TOMAHAWK3_SUPPORT)
  17767     case MPLS_ENTRY_SINGLEm:
  17768 #endif
  17769          used_by_table = FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE;
  17770          if  (lookup == 1) {
  17771              used_by_table =
  17772                  FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE;
  17773          } else if (lookup == 2) {
  17774 #if defined(BCM_APACHE_SUPPORT)
  17775              used_by_table =
  17776                  FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE_FOR_SCND_LKUP;
  17777 #endif
  17778          }
  17779          break;
  17780     case VLAN_XLATEm:
  17781 #if defined(BCM_TRIUMPH3_SUPPORT)
  17782     case VLAN_XLATE_EXTDm:
  17783 #endif
  17784 #if defined (BCM_TRIDENT3_SUPPORT)
  17785      case VLAN_XLATE_1_DOUBLEm:
  17786      case VLAN_XLATE_2_DOUBLEm:
  17787 #endif
  17788 
  17789          used_by_table = FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE;
  17790          if  (lookup == 1) {
  17791              used_by_table =
  17792                  FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE;
  17793          }
  17794          else if (lookup == 2) {
  17795              used_by_table =
  17796                  FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE_FOR_SCND_LKUP;
  17797          }
  17798          break;
  17799          /* L3_IIF and SOURCE_VP shares same pool*/
  17800     case L3_IIFm:
  17801          used_by_table = FLEX_COUNTER_POOL_USED_BY_L3_IIF_TABLE;
  17802          break;
  17803     case SOURCE_VPm:
  17804          used_by_table = FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE;
  17805          break;
  17806 #if defined(BCM_TRIUMPH3_SUPPORT)
  17807     case L3_TUNNELm:
  17808          used_by_table = FLEX_COUNTER_POOL_USED_BY_L3_TUNNEL_TABLE;
  17809          break;
  17810     case L3_ENTRY_2m:
  17811     case L3_ENTRY_4m:
  17812     case EXT_IPV4_UCAST_WIDEm:
  17813     case EXT_IPV6_128_UCAST_WIDEm:
  17814          used_by_table = FLEX_COUNTER_POOL_USED_BY_L3_ENTRY_TABLE;
  17815          break;
  17816     case EXT_FP_POLICYm:
  17817          used_by_table = FLEX_COUNTER_POOL_USED_BY_EXT_FP_POLICY_TABLE;
  17818          break;
  17819 #endif
  17820 #if defined(BCM_TRIDENT2_SUPPORT)
  17821     case ING_VSANm:
  17822          used_by_table = FLEX_COUNTER_POOL_USED_BY_VSAN_TABLE;
  17823          break;
  17824     case L3_ENTRY_IPV4_MULTICASTm:
  17825 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  17826     case L3_ENTRY_DOUBLEm:
  17827 #endif
  17828          used_by_table = FLEX_COUNTER_POOL_USED_BY_FCOE_TABLE;
  17829          break;
  17830     case L3_DEFIPm:
  17831     case L3_DEFIP_PAIR_128m:
  17832     case L3_DEFIP_ALPM_RAWm:
  17833     case L3_DEFIP_ALPM_IPV4_1m:
  17834     case L3_DEFIP_ALPM_IPV6_64_1m:
  17835     case L3_DEFIP_ALPM_IPV6_128m:
  17836     case L3_DEFIP_LEVEL1m:
  17837     case L3_DEFIP_PAIR_LEVEL1m:
  17838     case L3_DEFIP_ALPM_LEVEL2m:
  17839     case L3_DEFIP_ALPM_LEVEL3m:
  17840          used_by_table = FLEX_COUNTER_POOL_USED_BY_L3_ROUTE_TABLE;
  17841          break;
  17842 #endif
  17843 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
  17844 #if defined(BCM_TOMAHAWK_SUPPORT)
  17845     case IFP_POLICY_TABLE_PIPE0m:
  17846     case IFP_POLICY_TABLE_PIPE1m:
  17847     case IFP_POLICY_TABLE_PIPE2m:
  17848     case IFP_POLICY_TABLE_PIPE3m:
  17849     case IFP_POLICY_TABLE_PIPE4m:
  17850     case IFP_POLICY_TABLE_PIPE5m:
  17851     case IFP_POLICY_TABLE_PIPE6m:
  17852     case IFP_POLICY_TABLE_PIPE7m:
  17853          /* Check to see if counter allocation is being requested
  17854           * from a specific pool
  17855           */
  17856 
  17857          /* Get Pipe from ingress_table */
  17858          pipe_num = _bcm_esw_get_fp_pipe_num(unit, ingress_table);
  17859          /* Fall through */
  17860 #endif
  17861     case IFP_POLICY_TABLEm:
  17862          used_by_table = FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE;
  17863          break;
  17864 #if defined(BCM_TOMAHAWK_SUPPORT)
  17865     case EXACT_MATCH_2m:
  17866     case EXACT_MATCH_2_PIPE0m:
  17867     case EXACT_MATCH_2_PIPE1m:
  17868     case EXACT_MATCH_2_PIPE2m:
  17869     case EXACT_MATCH_2_PIPE3m:
  17870          /* Get Pipe from ingress_table */
  17871          pipe_num = _bcm_esw_get_fp_pipe_num(unit, ingress_table);
  17872          used_by_table = FLEX_COUNTER_POOL_USED_BY_EM_POLICY_TABLE;
  17873          break;
  17874     case AGM_MONITOR_TABLEm:
  17875          used_by_table = FLEX_COUNTER_POOL_USED_BY_AGM_MONITOR_TABLE;
  17876          break;
  17877 #endif
  17878 #endif
  17879     default:
  17880          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17881                    (BSL_META_U(unit,
  17882                                "Invalid Table is passed %d \n"),
  17883                     ingress_table));
  17884          return BCM_E_INTERNAL;
  17885     }
  17886     if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  17887         for (temp_base_idx =  base_idx;
  17888                 temp_base_idx <= (base_idx + total_counters - 1);
  17889                 temp_base_idx++) {
  17890             if (shr_aidxres_list_free(flex_aidxres_list_handle
  17891                         [unit][bcmStatFlexDirectionIngress][pipe_num][pool_number],
  17892                         temp_base_idx) != BCM_E_NONE) {
  17893                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17894                         (BSL_META_U(unit,
  17895                                     "Freeing memory Table:%s:encounter some problem due to entry not found or some other issue  \n"),
  17896                          SOC_MEM_UFNAME(unit, ingress_table)));
  17897                 return    BCM_E_NOT_FOUND;
  17898             }
  17899         }
  17900     } else {
  17901         if (shr_aidxres_list_free(flex_aidxres_list_handle
  17902                     [unit][bcmStatFlexDirectionIngress][pipe_num][pool_number],
  17903                     base_idx) != BCM_E_NONE) {
  17904             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17905                     (BSL_META_U(unit,
  17906                                 "Freeing memory Table:%s:encounter some problem due to entry not found or some other issue  \n"),
  17907                      SOC_MEM_UFNAME(unit, ingress_table)));
  17908             return    BCM_E_NOT_FOUND;
  17909         }
  17910     }
  17911 #if defined (BCM_TOMAHAWK_SUPPORT)
  17912     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  17913        (orig_mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  17914         (orig_mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  17915         bcm_error_t rv = BCM_E_CONFIG;
  17916  
  17917         rv = _bcm_esw_custom_stat_group_id_retrieve(unit, orig_mode, pipe_num, 
  17918                                   pool_number, base_idx, &stat_counter_id);
  17919         if (rv !=BCM_E_NONE) {
  17920             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  17921                   (BSL_META_U(unit,
  17922                               "Invalid mode value %d %d %d\n"),
  17923                    orig_mode, pool_number, base_idx));
  17924         }
  17925     } else
  17926 #endif
  17927     {  
  17928     _bcm_esw_stat_get_counter_id(
  17929                   unit, flex_ingress_modes[unit][offset_mode].group_mode,
  17930                   object,orig_mode,pool_number,base_idx,&stat_counter_id);
  17931     }
  17932 
  17933     if (_bcm_esw_stat_flex_delete_stat_id(unit,
  17934                  local_scache_ptr[unit],stat_counter_id) != BCM_E_NONE) {
  17935         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17936                  (BSL_META_U(unit,
  17937                              "WARMBOOT: Couldnot Delete entry in scache memory.\n")));
  17938     }
  17939     shr_aidxres_list_state(flex_aidxres_list_handle
  17940                            [unit][bcmStatFlexDirectionIngress][pipe_num][pool_number],
  17941                            NULL,NULL,NULL,NULL,
  17942                            &free_count,&alloc_count,&largest_free,NULL);
  17943     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  17944               (BSL_META_U(unit,
  17945                           "Current Pool status free_count:%d alloc_count:%d"
  17946                            "largest_free:%d used_by_tables:%d used_entries:%d\n"),
  17947                free_count,alloc_count,largest_free,
  17948                flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  17949                [pipe_num][pool_number].used_by_tables,
  17950                flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  17951                [pipe_num][pool_number].used_entries));
  17952     flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num]
  17953                   [pool_number].used_entries -= total_counters;
  17954     if (flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num][pool_number].
  17955         used_entries == 0) {
  17956 #if defined(BCM_TOMAHAWK_SUPPORT)
  17957         /* If this is a reserved pool then do not update
  17958          * used_by_tables info
  17959          */
  17960         if (!((SOC_IS_TOMAHAWKX(unit) ||SOC_IS_TRIDENT3X(unit)) &&
  17961             (pool_number >= BCM_FLEX_STAT_TH_RSVD_IFP_POOL_MIN)))
  17962 #endif
  17963         {
  17964             /* clear pipe0 info when all other pipes don't contain same object */
  17965             int tmp_pipe = 0;
  17966             if (pipe_num) {
  17967                 flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  17968                               [pipe_num][pool_number].used_by_tables &=
  17969                               ~used_by_table;
  17970                 SHR_BITCLR(flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  17971                            [pipe_num][pool_number].used_by_objects, object);
  17972             }
  17973             for (tmp_pipe = 0; tmp_pipe < NUM_PIPE(unit); tmp_pipe++) {
  17974                 if (SHR_BITGET(flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  17975                        [tmp_pipe][pool_number].used_by_objects, object)) {
  17976                     if(tmp_pipe == pipe_num) {
  17977                         continue;
  17978                     }
  17979 
  17980                     break;
  17981                 }
  17982             }
  17983             if(tmp_pipe == NUM_PIPE(unit)) {
  17984                 flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  17985                               [0][pool_number].used_by_tables &= ~used_by_table;
  17986                 SHR_BITCLR(flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  17987                            [0][pool_number].used_by_objects, object);
  17988             }
  17989             /* Decrement the free pool from the pool group database
  17990              * and if all the group pools are empty then remove the config from
  17991              * ING_FLEX_CTR_LM_CONFIG register.
  17992              * Clear the Group_type.
  17993              */
  17994             if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
  17995                 pool_group_id = pool_number/_bcm_esw_get_max_pool_groups(unit);
  17996                 flex_pool_group[unit][pipe_num][pool_group_id].free_pools++; 
  17997                 if(flex_pool_group[unit][pipe_num][pool_group_id].free_pools
  17998                             ==  BCM_STAT_FLEX_COUNTER_POOLS_PER_GROUP) {
  17999                     BCM_IF_ERROR_RETURN(
  18000                            _bcm_esw_stat_flex_oam_enable_ingress_group(
  18001                                                               unit,
  18002                                                               pool_group_id,
  18003                                                               0));
  18004                     flex_pool_group[unit][pipe_num][pool_group_id].group_type =
  18005                                                BCM_FLEX_POOL_GROUP_USED_BY_NONE;
  18006                 }
  18007             }
  18008         }
  18009     }
  18010     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  18011     flex_ingress_modes[unit][offset_mode].reference_count--;
  18012     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  18013 
  18014     if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  18015         flex_packet_counter_compaction[unit]
  18016             [bcmStatFlexDirectionIngress][pipe_num][pool_number]
  18017             [base_idx] = 0;
  18018         COMPILER_64_SET(flex_packet64_counter_compaction[unit]
  18019                 [bcmStatFlexDirectionIngress][pipe_num][pool_number]
  18020                 [base_idx],0,0);
  18021         COMPILER_64_SET(flex_byte_counter_compaction[unit]
  18022                 [bcmStatFlexDirectionIngress][pipe_num][pool_number]
  18023                 [base_idx],0,0);
  18024     }
  18025     return    BCM_E_NONE;
  18026 }
  18027 
  18028 /*
  18029  * Function:
  18030  *      _bcm_esw_stat_flex_attach_egress_table_counters1
  18031  * Description:
  18032  *      Atach i.e. Enable Egresss accounting table's statistics
  18033  * Parameters:
  18034  *      unit                  - (IN) unit number
  18035  *      egress_table          - (IN) Flex Accounting Table
  18036  *      index                 - (IN) Flex Accounting Table's Index
  18037  *      mode                  - (IN) Flex offset mode for Accounting Object
  18038  *      base_idx              - (IN) Flex Base Index for Accounting Object
  18039  *      pool_number           - (IN) Flex Pool Number for Accounting Object
  18040  * Return Value:
  18041  *      BCM_E_XXX
  18042  * Notes:
  18043  */
  18044 bcm_error_t _bcm_esw_stat_flex_attach_egress_table_counters1(
  18045             int                  unit,
  18046             soc_mem_t            egress_table,
  18047             uint32               index,
  18048             bcm_stat_flex_mode_t mode,
  18049             uint32               base_idx,
  18050             uint32               pool_number,
  18051             void                *egress_entry_data1)
  18052 {
  18053     uint32               egress_entry_data_size=0;
  18054     void                 *egress_entry_data=NULL;
  18055     void                 *egress_entry_data_temp=NULL;
  18056     bcm_stat_flex_mode_t offset_mode_l={0};
  18057     bcm_stat_object_t    object=bcmStatObjectEgrPort;
  18058     uint32               stat_counter_id=0;
  18059     uint32               base_idx_l=0;
  18060     uint32               pool_number_l=0;
  18061     int                  pipe_num = 0;
  18062     int                  total_counters = 0;
  18063 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  18064     uint32               cmode = mode;
  18065 
  18066     if (mode >= BCM_CUSTOM_INGRESS_MODE_START) {
  18067         uint32 tmp_mode = mode + (BCM_CUSTOM_EGRESS_MODE_START & 0xffff0000) -
  18068             BCM_CUSTOM_EGRESS_MODE_START;
  18069         total_counters = flex_custom_egress_modes[unit]
  18070             [tmp_mode].total_counters;
  18071         mode = flex_custom_egress_modes[unit]
  18072             [tmp_mode].offset_mode;
  18073     } else
  18074 #endif
  18075     {
  18076         total_counters = flex_egress_modes[unit][mode].total_counters;
  18077     }
  18078 
  18079     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  18080         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18081                   (BSL_META_U(unit,
  18082                               "Invalid flex counter mode value %d \n"),
  18083                    mode));
  18084         return BCM_E_PARAM;
  18085     }
  18086     if (flex_egress_modes[unit][mode].available==0) {
  18087         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18088                   (BSL_META_U(unit,
  18089                               "flex CounterMode:%d:Not configured yet\n"),
  18090                    mode));
  18091         return BCM_E_NOT_FOUND;
  18092     }
  18093 
  18094 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  18095     pipe_num = _bcm_esw_get_fp_pipe_num(unit, egress_table);
  18096 #endif
  18097     if (shr_aidxres_list_elem_state(flex_aidxres_list_handle
  18098                                     [unit][bcmStatFlexDirectionEgress]
  18099                                     [pipe_num][pool_number],base_idx) != BCM_E_EXISTS) {
  18100         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18101                   (BSL_META_U(unit,
  18102                               "Wrong base index %u \n"),
  18103                    base_idx));
  18104         return BCM_E_NOT_FOUND;
  18105     }
  18106     egress_entry_data_size = WORDS2BYTES(BYTES2WORDS(
  18107                              SOC_MEM_INFO(unit, egress_table).bytes));
  18108     if (egress_entry_data1  == NULL ) {
  18109     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  18110               (BSL_META_U(unit,
  18111                           ".Allocating EgressCounter Table:%s:Index:%d:Mode:%d"
  18112                            " ENTRY_BYTES %d\n"),
  18113                SOC_MEM_UFNAME(unit,egress_table),index,mode,
  18114                egress_entry_data_size));
  18115         egress_entry_data = sal_alloc(egress_entry_data_size,"egress_table");
  18116         if (egress_entry_data == NULL) {
  18117             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18118                     (BSL_META_U(unit,
  18119                                 "Failed to allocate memory for Table:%s "),
  18120                      SOC_MEM_UFNAME(unit, egress_table)));
  18121             return BCM_E_INTERNAL;
  18122         }
  18123         sal_memset(egress_entry_data,0,SOC_MEM_INFO(unit, egress_table).bytes);
  18124 
  18125         if (soc_mem_read(unit, egress_table, MEM_BLOCK_ANY,
  18126                     _bcm_esw_stat_flex_table_index_map(unit,egress_table,index),
  18127                     egress_entry_data) != SOC_E_NONE) {
  18128             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18129                     (BSL_META_U(unit,
  18130                                 "Read failure for Table %s with index %d \n"),
  18131                      SOC_MEM_UFNAME(unit, egress_table),index));
  18132             sal_free(egress_entry_data);
  18133             return BCM_E_INTERNAL;
  18134         }
  18135         egress_entry_data_temp = egress_entry_data;
  18136     } else {
  18137         egress_entry_data_temp = egress_entry_data1;
  18138     }
  18139     if (soc_mem_field_valid(unit,egress_table,VALIDf)) {
  18140         if (soc_mem_field32_get(unit,egress_table,egress_entry_data_temp,
  18141                                 VALIDf)==0) {
  18142             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18143                       (BSL_META_U(unit,
  18144                                   "Table %s  with index %d is Not valid \n"),
  18145                        SOC_MEM_UFNAME(unit, egress_table),index));
  18146             if (egress_entry_data1 == NULL) {
  18147                 sal_free(egress_entry_data);
  18148             }
  18149             return BCM_E_PARAM;
  18150         }
  18151     }
  18152     _bcm_esw_get_flex_counter_fields_values(
  18153                  unit,index,egress_table,egress_entry_data_temp,0,
  18154                  &offset_mode_l,&pool_number_l,&base_idx_l);
  18155     if (base_idx_l != 0) {
  18156         if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  18157             /*
  18158              * If counter movement is in progress allow the new base index
  18159              * programming to continue counter collection without delay.
  18160              * Decrement old base index refrence count and destroy old stat
  18161              * counter id in bcmStatCustomBaseIdxMove.
  18162              */
  18163             if (compaction_info.base_idx != base_idx_l &&
  18164                     compaction_info.pool_number != pool_number_l &&
  18165                     compaction_info.in_progress == FALSE) {
  18166                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18167                         (BSL_META_U(unit,
  18168                                     "Table:%s Has already allocated with index:%d"
  18169                                     "base %d mode %d."
  18170                                     "First dealloc it \n"), SOC_MEM_UFNAME(unit, egress_table),
  18171                          index,base_idx_l,offset_mode_l));
  18172                 if (egress_entry_data1 == NULL) {
  18173                     sal_free(egress_entry_data);
  18174                 }
  18175                 return BCM_E_EXISTS;/*Either NotConfigured or deallocated before */
  18176             }
  18177         } else {
  18178             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18179                     (BSL_META_U(unit,
  18180                                 "Table:%s HasAlreadyAllocatedWithIndex:%d base %d mode %d."
  18181                                 "First dealloc it \n"),SOC_MEM_UFNAME(unit, egress_table),
  18182                      index,base_idx_l,offset_mode_l));
  18183             if (egress_entry_data1 == NULL) {
  18184                 sal_free(egress_entry_data);
  18185             }
  18186             return BCM_E_EXISTS;/*Either Not configured or deallocated before*/
  18187         }
  18188     }
  18189     _bcm_esw_set_flex_counter_fields_values(
  18190              unit,index,egress_table,egress_entry_data_temp,0,
  18191              mode,pool_number,base_idx);
  18192 
  18193     if (egress_entry_data1 == NULL) {
  18194         if (
  18195 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  18196             (!_bcm_esw_stat_table_is_profile(unit, egress_table)) &&
  18197 #endif
  18198             soc_mem_write(unit,egress_table, MEM_BLOCK_ALL,
  18199                     _bcm_esw_stat_flex_table_index_map(unit,egress_table,index),
  18200                     egress_entry_data_temp) != SOC_E_NONE) {
  18201             if (egress_entry_data1 == NULL) {
  18202                 sal_free(egress_entry_data);
  18203             }
  18204             return BCM_E_INTERNAL;
  18205         }
  18206     }
  18207 
  18208     if(_bcm_esw_stat_flex_get_egress_object(unit,egress_table,
  18209        index,egress_entry_data_temp,&object) != BCM_E_NONE) {
  18210         if (egress_entry_data1 == NULL) {
  18211             sal_free(egress_entry_data);
  18212         }
  18213        return BCM_E_INTERNAL;
  18214     }
  18215 
  18216     if (egress_entry_data1 == NULL) {
  18217         sal_free(egress_entry_data);
  18218     }
  18219 
  18220 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  18221     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  18222        (cmode >= BCM_CUSTOM_EGRESS_MODE_START) &&
  18223         (cmode < BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE)) {
  18224         bcm_error_t rv = BCM_E_CONFIG;
  18225 
  18226         rv = _bcm_esw_custom_stat_group_id_retrieve(unit, cmode, pipe_num,
  18227                                pool_number, base_idx, &stat_counter_id);
  18228         if (rv != BCM_E_NONE) {
  18229             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18230                   (BSL_META_U(unit,
  18231                               "No stat ID for  %d %d %d\n"),
  18232                    cmode, pool_number, base_idx));
  18233         }
  18234     } else
  18235 #endif
  18236     {
  18237     _bcm_esw_stat_get_counter_id(unit,
  18238                   flex_egress_modes[unit][mode].group_mode,
  18239                   object,mode,pool_number,base_idx,&stat_counter_id);
  18240     }
  18241 
  18242     if (flex_base_index_reference_count[unit][bcmStatFlexDirectionEgress][pipe_num]
  18243                                        [pool_number][base_idx] == 0) {
  18244         if (_bcm_esw_stat_flex_delete_stat_id(unit,local_scache_ptr[unit],
  18245                                               stat_counter_id) != BCM_E_NONE) {
  18246             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  18247                         (BSL_META_U(unit,
  18248                                     "WARMBOOT: Could not delete entry in scache memory.\n")));
  18249         }
  18250     }
  18251 
  18252     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  18253     flex_base_index_reference_count[unit][bcmStatFlexDirectionEgress][pipe_num]
  18254                                    [pool_number][base_idx]++;
  18255     if (flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number].
  18256          attached_entries == 0) {
  18257 
  18258         _bcm_esw_stat_flex_enable_pool(
  18259                  unit,bcmStatFlexDirectionEgress,
  18260                  _pool_ctr_register[bcmStatFlexDirectionEgress][pool_number],1);
  18261     }
  18262     flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number].
  18263                        attached_entries += total_counters;
  18264     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  18265     return BCM_E_NONE;
  18266 }
  18267 
  18268 /*
  18269  * Function:
  18270  *      _bcm_esw_stat_flex_attach_egress_table_counters
  18271  * Description:
  18272  *      Atach i.e. Enable Egresss accounting table's statistics
  18273  * Parameters:
  18274  *      unit                  - (IN) unit number
  18275  *      egress_table          - (IN) Flex Accounting Table
  18276  *      index                 - (IN) Flex Accounting Table's Index
  18277  *      mode                  - (IN) Flex offset mode for Accounting Object
  18278  *      base_idx              - (IN) Flex Base Index for Accounting Object
  18279  *      pool_number           - (IN) Flex Pool Number for Accounting Object
  18280  * Return Value:
  18281  *      BCM_E_XXX
  18282  * Notes:
  18283  */
  18284 bcm_error_t _bcm_esw_stat_flex_attach_egress_table_counters(
  18285             int                  unit,
  18286             soc_mem_t            egress_table,
  18287             uint32               index,
  18288             bcm_stat_object_t    object_id,
  18289             bcm_stat_flex_mode_t mode,
  18290             uint32               base_idx,
  18291             uint32               pool_number)
  18292 {
  18293     uint32               egress_entry_data_size=0;
  18294     void                 *egress_entry_data=NULL;
  18295     bcm_stat_flex_mode_t offset_mode_l={0};
  18296     bcm_stat_object_t    object=bcmStatObjectEgrPort;
  18297     uint32               stat_counter_id=0;
  18298     uint32               base_idx_l=0;
  18299     uint32               pool_number_l=0;
  18300     uint32               exact_index=0;
  18301 #if defined(BCM_TRIDENT3_SUPPORT)
  18302     soc_flow_db_mem_view_info_t mem_view_info;
  18303     uint32 is_view = 0;
  18304 #endif
  18305     uint32 width = 0;
  18306     soc_mem_t egress_view_table = egress_table; /* memory view or memory */
  18307     int                  pipe_num = 0;
  18308 
  18309 #if defined(BCM_TRIDENT3_SUPPORT)
  18310     if ((soc_feature(unit,soc_feature_flex_flow)) &&
  18311         (soc_flow_db_mem_view_is_valid(unit, egress_table))) {
  18312         /* when egress_table is view_id perform below else
  18313             */
  18314         BCM_IF_ERROR_RETURN(soc_flow_db_mem_view_info_get(unit, egress_table,
  18315                                       &mem_view_info));
  18316         is_view = 1;
  18317         egress_table = mem_view_info.mem;
  18318         width = BITS2BYTES(mem_view_info.width);
  18319         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  18320                     (BSL_META_U(unit,
  18321                     "View ID %d mem_id %d\n"),
  18322                      egress_view_table, egress_table));
  18323 
  18324     } else
  18325 #endif  /* BCM_TRIDENT3_SUPPORT */
  18326     {
  18327         width =  SOC_MEM_INFO(unit, egress_table).bytes;
  18328     }
  18329 
  18330     exact_index = index;
  18331     if ((egress_table == EGR_IP_TUNNEL_MPLSm)
  18332 #if defined (BCM_TRIDENT3_SUPPORT)
  18333         || (egress_table == EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm)
  18334 #endif
  18335         ) {
  18336         index = index / _BCM_MPLS_NUM_MPLS_ENTRIES_PER_INDEX(unit);
  18337     }
  18338     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  18339         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18340                   (BSL_META_U(unit,
  18341                               "Invalid flex counter mode value %d \n"),
  18342                    mode));
  18343         return BCM_E_PARAM;
  18344     }
  18345     if (flex_egress_modes[unit][mode].available==0) {
  18346         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18347                   (BSL_META_U(unit,
  18348                               "flex CounterMode:%d:Not configured yet\n"),
  18349                    mode));
  18350         return BCM_E_NOT_FOUND;
  18351     }
  18352 
  18353 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  18354     pipe_num = _bcm_esw_get_fp_pipe_num(unit, egress_table);
  18355 #endif
  18356 
  18357     if (shr_aidxres_list_elem_state(flex_aidxres_list_handle
  18358                                     [unit][bcmStatFlexDirectionEgress]
  18359                                     [pipe_num][pool_number],base_idx) != BCM_E_EXISTS) {
  18360         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18361                   (BSL_META_U(unit,
  18362                               "Wrong base index %u \n"),
  18363                    base_idx));
  18364         return BCM_E_NOT_FOUND;
  18365     }
  18366     egress_entry_data_size = WORDS2BYTES(BYTES2WORDS(width));
  18367     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  18368               (BSL_META_U(unit,
  18369                           ".Allocating EgressCounter Table:%s:Index:%d:Mode:%d"
  18370                            " ENTRY_BYTES %d\n"),
  18371                SOC_MEM_UFNAME(unit,egress_table),index,mode,
  18372                egress_entry_data_size));
  18373     egress_entry_data = sal_alloc(egress_entry_data_size,"egress_table");
  18374     if (egress_entry_data == NULL) {
  18375         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18376                   (BSL_META_U(unit,
  18377                               "Failed to allocate memory for Table:%s "),
  18378                    SOC_MEM_UFNAME(unit, egress_table)));
  18379         return BCM_E_INTERNAL;
  18380     }
  18381     sal_memset(egress_entry_data, 0, width);
  18382 
  18383     if (soc_mem_read(unit, egress_view_table, MEM_BLOCK_ANY,
  18384                 _bcm_esw_stat_flex_table_index_map(unit,egress_table,index),
  18385                 egress_entry_data) != SOC_E_NONE) {
  18386         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18387                   (BSL_META_U(unit,
  18388                               "Read failure for Table %s with index %d \n"),
  18389                    SOC_MEM_UFNAME(unit, egress_table),index));
  18390         sal_free(egress_entry_data);
  18391         return BCM_E_INTERNAL;
  18392     }
  18393 #if defined(BCM_TRIDENT3_SUPPORT)
  18394     if (is_view) {
  18395         if (soc_flow_db_mem_view_entry_is_valid(unit,
  18396                                             egress_view_table,
  18397                                             egress_entry_data) == FALSE) {
  18398             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18399                       (BSL_META_U(unit,
  18400                                   "Table %s  with index %d is Not valid \n"),
  18401                        SOC_MEM_UFNAME(unit, egress_table),index));
  18402             sal_free(egress_entry_data);
  18403             return BCM_E_PARAM;
  18404         }
  18405     } else
  18406 #endif
  18407     {
  18408     if (soc_mem_field_valid(unit,egress_table,VALIDf)) {
  18409         if (soc_mem_field32_get(unit,egress_table,egress_entry_data,
  18410                                 VALIDf)==0) {
  18411             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18412                       (BSL_META_U(unit,
  18413                                   "Table %s  with index %d is Not valid \n"),
  18414                        SOC_MEM_UFNAME(unit, egress_table),index));
  18415             sal_free(egress_entry_data);
  18416             return BCM_E_PARAM;
  18417         }
  18418     }
  18419     }
  18420     _bcm_esw_get_flex_counter_fields_values(
  18421                  unit,exact_index,egress_view_table,
  18422                  egress_entry_data,object_id,&offset_mode_l,
  18423                  &pool_number_l,&base_idx_l);
  18424     if (base_idx_l != 0) {
  18425         if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  18426             /*
  18427              * If counter movement is in progress allow the new base index
  18428              * programming to continue counter collection without delay.
  18429              * Decrement old base index refrence count and destroy old stat
  18430              * counter id in bcmStatCustomBaseIdxMove.
  18431              */
  18432             if (compaction_info.base_idx != base_idx_l &&
  18433                     compaction_info.pool_number != pool_number_l &&
  18434                     compaction_info.in_progress == FALSE) {
  18435                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18436                         (BSL_META_U(unit,
  18437                                     "Table:%s Has already allocated with index:%d"
  18438                                     "base %d mode %d."
  18439                                     "First dealloc it \n"), SOC_MEM_UFNAME(unit, egress_table),
  18440                          index,base_idx_l,offset_mode_l));
  18441                 sal_free(egress_entry_data);
  18442                 return BCM_E_EXISTS;/*Either NotConfigured or deallocated before */
  18443             }
  18444         } else {
  18445             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18446                     (BSL_META_U(unit,
  18447                                 "Table:%s HasAlreadyAllocatedWithIndex:%d base %d mode %d."
  18448                                 "First dealloc it \n"),SOC_MEM_UFNAME(unit, egress_table),
  18449                      index,base_idx_l,offset_mode_l));
  18450             sal_free(egress_entry_data);
  18451             return BCM_E_EXISTS;/*Either Not configured or deallocated before*/
  18452         }
  18453     }
  18454     _bcm_esw_set_flex_counter_fields_values(
  18455              unit,exact_index,egress_view_table,
  18456              egress_entry_data,object_id,
  18457              mode,pool_number,base_idx);
  18458     if (
  18459 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  18460         (!_bcm_esw_stat_table_is_profile(unit, egress_table)) &&
  18461 #endif
  18462         soc_mem_write(unit,egress_view_table, MEM_BLOCK_ALL,
  18463                        _bcm_esw_stat_flex_table_index_map(unit,egress_table,index),
  18464                        egress_entry_data) != SOC_E_NONE) {
  18465         sal_free(egress_entry_data);
  18466         return BCM_E_INTERNAL;
  18467     }
  18468     if (object_id != bcmStatObjectEgrMplsTunnelSecondLabel) {
  18469         if(_bcm_esw_stat_flex_get_egress_object(unit,egress_view_table,
  18470        index,egress_entry_data,&object) != BCM_E_NONE) {
  18471        sal_free(egress_entry_data);
  18472        return BCM_E_INTERNAL;
  18473     }
  18474     } else {
  18475         object = object_id;
  18476     }
  18477     sal_free(egress_entry_data);
  18478     _bcm_esw_stat_get_counter_id(
  18479                   unit, flex_egress_modes[unit][mode].group_mode,
  18480                   object,mode,pool_number,base_idx,&stat_counter_id);
  18481     if (flex_base_index_reference_count[unit][bcmStatFlexDirectionEgress][pipe_num]
  18482                                        [pool_number][base_idx] == 0) {
  18483         if (_bcm_esw_stat_flex_delete_stat_id(unit,local_scache_ptr[unit],
  18484                                               stat_counter_id) != BCM_E_NONE) {
  18485             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  18486                      (BSL_META_U(unit,
  18487                                  "WARMBOOT:Couldnot Delete entry in scache memory\n")));
  18488         }
  18489     }
  18490     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  18491     flex_base_index_reference_count[unit][bcmStatFlexDirectionEgress][pipe_num]
  18492                                    [pool_number][base_idx]++;
  18493     if (flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number].
  18494          attached_entries == 0) {
  18495 
  18496         _bcm_esw_stat_flex_enable_pool(
  18497                  unit,bcmStatFlexDirectionEgress,
  18498                  _pool_ctr_register[bcmStatFlexDirectionEgress][pool_number],1);
  18499     }
  18500     flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num][pool_number].
  18501                        attached_entries += flex_egress_modes[unit]
  18502                                            [mode].total_counters;
  18503     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  18504     return BCM_E_NONE;
  18505 }
  18506 /*
  18507  * Function:
  18508  *      _bcm_esw_stat_flex_pool_operation
  18509  * Description:
  18510  *      Allocated or Deallocate Pool Counters
  18511  * Parameters:
  18512  *      unit                  - (IN) unit number
  18513  *      flex_pool_attributes  - (IN) Flex Pool Attributes
  18514  *           module_type           - (IN) Flex Module Type (Not Used Currently)
  18515  *           pool_size             - (IN) Flex Pool Size
  18516  *           flags                 - (IN) Combination of below flags
  18517  *                                        1)Either
  18518  *                                               BCM_FLEX_INGRESS_POOL(default)
  18519  *                                                    OR
  18520  *                                               BCM_FLEX_EGRESS_POOL
  18521  *                                        2)Either
  18522  *                                               BCM_FLEX_ALLOCATE_POOL(default)
  18523  *                                                    OR
  18524  *                                               BCM_FLEX_DEALLOCATE_POOL
  18525  *                                        3)Either
  18526  *                                               BCM_FLEX_SHARED_POOL(default)
  18527  *                                                    OR
  18528  *                                               BCM_FLEX_NOT_SHARED_POOL
  18529  *                                          (NotApplicable in deallocation case)
  18530  *           pool_id               - (IN/OUT) Flex Pool ID
  18531  *           offset                - (IN/OUT) Flex Pool Base Index
  18532  *
  18533  * Return Value:
  18534  *      BCM_E_XXX
  18535  * Notes:
  18536  */
  18537 bcm_error_t  _bcm_esw_stat_flex_pool_operation(
  18538               int                            unit,
  18539               bcm_stat_flex_pool_attribute_t *flex_pool_attribute)
  18540 {
  18541     bcm_stat_flex_direction_t direction = bcmStatFlexDirectionIngress;
  18542     uint32                    num_flex_pools=SOC_INFO(unit).
  18543                                              num_flex_ingress_pools;
  18544     uint32                    size_pool= SOC_INFO(unit).size_flex_ingress_pool;
  18545     uint32                    block_factor=15;
  18546     uint32                    pool_number_l=0;
  18547     uint32                    default_pool_number=0;
  18548     uint32                    used_by_table_selection_criteria=
  18549                               TABLE_INDEPENDENT_POOL_MASK;
  18550     uint32                    shared_pool=1;
  18551     uint32                    base_idx_l=0;
  18552     uint32                    alloc_count=0;
  18553 
  18554     if (flex_pool_attribute == NULL) {
  18555         return BCM_E_PARAM;
  18556     }
  18557     if ((flex_pool_attribute->flags & BCM_FLEX_EGRESS_POOL) ==
  18558          BCM_FLEX_EGRESS_POOL) {
  18559          direction = bcmStatFlexDirectionEgress;
  18560          num_flex_pools=SOC_INFO(unit).num_flex_egress_pools;
  18561          size_pool= SOC_INFO(unit).size_flex_egress_pool;
  18562     }
  18563     if ((flex_pool_attribute->flags & BCM_FLEX_NOT_SHARED_POOL) ==
  18564          BCM_FLEX_NOT_SHARED_POOL) {
  18565          shared_pool=0;
  18566     }
  18567     if (flex_pool_attribute->pool_size > size_pool) {
  18568         return BCM_E_PARAM;
  18569     }
  18570     if ((flex_pool_attribute->flags & BCM_FLEX_DEALLOCATE_POOL) ==
  18571          BCM_FLEX_DEALLOCATE_POOL) {
  18572          pool_number_l =  (flex_pool_attribute->pool_id);
  18573          if (pool_number_l > num_flex_pools) {
  18574              return BCM_E_PARAM;
  18575          }
  18576          if (flex_pool_stat[unit][direction][0][pool_number_l].
  18577              used_by_tables != TABLE_INDEPENDENT_POOL_MASK) {
  18578              return BCM_E_PARAM;
  18579          }
  18580          BCM_STAT_FLEX_COUNTER_LOCK(unit);
  18581          if (shr_aidxres_list_free(
  18582              flex_aidxres_list_handle[unit][direction][0][pool_number_l],
  18583              flex_pool_attribute->offset) != BCM_E_NONE) {
  18584              BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  18585              return BCM_E_PARAM;
  18586         }
  18587         flex_pool_stat[unit][direction][0][pool_number_l].
  18588                       used_entries -= flex_pool_attribute->pool_size;
  18589         shr_aidxres_list_state(flex_aidxres_list_handle
  18590                                [unit][direction][0][pool_number_l],
  18591                                NULL,NULL,NULL,NULL,
  18592                                NULL,&alloc_count,NULL,NULL);
  18593         if ((flex_pool_stat[unit][direction][0][pool_number_l].
  18594              used_entries == 0) ||
  18595              (alloc_count == 0)) {
  18596              _bcm_esw_stat_flex_enable_pool(
  18597                   unit,
  18598                   direction,
  18599                   _pool_ctr_register[direction][pool_number_l],0);
  18600              flex_pool_stat[unit][direction][0][pool_number_l].used_entries=0;
  18601              flex_pool_stat[unit][direction][0][pool_number_l].used_by_tables = 0;
  18602              SHR_BITCLR_RANGE(flex_pool_stat[unit][direction][0][pool_number_l].
  18603                                 used_by_objects, 0, bcmIntStatObjectMaxValue);
  18604              /* Destroy Existing One */
  18605              shr_aidxres_list_destroy(flex_aidxres_list_handle[unit]
  18606                                       [direction][0][pool_number_l]);
  18607              /* Re Create it back to original one */
  18608              if (shr_aidxres_list_create(&flex_aidxres_list_handle
  18609                  [unit][direction][0][pool_number_l],
  18610                  0,size_pool-1,
  18611                  0,size_pool-1,
  18612                  8, /* Max 256 counters */
  18613                  "flex-counter") != BCM_E_NONE) {
  18614                  LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18615                            (BSL_META_U(unit,
  18616                                        "Unrecoverable error. Couldn'tCreate "
  18617                                         "AllignedList:FlexCounter\n")));
  18618                  BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  18619                  return BCM_E_INTERNAL;
  18620              }
  18621              shr_aidxres_list_reserve_block(
  18622                  flex_aidxres_list_handle[unit][direction][0][pool_number_l],
  18623                  0, (1 << 1));
  18624         }
  18625         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  18626     } else {
  18627         BCM_STAT_FLEX_COUNTER_LOCK(unit);
  18628         pool_number_l =  (flex_pool_attribute->pool_id);
  18629         do {
  18630            if ((flex_pool_stat[unit][direction][0][pool_number_l].
  18631                 used_by_tables == 0) ||
  18632                 ((shared_pool == 1) &&
  18633                  (flex_pool_stat[unit][direction][0][pool_number_l].
  18634                   used_by_tables & used_by_table_selection_criteria))) {
  18635 
  18636                 if ((flex_pool_stat[unit][0][direction][pool_number_l].
  18637                      used_by_tables == 0)) {
  18638                      /* Destroy Existing One */
  18639                      shr_aidxres_list_destroy(flex_aidxres_list_handle[unit]
  18640                                               [direction][0][pool_number_l]);
  18641                      /* Re Create it */
  18642                      if (shr_aidxres_list_create(&flex_aidxres_list_handle
  18643                          [unit][direction][0][pool_number_l],
  18644                          0,size_pool-1,
  18645                          0,size_pool-1,
  18646                          block_factor,
  18647                          "flex-counter") != BCM_E_NONE) {
  18648                          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18649                                    (BSL_META_U(unit,
  18650                                                "Unrecoverable error. Couldn'tCreate "
  18651                                                 "AllignedList:FlexCounter\n")));
  18652                          BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  18653                          return BCM_E_INTERNAL;
  18654                    }
  18655                 }
  18656                 shr_aidxres_list_state(flex_aidxres_list_handle
  18657                                        [unit][direction][0][pool_number_l],
  18658                                        NULL,NULL,NULL,NULL,
  18659                                        NULL,&alloc_count,NULL,NULL);
  18660                 if (shr_aidxres_list_alloc_block(
  18661                     flex_aidxres_list_handle[unit][direction][0][pool_number_l],
  18662                     flex_pool_attribute->pool_size,
  18663                     &base_idx_l) == BCM_E_NONE) {
  18664                     if ((flex_pool_stat[unit][direction][0][pool_number_l].
  18665                          used_entries == 0) ||
  18666                          (alloc_count == 0)) {
  18667                          _bcm_esw_stat_flex_enable_pool(
  18668                               unit,
  18669                               direction,
  18670                               _pool_ctr_register[direction][pool_number_l],1);
  18671                     }
  18672                     flex_pool_stat[unit][direction][0][pool_number_l].
  18673                          used_by_tables = TABLE_INDEPENDENT_POOL_MASK;
  18674                     flex_pool_stat[unit][direction][0][pool_number_l].
  18675                          used_entries += flex_pool_attribute->pool_size;
  18676                     flex_pool_attribute->offset  = (int)base_idx_l;
  18677                     flex_pool_attribute->pool_id = (int)pool_number_l;
  18678                     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  18679                     return BCM_E_NONE;
  18680                 }
  18681             } else {
  18682                BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  18683                return BCM_E_RESOURCE;
  18684             }
  18685             pool_number_l = (pool_number_l+1) % num_flex_pools;
  18686         } while(pool_number_l != default_pool_number);
  18687         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  18688         return BCM_E_RESOURCE;
  18689     }
  18690     return BCM_E_NONE;
  18691 }
  18692 
  18693 #if defined (BCM_TOMAHAWK3_SUPPORT)
  18694 /*
  18695  *  The function returns "1" if it meets all of the below conditions:
  18696  *  (1) If the given pool ID (parameter) is already shared by another latency monitor,
  18697  *      checks if the time step value of that monitor is matching with the time step
  18698  *      value of the given monitor ID (parameter).
  18699  *  (2) Check f there is no overlap between the source port bit map of monitors that
  18700  *      we want to share the same flex pool.
  18701  */
  18702 static int
  18703 _check_for_time_step_value_match_and_pbmp_conflict(
  18704                             int unit,
  18705                             bcm_stat_object_t object,
  18706                             uint32 pool_number,
  18707                             uint8  monitor_id)
  18708 {
  18709     uint8       i;
  18710     uint8       monitor_bmp = 0;
  18711     uint8       pbmp_conflict_flag = 0;
  18712     soc_pbmp_t  dest_pbmp;
  18713     soc_pbmp_t  src_pbmp;
  18714 
  18715     /* Find all the the monitors that share the given pool ID (in to a bit map) */
  18716     for (i=0; i<LATENCY_MONITOR_MAX_COUNT; i++) {
  18717         if (SOC_LATENCY_MONITOR_INFO(unit, i).flex_pool_number == pool_number)
  18718             monitor_bmp |= (1 << i);
  18719     }
  18720 
  18721     /* If no monitors sharig the pool, then return 0 */
  18722     if (!monitor_bmp)
  18723         return 0;
  18724 
  18725     for (i = 0; i < LATENCY_MONITOR_MAX_COUNT; i++) {
  18726         if (!(monitor_bmp & (1 << i)))
  18727             continue;
  18728         /*
  18729          * Check if the time step value of given Monitor ID matches with that of the
  18730          * monitor we want to share the flex pool with.
  18731          */
  18732         if (SOC_LATENCY_MONITOR_INFO(unit, i).time_step ==
  18733                 SOC_LATENCY_MONITOR_INFO(unit, monitor_id).time_step) {
  18734 
  18735             /* Check if there is overlapping the source port bit map */
  18736             BCM_PBMP_CLEAR(dest_pbmp);
  18737             BCM_PBMP_OR(dest_pbmp, SOC_LATENCY_MONITOR_INFO(unit, monitor_id).dest_pbmp);
  18738             BCM_PBMP_AND(dest_pbmp, SOC_LATENCY_MONITOR_INFO(unit, i).dest_pbmp);
  18739 
  18740             /* Check if there is overlapping the destination port bit map */
  18741             BCM_PBMP_CLEAR(src_pbmp);
  18742             BCM_PBMP_OR(src_pbmp, SOC_LATENCY_MONITOR_INFO(unit, monitor_id).src_pbmp);
  18743             BCM_PBMP_AND(src_pbmp, SOC_LATENCY_MONITOR_INFO(unit, i).src_pbmp);
  18744 
  18745             /* If there is overlap, set the flag */
  18746             if (BCM_PBMP_NOT_NULL(dest_pbmp) && BCM_PBMP_NOT_NULL(src_pbmp)) {
  18747                 pbmp_conflict_flag |= 1;
  18748                 break;
  18749             }
  18750         } else {
  18751             pbmp_conflict_flag |= 1;
  18752             break;
  18753         }
  18754     }
  18755 
  18756     if (!pbmp_conflict_flag)
  18757         return 1;
  18758 
  18759     return 0;
  18760 }
  18761 #endif
  18762 
  18763 /*
  18764  * Function:
  18765  *      _bcm_esw_stat_flex_create_egress_table_counters
  18766  * Description:
  18767  *      Create and Reserve Flex Counter Space for Egresss accounting table
  18768  * Parameters:
  18769  *      unit                  - (IN) unit number
  18770  *      egress_table          - (IN) Flex Accounting Table
  18771  *      mode                  - (IN) Flex offset mode for Accounting Object
  18772  *      base_idx              - (IN) Flex Base Index for Accounting Object
  18773  *      pool_number           - (IN) Flex Pool Number for Accounting Object
  18774  *
  18775  * Return Value:
  18776  *      BCM_E_XXX
  18777  * Notes:
  18778  */
  18779 bcm_error_t _bcm_esw_stat_flex_create_egress_table_counters(
  18780             int                  unit,
  18781             soc_mem_t            egress_table,
  18782             int                  lookup,
  18783             bcm_stat_object_t    object,
  18784             bcm_stat_flex_mode_t mode_id,
  18785             uint32               *base_idx,
  18786             uint32               *pool_number)
  18787 {
  18788     uint32            base_idx_l=0;
  18789     uint32            pool_number_l=0;
  18790     uint32            default_pool_number=0;
  18791     uint32            used_by_table=0;
  18792     uint32            used_by_table_selection_criteria=0;
  18793     uint32            free_count=0;
  18794     uint32            alloc_count=0;
  18795     uint32            largest_free=0;
  18796     uint32            stat_counter_id=0;
  18797     uint32            num_flex_egress_pools = SOC_INFO(unit).
  18798                                               num_flex_egress_pools;
  18799     flex_object_config_t object_config = {0};
  18800 #if defined (BCM_TOMAHAWK3_SUPPORT)
  18801     uint32            num_ctr;
  18802     int8              monitor_id;
  18803     uint8             pool_found = 0;
  18804     soc_reg_t         reg = INVALIDr;
  18805     uint32            reg_val = 0;
  18806 #endif
  18807 
  18808 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  18809     /* Used to indicate if counter allocation for EFP
  18810      * should be carried out from a specific pool
  18811      */
  18812     uint32            allocate_from_specific_pool = 0;
  18813 #endif
  18814         int               pipe_num = 0;
  18815 #if defined(BCM_TRIDENT3_SUPPORT)
  18816         bcm_field_qualify_t field_stage = 0;
  18817         int            pool = 0;
  18818 #endif
  18819         int            total_counters = 0;
  18820         bcm_stat_flex_mode_t mode = mode_id;
  18821 
  18822 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  18823         if ((mode_id >= BCM_CUSTOM_EGRESS_MODE_START)  &&
  18824             (mode_id < BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE)) {
  18825             total_counters = flex_custom_egress_modes[unit][mode_id -
  18826                                      BCM_CUSTOM_EGRESS_MODE_START].total_counters;
  18827             mode = flex_custom_egress_modes[unit][mode_id -
  18828                                      BCM_CUSTOM_EGRESS_MODE_START].offset_mode;
  18829         } else
  18830 #endif
  18831         {
  18832             total_counters = flex_egress_modes[unit][mode_id].total_counters;
  18833         }
  18834 
  18835     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  18836         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18837                   (BSL_META_U(unit,
  18838                               "Invalid flex counter mode value %d \n"),
  18839                    mode));
  18840         return BCM_E_PARAM;
  18841     }
  18842     if (flex_egress_modes[unit][mode].available==0) {
  18843         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18844                   (BSL_META_U(unit,
  18845                               "flex CounterMode:%d:Not configured yet\n"),
  18846                    mode));
  18847         return BCM_E_NOT_FOUND;
  18848     }
  18849     /* Below case statement can be avoided by passing arguements for pool_number
  18850        and selection criteria But keeping it for better understanding
  18851        at same place */
  18852     switch(egress_table) {
  18853     case EGR_VLANm:
  18854          default_pool_number = pool_number_l =
  18855              FLEX_COUNTER_DEFAULT_EGR_VLAN_TABLE_POOL_NUMBER;
  18856          used_by_table_selection_criteria = used_by_table =
  18857              FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_TABLE;
  18858          break;
  18859     case EGR_VFIm:
  18860          default_pool_number = pool_number_l =
  18861              FLEX_COUNTER_DEFAULT_EGR_VFI_TABLE_POOL_NUMBER;
  18862          used_by_table_selection_criteria = used_by_table =
  18863              FLEX_COUNTER_POOL_USED_BY_EGR_VFI_TABLE;
  18864          break;
  18865     case EGR_L3_NEXT_HOPm:
  18866          default_pool_number = pool_number_l =
  18867              FLEX_COUNTER_DEFAULT_EGR_L3_NEXT_HOP_TABLE_POOL_NUMBER;
  18868          used_by_table_selection_criteria = used_by_table =
  18869              FLEX_COUNTER_POOL_USED_BY_EGR_L3_NEXT_HOP_TABLE;
  18870          break;
  18871     case EGR_VLAN_XLATEm:
  18872 #if defined (BCM_TRIDENT3_SUPPORT)
  18873     case EGR_VLAN_XLATE_1_DOUBLEm:
  18874     case EGR_VLAN_XLATE_2_DOUBLEm:
  18875 #endif
  18876 #if defined(BCM_TRIDENT2_SUPPORT)
  18877          if (SOC_IS_TD2_TT2(unit)) {
  18878              if (lookup == 1) {
  18879                  default_pool_number = pool_number_l =
  18880                      FLEX_COUNTER_TD2_DEFAULT_EGR_VLAN_XLATE_TABLE_POOL_NUMBER;
  18881                  used_by_table_selection_criteria = used_by_table =
  18882                      FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE;
  18883              } else if (lookup == 2) {
  18884 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  18885                  if (soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup)) {
  18886                      default_pool_number = pool_number_l =
  18887                          FLEX_COUNTER_DEFAULT_EGR_VLAN_XLATE_SCND_LKUP_POOL_NUMBER;
  18888                      used_by_table_selection_criteria = used_by_table =
  18889                          FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE_FOR_SCND_LKUP;
  18890                  }
  18891 #endif
  18892              }
  18893          } else
  18894 #endif
  18895          {
  18896              default_pool_number = pool_number_l =
  18897                  FLEX_COUNTER_DEFAULT_EGR_VLAN_XLATE_TABLE_POOL_NUMBER;
  18898              used_by_table_selection_criteria = used_by_table =
  18899                  FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE;
  18900 #if defined(BCM_METROLITE_SUPPORT)
  18901              if (SOC_IS_METROLITE(unit)) {
  18902                  default_pool_number = pool_number_l =
  18903                      FLEX_COUNTER_TD2_DEFAULT_EGR_VLAN_XLATE_TABLE_POOL_NUMBER;
  18904              }
  18905 #endif
  18906          }
  18907          break;
  18908    case EGR_PORTm:
  18909 #if defined (BCM_TRIDENT3_SUPPORT)
  18910     case EGR_LPORT_PROFILEm:
  18911 #endif
  18912          default_pool_number = pool_number_l =
  18913              FLEX_COUNTER_DEFAULT_EGR_PORT_TABLE_POOL_NUMBER;
  18914          used_by_table_selection_criteria = used_by_table =
  18915              FLEX_COUNTER_POOL_USED_BY_EGR_PORT_TABLE;
  18916          break;
  18917    case EGR_DVP_ATTRIBUTE_1m:
  18918 #if defined (BCM_TRIDENT3_SUPPORT)
  18919     case EGR_DVP_ATTRIBUTEm:
  18920 #endif
  18921          default_pool_number = pool_number_l =
  18922            FLEX_COUNTER_DEFAULT_EGR_DVP_ATTRIBUTE_1_TABLE_POOL_NUMBER;
  18923 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_METROLITE_SUPPORT)
  18924          if (SOC_IS_TD2_TT2(unit) || SOC_IS_METROLITE(unit)) {
  18925              default_pool_number = pool_number_l =
  18926                  FLEX_COUNTER_TD2_DEFAULT_EGR_DVP_ATTRIBUTE_1_TABLE_POOL_NUMBER;
  18927          }     
  18928 #endif
  18929          used_by_table_selection_criteria = used_by_table =
  18930              FLEX_COUNTER_POOL_USED_BY_EGR_DVP_ATTRIBUTE_1_TABLE;
  18931          break;
  18932    case EGR_NAT_PACKET_EDIT_INFOm:
  18933              default_pool_number = pool_number_l =
  18934                  FLEX_COUNTER_DEFAULT_L3_NAT_TABLE_POOL_NUMBER;
  18935 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_METROLITE_SUPPORT)
  18936          if (SOC_IS_TD2_TT2(unit) || SOC_IS_METROLITE(unit)) {
  18937             default_pool_number = pool_number_l =
  18938                 FLEX_COUNTER_TD2_DEFAULT_L3_NAT_TABLE_POOL_NUMBER;
  18939          }
  18940 #endif
  18941          used_by_table_selection_criteria = used_by_table =
  18942              FLEX_COUNTER_POOL_USED_BY_EGR_L3_NAT_TABLE;
  18943          break;
  18944 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  18945    case EFP_POLICY_TABLEm:
  18946 #if defined(BCM_TRIDENT3_SUPPORT)
  18947    case EFP_POLICY_TABLE_PIPE0m:
  18948    case EFP_POLICY_TABLE_PIPE1m:
  18949       field_stage = _bcm_esw_stat_get_field_stage_from_table(egress_table);
  18950       _bcm_esw_get_fp_pipe_pool_from_mode(unit, mode_id,
  18951                           field_stage, &pipe_num, &pool);
  18952 #endif
  18953          if (SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit) || SOC_IS_TRIDENT3X(unit)) {
  18954              if (-1 != *pool_number) {
  18955                  if (*pool_number < num_flex_egress_pools) {
  18956                      if (FLEX_COUNTER_POOL_USED_BY_EGR_EFP_POLICY_TABLE !=
  18957                          flex_pool_stat[unit][bcmStatFlexDirectionEgress]
  18958                                        [pipe_num][*pool_number].used_by_tables) {
  18959                          /* Pool from which counter allocation is being
  18960                           * requested is not used by EFP_POLICY_TABLE
  18961                           */
  18962                          return BCM_E_PARAM;
  18963                      }
  18964                      allocate_from_specific_pool = 1;
  18965                      default_pool_number = pool_number_l = *pool_number;
  18966                  } else {
  18967                      /* Invalid pool_number specified */
  18968                      return BCM_E_PARAM;
  18969                  }
  18970              } else {
  18971                  default_pool_number = pool_number_l =
  18972                      FLEX_COUNTER_DEFAULT_EGR_EFP_POLICY_TABLE_POOL_NUMBER;
  18973              }
  18974              used_by_table_selection_criteria = used_by_table =
  18975                  FLEX_COUNTER_POOL_USED_BY_EGR_EFP_POLICY_TABLE;
  18976          } else {
  18977              LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18978                        (BSL_META_U(unit, "Invalid Table is passed %d \n"),
  18979                         egress_table));
  18980              return BCM_E_PARAM;
  18981          }
  18982          break;
  18983    case EGR_IP_TUNNEL_MPLSm:
  18984          if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit) || SOC_IS_TRIDENT3X(unit)) {
  18985          if (lookup == 1) {
  18986             default_pool_number = pool_number_l =
  18987                  FLEX_COUNTER_DEFAULT_EGR_IP_TUNNEL_MPLS_POOL_NUMBER;
  18988             used_by_table_selection_criteria = used_by_table =
  18989                 FLEX_COUNTER_POOL_USED_BY_EGR_IP_TUNNEL_MPLS_TABLE;
  18990          } else if (lookup == 2) {
  18991               default_pool_number = pool_number_l =
  18992               FLEX_COUNTER_DEFAULT_EGR_IP_TUNNEL_MPLS_SCND_LBL_POOL_NUMBER;
  18993               used_by_table_selection_criteria = used_by_table =
  18994               FLEX_COUNTER_POOL_USED_BY_EGR_IP_TUNNEL_MPLS_SCND_LBL_TABLE;
  18995          }
  18996          } else {
  18997              LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  18998                        (BSL_META_U(unit, "Invalid Table is passed %d \n"),
  18999                         egress_table));
  19000              return BCM_E_PARAM;
  19001          }
  19002          break;
  19003 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  19004 #if defined(BCM_TOMAHAWK3_SUPPORT)
  19005    case EGR_HISTO_MON_0_Q_LATENCY_LIMIT_SELm:
  19006    case EGR_HISTO_MON_1_Q_LATENCY_LIMIT_SELm:
  19007    case EGR_HISTO_MON_2_Q_LATENCY_LIMIT_SELm:
  19008    case EGR_HISTO_MON_3_Q_LATENCY_LIMIT_SELm:
  19009         default_pool_number = pool_number_l =
  19010             FLEX_COUNTER_DEFAULT_LATENCY_MONITOR_POOL_NUMBER;
  19011         used_by_table_selection_criteria = used_by_table =
  19012             FLEX_COUNTER_POOL_USED_BY_LATENCY_MONITOR_TABLE;
  19013         break;
  19014 #endif /* BCM_TOMAHAWK3_SUPPORT */
  19015    default:
  19016          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19017                    (BSL_META_U(unit,
  19018                                "Invalid Table is passed %d \n"),
  19019                     egress_table));
  19020          return BCM_E_INTERNAL;
  19021    }
  19022 
  19023    if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  19024        /* Override default pool number with user configured pool */
  19025        pool_number_l = default_pool_number = 0;
  19026        if (*pool_number <= BCM_STAT_FLEX_COUNTER_MAX_POOL) {
  19027            default_pool_number = *pool_number;
  19028            pool_number_l = *pool_number;
  19029        }
  19030        base_idx_l = *base_idx;
  19031 
  19032        if (_bcm_stat_flex_reserve_base_index(unit,
  19033                    bcmStatFlexDirectionEgress,
  19034                    pool_number_l,
  19035                    total_counters,base_idx_l,
  19036                    used_by_table,pipe_num,object) == BCM_E_NONE){
  19037            _bcm_esw_stat_get_counter_id(
  19038                    unit, flex_egress_modes[unit][mode].group_mode,
  19039                    object,mode,pool_number_l,base_idx_l,
  19040                    &stat_counter_id);
  19041 
  19042            BCM_STAT_FLEX_COUNTER_LOCK(unit);
  19043            flex_egress_modes[unit][mode].reference_count++;
  19044            BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  19045            LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  19046                    (BSL_META_U(unit,
  19047                                "Allocated  counter Table:%s with pool_number:%d"
  19048                                "mode:%d base_idx:%d ref_count %d\n"),
  19049                     SOC_MEM_UFNAME(unit, egress_table),
  19050                     pool_number_l,mode,base_idx_l,
  19051                     flex_egress_modes[unit][mode].reference_count));
  19052            if (_bcm_esw_stat_flex_insert_stat_id(unit,
  19053                        local_scache_ptr[unit], stat_counter_id) != BCM_E_NONE) {
  19054                LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  19055                        (BSL_META_U(unit,
  19056                                    "WARMBOOT:Couldnot add entry in scache memory"
  19057                                    "Attach it\n")));
  19058                return BCM_E_INTERNAL;
  19059            }
  19060            return BCM_E_NONE;
  19061        } else {
  19062            return BCM_E_RESOURCE;
  19063        }
  19064    }
  19065    BCM_IF_ERROR_RETURN(
  19066        _bcm_esw_stat_flex_object_config_get(unit,
  19067                                             egress_table, &object_config));
  19068 
  19069    if (object_config.share_criteria != INVALID_CONFIG) {
  19070        used_by_table_selection_criteria |= object_config.share_criteria;
  19071        default_pool_number=pool_number_l = object_config.config_pool;
  19072    }
  19073    if (object_config.exclude_criteria != INVALID_CONFIG) {
  19074        used_by_table_selection_criteria &= ~(object_config.exclude_criteria);
  19075    }
  19076 
  19077 #if defined (BCM_TOMAHAWK3_SUPPORT)
  19078     if (SOC_IS_TOMAHAWK3(unit)) {
  19079         switch ((bcm_int_stat_object_t)object) {
  19080         case bcmIntStatObjectEgrLatencyMonitor0:
  19081             monitor_id = 0;
  19082             break;
  19083         case bcmIntStatObjectEgrLatencyMonitor1:
  19084             monitor_id = 1;
  19085             break;
  19086         case bcmIntStatObjectEgrLatencyMonitor2:
  19087             monitor_id = 2;
  19088             break;
  19089         case bcmIntStatObjectEgrLatencyMonitor3:
  19090             monitor_id = 3;
  19091             break;
  19092         default:
  19093             monitor_id = -1;
  19094             break;
  19095         }
  19096 
  19097         if (monitor_id != -1) {
  19098             pool_found = 0;
  19099             do {
  19100                 if ((flex_pool_stat[unit][bcmStatFlexDirectionEgress][0][pool_number_l].used_by_tables &
  19101                     FLEX_COUNTER_POOL_USED_BY_LATENCY_MONITOR_TABLE) &&
  19102                     (_check_for_time_step_value_match_and_pbmp_conflict(unit, object, pool_number_l, monitor_id))) {
  19103                     pool_found = 1;
  19104                     break;
  19105                 } else if (flex_pool_stat[unit][bcmStatFlexDirectionEgress]
  19106                         [0][pool_number_l].used_by_tables == 0) {
  19107                     pool_found = 1;
  19108                     break;
  19109                 }
  19110                 pool_number_l = (pool_number_l+1) % num_flex_egress_pools;
  19111             } while(pool_number_l != default_pool_number);
  19112 
  19113             if (!pool_found) {
  19114                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19115                           (BSL_META_U(unit,
  19116                                       "Pools exhausted for Table:%s\n"),
  19117                            SOC_MEM_UFNAME(unit, egress_table)));
  19118                 return BCM_E_RESOURCE;
  19119             }
  19120 
  19121             if (flex_pool_stat[unit][bcmStatFlexDirectionEgress]
  19122                         [0][pool_number_l].used_by_tables == 0) {
  19123                 num_ctr = SOC_INFO(unit).size_flex_egress_pool;
  19124                 shr_aidxres_list_destroy(flex_aidxres_list_handle
  19125                        [unit][bcmStatFlexDirectionEgress][0][pool_number_l]);
  19126                 if (shr_aidxres_list_create(
  19127                      &flex_aidxres_list_handle[unit][bcmStatFlexDirectionEgress][0][pool_number_l],
  19128                      0,num_ctr-1,
  19129                      0,num_ctr-1,
  19130                      10, /* Max 1024 counters */
  19131                      "flex-counter") != BCM_E_NONE) {
  19132                      LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19133                                 (BSL_META_U(unit,
  19134                                 "Unrecoverable error. Couldn'tCreate "
  19135                                 "AllignedList:FlexCounter\n")));
  19136                      return BCM_E_INTERNAL;
  19137                 }
  19138             }
  19139 
  19140             SOC_LATENCY_MONITOR_INFO(unit, monitor_id).flex_pool_number = pool_number_l;
  19141             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  19142                   (BSL_META_U(unit,
  19143                               "monitor_id:%d assigned pool:%d \n"),
  19144                    monitor_id, pool_number_l));
  19145 
  19146             /* Enable clear on read for the choosen flex counter pool */
  19147             reg = _pool_ctr_register[bcmStatFlexDirectionEgress][pool_number_l];
  19148             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY,0, &reg_val));
  19149             soc_reg_field_set(unit, reg, &reg_val, COUNTER_POOL_ENABLEf, 1);
  19150             soc_reg_field_set(unit, reg, &reg_val, CLR_ON_READf, 1);
  19151             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, reg_val));
  19152 
  19153             /* Disable the counter eviction explicitly for the allocated pool */
  19154             reg = egr_evict_regs[pool_number_l];
  19155             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY,
  19156                                 0, &reg_val));
  19157             soc_reg_field_set(unit, reg, &reg_val, MODEf, 0);
  19158             SOC_IF_ERROR_RETURN
  19159                     (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, reg_val));
  19160         } else if (flex_pool_stat[unit][bcmStatFlexDirectionEgress][0][pool_number_l].used_by_tables &
  19161                     FLEX_COUNTER_POOL_USED_BY_LATENCY_MONITOR_TABLE) {
  19162             pool_number_l++;
  19163         }
  19164     }
  19165 #endif /* BCM_TOMAHAWK3_SUPPORT */
  19166     
  19167    do {
  19168       /* Either free or being used by port table only */
  19169       if ((flex_pool_stat[unit][bcmStatFlexDirectionEgress]
  19170            [0][pool_number_l].used_by_tables == 0) ||
  19171           (flex_pool_stat[unit][bcmStatFlexDirectionEgress]
  19172            [0][pool_number_l].used_by_tables & used_by_table_selection_criteria)) {
  19173 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  19174             if ((SOC_IS_TD2P_TT2P(unit) || SOC_IS_TRIDENT3X(unit)) &&
  19175                 !allocate_from_specific_pool &&
  19176                 (bcmStatObjectEgrFieldStageEgress == object)) {
  19177                 if (0 != flex_pool_stat[unit][bcmStatFlexDirectionEgress]
  19178                                        [pipe_num][pool_number_l].used_entries) {
  19179                     /* For a non specific pool allocation
  19180                      * request, allocate from an unused pool only.
  19181                      */
  19182                     pool_number_l = (pool_number_l + 1) %
  19183                                     num_flex_egress_pools;
  19184                     if (pool_number_l == default_pool_number) {
  19185                         break;
  19186                     } else {
  19187                         continue;
  19188                     }
  19189                 }
  19190             }
  19191 #endif
  19192            if (shr_aidxres_list_alloc_block(flex_aidxres_list_handle
  19193                    [unit][bcmStatFlexDirectionEgress][pipe_num][pool_number_l],
  19194                    total_counters,
  19195                    &base_idx_l) == BCM_E_NONE) {
  19196                flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num]
  19197                     [pool_number_l].used_by_tables |= used_by_table;
  19198                SHR_BITSET(flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num]
  19199                     [pool_number_l].used_by_objects, object);
  19200                flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num]
  19201                     [pool_number_l].used_entries += total_counters;
  19202                LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  19203                          (BSL_META_U(unit,
  19204                                      "Allocated  counter Table:%s with pool_number:%d"
  19205                                       "mode:%d base_idx:%d ref_count %d\n"),
  19206                           SOC_MEM_UFNAME(unit, egress_table),
  19207                           pool_number_l,mode,base_idx_l,
  19208                           flex_egress_modes[unit][mode].reference_count));
  19209                shr_aidxres_list_state(
  19210                    flex_aidxres_list_handle[unit][bcmStatFlexDirectionEgress][pipe_num]
  19211                                            [pool_number_l],
  19212                    NULL,NULL,NULL,NULL,&free_count,&alloc_count,&largest_free,
  19213                    NULL);
  19214                LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  19215                          (BSL_META_U(unit,
  19216                                      "Current Pool status free_count:%d alloc_count:%d"
  19217                                       "largest_free:%d used_by_tables:%d"
  19218                                       "used_entries:%d\n"),
  19219                           free_count,alloc_count,largest_free,
  19220                           flex_pool_stat[unit][bcmStatFlexDirectionEgress][0]
  19221                           [pool_number_l].used_by_tables,
  19222                           flex_pool_stat[unit][bcmStatFlexDirectionEgress][0]
  19223                           [pool_number_l].used_entries));
  19224                *base_idx = base_idx_l;
  19225                *pool_number = pool_number_l;
  19226                _bcm_esw_stat_get_counter_id(
  19227                              unit, flex_egress_modes[unit][mode].group_mode,
  19228                              object,mode,pool_number_l,base_idx_l,
  19229                              &stat_counter_id);
  19230                BCM_STAT_FLEX_COUNTER_LOCK(unit);
  19231                flex_egress_modes[unit][mode].reference_count++;
  19232                BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  19233                if (_bcm_esw_stat_flex_insert_stat_id(unit,
  19234                    local_scache_ptr[unit], stat_counter_id) != BCM_E_NONE) {
  19235                    LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  19236                             (BSL_META_U(unit,
  19237                                         "WARMBOOT:Couldnot add entry in scache memory"
  19238                                          "Attach it\n")));
  19239                }
  19240                return BCM_E_NONE;
  19241            }
  19242 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  19243            else {
  19244                if ((SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit) || SOC_IS_TRIDENT3X(unit)) &&
  19245                    allocate_from_specific_pool &&
  19246                    (bcmStatObjectEgrFieldStageEgress == object)) {
  19247                    return BCM_E_RESOURCE;
  19248                }
  19249            }
  19250 #endif
  19251       }
  19252       pool_number_l = (pool_number_l+1) % num_flex_egress_pools;
  19253     } while(pool_number_l != default_pool_number);
  19254     LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19255               (BSL_META_U(unit,
  19256                           "Pools exhausted for Table:%s\n"),
  19257                SOC_MEM_UFNAME(unit, egress_table)));
  19258     return BCM_E_RESOURCE;
  19259 }
  19260 /*
  19261  * Function:
  19262  *      _bcm_esw_stat_flex_attach_ingress_table_counters_update
  19263  * Description:
  19264  *      Attach i.e. Update Ingresss accounting table's statistics
  19265  * Parameters:
  19266  *      unit                  - (IN) unit number
  19267  *      pool_number           - (IN) Flex Pool Number for Accounting Object
  19268  *      base_idx              - (IN) Flex Base Index for Accounting Object
  19269  *      mode                  - (IN) Flex offset mode for Accounting Object
  19270  * Return Value:
  19271  *      BCM_E_NONE
  19272  * Notes:
  19273  */
  19274 bcm_error_t _bcm_esw_stat_flex_attach_ingress_table_counters_update(
  19275             int                  unit,
  19276             uint32               pool_number,
  19277             uint32               pipe_num,
  19278             uint32               base_idx,
  19279             bcm_stat_flex_mode_t mode)
  19280 {
  19281     int    pipe = 0, maxpipe = 1, unused_pool = 1;
  19282     int    total_counters = 0;
  19283     /* coverity :: 21245 */      
  19284     if (pool_number > 19) {
  19285         /* Return with no update */
  19286         return BCM_E_NONE;
  19287     }
  19288 
  19289     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  19290     flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress][pipe_num]
  19291                                    [pool_number][base_idx]++;
  19292 
  19293 #if defined(BCM_TOMAHAWK_SUPPORT)
  19294     if (BCM_TH_LOCAL_PIPE_MODE(unit, pool_number)) {
  19295         /* In this mode, counters must be collected independently for each pipe. */
  19296         maxpipe = NUM_PIPE(unit);
  19297     }
  19298 
  19299 #endif
  19300     unused_pool = 1;
  19301 
  19302     for(pipe = 0; pipe < maxpipe; ++pipe) {
  19303         if (flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe]
  19304                        [pool_number].attached_entries != 0) {
  19305             unused_pool = 0;
  19306             break;
  19307         }
  19308     }
  19309 
  19310     if (unused_pool) {
  19311         _bcm_esw_stat_flex_enable_pool(
  19312                unit,bcmStatFlexDirectionIngress,
  19313                _pool_ctr_register[bcmStatFlexDirectionIngress][pool_number],1);
  19314     } 
  19315 
  19316 #if defined(BCM_TOMAHAWK_SUPPORT)
  19317     if ((mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  19318         (mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  19319         total_counters = flex_custom_ingress_modes[unit][mode - BCM_CUSTOM_INGRESS_MODE_START].
  19320                                                 total_counters;
  19321     } else {
  19322 #endif
  19323         total_counters = flex_ingress_modes[unit][mode].total_counters;
  19324 #if defined(BCM_TOMAHAWK_SUPPORT)
  19325     }
  19326 #endif
  19327 
  19328     flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num][pool_number].
  19329                        attached_entries += total_counters;
  19330     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  19331 
  19332     return BCM_E_NONE;
  19333 }
  19334 /*
  19335  * Function:
  19336  *      _bcm_esw_stat_flex_detach_ingress_table_counters_update
  19337  * Description:
  19338  *      Manage flex reference count, clear counter values in the hardware
  19339  *      and disable flex pool for the stat applicable
  19340  * Parameters:
  19341  *      unit                  - (IN) unit number
  19342  *      pool_number           - (IN) Flex Pool Number for Accounting Object
  19343  *      base_idx              - (IN) Flex Base Index for Accounting Object
  19344  *      mode                  - (IN) Flex offset mode for Accounting Object
  19345  * Return Value:
  19346  *      BCM_E_NONE
  19347  * Notes:
  19348  */
  19349 bcm_error_t _bcm_esw_stat_flex_detach_ingress_table_counters_update(
  19350             int                  unit,
  19351             uint32               pool_number,
  19352             uint32               base_idx,
  19353             bcm_stat_flex_mode_t mode)
  19354 {
  19355     uint32                          flex_entries=0;
  19356     uint32                          alloc_size=0;
  19357     bcm_stat_flex_ctr_offset_info_t flex_ctr_offset_info={0};
  19358     bcm_stat_flex_counter_value_t   *flex_counter_value=NULL;
  19359     int pipe_num = 0;
  19360     int                             pipe = 0, maxpipe = 1, unused_pool;
  19361     int total_counters = 0;
  19362     /* coverity :: 21246 */
  19363     if (pool_number > 15) {
  19364         /* Return with no update */
  19365         return BCM_E_NONE;
  19366     }
  19367 
  19368 #if defined(BCM_TOMAHAWK_SUPPORT)
  19369     if ((mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  19370         (mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  19371         total_counters = flex_custom_ingress_modes[unit][mode - BCM_CUSTOM_INGRESS_MODE_START].
  19372                                                 total_counters;
  19373     } else {
  19374 #endif
  19375         total_counters = flex_ingress_modes[unit][mode].total_counters;
  19376 #if defined(BCM_TOMAHAWK_SUPPORT)
  19377     }
  19378 #endif
  19379 
  19380 #if defined (BCM_TOMAHAWK_SUPPORT)
  19381          if ((FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE ==                 
  19382                            flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  19383                                          [0][pool_number].used_by_tables)) {
  19384              _bcm_esw_get_fp_pipe_from_mode(unit, mode, 
  19385                          bcmFieldQualifyStageIngress, &pipe_num);
  19386          } else if ((FLEX_COUNTER_POOL_USED_BY_VFP_POLICY_TABLE ==                 
  19387                            flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  19388                                          [0][pool_number].used_by_tables)) {
  19389              _bcm_esw_get_fp_pipe_from_mode(unit, mode, 
  19390                          bcmFieldQualifyStageLookup, &pipe_num);
  19391          }
  19392 
  19393 #endif
  19394     /* Decrement reference count */
  19395     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  19396     flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress]
  19397                                        [pipe_num][pool_number][base_idx]--;
  19398     flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num][pool_number].
  19399                        attached_entries -= total_counters;
  19400     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  19401 
  19402     /* Clear Counter Values */
  19403     if ((flex_base_index_reference_count[unit]
  19404             [bcmStatFlexDirectionIngress] [pipe_num][pool_number][base_idx]) == 0 ) {
  19405 
  19406         LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  19407                   (BSL_META_U(unit,
  19408                               "Clearing Counter Tables for EXT_FP_POLICY: Offset:%d "
  19409                                "Len:%d\n"),
  19410                    base_idx,
  19411                    total_counters));
  19412 
  19413         flex_ctr_offset_info.all_counters_flag =  1;
  19414         alloc_size = sizeof(bcm_stat_flex_counter_value_t) *
  19415                       total_counters;
  19416 
  19417         flex_counter_value = sal_alloc(alloc_size,"counter-table-values");
  19418         if (flex_counter_value == NULL) {
  19419             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19420                       (BSL_META_U(unit,
  19421                                   "Failed: AllocateCounterMemoryForTable:EXT_FP_POLICY: "
  19422                                    "pool_number:%d mode:%d base_idx:%d\n"),
  19423                        pool_number, mode, base_idx));
  19424             return BCM_E_INTERNAL;
  19425         }
  19426 
  19427         sal_memset(flex_counter_value,0,alloc_size);
  19428         _bcm_esw_ext_stat_flex_set(unit, pool_number, base_idx, mode,
  19429                                    EXT_FP_POLICYm, 1, flex_ctr_offset_info,
  19430                                    &flex_entries, flex_counter_value);
  19431         _bcm_esw_ext_stat_flex_set(unit, pool_number, base_idx,mode,
  19432                                    EXT_FP_POLICYm, 0, flex_ctr_offset_info,
  19433                                    &flex_entries, flex_counter_value);
  19434         sal_free(flex_counter_value);
  19435     }
  19436 
  19437 #if defined (BCM_TOMAHAWK_SUPPORT)
  19438     if (BCM_TH_LOCAL_PIPE_MODE(unit, pool_number)) {
  19439         /* In this mode, counters must be collected independently for each pipe. */
  19440         maxpipe = NUM_PIPE(unit);
  19441     }
  19442 
  19443 #endif
  19444     unused_pool = 1;
  19445 
  19446     for(pipe = 0; pipe < maxpipe; ++pipe) {
  19447         if (flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe][pool_number].
  19448                        attached_entries != 0) {
  19449             unused_pool = 0;
  19450             break;
  19451         }
  19452     }
  19453         
  19454     /* Disable flex pool for this stat on no flex entries */
  19455     if (unused_pool) {
  19456         _bcm_esw_stat_flex_enable_pool(
  19457                  unit,
  19458                  bcmStatFlexDirectionIngress,
  19459                  _pool_ctr_register[bcmStatFlexDirectionIngress][pool_number],
  19460                  0);
  19461     }
  19462     return BCM_E_NONE;
  19463 }
  19464 
  19465 /*
  19466  * Function:
  19467  *      _bcm_esw_stat_flex_attach_ingress_table_counters2
  19468  * Description:
  19469  *      Atach i.e. Enable Ingresss accounting table's statistics
  19470  * Parameters:
  19471  *      unit                  - (IN) unit number
  19472  *      ingress_table         - (IN) Flex Accounting Table
  19473  *      index                 - (IN) Flex Accounting Table's Index
  19474  *      mode                  - (IN) Flex offset mode for Accounting Object
  19475  *      base_idx              - (IN) Flex Base Index for Accounting Object
  19476  *      pool_number           - (IN) Flex Pool Number for Accounting Object
  19477  *      ingress_entry_data1   - (IN) Entry Data(Null or Valid)
  19478  *                                   Null, table will be modified
  19479  *                                   NON-Null, table won't be modified
  19480  *
  19481  * Return Value:
  19482  *      BCM_E_XXX
  19483  * Notes:
  19484  *          ###############################################################
  19485  *          BE CAREFULL while using this routine(i.e. if possible don't use)
  19486  *          ###############################################################
  19487  *          Currently being used from field module to avoid two write operations
  19488  */
  19489 bcm_error_t _bcm_esw_stat_flex_attach_ingress_table_counters2(
  19490             int                  unit,
  19491             soc_mem_t            ingress_table,
  19492             uint32               index,
  19493             bcm_stat_flex_mode_t mode,
  19494             uint32               base_idx,
  19495             uint32               pool_number,
  19496             bcm_stat_object_t    object,
  19497             void                 *ingress_entry_data1)
  19498 {
  19499     uint32               ingress_entry_data_size=0;
  19500     void                 *ingress_entry_data=NULL;
  19501     void                 *ingress_entry_data_temp=NULL;
  19502     bcm_stat_flex_mode_t offset_mode_l={0};
  19503     uint32               stat_counter_id=0;
  19504     uint32               base_idx_l=0;
  19505     uint32               pool_number_l=0;
  19506     int                  pipe_num = 0;
  19507 #if defined (BCM_TOMAHAWK_SUPPORT)
  19508     int                  total_counters = 0;
  19509 #endif
  19510     uint32               cmode = mode;
  19511 
  19512 #if defined (BCM_TOMAHAWK_SUPPORT)
  19513     if ((mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  19514         (mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  19515         total_counters = flex_custom_ingress_modes[unit][mode - BCM_CUSTOM_INGRESS_MODE_START].
  19516                                                 total_counters;
  19517         mode = flex_custom_ingress_modes[unit][mode - BCM_CUSTOM_INGRESS_MODE_START].
  19518                                                 offset_mode;
  19519     } else {
  19520         total_counters = flex_ingress_modes[unit][mode].total_counters;
  19521     }
  19522 #endif
  19523 
  19524     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  19525         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19526                   (BSL_META_U(unit,
  19527                               "Invalid flex counter mode value %d \n"),
  19528                    mode));
  19529         return BCM_E_PARAM;
  19530     }
  19531     if (flex_ingress_modes[unit][mode].available==0) {
  19532         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19533                   (BSL_META_U(unit,
  19534                               "flex counter mode %d not configured yet\n"),
  19535                    mode));
  19536         return BCM_E_NOT_FOUND;
  19537     }
  19538 
  19539 #if defined (BCM_TOMAHAWK_SUPPORT)
  19540     pipe_num = _bcm_esw_get_fp_pipe_num(unit, ingress_table);
  19541 #endif
  19542 
  19543     if (shr_aidxres_list_elem_state(
  19544             flex_aidxres_list_handle[unit][bcmStatFlexDirectionIngress]
  19545             [pipe_num][pool_number],
  19546             base_idx) != BCM_E_EXISTS) {
  19547         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19548                   (BSL_META_U(unit,
  19549                               "Wrong base index %u \n"),
  19550                    base_idx));
  19551         return BCM_E_NOT_FOUND;
  19552     }
  19553 
  19554 #if defined (BCM_TOMAHAWK_SUPPORT)
  19555     if (!_bcm_esw_is_exact_match(ingress_table)) {
  19556 #endif
  19557         /* No HW setup for EXACT match */
  19558         ingress_entry_data_size = WORDS2BYTES(BYTES2WORDS(
  19559                                   SOC_MEM_INFO(unit, ingress_table).bytes));
  19560         if (ingress_entry_data1  == NULL ) {
  19561             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  19562                       (BSL_META_U(unit,
  19563                                   ".Attaching INGRESS counter for Table:%s with index:%d"
  19564                                    "mode:%d ENTRY_BYTES %d \n"),
  19565                        SOC_MEM_UFNAME(unit,ingress_table),index,mode,
  19566                        ingress_entry_data_size));
  19567             ingress_entry_data = sal_alloc(ingress_entry_data_size,"ingress_table");
  19568             if (ingress_entry_data == NULL) {
  19569                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19570                           (BSL_META_U(unit,
  19571                                       "Failed to allocate memory for Table:%s "),
  19572                            SOC_MEM_UFNAME(unit, ingress_table)));
  19573                 return BCM_E_INTERNAL;
  19574             }
  19575             sal_memset(ingress_entry_data,0,
  19576                        SOC_MEM_INFO(unit, ingress_table).bytes);
  19577             if (soc_mem_read(unit, ingress_table, MEM_BLOCK_ANY,
  19578                              _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  19579                              ingress_entry_data) != SOC_E_NONE) {
  19580                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19581                           (BSL_META_U(unit,
  19582                                       "Read failure for Table %s with index %d \n"),
  19583                            SOC_MEM_UFNAME(unit, ingress_table),index));
  19584                 sal_free(ingress_entry_data);
  19585                 return    BCM_E_INTERNAL;
  19586             }
  19587             ingress_entry_data_temp = ingress_entry_data;
  19588         } else {
  19589             ingress_entry_data_temp = ingress_entry_data1;
  19590         }
  19591         if (soc_mem_field_valid(unit,ingress_table,VALIDf)) {
  19592             if (soc_mem_field32_get(unit,ingress_table,ingress_entry_data_temp,
  19593                 VALIDf)==0) {
  19594                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19595                           (BSL_META_U(unit,
  19596                                       "Table %s  with index %d is Not valid \n"),
  19597                            SOC_MEM_UFNAME(unit, ingress_table),index));
  19598                 if (ingress_entry_data1 == NULL) {
  19599                     sal_free(ingress_entry_data);
  19600                 }
  19601                 return BCM_E_PARAM;
  19602             }
  19603         }
  19604         _bcm_esw_get_flex_counter_fields_values(
  19605                    unit,index,ingress_table,ingress_entry_data_temp, object,
  19606                    &offset_mode_l,&pool_number_l,&base_idx_l);
  19607         if (base_idx_l != 0) {
  19608             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19609                       (BSL_META_U(unit,
  19610                                   "Table:%s Has already allocated with index:%d"
  19611                                    "base %d mode %d."
  19612                                    "First dealloc it \n"), SOC_MEM_UFNAME(unit, ingress_table),
  19613                        index,base_idx_l,offset_mode_l));
  19614             if (ingress_entry_data1 == NULL) {
  19615                 sal_free(ingress_entry_data);
  19616             }
  19617             return BCM_E_EXISTS;/*Either NotConfigured or deallocated before */
  19618         }
  19619         _bcm_esw_set_flex_counter_fields_values(
  19620              unit,index,ingress_table,ingress_entry_data_temp,
  19621              object,mode,pool_number,base_idx);
  19622 #if defined(BCM_TOMAHAWK_SUPPORT)
  19623         /* Appropriately program G_COUNT, Y_COUNT and R_COUNT fields based on
  19624          * ifp_color_map that has been setup
  19625          */
  19626         if (SOC_IS_TOMAHAWKX(unit) &&
  19627             ((0 == flex_ingress_modes[unit][mode].num_selectors) ||
  19628              ((flex_ingress_modes[unit][mode].num_selectors > 0) && 
  19629              (flex_ingress_modes[unit][mode].attr_selectors[0].attr 
  19630                        == bcmStatGroupModeAttrFieldIngressColor))) &&
  19631             ((IFP_POLICY_TABLEm == ingress_table) ||
  19632              (IFP_POLICY_TABLE_PIPE0m == ingress_table) ||
  19633              (IFP_POLICY_TABLE_PIPE1m == ingress_table) ||
  19634              (IFP_POLICY_TABLE_PIPE2m == ingress_table) ||
  19635              (IFP_POLICY_TABLE_PIPE3m == ingress_table) ||
  19636              (IFP_POLICY_TABLE_PIPE4m == ingress_table) ||
  19637              (IFP_POLICY_TABLE_PIPE5m == ingress_table) ||
  19638              (IFP_POLICY_TABLE_PIPE6m == ingress_table) ||
  19639              (IFP_POLICY_TABLE_PIPE7m == ingress_table))) {
  19640             int ctr_idx, color_mask;
  19641             uint32 g_count = 0, y_count = 0, r_count = 0;
  19642             uint8 color_map_mask[BCM_MAX_IFP_COLORS] = {BCM_STAT_FLEX_COLOR_GREEN,
  19643                                                         BCM_STAT_FLEX_COLOR_YELLOW,
  19644                                                         BCM_STAT_FLEX_COLOR_RED};
  19645 
  19646             for (ctr_idx = 0;
  19647                  ctr_idx < total_counters;
  19648                  ctr_idx++) {
  19649                 if (0 != ifp_color_map[unit][pipe_num][pool_number][base_idx + ctr_idx]) {
  19650                     for (color_mask = 0; color_mask < BCM_MAX_IFP_COLORS; color_mask++) {
  19651                         switch (ifp_color_map[unit][pipe_num][pool_number][base_idx + ctr_idx]
  19652                                 & color_map_mask[color_mask]) {
  19653                             /* Checking arguments once again here, although this
  19654                              * should be checked while setting up color map
  19655                              */
  19656                             case BCM_STAT_FLEX_COLOR_GREEN:
  19657                                 if (0 == g_count) {
  19658                                     g_count = ctr_idx + 1;
  19659                                 } else {
  19660                                     if (ingress_entry_data1 == NULL) {
  19661                                         sal_free(ingress_entry_data);
  19662                                     }
  19663                                     /* Color green used more than once. */
  19664                                     return BCM_E_PARAM;
  19665                                 }
  19666                                 continue;
  19667                             case BCM_STAT_FLEX_COLOR_YELLOW:
  19668                                 if (0 == y_count) {
  19669                                     y_count = ctr_idx + 1;
  19670                                 } else {
  19671                                     if (ingress_entry_data1 == NULL) {
  19672                                         sal_free(ingress_entry_data);
  19673                                     }
  19674                                     /* Color yellow used more than once. */
  19675                                     return BCM_E_PARAM;
  19676                                 }
  19677                                 continue;
  19678                             case BCM_STAT_FLEX_COLOR_RED:
  19679                                 if (0 == r_count) {
  19680                                     r_count = ctr_idx + 1;
  19681                                 } else {
  19682                                     if (ingress_entry_data1 == NULL) {
  19683                                         sal_free(ingress_entry_data);
  19684                                     }
  19685                                     /* Color red used more than once. */
  19686                                     return BCM_E_PARAM;
  19687                                 }
  19688                                 continue;
  19689                             default:
  19690                                 if (0 != (color_map_mask[color_mask] &
  19691                                     ifp_color_map[unit][pipe_num][pool_number]
  19692                                     [base_idx + ctr_idx])) {
  19693                                     if (ingress_entry_data1 == NULL) {
  19694                                         sal_free(ingress_entry_data);
  19695                                     }
  19696                                     return BCM_E_PARAM;
  19697                                 }
  19698                                 break;
  19699                         }
  19700                     }
  19701                 } else {
  19702                     if (ingress_entry_data1 == NULL) {
  19703                         sal_free(ingress_entry_data);
  19704                     }
  19705                     /* IFP color map not setup correctly */
  19706                     return BCM_E_INTERNAL;
  19707                 }
  19708             }
  19709             if ((0 == g_count) && (0 == y_count) && (0 == r_count)) {
  19710                 /* IFP color map not setup correctly */
  19711                 if (ingress_entry_data1 == NULL) {
  19712                     sal_free(ingress_entry_data);
  19713                 }
  19714                 return BCM_E_INTERNAL;
  19715             }
  19716             /* Program g_count, y_count and r_count fields appropriately */
  19717             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data_temp,
  19718                                             G_COUNTf, &g_count);
  19719             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data_temp,
  19720                                             Y_COUNTf, &y_count);
  19721             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data_temp,
  19722                                             R_COUNTf, &r_count);
  19723         }
  19724 #endif
  19725         if (ingress_entry_data1 == NULL) {
  19726             if (soc_mem_write(unit, ingress_table, MEM_BLOCK_ALL,
  19727                               _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  19728                               ingress_entry_data_temp) != SOC_E_NONE) {
  19729                 sal_free(ingress_entry_data);
  19730                 return    BCM_E_INTERNAL;
  19731             }
  19732         }
  19733         if (ingress_entry_data1 == NULL) {
  19734             sal_free(ingress_entry_data);
  19735         }
  19736 #if defined (BCM_TOMAHAWK_SUPPORT)
  19737     }
  19738 #endif
  19739 
  19740 #if defined (BCM_TOMAHAWK_SUPPORT)
  19741     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  19742        (cmode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  19743         (cmode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  19744         bcm_error_t rv = BCM_E_CONFIG;
  19745  
  19746         rv = _bcm_esw_custom_stat_group_id_retrieve(unit, cmode, pipe_num, 
  19747                                pool_number, base_idx, &stat_counter_id);
  19748         if (rv !=BCM_E_NONE) {
  19749             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19750                   (BSL_META_U(unit,
  19751                               "Invalid mode value %d %d %d\n"),
  19752                    cmode, pool_number, base_idx));
  19753         }
  19754     } else
  19755 #endif
  19756     {
  19757     _bcm_esw_stat_get_counter_id(
  19758                   unit, flex_ingress_modes[unit][mode].group_mode,
  19759                   object,mode,pool_number,base_idx,&stat_counter_id);
  19760     }
  19761 
  19762     if (flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress][pipe_num]
  19763                                        [pool_number][base_idx] == 0) {
  19764         if (_bcm_esw_stat_flex_delete_stat_id(unit,
  19765             local_scache_ptr[unit],stat_counter_id) != BCM_E_NONE) {
  19766             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  19767                      (BSL_META_U(unit,
  19768                                  "WARMBOOT:Couldnot Delete entry in scache memory\n")));
  19769         }
  19770     }
  19771 
  19772     if (_bcm_esw_stat_flex_attach_ingress_table_counters_update(
  19773         unit, pool_number, pipe_num, base_idx, cmode) != BCM_E_NONE) {
  19774         return BCM_E_INTERNAL;
  19775     }
  19776 
  19777     return BCM_E_NONE;
  19778 }
  19779 /*
  19780  * Function:
  19781  *      _bcm_esw_stat_flex_attach_ingress_table_counters1
  19782  * Description:
  19783  *      Atach i.e. Enable Ingresss accounting table's statistics
  19784  * Parameters:
  19785  *      unit                  - (IN) unit number
  19786  *      ingress_table         - (IN) Flex Accounting Table
  19787  *      index                 - (IN) Flex Accounting Table's Index
  19788  *      mode                  - (IN) Flex offset mode for Accounting Object
  19789  *      base_idx              - (IN) Flex Base Index for Accounting Object
  19790  *      pool_number           - (IN) Flex Pool Number for Accounting Object
  19791  *      ingress_entry_data1   - (IN) Entry Data(Null or Valid)
  19792  *                                   Null, table will be modified
  19793  *                                   NON-Null, table won't be modified
  19794  *
  19795  * Return Value:
  19796  *      BCM_E_XXX
  19797  * Notes:
  19798  *          ###############################################################
  19799  *          BE CAREFULL while using this routine(i.e. if possible don't use)
  19800  *          ###############################################################
  19801  *          Currently being used from field module to avoid two write operations
  19802  */
  19803 bcm_error_t _bcm_esw_stat_flex_attach_ingress_table_counters1(
  19804             int                  unit,
  19805             soc_mem_t            ingress_table,
  19806             uint32               index,
  19807             bcm_stat_flex_mode_t mode,
  19808             uint32               base_idx,
  19809             uint32               pool_number,
  19810             void                 *ingress_entry_data1)
  19811 {
  19812     uint32               ingress_entry_data_size=0;
  19813     void                 *ingress_entry_data=NULL;
  19814     void                 *ingress_entry_data_temp=NULL;
  19815     bcm_stat_flex_mode_t offset_mode_l={0};
  19816     bcm_stat_object_t    object=bcmStatObjectIngPort;
  19817     uint32               stat_counter_id=0;
  19818     uint32               base_idx_l=0;
  19819     uint32               pool_number_l=0;
  19820     int                  pipe_num = 0;
  19821 #if defined (BCM_TOMAHAWK_SUPPORT)
  19822     int                  total_counters = 0;
  19823 #endif
  19824     uint32               cmode = mode;
  19825 #if defined(BCM_TRIDENT3_SUPPORT)
  19826     soc_flow_db_mem_view_info_t mem_view_info;
  19827     uint32 is_view = 0;
  19828 #endif
  19829     uint32 width = 0;
  19830     soc_mem_t ingress_view_table = ingress_table; /* memory view or memory */
  19831 
  19832 #if defined(BCM_TRIDENT3_SUPPORT)
  19833     if ((soc_feature(unit,soc_feature_flex_flow)) &&
  19834         (soc_flow_db_mem_view_is_valid(unit, ingress_table))) {
  19835         /* when ingress_table is view_id perform below else
  19836          */
  19837         BCM_IF_ERROR_RETURN(soc_flow_db_mem_view_info_get(unit, ingress_table,
  19838                                       &mem_view_info));
  19839         is_view = 1;
  19840         ingress_table = mem_view_info.mem;
  19841         width = BITS2BYTES(mem_view_info.width);
  19842         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  19843                     (BSL_META_U(unit,
  19844                     "View ID %d mem_id %d\n"),
  19845                      ingress_view_table, ingress_table));
  19846 
  19847     } else
  19848 #endif  /* BCM_TRIDENT3_SUPPORT */
  19849     {
  19850         if (!soc_mem_is_valid(unit, ingress_table)) {
  19851             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19852                       (BSL_META_U(unit,
  19853                                   "Invalid mem %d\n"), ingress_table));
  19854             return BCM_E_INTERNAL;
  19855         }
  19856 
  19857         width =  SOC_MEM_INFO(unit, ingress_table).bytes;
  19858     }
  19859 
  19860 #if defined (BCM_TOMAHAWK_SUPPORT)
  19861     if ((mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  19862         (mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  19863         total_counters = flex_custom_ingress_modes[unit][mode - BCM_CUSTOM_INGRESS_MODE_START].
  19864                                                 total_counters;
  19865         mode = flex_custom_ingress_modes[unit][mode - BCM_CUSTOM_INGRESS_MODE_START].
  19866                                                 offset_mode;
  19867     } else {
  19868         total_counters = flex_ingress_modes[unit][mode].total_counters;
  19869     }
  19870 #endif
  19871 
  19872     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  19873         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19874                   (BSL_META_U(unit,
  19875                               "Invalid flex counter mode value %d \n"),
  19876                    mode));
  19877         return BCM_E_PARAM;
  19878     }
  19879     if (flex_ingress_modes[unit][mode].available==0) {
  19880         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19881                   (BSL_META_U(unit,
  19882                               "flex counter mode %d not configured yet\n"),
  19883                    mode));
  19884         return BCM_E_NOT_FOUND;
  19885     }
  19886 
  19887 #if defined (BCM_TOMAHAWK_SUPPORT)
  19888     pipe_num = _bcm_esw_get_fp_pipe_num(unit, ingress_table);
  19889 #endif
  19890 
  19891     if (shr_aidxres_list_elem_state(
  19892             flex_aidxres_list_handle[unit][bcmStatFlexDirectionIngress]
  19893             [pipe_num][pool_number],
  19894             base_idx) != BCM_E_EXISTS) {
  19895         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19896                   (BSL_META_U(unit,
  19897                               "Wrong base index %u \n"),
  19898                    base_idx));
  19899         return BCM_E_NOT_FOUND;
  19900     }
  19901 
  19902 #if defined (BCM_TOMAHAWK_SUPPORT)
  19903     if (!(_bcm_esw_is_exact_match(ingress_table)
  19904         || (SOC_IS_TRIDENT3X(unit) && _bcm_esw_is_ifp_table(ingress_table)))) {
  19905 #endif
  19906         /* No HW setup for EXACT match */
  19907         ingress_entry_data_size = WORDS2BYTES(BYTES2WORDS(width));
  19908         if (ingress_entry_data1  == NULL ) {
  19909             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  19910                       (BSL_META_U(unit,
  19911                                   ".Attaching INGRESS counter for Table:%s with index:%d"
  19912                                    "mode:%d ENTRY_BYTES %d \n"),
  19913                        SOC_MEM_UFNAME(unit,ingress_table),index,mode,
  19914                        ingress_entry_data_size));
  19915             ingress_entry_data = sal_alloc(ingress_entry_data_size,"ingress_table");
  19916             if (ingress_entry_data == NULL) {
  19917                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19918                           (BSL_META_U(unit,
  19919                                       "Failed to allocate memory for Table:%s "),
  19920                            SOC_MEM_UFNAME(unit, ingress_table)));
  19921                 return BCM_E_INTERNAL;
  19922             }
  19923             sal_memset(ingress_entry_data, 0, width);
  19924             if (soc_mem_read(unit, ingress_view_table, MEM_BLOCK_ANY,
  19925                              _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  19926                              ingress_entry_data) != SOC_E_NONE) {
  19927                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19928                           (BSL_META_U(unit,
  19929                                       "Read failure for Table %s with index %d \n"),
  19930                            SOC_MEM_UFNAME(unit, ingress_table),index));
  19931                 sal_free(ingress_entry_data);
  19932                 return    BCM_E_INTERNAL;
  19933             }
  19934             ingress_entry_data_temp = ingress_entry_data;
  19935         } else {
  19936             ingress_entry_data_temp = ingress_entry_data1;
  19937         }
  19938 #if defined(BCM_TRIDENT3_SUPPORT)
  19939         if(is_view) {
  19940             if (soc_flow_db_mem_view_entry_is_valid(unit,
  19941                                         ingress_view_table,
  19942                                         ingress_entry_data_temp) == FALSE) {
  19943                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19944                            (BSL_META_U(unit,
  19945                                        "Table %s  with index %d is Not valid \n"),
  19946                            SOC_MEM_UFNAME(unit, ingress_table),index));
  19947                 if (ingress_entry_data1 == NULL) {
  19948                     sal_free(ingress_entry_data);
  19949                 }
  19950                 return BCM_E_PARAM;
  19951             }
  19952         } else
  19953 #endif
  19954         {
  19955         if (soc_mem_field_valid(unit,ingress_table,VALIDf)) {
  19956             if (soc_mem_field32_get(unit,ingress_table,ingress_entry_data_temp,
  19957                 VALIDf)==0) {
  19958                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19959                           (BSL_META_U(unit,
  19960                                       "Table %s  with index %d is Not valid \n"),
  19961                            SOC_MEM_UFNAME(unit, ingress_table),index));
  19962                 if (ingress_entry_data1 == NULL) {
  19963                     sal_free(ingress_entry_data);
  19964                 }
  19965                 return BCM_E_PARAM;
  19966             }
  19967         }
  19968         }
  19969 
  19970         _bcm_esw_get_flex_counter_fields_values(
  19971                    unit,index,ingress_view_table,ingress_entry_data_temp,0,
  19972                    &offset_mode_l,&pool_number_l,&base_idx_l);
  19973         if (base_idx_l != 0) {
  19974             if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  19975                 /*
  19976                  * If counter movement is in progress allow the new base index
  19977                  * programming to continue counter collection without delay.
  19978                  * Decrement old base index refrence count and destroy old stat
  19979                  * counter id in bcmStatCustomBaseIdxMove.
  19980                  */
  19981                 if (compaction_info.base_idx != base_idx_l &&
  19982                         compaction_info.pool_number != pool_number_l &&
  19983                         compaction_info.in_progress == FALSE) {
  19984                     LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19985                             (BSL_META_U(unit,
  19986                                         "Table:%s Has already allocated with index:%d"
  19987                                         "base %d mode %d."
  19988                                         "First dealloc it \n"), SOC_MEM_UFNAME(unit, ingress_table),
  19989                              index,base_idx_l,offset_mode_l));
  19990                     if (ingress_entry_data1 == NULL) {
  19991                         sal_free(ingress_entry_data);
  19992                     }
  19993                     return BCM_E_EXISTS;/*Either NotConfigured or deallocated before */
  19994                 }
  19995             } else {
  19996                 LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  19997                         (BSL_META_U(unit,
  19998                                     "Table:%s Has already allocated with index:%d"
  19999                                     "base %d mode %d."
  20000                                     "First dealloc it \n"), SOC_MEM_UFNAME(unit, ingress_table),
  20001                          index,base_idx_l,offset_mode_l));
  20002                 if (ingress_entry_data1 == NULL) {
  20003                     sal_free(ingress_entry_data);
  20004                 }
  20005                 return BCM_E_EXISTS;/*Either NotConfigured or deallocated before */
  20006             }
  20007         }
  20008         _bcm_esw_set_flex_counter_fields_values(
  20009              unit,index,ingress_view_table,ingress_entry_data_temp,0,
  20010              mode,pool_number,base_idx);
  20011 #if defined(BCM_TOMAHAWK_SUPPORT)
  20012         /* Appropriately program G_COUNT, Y_COUNT and R_COUNT fields based on
  20013          * ifp_color_map that has been setup
  20014          */
  20015         if (SOC_IS_TOMAHAWKX(unit) &&
  20016             ((0 == flex_ingress_modes[unit][mode].num_selectors) ||
  20017              ((flex_ingress_modes[unit][mode].num_selectors > 0) && 
  20018              (flex_ingress_modes[unit][mode].attr_selectors[0].attr 
  20019                        == bcmStatGroupModeAttrFieldIngressColor))) &&
  20020             ((IFP_POLICY_TABLEm == ingress_table) ||
  20021              (IFP_POLICY_TABLE_PIPE0m == ingress_table) ||
  20022              (IFP_POLICY_TABLE_PIPE1m == ingress_table) ||
  20023              (IFP_POLICY_TABLE_PIPE2m == ingress_table) ||
  20024              (IFP_POLICY_TABLE_PIPE3m == ingress_table) ||
  20025              (IFP_POLICY_TABLE_PIPE4m == ingress_table) ||
  20026              (IFP_POLICY_TABLE_PIPE5m == ingress_table) ||
  20027              (IFP_POLICY_TABLE_PIPE6m == ingress_table) ||
  20028              (IFP_POLICY_TABLE_PIPE7m == ingress_table))) {
  20029             int ctr_idx, color_mask;
  20030             uint32 g_count = 0, y_count = 0, r_count = 0;
  20031             uint8 color_map_mask[BCM_MAX_IFP_COLORS] = {BCM_STAT_FLEX_COLOR_GREEN,
  20032                                                         BCM_STAT_FLEX_COLOR_YELLOW,
  20033                                                         BCM_STAT_FLEX_COLOR_RED};
  20034 
  20035             for (ctr_idx = 0;
  20036                  ctr_idx < total_counters;
  20037                  ctr_idx++) {
  20038                 if (0 != ifp_color_map[unit][pipe_num][pool_number][base_idx + ctr_idx]) {
  20039                     for (color_mask = 0; color_mask < BCM_MAX_IFP_COLORS; color_mask++) {
  20040                         switch (ifp_color_map[unit][pipe_num][pool_number][base_idx + ctr_idx]
  20041                                 & color_map_mask[color_mask]) {
  20042                             /* Checking arguments once again here, although this
  20043                              * should be checked while setting up color map
  20044                              */
  20045                             case BCM_STAT_FLEX_COLOR_GREEN:
  20046                                 if (0 == g_count) {
  20047                                     g_count = ctr_idx + 1;
  20048                                 } else {
  20049                                     if (ingress_entry_data1 == NULL) {
  20050                                         sal_free(ingress_entry_data);
  20051                                     }
  20052                                     /* Color green used more than once. */
  20053                                     return BCM_E_PARAM;
  20054                                 }
  20055                                 continue;
  20056                             case BCM_STAT_FLEX_COLOR_YELLOW:
  20057                                 if (0 == y_count) {
  20058                                     y_count = ctr_idx + 1;
  20059                                 } else {
  20060                                     if (ingress_entry_data1 == NULL) {
  20061                                         sal_free(ingress_entry_data);
  20062                                     }
  20063                                     /* Color yellow used more than once. */
  20064                                     return BCM_E_PARAM;
  20065                                 }
  20066                                 continue;
  20067                             case BCM_STAT_FLEX_COLOR_RED:
  20068                                 if (0 == r_count) {
  20069                                     r_count = ctr_idx + 1;
  20070                                 } else {
  20071                                     if (ingress_entry_data1 == NULL) {
  20072                                         sal_free(ingress_entry_data);
  20073                                     }
  20074                                     /* Color red used more than once. */
  20075                                     return BCM_E_PARAM;
  20076                                 }
  20077                                 continue;
  20078                             default:
  20079                                 if (0 != (color_map_mask[color_mask] &
  20080                                     ifp_color_map[unit][pipe_num][pool_number]
  20081                                     [base_idx + ctr_idx])) {
  20082                                     if (ingress_entry_data1 == NULL) {
  20083                                         sal_free(ingress_entry_data);
  20084                                     }
  20085                                     return BCM_E_PARAM;
  20086                                 }
  20087                                 break;
  20088                         }
  20089                     }
  20090                 } else {
  20091                     if (ingress_entry_data1 == NULL) {
  20092                         sal_free(ingress_entry_data);
  20093                     }
  20094                     /* IFP color map not setup correctly */
  20095                     return BCM_E_INTERNAL;
  20096                 }
  20097             }
  20098             if ((0 == g_count) && (0 == y_count) && (0 == r_count)) {
  20099                 /* IFP color map not setup correctly */
  20100                 if (ingress_entry_data1 == NULL) {
  20101                     sal_free(ingress_entry_data);
  20102                 }
  20103                 return BCM_E_INTERNAL;
  20104             }
  20105             /* Program g_count, y_count and r_count fields appropriately */
  20106             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data_temp,
  20107                                             G_COUNTf, &g_count);
  20108             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data_temp,
  20109                                             Y_COUNTf, &y_count);
  20110             soc_IFP_POLICY_TABLEm_field_set(unit, ingress_entry_data_temp,
  20111                                             R_COUNTf, &r_count);
  20112         }
  20113 #endif
  20114         if (ingress_entry_data1 == NULL) {
  20115             if (
  20116 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  20117                 (!_bcm_esw_stat_table_is_profile(unit, ingress_table)) &&
  20118 #endif
  20119                 soc_mem_write(unit, ingress_view_table, MEM_BLOCK_ALL,
  20120                               _bcm_esw_stat_flex_table_index_map(unit,ingress_table,index),
  20121                               ingress_entry_data_temp) != SOC_E_NONE) {
  20122                 sal_free(ingress_entry_data);
  20123                 return    BCM_E_INTERNAL;
  20124             }
  20125         }
  20126         if(_bcm_esw_stat_flex_get_ingress_object(
  20127            unit,ingress_view_table,index,ingress_entry_data_temp,&object) !=BCM_E_NONE) {
  20128            if (ingress_entry_data1 == NULL) {
  20129                sal_free(ingress_entry_data);
  20130            }
  20131            return BCM_E_INTERNAL;
  20132         }
  20133         if (ingress_entry_data1 == NULL) {
  20134             sal_free(ingress_entry_data);
  20135         }
  20136 #if defined (BCM_TOMAHAWK_SUPPORT)
  20137     }
  20138 #endif
  20139 
  20140 #if defined (BCM_TOMAHAWK_SUPPORT)
  20141     if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  20142        (cmode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  20143         (cmode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  20144         bcm_error_t rv = BCM_E_CONFIG;
  20145  
  20146         rv = _bcm_esw_custom_stat_group_id_retrieve(unit, cmode, pipe_num, 
  20147                                pool_number, base_idx, &stat_counter_id);
  20148         if (rv !=BCM_E_NONE) {
  20149             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  20150                   (BSL_META_U(unit,
  20151                               "Invalid mode value %d %d %d\n"),
  20152                    cmode, pool_number, base_idx));
  20153         }
  20154     } else
  20155 #endif
  20156     {
  20157     _bcm_esw_stat_get_counter_id(
  20158                   unit, flex_ingress_modes[unit][mode].group_mode,
  20159                   object,mode,pool_number,base_idx,&stat_counter_id);
  20160     }
  20161 
  20162     if (flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress][pipe_num]
  20163                                        [pool_number][base_idx] == 0) {
  20164         if (_bcm_esw_stat_flex_delete_stat_id(unit,
  20165             local_scache_ptr[unit],stat_counter_id) != BCM_E_NONE) {
  20166             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  20167                      (BSL_META_U(unit,
  20168                                  "WARMBOOT:Couldnot Delete entry in scache memory\n")));
  20169         }
  20170     }
  20171 
  20172     if (_bcm_esw_stat_flex_attach_ingress_table_counters_update(
  20173         unit, pool_number, pipe_num, base_idx, cmode) != BCM_E_NONE) {
  20174         return BCM_E_INTERNAL;
  20175     }
  20176 
  20177     return BCM_E_NONE;
  20178 }
  20179 /*
  20180  * Function:
  20181  *      _bcm_esw_stat_flex_attach_ingress_table_counters
  20182  * Description:
  20183  *      Atach i.e. Enable Ingresss accounting table's statistics
  20184  * Parameters:
  20185  *      unit                  - (IN) unit number
  20186  *      ingress_table         - (IN) Flex Accounting Table
  20187  *      index                 - (IN) Flex Accounting Table's Index
  20188  *      mode                  - (IN) Flex offset mode for Accounting Object
  20189  *      base_idx              - (IN) Flex Base Index for Accounting Object
  20190  *      pool_number           - (IN) Flex Pool Number for Accounting Object
  20191  *
  20192  * Return Value:
  20193  *      BCM_E_XXX
  20194  * Notes:
  20195  *      Calls _bcm_esw_stat_flex_attach_ingress_table_counters1() with
  20196  *      NULL as ingress_entry_data i.e. ingress table will be modified
  20197  */
  20198 bcm_error_t _bcm_esw_stat_flex_attach_ingress_table_counters(
  20199             int                  unit,
  20200             soc_mem_t            ingress_table,
  20201             uint32               index,
  20202             bcm_stat_flex_mode_t mode,
  20203             uint32               base_idx,
  20204             uint32               pool_number)
  20205 {
  20206    return _bcm_esw_stat_flex_attach_ingress_table_counters1(
  20207           unit, ingress_table, index, mode, base_idx, pool_number, NULL);
  20208 
  20209 }
  20210 
  20211 /*
  20212  * Function:
  20213  *      _bcm_esw_stat_flex_create_ingress_table_counters
  20214  * Description:
  20215  *      Create and Reserve Flex Counter Space for Ingresss accounting table
  20216  * Parameters:
  20217  *      unit                  - (IN) unit number
  20218  *      ingress_table         - (IN) Flex Accounting Table
  20219  *      mode                  - (IN) Flex offset mode for Accounting Object
  20220  *      base_idx              - (IN) Flex Base Index for Accounting Object
  20221  *      pool_number           - (IN) Flex Pool Number for Accounting Object
  20222  *
  20223  * Return Value:
  20224  *      BCM_E_XXX
  20225  * Notes:
  20226  */
  20227 bcm_error_t _bcm_esw_stat_flex_create_ingress_table_counters(
  20228             int                  unit,
  20229             soc_mem_t            ingress_table,
  20230             int                  lookup,
  20231             bcm_stat_object_t    object,
  20232             bcm_stat_flex_mode_t mode_id,
  20233             uint32               *base_idx,
  20234             uint32               *pool_number)
  20235 {
  20236     uint32            base_idx_l=0;
  20237     uint32            pool_number_l=0;
  20238     uint32            default_pool_number=0;
  20239     uint32            used_by_table=0;
  20240     uint32            used_by_table_selection_criteria=0;
  20241     uint32            free_count=0;
  20242     uint32            alloc_count=0;
  20243     uint32            largest_free=0;
  20244     uint32            stat_counter_id=0;
  20245     uint32            num_flex_ingress_pools=SOC_INFO(unit).
  20246                                                num_flex_ingress_pools;
  20247     int               pipe_num = 0;
  20248     uint32            used_by_flag = 0;
  20249     int               total_counters = 0;
  20250     flex_object_config_t object_config = {0};
  20251     bcm_field_qualify_t field_stage = 0; 
  20252     /* Used to indicate if counter allocation for IFP
  20253      * should be carried out from a specific pool
  20254      */
  20255 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
  20256     uint32            allocate_from_specific_pool = 0;
  20257 #endif
  20258 
  20259 #if defined(BCM_TOMAHAWK_SUPPORT)
  20260     int            pool = 0;
  20261 #endif
  20262     uint32            mode = mode_id;                 
  20263     uint32            allocate_group_type = BCM_FLEX_POOL_GROUP_USED_BY_NONE;
  20264     uint32            pool_group_id = 0;
  20265     uint32            pool_group_type;                
  20266     uint32            oam_mode = 0;
  20267                                                       
  20268 #if defined(BCM_TOMAHAWK_SUPPORT)
  20269        if ((SOC_IS_TOMAHAWKX(unit) ||SOC_IS_TRIDENT3X(unit)) &&
  20270                    (ingress_table != IFP_POLICY_TABLEm) && 
  20271                    (ingress_table != IFP_POLICY_TABLE_PIPE0m) && 
  20272                    (ingress_table != IFP_POLICY_TABLE_PIPE1m) && 
  20273                    (ingress_table != IFP_POLICY_TABLE_PIPE2m) && 
  20274                    (ingress_table != IFP_POLICY_TABLE_PIPE3m) &&
  20275                    (ingress_table != IFP_POLICY_TABLE_PIPE4m) &&
  20276                    (ingress_table != IFP_POLICY_TABLE_PIPE5m) &&
  20277                    (ingress_table != IFP_POLICY_TABLE_PIPE6m) &&
  20278                    (ingress_table != IFP_POLICY_TABLE_PIPE7m)) {
  20279            num_flex_ingress_pools -= 8; /* Last 8 are for IFP use only */
  20280        }
  20281 #endif
  20282 
  20283     if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
  20284         if (BCM_STAT_GROUP_MODE_ID_OAM_SUFFIX ==      
  20285             (mode_id & BCM_STAT_GROUP_MODE_ID_OAM_MASK)) {
  20286             mode = mode_id & ~(BCM_STAT_GROUP_MODE_ID_OAM_MASK);
  20287             oam_mode = 1;                             
  20288         }                                             
  20289     }
  20290  
  20291 #if defined (BCM_TOMAHAWK_SUPPORT)
  20292     if ((mode_id >= BCM_CUSTOM_INGRESS_MODE_START)  &&
  20293         (mode_id < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  20294         total_counters = flex_custom_ingress_modes[unit][mode_id - 
  20295                                  BCM_CUSTOM_INGRESS_MODE_START].total_counters;
  20296         mode = flex_custom_ingress_modes[unit][mode_id - 
  20297                                  BCM_CUSTOM_INGRESS_MODE_START].offset_mode;
  20298     } else {
  20299 #endif
  20300         total_counters = flex_ingress_modes[unit][mode].total_counters;
  20301 #if defined (BCM_TOMAHAWK_SUPPORT)
  20302     }
  20303 #endif
  20304 
  20305     if (mode > (BCM_STAT_FLEX_COUNTER_MAX_MODE-1)) {
  20306         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  20307                   (BSL_META_U(unit,
  20308                               "Invalid flex counter mode value %d \n"),
  20309                    mode));
  20310         return BCM_E_PARAM;
  20311     }
  20312     if (flex_ingress_modes[unit][mode].available==0) {
  20313         LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  20314                   (BSL_META_U(unit,
  20315                               "flex counter mode %d not configured yet\n"),
  20316                    mode));
  20317         return BCM_E_NOT_FOUND;
  20318     }
  20319 
  20320     /* Below case statement can be avoided by passing arguements for
  20321        pool_number and selection criteria But keeping it for better
  20322        understanding at same place */
  20323     switch(ingress_table) {
  20324         case PORT_TABm:
  20325 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  20326         case LPORT_TABm:
  20327 #endif
  20328              default_pool_number=pool_number_l=
  20329                      FLEX_COUNTER_DEFAULT_PORT_TABLE_POOL_NUMBER;
  20330              used_by_table_selection_criteria=used_by_table =
  20331                      FLEX_COUNTER_POOL_USED_BY_PORT_TABLE;
  20332              break;
  20333             /* VLAN and VFI shares same pool */
  20334         case VLAN_TABm:
  20335              default_pool_number=pool_number_l=
  20336                      FLEX_COUNTER_DEFAULT_VLAN_TABLE_POOL_NUMBER;
  20337              used_by_table = FLEX_COUNTER_POOL_USED_BY_VLAN_TABLE;
  20338              used_by_table_selection_criteria=
  20339                      (FLEX_COUNTER_POOL_USED_BY_VLAN_TABLE |
  20340                       FLEX_COUNTER_POOL_USED_BY_VFI_TABLE);
  20341              break;
  20342         case VFIm:
  20343              default_pool_number=pool_number_l=
  20344                      FLEX_COUNTER_DEFAULT_VFI_TABLE_POOL_NUMBER;
  20345              used_by_table = FLEX_COUNTER_POOL_USED_BY_VFI_TABLE;
  20346              used_by_table_selection_criteria=
  20347                      (FLEX_COUNTER_POOL_USED_BY_VLAN_TABLE |
  20348                       FLEX_COUNTER_POOL_USED_BY_VFI_TABLE );
  20349              break;
  20350             /* VRF and MPLS_VC_LABEL shares same pool */
  20351         case VRFm:
  20352 #if defined(BCM_TRIUMPH3_SUPPORT)
  20353         case VRF_ATTRS_2m:
  20354 #endif
  20355 #if defined(BCM_METROLITE_SUPPORT)
  20356              if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20357                  default_pool_number=pool_number_l=
  20358                      FLEX_COUNTER_ML_DEFAULT_VRF_TABLE_POOL_NUMBER;
  20359              } else
  20360 #endif
  20361              {
  20362              default_pool_number=pool_number_l=
  20363                      FLEX_COUNTER_DEFAULT_VRF_TABLE_POOL_NUMBER;
  20364              }
  20365              used_by_table = FLEX_COUNTER_POOL_USED_BY_VRF_TABLE;
  20366              used_by_table_selection_criteria=FLEX_COUNTER_POOL_USED_BY_VRF_TABLE;
  20367              break;
  20368 
  20369             /* VLAN_XLATE and MPLS_TABLE shares same pool */
  20370         case MPLS_ENTRYm:
  20371 #if defined(BCM_TRIUMPH3_SUPPORT)
  20372         case MPLS_ENTRY_EXTDm:
  20373 #endif
  20374 #if defined(BCM_TOMAHAWK3_SUPPORT)
  20375         case MPLS_ENTRY_SINGLEm:
  20376 #endif
  20377              if (lookup == 1) {
  20378                  default_pool_number=pool_number_l=
  20379                      FLEX_COUNTER_DEFAULT_MPLS_ENTRY_TABLE_POOL_NUMBER;
  20380                  used_by_table =
  20381                      FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE;
  20382                  if (oam_mode && soc_feature(unit,
  20383                      soc_feature_oam_split_counter_pools)) {
  20384                      used_by_table_selection_criteria =
  20385                          FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE;
  20386                  } else {
  20387                  used_by_table_selection_criteria=
  20388                      (FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE|
  20389                       FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE);
  20390                  }
  20391              } else if (lookup == 2) {
  20392 #if defined(BCM_APACHE_SUPPORT)
  20393                  if (soc_feature(unit,
  20394                          soc_feature_mpls_entry_second_label_lookup)) {
  20395                      default_pool_number=pool_number_l=
  20396                          FLEX_COUNTER_DEFAULT_MPLS_ENTRY_SCND_LKUP_TABLE_POOL_NUMBER;
  20397                      used_by_table =
  20398                          FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE_FOR_SCND_LKUP;
  20399                      used_by_table_selection_criteria=
  20400                          (FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE_FOR_SCND_LKUP|
  20401                           FLEX_COUNTER_POOL_USED_BY_L3_IIF_TABLE|
  20402                           FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE);
  20403                  }
  20404 #endif
  20405              }
  20406              break;
  20407         case VLAN_XLATEm:
  20408 #if defined(BCM_TRIUMPH3_SUPPORT)
  20409         case VLAN_XLATE_EXTDm:
  20410 #endif
  20411 #if defined (BCM_TRIDENT3_SUPPORT)
  20412                  case VLAN_XLATE_1_DOUBLEm:
  20413                  case VLAN_XLATE_2_DOUBLEm:
  20414 #endif
  20415              if (lookup == 1) {
  20416                  default_pool_number=pool_number_l=
  20417                      FLEX_COUNTER_DEFAULT_VLAN_XLATE_TABLE_POOL_NUMBER;
  20418                  used_by_table = FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE;
  20419                  if (oam_mode && soc_feature(unit,
  20420                      soc_feature_oam_split_counter_pools)) {
  20421                      used_by_table_selection_criteria =
  20422                          FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE;
  20423                  } else {
  20424                  used_by_table_selection_criteria=
  20425                      (FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE|
  20426                       FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE);
  20427                  }
  20428              } else if (lookup == 2) {
  20429 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  20430                  if (soc_feature(unit,soc_feature_ing_vlan_xlate_second_lookup)) {
  20431                      default_pool_number=pool_number_l=
  20432                      FLEX_COUNTER_DEFAULT_VLAN_XLATE_SCND_LKUP_TABLE_POOL_NUMBER;
  20433                      used_by_table =
  20434                          FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE_FOR_SCND_LKUP;
  20435                      used_by_table_selection_criteria=
  20436                          (FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE_FOR_SCND_LKUP|
  20437                           FLEX_COUNTER_POOL_USED_BY_VRF_TABLE);
  20438                  }
  20439 #endif
  20440              }
  20441              break;
  20442             /* L3_IIF and SOURCE_VP shares same pool*/
  20443         case L3_IIFm:
  20444 #if defined(BCM_METROLITE_SUPPORT)
  20445              if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20446                  default_pool_number=pool_number_l=
  20447                      FLEX_COUNTER_ML_DEFAULT_L3_IIF_TABLE_POOL_NUMBER;
  20448              } else
  20449 #endif
  20450              {
  20451              default_pool_number=pool_number_l=
  20452                      FLEX_COUNTER_DEFAULT_L3_IIF_TABLE_POOL_NUMBER;
  20453              }
  20454              /* Time being keeping separate default pool for l3_iif and source_vp */
  20455              used_by_table = FLEX_COUNTER_POOL_USED_BY_L3_IIF_TABLE;
  20456              /* But IfRequired L3_IIF & SOURCE_VP counters can be shared in
  20457                 same pool*/
  20458              used_by_table_selection_criteria=
  20459                      FLEX_COUNTER_POOL_USED_BY_L3_IIF_TABLE |
  20460                      FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE ;
  20461              break;
  20462         case L3_TUNNELm:
  20463 #if defined(BCM_METROLITE_SUPPORT)
  20464              if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20465                   default_pool_number=pool_number_l=
  20466                       FLEX_COUNTER_ML_DEFAULT_L3_TUNNEL_TABLE_POOL_NUMBER;
  20467              } else
  20468 #endif
  20469              {
  20470              default_pool_number=pool_number_l=
  20471                      FLEX_COUNTER_DEFAULT_L3_TUNNEL_TABLE_POOL_NUMBER;
  20472              }
  20473              used_by_table = FLEX_COUNTER_POOL_USED_BY_L3_TUNNEL_TABLE;
  20474              used_by_table_selection_criteria=
  20475                      FLEX_COUNTER_POOL_USED_BY_L3_TUNNEL_TABLE;
  20476              break;
  20477         case L3_ENTRY_2m:
  20478         case L3_ENTRY_4m:
  20479         case EXT_IPV4_UCAST_WIDEm:
  20480         case EXT_IPV6_128_UCAST_WIDEm:
  20481 #if defined(BCM_METROLITE_SUPPORT)
  20482              if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20483                  default_pool_number=pool_number_l=
  20484                      FLEX_COUNTER_ML_DEFAULT_L3_ENTRY_TABLE_POOL_NUMBER;
  20485              } else
  20486 #endif
  20487              {
  20488              default_pool_number=pool_number_l=
  20489                      FLEX_COUNTER_DEFAULT_L3_ENTRY_TABLE_POOL_NUMBER;
  20490              }
  20491              used_by_table = FLEX_COUNTER_POOL_USED_BY_L3_ENTRY_TABLE;
  20492              used_by_table_selection_criteria=
  20493                      FLEX_COUNTER_POOL_USED_BY_L3_ENTRY_TABLE;
  20494              break;
  20495 #if defined(BCM_TRIDENT2_SUPPORT)
  20496         case L3_DEFIPm:
  20497         case L3_DEFIP_PAIR_128m:
  20498         case L3_DEFIP_ALPM_RAWm:
  20499         case L3_DEFIP_ALPM_IPV4_1m:
  20500         case L3_DEFIP_ALPM_IPV6_64_1m:
  20501         case L3_DEFIP_ALPM_IPV6_128m:
  20502         case L3_DEFIP_LEVEL1m:
  20503         case L3_DEFIP_PAIR_LEVEL1m:
  20504         case L3_DEFIP_ALPM_LEVEL2m:
  20505         case L3_DEFIP_ALPM_LEVEL3m:
  20506 #if defined(BCM_METROLITE_SUPPORT)
  20507              if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20508                  default_pool_number=pool_number_l=
  20509                      FLEX_COUNTER_ML_DEFAULT_L3_ROUTE_TABLE_POOL_NUMBER;
  20510              } else
  20511 #endif
  20512              {
  20513              default_pool_number=pool_number_l=
  20514                      FLEX_COUNTER_DEFAULT_L3_ROUTE_TABLE_POOL_NUMBER;
  20515              }
  20516              used_by_table = FLEX_COUNTER_POOL_USED_BY_L3_ROUTE_TABLE;
  20517              used_by_table_selection_criteria=
  20518                      FLEX_COUNTER_POOL_USED_BY_L3_ROUTE_TABLE;
  20519              break;
  20520         case L3_ENTRY_IPV4_MULTICASTm:
  20521         case L3_ENTRY_IPV6_MULTICASTm:
  20522 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  20523         case L3_ENTRY_QUADm:
  20524         case L3_ENTRY_DOUBLEm:
  20525 #endif
  20526 #if defined(BCM_METROLITE_SUPPORT)
  20527              if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20528                  default_pool_number=pool_number_l=
  20529                      FLEX_COUNTER_ML_DEFAULT_FCOE_TABLE_POOL_NUMBER;
  20530              } else
  20531 #endif
  20532              {
  20533              default_pool_number=pool_number_l=
  20534                     FLEX_COUNTER_DEFAULT_FCOE_TABLE_POOL_NUMBER;
  20535              }
  20536              used_by_table = FLEX_COUNTER_POOL_USED_BY_FCOE_TABLE;
  20537              used_by_table_selection_criteria=
  20538                      FLEX_COUNTER_POOL_USED_BY_FCOE_TABLE;
  20539              break;
  20540         case ING_VSANm:
  20541 #if defined(BCM_METROLITE_SUPPORT)
  20542              if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20543                  default_pool_number=pool_number_l=
  20544                      FLEX_COUNTER_ML_DEFAULT_FCOE_TABLE_POOL_NUMBER;
  20545              } else
  20546 #endif
  20547              {
  20548              default_pool_number=pool_number_l=
  20549                     FLEX_COUNTER_DEFAULT_FCOE_TABLE_POOL_NUMBER;
  20550              }
  20551              used_by_table = FLEX_COUNTER_POOL_USED_BY_VSAN_TABLE;
  20552              used_by_table_selection_criteria=
  20553                      FLEX_COUNTER_POOL_USED_BY_VSAN_TABLE;
  20554              break;
  20555 #endif
  20556         case EXT_FP_POLICYm:
  20557 #if defined(BCM_METROLITE_SUPPORT)
  20558              if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20559                  default_pool_number=pool_number_l=
  20560                      FLEX_COUNTER_ML_DEFAULT_EXT_FP_POLICY_TABLE_POOL_NUMBER;
  20561              } else
  20562 #endif
  20563              {
  20564              default_pool_number=pool_number_l=
  20565                      FLEX_COUNTER_DEFAULT_EXT_FP_POLICY_TABLE_POOL_NUMBER;
  20566              }
  20567              used_by_table = FLEX_COUNTER_POOL_USED_BY_EXT_FP_POLICY_TABLE;
  20568              used_by_table_selection_criteria=
  20569                      FLEX_COUNTER_POOL_USED_BY_EXT_FP_POLICY_TABLE;
  20570              break;
  20571         case SOURCE_VPm:
  20572 #if defined(BCM_METROLITE_SUPPORT)
  20573              if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20574                  default_pool_number=pool_number_l=
  20575                      FLEX_COUNTER_ML_DEFAULT_SOURCE_VP_TABLE_POOL_NUMBER;
  20576              } else
  20577 #endif
  20578              {
  20579              default_pool_number=pool_number_l=
  20580                      FLEX_COUNTER_DEFAULT_SOURCE_VP_TABLE_POOL_NUMBER;
  20581              }
  20582              /* Time being keeping separate default pool for source vp and l3_iif */
  20583              used_by_table = FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE;
  20584              /* But IfRequired SOURCE_VP & L3_IIF counters CanBeShared in same
  20585                 pool!*/
  20586              used_by_table_selection_criteria=
  20587                      FLEX_COUNTER_POOL_USED_BY_L3_IIF_TABLE |
  20588                      FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE ;
  20589              break;
  20590         case VFP_POLICY_TABLEm:
  20591             field_stage = bcmFieldQualifyStageLookup;
  20592             used_by_flag = FLEX_COUNTER_POOL_USED_BY_VFP_POLICY_TABLE;
  20593             /* coverity[unterminated case : FALSE] */
  20594 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
  20595         case FP_POLICY_TABLEm:
  20596         case IFP_POLICY_TABLEm:
  20597             field_stage = _bcm_esw_stat_get_field_stage_from_table(ingress_table);
  20598             /* coverity[unterminated case : FALSE] */
  20599 #if defined(BCM_TOMAHAWK_SUPPORT)
  20600         case IFP_POLICY_TABLE_PIPE0m:
  20601         case IFP_POLICY_TABLE_PIPE1m:
  20602         case IFP_POLICY_TABLE_PIPE2m:
  20603         case IFP_POLICY_TABLE_PIPE3m:
  20604         case IFP_POLICY_TABLE_PIPE4m:
  20605         case IFP_POLICY_TABLE_PIPE5m:
  20606         case IFP_POLICY_TABLE_PIPE6m:
  20607         case IFP_POLICY_TABLE_PIPE7m:
  20608         case EXACT_MATCH_2m:
  20609         case EXACT_MATCH_2_PIPE0m:
  20610         case EXACT_MATCH_2_PIPE1m:
  20611         case EXACT_MATCH_2_PIPE2m:
  20612         case EXACT_MATCH_2_PIPE3m:
  20613         case VFP_POLICY_TABLE_PIPE0m:
  20614         case VFP_POLICY_TABLE_PIPE1m:
  20615         case VFP_POLICY_TABLE_PIPE2m:
  20616         case VFP_POLICY_TABLE_PIPE3m:
  20617         case VFP_POLICY_TABLE_PIPE4m:
  20618         case VFP_POLICY_TABLE_PIPE5m:
  20619         case VFP_POLICY_TABLE_PIPE6m:
  20620         case VFP_POLICY_TABLE_PIPE7m:
  20621              /* Get Pipe from ingress_table */
  20622             field_stage = _bcm_esw_stat_get_field_stage_from_table(ingress_table);
  20623 
  20624             _bcm_esw_get_fp_pipe_pool_from_mode(unit, mode_id, 
  20625                                 field_stage, &pipe_num, &pool);
  20626 #endif
  20627             if (field_stage == bcmFieldQualifyStageIngress) {
  20628                 used_by_flag = FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE;
  20629             } else if (field_stage == bcmFieldQualifyStageIngressExactMatch){
  20630                 used_by_flag = FLEX_COUNTER_POOL_USED_BY_EM_POLICY_TABLE;
  20631             } else if (field_stage == bcmFieldQualifyStageLookup) {
  20632                 used_by_flag = FLEX_COUNTER_POOL_USED_BY_VFP_POLICY_TABLE;
  20633             }
  20634              used_by_table = used_by_flag;
  20635 
  20636 #endif
  20637              used_by_table_selection_criteria = used_by_flag;
  20638              /* Check to see if counter allocation is being requested
  20639               * from a specific pool
  20640               */
  20641              if (0xff != *pool_number) {
  20642                  if (*pool_number < num_flex_ingress_pools) {
  20643                      if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  20644                          default_pool_number = pool_number_l = *pool_number;
  20645                      } else {
  20646                          if ((flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  20647                                      [pipe_num][*pool_number].used_by_tables != 0) &&
  20648                                  (used_by_flag !=
  20649                                   flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  20650                                   [pipe_num][*pool_number].used_by_tables)) {
  20651                              /* Pool in pipe 0 from which counter allocation is being
  20652                               * requested is not used by IFP_POLICY_TABLE
  20653                               */
  20654                              LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  20655                                      (BSL_META_U(unit,
  20656                                                  "Invalid pool:%d pipe_num:%d\n\r"),
  20657                                       *pool_number, pipe_num));
  20658                              return BCM_E_PARAM;
  20659                          }
  20660 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
  20661                          allocate_from_specific_pool = 1;
  20662 #endif
  20663                          default_pool_number = pool_number_l = *pool_number;
  20664                      }
  20665                  } else {
  20666                      /* Invalid pool_number specified */
  20667                      LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  20668                                             (BSL_META_U(unit,
  20669                                             "Invalid pool:%d pipe_num:%d\n\r"),
  20670                                              *pool_number, pipe_num));
  20671                      return BCM_E_PARAM;
  20672                  }
  20673              } else {
  20674                  if (field_stage == bcmFieldQualifyStageIngress) {
  20675 #if defined(BCM_METROLITE_SUPPORT)
  20676                      if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20677                          default_pool_number = pool_number_l = 
  20678                              FLEX_COUNTER_ML_DEFAULT_IFP_POLICY_TABLE_POOL_NUMBER;
  20679                      } else
  20680 #endif
  20681                      {
  20682                      default_pool_number = pool_number_l = 
  20683                         FLEX_COUNTER_DEFAULT_IFP_POLICY_TABLE_POOL_NUMBER;
  20684                      }
  20685                  } else if (field_stage == bcmFieldQualifyStageIngressExactMatch) {
  20686 #if defined(BCM_METROLITE_SUPPORT)
  20687                      if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20688                          default_pool_number = pool_number_l = 
  20689                              FLEX_COUNTER_ML_DEFAULT_EM_POLICY_TABLE_POOL_NUMBER;
  20690                     } else
  20691 #endif
  20692                     {
  20693                      default_pool_number = pool_number_l = 
  20694                         FLEX_COUNTER_DEFAULT_EM_POLICY_TABLE_POOL_NUMBER;
  20695                     }
  20696                  } else if (field_stage == bcmFieldQualifyStageLookup) {
  20697                      default_pool_number = pool_number_l = 
  20698                         FLEX_COUNTER_DEFAULT_VFP_POLICY_TABLE_POOL_NUMBER;
  20699                  }
  20700              }
  20701              break;
  20702 #if defined(BCM_TOMAHAWK_SUPPORT)
  20703         case AGM_MONITOR_TABLEm:
  20704 #if defined(BCM_METROLITE_SUPPORT)
  20705             if (soc_feature(unit, soc_feature_flex_stat_ing_pools_4)) {
  20706                 default_pool_number = pool_number_l =
  20707                     FLEX_COUNTER_ML_DEFAULT_AGM_MONITOR_TABLE_POOL_NUMBER;
  20708                 used_by_table =
  20709                       FLEX_COUNTER_POOL_USED_BY_AGM_MONITOR_TABLE;
  20710                 used_by_table_selection_criteria=
  20711                       FLEX_COUNTER_POOL_USED_BY_AGM_MONITOR_TABLE;
  20712             } else
  20713 #endif
  20714             {
  20715                 if (lookup == 1) {
  20716              default_pool_number=pool_number_l=
  20717                    FLEX_COUNTER_DEFAULT_AGM_MONITOR_TABLE_POOL_NUMBER;
  20718              used_by_table =
  20719                    FLEX_COUNTER_POOL_USED_BY_AGM_MONITOR_TABLE;
  20720              used_by_table_selection_criteria=
  20721                    FLEX_COUNTER_POOL_USED_BY_AGM_MONITOR_TABLE;
  20722                 } else if (lookup == 2) {
  20723                      default_pool_number=pool_number_l=
  20724                         FLEX_COUNTER_DEFAULT_AGM_MONITOR_TABLE_SCND_LKUP_POOL_NUMBER;
  20725                      used_by_table =
  20726                         FLEX_COUNTER_POOL_USED_BY_AGM_MONITOR_TABLE_FOR_SCND_LKUP;
  20727                      used_by_table_selection_criteria=
  20728                         FLEX_COUNTER_POOL_USED_BY_AGM_MONITOR_TABLE_FOR_SCND_LKUP;
  20729                 }
  20730             }
  20731              break;
  20732 #endif
  20733         default:
  20734              LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  20735                        (BSL_META_U(unit,
  20736                                    "Invalid Table is passed %d \n"),
  20737                         ingress_table));
  20738              return BCM_E_INTERNAL;
  20739     }
  20740 
  20741     if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  20742         /* Override default pool number with user configured pool */
  20743         pool_number_l = default_pool_number = 0;
  20744         default_pool_number = *pool_number;
  20745         pool_number_l= *pool_number;
  20746         base_idx_l = *base_idx;
  20747         if (_bcm_stat_flex_reserve_base_index(unit,
  20748                     bcmStatFlexDirectionIngress,
  20749                     pool_number_l,
  20750                     total_counters,base_idx_l,
  20751                     used_by_table,pipe_num,object) == BCM_E_NONE) {
  20752             _bcm_esw_stat_get_counter_id(
  20753                     unit, flex_ingress_modes[unit][mode].group_mode,
  20754                     object,mode,pool_number_l,base_idx_l,
  20755                     &stat_counter_id);
  20756             BCM_STAT_FLEX_COUNTER_LOCK(unit);
  20757             flex_ingress_modes[unit][mode].reference_count++;
  20758             BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  20759             if (_bcm_esw_stat_flex_insert_stat_id(unit,
  20760                         local_scache_ptr[unit],stat_counter_id) != BCM_E_NONE) {
  20761                 LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  20762                         (BSL_META_U(unit,
  20763                                     "WARMBOOT:Couldnot add entry in scache memory"
  20764                                     ".Attach it\n")));
  20765                return BCM_E_INTERNAL;
  20766             }
  20767             return BCM_E_NONE;
  20768         } else {
  20769             return BCM_E_RESOURCE;
  20770         }
  20771     }
  20772     BCM_IF_ERROR_RETURN(
  20773         _bcm_esw_stat_flex_object_config_get(unit,
  20774                                              ingress_table, &object_config));
  20775 
  20776     if (object_config.share_criteria != INVALID_CONFIG) {
  20777         used_by_table_selection_criteria |= object_config.share_criteria;
  20778         default_pool_number=pool_number_l = object_config.config_pool;
  20779     }
  20780     if (object_config.exclude_criteria != INVALID_CONFIG) {
  20781         used_by_table_selection_criteria &= ~(object_config.exclude_criteria);
  20782     }
  20783 
  20784     if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
  20785         /* For TD2Plus, always start from the first pool and traverse all
  20786          * the pools to identify the correct pool for allocation.
  20787          */                                           
  20788         /* Note: Eventhough for each object the default pool number is defined 
  20789          * , (e.g) for IFP, it is reserved a value of
  20790          * FLEX_COUNTER_DEFAULT_IFP_POLICY_TABLE_POOL_NUMBER, The allocation of
  20791          * pools in TD2Plus starts from zero. This is because of the following
  20792          * reasons.                                   
  20793          * 1. Limited Pools are available for TD2Plus (8 pools).
  20794          * 2. These counter pools needs to be divided for regular as well as 
  20795          * for OAM operation.                         
  20796          * 3. So For TD2Plus, the pools are allocated in the same order as group
  20797          * creation.                                  
  20798          * 4. During Initialization, Specific pools are not reserved for OAM, 
  20799          * They are determined dynamically (i.e) When the group mode is created
  20800          * with OAM capability then the ING_FLEX_CTR_LM_CONFIG register is 
  20801          * programed based on the available group.    
  20802          */                                           
  20803         default_pool_number = pool_number_l = 0;      
  20804                                                       
  20805         /* Check the required group type.             
  20806          */                                           
  20807         if (flex_ingress_modes[unit][mode].oam_flags && oam_mode) {
  20808             allocate_group_type = BCM_FLEX_POOL_GROUP_USED_BY_OAM;
  20809         } else {                                      
  20810             allocate_group_type = BCM_FLEX_POOL_GROUP_USED_BY_OTHER;
  20811         }                                             
  20812                                                       
  20813         /* Check if the Flex counter pool group is already allocated 
  20814          * for the required group mode.               
  20815          */                                           
  20816         for ( pool_group_id = 0;                      
  20817               pool_group_id < _bcm_esw_get_max_pool_groups(unit); 
  20818               pool_group_id++) {                      
  20819             if ((flex_pool_group[unit][pipe_num][pool_group_id].group_type == 
  20820                                                     allocate_group_type) &&
  20821                   flex_pool_group[unit][pipe_num][pool_group_id].free_pools) {
  20822                  default_pool_number = pool_number_l =  
  20823                                 flex_pool_group[unit][pipe_num][pool_group_id].base_pool;
  20824                 break;                                
  20825             }
  20826         }
  20827     }
  20828 
  20829     do {
  20830 #if defined(BCM_TOMAHAWK_SUPPORT) && defined (INCLUDE_FLOWTRACKER)
  20831     if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
  20832          soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
  20833          soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
  20834             if (_bcm_esw_stat_pool_reserved(unit,
  20835                     bcmStatFlexDirectionIngress, pool_number_l)) {
  20836                 pool_number_l = (pool_number_l + 1) % num_flex_ingress_pools;
  20837                 continue;
  20838             }
  20839        }
  20840 #endif
  20841 
  20842        /* Either free or being used by port table only */
  20843        if ((flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num]
  20844                           [pool_number_l].used_by_tables == 0) ||
  20845            (flex_pool_stat[unit][bcmStatFlexDirectionIngress][pipe_num][pool_number_l].
  20846             used_by_tables & used_by_table_selection_criteria)) {
  20847                                                       
  20848             /* Determine the Pool Group and check if the pool group 
  20849              * is eligible for allocation.            
  20850              */                                       
  20851             pool_group_id = pool_number_l /
  20852                              BCM_STAT_FLEX_COUNTER_POOLS_PER_GROUP;
  20853                                                       
  20854             if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
  20855                 pool_group_type = flex_pool_group[unit][pipe_num]
  20856                                                  [pool_group_id].group_type; 
  20857                 if (!((BCM_FLEX_POOL_GROUP_USED_BY_NONE == 
  20858                                                     pool_group_type)|| 
  20859                       (allocate_group_type == pool_group_type ))) {
  20860                     pool_number_l = ((pool_group_id + 1) *
  20861                     BCM_STAT_FLEX_COUNTER_POOLS_PER_GROUP) % 
  20862                                     num_flex_ingress_pools;
  20863                     continue;                         
  20864                 }
  20865             }
  20866                                                       
  20867 #if defined(BCM_TOMAHAWK_SUPPORT)
  20868             if ((SOC_IS_TOMAHAWKX(unit)||SOC_IS_TRIDENT3X(unit)) &&
  20869                 !allocate_from_specific_pool &&
  20870                 ((bcmStatObjectIngFieldStageIngress == object) ||
  20871                  ((bcmStatObjectIngPolicy == object) && (mode_id >=
  20872                  BCM_CUSTOM_INGRESS_MODE_START)) ||
  20873                  (bcmStatObjectIngExactMatch == object))) {
  20874                     /* Pool num comes from field module.
  20875                      */
  20876                 if (0 != flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  20877                                        [pipe_num][pool_number_l].used_entries) {
  20878                     /* For a non specific pool allocation
  20879                      * request, allocate from an unused pool only.
  20880                      */
  20881                     pool_number_l = (pool_number_l + 1) %
  20882                                     num_flex_ingress_pools;
  20883                     if (pool_number_l == default_pool_number) {
  20884                         break;
  20885                     } else {
  20886                         continue;
  20887                     }
  20888                 }
  20889             }
  20890 #endif
  20891             if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
  20892                 /* Update the pool_group type */      
  20893                 flex_pool_group[unit][pipe_num][pool_group_id].group_type 
  20894                                                      = allocate_group_type;
  20895                 /* If the pool is newly reserved, update the 
  20896                  * free_pool database                 
  20897                  */                                   
  20898                 if (flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  20899                           [0][pool_number_l].used_by_tables == 0) {
  20900                     if ((flex_pool_group[unit][pipe_num][pool_group_id].free_pools == 
  20901                                       BCM_STAT_FLEX_COUNTER_POOLS_PER_GROUP) &&
  20902                         (allocate_group_type ==       
  20903                                       BCM_FLEX_POOL_GROUP_USED_BY_OAM)) {
  20904                         BCM_IF_ERROR_RETURN(          
  20905                                _bcm_esw_stat_flex_oam_enable_ingress_group(unit,
  20906                                                                   pool_group_id,
  20907                                                                   1));
  20908                     }
  20909                     flex_pool_group[unit][pipe_num][pool_group_id].free_pools--;
  20910                 }
  20911            }
  20912 #if defined(BCM_TRIDENT2PLUS_SUPPORT)               
  20913                 /* In TD2Plus, We have already decided the pool to be used for
  20914                  * OAM counters . As per the improvement requirement for
  20915                  * FP, Flex Counters for OAM should not extend to next pool.
  20916                  */
  20917                 if (flex_pool_group[unit][0][pool_group_id].group_type == 
  20918                                           BCM_FLEX_POOL_GROUP_USED_BY_OAM) {
  20919                     allocate_from_specific_pool = 1;
  20920                 }
  20921 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 
  20922        
  20923            if (shr_aidxres_list_alloc_block(flex_aidxres_list_handle[unit]
  20924                    [bcmStatFlexDirectionIngress][pipe_num][pool_number_l],
  20925                    total_counters,
  20926                    &base_idx_l) == BCM_E_NONE) {
  20927                flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  20928                     [pipe_num][pool_number_l].used_by_tables |= used_by_table;
  20929 
  20930                if (pipe_num != 0) {
  20931                    /* The pool in pipe 0 also reserved for IFP if the pool is reserved for IFP
  20932                     * in any other pipe */
  20933                    flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  20934                         [0][pool_number_l].used_by_tables |= used_by_table;
  20935                }
  20936 #if defined BCM_TOMAHAWK_SUPPORT
  20937                if (SOC_IS_TOMAHAWKX(unit) &&
  20938                    (_bcm_esw_get_fp_mode_global(unit, field_stage) == 1)) {
  20939                   /* If pool belongs to Global mode, reserve it for all pipes. */
  20940                   int pipe;
  20941 
  20942                   for(pipe = 0; pipe < _MAX_PIPES_PER_DEV(unit); pipe++) {
  20943                      flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  20944                       [pipe][pool_number_l].used_by_tables |= used_by_table;
  20945                   }
  20946                }
  20947 #endif /* BCM_TOMAHAWK_SUPPORT */
  20948                SHR_BITSET(flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  20949                     [pipe_num][pool_number_l].used_by_objects, object);
  20950                flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  20951                     [pipe_num][pool_number_l].used_entries += total_counters;
  20952                LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  20953                          (BSL_META_U(unit,
  20954                                      "Allocated  counter for Table:%s "
  20955                                       "pool_number:%d mode:%d base_idx:%d ref_cnt:%d\n"),
  20956                           SOC_MEM_UFNAME(unit, ingress_table),
  20957                           pool_number_l,mode,base_idx_l,
  20958                           flex_ingress_modes[unit][mode].reference_count));
  20959                shr_aidxres_list_state(flex_aidxres_list_handle[unit]
  20960                    [bcmStatFlexDirectionIngress][pipe_num][pool_number_l],
  20961                    NULL,NULL,NULL,NULL,&free_count,&alloc_count,&largest_free,
  20962                    NULL);
  20963 
  20964                LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  20965                          (BSL_META_U(unit,
  20966                                      "Current Pool status free_count:%d alloc_count:%d"
  20967                                       "largest_free:%d used_by_tables:%d"
  20968                                       "used_entries:%d\n"),
  20969                           free_count,alloc_count,largest_free,
  20970                           flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  20971                           [pipe_num][pool_number_l].used_by_tables,
  20972                           flex_pool_stat[unit][bcmStatFlexDirectionIngress]
  20973                           [pipe_num][pool_number_l].used_entries));
  20974                *pool_number    = pool_number_l;
  20975                *base_idx       = base_idx_l;
  20976 #if defined (BCM_TOMAHAWK_SUPPORT)
  20977                if (soc_feature(unit, soc_feature_flex_counter_opaque_stat_id) &&
  20978                    (mode_id >= BCM_CUSTOM_INGRESS_MODE_START) &&
  20979                    (mode_id < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  20980                    /* _bcm_esw_stat_get_counter_id will allocate counter ID.
  20981                     * But we need no counter ID allocation at this point.
  20982                     */
  20983                } else
  20984 #endif
  20985                {
  20986                    _bcm_esw_stat_get_counter_id(
  20987                                  unit, flex_ingress_modes[unit][mode].group_mode,
  20988                                  object,mode,pool_number_l,base_idx_l,
  20989                                  &stat_counter_id);
  20990                    if (_bcm_esw_stat_flex_insert_stat_id(unit,
  20991                        local_scache_ptr[unit],stat_counter_id) != BCM_E_NONE) {
  20992                        LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  20993                                 (BSL_META_U(unit,
  20994                                             "WARMBOOT:Couldnot add entry in scache memory"
  20995                                              ".Attach it\n")));
  20996                    }
  20997                }
  20998                BCM_STAT_FLEX_COUNTER_LOCK(unit);
  20999                flex_ingress_modes[unit][mode].reference_count++;
  21000                BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  21001                return BCM_E_NONE;
  21002            }
  21003 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
  21004            else {
  21005                if ((SOC_IS_TOMAHAWKX(unit) ||SOC_IS_TRIDENT3X(unit)) &&
  21006                    allocate_from_specific_pool &&
  21007                    ((bcmStatObjectIngFieldStageIngress == object) ||
  21008                     (bcmStatObjectIngPolicy == object) ||
  21009                     (bcmStatObjectIngExactMatch == object))) {
  21010                       return BCM_E_RESOURCE;
  21011                }
  21012                if (SOC_IS_TD2P_TT2P(unit) &&
  21013                    allocate_from_specific_pool) { 
  21014                    return BCM_E_RESOURCE;
  21015                }
  21016            }
  21017 #endif
  21018        }
  21019       
  21020        pool_number_l = (pool_number_l + 1) % num_flex_ingress_pools;
  21021 
  21022     } while (pool_number_l != default_pool_number);
  21023     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  21024               (BSL_META_U(unit,
  21025                           "Pools exhausted for Table:%s\n"),
  21026                SOC_MEM_UFNAME(unit,ingress_table)));
  21027     return BCM_E_RESOURCE;
  21028 }
  21029 
  21030 #if defined(BCM_TOMAHAWK_SUPPORT)
  21031 
  21032 bcm_error_t _bcm_esw_ifp_wb_color_map_set(
  21033         int                   unit,
  21034         uint32                pool_number,
  21035         uint32                base_index,
  21036         uint32                pipe_num,
  21037         bcm_stat_flex_mode_t offset_mode,
  21038         _bcm_ifp_color_map_t  *color_map)
  21039 {
  21040     uint32 ctr_idx, color_mask;
  21041     soc_mem_t mem;
  21042     uint32 total_counters = 0;
  21043     uint32 num_flex_ingress_pools = SOC_INFO(unit).num_flex_ingress_pools;
  21044     uint8 g_count = 0xFF, y_count = 0xFF, r_count = 0xFF;
  21045     uint8 color_map_mask[BCM_MAX_IFP_COLORS] = {BCM_STAT_FLEX_COLOR_GREEN,
  21046                                                 BCM_STAT_FLEX_COLOR_YELLOW,
  21047                                                 BCM_STAT_FLEX_COLOR_RED};
  21048 
  21049     if (NULL == color_map) {
  21050         return BCM_E_PARAM;
  21051     }
  21052      mem = _ctr_counter_table[bcmStatFlexDirectionIngress][pool_number];
  21053 
  21054     if ((offset_mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  21055         (offset_mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  21056         offset_mode = flex_custom_ingress_modes[unit][offset_mode - 
  21057                                  BCM_CUSTOM_INGRESS_MODE_START].offset_mode;
  21058 
  21059     }
  21060     /* Validate retrieved field values */
  21061     if (offset_mode >= BCM_STAT_FLEX_COUNTER_MAX_MODE) {
  21062         return BCM_E_PARAM;
  21063     }
  21064     if (pool_number >= num_flex_ingress_pools) {
  21065         return BCM_E_PARAM;
  21066     }
  21067 
  21068     if (base_index >= soc_mem_index_count(unit, mem)) {
  21069         return BCM_E_PARAM;
  21070     }
  21071  
  21072 
  21073     for (ctr_idx = 0; ctr_idx < BCM_MAX_IFP_COLOR_COUNTERS; ctr_idx++) {
  21074         if (0 != color_map->map[ctr_idx]) {
  21075             if ((ctr_idx > 0) &&
  21076                 (0 == total_counters)) {
  21077                 /* Incorrect specification of color map. At least one
  21078                  * preceding element is 0 */
  21079                 return BCM_E_PARAM;
  21080             }
  21081             for (color_mask = 0; color_mask < BCM_MAX_IFP_COLORS; color_mask++) {
  21082                 switch (color_map->map[ctr_idx] & color_map_mask[color_mask]) {
  21083                     case BCM_STAT_FLEX_COLOR_GREEN:
  21084                         if (0xFF == g_count) {
  21085                             g_count = ctr_idx;
  21086                         } else {
  21087                             /* Color green used more than once. */
  21088                             return BCM_E_PARAM;
  21089                         }
  21090                         continue;
  21091                     case BCM_STAT_FLEX_COLOR_YELLOW:
  21092                         if (0xFF == y_count) {
  21093                             y_count = ctr_idx;
  21094                         } else {
  21095                             /* Color yellow used more than once. */
  21096                             return BCM_E_PARAM;
  21097                         }
  21098                         continue;
  21099                     case BCM_STAT_FLEX_COLOR_RED:
  21100                         if (0xFF == r_count) {
  21101                             r_count = ctr_idx;
  21102                         } else {
  21103                             /* Color red used more than once. */
  21104                             return BCM_E_PARAM;
  21105                         }
  21106                         continue;
  21107                     default:
  21108                         if (0 != (color_map->map[ctr_idx] &
  21109                             color_map_mask[color_mask])) {
  21110                             return BCM_E_PARAM;
  21111                         }
  21112                         break;
  21113                 }
  21114             }
  21115             total_counters++;
  21116         }
  21117     }
  21118     for (ctr_idx = 0; ctr_idx < total_counters; ctr_idx++) {
  21119         if (NULL == ifp_color_map[unit][pipe_num][pool_number]) {
  21120             /* This should not happen. Error during init ? */
  21121             return BCM_E_INTERNAL;
  21122         }
  21123         ifp_color_map[unit][pipe_num][pool_number][base_index + ctr_idx] =
  21124             color_map->map[ctr_idx];
  21125     }
  21126     return BCM_E_NONE;
  21127 }
  21128 
  21129 /*
  21130  * Function:
  21131  *      _bcm_esw_ifp_color_map_set
  21132  * Description:
  21133  *      Specify color map for an IFP stat group. This color
  21134  *      map is used during the stat_attach call, in order to
  21135  *      program G_COUNT, Y_COUNT, R_COUNT appropriately in the
  21136  *      IFP_POLICY_TABLE.
  21137  * Parameters:
  21138  *      unit                  - (IN) unit number
  21139  *      stat_counter_id       - (IN) stat id returned by
  21140  *                              stat_group_create call
  21141  *      color_map             - (IN) Array specifying mapping
  21142  *                              of color to counter offset
  21143  * Return Value:
  21144  *      BCM_E_XXX
  21145  */
  21146 bcm_error_t _bcm_esw_ifp_color_map_set(
  21147         int                   unit,
  21148         uint32                stat_counter_id,
  21149         _bcm_ifp_color_map_t  *color_map)
  21150 {
  21151     uint32 pool_number, base_index, ctr_idx, color_mask;
  21152     soc_mem_t mem;
  21153     uint32 total_counters = 0;
  21154     bcm_stat_group_mode_t group;
  21155     bcm_stat_object_t object;
  21156     bcm_stat_flex_mode_t offset_mode;
  21157     uint32 num_flex_ingress_pools = SOC_INFO(unit).num_flex_ingress_pools;
  21158     uint8 g_count = 0xFF, y_count = 0xFF, r_count = 0xFF;
  21159     uint8 color_map_mask[BCM_MAX_IFP_COLORS] = {BCM_STAT_FLEX_COLOR_GREEN,
  21160                                                 BCM_STAT_FLEX_COLOR_YELLOW,
  21161                                                 BCM_STAT_FLEX_COLOR_RED};
  21162     int pipe_num = 0;
  21163     bcm_field_qualify_t stage;
  21164     bcm_stat_flex_custom_ingress_mode_t *cmode = NULL;
  21165 
  21166     if (NULL == color_map) {
  21167         return BCM_E_PARAM;
  21168     }
  21169     _bcm_esw_stat_get_counter_id_info(
  21170         unit, stat_counter_id, &group, &object,
  21171         &offset_mode, &pool_number, &base_index);
  21172 
  21173      mem = _ctr_counter_table[bcmStatFlexDirectionIngress][pool_number];
  21174 
  21175     stage = _bcm_esw_stat_get_field_stage_from_stat_ctr(unit, stat_counter_id);
  21176     _bcm_esw_get_fp_pipe_from_mode(unit, offset_mode, stage, &pipe_num);
  21177     if ((offset_mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  21178         (offset_mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  21179         cmode = &flex_custom_ingress_modes[unit][offset_mode - 
  21180                                  BCM_CUSTOM_INGRESS_MODE_START];
  21181         offset_mode = flex_custom_ingress_modes[unit][offset_mode - 
  21182                                  BCM_CUSTOM_INGRESS_MODE_START].offset_mode;
  21183 
  21184     }
  21185     /* Validate retrieved field values */
  21186     if (!((group >= (bcm_stat_group_mode_t) bcmStatGroupModeFlex1) &&
  21187         (group <= (bcm_stat_group_mode_t) bcmStatGroupModeFlex4))) {
  21188         return BCM_E_PARAM;
  21189     }
  21190     if ((bcmStatObjectIngFieldStageIngress != object) &&
  21191         (bcmStatObjectIngExactMatch != object)) {
  21192         return BCM_E_PARAM;
  21193     }
  21194     if (offset_mode >= BCM_STAT_FLEX_COUNTER_MAX_MODE) {
  21195         return BCM_E_PARAM;
  21196     }
  21197     if (pool_number >= num_flex_ingress_pools) {
  21198         return BCM_E_PARAM;
  21199     }
  21200 
  21201     if (base_index >= soc_mem_index_count(unit, mem)) {
  21202         return BCM_E_PARAM;
  21203     }
  21204  
  21205 
  21206     for (ctr_idx = 0; ctr_idx < BCM_MAX_IFP_COLOR_COUNTERS; ctr_idx++) {
  21207         if (0 != color_map->map[ctr_idx]) {
  21208             if ((ctr_idx > 0) &&
  21209                 (0 == total_counters)) {
  21210                 /* Incorrect specification of color map. At least one
  21211                  * preceding element is 0 */
  21212                 return BCM_E_PARAM;
  21213             }
  21214             for (color_mask = 0; color_mask < BCM_MAX_IFP_COLORS; color_mask++) {
  21215                 switch (color_map->map[ctr_idx] & color_map_mask[color_mask]) {
  21216                     case BCM_STAT_FLEX_COLOR_GREEN:
  21217                         if (0xFF == g_count) {
  21218                             g_count = ctr_idx;
  21219                         } else {
  21220                             /* Color green used more than once. */
  21221                             return BCM_E_PARAM;
  21222                         }
  21223                         continue;
  21224                     case BCM_STAT_FLEX_COLOR_YELLOW:
  21225                         if (0xFF == y_count) {
  21226                             y_count = ctr_idx;
  21227                         } else {
  21228                             /* Color yellow used more than once. */
  21229                             return BCM_E_PARAM;
  21230                         }
  21231                         continue;
  21232                     case BCM_STAT_FLEX_COLOR_RED:
  21233                         if (0xFF == r_count) {
  21234                             r_count = ctr_idx;
  21235                         } else {
  21236                             /* Color red used more than once. */
  21237                             return BCM_E_PARAM;
  21238                         }
  21239                         continue;
  21240                     default:
  21241                         if (0 != (color_map->map[ctr_idx] &
  21242                             color_map_mask[color_mask])) {
  21243                             return BCM_E_PARAM;
  21244                         }
  21245                         break;
  21246                 }
  21247             }
  21248             total_counters++;
  21249         }
  21250     }
  21251     if ((0 == total_counters) ||
  21252         (cmode && cmode->total_counters != total_counters) ||
  21253         (!cmode && (total_counters != flex_ingress_modes[unit]
  21254         [offset_mode].total_counters))) {
  21255         /* Number of counters specified in color map does not match
  21256          * number of counters for the given mode.
  21257          */
  21258         return BCM_E_PARAM;
  21259     }
  21260     for (ctr_idx = 0; ctr_idx < total_counters; ctr_idx++) {
  21261         if (NULL == ifp_color_map[unit][pipe_num][pool_number]) {
  21262             /* This should not happen. Error during init ? */
  21263             return BCM_E_INTERNAL;
  21264         }
  21265         ifp_color_map[unit][pipe_num][pool_number][base_index + ctr_idx] =
  21266             color_map->map[ctr_idx];
  21267     }
  21268     return BCM_E_NONE;
  21269 }
  21270 
  21271 /*
  21272  * Function:
  21273  *      _bcm_esw_ifp_color_map_get
  21274  * Description:
  21275  *      Read color map for an IFP stat group.
  21276  * Parameters:
  21277  *      unit                  - (IN) unit number
  21278  *      stat_counter_id       - (IN) stat id returned by
  21279  *                              stat_group_create call
  21280  *      color_map             - (OUT) Array specifying mapping
  21281  *                              of color to counter offset
  21282  * Return Value:
  21283  *      BCM_E_XXX
  21284  * Notes:
  21285  */
  21286 bcm_error_t _bcm_esw_ifp_color_map_get(
  21287         int                   unit,
  21288         uint32                stat_counter_id,
  21289         _bcm_ifp_color_map_t  *color_map)
  21290 {
  21291     uint32 pool_number, base_index, ctr_idx;
  21292     soc_mem_t  mem;
  21293     uint32 total_counters = 0;
  21294     bcm_stat_group_mode_t group;
  21295     bcm_stat_object_t object;
  21296     bcm_stat_flex_mode_t offset_mode;
  21297     uint32 num_flex_ingress_pools = SOC_INFO(unit).num_flex_ingress_pools;
  21298     int pipe_num = 0;
  21299     bcm_field_qualify_t stage;
  21300 
  21301     if (NULL == color_map) {
  21302         return BCM_E_PARAM;
  21303     }
  21304     _bcm_esw_stat_get_counter_id_info(
  21305         unit, stat_counter_id, &group, &object,
  21306         &offset_mode, &pool_number, &base_index);
  21307     /* Validate retrieved field values */
  21308     if (!((group >= (bcm_stat_group_mode_t) bcmStatGroupModeFlex1) &&
  21309         (group <= (bcm_stat_group_mode_t) bcmStatGroupModeFlex4))) {
  21310         return BCM_E_PARAM;
  21311     }
  21312     if ((bcmStatObjectIngFieldStageIngress != object) &&
  21313         (bcmStatObjectIngExactMatch != object)) {
  21314         return BCM_E_PARAM;
  21315     }
  21316     if (pool_number >= num_flex_ingress_pools) {
  21317         return BCM_E_PARAM;
  21318     }
  21319 
  21320      mem = _ctr_counter_table[bcmStatFlexDirectionIngress][pool_number];
  21321     stage = _bcm_esw_stat_get_field_stage_from_stat_ctr(unit, stat_counter_id);
  21322     _bcm_esw_get_fp_pipe_from_mode(unit, offset_mode, stage, &pipe_num);
  21323 
  21324     if ((offset_mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  21325         (offset_mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  21326         total_counters = flex_custom_ingress_modes[unit][offset_mode].total_counters;
  21327     } else if (offset_mode >= BCM_STAT_FLEX_COUNTER_MAX_MODE) {
  21328         return BCM_E_PARAM;
  21329     } else {
  21330         total_counters = flex_ingress_modes[unit][offset_mode].total_counters;
  21331     }
  21332 
  21333     _CTR_COUNTER_TABLE_IFP(unit, bcmStatFlexDirectionIngress, pipe_num, pool_number, mem);
  21334 
  21335     if (base_index >= soc_mem_index_count(unit, mem)) {
  21336         return BCM_E_PARAM;
  21337     }
  21338     if (0 == flex_base_index_reference_count[unit][bcmStatFlexDirectionIngress]
  21339         [pipe_num][pool_number][base_index]) {
  21340         /* Base index not in use */
  21341         return BCM_E_PARAM;
  21342     }
  21343 
  21344     if (NULL == ifp_color_map[unit][pipe_num][pool_number]) {
  21345         /* This should not happen. Possible init failure */
  21346         return BCM_E_INTERNAL;
  21347     }
  21348     if (total_counters > BCM_MAX_IFP_COLOR_COUNTERS) {
  21349         /* Error mismatch in number of counters */
  21350         return BCM_E_PARAM;
  21351     }
  21352 
  21353     for (ctr_idx = 0; ctr_idx < total_counters; ctr_idx++) {
  21354         color_map->map[ctr_idx] = ifp_color_map[unit][pipe_num][pool_number]
  21355                                   [base_index + ctr_idx];
  21356     }
  21357     return BCM_E_NONE;
  21358 }
  21359 #endif
  21360 /*
  21361  * Function:
  21362  *      _bcm_esw_stat_flex_set_group_mode
  21363  * Description:
  21364  *      Set Flex group mode  in s/w copy  for reference
  21365  * Parameters:
  21366  *      unit                  - (IN) unit number
  21367  *      direction             - (IN) Flex Data Flow Direction
  21368  *      offset_mode           - (IN) Flex Offset Mode
  21369  *      group_mode            - (IN) Flex Group Mode
  21370  * Return Value:
  21371  *      BCM_E_XXX
  21372  * Notes:
  21373  */
  21374 bcm_error_t _bcm_esw_stat_flex_set_group_mode(
  21375             int                       unit,
  21376             bcm_stat_flex_direction_t direction,
  21377             uint32                    offset_mode,
  21378             bcm_stat_group_mode_t     group_mode)
  21379 {
  21380     /* Better to check */
  21381     if(!((group_mode >= bcmStatGroupModeSingle) &&
  21382          (group_mode <= (bcm_stat_group_mode_t) bcmStatGroupModeFlex4))) {
  21383          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  21384                    (BSL_META_U(unit,
  21385                                "Invalid bcm_stat_group_mode_t passed %d \n"),
  21386                     group_mode));
  21387          return BCM_E_PARAM;
  21388     }
  21389     if (direction == bcmStatFlexDirectionIngress) {
  21390 #if defined (BCM_TOMAHAWK_SUPPORT)
  21391         if ((offset_mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  21392         (offset_mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  21393             offset_mode = flex_custom_ingress_modes[unit][offset_mode - 
  21394                                      BCM_CUSTOM_INGRESS_MODE_START].offset_mode;
  21395     }
  21396 #endif
  21397         flex_ingress_modes[unit][offset_mode].group_mode = group_mode;
  21398     } else {
  21399 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  21400         if ((offset_mode >= BCM_CUSTOM_EGRESS_MODE_START) &&
  21401         (offset_mode < BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE)) {
  21402             offset_mode = flex_custom_egress_modes[unit][offset_mode -
  21403                                      BCM_CUSTOM_EGRESS_MODE_START].offset_mode;
  21404         }
  21405 #endif
  21406         flex_egress_modes[unit][offset_mode].group_mode = group_mode;
  21407     }
  21408     return BCM_E_NONE;
  21409 }
  21410 /*
  21411  * Function:
  21412  *      _bcm_esw_stat_flex_reset_group_mode
  21413  * Description:
  21414  *      ReSet Flex group mode  in s/w copy  for reference
  21415  * Parameters:
  21416  *      unit                  - (IN) unit number
  21417  *      direction             - (IN) Flex Data Flow Direction
  21418  *      offset_mode           - (IN) Flex Offset Mode
  21419  *      group_mode            - (IN) Flex Group Mode
  21420  * Return Value:
  21421  *      BCM_E_XXX
  21422  * Notes:
  21423  */
  21424 bcm_error_t _bcm_esw_stat_flex_reset_group_mode(
  21425             int                       unit,
  21426             bcm_stat_flex_direction_t direction,
  21427             uint32                    offset_mode,
  21428             bcm_stat_group_mode_t     group_mode)
  21429 {
  21430     /* Better to check */
  21431     if(!((group_mode >= bcmStatGroupModeSingle) &&
  21432          (group_mode <= (bcm_stat_group_mode_t) bcmStatGroupModeFlex4))) {
  21433          LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  21434                    (BSL_META_U(unit,
  21435                                "Invalid bcm_stat_group_mode_t passed %d \n"),
  21436                     group_mode));
  21437          return BCM_E_PARAM;
  21438     }
  21439     if (direction == bcmStatFlexDirectionIngress) {
  21440 #if defined (BCM_TOMAHAWK_SUPPORT)
  21441         if ((offset_mode >= BCM_CUSTOM_INGRESS_MODE_START) &&
  21442         (offset_mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE)) {
  21443             offset_mode = flex_custom_ingress_modes[unit][offset_mode -
  21444                                              BCM_CUSTOM_INGRESS_MODE_START].offset_mode;
  21445     }
  21446 #endif
  21447         flex_ingress_modes[unit][offset_mode].group_mode = 0;
  21448     } else {
  21449 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  21450         if ((offset_mode >= BCM_CUSTOM_EGRESS_MODE_START) &&
  21451             (offset_mode < BCM_STAT_FLEX_CUSTOM_EGRESS_COUNTER_MAX_MODE)) {
  21452                 offset_mode = flex_custom_egress_modes[unit][offset_mode -
  21453                               BCM_CUSTOM_EGRESS_MODE_START].offset_mode;
  21454         }
  21455 #endif
  21456         flex_egress_modes[unit][offset_mode].group_mode = 0;
  21457     }
  21458     return BCM_E_NONE;
  21459 }
  21460 /*
  21461  * Function:
  21462  *      _bcm_esw_stat_flex_show_mode_info
  21463  * Description:
  21464  *      Show Mode information
  21465  * Parameters:
  21466  *      unit                  - (IN) unit number
  21467  * Return Value:
  21468  *      BCM_E_XXX
  21469  * Notes:
  21470  *      For Debugging purpose only
  21471  */
  21472 void _bcm_esw_stat_flex_show_mode_info(int unit)
  21473 {
  21474     uint32                    mode=0;
  21475     LOG_CLI((BSL_META_U(unit,
  21476                         "#####################  INGRESS  #########################\n")));
  21477     LOG_CLI((BSL_META_U(unit,
  21478                         "Mode:\t\tReference_Count\t\tTotal_Counters\t\tGroup_Mode \n")));
  21479     for (mode=0;mode<BCM_STAT_FLEX_COUNTER_MAX_MODE;mode++) {
  21480          if (flex_ingress_modes[unit][mode].available) {
  21481              LOG_CLI((BSL_META_U(unit,
  21482                                  "%u\t\t%u\t\t%u\t\t%s\n"), mode,
  21483                       flex_ingress_modes[unit][mode].reference_count,
  21484                       flex_ingress_modes[unit][mode].total_counters,
  21485                       flex_group_modes[flex_ingress_modes[unit][mode].
  21486                       group_mode]));
  21487          } else {
  21488              LOG_CLI((BSL_META_U(unit,
  21489                                  "%u===UNCONFIGURED====\n"), mode));
  21490          }
  21491     }
  21492     LOG_CLI((BSL_META_U(unit,
  21493                         "#####################  EGRESS  ##########################\n")));
  21494     LOG_CLI((BSL_META_U(unit,
  21495                         "Mode:\t\tReference_Count\t\tTotal_Counters\t\tGroup_Mode \n")));
  21496     for (mode=0;mode<BCM_STAT_FLEX_COUNTER_MAX_MODE;mode++) {
  21497          if (flex_egress_modes[unit][mode].available) {
  21498              LOG_CLI((BSL_META_U(unit,
  21499                                  "%u\t\t%u\t\t%u\t\t%s\n"), mode,
  21500                       flex_egress_modes[unit][mode].reference_count,
  21501                       flex_egress_modes[unit][mode].total_counters,
  21502                       flex_group_modes[flex_egress_modes[unit][mode].group_mode]));
  21503          } else {
  21504              LOG_CLI((BSL_META_U(unit,
  21505                                  "%u===UNCONFIGURED====\n"), mode));
  21506          }
  21507     }
  21508 }
  21509 /*
  21510  * Function:
  21511  *      _bcm_esw_stat_flex_get_ingress_object
  21512  * Description:
  21513  *      Get Ingress Object  corresponding to given Ingress Flex Table
  21514  * Parameters:
  21515  *      ingress_table                  - (IN) Flex Ingress Table
  21516  *      object                         - (OUT) Flex Ingress Object
  21517  * Return Value:
  21518  *      BCM_E_XXX
  21519  * Notes:
  21520  */
  21521 bcm_error_t _bcm_esw_stat_flex_get_ingress_object(
  21522             int               unit,
  21523             soc_mem_t         ingress_table,
  21524             uint32            table_index,
  21525             void              *ingress_entry,
  21526             bcm_stat_object_t *object)
  21527 {
  21528     soc_mem_info_t *memp;
  21529     void           *entry=NULL;
  21530     uint32         ingress_entry_data_size=0;
  21531     uint32         key_type = 0;
  21532 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  21533     uint32         mem_view_id = 0;
  21534 #endif
  21535 #if defined(BCM_TRIDENT3_SUPPORT)
  21536     soc_flow_db_mem_view_info_t mem_view_info;
  21537 
  21538     if ((soc_feature(unit,soc_feature_flex_flow)) &&
  21539         (soc_flow_db_mem_view_is_valid(unit, ingress_table))) {
  21540         /* when ingress_table is view_id perform below else
  21541          */
  21542         mem_view_id = ingress_table;
  21543         BCM_IF_ERROR_RETURN(soc_flow_db_mem_view_info_get(unit, mem_view_id,
  21544                                       &mem_view_info));
  21545         ingress_table = mem_view_info.mem;
  21546         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  21547                     (BSL_META_U(unit,
  21548                     "View ID %d mem_id %d\n"),
  21549                      mem_view_id, ingress_table));
  21550         memp = &SOC_MEM_INFO(unit, ingress_table);
  21551     } else
  21552 #endif
  21553     {
  21554     memp = &SOC_MEM_INFO(unit, ingress_table);
  21555 
  21556     if (memp->flags & SOC_MEM_FLAG_MULTIVIEW) {
  21557         if (ingress_entry != NULL) {
  21558             entry = ingress_entry;
  21559         } else {
  21560             ingress_entry_data_size = WORDS2BYTES(BYTES2WORDS(
  21561                                       SOC_MEM_INFO(unit, ingress_table).bytes));
  21562             entry = sal_alloc(ingress_entry_data_size,"ingress_table");
  21563             if (entry == NULL) {
  21564                 return BCM_E_MEMORY;
  21565             }
  21566             if (soc_mem_read(unit, ingress_table, MEM_BLOCK_ANY,table_index,
  21567                              entry) != SOC_E_NONE) {
  21568                 sal_free(entry);
  21569                 return BCM_E_INTERNAL;
  21570             }
  21571         }
  21572         if (soc_mem_field_valid(unit, ingress_table, KEY_TYPEf)) {
  21573             soc_mem_field_get(unit, ingress_table, entry, KEY_TYPEf, &key_type);
  21574         } else if (soc_mem_field_valid(unit, ingress_table, KEY_TYPE_0f)) {
  21575             soc_mem_field_get(unit, ingress_table, entry,
  21576                               KEY_TYPE_0f, &key_type);
  21577         } else if (soc_mem_field_valid(unit, ingress_table,ENTRY_TYPEf)) {
  21578             soc_mem_field_get(unit, ingress_table, entry,
  21579                               ENTRY_TYPEf, &key_type);
  21580         }
  21581         if (ingress_entry == NULL) {
  21582             sal_free(entry);
  21583         }
  21584     }
  21585     }
  21586     switch(ingress_table) {
  21587     case PORT_TABm:
  21588 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  21589     case LPORT_TABm:
  21590 #endif
  21591          *object=bcmStatObjectIngPort;
  21592          break;
  21593     case VLAN_TABm:
  21594          *object=bcmStatObjectIngVlan;
  21595          break;
  21596     case VLAN_XLATEm:
  21597 #if defined (BCM_TRIDENT3_SUPPORT)
  21598     case VLAN_XLATE_1_DOUBLEm:
  21599     case VLAN_XLATE_2_DOUBLEm:
  21600         if ((soc_feature(unit,soc_feature_flex_flow)) && (mem_view_id)) {
  21601             *object = bcmStatObjectIngVlanXlate;
  21602             break;
  21603         }
  21604 #endif
  21605 #if defined(BCM_TRIDENT2_SUPPORT)
  21606          if (sal_strcmp(memp->views[key_type],"VXLAN_DIP")  == 0) {
  21607              *object = bcmStatObjectIngVxlanDip;
  21608          } else
  21609 #endif /* BCM_TRIDENT2_SUPPORT */
  21610          if (sal_strcmp(memp->views[key_type],"L2GRE_DIP")  == 0) {
  21611              *object = bcmStatObjectIngL2Gre;
  21612          } else {
  21613              *object=bcmStatObjectIngVlanXlate;
  21614          }
  21615          break;
  21616 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  21617     case MPLS_ENTRY_SINGLEm:
  21618 #if defined(BCM_TOMAHAWK3_SUPPORT)
  21619         if (SOC_IS_TOMAHAWK3(unit)) {
  21620             *object = bcmStatObjectIngMplsSwitchLabel;
  21621         } else
  21622 #endif /* BCM_TOMAHAWK3_SUPPORT */
  21623         {
  21624             *object = bcmStatObjectIngVxlanDip;
  21625         }
  21626         break;
  21627 #endif /* BCM_TRIDENT3_SUPPORT or BCM_TOMAHAWK3_SUPPORT */
  21628 #if defined(BCM_TRIUMPH3_SUPPORT)
  21629     case VLAN_XLATE_EXTDm:
  21630          *object=bcmStatObjectIngVlanXlate;
  21631          break;
  21632 #endif
  21633     case VFIm:
  21634         *object=bcmStatObjectIngVfi;
  21635         break;
  21636     case L3_IIFm:
  21637          *object=bcmStatObjectIngL3Intf;
  21638          break;
  21639     case VRFm:
  21640 #if defined (BCM_TRIDENT3_SUPPORT)
  21641     case VRF_ATTRS_2m:
  21642 #endif
  21643          *object=bcmStatObjectIngVrf;
  21644          break;
  21645     case SOURCE_VPm:
  21646 #if defined(BCM_TRIDENT3_SUPPORT) & defined(INCLUDE_L3)
  21647         if ((soc_feature(unit,soc_feature_flex_flow)) &&
  21648             (_bcm_vp_used_get(unit, table_index, _bcmVpTypeFlow))) {
  21649             *object = bcmStatObjectIngGport;
  21650             break;
  21651         }
  21652 #endif
  21653 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  21654         if (_bcm_vp_used_get(unit, table_index,_bcmVpTypeL2Gre)) {
  21655              *object = bcmStatObjectIngL2Gre;
  21656         } else if (_bcm_vp_used_get(unit, table_index,_bcmVpTypeVxlan)) {
  21657             *object=bcmStatObjectIngVxlan;
  21658         } else if (_bcm_vp_used_get(unit, table_index,_bcmVpTypeNiv)) {
  21659             *object=bcmStatObjectIngNiv;
  21660         } else
  21661 #endif
  21662         {
  21663             *object=bcmStatObjectIngMplsVcLabel;
  21664         }
  21665          break;
  21666     case MPLS_ENTRYm:
  21667          *object=bcmStatObjectIngMplsSwitchLabel;
  21668          break;
  21669 #if defined(BCM_TRIUMPH3_SUPPORT)
  21670     case MPLS_ENTRY_EXTDm:
  21671          if (sal_strcmp(memp->views[key_type],"TRILL") == 0) {
  21672              *object=bcmStatObjectIngTrill;
  21673          } else if (sal_strcmp(memp->views[key_type],"MIM_ISID") == 0) {
  21674              *object=bcmStatObjectIngMimLookupId;
  21675          } else {
  21676              *object=bcmStatObjectIngMplsSwitchLabel;
  21677          }
  21678          break;
  21679 #endif
  21680     case VFP_POLICY_TABLEm:
  21681     case VFP_POLICY_TABLE_PIPE0m:
  21682     case VFP_POLICY_TABLE_PIPE1m:
  21683     case VFP_POLICY_TABLE_PIPE2m:
  21684     case VFP_POLICY_TABLE_PIPE3m:
  21685     case VFP_POLICY_TABLE_PIPE4m:
  21686     case VFP_POLICY_TABLE_PIPE5m:
  21687     case VFP_POLICY_TABLE_PIPE6m:
  21688     case VFP_POLICY_TABLE_PIPE7m:
  21689          *object=bcmStatObjectIngPolicy;
  21690          break;
  21691     case EXT_FP_POLICYm:
  21692          *object=bcmStatObjectIngEXTPolicy;
  21693          break;
  21694     case L3_TUNNELm:
  21695          *object=bcmStatObjectIngMplsFrrLabel;
  21696          break;
  21697     case L3_ENTRY_2m:
  21698          *object=bcmStatObjectIngL3Host;
  21699          break;
  21700     case L3_ENTRY_4m:
  21701          *object=bcmStatObjectIngL3Host;
  21702          break;
  21703     case EXT_IPV4_UCAST_WIDEm:
  21704          *object=bcmStatObjectIngL3Host;
  21705          break;
  21706     case EXT_IPV6_128_UCAST_WIDEm:
  21707          *object=bcmStatObjectIngL3Host;
  21708          break;
  21709 #if defined(BCM_TRIDENT2_SUPPORT)
  21710     case ING_VSANm:
  21711         if (SOC_IS_TD2_TT2(unit)) {
  21712             *object = bcmStatObjectIngVsan;
  21713         }
  21714          break;
  21715     case L3_ENTRY_IPV4_MULTICASTm:
  21716 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  21717     case L3_ENTRY_DOUBLEm:
  21718          if ((soc_feature(unit,soc_feature_flex_flow)) && (mem_view_id)) {
  21719              *object = bcmStatObjectIngL3Host;
  21720              break;
  21721          }
  21722 #endif
  21723         if (SOC_IS_TD2_TT2(unit)) {
  21724             if (sal_strcmp(memp->views[key_type],"FCOE_EXT") == 0) {
  21725                 *object=bcmStatObjectIngFcoe;
  21726             } else if (sal_strcmp(memp->views[key_type],"IPV4UC_EXT") == 0) {
  21727                 *object=bcmStatObjectIngL3Host;
  21728             } else if (sal_strcmp(memp->views[key_type],"IPV4MC") == 0) {
  21729                 *object=bcmStatObjectIngIpmc;
  21730             }
  21731         }
  21732          break;
  21733     case L3_ENTRY_IPV6_MULTICASTm:
  21734 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  21735     case L3_ENTRY_QUADm:
  21736          if ((soc_feature(unit,soc_feature_flex_flow)) && (mem_view_id)) {
  21737              *object = bcmStatObjectIngL3Host;
  21738              break;
  21739          }
  21740 #endif
  21741         if (SOC_IS_TD2_TT2(unit)) {
  21742             if (sal_strcmp(memp->views[key_type],"IPV6UC_EXT") == 0) {
  21743                 *object=bcmStatObjectIngL3Host;
  21744             } else if (sal_strcmp(memp->views[key_type],"IPV6MC") == 0) {
  21745                 *object=bcmStatObjectIngIpmc;
  21746             }
  21747         }
  21748          break;
  21749     case L3_DEFIPm:
  21750     case L3_DEFIP_PAIR_128m:
  21751     case L3_DEFIP_LEVEL1m:
  21752     case L3_DEFIP_PAIR_LEVEL1m:
  21753     case L3_DEFIP_ALPM_LEVEL2m:
  21754     case L3_DEFIP_ALPM_LEVEL3m:
  21755     case L3_DEFIP_ALPM_RAWm:
  21756     case L3_DEFIP_ALPM_IPV4_1m:
  21757     case L3_DEFIP_ALPM_IPV6_64_1m:
  21758     case L3_DEFIP_ALPM_IPV6_128m:
  21759         if (SOC_IS_TD2_TT2(unit)) {
  21760             *object = bcmStatObjectIngL3Route;
  21761         }
  21762          break;
  21763 #endif /* BCM_TRIDENT2_SUPPORT */
  21764 
  21765 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  21766     case FP_POLICY_TABLEm:
  21767          if (SOC_IS_TD2P_TT2P(unit)) {
  21768              *object = bcmStatObjectIngFieldStageIngress;
  21769          }
  21770          break;
  21771 #endif
  21772 #if defined (BCM_TOMAHAWK_SUPPORT)
  21773     case IFP_POLICY_TABLEm:
  21774          if (SOC_IS_TOMAHAWKX(unit)) {
  21775              *object = bcmStatObjectIngFieldStageIngress;
  21776          }
  21777          break;
  21778     case IFP_POLICY_TABLE_PIPE0m:
  21779     case IFP_POLICY_TABLE_PIPE1m:
  21780         if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TRIDENT3X(unit)) {
  21781              *object = bcmStatObjectIngFieldStageIngress;
  21782          }
  21783          break;
  21784     case IFP_POLICY_TABLE_PIPE2m:
  21785     case IFP_POLICY_TABLE_PIPE3m:
  21786     case IFP_POLICY_TABLE_PIPE4m:
  21787     case IFP_POLICY_TABLE_PIPE5m:
  21788     case IFP_POLICY_TABLE_PIPE6m:
  21789     case IFP_POLICY_TABLE_PIPE7m:
  21790          if (SOC_IS_TOMAHAWKX(unit)) {
  21791              *object = bcmStatObjectIngFieldStageIngress;
  21792          }
  21793          break;
  21794     case EXACT_MATCH_2m:
  21795     case EXACT_MATCH_2_PIPE0m:
  21796     case EXACT_MATCH_2_PIPE1m:
  21797     case EXACT_MATCH_2_PIPE2m:
  21798     case EXACT_MATCH_2_PIPE3m:
  21799     case EXACT_MATCH_4m:
  21800     case EXACT_MATCH_4_PIPE0m:
  21801     case EXACT_MATCH_4_PIPE1m:
  21802     case EXACT_MATCH_4_PIPE2m:
  21803     case EXACT_MATCH_4_PIPE3m:
  21804          if (SOC_IS_TOMAHAWKX(unit)) {
  21805              *object = bcmStatObjectIngExactMatch;
  21806          }
  21807          break;
  21808     case AGM_MONITOR_TABLEm:
  21809          if (SOC_IS_TOMAHAWKX(unit) ||SOC_IS_TRIDENT3X(unit)) {
  21810              *object = bcmIntStatObjectIngAgm;
  21811          }
  21812          break;
  21813 #endif
  21814 
  21815     default:
  21816          return BCM_E_INTERNAL;
  21817     }
  21818     return BCM_E_NONE;
  21819 }
  21820 /*
  21821  * Function:
  21822  *      _bcm_esw_stat_flex_get_egress_object
  21823  * Description:
  21824  *      Get Egress Object  corresponding to given Egress Flex Table
  21825  * Parameters:
  21826  *      egress_table                   - (IN) Flex Egress Table
  21827  *      object                         - (OUT) Flex Egress Object
  21828  *
  21829  * Return Value:
  21830  *      BCM_E_XXX
  21831  * Notes:
  21832  */
  21833 bcm_error_t _bcm_esw_stat_flex_get_egress_object(
  21834             int               unit,
  21835             soc_mem_t         egress_table,
  21836             uint32            table_index,
  21837             void              *egress_entry,
  21838             bcm_stat_object_t *object)
  21839 {
  21840     soc_mem_info_t *memp;
  21841     void           *entry=NULL;
  21842     uint32         egress_entry_data_size=0;
  21843     uint32         key_type = 0;
  21844 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  21845     uint32         dvp = 0;
  21846 #endif
  21847 #if defined(BCM_TRIDENT3_SUPPORT)
  21848     uint32         mem_view_id = 0;
  21849     soc_flow_db_mem_view_info_t mem_view_info;
  21850 
  21851     if ((soc_feature(unit,soc_feature_flex_flow)) &&
  21852         (soc_flow_db_mem_view_is_valid(unit, egress_table))) {
  21853         /* when ingress_table is view_id perform below else
  21854          */
  21855         mem_view_id = egress_table;
  21856         BCM_IF_ERROR_RETURN(soc_flow_db_mem_view_info_get(unit, mem_view_id,
  21857                                       &mem_view_info));
  21858 
  21859         egress_table = mem_view_info.mem;
  21860         LOG_VERBOSE(BSL_LS_BCM_FLEXCTR,
  21861                     (BSL_META_U(unit,
  21862                     "View ID %d mem_id %d\n"),
  21863                      mem_view_id, egress_table));
  21864         memp = &SOC_MEM_INFO(unit, egress_table);
  21865     } else
  21866 #endif
  21867     {
  21868     memp = &SOC_MEM_INFO(unit, egress_table);
  21869 
  21870     if (memp->flags & SOC_MEM_FLAG_MULTIVIEW) {
  21871         if (egress_entry != NULL) {
  21872             entry = egress_entry;
  21873         } else {
  21874             egress_entry_data_size = WORDS2BYTES(BYTES2WORDS(
  21875                                       SOC_MEM_INFO(unit, egress_table).bytes));
  21876             entry = sal_alloc(egress_entry_data_size,"egress_table");
  21877             if (entry == NULL) {
  21878                 return BCM_E_MEMORY;
  21879             }
  21880             if (soc_mem_read(unit, egress_table, MEM_BLOCK_ANY,table_index,
  21881                              entry) != SOC_E_NONE) {
  21882                 sal_free(entry);
  21883                 return BCM_E_INTERNAL;
  21884             }
  21885         }
  21886 
  21887         if (soc_mem_field_valid(unit, egress_table, KEY_TYPEf)) {
  21888                 soc_mem_field_get(unit, egress_table,
  21889                                    entry, KEY_TYPEf, &key_type);
  21890         } else if (soc_mem_field_valid(unit, egress_table, KEY_TYPE_0f)) {
  21891             soc_mem_field_get(unit, egress_table, entry,
  21892                               KEY_TYPE_0f, &key_type);
  21893         } else if (soc_mem_field_valid(unit, egress_table,ENTRY_TYPEf)) {
  21894             soc_mem_field_get(unit, egress_table, entry,
  21895                               ENTRY_TYPEf, &key_type);
  21896         }
  21897 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  21898         if (egress_table == EGR_L3_NEXT_HOPm) {
  21899 #if defined(BCM_TRIDENT3_SUPPORT)
  21900             if (soc_mem_field_valid(unit, egress_table, DATA_TYPEf)) {
  21901                     soc_mem_field_get(unit, egress_table, entry, DATA_TYPEf,
  21902                             &key_type);
  21903             }
  21904             if (key_type == _BCM_VXLAN_EGR_NEXT_HOP_L2OTAG_VIEW) {
  21905                 soc_mem_field_get(unit, egress_table, entry, L2_OTAG__DVPf,
  21906                         &dvp);
  21907             } else
  21908 #endif
  21909             if ((sal_strcmp(memp->views[key_type],"SD_TAG") == 0)) {
  21910                 soc_mem_field_get(unit, egress_table, entry, SD_TAG__DVPf,
  21911                         &dvp);
  21912             }
  21913         }
  21914 #endif
  21915         if (egress_entry == NULL) {
  21916             sal_free(entry);
  21917         }
  21918     }
  21919     }
  21920     switch(egress_table) {
  21921     case EGR_PORTm:
  21922 #if defined(BCM_TRIDENT3_SUPPORT)
  21923     case EGR_LPORT_PROFILEm:
  21924 #endif
  21925          *object=bcmStatObjectEgrPort;
  21926          break;
  21927     case EGR_VLANm:
  21928          *object=bcmStatObjectEgrVlan;
  21929          break;
  21930     case EGR_VLAN_XLATEm:
  21931 #if defined(BCM_TRIDENT3_SUPPORT)
  21932     case EGR_VLAN_XLATE_1_DOUBLEm:
  21933     case EGR_VLAN_XLATE_2_DOUBLEm:
  21934          if ((soc_feature(unit,soc_feature_flex_flow)) &&
  21935              (mem_view_id)) {
  21936              *object=bcmStatObjectEgrVlanXlate;
  21937              break;
  21938          }
  21939         if ((egress_table == EGR_VLAN_XLATE_2_DOUBLEm) && (key_type > 16)) {
  21940             /* In TD3X, key_type for flex view in EGR_VLAN_XLATE_2_DOUBLE starts
  21941              * after 16. Flex view does not have Flex counters.
  21942              */
  21943             return BCM_E_INTERNAL;
  21944         }
  21945 #endif
  21946          if (sal_strcmp(memp->views[key_type],"MIM_ISID") == 0) {
  21947              *object=bcmStatObjectEgrMimLookupId;
  21948          } else {
  21949              *object=bcmStatObjectEgrVlanXlate;
  21950          }
  21951          break;
  21952     case EGR_VFIm:
  21953          *object=bcmStatObjectEgrVfi;
  21954          break;
  21955     case EGR_L3_NEXT_HOPm:
  21956 #if defined(BCM_TRIDENT3_SUPPORT)  && defined(INCLUDE_L3)
  21957          if ((soc_feature(unit,soc_feature_flex_flow)) && (mem_view_id)) {
  21958              *object=bcmStatObjectEgrL3Intf;
  21959              break;
  21960          }
  21961 
  21962          if (key_type == _BCM_VXLAN_EGR_NEXT_HOP_L2OTAG_VIEW) {
  21963              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  21964                        (BSL_META_U(unit,
  21965                                    "L2_OTAG view\n")));
  21966              if (_bcm_vp_used_get(unit, dvp,_bcmVpTypeVxlan)) {
  21967                  *object=bcmStatObjectEgrVxlan;
  21968              } else if (_bcm_vp_used_get(unit, dvp,_bcmVpTypeNiv)) {
  21969                  *object=bcmStatObjectEgrNiv;
  21970              } else {
  21971                  *object=bcmStatObjectEgrL3Intf;
  21972              }
  21973              break;
  21974           }
  21975 
  21976 #endif
  21977          if (sal_strcmp(memp->views[key_type],"WLAN") == 0) {
  21978              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  21979                        (BSL_META_U(unit,
  21980                                    "WLAN view")));
  21981              *object=bcmStatObjectEgrWlan;
  21982          } else if (sal_strcmp(memp->views[key_type],"MIM") == 0) {
  21983              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  21984                        (BSL_META_U(unit,
  21985                                    "MIM view")));
  21986              *object=bcmStatObjectEgrMim;
  21987         }
  21988 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  21989         else if (sal_strcmp(memp->views[key_type],"SD_TAG") == 0) {
  21990             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  21991                       (BSL_META_U(unit,
  21992                                   "SD_TAG view\n")));
  21993             if (_bcm_vp_used_get(unit, dvp,_bcmVpTypeVxlan)) {
  21994                 *object=bcmStatObjectEgrVxlan;
  21995             } else if (_bcm_vp_used_get(unit, dvp,_bcmVpTypeNiv)) {
  21996                 *object=bcmStatObjectEgrNiv;
  21997             } else {
  21998                 *object=bcmStatObjectEgrL3Intf;
  21999             }
  22000          }
  22001 #endif
  22002 		 else {
  22003              LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  22004                        (BSL_META_U(unit,
  22005                                    "Other view %s \n"),
  22006                         memp->views[key_type]));
  22007              *object=bcmStatObjectEgrL3Intf;
  22008          }
  22009 
  22010          break;
  22011     case EGR_DVP_ATTRIBUTE_1m:
  22012 #if defined(BCM_TRIDENT3_SUPPORT)
  22013     case EGR_DVP_ATTRIBUTEm:
  22014         if ((soc_feature(unit,soc_feature_flex_flow)) && (mem_view_id)) {
  22015             *object = bcmStatObjectEgrDvpAttr;
  22016             break;
  22017         } else
  22018 #endif
  22019         egress_table = EGR_DVP_ATTRIBUTEm;
  22020         memp = &SOC_MEM_INFO(unit, egress_table);
  22021         if (memp->flags & SOC_MEM_FLAG_MULTIVIEW) {
  22022             egress_entry_data_size = WORDS2BYTES(BYTES2WORDS(
  22023                                       SOC_MEM_INFO(unit, egress_table).bytes));
  22024             entry = sal_alloc(egress_entry_data_size,"egress_table");
  22025             if (entry == NULL) {
  22026                 return BCM_E_MEMORY;
  22027             }
  22028             if (soc_mem_read(unit, egress_table, MEM_BLOCK_ANY,table_index,
  22029                              entry) != SOC_E_NONE) {
  22030                 sal_free(entry);
  22031                 return BCM_E_INTERNAL;
  22032             }
  22033 
  22034 #if defined (BCM_TRIDENT3_SUPPORT)
  22035             if (soc_mem_field_valid(unit, egress_table, DATA_TYPEf)) {
  22036                 soc_mem_field_get(unit, egress_table, entry, DATA_TYPEf, &key_type);
  22037             } else
  22038 #endif
  22039             if (soc_mem_field_valid(unit, egress_table, VP_TYPEf)) {
  22040                 soc_mem_field_get(unit, egress_table, entry, VP_TYPEf, &key_type);
  22041             }
  22042             sal_free(entry);
  22043         }
  22044 #if defined(BCM_TRIDENT2_SUPPORT)
  22045          if (sal_strcmp(memp->views[key_type],"VXLAN") == 0) {
  22046             *object = bcmStatObjectEgrVxlan;
  22047          } else
  22048 #endif /* BCM_TRIDENT2_SUPPORT */
  22049          if (sal_strcmp(memp->views[key_type],"L2GRE") == 0) {
  22050             *object = bcmStatObjectEgrL2Gre;
  22051          } else {
  22052                 return BCM_E_INTERNAL;
  22053          }
  22054          break;
  22055 #if defined(BCM_TRIDENT2_SUPPORT)
  22056     case  EGR_NAT_PACKET_EDIT_INFOm:
  22057         if (SOC_IS_TD2_TT2(unit)) {
  22058             *object = bcmStatObjectEgrL3Nat;
  22059         }
  22060         break;
  22061 #endif /* BCM_TRIDENT2_SUPPORT */
  22062 #if defined(BCM_TRIDENT2PLUS_SUPPORT)                 
  22063     case  EFP_POLICY_TABLEm:    
  22064 #if defined(BCM_TRIDENT3_SUPPORT)                      
  22065     case  EFP_POLICY_TABLE_PIPE0m:                          
  22066     case  EFP_POLICY_TABLE_PIPE1m:
  22067 #endif /* BCM_TRIDENT3_SUPPORT */                          
  22068         if (SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit) || SOC_IS_TRIDENT3X(unit)) {
  22069             *object = bcmStatObjectEgrFieldStageEgress;
  22070         } else {                                      
  22071              return BCM_E_INTERNAL;
  22072         }                                             
  22073         break;                                        
  22074     case  EGR_IP_TUNNEL_MPLSm:                        
  22075         if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
  22076             *object = bcmStatObjectEgrMplsTunnelLabel;
  22077         } else {                                      
  22078              return BCM_E_INTERNAL;                   
  22079         }                                             
  22080         break;                                        
  22081 #endif /* BCM_TRIDENT2_SUPPORT */
  22082 #if defined(BCM_TRIDENT3_SUPPORT)
  22083     case  EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm:
  22084         if (SOC_IS_TRIDENT3X(unit) &&
  22085             soc_feature(unit, soc_feature_td3_style_mpls)) {
  22086             *object = bcmStatObjectEgrMplsTunnelLabel;
  22087         } else {
  22088              return BCM_E_INTERNAL;
  22089         }
  22090         break;
  22091 #endif
  22092     default:
  22093          return BCM_E_INTERNAL;
  22094     }
  22095     return BCM_E_NONE;
  22096 }
  22097 /*
  22098  * Function:
  22099  *      _bcm_esw_stat_flex_get_counter_id
  22100  * Description:
  22101  *      Get Stat Counter Id for given accounting table and index
  22102  * Parameters
  22103  *      unit                  - (IN) unit number
  22104  *      num_of_tables         - (IN) Number of Accounting Tables
  22105  *      table_info            - (IN) Tables Info(Name,direction and index)
  22106  *      num_stat_counter_ids  - (OUT) Number of Stat Counter Ids
  22107  *      stat_counter_id       - (OUT) Stat Counter Ids
  22108  * Return Value:
  22109  *      BCM_E_XXX
  22110  * Notes:
  22111  */
  22112 bcm_error_t _bcm_esw_stat_flex_get_counter_id(
  22113             int                        unit,
  22114             uint32                     num_of_tables,
  22115             bcm_stat_flex_table_info_t *table_info,
  22116             uint32                     *num_stat_counter_ids,
  22117             uint32                     *stat_counter_id)
  22118 {
  22119     int                        index=0;
  22120     uint32                     offset_mode=0;
  22121     uint32                     pool_number=0;
  22122     uint32                     base_idx=0;
  22123     void                       *entry_data=NULL;
  22124     uint32                     entry_data_size=0;
  22125     bcm_stat_object_t          object=bcmStatObjectIngPort;
  22126     bcm_stat_group_mode_t      group= bcmStatGroupModeSingle;
  22127     uint32                     exact_index=0;
  22128 #if defined(BCM_TRIDENT3_SUPPORT)
  22129     uint32 entry[SOC_MAX_MEM_WORDS];
  22130 #endif /* BCM_TRIDENT3_SUPPORT */
  22131 
  22132     if ((num_stat_counter_ids == NULL) || (stat_counter_id == NULL)) {
  22133         return BCM_E_PARAM;
  22134     }
  22135 
  22136     exact_index = table_info[index].index;
  22137     if (table_info[index].table == EGR_IP_TUNNEL_MPLSm) {
  22138         table_info[index].index =
  22139         table_info[index].index / _BCM_MPLS_NUM_MPLS_ENTRIES_PER_INDEX(unit);
  22140     }
  22141 
  22142     for (index=0;index < num_of_tables ;index++) {
  22143 #if defined(BCM_TRIDENT3_SUPPORT)
  22144         if ((soc_feature(unit,soc_feature_flex_flow)) &&
  22145             (soc_flow_db_mem_view_is_valid(unit, table_info[index].table))) {
  22146             /* when ingress_table is view_id perform below else
  22147              */
  22148             sal_memset(entry, 0, sizeof(entry));
  22149             if (soc_mem_read(unit, table_info[index].table, MEM_BLOCK_ANY,
  22150                       _bcm_esw_stat_flex_table_index_map(unit,
  22151                       table_info[index].table,
  22152                       table_info[index].index), entry) == SOC_E_NONE) {
  22153                 if (soc_flow_db_mem_view_entry_is_valid(unit,
  22154                                             table_info[index].table,
  22155                                             entry) == FALSE) {
  22156                      continue;
  22157                 }
  22158                 if (table_info[index].direction ==
  22159                     bcmStatFlexDirectionIngress) {
  22160                     if (_bcm_esw_stat_flex_get_ingress_object(unit,
  22161                              table_info[index].table,table_info[index].index,
  22162                              entry, &object) != BCM_E_NONE) {
  22163                         return BCM_E_NONE;
  22164                     }
  22165                     group=flex_ingress_modes[unit][offset_mode].group_mode;
  22166                 } else {
  22167                     if (_bcm_esw_stat_flex_get_egress_object(unit,
  22168                              table_info[index].table,table_info[index].index,
  22169                             entry, &object) != BCM_E_NONE) {
  22170                         return BCM_E_NONE;
  22171                     }
  22172                     group=flex_egress_modes[unit][offset_mode].group_mode;
  22173                 }
  22174 
  22175                 _bcm_esw_get_flex_counter_fields_values(
  22176                             unit, exact_index,table_info[index].table,
  22177                             entry, object, &offset_mode, &pool_number, &base_idx);
  22178                 if ((offset_mode == 0) && (base_idx == 0)) {
  22179                      continue;
  22180                  }
  22181                 _bcm_esw_stat_counter_id_retrieve(
  22182                                             unit, group, object,
  22183                                             offset_mode, pool_number, base_idx,
  22184                                             &stat_counter_id[index]);
  22185                 (*num_stat_counter_ids)++;
  22186             }
  22187         } else
  22188 #endif
  22189         {
  22190         entry_data_size = WORDS2BYTES(BYTES2WORDS(
  22191                        SOC_MEM_INFO(unit,table_info[index].table).bytes));
  22192         entry_data = sal_alloc(entry_data_size,"vrf_table");
  22193         if (entry_data == NULL) {
  22194             return BCM_E_MEMORY;
  22195         }
  22196         sal_memset(entry_data,0,
  22197                 SOC_MEM_INFO(unit, table_info[index].table).bytes);
  22198         if (soc_mem_read(unit, table_info[index].table, MEM_BLOCK_ANY,
  22199                         _bcm_esw_stat_flex_table_index_map(unit,
  22200                         table_info[index].table,
  22201                         table_info[index].index), entry_data) == SOC_E_NONE) {
  22202             if (soc_mem_field_valid(unit,table_info[index].table,VALIDf)) {
  22203                 if (soc_mem_field32_get(unit,table_info[index].table,
  22204                     entry_data,VALIDf)==0) {
  22205                     sal_free(entry_data);
  22206                     continue;
  22207                 }
  22208             }
  22209             _bcm_esw_get_flex_counter_fields_values(
  22210                         unit, exact_index,table_info[index].table,
  22211                         entry_data,0,&offset_mode, &pool_number, &base_idx);
  22212             if ((offset_mode == 0) && (base_idx == 0)) {
  22213                 sal_free(entry_data);
  22214                 continue;
  22215             }
  22216 
  22217             if (table_info[index].direction == bcmStatFlexDirectionIngress) {
  22218                 if (_bcm_esw_stat_flex_get_ingress_object(
  22219                             unit,table_info[index].table,table_info[index].index,
  22220                             entry_data,&object) != BCM_E_NONE) {
  22221                     sal_free(entry_data);
  22222                     return BCM_E_NONE;
  22223                 }
  22224                 group=flex_ingress_modes[unit][offset_mode].group_mode;
  22225             } else {
  22226                 if (_bcm_esw_stat_flex_get_egress_object(
  22227                         unit,table_info[index].table,table_info[index].index,
  22228                         entry_data,&object) != BCM_E_NONE) {
  22229                     sal_free(entry_data);
  22230                     return BCM_E_NONE;
  22231                 }
  22232                 group=flex_egress_modes[unit][offset_mode].group_mode;
  22233             }
  22234             sal_free(entry_data);
  22235             _bcm_esw_stat_counter_id_retrieve(
  22236                                         unit, group,object,
  22237                                         offset_mode,pool_number,base_idx,
  22238                                         &stat_counter_id[index]);
  22239             (*num_stat_counter_ids)++;
  22240         }
  22241     }
  22242     }
  22243     if ((*num_stat_counter_ids) == 0) {
  22244          return BCM_E_NOT_FOUND;
  22245     }
  22246     return BCM_E_NONE;
  22247 }
  22248 
  22249 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined (INCLUDE_L3)
  22250 /*
  22251  * Function:
  22252  *      _bcm_esw_stat_flex_get_counter_id
  22253  * Description:
  22254  *      Get Stat Counter Id for given accounting table and index
  22255  * Parameters
  22256  *      unit                  - (IN) unit number
  22257  *      num_of_tables         - (IN) Number of Accounting Tables
  22258  *      table_info            - (IN) Tables Info(Name,direction and index)
  22259  *      num_stat_counter_ids  - (OUT) Number of Stat Counter Ids
  22260  *      stat_counter_id       - (OUT) Stat Counter Ids
  22261  * Return Value:
  22262  *      BCM_E_XXX
  22263  * Notes:
  22264  */
  22265 bcm_error_t _bcm_esw_stat_flex_get_multi_counter_id(
  22266         int                        unit,
  22267         bcm_stat_flex_table_info_t *table_info,
  22268         int                        *num_stat_counter_ids,
  22269         uint32                     *stat_counter_id)
  22270 {
  22271     int                        index=0;
  22272     int                        object_index=0;
  22273     int                        counter_index=0;
  22274     uint32                     offset_mode=0;
  22275     uint32                     pool_number=0;
  22276     uint32                     base_idx=0;
  22277     void                       *entry_data=NULL;
  22278     uint32                     entry_data_size=0;
  22279     bcm_stat_group_mode_t      group= bcmStatGroupModeSingle;
  22280     uint32                     exact_index=0;
  22281 
  22282     if (((*num_stat_counter_ids != -1) && (stat_counter_id == NULL)) ||
  22283         (*num_stat_counter_ids == 0)) {
  22284         return BCM_E_PARAM;
  22285     }
  22286     switch (table_info[index].table) {
  22287         case EGR_IP_TUNNEL_MPLSm:
  22288             exact_index = table_info[index].index;
  22289             table_info[index].index =
  22290                 table_info[index].index / _BCM_MPLS_NUM_MPLS_ENTRIES_PER_INDEX(unit);
  22291             entry_data_size = WORDS2BYTES(BYTES2WORDS(
  22292                         SOC_MEM_INFO(unit,table_info[index].table).bytes));
  22293             entry_data = sal_alloc(entry_data_size,"flex-counter-table");
  22294             if (entry_data == NULL) {
  22295                 return BCM_E_MEMORY;
  22296             }
  22297             sal_memset(entry_data,0,
  22298                     SOC_MEM_INFO(unit, table_info[index].table).bytes);
  22299             if (soc_mem_read(unit, table_info[index].table, MEM_BLOCK_ANY,
  22300                         _bcm_esw_stat_flex_table_index_map(unit,
  22301                             table_info[index].table,
  22302                             table_info[index].index), entry_data) == SOC_E_NONE) {
  22303                 if (soc_mem_field_valid(unit,table_info[index].table,VALIDf)) {
  22304                     if (soc_mem_field32_get(unit,table_info[index].table,
  22305                                 entry_data,VALIDf)==0) {
  22306                         sal_free(entry_data);
  22307                         return BCM_E_PARAM;
  22308                     }
  22309                 }
  22310             }
  22311 
  22312             for (object_index=0;object_index < ((sizeof(egr_mpls_tunnel_object)/
  22313                         sizeof(egr_mpls_tunnel_object[0])));object_index++) {
  22314                 _bcm_esw_get_flex_counter_fields_values(
  22315                         unit, exact_index,
  22316                         table_info[index].table,
  22317                         entry_data,egr_mpls_tunnel_object[object_index],
  22318                         &offset_mode, &pool_number, &base_idx);
  22319                 if ((offset_mode != 0) && (base_idx != 0)) {
  22320                     continue;
  22321                 }
  22322 
  22323                 group=flex_egress_modes[unit][offset_mode].group_mode;
  22324                 if (*num_stat_counter_ids != -1) {
  22325                     _bcm_esw_stat_get_counter_id(
  22326                             unit, group,egr_mpls_tunnel_object[object_index],
  22327                             offset_mode,pool_number,base_idx,
  22328                             &stat_counter_id[counter_index]);
  22329                 }
  22330                 counter_index++;
  22331                 if (*num_stat_counter_ids != -1 &&
  22332                     *num_stat_counter_ids == counter_index) {
  22333                     break;
  22334                 }
  22335             }
  22336             break;
  22337         default:
  22338             LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  22339                     (BSL_META_U(unit,
  22340                                 "Invalid Table is passed %d \n"),
  22341                      table_info[index].table));
  22342             sal_free(entry_data);
  22343             return BCM_E_INTERNAL;
  22344     }
  22345     sal_free(entry_data);
  22346     if (*num_stat_counter_ids == -1) {
  22347         *num_stat_counter_ids = counter_index;
  22348     } else if (counter_index != *num_stat_counter_ids) {
  22349         return BCM_E_PARAM;
  22350     }
  22351     return BCM_E_NONE;
  22352 }
  22353 #endif
  22354 
  22355 /*
  22356  * Function:
  22357  *      _bcm_esw_stat_get_ingress_object
  22358  * Description:
  22359  *      Get Ingress Object available in give table
  22360  * Parameters:
  22361  *      unit                  - (IN) unit number
  22362  *      pool_number           - (IN) Flex Pool number
  22363  *      num_objects           - (OUT) Number of Flex Object found in given pool
  22364  *      object                - (OUT) Flex Objects found in given pool
  22365  * Return Value:
  22366  *      BCM_E_XXX
  22367  * Notes:
  22368  *      For debuging purpose only
  22369  */
  22370 void _bcm_esw_stat_get_ingress_object(
  22371      int               unit,
  22372      uint32            pool_number,
  22373      uint32            *num_objects,
  22374      bcm_stat_object_t *object)
  22375 {
  22376      int index=0;
  22377      uint32            ingress_table_masks[]={
  22378                        FLEX_COUNTER_POOL_USED_BY_PORT_TABLE,
  22379                        FLEX_COUNTER_POOL_USED_BY_VFP_POLICY_TABLE,
  22380                        FLEX_COUNTER_POOL_USED_BY_VLAN_TABLE,
  22381                        FLEX_COUNTER_POOL_USED_BY_VFI_TABLE,
  22382                        FLEX_COUNTER_POOL_USED_BY_VRF_TABLE,
  22383                        FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE,
  22384                        FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE,
  22385                        FLEX_COUNTER_POOL_USED_BY_L3_IIF_TABLE,
  22386                        FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE,
  22387                        FLEX_COUNTER_POOL_USED_BY_SOURCE_VP_TABLE,
  22388                        FLEX_COUNTER_POOL_USED_BY_L3_TUNNEL_TABLE,
  22389                        FLEX_COUNTER_POOL_USED_BY_L3_ENTRY_TABLE,
  22390                        FLEX_COUNTER_POOL_USED_BY_EXT_FP_POLICY_TABLE,
  22391                        FLEX_COUNTER_POOL_USED_BY_FCOE_TABLE,
  22392                        FLEX_COUNTER_POOL_USED_BY_IFP_POLICY_TABLE,
  22393                        FLEX_COUNTER_POOL_USED_BY_AGM_MONITOR_TABLE,
  22394                        FLEX_COUNTER_POOL_USED_BY_AGM_MONITOR_TABLE_FOR_SCND_LKUP,
  22395                        FLEX_COUNTER_POOL_USED_BY_EM_POLICY_TABLE,
  22396                        FLEX_COUNTER_POOL_USED_BY_VLAN_XLATE_TABLE_FOR_SCND_LKUP,
  22397                        FLEX_COUNTER_POOL_USED_BY_MPLS_ENTRY_TABLE_FOR_SCND_LKUP
  22398      };
  22399      bcm_stat_object_t ingress_table_objects[]={
  22400                        bcmStatObjectIngPort,
  22401                        bcmStatObjectIngPolicy,
  22402                        bcmStatObjectIngVlan,
  22403                        bcmStatObjectIngVfi,
  22404                        bcmStatObjectIngVrf,
  22405                        bcmStatObjectIngMplsSwitchLabel,
  22406                        bcmStatObjectIngVlanXlate,
  22407                        bcmStatObjectIngL3Intf,
  22408                        bcmStatObjectIngMplsVcLabel,
  22409                        bcmStatObjectIngGport,
  22410                        bcmStatObjectIngMplsFrrLabel,
  22411                        bcmStatObjectIngL3Host,
  22412                        bcmStatObjectIngEXTPolicy,
  22413                        bcmStatObjectIngIpmc,
  22414                        bcmStatObjectIngFieldStageIngress,
  22415                        bcmIntStatObjectIngAgm,
  22416                        bcmIntStatObjectIngAgmSecondLookup,
  22417                        bcmStatObjectIngExactMatch,
  22418                        bcmStatObjectIngVlanXlateSecondLookup,
  22419                        bcmStatObjectIngMplsSwitchSecondLabel
  22420      };
  22421      *num_objects=0;
  22422      for(index=0;
  22423          index<sizeof(ingress_table_objects)/sizeof(ingress_table_objects[0]);
  22424          index++) {
  22425          if (flex_pool_stat[unit][bcmStatFlexDirectionIngress][0][pool_number].
  22426                            used_by_tables & ingress_table_masks[index]) {
  22427              object[*num_objects]=ingress_table_objects[index];
  22428              (*num_objects)++;
  22429          }
  22430      }
  22431 }
  22432 /*
  22433  * Function:
  22434  *      _bcm_esw_stat_get_egress_object
  22435  * Description:
  22436  *      Get Egress Object available in give table
  22437  * Parameters:
  22438  *      unit                  - (IN) unit number
  22439  *      pool_number           - (IN) Flex Pool number
  22440  *      num_objects           - (OUT) Number of Flex Object found in given pool
  22441  *      object                - (OUT) Flex Objects found in given pool
  22442  *
  22443  * Return Value:
  22444  *      BCM_E_XXX
  22445  * Notes:
  22446  *      For debuging purpose only
  22447  */
  22448 void _bcm_esw_stat_get_egress_object(
  22449      int               unit,
  22450      uint32            pool_number,
  22451      uint32            *num_objects,
  22452      bcm_stat_object_t *object)
  22453 {
  22454      int index=0;
  22455      uint32            egress_table_masks[]={
  22456                        FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_TABLE,
  22457                        FLEX_COUNTER_POOL_USED_BY_EGR_VFI_TABLE,
  22458                        FLEX_COUNTER_POOL_USED_BY_EGR_L3_NEXT_HOP_TABLE,
  22459                        FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE,
  22460                        FLEX_COUNTER_POOL_USED_BY_EGR_VLAN_XLATE_TABLE_FOR_SCND_LKUP,
  22461                        FLEX_COUNTER_POOL_USED_BY_EGR_PORT_TABLE,
  22462                        FLEX_COUNTER_POOL_USED_BY_EGR_DVP_ATTRIBUTE_1_TABLE,
  22463                        FLEX_COUNTER_POOL_USED_BY_EGR_DVP_ATTRIBUTE_1_TABLE,
  22464                        FLEX_COUNTER_POOL_USED_BY_EGR_L3_NAT_TABLE,
  22465                        FLEX_COUNTER_POOL_USED_BY_EGR_EFP_POLICY_TABLE,
  22466                        FLEX_COUNTER_POOL_USED_BY_EGR_IP_TUNNEL_MPLS_TABLE,
  22467                        FLEX_COUNTER_POOL_USED_BY_EGR_IP_TUNNEL_MPLS_SCND_LBL_TABLE
  22468      };
  22469      bcm_stat_object_t egress_table_objects[]={
  22470                        bcmStatObjectEgrVlan,
  22471                        bcmStatObjectEgrVfi,
  22472                        bcmStatObjectEgrL3Intf,
  22473                        bcmStatObjectEgrVlanXlate,
  22474                        bcmStatObjectEgrVlanXlateSecondLookup,
  22475                        bcmStatObjectEgrPort,
  22476                        bcmStatObjectEgrL2Gre,
  22477                        bcmStatObjectEgrVxlan,
  22478                        bcmStatObjectEgrL3Nat,         
  22479                        bcmStatObjectEgrFieldStageEgress,
  22480                        bcmStatObjectEgrMplsTunnelLabel,
  22481                        bcmStatObjectEgrMplsTunnelSecondLabel
  22482      };
  22483      *num_objects=0;
  22484      for(index=0;
  22485          index<sizeof(egress_table_objects)/sizeof(egress_table_objects[0]);
  22486          index++) {
  22487          if (flex_pool_stat[unit][bcmStatFlexDirectionEgress][0][pool_number].
  22488                            used_by_tables & egress_table_masks[index]) {
  22489              object[*num_objects]=egress_table_objects[index];
  22490              (*num_objects)++;
  22491          }
  22492      }
  22493 }
  22494 /*
  22495  * Function:
  22496  *      _bcm_esw_stat_validate_group
  22497  * Description:
  22498  *      Validates passed stat group
  22499  * Parameters:
  22500  *      unit                  - (IN) unit number
  22501  *      group                 - (IN) Flex Group Mode
  22502  * Return Value:
  22503  *      BCM_E_XXX
  22504  * Notes:
  22505  */
  22506 bcm_error_t _bcm_esw_stat_validate_group(
  22507             int                   unit,
  22508             bcm_stat_group_mode_t group)
  22509 {
  22510     if(!((group >= bcmStatGroupModeSingle) &&
  22511          (group <= (bcm_stat_group_mode_t) bcmStatGroupModeFlex4))) {
  22512           LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  22513                     (BSL_META_U(unit,
  22514                                 "Invalid bcm_stat_group_mode_t passed %d \n"),group));
  22515           return BCM_E_PARAM;
  22516     }
  22517     return BCM_E_NONE;
  22518 }
  22519 /*
  22520  * Function:
  22521  *      _bcm_esw_stat_total_counters_get
  22522  * Description:
  22523  *      Fetches total counters that have been created with the
  22524  *      given stat counter id
  22525  * Parameters:
  22526  *      unit                  - (IN)  unit number
  22527  *      stat_counter_id       - (IN)  Stat Counter Id
  22528  *      total_counters        - (OUT) Total Counters
  22529  * Return Value:
  22530  *      BCM_E_XXX
  22531  * Notes:
  22532  */
  22533 bcm_error_t _bcm_esw_stat_total_counters_get(
  22534             int    unit,
  22535             uint32 stat_counter_id,
  22536             uint32 *total_counters)
  22537 {
  22538     bcm_stat_flex_direction_t    direction = bcmStatFlexDirectionIngress;
  22539     uint32                       mode=0;
  22540     uint32                       base_index=0;
  22541     uint32                       pool_number=0;
  22542     bcm_error_t                  rv=BCM_E_NONE;
  22543     bcm_stat_group_mode_t        group_mode= bcmStatGroupModeSingle;
  22544     bcm_stat_object_t            object=bcmStatObjectIngPort;
  22545     bcm_stat_flex_ingress_mode_t *flex_ingress_mode=NULL;
  22546     bcm_stat_flex_egress_mode_t  *flex_egress_mode=NULL;
  22547 
  22548     _bcm_esw_stat_get_counter_id_info(unit, stat_counter_id,&group_mode,&object,
  22549                                       &mode,&pool_number,&base_index);
  22550     rv = _bcm_esw_stat_validate_object(unit,object,&direction);
  22551 
  22552     if (rv != BCM_E_NONE) {
  22553         return rv;
  22554     }
  22555     rv = _bcm_esw_stat_validate_group(unit,group_mode);
  22556     if (rv != BCM_E_NONE) {
  22557         return rv;
  22558     }
  22559     if (direction == bcmStatFlexDirectionIngress) {
  22560         flex_ingress_mode = sal_alloc(sizeof(bcm_stat_flex_ingress_mode_t),
  22561                                       "flex_ingress_mod");
  22562         if (flex_ingress_mode == NULL) {
  22563             return BCM_E_MEMORY;
  22564         }
  22565 
  22566         sal_memset(flex_ingress_mode, 0, sizeof(bcm_stat_flex_ingress_mode_t));
  22567 
  22568         rv = _bcm_esw_stat_flex_get_ingress_mode_info(
  22569                   unit,mode,flex_ingress_mode);
  22570         if (BCM_SUCCESS(rv)) {
  22571             *total_counters = flex_ingress_mode->total_counters;
  22572         }
  22573         sal_free(flex_ingress_mode);
  22574         BCM_IF_ERROR_RETURN(rv);
  22575      } else {
  22576         flex_egress_mode = sal_alloc(sizeof(bcm_stat_flex_egress_mode_t),
  22577                                       "flex_egress_mod");
  22578         if (flex_egress_mode == NULL) {
  22579             return BCM_E_MEMORY;
  22580         }
  22581 
  22582         sal_memset(flex_egress_mode, 0, sizeof(bcm_stat_flex_egress_mode_t));
  22583 
  22584         rv = _bcm_esw_stat_flex_get_egress_mode_info(
  22585                   unit,mode,flex_egress_mode);
  22586         if (BCM_SUCCESS(rv)) {
  22587             *total_counters = flex_egress_mode->total_counters;
  22588         }
  22589         sal_free(flex_egress_mode);
  22590         BCM_IF_ERROR_RETURN(rv);
  22591      }
  22592      return rv;
  22593 }
  22594 /*
  22595  * Function:
  22596  *      _bcm_esw_stat_validate_object
  22597  * Description:
  22598  *      Validates passed stat object and returns corresponding object's
  22599  *      direction
  22600  * Parameters:
  22601  *      unit                  - (IN) unit number
  22602  *      object                - (IN) Flex Accounting object
  22603  *      direction             - (OUT) Flex Object's direction
  22604  * Return Value:
  22605  *      BCM_E_XXX
  22606  * Notes:
  22607  */
  22608 bcm_error_t _bcm_esw_stat_validate_object(
  22609             int                       unit,
  22610             bcm_stat_object_t         object,
  22611             bcm_stat_flex_direction_t *direction)
  22612 {
  22613     if ((object >= bcmStatObjectIngPort) &&
  22614         (object <= bcmStatObjectIngMplsSwitchLabel)) {
  22615         *direction=bcmStatFlexDirectionIngress;
  22616         return BCM_E_NONE;
  22617     }
  22618 #if defined(BCM_TRIDENT2PLUS_SUPPORT)                 
  22619     if (SOC_IS_TRIDENT2PLUS(unit)  &&                 
  22620         (object == bcmStatObjectIngMplsFrrLabel)) {   
  22621         return BCM_E_PARAM;                           
  22622     }                                                 
  22623 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  22624 #if defined(BCM_KATANA2_SUPPORT)
  22625     if (SOC_IS_KATANA2(unit) && (object == bcmStatObjectIngMplsFrrLabel)) {
  22626         *direction=bcmStatFlexDirectionIngress;
  22627         return BCM_E_NONE;
  22628     }
  22629 #endif
  22630 #if defined(BCM_TRIUMPH3_SUPPORT)
  22631     if ((SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit)) &&
  22632         (object >= bcmStatObjectIngMplsFrrLabel) &&
  22633         (object <= bcmStatObjectIngEXTPolicy)) {
  22634         *direction=bcmStatFlexDirectionIngress;
  22635         return BCM_E_NONE;
  22636     }
  22637 #endif
  22638 #if defined(BCM_TRIDENT2_SUPPORT)
  22639     if (SOC_IS_TD2_TT2(unit) &&
  22640         (object >= bcmStatObjectIngVxlan) &&
  22641         (object <= bcmStatObjectIngL3Route)) {
  22642         *direction=bcmStatFlexDirectionIngress;
  22643         return BCM_E_NONE;
  22644     }
  22645 #endif /* BCM_TRIDENT2_SUPPORT */
  22646     /* additional valid ingress objects check */
  22647 	if (object == bcmStatObjectIngNiv) {
  22648 	    *direction=bcmStatFlexDirectionIngress;
  22649         return BCM_E_NONE;
  22650 	}
  22651 
  22652 #if defined(BCM_TRIDENT2_SUPPORT)
  22653     if (SOC_IS_TD2_TT2(unit) &&
  22654         (object == bcmStatObjectIngIpmc)) {
  22655         *direction=bcmStatFlexDirectionIngress;
  22656         return BCM_E_NONE;
  22657     }
  22658 #endif /* BCM_TRIDENT2_SUPPORT */
  22659 
  22660 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)
  22661     if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit) || 
  22662          SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit))  &&
  22663         (bcmStatObjectIngFieldStageIngress == object)) {
  22664         *direction = bcmStatFlexDirectionIngress;
  22665         return BCM_E_NONE;
  22666     }
  22667 #endif
  22668 
  22669 #if defined(BCM_TOMAHAWK3_SUPPORT)
  22670     if ((bcmIntStatObjectEgrLatencyMonitor0 == (bcm_int_stat_object_t)object) ||
  22671         (bcmIntStatObjectEgrLatencyMonitor1 == (bcm_int_stat_object_t)object) ||
  22672         (bcmIntStatObjectEgrLatencyMonitor2 == (bcm_int_stat_object_t)object) ||
  22673         (bcmIntStatObjectEgrLatencyMonitor3 == (bcm_int_stat_object_t)object)) {
  22674         *direction = bcmStatFlexDirectionEgress;
  22675         return BCM_E_NONE;
  22676     }
  22677 #endif
  22678 
  22679 #if defined(BCM_TOMAHAWK_SUPPORT)
  22680     if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) && 
  22681         (object == (bcm_stat_object_t)bcmIntStatObjectIngAgm)) {
  22682         *direction = bcmStatFlexDirectionIngress;
  22683         return BCM_E_NONE;
  22684     }
  22685 #endif
  22686 
  22687 #if defined(BCM_TOMAHAWK_SUPPORT)
  22688     if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) &&
  22689         (object == (bcm_stat_object_t)bcmIntStatObjectIngAgmSecondLookup)) {
  22690         *direction = bcmStatFlexDirectionIngress;
  22691         return BCM_E_NONE;
  22692     }
  22693 #endif
  22694 
  22695 #if defined(BCM_TOMAHAWK_SUPPORT)
  22696     if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit))
  22697         && (object == (bcm_stat_object_t)bcmStatObjectIngExactMatch)) {
  22698         *direction = bcmStatFlexDirectionIngress;
  22699         return BCM_E_NONE;
  22700     }
  22701 #endif
  22702 
  22703 #if defined(BCM_TRIDENT2_SUPPORT)
  22704     if (SOC_IS_TD2_TT2(unit) &&
  22705         (object == bcmStatObjectIngVxlanDip)) {
  22706         *direction=bcmStatFlexDirectionIngress;
  22707         return BCM_E_NONE;
  22708     }
  22709 #endif /* BCM_TRIDENT2_SUPPORT */
  22710 
  22711     if ((object >= bcmStatObjectEgrPort) &&
  22712         (object <= bcmStatObjectEgrL3Intf)) {
  22713         *direction=bcmStatFlexDirectionEgress;
  22714         return BCM_E_NONE;
  22715     }
  22716 #if defined(BCM_TRIUMPH3_SUPPORT)
  22717     if ((SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit)) &&
  22718         (object >= bcmStatObjectEgrWlan) &&
  22719         (object <= bcmStatObjectEgrL2Gre)) {
  22720         *direction=bcmStatFlexDirectionEgress;
  22721         return BCM_E_NONE;
  22722     }
  22723 #endif
  22724 #if defined(BCM_TRIDENT2_SUPPORT)
  22725     if (SOC_IS_TD2_TT2(unit) &&
  22726         (object >= bcmStatObjectEgrL2Gre) &&
  22727         (object <= bcmStatObjectEgrL3Nat)) {
  22728         *direction=bcmStatFlexDirectionEgress;
  22729         return BCM_E_NONE;
  22730     }
  22731 #endif /* BCM_TRIDENT2_SUPPORT */
  22732 #if defined(BCM_TRIDENT3_SUPPORT)
  22733     if (SOC_IS_TRIDENT3X(unit) &&
  22734        (object == bcmStatObjectEgrDvpAttr)) {
  22735        *direction=bcmStatFlexDirectionEgress;
  22736         return BCM_E_NONE;
  22737     }
  22738 #endif /*BCM_TRIDENT3_SUPPORT */
  22739 #if defined(BCM_TRIDENT2PLUS_SUPPORT)                 
  22740     if ((SOC_IS_TD2P_TT2P(unit) || SOC_IS_APACHE(unit)) &&
  22741         ((object == bcmStatObjectEgrFieldStageEgress) ||
  22742         (object == bcmStatObjectEgrMplsTunnelLabel) ||
  22743         (object == bcmStatObjectEgrMplsTunnelSecondLabel))) {
  22744         *direction=bcmStatFlexDirectionEgress;        
  22745         return BCM_E_NONE;                            
  22746     }                                                 
  22747 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  22748 #if defined(BCM_TRIDENT3_SUPPORT)
  22749     if (SOC_IS_TRIDENT3X(unit) && ((object == bcmStatObjectEgrFieldStageEgress)
  22750         || (object == bcmStatObjectEgrMplsTunnelLabel))) {
  22751         *direction=bcmStatFlexDirectionEgress;
  22752         return BCM_E_NONE;                            
  22753     }                                                 
  22754 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  22755 
  22756 	/* additional valid egress objects check */
  22757 	if (object == bcmStatObjectEgrNiv) {
  22758 	    *direction=bcmStatFlexDirectionEgress;
  22759 	    return BCM_E_NONE;
  22760 	}
  22761    
  22762         if (object == bcmStatObjectIngGport) {
  22763             *direction= bcmStatFlexDirectionIngress;
  22764             return BCM_E_NONE;
  22765         }
  22766 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  22767         if ((soc_feature(unit,soc_feature_ing_vlan_xlate_second_lookup)) &&
  22768             (object == bcmStatObjectIngVlanXlateSecondLookup)) {
  22769             *direction= bcmStatFlexDirectionIngress;
  22770             return BCM_E_NONE;
  22771         }
  22772 #endif
  22773 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  22774         if ((soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup)) &&
  22775             (object == bcmStatObjectEgrVlanXlateSecondLookup)) {
  22776             *direction= bcmStatFlexDirectionEgress;
  22777             return BCM_E_NONE;
  22778         }
  22779         if ((soc_feature(unit,soc_feature_mpls_entry_second_label_lookup)) &&
  22780             (object == bcmStatObjectIngMplsSwitchSecondLabel)) {
  22781             *direction= bcmStatFlexDirectionIngress;
  22782             return BCM_E_NONE;
  22783         }
  22784 #endif
  22785     LOG_ERROR(BSL_LS_BCM_FLEXCTR,
  22786               (BSL_META_U(unit,
  22787                           "Invalid bcm_stat_object_t passed %d \n"),object));
  22788     return BCM_E_PARAM;
  22789 }
  22790 
  22791 /*
  22792  * Function:
  22793  *	_bcm_esw_stat_flex_pipe_pool_info_multi_get
  22794  * Description:
  22795  *	Retrieves the flex counter details for a given direction and pipe
  22796  * Parameters:
  22797  *
  22798  *  unit             : (IN)  UNIT number
  22799  *  pipe_num        : (IN)  pipe number
  22800  *  direction        : (IN)  Direction (Ingress/egress)
  22801  *  num_pools        : (IN)  Passing a 0, then actual_num_pools will return the number of pools that are available.
  22802  *                         return the number of pools that are available.
  22803  *                         Passing n will return up to n pools in the return array
  22804  *  flex_pool_stat   : (INOUT)  array that provides the pool info
  22805  *  actual_num_pools : (OUT)  Returns actual no of pools available for a given direction
  22806  *
  22807  * Returns:
  22808  *	BCM_E_*
  22809  */
  22810 int _bcm_esw_stat_flex_pipe_pool_info_multi_get(
  22811     int unit,
  22812     bcm_stat_flex_direction_t direction,
  22813     uint32 pipe_num,
  22814     uint32 num_pools,
  22815     bcm_stat_flex_pool_stat_info_t *flex_pool_stat_info,
  22816     uint32 *actual_num_pools)
  22817 {
  22818     uint32  num_pools_arr[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  22819     uint32  size_pool[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  22820     uint32  poolIndx = 0;
  22821     uint32  lIndx = 0;
  22822     uint32 num_ctr = 0;
  22823 
  22824     /* Coverity :: 21295 */
  22825     if((direction != bcmStatFlexDirectionEgress) &&
  22826 	   (direction != bcmStatFlexDirectionIngress) ) {
  22827         return BCM_E_PARAM;
  22828     }
  22829 
  22830     if( pipe_num >= NUM_PIPE(unit)) {
  22831         return BCM_E_PARAM;
  22832     }
  22833 
  22834     num_pools_arr[bcmStatFlexDirectionIngress] = SOC_INFO(unit).
  22835                                                  num_flex_ingress_pools;
  22836     num_pools_arr[bcmStatFlexDirectionEgress]  = SOC_INFO(unit).
  22837                                                  num_flex_egress_pools;
  22838     size_pool[bcmStatFlexDirectionIngress] = SOC_INFO(unit).
  22839                                              size_flex_ingress_pool;
  22840     size_pool[bcmStatFlexDirectionEgress]  = SOC_INFO(unit).
  22841                                              size_flex_egress_pool;
  22842 
  22843     /*chk the value of num_pools*/
  22844     if(num_pools == 0) {
  22845     /*return the actual_num_of pools available for the given direction */
  22846  	    *actual_num_pools = num_pools_arr[direction];
  22847     }  else { /*fill the structure and send it back */
  22848         if(num_pools > num_pools_arr[direction] ) {
  22849 	        return BCM_E_PARAM;
  22850 	    }
  22851 	    for(poolIndx = 0; poolIndx < num_pools; poolIndx++)
  22852 	    {
  22853 	        flex_pool_stat_info[poolIndx].pool_id = poolIndx;
  22854 
  22855             /* use the least one of the configured pool size and mem table */
  22856             num_ctr = soc_mem_index_count(unit,
  22857                              _ctr_counter_table[direction][poolIndx]);
  22858             if (size_pool[direction] < num_ctr) {
  22859                 num_ctr = size_pool[direction];
  22860             }
  22861 
  22862 	        flex_pool_stat_info[poolIndx].total_entries = num_ctr;
  22863 	        flex_pool_stat_info[poolIndx].used_entries = flex_pool_stat[unit]
  22864                                                          [direction][pipe_num][poolIndx].
  22865                                                          used_entries;
  22866 	        flex_pool_stat_info[poolIndx].attached_entries=flex_pool_stat[unit]
  22867                                                            [direction][pipe_num]
  22868                                                            [poolIndx].
  22869                                                            attached_entries;
  22870 	        flex_pool_stat_info[poolIndx].
  22871                 free_entries = flex_pool_stat_info[poolIndx].total_entries -
  22872                                flex_pool_stat_info[poolIndx].used_entries;
  22873             for(lIndx = 0 ; lIndx < _SHR_BITDCLSIZE(bcmStatObjectMaxValue);
  22874                 lIndx++)
  22875             {
  22876                 
  22877                 flex_pool_stat_info[poolIndx].
  22878                     used_by_objects[lIndx]     =  flex_pool_stat[unit]
  22879                                                   [direction][pipe_num][poolIndx].
  22880                                                   used_by_objects[lIndx];
  22881             }
  22882 	    }
  22883     } /* end of if(num_pools == 0) */
  22884     return BCM_E_NONE;
  22885 }
  22886 
  22887 /*
  22888  * Function:
  22889  *	_bcm_esw_stat_flex_pool_info_multi_get
  22890  * Description:
  22891  *	Retrieves the flex counter details for a given direction
  22892  * Parameters:
  22893  *
  22894  *  unit             : (IN)  UNIT number
  22895  *  direction        : (IN)  Direction (Ingress/egress)
  22896  *  num_pools        : (IN)  Passing a 0, then actual_num_pools will return the number of pools that are available.
  22897  *                         return the number of pools that are available.
  22898  *                         Passing n will return up to n pools in the return array
  22899  *  flex_pool_stat   : (INOUT)  array that provides the pool info
  22900  *  actual_num_pools : (OUT)  Returns actual no of pools available for a given direction
  22901  *
  22902  * Returns:
  22903  *	BCM_E_*
  22904  */
  22905 int _bcm_esw_stat_flex_pool_info_multi_get(
  22906     int unit,
  22907     bcm_stat_flex_direction_t direction,
  22908     uint32 num_pools,
  22909     bcm_stat_flex_pool_stat_info_t *flex_pool_stat_info,
  22910     uint32 *actual_num_pools)
  22911 {
  22912     return _bcm_esw_stat_flex_pipe_pool_info_multi_get(unit, direction, 0, num_pools,
  22913                 flex_pool_stat_info, actual_num_pools);
  22914 }
  22915 
  22916 /*
  22917  * Function:
  22918  *      _bcm_esw_stat_object_pool_num_get
  22919  * Description:
  22920  *      Get counter pool Index from Flex counter Ingress Stat Object.
  22921  * Parameters:
  22922  *      unit            - (IN) unit number
  22923  *      object          - (IN) stat object
  22924  *      pool_num        - (OUT) Counter pool used.
  22925  * Return Value:
  22926  *      BCM_E_XXX
  22927  * Notes:
  22928  */
  22929 bcm_error_t
  22930 _bcm_esw_stat_object_pool_num_get(
  22931     int unit,
  22932     bcm_stat_object_t object,
  22933     uint32 *pool_num)
  22934 {
  22935     uint32   index;
  22936     uint32   pool_number;
  22937     uint32   pool_group_id;
  22938     uint32   num_objects = 0;
  22939     bcm_stat_flex_direction_t direction;
  22940     uint32                    num_pools;
  22941     bcm_stat_object_t         object_list[
  22942                                  BCM_STAT_FLEX_COUNTER_MAX_INGRESS_TABLE];
  22943 
  22944     /* Parameter validation checks */
  22945     if (!SOC_UNIT_VALID(unit)) {
  22946         return BCM_E_UNIT;
  22947     }
  22948 
  22949     if ((NULL == pool_num)){
  22950         return BCM_E_PARAM;
  22951     }
  22952 
  22953     /* Validate object */
  22954     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit, 
  22955                                                       object,
  22956                                                       &direction));
  22957 
  22958     if (soc_feature(unit, soc_feature_use_flex_ctr_oam_lm)) {
  22959         if (direction == bcmStatFlexDirectionIngress) {
  22960             num_pools = SOC_INFO(unit).num_flex_ingress_pools;
  22961             for (pool_number = 0; pool_number < num_pools; pool_number++) {
  22962                 _bcm_esw_stat_get_ingress_object(unit, pool_number, &num_objects,
  22963                                                  &object_list[0]);
  22964                 for (index = 0; index < num_objects; index++) {
  22965                     if (object_list[index] == object) {
  22966                         /* In TD2Plus, for OAM counters one group object can be in
  22967                          * one pool.
  22968                          */
  22969                         pool_group_id = pool_number /
  22970                             BCM_STAT_FLEX_COUNTER_POOLS_PER_GROUP;
  22971                         if (flex_pool_group[unit][0][pool_group_id].group_type ==
  22972                             BCM_FLEX_POOL_GROUP_USED_BY_OAM) {
  22973                             *pool_num = pool_number;
  22974                             return BCM_E_NONE;
  22975                         }
  22976                     }
  22977                 }
  22978             }
  22979         } else {
  22980             num_pools = SOC_INFO(unit).num_flex_egress_pools;
  22981             for (pool_number = 0; pool_number < num_pools; pool_number++) {
  22982                 _bcm_esw_stat_get_egress_object(unit, pool_number, &num_objects,
  22983                                                  &object_list[0]);
  22984                 for (index = 0; index < num_objects; index++) {
  22985                     if (object_list[index] == object) {
  22986                         /* In TD2Plus, for OAM counters one group object can be in
  22987                          * one pool.
  22988                          */
  22989                             *pool_num = pool_number;
  22990                             return BCM_E_NONE;
  22991                     }
  22992                 }
  22993             }
  22994         }
  22995     }
  22996 
  22997     return BCM_E_NOT_FOUND;
  22998 }
  22999 
  23000 bcm_error_t
  23001 _bcm_flex_ctr_field_stat_types_get(int unit, uint32 flex_sid, 
  23002                                    bcm_stat_group_mode_attr_selector_t *attr_selectors,
  23003                                    uint32                              *num_selectors)
  23004 {
  23005     uint32                    pool_number=0;
  23006     uint32                    base_index=0;
  23007     bcm_stat_flex_mode_t      offset_mode=0;
  23008     bcm_stat_object_t         object_l=bcmStatObjectIngPort;
  23009     bcm_stat_group_mode_t     group_l= bcmStatGroupModeSingle;
  23010     int i;
  23011     bcm_error_t status = BCM_E_NONE;
  23012 
  23013     _bcm_esw_stat_get_counter_id_info(
  23014                   unit, flex_sid,&group_l,&object_l,
  23015                   &offset_mode,&pool_number,&base_index);
  23016 
  23017     if ((offset_mode < BCM_STAT_FLEX_CUSTOM_INGRESS_COUNTER_MAX_MODE) &&
  23018        (offset_mode >= BCM_CUSTOM_INGRESS_MODE_START)) {
  23019        offset_mode -= BCM_CUSTOM_INGRESS_MODE_START;
  23020        if (flex_custom_ingress_modes[unit][offset_mode].attr_selectors) {
  23021        *num_selectors = flex_custom_ingress_modes[unit][offset_mode].num_selectors;
  23022        for(i = 0; i < *num_selectors; ++i ) {
  23023            attr_selectors[i] = flex_custom_ingress_modes[unit][offset_mode].attr_selectors[i];
  23024        }
  23025            return status;
  23026        }
  23027        offset_mode = flex_custom_ingress_modes[unit][offset_mode].offset_mode;
  23028     }
  23029  
  23030        *num_selectors = flex_ingress_modes[unit][offset_mode].num_selectors;
  23031        for(i = 0; i < *num_selectors; ++i ) {
  23032            attr_selectors[i] = flex_ingress_modes[unit][offset_mode].attr_selectors[i];
  23033        }
  23034     return BCM_E_NONE;
  23035 }
  23036 
  23037 /*
  23038  * Function:
  23039  *      _bcm_esw_stat_id_get_all
  23040  * Description:
  23041  *      Get all stat ids attached to the stat object.
  23042  * Parameters:
  23043  *      unit            - (IN) unit number
  23044  *      object          - (IN) stat object
  23045  *      stat_max        - (IN) max stat id count
  23046  *      stat_array      - (OUT) array of stat ids
  23047  *      stat_count      - (OUT) actual stat id count
  23048  * Return Value:
  23049  *      BCM_E_XXX
  23050  * Notes:
  23051  */
  23052 bcm_error_t
  23053 _bcm_esw_stat_id_get_all(
  23054     int unit,
  23055     bcm_stat_object_t object,
  23056     int stat_max,
  23057     uint32 *stat_array,
  23058     int *stat_count)
  23059 {
  23060     uint32   index, array_index = 0;
  23061     uint32   pool_number, base_index;
  23062     uint32   num_objects = 0;
  23063     uint32   stat_counter_id = 0;
  23064     bcm_stat_flex_mode_t    offset_mode = 0;
  23065     bcm_stat_object_t       object_l;
  23066     bcm_stat_group_mode_t   group_l;
  23067     bcm_stat_flex_direction_t direction;
  23068     uint32                    num_ctr = 0;
  23069     uint32                    num_pools[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  23070     uint32                    size_pool[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  23071     bcm_stat_object_t         object_list[
  23072                                  BCM_STAT_FLEX_COUNTER_MAX_EGRESS_TABLE +
  23073                                  BCM_STAT_FLEX_COUNTER_MAX_INGRESS_TABLE];
  23074 
  23075     /* Parameter validation checks */
  23076     if (!SOC_UNIT_VALID(unit)) {
  23077         return BCM_E_UNIT;
  23078     }
  23079 
  23080     if ((NULL == stat_count) || (stat_max < 0) ){
  23081         return BCM_E_PARAM;
  23082     }
  23083 
  23084     /* Validate object */
  23085     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit, object, &direction));
  23086 
  23087     /*
  23088      * Loop through ingress and egress counter pools to get base/group index,
  23089      * to retrieve all attached stat objects.
  23090      */
  23091     num_pools[bcmStatFlexDirectionIngress] = SOC_INFO(unit).
  23092                                              num_flex_ingress_pools;
  23093     num_pools[bcmStatFlexDirectionEgress]  = SOC_INFO(unit).
  23094                                              num_flex_egress_pools;
  23095     size_pool[bcmStatFlexDirectionIngress] = SOC_INFO(unit).
  23096                                              size_flex_ingress_pool;
  23097     size_pool[bcmStatFlexDirectionEgress]  = SOC_INFO(unit).
  23098                                              size_flex_egress_pool;
  23099 
  23100     /* Loop all ingress and Egress Pools */
  23101     for (direction = 0; direction < BCM_STAT_FLEX_COUNTER_MAX_DIRECTION;
  23102          direction++ )
  23103     {
  23104         /* Loop all offset/Group Modes */
  23105         for (offset_mode = 0; offset_mode < BCM_STAT_FLEX_COUNTER_MAX_MODE;
  23106               offset_mode++)
  23107         {
  23108             if (direction == bcmStatFlexDirectionIngress) {
  23109                 if (flex_ingress_modes[unit][offset_mode].available == 0) {
  23110                       continue;
  23111                 }
  23112                 group_l=flex_ingress_modes[unit][offset_mode].group_mode;
  23113             } else {
  23114                 if (flex_egress_modes[unit][offset_mode].available == 0 ) {
  23115                       continue;
  23116                 }
  23117                 group_l=flex_egress_modes[unit][offset_mode].group_mode;
  23118             }
  23119             for (pool_number = 0; pool_number < num_pools[direction];
  23120                  pool_number++)
  23121             {
  23122                 /* use the least one of the configured pool size and mem table */
  23123                 num_ctr = soc_mem_index_count(unit,
  23124                                  _ctr_counter_table[direction][pool_number]);
  23125                 if (size_pool[direction] < num_ctr) {
  23126                     num_ctr = size_pool[direction];
  23127                 }
  23128                 for (base_index = 0; base_index < num_ctr; base_index++)
  23129                 {
  23130                     if (flex_base_index_reference_count[unit][direction][0]
  23131                                         [pool_number][base_index] == 0) {
  23132                         continue;
  23133                     }
  23134                     /* Get All Attached objects */
  23135                     if(direction == bcmStatFlexDirectionIngress) {
  23136                        _bcm_esw_stat_get_ingress_object(
  23137                                 unit,
  23138                                 pool_number,
  23139                                 &num_objects,
  23140                                 &object_list[0]);
  23141                     } else { /* Egress direction */
  23142                        _bcm_esw_stat_get_egress_object(
  23143                                 unit,
  23144                                 pool_number,
  23145                                 &num_objects,
  23146                                 &object_list[0]);
  23147                     }
  23148                     /*
  23149                      * Loop through for the given object to get the
  23150                      * attached stat counter ids
  23151                      */
  23152                     for(index = 0; index < num_objects; index++)
  23153                     {
  23154                         object_l = object_list[index];
  23155                         if (object_l != object) {
  23156                             continue;
  23157                         }
  23158                         _bcm_esw_stat_counter_id_retrieve(
  23159                                     unit, group_l, object_l, offset_mode,
  23160                                     pool_number, base_index,
  23161                                     &stat_counter_id);
  23162                         if (stat_counter_id == 0) {
  23163                             continue;
  23164                         }
  23165                         if ((stat_max > 0) && (NULL != stat_array)) {
  23166                             /* Assign the attached stat_id for the object */
  23167                             stat_array[array_index] = stat_counter_id;
  23168                             array_index++;
  23169                             stat_max--;
  23170                         }
  23171                     }
  23172                 } /* Pool counter base */
  23173             } /* Pools */
  23174         }   /* Offset/Group modes */
  23175     } /* Pool directions */
  23176     *stat_count = array_index;
  23177     return BCM_E_NONE;
  23178 }
  23179 
  23180 /*
  23181  * Function:
  23182  *      _bcm_esw_stat_group_dump_info
  23183  * Description:
  23184  *      Dump Useful Info about configured group
  23185  * Parameters:
  23186  *      unit                  - (IN) unit number
  23187  *      all_flag              - (IN) If 1, object and group_mode are ignored
  23188  *      object                - (IN) Flex Accounting object
  23189  *      group                 - (IN) Flex Group Mode
  23190  * Return Value:
  23191  *      BCM_E_XXX
  23192  * Notes:
  23193  */
  23194 void _bcm_esw_stat_group_dump_info(
  23195      int                   unit,
  23196      int                   all_flag,
  23197      bcm_stat_object_t     object,
  23198      bcm_stat_group_mode_t group)
  23199 {
  23200     uint32                    num_objects=0;
  23201     bcm_stat_object_t         ing_object_list[
  23202                                  BCM_STAT_FLEX_COUNTER_MAX_INGRESS_TABLE];
  23203     bcm_stat_object_t         egr_object_list[
  23204                                  BCM_STAT_FLEX_COUNTER_MAX_EGRESS_TABLE];
  23205     uint32                    index=0;
  23206     uint32                    stat_counter_id=0;
  23207     uint32                    pool_number=0;
  23208     uint32                    base_index=0;
  23209     bcm_stat_flex_mode_t      offset_mode=0;
  23210     bcm_stat_object_t         object_l=bcmStatObjectIngPort;
  23211     bcm_stat_group_mode_t     group_l= bcmStatGroupModeSingle;
  23212     bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress;
  23213     uint32                    total_counters=0;
  23214     uint32                    num_ctr = 0;
  23215     uint32                    num_pools[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  23216     uint32                    size_pool[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  23217     bcm_stat_flex_ing_attr_t  *ing_attr=NULL;
  23218     bcm_stat_flex_egr_attr_t  *egr_attr=NULL;
  23219     uint32                    attr_index=0;
  23220     uint32                    total_attrs=0;
  23221     uint8                     attr_value=0;
  23222 
  23223     if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  23224         LOG_CLI((BSL_META_U(unit,
  23225                             "Not Available ...\n")));
  23226         return;
  23227     }
  23228 
  23229     LOG_CLI((BSL_META_U(unit,
  23230                         "Not attached(MAX=%d) Stat counter Id info \n"),
  23231              BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE));
  23232     for (index=0;index<BCM_STAT_FLEX_COUNTER_MAX_SCACHE_SIZE;index++) {
  23233          if (local_scache_ptr[unit][index] != 0) {
  23234              stat_counter_id = local_scache_ptr[unit][index];
  23235              _bcm_esw_stat_get_counter_id_info(
  23236                            unit, stat_counter_id,&group_l,&object_l,
  23237                            &offset_mode,&pool_number,&base_index);
  23238              if (_bcm_esw_stat_validate_object(unit,object_l,&direction)
  23239                  != BCM_E_NONE) {
  23240                  LOG_CLI((BSL_META_U(unit,
  23241                                      "\tInvalid object %d so skipping it \n"),object_l));
  23242                  continue;
  23243              }
  23244              if (direction == bcmStatFlexDirectionIngress) {
  23245                   total_counters = flex_ingress_modes[unit][offset_mode].
  23246                                    total_counters;
  23247              } else {
  23248                   total_counters = flex_egress_modes[unit][offset_mode].
  23249                                   total_counters;
  23250              }
  23251              if ((all_flag == TRUE) ||
  23252                  ((object_l == object) &&
  23253                   (group_l == group))) {
  23254                    LOG_CLI((BSL_META_U(unit,
  23255                                        "\tstat_counter_id = %d=0x%x \n"),
  23256                             stat_counter_id,stat_counter_id));
  23257                    LOG_CLI((BSL_META_U(unit,
  23258                                        "\t\tDirection:%s mode:%d group_mode:%s"
  23259                                        "\n\t\tpool:%d object:%s base:%d"
  23260                                        " total_counters=%d\n"),
  23261                             flex_directions[direction],offset_mode,
  23262                             flex_group_modes[group_l],
  23263                             pool_number,flex_objects[object_l],
  23264                             base_index,total_counters));
  23265              }
  23266          }
  23267     }
  23268     LOG_CLI((BSL_META_U(unit,
  23269                         "Atached Stat counter Id info \n")));
  23270     num_pools[bcmStatFlexDirectionIngress] = SOC_INFO(unit).
  23271                                              num_flex_ingress_pools;
  23272     num_pools[bcmStatFlexDirectionEgress]  = SOC_INFO(unit).
  23273                                              num_flex_egress_pools;
  23274     size_pool[bcmStatFlexDirectionIngress] = SOC_INFO(unit).
  23275                                              size_flex_ingress_pool;
  23276     size_pool[bcmStatFlexDirectionEgress]  = SOC_INFO(unit).
  23277                                              size_flex_egress_pool;
  23278 
  23279     for (direction=0;
  23280          direction<BCM_STAT_FLEX_COUNTER_MAX_DIRECTION;
  23281          direction++) {
  23282          for (offset_mode=0;
  23283               offset_mode<BCM_STAT_FLEX_COUNTER_MAX_MODE;
  23284               offset_mode++) {
  23285               LOG_CLI((BSL_META_U(unit,
  23286                                   "=============================================\n")));
  23287               if (direction == bcmStatFlexDirectionIngress) {
  23288                   if (flex_ingress_modes[unit][offset_mode].available == 0) {
  23289                       continue;
  23290                   }
  23291                   total_counters=flex_ingress_modes[unit][offset_mode].
  23292                                                    total_counters;
  23293                   group_l=flex_ingress_modes[unit][offset_mode].group_mode;
  23294                   ing_attr = &flex_ingress_modes[unit][offset_mode].ing_attr;
  23295                   switch(ing_attr->packet_attr_type) {
  23296                   case bcmStatFlexPacketAttrTypeUncompressed:
  23297                        LOG_CLI((BSL_META_U(unit,
  23298                                            "IngressPacketAttributMode:Uncompressed\n")));
  23299                        LOG_CLI((BSL_META_U(unit,
  23300                                            "Attr_bits_selector:%x \n"),
  23301                                 ing_attr->uncmprsd_attr_selectors.
  23302                                 uncmprsd_attr_bits_selector));
  23303                        total_attrs = sizeof(ing_uncmprsd_attr_bits_selector)/
  23304                                      sizeof(ing_uncmprsd_attr_bits_selector[0]);
  23305                        for(attr_index=0; attr_index<total_attrs; attr_index++) {
  23306                            if(ing_attr->uncmprsd_attr_selectors.
  23307                               uncmprsd_attr_bits_selector &
  23308                               ing_uncmprsd_attr_bits_selector[attr_index].
  23309                               attr_bits)
  23310                               LOG_CLI((BSL_META_U(unit,
  23311                                                   "-->%s bit used\n"),
  23312                                        ing_uncmprsd_attr_bits_selector[attr_index].
  23313                                        attr_name));
  23314                        }
  23315                        break;
  23316                   case bcmStatFlexPacketAttrTypeCompressed:
  23317                        LOG_CLI((BSL_META_U(unit,
  23318                                            "IngressPacket Attribut Mode:Compressed\n")));
  23319                        total_attrs=sizeof(_bcm_esw_get_ing_func)/
  23320                                    sizeof(_bcm_esw_get_ing_func[0]);
  23321                        for(attr_index=0;attr_index<total_attrs;attr_index++) {
  23322                           if((attr_value=_bcm_esw_get_ing_func[attr_index].func(
  23323                              &(ing_attr->cmprsd_attr_selectors.
  23324                                pkt_attr_bits)))){
  23325                              LOG_CLI((BSL_META_U(unit,
  23326                                                  "-->%s:%d\n"),
  23327                                       _bcm_esw_get_ing_func[attr_index].func_desc,
  23328                                       attr_value));
  23329                           }
  23330                        }
  23331                        break;
  23332                   default:
  23333                        LOG_CLI((BSL_META_U(unit,
  23334                                            "Not Implemented yet")));
  23335                   }
  23336               } else {
  23337                   if (flex_egress_modes[unit][offset_mode].available == 0 ) {
  23338                       continue;
  23339                   }
  23340                   egr_attr = &flex_egress_modes[unit][offset_mode].egr_attr;
  23341                   switch(egr_attr->packet_attr_type) {
  23342                   case bcmStatFlexPacketAttrTypeUncompressed:
  23343                        LOG_CLI((BSL_META_U(unit,
  23344                                            "EgressPacketAttributMode:Uncompressed\n")));
  23345                        LOG_CLI((BSL_META_U(unit,
  23346                                            "Attr_bits_selector:%x \n"),
  23347                                 egr_attr->uncmprsd_attr_selectors.
  23348                                 uncmprsd_attr_bits_selector));
  23349                        total_attrs = sizeof(egr_uncmprsd_attr_bits_selector)/
  23350                                      sizeof(egr_uncmprsd_attr_bits_selector[0]);
  23351                        for(attr_index=0; attr_index<total_attrs; attr_index++) {
  23352                            if(egr_attr->uncmprsd_attr_selectors.
  23353                               uncmprsd_attr_bits_selector &
  23354                               egr_uncmprsd_attr_bits_selector[attr_index].
  23355                               attr_bits)
  23356                               LOG_CLI((BSL_META_U(unit,
  23357                                                   "-->%s bit used\n"),
  23358                                        egr_uncmprsd_attr_bits_selector[attr_index].
  23359                                        attr_name));
  23360                        }
  23361                        break;
  23362                   case bcmStatFlexPacketAttrTypeCompressed:
  23363                        LOG_CLI((BSL_META_U(unit,
  23364                                            "EgrressPacket Attribut Mode:Compressed\n")));
  23365                        total_attrs=sizeof(_bcm_esw_get_egr_func)/
  23366                                    sizeof(_bcm_esw_get_egr_func[0]);
  23367                        for(attr_index=0;attr_index<total_attrs;attr_index++) {
  23368                           if((attr_value=_bcm_esw_get_egr_func[attr_index].func(
  23369                              &(egr_attr->cmprsd_attr_selectors.
  23370                                pkt_attr_bits)))){
  23371                               LOG_CLI((BSL_META_U(unit,
  23372                                                   "-->%s:%d\n"),
  23373                                        _bcm_esw_get_egr_func[attr_index].func_desc,
  23374                                        attr_value));
  23375                           }
  23376                        }
  23377                        break;
  23378                   default:
  23379                        LOG_CLI((BSL_META_U(unit,
  23380                                            "Not Implemented yet")));
  23381                   }
  23382                   total_counters=flex_egress_modes[unit][offset_mode].
  23383                                                   total_counters;
  23384                   group_l=flex_egress_modes[unit][offset_mode].group_mode;
  23385               }
  23386               LOG_CLI((BSL_META_U(unit,
  23387                                   "-->Direction:%s offset mode=%d\n"
  23388                                   "-->group_mode:%s total_counters=%d \n"),
  23389                        flex_directions[direction], offset_mode,
  23390                        flex_group_modes[group_l], total_counters));
  23391               for (pool_number=0;
  23392                    pool_number<num_pools[direction];
  23393                    pool_number++) {
  23394                    /* use the least one of the configured pool size and mem table */
  23395                    num_ctr = soc_mem_index_count(unit,
  23396                                     _ctr_counter_table[direction][pool_number]);
  23397                    if (size_pool[direction] < num_ctr) {
  23398                        num_ctr = size_pool[direction];
  23399                    }
  23400                    for (base_index=0;
  23401                         base_index<num_ctr;
  23402                         base_index++) {
  23403                         if (flex_base_index_reference_count[unit][direction]
  23404                                             [pool_number][base_index] != 0) {
  23405                             if(direction==bcmStatFlexDirectionIngress) {
  23406                                _bcm_esw_stat_get_ingress_object(
  23407                                         unit,
  23408                                         pool_number,
  23409                                         &num_objects,
  23410                                         &ing_object_list[0]);
  23411                               for(index=0;index<num_objects;index++) {
  23412                                   object_l=ing_object_list[index];
  23413                                   _bcm_esw_stat_get_counter_id(
  23414                                                 unit, group_l,object_l,offset_mode,
  23415                                                 pool_number,base_index,
  23416                                                 &stat_counter_id);
  23417                                   if (num_objects != 1) {
  23418                                       LOG_CLI((BSL_META_U(unit,
  23419                                                           "-->Probable..")));
  23420                                   }
  23421                                   if ((all_flag == TRUE) ||
  23422                                       ((object_l == object) &&
  23423                                        (group_l == group))) {
  23424                                         LOG_CLI((BSL_META_U(unit,
  23425                                                             "\tstat counter id %d (0x%x) "
  23426                                                             "object=%s base index=%d (0x%x)\n"),
  23427                                                  stat_counter_id,stat_counter_id,
  23428                                                  flex_objects[object_l],
  23429                                                  base_index,base_index));
  23430                                   }
  23431                               }
  23432                         } else {
  23433                             _bcm_esw_stat_get_egress_object(
  23434                                      unit, pool_number,
  23435                                      &num_objects,&egr_object_list[0]);
  23436                             for (index=0; index<num_objects; index++) {
  23437                                  object_l = egr_object_list[index];
  23438                                  _bcm_esw_stat_get_counter_id(
  23439                                                 unit, group_l,object_l,offset_mode,
  23440                                                 pool_number,base_index,
  23441                                                 &stat_counter_id);
  23442                                  if (num_objects != 1) {
  23443                                      LOG_CLI((BSL_META_U(unit,
  23444                                                          "Probable..")));
  23445                                  }
  23446                                  if ((all_flag == TRUE) ||
  23447                                      ((object_l == object) &&
  23448                                       (group_l == group))) {
  23449                                        LOG_CLI((BSL_META_U(unit,
  23450                                                            "\tstat counter id %d (0x%x) "
  23451                                                            "object=%s base index=%d (0x%x)\n"),
  23452                                                 stat_counter_id,stat_counter_id,
  23453                                                 flex_objects[object_l],
  23454                                                 base_index,base_index));
  23455                                  }
  23456                             }
  23457                         }
  23458                    }
  23459                 }
  23460               }
  23461               LOG_CLI((BSL_META_U(unit,
  23462                                   "=============================================\n")));
  23463          }
  23464     }
  23465 }
  23466 
  23467 int _bcm_stat_flex_reserve_base_index(int unit,
  23468         bcm_stat_flex_direction_t direction,
  23469         uint32 pool_number_l, uint32 total_counters,
  23470         uint32 base_idx, uint32 used_by_table,
  23471         uint32 pipe_num, bcm_stat_object_t object)
  23472 {
  23473     int rv = BCM_E_NONE;
  23474     uint32 free_count = 0,largest_free = 0;
  23475     uint32 alloc_count = 0;
  23476 
  23477     if (soc_feature(unit, soc_feature_flex_stat_compaction_support)) {
  23478         flex_pool_stat[unit][direction]
  23479             [pipe_num][pool_number_l].used_entries += total_counters;
  23480         /* Reserve a base index from the pool */
  23481         rv = shr_aidxres_list_reserve(flex_aidxres_list_handle[unit]
  23482                 [direction][pipe_num][pool_number_l],
  23483                 base_idx, base_idx + total_counters - 1);
  23484         if (rv == BCM_E_NONE) {
  23485             flex_pool_stat[unit][direction]
  23486                 [pipe_num][pool_number_l].used_by_tables |= used_by_table;
  23487             SHR_BITSET(flex_pool_stat[unit][direction]
  23488                     [pipe_num][pool_number_l].used_by_objects, object);
  23489         } else {
  23490             flex_pool_stat[unit][direction]
  23491                 [pipe_num][pool_number_l].used_entries -= total_counters;
  23492         }
  23493         if(shr_aidxres_list_state(flex_aidxres_list_handle[unit]
  23494                     [direction][pipe_num][pool_number_l],
  23495                     NULL,NULL,NULL,NULL,&free_count,&alloc_count,&largest_free,
  23496                     NULL) != BCM_E_NONE) {
  23497             LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  23498                     (BSL_META_U(unit,
  23499                                 "Pool status free_count:%d alloc_count:%d largest_free:%d"
  23500                                 "used_by_tables:%d used_entries:%d\n"),
  23501                      free_count,alloc_count,largest_free,
  23502                      flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num]
  23503                      [pool_number_l].used_by_tables,
  23504                      flex_pool_stat[unit][bcmStatFlexDirectionEgress][pipe_num]
  23505                      [pool_number_l].used_entries));
  23506         }
  23507     }
  23508     return rv;
  23509 }
  23510 
  23511 int _bcm_stat_flex_counter_base_idx_move(int unit,
  23512         bcm_stat_custom_counter_info_t   counter_info_old,
  23513         bcm_stat_custom_counter_info_t   *counter_info_new)
  23514 {
  23515     uint32 new_base_idx = 0,old_base_idx = 0;
  23516     uint32 new_pool_id = 0,old_pool_id = 0;
  23517     uint32 old_object = 0,old_mode_id = 0;
  23518     int old_idx =0,new_idx = 0;
  23519     int rv = BCM_E_NONE,alloc_size = 0;
  23520     int total_counters = 0,pipe_num = 0;
  23521     bcm_stat_flex_direction_t direction = 0;
  23522     bcm_stat_group_mode_t group_mode = bcmStatGroupModeSingle;
  23523     uint32 stat_counter_id=0;
  23524     uint32 old_pkt_ctr_value = 0;
  23525     uint32 *dma_ptr_old = NULL;
  23526     soc_mem_t pool_mem_old;
  23527     uint32 old_byte_ctr[2];
  23528     int num_entries,entry_words;
  23529     uint64 old_byte_ctr_value,old_pkt64_ctr_value;
  23530     ing_flex_ctr_counter_table_0_entry_t *hw_entry_old = NULL;
  23531 
  23532     if (counter_info_new == NULL)
  23533         return BCM_E_PARAM;
  23534     new_pool_id  = counter_info_new->ctr_tbl_pool_id;
  23535     new_base_idx = counter_info_new->ctr_tbl_pool_base_idx;
  23536     old_pool_id  = counter_info_old.ctr_tbl_pool_id;
  23537     old_base_idx = counter_info_old.ctr_tbl_pool_base_idx;
  23538     old_mode_id  = counter_info_old.ctr_tbl_mode_id;
  23539     old_object   = counter_info_old.object;
  23540 
  23541     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,old_object,
  23542                 &direction));
  23543     if (direction == bcmStatFlexDirectionIngress) {
  23544         total_counters = flex_ingress_modes[unit][old_mode_id].total_counters;
  23545         group_mode = flex_ingress_modes[unit][old_mode_id].group_mode;
  23546     } else if (direction == bcmStatFlexDirectionEgress) {
  23547         if(old_mode_id >= BCM_STAT_FLEX_COUNTER_MAX_MODE) {
  23548             old_mode_id -= BCM_STAT_FLEX_COUNTER_MAX_MODE;
  23549         }
  23550         total_counters = flex_egress_modes[unit][old_mode_id].total_counters;
  23551         group_mode = flex_egress_modes[unit][old_mode_id].group_mode;
  23552     }
  23553 
  23554     /*
  23555      * Add the old counter values (PACKET_COUNTERf,BYTE_COUNTEf)
  23556      * pointing old base index to new base index.
  23557      * Call counter sync.Delete old stat counter id.
  23558      */
  23559     num_entries = soc_mem_index_count(unit, ING_FLEX_CTR_COUNTER_TABLE_0m);
  23560     entry_words = soc_mem_entry_words(unit, ING_FLEX_CTR_COUNTER_TABLE_0m);
  23561     alloc_size = NUM_PIPE(unit) * num_entries * sizeof(uint32) * entry_words;
  23562 
  23563     dma_ptr_old=soc_cm_salloc(unit,alloc_size, "dma_ptr_old");
  23564     if (dma_ptr_old== NULL) {
  23565         return BCM_E_MEMORY;
  23566     }
  23567 
  23568     sal_memset(dma_ptr_old, 0,alloc_size);
  23569     pool_mem_old = _ctr_counter_table[direction][old_pool_id];
  23570 
  23571     BCM_STAT_FLEX_COUNTER_LOCK(unit);
  23572     if (soc_mem_read_range(
  23573                 unit,
  23574                 pool_mem_old,
  23575                 MEM_BLOCK_ANY,
  23576                 soc_mem_index_min(unit,pool_mem_old),
  23577                 soc_mem_index_max(unit,pool_mem_old),
  23578                 dma_ptr_old) != BCM_E_NONE) {
  23579         soc_cm_sfree(unit,dma_ptr_old);
  23580         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  23581         return BCM_E_INTERNAL;
  23582     }
  23583 
  23584     new_idx = new_base_idx;
  23585     for (old_idx=old_base_idx; old_idx < (old_base_idx + total_counters);
  23586             old_idx++) {
  23587         hw_entry_old = soc_mem_table_idx_to_pointer(unit, pool_mem_old,
  23588                 ing_flex_ctr_counter_table_0_entry_t *,
  23589                 dma_ptr_old, old_idx);
  23590 
  23591         /* Packet count */
  23592         soc_mem_field_get(unit,
  23593                 pool_mem_old,
  23594                 (uint32 *)hw_entry_old,
  23595                 PACKET_COUNTERf,&old_pkt_ctr_value);
  23596 
  23597         /* Byte count */
  23598         soc_mem_field_get(unit,
  23599                 pool_mem_old,
  23600                 (uint32 *)hw_entry_old,
  23601                 BYTE_COUNTERf, old_byte_ctr);
  23602 
  23603         /* Update Compaction Counter Soft Copy */
  23604         flex_packet_counter_compaction[unit][direction][pipe_num]
  23605             [new_pool_id][new_idx] += old_pkt_ctr_value;
  23606         COMPILER_64_SET(old_pkt64_ctr_value, 0, old_pkt_ctr_value);
  23607         COMPILER_64_SET(old_byte_ctr_value, old_byte_ctr[1],
  23608                 old_byte_ctr[0]);
  23609         COMPILER_64_ADD_64(flex_byte_counter_compaction[unit]
  23610                 [direction][pipe_num][new_pool_id][new_idx],
  23611                 old_byte_ctr_value);
  23612         COMPILER_64_ADD_64(flex_packet64_counter_compaction[unit]
  23613                 [direction][pipe_num][new_pool_id][new_idx],
  23614                 old_pkt64_ctr_value);
  23615 
  23616         /* Reset old counter values */
  23617         old_pkt_ctr_value = 0;
  23618         old_byte_ctr[0]=old_byte_ctr[1]=0;
  23619         soc_mem_field_set(
  23620                 unit,
  23621                 pool_mem_old,
  23622                 (uint32 *)hw_entry_old,
  23623                 PACKET_COUNTERf,
  23624                 &old_pkt_ctr_value);
  23625 
  23626         soc_mem_field_set(
  23627                 unit,
  23628                 pool_mem_old,
  23629                 (uint32 *)hw_entry_old,
  23630                 BYTE_COUNTERf,
  23631                 old_byte_ctr);
  23632 
  23633         new_idx++;
  23634         hw_entry_old = NULL;
  23635     }
  23636     if (soc_mem_write_range(
  23637                 unit,
  23638                 pool_mem_old,
  23639                 MEM_BLOCK_ALL,
  23640                 soc_mem_index_min(unit,pool_mem_old),
  23641                 soc_mem_index_max(unit,pool_mem_old),
  23642                 dma_ptr_old) != BCM_E_NONE){
  23643         soc_cm_sfree(unit,dma_ptr_old);
  23644         BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  23645         return BCM_E_INTERNAL;
  23646     }
  23647     BCM_STAT_FLEX_COUNTER_UNLOCK(unit);
  23648 
  23649     /*
  23650      * Decrement refrence count and
  23651      * delete old stat counter id
  23652      */
  23653     _bcm_esw_stat_get_counter_id(unit, group_mode,
  23654             old_object, old_mode_id, old_pool_id,
  23655             old_base_idx, &stat_counter_id);
  23656     if(flex_base_index_reference_count[unit][direction][pipe_num]
  23657             [old_pool_id][old_base_idx] > 0) {
  23658         flex_base_index_reference_count[unit][direction][pipe_num]
  23659             [old_pool_id][old_base_idx] = 0;
  23660     }
  23661     if(flex_pool_stat[unit][direction][pipe_num][old_pool_id].
  23662             attached_entries > 0) {
  23663         flex_pool_stat[unit][direction][pipe_num][old_pool_id].
  23664             attached_entries -= total_counters;
  23665     }
  23666 
  23667     rv = _bcm_esw_stat_group_destroy(unit, stat_counter_id);
  23668     LOG_DEBUG(BSL_LS_BCM_FLEXCTR,
  23669             (BSL_META_U(unit,
  23670                         "Deleted old stat counter id: %d"
  23671                         "Counters synced from old_base_idx:%d to new_base_idx:%d\n"),
  23672              stat_counter_id,old_base_idx,new_base_idx));
  23673 
  23674     return rv;
  23675 }
  23676 
  23677 int _bcm_stat_flex_dump_pool_info(int unit)
  23678 {
  23679     uint32 free_count = 0,largest_free = 0;
  23680     uint32 alloc_count = 0;
  23681     uint32 pool_number_l=0,pipe_num=0;
  23682     uint32    num_pools[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  23683     uint32    size_pool[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  23684     bcm_stat_flex_direction_t    direction=bcmStatFlexDirectionIngress;
  23685 
  23686     num_pools[bcmStatFlexDirectionIngress]= SOC_INFO(unit).
  23687                                             num_flex_ingress_pools;
  23688     num_pools[bcmStatFlexDirectionEgress] = SOC_INFO(unit).
  23689                                             num_flex_egress_pools;
  23690     size_pool[bcmStatFlexDirectionIngress]= SOC_INFO(unit).
  23691                                             size_flex_ingress_pool;
  23692     size_pool[bcmStatFlexDirectionEgress] = SOC_INFO(unit).
  23693                                             size_flex_egress_pool;
  23694 
  23695     LOG_CLI((BSL_META_U(unit,
  23696                     "INFO: ingress_pools:%d num_flex_egress_pools:%d "
  23697                     "size_flex_ingress_pool:%d size_flex_egress_pool:%d"
  23698                     "MAX_DIRECTION %d MAX_MODE %d MAX_POOL %d\n"),
  23699                 num_pools[bcmStatFlexDirectionIngress],
  23700                 num_pools[bcmStatFlexDirectionEgress],
  23701                 size_pool[bcmStatFlexDirectionIngress],
  23702                 size_pool[bcmStatFlexDirectionEgress],
  23703                 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION,
  23704                 BCM_STAT_FLEX_COUNTER_MAX_MODE,
  23705                 BCM_STAT_FLEX_COUNTER_MAX_POOL));
  23706 
  23707     for (direction = bcmStatFlexDirectionIngress;
  23708             direction < bcmStatFlexDirectionCount;
  23709             direction++) {
  23710         for (pool_number_l= 0; pool_number_l < num_pools[direction]; pool_number_l++) {
  23711             shr_aidxres_list_state(flex_aidxres_list_handle[unit]
  23712                     [direction][pipe_num][pool_number_l],
  23713                     NULL,NULL,NULL,NULL,&free_count,&alloc_count,&largest_free,
  23714                     NULL);
  23715             LOG_CLI((BSL_META_U(unit,
  23716                             "Pool Number %d Direction %s   "
  23717                             "free_count:%d alloc_count:%d  "
  23718                             "used_by_tables:%d used_entries:%d\n"),
  23719                         pool_number_l,(direction == bcmStatFlexDirectionIngress) ? "Ingress":"Egress",free_count,alloc_count,
  23720                         flex_pool_stat[unit][direction][pipe_num]
  23721                         [pool_number_l].used_by_tables,
  23722                         flex_pool_stat[unit][direction][pipe_num]
  23723                         [pool_number_l].used_entries));
  23724         }
  23725     }
  23726     return BCM_E_NONE;
  23727 
  23728 }
  23729 
  23730 int _bcm_esw_stat_validate_counter_info(int unit,
  23731         bcm_stat_custom_counter_info_t   counter_info_old,
  23732         bcm_stat_custom_counter_info_t   *counter_info_new)
  23733 {
  23734     bcm_stat_flex_direction_t direction = 0;
  23735     int total_counters = 0, egr_old_mode_id = 0;
  23736 
  23737     if (counter_info_new == NULL) {
  23738         return BCM_E_PARAM;
  23739     }
  23740     /* Counter Set */
  23741     if ((counter_info_old.num_counters == 0) ||
  23742             (counter_info_old.num_counters >
  23743              BCM_STAT_FLEX_MAX_COUNTER)) {
  23744         return BCM_E_PARAM;
  23745     }
  23746 
  23747     if ((counter_info_new->num_counters == 0) ||
  23748             (counter_info_new->num_counters >
  23749              BCM_STAT_FLEX_MAX_COUNTER)) {
  23750         return BCM_E_PARAM;
  23751     }
  23752     /*
  23753      * Do not allow old base-idx,pool-id and
  23754      * different mode id in new counter info
  23755      * structure in counter movement.
  23756      */
  23757     if (((counter_info_new->ctr_tbl_pool_base_idx ==
  23758                     counter_info_old.ctr_tbl_pool_base_idx) &&
  23759                 (counter_info_new->ctr_tbl_pool_id ==
  23760                  counter_info_old.ctr_tbl_pool_id)) ||
  23761             (counter_info_new->ctr_tbl_mode_id !=
  23762              counter_info_old.ctr_tbl_mode_id)) {
  23763         return BCM_E_PARAM;
  23764     }
  23765 
  23766     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,
  23767                 counter_info_old.object,
  23768                 &direction));
  23769     if (direction == bcmStatFlexDirectionIngress) {
  23770         /* check mode id range */
  23771         if ((counter_info_old.ctr_tbl_mode_id >
  23772                     BCM_STAT_FLEX_COUNTER_MAX_MODE) ||
  23773                 (counter_info_new->ctr_tbl_mode_id >
  23774                  BCM_STAT_FLEX_COUNTER_MAX_MODE)) {
  23775             return BCM_E_PARAM;
  23776         }
  23777         total_counters = flex_ingress_modes[unit]
  23778             [counter_info_old.ctr_tbl_mode_id].total_counters;
  23779         if (total_counters !=
  23780                 counter_info_old.num_counters) {
  23781             return BCM_E_PARAM;
  23782         }
  23783     } else if (direction == bcmStatFlexDirectionEgress) {
  23784         if ((counter_info_old.ctr_tbl_mode_id <
  23785                     BCM_STAT_FLEX_COUNTER_MAX_MODE) ||
  23786                 (counter_info_new->ctr_tbl_mode_id <
  23787                  BCM_STAT_FLEX_COUNTER_MAX_MODE)) {
  23788             return BCM_E_PARAM;
  23789         }
  23790 
  23791         egr_old_mode_id = counter_info_old.ctr_tbl_mode_id;
  23792         if (counter_info_old.ctr_tbl_mode_id >=
  23793                 BCM_STAT_FLEX_COUNTER_MAX_MODE) {
  23794             egr_old_mode_id -= BCM_STAT_FLEX_COUNTER_MAX_MODE;
  23795         }
  23796         total_counters = flex_egress_modes[unit]
  23797             [egr_old_mode_id].total_counters;
  23798         if (total_counters !=
  23799                 counter_info_old.num_counters) {
  23800             return BCM_E_PARAM;
  23801         }
  23802     }
  23803     return BCM_E_NONE;
  23804 }