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

counter.c (794809B)


      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  * Packet Statistics Counter Management
      8  *
      9  * Firebolt     1024 bytes per port (128 * uint64)
     10  * Helix        1024 bytes per port (128 * uint64)
     11  * Felix        1024 bytes per port (128 * uint64)
     12  * Raptor       1024 bytes per port (128 * uint64)
     13  * Hercules:    1024 bytes per port (128 * uint64)
     14  * HUMV:        2048 bytes per port (256 * uint64)
     15  * Bradley:     2048 bytes per port (256 * uint64)
     16  * Goldwing:    2048 bytes per port (256 * uint64)
     17  * Triumph:     4096 bytes per port (512 * uint64)
     18  *
     19  * BCM5670 Endian: on Hercules, the well-intentioned ES_BIG_ENDIAN_OTHER
     20  * causes counter DMA to write the most significant word first in the
     21  * DMA buffer.  This is wrong because not all big-endian hosts have the
     22  * same setting for ES_BIG_ENDIAN_OTHER (e.g. mousse and idtrp334).
     23  * This problem makes it necessary to check the endian select to
     24  * determine whether to swap words.
     25  */
     26 
     27 #include <shared/bsl.h>
     28 
     29 #include <sal/core/libc.h>
     30 #include <shared/alloc.h>
     31 #include <sal/core/spl.h>
     32 #include <sal/core/sync.h>
     33 #include <sal/core/time.h>
     34 
     35 #include <soc/drv.h>
     36 #include <soc/counter.h>
     37 #include <soc/ll.h>
     38 #include <soc/debug.h>
     39 #include <soc/mem.h>
     40 #include <soc/register.h>
     41 #ifdef BCM_ESW_SUPPORT
     42 #include <soc/format.h>
     43 #endif
     44 #ifdef BCM_TRIDENT_SUPPORT
     45 #include <soc/trident.h>
     46 #endif
     47 #if defined(BCM_PETRA_SUPPORT)
     48 #include <soc/dpp/drv.h>
     49 #include <bcm_int/dpp/error.h>
     50 #include <bcm_int/dpp/utils.h>
     51 #endif
     52 #if defined(BCM_DFE_SUPPORT)
     53 #include <soc/dfe/cmn/dfe_drv.h>
     54 #endif
     55 #if defined(BCM_PETRA_SUPPORT)
     56 #include <soc/dpp/ARAD/arad_stat.h>
     57 #endif
     58 #if defined(BCM_JERICHO_SUPPORT)
     59 #include <soc/dpp/JER/jer_stat.h>
     60 #endif
     61 #if defined(BCM_88750_SUPPORT)
     62 #include <soc/dfe/fe1600/fe1600_stat.h>
     63 #endif
     64 #if defined(BCM_PETRA_SUPPORT)
     65 #include <soc/dpp/mbcm.h>
     66 #endif
     67 #if defined(BCM_DNX_SUPPORT)
     68 #include <soc/dnx/dnx_data/auto_generated/dnx_data_port.h>
     69 #include <soc/dnx/dnx_data/auto_generated/dnx_data_fabric.h>
     70 #include <soc/dnx/stat/jer2_stat.h>
     71 #include <soc/dnx/dnx_err_recovery_manager_utils.h>
     72 #endif
     73 #ifdef BCM_CMICM_SUPPORT
     74 #include <soc/cmicm.h>
     75 #endif
     76 #if defined(BCM_TRIDENT2_SUPPORT)
     77 #include <soc/trident2.h>
     78 #include <bcm_int/esw_dispatch.h>
     79 #endif
     80 #if defined(BCM_MONTEREY_SUPPORT)
     81 #include <soc/monterey.h>
     82 #endif
     83 #if defined(BCM_APACHE_SUPPORT)
     84 #include <soc/apache.h>
     85 #endif
     86 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
     87 #include <soc/td2_td2p.h>
     88 #endif
     89 #if defined(BCM_KATANA2_SUPPORT)
     90 #include <soc/katana2.h>
     91 #endif
     92 #if defined(BCM_KATANA2_SUPPORT)
     93 #include <soc/saber2.h>
     94 #endif
     95 
     96 #if defined(BCM_TOMAHAWK_SUPPORT)
     97 #include <soc/tomahawk.h>
     98 #include <soc/tomahawk2.h>
     99 #endif
    100 #if defined(BCM_TOMAHAWK3_SUPPORT)
    101 #include <soc/tomahawk3.h>
    102 #endif
    103 #if defined(BCM_TRIDENT3_SUPPORT)
    104 #include <soc/trident3.h>
    105 #endif
    106 #if defined(BCM_HELIX5_SUPPORT)
    107 #include <soc/helix5.h>
    108 #endif
    109 
    110 #if defined(BCM_GREYHOUND2_SUPPORT)
    111 #include <soc/greyhound2.h>
    112 #endif
    113 
    114 #ifdef CRASH_RECOVERY_SUPPORT
    115 #include <soc/hwstate/hw_log.h>
    116 #endif /* CRASH_RECOVERY_SUPPORT */
    117 
    118 #if defined (BCM_DNX_SUPPORT) || defined (BCM_DNXF_SUPPORT)
    119 #include <soc/dnxc/dnxc_ha.h>
    120 #endif
    121 
    122 #include <soc/dnxc/multithread_analyzer.h>
    123 
    124 #if defined(INCLUDE_PHY_8806X)
    125 extern int phy_mt2_update_led_speed_activity(int unit, soc_port_t port);
    126 #endif
    127 
    128 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT)
    129 
    130 #define COUNTER_IDX_PORTBASE(unit, port) \
    131         ((port) * SOC_CONTROL(unit)->counter_perport)
    132 
    133 #define COUNTER_IDX_GET(unit, ctr_ref, port) \
    134         (COUNTER_IDX_PORTBASE(unit, port) + \
    135          SOC_REG_CTR_IDX(unit, (ctr_ref)->reg) + (ctr_ref)->index)
    136 
    137 #define COUNTER_IDX_OFFSET(unit)        0
    138 
    139 #define COUNTER_MIN_IDX_GET(unit, port) \
    140         (COUNTER_IDX_PORTBASE(unit, port) + COUNTER_IDX_OFFSET(unit))
    141 
    142 soc_counter_control_t *soc_counter_control[SOC_MAX_NUM_DEVICES];
    143 
    144 static soc_counter_extra_f soc_counter_extra[SOC_MAX_NUM_DEVICES]
    145                                             [SOC_COUNTER_EXTRA_CB_MAX];
    146 /* Number of cosq per unit per port */
    147 static int num_cosq[SOC_MAX_NUM_DEVICES][SOC_MAX_NUM_PORTS] = {{ 0 }};
    148 
    149 #ifdef BCM_SBUSDMA_SUPPORT
    150 volatile uint32 _soc_counter_pending[SOC_MAX_NUM_DEVICES] = { 0 };
    151 #endif
    152 
    153 #ifdef BCM_TOMAHAWK_SUPPORT
    154 static uint32 *buff_max[SOC_MAX_NUM_DEVICES] = { NULL };
    155 static void *host_entry[SOC_MAX_NUM_DEVICES] = { NULL };
    156 static void *host_buff[SOC_MAX_NUM_DEVICES] = { NULL };
    157 #endif
    158 
    159 #if defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT)
    160 STATIC int
    161 soc_counter_collect64(int unit, int discard, soc_port_t tmp_port, soc_reg_t hw_ctr_reg);
    162 #endif /* defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT) */
    163 
    164 
    165 STATIC void
    166 soc_counter_collect_non_dma_entries(int unit,
    167                                     int tmp_port,
    168                                     int port_idx,
    169                                     int ar_idx,
    170                                     soc_reg_t ctr_reg);
    171 STATIC int
    172 _soc_counter_non_dma_is_invalid(int unit, soc_reg_t reg, soc_port_t port);
    173         
    174 #ifdef BCM_TOMAHAWK_SUPPORT
    175 STATIC void
    176 soc_counter_collect_th_non_dma_entries(int unit,
    177                                         int tmp_port,
    178                                         int port_idx,
    179                                         int ar_idx,
    180                                         soc_reg_t ctr_reg);
    181 #endif /* BCM_TOMAHAWK_SUPPORT */
    182 STATIC void soc_counter_generic_collect_non_dma_entries(int unit,
    183                                                         soc_ctr_control_info_t
    184                                                         ctrl_info, 
    185                                                         int base_idx,
    186                                                         int ar_idx,
    187                                                         soc_reg_t ctr_reg);
    188 /*
    189  * Turn on COUNTER_BENCH and "debug +verbose" to benchmark the CPU time
    190  * spent on counter activity.  NOTE: most useful on platforms where
    191  * sal_time_usecs() has usec precision instead of clock tick precision.
    192  */
    193 
    194 #undef COUNTER_BENCH
    195 
    196 /* Per port mapping to counter map structures */
    197 #define PORT_CTR_REG(unit, port, idx) \
    198         (&SOC_CONTROL(unit)->counter_map[port]->cmap_base[idx])
    199 #define PORT_CTR_NUM(unit, port) \
    200         (SOC_CONTROL(unit)->counter_map[port]->cmap_size)
    201 
    202 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT)
    203 
    204 static uint64 *soc_counter_tbuf[SOC_MAX_NUM_DEVICES];
    205 #define SOC_COUNTER_TBUF_SIZE(unit) \
    206     (SOC_CONTROL(unit)->counter_perport * sizeof(uint64))
    207 
    208 #ifdef BCM_TRIUMPH2_SUPPORT
    209 #define COUNTER_TIMESTAMP_FIFO_SIZE     4
    210 #define DIRECT_TIMESTAMP_DMA_COUNTER_NUM    100
    211 #define XMAC_DMA_COUNTER_BASE               42
    212 #endif /* BCM_TRIUMPH2_SUPPORT */
    213 
    214 #ifdef BCM_KATANA_SUPPORT
    215 typedef struct _kt_cosq_counter_mem_map_s {
    216     soc_mem_t mem;
    217     soc_counter_non_dma_id_t non_dma_id;
    218 }_kt_cosq_counter_mem_map_t;
    219 
    220 /*
    221  * CTR_FLEX_COUNT_0/1/2/3 = Total ENQ discarded
    222  * CTR_FLEX_COUNT_4/5/6/7  = Red packet ENQ discarded
    223  * CTR_FLEX_COUNT_8/9/10/11  = Total DEQ
    224  */
    225 _kt_cosq_counter_mem_map_t _kt_cosq_mem_map[] =
    226 {
    227     { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT },
    228     { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT },
    229     { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT },
    230     { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT },
    231     { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED },
    232     { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED },
    233     { CTR_FLEX_COUNT_6m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED },
    234     { CTR_FLEX_COUNT_7m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED },
    235     { CTR_FLEX_COUNT_8m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT },
    236     { CTR_FLEX_COUNT_9m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT },
    237     { CTR_FLEX_COUNT_10m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT },
    238     { CTR_FLEX_COUNT_11m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT }
    239 };
    240 
    241 /*
    242  * CTR_FLEX_COUNT_0 = Total ENQ discarded
    243  * CTR_FLEX_COUNT_1 = Total ENQ Accepted
    244  * CTR_FLEX_COUNT_2 = Green ENQ discarded
    245  * CTR_FLEX_COUNT_3 = Yellow ENQ discarded
    246  * CTR_FLEX_COUNT_4    = Red packet ENQ discarded
    247  * CTR_FLEX_COUNT_5 = Green ENQ Accepted
    248  * CTR_FLEX_COUNT_6 = Yellow ENQ Accepted
    249  * CTR_FLEX_COUNT_7 = Red ENQ Accepted
    250  * CTR_FLEX_COUNT_8    = Total DEQ
    251 */
    252 _kt_cosq_counter_mem_map_t _kt_cosq_gport_mem_map[] =
    253 {
    254     { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT },
    255     { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT },
    256     { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN },
    257     { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW },
    258     { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED },
    259     { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_GREEN },
    260     { CTR_FLEX_COUNT_6m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_YELLOW },
    261     { CTR_FLEX_COUNT_7m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_RED },
    262     { CTR_FLEX_COUNT_8m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT }
    263 };
    264 #endif
    265 #ifdef BCM_KATANA2_SUPPORT
    266 /*  
    267  * CTR_FLEX_COUNT_0/1/2/3 = Total ENQ discarded
    268  * CTR_FLEX_COUNT_4/5/6/7 = Red packet ENQ discarded
    269  * CTR_FLEX_COUNT_8/9/10/11 = Total DEQ
    270  */
    271 _sb2_cosq_counter_mem_map_t _kt2_cosq_mem_map[] =
    272 {
    273     { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"},
    274     { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"},
    275     { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"},
    276     { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"},
    277     { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" },
    278     { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" },
    279     { CTR_FLEX_COUNT_6m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" },
    280     { CTR_FLEX_COUNT_7m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" },
    281     { CTR_FLEX_COUNT_8m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE"},
    282     { CTR_FLEX_COUNT_9m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE" },
    283     { CTR_FLEX_COUNT_10m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE"},
    284     { CTR_FLEX_COUNT_11m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE" },
    285 };
    286 
    287 /*
    288  * CTR_FLEX_COUNT_0 = Total ENQ discarded
    289  * CTR_FLEX_COUNT_1 = Total ENQ Accepted
    290  * CTR_FLEX_COUNT_2 = Green ENQ discarded
    291  * CTR_FLEX_COUNT_3 = Yellow ENQ discarded
    292  * CTR_FLEX_COUNT_4 = Red packet ENQ discarded
    293  * CTR_FLEX_COUNT_5 = Green ENQ Accepted
    294  * CTR_FLEX_COUNT_6 = Yellow ENQ Accepted
    295  * CTR_FLEX_COUNT_7 = Red ENQ Accepted
    296  * CTR_FLEX_COUNT_8 = Total DEQ
    297 */
    298 _sb2_cosq_counter_mem_map_t _kt2_cosq_gport_mem_map[] =
    299 {
    300     { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT },
    301     { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT },
    302     { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN },
    303     { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW },
    304     { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED },
    305     { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_GREEN },
    306     { CTR_FLEX_COUNT_6m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_YELLOW },
    307     { CTR_FLEX_COUNT_7m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_RED },
    308     { CTR_FLEX_COUNT_8m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT }
    309 };
    310 
    311 /*  
    312  * CTR_FLEX_COUNT_0/1 = Total ENQ discarded
    313  * CTR_FLEX_COUNT_2/3  = Red packet ENQ discarded
    314  * CTR_FLEX_COUNT_4/5  = Total DEQ
    315  */
    316 _sb2_cosq_counter_mem_map_t _sb2_cosq_mem_map[] =
    317 {
    318     { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"},
    319     { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"},
    320     { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" },
    321     { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" },
    322     { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE"},
    323     { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE" },
    324 };
    325 
    326 /* 
    327  * CTR_FLEX_COUNT_0 = Total ENQ discarded
    328  * CTR_FLEX_COUNT_1  = Red packet ENQ discarded
    329  * CTR_FLEX_COUNT_2  = Total DEQ
    330  */
    331 _sb2_cosq_counter_mem_map_t _dg2_cosq_mem_map[] =
    332 {
    333     { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"},
    334     { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" },
    335     { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE"},
    336 };
    337 
    338 /* 
    339  * CTR_FLEX_COUNT_0 = Total ENQ discarded
    340  * CTR_FLEX_COUNT_1 = Total ENQ Accepted
    341  * CTR_FLEX_COUNT_2 = Green ENQ discarded
    342  * CTR_FLEX_COUNT_3 = Yellow ENQ discarded
    343  * CTR_FLEX_COUNT_4 = Red packet ENQ discarded
    344  * CTR_FLEX_COUNT_5 = Total DEQ
    345 */
    346 _sb2_cosq_counter_mem_map_t _sb2_cosq_gport_mem_map[] =
    347 {
    348     { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT },
    349     { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT },
    350     { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN },
    351     { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW },
    352     { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED },
    353     { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT },
    354 };
    355 
    356 #if defined (BCM_METROLITE_SUPPORT)
    357 /*
    358  * CTR_FLEX_COUNT_0 = Total ENQ discarded
    359  * CTR_FLEX_COUNT_1  = Red packet ENQ discarded
    360  * CTR_FLEX_COUNT_2  = Total DEQ
    361  */
    362 _sb2_cosq_counter_mem_map_t _ml_cosq_mem_map[] =
    363 {   { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"},
    364     { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" },
    365     { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE" },
    366 };
    367 #endif
    368 #endif
    369 #ifdef BCM_KATANA2_SUPPORT
    370 void
    371 soc_sb2_cosq_counter_mem_map_get(int unit, int *num_elem,
    372                                  _sb2_cosq_counter_mem_map_t **mem_map)
    373 {
    374     uint16 dev_id;
    375     uint8 rev_id;
    376     soc_cm_get_id(unit, &dev_id, &rev_id);
    377 #if defined (BCM_METROLITE_SUPPORT)
    378      if (SOC_IS_METROLITE(0)) {
    379          *mem_map = _ml_cosq_mem_map;
    380          *num_elem = sizeof(_ml_cosq_mem_map)/sizeof(_sb2_cosq_counter_mem_map_t);
    381      } else 
    382 #endif
    383     if (dev_id == BCM56233_DEVICE_ID) {
    384         *mem_map = _dg2_cosq_mem_map;
    385         *num_elem = sizeof(_dg2_cosq_mem_map)/sizeof(_sb2_cosq_counter_mem_map_t);
    386      } else if (SOC_IS_SABER2(unit)) {
    387     *mem_map = _sb2_cosq_mem_map;
    388     *num_elem = sizeof(_sb2_cosq_mem_map)/sizeof(_sb2_cosq_counter_mem_map_t);
    389      } else {
    390         *mem_map = _kt2_cosq_mem_map;
    391         *num_elem = sizeof(_kt2_cosq_mem_map)/sizeof(_sb2_cosq_counter_mem_map_t);
    392      }
    393     
    394 }
    395 #endif
    396 
    397 int
    398 is_xaui_rx_counter(soc_reg_t ctr_reg)
    399 {
    400     switch (ctr_reg) {
    401     case IR64r:
    402     case IR127r:
    403     case IR255r:
    404     case IR511r:
    405     case IR1023r:
    406     case IR1518r:
    407     case IR2047r:
    408     case IR4095r:
    409     case IR9216r:
    410     case IR16383r:
    411     case IRBCAr:
    412     case IRBYTr:
    413     case IRERBYTr:
    414     case IRERPKTr:
    415     case IRFCSr:
    416     case IRFLRr:
    417     case IRFRGr:
    418     case IRJBRr:
    419     case IRJUNKr:
    420     case IRMAXr:
    421     case IRMCAr:
    422     case IRMEBr:
    423     case IRMEGr:
    424     case IROVRr:
    425     case IRPKTr:
    426     case IRUNDr:
    427     case IRXCFr:
    428     case IRXPFr:
    429     case IRXUOr:
    430 #ifdef BCM_TRX_SUPPORT
    431     case IRUCr:
    432 #ifdef BCM_ENDURO_SUPPORT
    433     case IRUCAr:
    434 #endif /* BCM_ENDURO_SUPPORT */
    435     case IRPOKr:
    436     case MAC_RXLLFCMSGCNTr:
    437 #endif
    438 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
    439     case IRXPPr:
    440 #endif
    441         return 1;
    442     default:
    443         break;
    444     }
    445     return 0;
    446 }
    447 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */
    448 
    449 #ifdef BCM_TRIDENT_SUPPORT
    450 STATIC int
    451 _soc_counter_trident_get_info(int unit, soc_port_t port, soc_reg_t id,
    452                               int *base_index, int *num_entries)
    453 {
    454     soc_control_t *soc;
    455     soc_info_t *si;
    456     soc_counter_non_dma_t *non_dma;
    457     soc_port_t phy_port, mmu_port;
    458     soc_port_t mmu_cmic_port, mmu_lb_port;
    459 
    460     soc = SOC_CONTROL(unit);
    461     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
    462 
    463     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    464         return SOC_E_UNAVAIL;
    465     }
    466 
    467     if (port < 0) {
    468         return SOC_E_PARAM;
    469     }
    470 
    471     si = &SOC_INFO(unit);
    472     if (si->port_l2p_mapping[port] == -1) {
    473         *base_index = 0;
    474         *num_entries = 0;
    475         return SOC_E_NONE;
    476     }
    477 
    478     mmu_cmic_port = si->port_p2m_mapping[si->port_l2p_mapping[si->cmic_port]];
    479     mmu_lb_port = si->port_p2m_mapping[si->port_l2p_mapping[si->lb_port]];
    480 
    481     phy_port = si->port_l2p_mapping[port];
    482     mmu_port = si->port_p2m_mapping[phy_port];
    483 
    484     switch (id) {
    485     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT:
    486     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE:
    487         if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* in X pipe */
    488             *base_index = si->port_cosq_base[port];
    489         } else { /* in Y pipe */
    490             *base_index = si->port_cosq_base[port] +
    491                 non_dma->dma_index_max[0] + 1;
    492         }
    493         *num_entries = si->port_num_cosq[port];
    494         break;
    495     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC:
    496     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC:
    497         if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* in X pipe */
    498             *base_index = si->port_uc_cosq_base[port];
    499         } else { /* in Y pipe */
    500             *base_index = si->port_uc_cosq_base[port] +
    501                 non_dma->dma_index_max[0] + 1;
    502         }
    503         *num_entries = si->port_num_uc_cosq[port];
    504         break;
    505     case SOC_COUNTER_NON_DMA_MMU_QCN_CNM:
    506         if((mmu_port == mmu_lb_port) || (mmu_port == mmu_cmic_port)){
    507             *num_entries = 0;
    508             *base_index = 0;
    509         }else{
    510             *num_entries = 2;/* 2 QCN queue per port */
    511             *base_index = port * (*num_entries);
    512         }
    513         break;
    514     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT:
    515     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT:
    516         if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* in X pipe */
    517             *base_index = si->port_ext_cosq_base[port];
    518         } else { /* in Y pipe */
    519             *base_index = si->port_ext_cosq_base[port] +
    520                 non_dma->dma_index_max[0] + 1;
    521         }
    522         *num_entries = si->port_num_ext_cosq[port];
    523         break;
    524     case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT:
    525     case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE:
    526         if (mmu_port == mmu_cmic_port) {
    527             *base_index = 0;
    528             *num_entries = 48;
    529         } else {
    530             *base_index = 48 + (mmu_port - mmu_cmic_port - 1) * 5;
    531             *num_entries = 5;
    532         }
    533         break;
    534     case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC:
    535     case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC:
    536         if (mmu_port < mmu_lb_port) { /* in X pipe */
    537             if (mmu_port == mmu_cmic_port) {
    538                 *base_index = 0;
    539                 *num_entries = 0;
    540             } else if (mmu_port <= mmu_cmic_port + 4) {
    541                 *base_index = (mmu_port - mmu_cmic_port - 1) * 74;
    542                 *num_entries = 74; /* 10 ucast + 64 ext ucast */
    543             } else {
    544                 *base_index = 74 * 4 + (mmu_port - mmu_cmic_port - 5) * 10;
    545                 *num_entries = 10;
    546             }
    547         } else { /* in Y pipe */
    548             if (mmu_port == mmu_lb_port) {
    549                 *base_index = 0;
    550                 *num_entries = 0;
    551             } else if (mmu_port <= mmu_lb_port + 4) {
    552                 *base_index = 576 + (mmu_port - mmu_lb_port - 1) * 74;
    553                 *num_entries = 74; /* 10 ucast + 64 ext ucast */
    554             } else {
    555                 *base_index = 576 + 74 * 4 + (mmu_port - mmu_lb_port - 5) * 10;
    556                 *num_entries = 10;
    557             }
    558         }
    559         break;
    560     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING:
    561     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING:
    562         *num_entries = 1;
    563         *base_index = port;
    564         break;
    565     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW:
    566     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED:
    567     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN:
    568     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW:
    569     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED:
    570         *num_entries = 1;
    571         *base_index = mmu_port;
    572         break;
    573     case SOC_COUNTER_NON_DMA_PG_MIN_PEAK:
    574     case SOC_COUNTER_NON_DMA_PG_MIN_CURRENT:
    575     case SOC_COUNTER_NON_DMA_PG_SHARED_PEAK:
    576     case SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT:
    577     case SOC_COUNTER_NON_DMA_PG_HDRM_PEAK:
    578     case SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT:
    579         *num_entries = 8;
    580         *base_index = port * (*num_entries);
    581         break;
    582     case SOC_COUNTER_NON_DMA_QUEUE_PEAK:
    583     case SOC_COUNTER_NON_DMA_QUEUE_CURRENT:
    584         *num_entries = 5;
    585         *base_index = port * (*num_entries);
    586         break;
    587     case SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK:
    588     case SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT:
    589         *num_entries = 10;
    590         *base_index = port * (*num_entries);
    591         break;
    592     case SOC_COUNTER_NON_DMA_EXT_QUEUE_PEAK:
    593     case SOC_COUNTER_NON_DMA_EXT_QUEUE_CURRENT:
    594         *num_entries = 64;
    595         *base_index = port * (*num_entries);
    596         break;
    597     case SOC_COUNTER_NON_DMA_POOL_PEAK:
    598     case SOC_COUNTER_NON_DMA_POOL_CURRENT:
    599         *base_index = 0;
    600         *num_entries = non_dma->num_entries;
    601         break;
    602     default:
    603         return SOC_E_INTERNAL;
    604     }
    605     *base_index += non_dma->base_index;
    606 
    607     return SOC_E_NONE;
    608 }
    609 #endif /* BCM_TRIDENT_SUPPORT */
    610 
    611 #if defined ( BCM_APACHE_SUPPORT )
    612 #define _AP_PBLKS_PER_PIPE            9
    613 #define _APACHE_XLPS_PER_PGW          9
    614 #define _APACHE_PORTS_PER_XLP         4
    615 
    616 #define _MONTEREY_XLPS_PER_PGW        8 
    617 #define _MN_PBLKS_PER_PIPE            8
    618 
    619 STATIC int
    620 _soc_counter_apache_get_child_dma_by_idx(int unit, soc_counter_non_dma_t *parent,
    621                                      int idx, soc_counter_non_dma_t **child)
    622 {
    623     int rv = SOC_E_NONE;
    624 
    625     if ((parent->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
    626         if (idx >= parent->extra_ctr_ct) {
    627             return SOC_E_PARAM;
    628         }
    629         *child = &parent->extra_ctrs[idx << 1];
    630     } else {
    631         *child = parent;
    632     }
    633     return rv;
    634 }
    635 
    636 /* For a given logical port, return the OBM id and the lane number */
    637 int
    638 soc_apache_port_obm_info_get(int unit, soc_port_t port,
    639                                int *obm_id, int *lane)
    640 {
    641     soc_info_t *si;
    642     soc_port_t phy_port;
    643     int obm, pgw;
    644 
    645     si = &SOC_INFO(unit);
    646     phy_port = si->port_l2p_mapping[port];
    647     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_MACSEC_PORT(unit, port) ||
    648         IS_RDB_PORT(unit, port)) {
    649         /*  nothing to do for non-idb ports */
    650         return SOC_E_NONE;
    651     }
    652 
    653     /* OBM group (num groups = num tsc's) belongs to PGW0/PGW1  */
    654     obm = si->port_serdes[port];
    655     if (SOC_IS_MONTEREY(unit)) {
    656         obm %= _MONTEREY_XLPS_PER_PGW; 
    657     } else { 
    658     obm %= _APACHE_XLPS_PER_PGW;
    659     }
    660 
    661     pgw = si->port_group[port];
    662     if (lane) {
    663         *lane = (phy_port - 1) % _APACHE_PORTS_PER_XLP;
    664         *lane += (pgw) ? 4 : 0;
    665     }
    666     if (obm_id) {
    667         *obm_id = obm;
    668     }
    669 
    670     return SOC_E_NONE;
    671 }
    672 
    673 STATIC int
    674 _soc_counter_apache_get_pgw_inst(int unit, soc_port_t port, 
    675                                  int *pgw_inst, int *lane)
    676 {
    677     soc_info_t *si;
    678     soc_port_t phy_port;
    679     int pgw;
    680 
    681     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_MACSEC_PORT(unit, port) ||
    682         IS_RDB_PORT(unit, port)) {
    683         /*  nothing to do for non-idb ports */
    684         return SOC_E_NONE;
    685     }
    686 
    687     si = &SOC_INFO(unit);
    688     phy_port = si->port_l2p_mapping[port];
    689     pgw = si->port_group[port];
    690     if (lane) {
    691         *lane = (phy_port - 1) % _APACHE_PORTS_PER_XLP;
    692     }
    693     if (pgw_inst) {
    694         *pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
    695     }
    696     return SOC_E_NONE;
    697 }
    698 
    699 STATIC int
    700 _soc_counter_apache_get_info(int unit, soc_port_t port, soc_reg_t id,
    701                               int *base_index, int *num_entries)
    702 {
    703     soc_info_t *si;
    704     soc_control_t *soc;
    705     soc_counter_non_dma_t *non_dma;
    706     soc_port_t phy_port = 0, mmu_port = 0;
    707     int obm_id, lane;
    708     int maxports = 75;
    709     soc = SOC_CONTROL(unit);
    710     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
    711 
    712     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    713         return SOC_E_UNAVAIL;
    714     }
    715 
    716     si = &SOC_INFO(unit);
    717     if (port >= 0  && port < maxports) {
    718         if (si->port_l2p_mapping[port] == -1) {
    719             *base_index = 0;
    720             *num_entries = 0;
    721             return SOC_E_NONE;
    722         }
    723 
    724         phy_port = si->port_l2p_mapping[port];
    725         mmu_port = si->port_p2m_mapping[phy_port];
    726     } else {
    727 
    728       mmu_port =-1 ;
    729 
    730     }
    731 
    732     switch (id) {
    733     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT:
    734     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE:
    735         if (mmu_port >= 0) {
    736 #ifdef BCM_MONTEREY_SUPPORT
    737             if (SOC_IS_MONTEREY(unit)) { 
    738                 *base_index =
    739                   soc_monterey_logical_qnum_hw_qnum(unit, port,
    740                                              si->port_cosq_base[port], 0);
    741             } else 
    742 #endif
    743            { 
    744                  *base_index =
    745                 soc_apache_logical_qnum_hw_qnum(unit, port,
    746                                              si->port_cosq_base[port], 0);
    747             } 
    748             *num_entries = si->port_num_cosq[port];
    749         } else {
    750             *base_index = port;
    751             *num_entries = non_dma->num_entries;
    752         }
    753         break;
    754     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC:
    755     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC:
    756         if (mmu_port >= 0) {
    757 #ifdef BCM_MONTEREY_SUPPORT 
    758             if (SOC_IS_MONTEREY(unit)) { 
    759                 *base_index =
    760                   soc_monterey_logical_qnum_hw_qnum(unit, port,
    761                                              si->port_uc_cosq_base[port], 1);
    762             } else 
    763 #endif
    764             { 
    765                 *base_index =
    766                     soc_apache_logical_qnum_hw_qnum(unit, port,
    767                                              si->port_uc_cosq_base[port], 1);
    768             }
    769             *num_entries = si->port_num_uc_cosq[port];
    770         } else {
    771             *base_index = 0;
    772             *num_entries = non_dma->num_entries;
    773         }
    774         break;
    775     case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT:
    776     case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE:
    777     case SOC_COUNTER_NON_DMA_QUEUE_PEAK:
    778     case SOC_COUNTER_NON_DMA_QUEUE_CURRENT:
    779         if (mmu_port >= 0) {
    780             *base_index = si->port_cosq_base[port];
    781             *num_entries = si->port_num_cosq[port];
    782         } else {
    783             *base_index = port;
    784             *num_entries = non_dma->num_entries;
    785         }
    786         break;
    787     case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC:
    788     case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC:
    789     case SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK:
    790     case SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT:
    791         if (mmu_port >= 0) {
    792             *base_index = si->port_uc_cosq_base[port];
    793             *num_entries = si->port_num_uc_cosq[port];
    794         } else {
    795             *base_index = 0;
    796             *num_entries = non_dma->num_entries;
    797         }
    798         break;
    799     case SOC_COUNTER_NON_DMA_MMU_QCN_CNM:        
    800         if (mmu_port >= 0) {
    801             *base_index = si->port_uc_cosq_base[port];
    802             *num_entries = si->port_num_uc_cosq[port];
    803         } else {
    804             *base_index = 0;     
    805             *num_entries = non_dma->num_entries;
    806         }
    807         break;
    808     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_HIGH_PRI:
    809     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_LOW_PRI:
    810     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_HIGH_PRI:
    811     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_LOW_PRI: 
    812     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_HIGH_PRI:
    813     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_LOW_PRI:
    814     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_HIGH_PRI:
    815     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_LOW_PRI:
    816     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_HIGH_PRI:
    817     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_LOW_PRI:
    818     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_HIGH_PRI:
    819     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_LOW_PRI:
    820     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_HIGH_PRI:
    821     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_LOW_PRI:
    822     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_HIGH_PRI:
    823     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_LOW_PRI:
    824         *base_index = (phy_port - 1) / 16 * 4;     
    825         *num_entries = 4;
    826         break;
    827     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT:
    828     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT:
    829         if (mmu_port >= 0) {
    830             *base_index = non_dma->dma_index_min[0]; 
    831             *num_entries = non_dma->dma_index_max[0] + 1; 
    832         } else {
    833             *base_index = 0;
    834             *num_entries = non_dma->num_entries;
    835         }
    836         break;
    837     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING:
    838     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING:
    839     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER:
    840     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER:
    841         if (mmu_port >= 0) {
    842             *num_entries = non_dma->entries_per_port;
    843             *base_index = mmu_port;
    844         } else {
    845             return SOC_E_INTERNAL;
    846         }
    847         break;
    848     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW:
    849     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED:
    850     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN:
    851     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW:
    852     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED:
    853         if ((mmu_port >= 0) && (mmu_port < 74)) {
    854             *base_index = (mmu_port & 0x7f) * non_dma->entries_per_port;
    855             *num_entries = non_dma->entries_per_port;
    856         } else {
    857             return SOC_E_INTERNAL;
    858         }
    859         break;
    860     case SOC_COUNTER_NON_DMA_PG_MIN_PEAK:
    861     case SOC_COUNTER_NON_DMA_PG_MIN_CURRENT:
    862     case SOC_COUNTER_NON_DMA_PG_SHARED_PEAK:
    863     case SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT:
    864     case SOC_COUNTER_NON_DMA_PG_HDRM_PEAK:
    865     case SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT:
    866         if (mmu_port >= 0) {
    867             *base_index = (mmu_port & 0x7f) * non_dma->entries_per_port;
    868             *num_entries = non_dma->entries_per_port;
    869         } else {
    870             return SOC_E_INTERNAL;
    871         }
    872         break;
    873     case SOC_COUNTER_NON_DMA_DROP_RQ_PKT:
    874     case SOC_COUNTER_NON_DMA_DROP_RQ_BYTE:
    875     case SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW:
    876     case SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED:
    877     case SOC_COUNTER_NON_DMA_POOL_PEAK:
    878     case SOC_COUNTER_NON_DMA_POOL_CURRENT:
    879     case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_PEAK:
    880     case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_CURRENT:
    881     case SOC_COUNTER_NON_DMA_E2E_DROP_COUNT:
    882         *base_index = 0;
    883         *num_entries = non_dma->num_entries;
    884         break;
    885     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO:
    886     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO:
    887     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI:
    888     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI:
    889     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0:
    890     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0:
    891     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1:
    892     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1:
    893     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS:
    894     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS:
    895     case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO:
    896     case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO:
    897     case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI:
    898     case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI:
    899     case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0:
    900     case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0:
    901     case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1:
    902     case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1:
    903     case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS:
    904     case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS:
    905         *base_index = 0;
    906         *num_entries = 1;
    907         lane = 0;
    908         /* find obm from the port number */
    909         SOC_IF_ERROR_RETURN
    910             (soc_apache_port_obm_info_get(unit, port, &obm_id, &lane));
    911         if (obm_id >= _AP_PBLKS_PER_PIPE) {
    912             return SOC_E_PARAM;
    913         }
    914         _soc_counter_apache_get_child_dma_by_idx(unit, non_dma, obm_id, &non_dma);
    915         *base_index += lane;
    916         break;
    917     default:
    918         return SOC_E_INTERNAL;
    919     }
    920     *base_index += non_dma->base_index;
    921 
    922     return SOC_E_NONE;
    923 }
    924 #endif /* BCM_APACHE_SUPPORT */
    925 
    926 #if defined(BCM_MONTEREY_SUPPORT) && defined (CPRIMOD_SUPPORT)
    927 STATIC int
    928 _soc_counter_monterey_cpri_get_info(int unit, soc_port_t port, soc_reg_t id,
    929                               int *base_index, int *num_entries)
    930 {
    931     soc_control_t *soc;
    932     soc_counter_non_dma_t *non_dma;
    933 
    934     soc = SOC_CONTROL(unit);
    935     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
    936 
    937     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    938         return SOC_E_UNAVAIL;
    939     }
    940 
    941     if ((id >= SOC_COUNTER_NON_DMA_CPRI_START) &&
    942         (id <= SOC_COUNTER_NON_DMA_CPRI_END)) {
    943         *base_index = port;
    944         *num_entries = non_dma->entries_per_port;
    945         *base_index += non_dma->base_index;
    946     }
    947 
    948     return SOC_E_NONE;
    949 }
    950 #endif /* BCM_MONTEREY_SUPPORT && CPRIMOD_SUPPORT */
    951 
    952 #if defined ( BCM_TRIDENT2_SUPPORT ) || defined ( BCM_TRIDENT2PLUS_SUPPORT )
    953 STATIC int
    954 _soc_counter_trident2_get_info(int unit, soc_port_t port, soc_reg_t id,
    955                               int *base_index, int *num_entries)
    956 {
    957     soc_info_t *si;
    958     soc_control_t *soc;
    959     soc_counter_non_dma_t *non_dma;
    960     soc_port_t phy_port, mmu_port;
    961     int pipe;
    962 
    963     soc = SOC_CONTROL(unit);
    964     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
    965 
    966     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    967         return SOC_E_UNAVAIL;
    968     }
    969 
    970     if (_soc_counter_non_dma_is_invalid(unit, non_dma->reg, port)) {
    971         return SOC_E_UNAVAIL;
    972     }
    973 
    974     si = &SOC_INFO(unit);
    975     if (port >= 0) {
    976         if (si->port_l2p_mapping[port] == -1) {
    977             *base_index = 0;
    978             *num_entries = 0;
    979             return SOC_E_NONE;
    980         }
    981 
    982         phy_port = si->port_l2p_mapping[port];
    983         mmu_port = si->port_p2m_mapping[phy_port];
    984         pipe = (mmu_port >= 64) ? 1 : 0;
    985     } else {
    986         phy_port = mmu_port = -1;
    987         pipe = -1;
    988     }
    989     COMPILER_REFERENCE(pipe);
    990 
    991     switch (id) {
    992     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT:
    993     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE:
    994         if (mmu_port >= 0) {
    995             *base_index =
    996                 soc_td2_logical_qnum_hw_qnum(unit, port,
    997                                              si->port_cosq_base[port], 0);
    998             *num_entries = si->port_num_cosq[port];
    999         } else {
   1000             *base_index = 0;
   1001             *num_entries = non_dma->num_entries;
   1002         }
   1003         break;
   1004     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC:
   1005     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC:
   1006         if (mmu_port >= 0) {
   1007             *base_index =
   1008                 soc_td2_logical_qnum_hw_qnum(unit, port,
   1009                                              si->port_uc_cosq_base[port], 1);
   1010             *num_entries = si->port_num_uc_cosq[port];
   1011         } else {
   1012             *base_index = 0;
   1013             *num_entries = non_dma->num_entries;
   1014         }
   1015         break;
   1016     case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT:
   1017     case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE:
   1018     case SOC_COUNTER_NON_DMA_QUEUE_PEAK:
   1019     case SOC_COUNTER_NON_DMA_QUEUE_CURRENT:
   1020         if (mmu_port >= 0) {
   1021             *base_index = si->port_cosq_base[port];
   1022             *num_entries = si->port_num_cosq[port];
   1023         } else {
   1024             *base_index = 0;
   1025             *num_entries = non_dma->num_entries;
   1026         }
   1027         break;
   1028     case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC:
   1029     case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC:
   1030     case SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK:
   1031     case SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT:
   1032         if (mmu_port >= 0) {
   1033             *base_index = si->port_uc_cosq_base[port];
   1034             *num_entries = si->port_num_uc_cosq[port];
   1035         } else {
   1036             *base_index = 0;
   1037             *num_entries = non_dma->num_entries;
   1038         }
   1039         break;
   1040     case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_EXT:
   1041     case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_EXT:
   1042         if (mmu_port >= 0) {
   1043             if (pipe > 0) {
   1044                 /*
   1045                  * Y-PIPE entries in DMA buffer is begging with 1480.
   1046                  */
   1047                 *base_index = 1480;
   1048                 *num_entries = non_dma->dma_index_max[1]
   1049                                - non_dma->dma_index_min[1] + 1;
   1050             } else {
   1051                 *base_index = 0;
   1052                 *num_entries = non_dma->dma_index_max[0] + 1;
   1053             }
   1054         } else {
   1055             *base_index = 0;
   1056             *num_entries = non_dma->num_entries;
   1057         }
   1058         break;
   1059     case SOC_COUNTER_NON_DMA_MMU_QCN_CNM:        
   1060         if (mmu_port >= 0) {
   1061             *base_index = si->port_uc_cosq_base[port];
   1062             *num_entries = si->port_num_uc_cosq[port];
   1063         } else {
   1064             *base_index = 0;     
   1065             *num_entries = non_dma->num_entries;
   1066         }
   1067         break;
   1068     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_HIGH_PRI:
   1069     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_LOW_PRI:
   1070     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_HIGH_PRI:
   1071     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_LOW_PRI:
   1072     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_HIGH_PRI:
   1073     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_LOW_PRI:
   1074     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_HIGH_PRI:
   1075     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_LOW_PRI:
   1076     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_HIGH_PRI:
   1077     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_LOW_PRI:
   1078     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_HIGH_PRI:
   1079     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_LOW_PRI:
   1080     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_HIGH_PRI:
   1081     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_LOW_PRI:
   1082     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_HIGH_PRI:
   1083     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_LOW_PRI:
   1084         *base_index = SOC_INFO(unit).port_group[port] * 4;
   1085         *num_entries = 4;
   1086         break;
   1087     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT:
   1088     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT:
   1089         if (mmu_port >= 0) {
   1090             *base_index = non_dma->dma_index_min[0];
   1091             *num_entries = non_dma->dma_index_max[0] + 1;
   1092             if (pipe > 0) {
   1093                 *base_index = non_dma->dma_index_max[0] + 1;
   1094             }
   1095         } else {
   1096             *base_index = 0;
   1097             *num_entries = non_dma->num_entries;
   1098         }
   1099         break;
   1100     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING:
   1101     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING:
   1102     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER:
   1103     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER:
   1104         if (mmu_port >= 0) {
   1105             *num_entries = non_dma->entries_per_port;
   1106             *base_index = mmu_port;
   1107         } else {
   1108             return SOC_E_INTERNAL;
   1109         }
   1110         break;
   1111     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW:
   1112     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED:
   1113     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN:
   1114     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW:
   1115     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED:
   1116         if (mmu_port >= 0) {
   1117             if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* in X pipe */
   1118                 *base_index = (mmu_port & 0x3f) * non_dma->entries_per_port;
   1119             } else { /* in Y pipe */
   1120                 *base_index = (mmu_port & 0x3f) * non_dma->entries_per_port +
   1121                     (non_dma->num_entries / 2);
   1122             }
   1123             *num_entries = non_dma->entries_per_port;
   1124         } else {
   1125             return SOC_E_INTERNAL;
   1126         }
   1127         break;
   1128     case SOC_COUNTER_NON_DMA_PG_MIN_PEAK:
   1129     case SOC_COUNTER_NON_DMA_PG_MIN_CURRENT:
   1130     case SOC_COUNTER_NON_DMA_PG_SHARED_PEAK:
   1131     case SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT:
   1132     case SOC_COUNTER_NON_DMA_PG_HDRM_PEAK:
   1133     case SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT:
   1134         if (mmu_port >= 0) {
   1135             if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* in X pipe */
   1136                 *base_index = (mmu_port & 0x3f) * non_dma->entries_per_port;
   1137             } else { /* in Y pipe */
   1138                 *base_index = (mmu_port & 0x3f) * non_dma->entries_per_port +
   1139                     non_dma->dma_index_max[0] + 1;
   1140             }
   1141             *num_entries = non_dma->entries_per_port;
   1142         } else {
   1143             return SOC_E_INTERNAL;
   1144         }
   1145         break;
   1146     case SOC_COUNTER_NON_DMA_DROP_RQ_PKT:
   1147     case SOC_COUNTER_NON_DMA_DROP_RQ_BYTE:
   1148     case SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW:
   1149     case SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED:
   1150     case SOC_COUNTER_NON_DMA_POOL_PEAK:
   1151     case SOC_COUNTER_NON_DMA_POOL_CURRENT:
   1152     case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_PEAK:
   1153     case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_CURRENT:
   1154     case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_Y_PEAK:
   1155     case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_Y_CURRENT:
   1156         *base_index = 0;
   1157         *num_entries = non_dma->num_entries;
   1158         break;
   1159     default:
   1160         return SOC_E_INTERNAL;
   1161     }
   1162     *base_index += non_dma->base_index;
   1163 
   1164     return SOC_E_NONE;
   1165 }
   1166 #endif /* BCM_TRIDENT2_SUPPORT || BCM_TRIDENT2PLUS_SUPPORT */
   1167 
   1168 #ifdef BCM_TRIUMPH3_SUPPORT
   1169 STATIC int
   1170 _soc_counter_triumph3_get_info(int unit, soc_port_t port, soc_reg_t id,
   1171                               int *base_index, int *num_entries)
   1172 {
   1173     soc_info_t *si;
   1174     soc_control_t *soc;
   1175     soc_counter_non_dma_t *non_dma;
   1176     soc_port_t phy_port, mmu_port;
   1177 
   1178     soc = SOC_CONTROL(unit);
   1179     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
   1180 
   1181     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
   1182         return SOC_E_UNAVAIL;
   1183     }
   1184 
   1185     si = &SOC_INFO(unit);
   1186     if (port >= 0) {
   1187         phy_port = si->port_l2p_mapping[port];
   1188         mmu_port = si->port_p2m_mapping[phy_port];
   1189     } else {
   1190         phy_port = mmu_port = -1;
   1191     }
   1192 
   1193     switch (id) {
   1194     case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT:
   1195     case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE:
   1196         if (mmu_port >= 0) {
   1197             if (mmu_port <= 39) {
   1198                 *base_index = mmu_port * 8;
   1199                 *num_entries = 8;
   1200             } else if (mmu_port <= 55) {
   1201                 *base_index = 320 + (mmu_port - 40) * 10;
   1202                 *num_entries = 10;
   1203             } else if (mmu_port == 56) {
   1204                 *base_index = 0x1e0;
   1205                 *num_entries = 8;
   1206             } else if (mmu_port == 57) {
   1207                 *num_entries = 0;
   1208             } else if (mmu_port == 58) {
   1209                 *base_index = 0x1e8;
   1210                 *num_entries = 8;
   1211             } else if (mmu_port == 59) {
   1212                 *base_index = 0x200;
   1213                 *num_entries = 48;
   1214             } else if (mmu_port == 60) {
   1215                 *base_index = 0x1f0;
   1216                 *num_entries = 8;
   1217             } else if (mmu_port == 61) {
   1218                 *base_index = 0x1f8;
   1219                 *num_entries = 1;
   1220             } else {
   1221                 return SOC_E_PARAM;
   1222             }
   1223         } else {
   1224             *base_index = 0;
   1225             *num_entries = 560;
   1226         }
   1227         break;
   1228     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT:
   1229     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE:
   1230         if (mmu_port >= 0) {
   1231             *base_index = si->port_cosq_base[port] + 1024;
   1232             *num_entries = si->port_num_cosq[port];
   1233         } else {
   1234             *base_index = 0;
   1235             *num_entries = 1592;
   1236         }
   1237         break;
   1238     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC:
   1239     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC:
   1240         if (mmu_port >= 0) {
   1241             *base_index = si->port_uc_cosq_base[port];
   1242             *num_entries = si->port_num_uc_cosq[port];
   1243         } else {
   1244             *base_index = 0;
   1245             *num_entries = 1592;
   1246         }
   1247         break;
   1248     case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC:
   1249     case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC:
   1250     case SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK:
   1251     case SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT:
   1252         if (mmu_port >= 0) {
   1253             *base_index = si->port_uc_cosq_base[port];
   1254             *num_entries = si->port_num_uc_cosq[port];
   1255         } else {
   1256             *base_index = 0;
   1257             *num_entries = 1024;
   1258         }
   1259         break;
   1260     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING:
   1261     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING:
   1262         *num_entries = 1;
   1263         *base_index = port;
   1264         break;
   1265     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW:
   1266     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED:
   1267     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN:
   1268     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW:
   1269     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED:
   1270         if (mmu_port >= 0) {
   1271             *num_entries = 1;
   1272             *base_index = mmu_port;
   1273         } else {
   1274             return SOC_E_INTERNAL;
   1275         }
   1276         break;
   1277     case SOC_COUNTER_NON_DMA_PG_MIN_PEAK:
   1278     case SOC_COUNTER_NON_DMA_PG_MIN_CURRENT:
   1279     case SOC_COUNTER_NON_DMA_PG_SHARED_PEAK:
   1280     case SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT:
   1281     case SOC_COUNTER_NON_DMA_PG_HDRM_PEAK:
   1282     case SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT:
   1283         if (mmu_port >= 0) {
   1284             *num_entries = 8;
   1285             *base_index = mmu_port * (*num_entries);
   1286         } else {
   1287             *base_index = 0;
   1288             *num_entries = 504;
   1289         }
   1290         break;
   1291     case SOC_COUNTER_NON_DMA_QUEUE_PEAK:
   1292     case SOC_COUNTER_NON_DMA_QUEUE_CURRENT:
   1293         *num_entries = 48;
   1294         *base_index = port * (*num_entries);
   1295         break;
   1296     case SOC_COUNTER_NON_DMA_POOL_PEAK:
   1297     case SOC_COUNTER_NON_DMA_POOL_CURRENT:
   1298         *base_index = 0;
   1299         *num_entries = non_dma->num_entries;
   1300         break;
   1301     default:
   1302         return SOC_E_INTERNAL;
   1303     }
   1304     *base_index += non_dma->base_index;
   1305 
   1306     return SOC_E_NONE;
   1307 }
   1308 #endif /* BCM_TRIUMPH3_SUPPORT */
   1309 
   1310 #ifdef BCM_KATANA_SUPPORT
   1311 STATIC int
   1312 _soc_counter_katana_get_info(int unit, soc_port_t port, soc_reg_t id,
   1313                               int *base_index, int *num_entries)
   1314 {
   1315     soc_control_t *soc;
   1316     soc_counter_non_dma_t *non_dma;
   1317     int max_ports = 0;
   1318 #if defined (BCM_SABER2_SUPPORT)
   1319     soc_info_t *si = &SOC_INFO(unit);
   1320 #endif
   1321     soc = SOC_CONTROL(unit);
   1322     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
   1323 
   1324     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
   1325         return SOC_E_UNAVAIL;
   1326     }
   1327 
   1328     max_ports = (SOC_IS_KATANA(unit)) ? SOC_MAX_NUM_PORTS :
   1329                                         SOC_MAX_NUM_PP_PORTS;
   1330 #if defined (BCM_SABER2_SUPPORT)
   1331              if (SOC_IS_SABER2(unit)) {
   1332                  max_ports = si->cpu_hg_pp_port_index;
   1333              }
   1334 #endif
   1335     if (port >= 0 ) {
   1336         if (port < max_ports) {
   1337             if (SOC_IS_KATANA2(unit)) {
   1338                *base_index = SOC_INFO(unit).port_uc_cosq_base[port];
   1339             } 
   1340             else if (SOC_IS_KATANAX(unit)) {
   1341                *base_index = SOC_INFO(unit).port_cosq_base[port];
   1342             }
   1343             *num_entries = SOC_INFO(unit).port_num_uc_cosq[port];
   1344             *base_index += non_dma->base_index;
   1345         } else {
   1346             /* extended queues */
   1347             *base_index = port;
   1348             *num_entries = non_dma->num_entries;
   1349             *base_index += non_dma->base_index;
   1350         }
   1351     }
   1352 
   1353     return SOC_E_NONE;
   1354 }
   1355 #endif /* BCM_KATANA_SUPPORT */
   1356 #ifdef BCM_KATANA2_SUPPORT
   1357 int
   1358 _soc_counter_katana2_get_mcindex(int unit, soc_port_t port, soc_reg_t id,
   1359                               int *base_index, int *num_entries)
   1360 {
   1361     soc_control_t *soc;
   1362     soc_counter_non_dma_t *non_dma;
   1363     int max_ports = 0;
   1364     soc = SOC_CONTROL(unit);
   1365     if (id < NUM_SOC_REG) {
   1366         return SOC_E_PARAM;
   1367     } 
   1368     if (id >= SOC_COUNTER_NON_DMA_END) {
   1369         return SOC_E_PARAM;
   1370     }
   1371     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
   1372     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
   1373         return SOC_E_UNAVAIL;
   1374     }
   1375     max_ports = SOC_MAX_NUM_PP_PORTS;
   1376 
   1377     if (port >= 0 ) {
   1378         if (port < max_ports) {
   1379                *base_index = SOC_INFO(unit).port_cosq_base[port];
   1380             *num_entries = SOC_INFO(unit).port_num_uc_cosq[port];
   1381             *base_index += non_dma->base_index;
   1382         } else {
   1383             *base_index = -1;
   1384         }
   1385     }
   1386 
   1387     return SOC_E_NONE;
   1388 }
   1389 #endif 
   1390 
   1391 #ifdef BCM_GREYHOUND2_SUPPORT
   1392 STATIC int
   1393 _soc_counter_gh2_get_info(int unit, soc_port_t port, soc_reg_t id,
   1394                           int *base_index, int *num_entries)
   1395 {
   1396     soc_control_t *soc;
   1397     soc_counter_non_dma_t *non_dma;
   1398     soc_port_t phy_port, mmu_port;
   1399     int i;
   1400 
   1401     if ((NULL == base_index) || (NULL == num_entries)) {
   1402         return SOC_E_PARAM;
   1403     }
   1404 
   1405     soc = SOC_CONTROL(unit);
   1406     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
   1407 
   1408     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
   1409         return SOC_E_UNAVAIL;
   1410     }
   1411 
   1412     if (port >= 0) {
   1413         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   1414         mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
   1415     } else {
   1416         phy_port = mmu_port = -1;
   1417     }
   1418 
   1419     if (non_dma->entries_per_port == 1) {
   1420         /* This non-dma counter is per port */
   1421         *base_index = non_dma->base_index + port;
   1422         *num_entries = 1;
   1423     } else {
   1424         switch (id) {
   1425         case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT:
   1426         case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE:
   1427             if (mmu_port >= 0) {
   1428                 if (mmu_port >= SOC_GH2_64Q_MMU_PORT_IDX_MIN) {
   1429                     /* Port with 64 COSQ */
   1430                     *num_entries = SOC_GH2_2LEVEL_QUEUE_NUM;
   1431                     *base_index =
   1432                         (SOC_GH2_64Q_MMU_PORT_IDX_MIN *
   1433                         SOC_GH2_LEGACY_QUEUE_NUM) +
   1434                         ((mmu_port - SOC_GH2_64Q_MMU_PORT_IDX_MIN) *
   1435                         (*num_entries));
   1436                 } else {
   1437                      /* Port with 8 COSQ */
   1438                     *num_entries = SOC_GH2_LEGACY_QUEUE_NUM;
   1439                     *base_index = mmu_port * (*num_entries);
   1440                 }
   1441             } else {
   1442                 *base_index = 0;
   1443                 *num_entries =
   1444                     (SOC_GH2_64Q_MMU_PORT_IDX_MIN *
   1445                     SOC_GH2_LEGACY_QUEUE_NUM) +
   1446                     ((SOC_GH2_64Q_MMU_PORT_IDX_MAX -
   1447                     SOC_GH2_64Q_MMU_PORT_IDX_MIN + 1) *
   1448                     SOC_GH2_2LEVEL_QUEUE_NUM);
   1449             }
   1450             *base_index += non_dma->base_index;
   1451             break;
   1452         case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT:
   1453             *base_index = non_dma->base_index;
   1454             for (i = 0; i < SOC_MAX_NUM_PORTS; i++) {
   1455                 if (i == port) {
   1456                     break;
   1457                 }
   1458                 *base_index += SOC_GH2_2LEVEL_QUEUE_NUM;
   1459             }
   1460             *num_entries = SOC_GH2_2LEVEL_QUEUE_NUM;
   1461             break;
   1462         default:
   1463             *base_index = non_dma->base_index;
   1464             for (i = 0; i < SOC_MAX_NUM_PORTS; i++) {
   1465                 if (i == port) {
   1466                     break;
   1467                 }
   1468                 *base_index += num_cosq[unit][i];
   1469             }
   1470             *num_entries = num_cosq[unit][port];
   1471             return SOC_E_NONE;
   1472         }
   1473     }
   1474 
   1475     return SOC_E_NONE;
   1476 }
   1477 #endif /* BCM_GREYHOUND2_SUPPORT */
   1478 
   1479 #ifdef BCM_FIREBOLT_SUPPORT
   1480 STATIC int
   1481 _soc_counter_fb_get_info(int unit, soc_port_t port, soc_reg_t id,
   1482                          int *base_index, int *num_entries)
   1483 {
   1484     soc_control_t *soc;
   1485     soc_counter_non_dma_t *non_dma;
   1486     int i;
   1487 
   1488     soc = SOC_CONTROL(unit);
   1489     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
   1490 
   1491     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
   1492         return SOC_E_UNAVAIL;
   1493     }
   1494 
   1495     if (non_dma->entries_per_port == 1) {
   1496         /* This non-dma counter is per port */
   1497         *base_index = non_dma->base_index + port;
   1498         *num_entries = 1;
   1499     } else {
   1500         if (SOC_IS_SC_CQ(unit)) {
   1501             /* This non-dma counter is per cosq */
   1502             if (non_dma->flags & _SOC_COUNTER_NON_DMA_PERQ_REG) {
   1503                 *base_index = non_dma->base_index;
   1504                 for (i = 0; i < SOC_MAX_NUM_PORTS; i++) {
   1505                     if (i == port) {
   1506                         break;
   1507                     }
   1508                     *base_index += num_cosq[unit][i];
   1509                 }
   1510                 *num_entries = num_cosq[unit][port];
   1511             } else {
   1512                 /* This non-dma counter is per uc/mc q */
   1513                 *base_index = non_dma->base_index +
   1514                               (non_dma->entries_per_port * port);
   1515                 *num_entries = non_dma->entries_per_port;
   1516             }
   1517         } else {
   1518             *base_index = non_dma->base_index;
   1519             for (i = 0; i < SOC_MAX_NUM_PORTS; i++) {
   1520                 if (i == port) {
   1521                     break;
   1522                 }
   1523                 *base_index += num_cosq[unit][i];
   1524             }
   1525             *num_entries = num_cosq[unit][port];
   1526         }
   1527     }
   1528 
   1529     return SOC_E_NONE;
   1530 }
   1531 #endif /* BCM_FIREBOLT_SUPPORT */
   1532 
   1533 #ifdef BCM_SHADOW_SUPPORT
   1534 STATIC int
   1535 _soc_counter_shadow_get_info(int unit, soc_port_t port, soc_reg_t id,
   1536                          int *base_index, int *num_entries)
   1537 {
   1538     soc_control_t *soc;
   1539     soc_counter_non_dma_t *non_dma;
   1540 
   1541     soc = SOC_CONTROL(unit);
   1542     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
   1543 
   1544     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
   1545         return SOC_E_UNAVAIL;
   1546     }
   1547 
   1548     *base_index = non_dma->base_index;
   1549     *num_entries = 1;
   1550 
   1551     return SOC_E_NONE;
   1552 }
   1553 #endif /* BCM_SHADOW_SUPPORT */
   1554 
   1555 int
   1556 _soc_controlled_counter_get_info(int unit, soc_port_t port, soc_reg_t ctr_reg,
   1557                             int *base_index, int *num_entries, char **cname)
   1558 {
   1559     soc_control_t       *soc = SOC_CONTROL(unit);
   1560 
   1561     if (ctr_reg < 0) {
   1562         return SOC_E_PARAM;
   1563     }
   1564 
   1565     if (soc->controlled_counters == NULL) {
   1566         return SOC_E_UNAVAIL;
   1567     }
   1568 
   1569     if(!COUNTER_IS_COLLECTED(soc->controlled_counters[ctr_reg])) {
   1570         return SOC_E_PARAM;
   1571     }
   1572 
   1573     {
   1574         *base_index = COUNTER_IDX_PORTBASE(unit, port) + soc->controlled_counters[ctr_reg].counter_idx;
   1575         *num_entries = 1; /* MAC counters are non-array */
   1576     }
   1577 
   1578     if (NULL != cname) {
   1579         *cname = soc->controlled_counters[ctr_reg].cname;
   1580     }
   1581 
   1582     return SOC_E_NONE;
   1583 }
   1584 
   1585 #ifdef BCM_PETRA_SUPPORT
   1586 STATIC int
   1587 _soc_counter_arad_get_info(int unit, soc_port_t port, soc_reg_t ctr_reg,
   1588                             int *base_index, int *num_entries, char **cname)
   1589 {
   1590     int rv = SOC_E_NONE;
   1591 
   1592     if (_SOC_CONTROLLED_COUNTER_USE(unit, port)) {
   1593         rv = _soc_controlled_counter_get_info(unit, port, ctr_reg, base_index,
   1594                                              num_entries, cname);
   1595 
   1596     }  else if (ctr_reg >= NUM_SOC_REG) {
   1597         if (ctr_reg >= SOC_COUNTER_NON_DMA_END) {
   1598             return SOC_E_PARAM;
   1599         } else {
   1600             /*non dma counters*/
   1601             return SOC_E_UNAVAIL;
   1602         }
   1603     } else  {
   1604         *base_index = COUNTER_IDX_PORTBASE(unit, port) +
   1605             SOC_REG_CTR_IDX(unit, ctr_reg) + _SOC_CONTROLLED_COUNTER_NOF(unit)/*added shift for tbe controlled registers*/;
   1606 
   1607         *num_entries = SOC_REG_NUMELS(unit, ctr_reg);
   1608         if (cname) {
   1609             *cname = SOC_REG_NAME(unit, ctr_reg);
   1610         }
   1611     }
   1612     return rv;
   1613 
   1614 }
   1615 #endif /* BCM_PETRA_SUPPORT */
   1616 
   1617 #ifdef SOC_COUNTER_TABLE_SUPPORT
   1618 STATIC int
   1619 _soc_counter_tbl_get_info(int unit, soc_port_t port, int ctr_reg,
   1620                           soc_ctr_tbl_entry_t **entry) {
   1621     int i;
   1622     int ctr_fld;
   1623     soc_ctr_tbl_info_t   *ctr_tbl_info = SOC_CTR_TBL_INFO(unit);
   1624     soc_ctr_tbl_entry_t  *ctr_tbl_entry = NULL;
   1625     int entry_num = 0;
   1626 
   1627     if ((entry == NULL) || (ctr_reg < SOC_COUNTER_TABLE_FIELD_START)) {
   1628          return SOC_E_PARAM;
   1629      }
   1630  
   1631     ctr_tbl_entry = ctr_tbl_info->tables;
   1632     entry_num = ctr_tbl_info->num;
   1633 
   1634     ctr_fld = ctr_reg - SOC_COUNTER_TABLE_FIELD_START;
   1635 
   1636     for(i=0; i < entry_num; i++) {
   1637         if(ctr_fld == ctr_tbl_entry->ctr_field) {
   1638             *entry = ctr_tbl_entry;
   1639             return SOC_E_NONE;
   1640         }
   1641         ctr_tbl_entry++;
   1642     }
   1643 
   1644     return SOC_E_NOT_FOUND;
   1645 }
   1646 #endif /* SOC_COUNTER_TABLE_SUPPORT */
   1647 
   1648 STATIC int
   1649 _soc_counter_get_info(int unit, soc_port_t port, soc_reg_t ctr_reg,
   1650                       int *base_index, int *num_entries, char **cname)
   1651 {
   1652     int rv;
   1653 #ifdef BCM_TOMAHAWK_SUPPORT
   1654     soc_reg_t ctr_reg_offset = ctr_reg;
   1655 #endif /* BCM_TOMAHAWK_SUPPORT */
   1656 #ifdef SOC_COUNTER_TABLE_SUPPORT
   1657     soc_ctr_tbl_entry_t *ctr_tbl_entry = NULL;
   1658 #endif /* SOC_COUNTER_TABLE_SUPPORT */
   1659 
   1660     if ((!(SOC_IS_TD2_TT2(unit) || SOC_IS_TRIUMPH3(unit) ||
   1661            SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit))) && (port < 0)) {
   1662         return SOC_E_PARAM;
   1663     }
   1664 
   1665 #ifdef BCM_PETRA_SUPPORT
   1666     if (SOC_IS_ARAD(unit)) {
   1667         rv = _soc_counter_arad_get_info(unit, port, ctr_reg, base_index,
   1668                                          num_entries, cname);
   1669         return rv;
   1670     }
   1671 #endif /* BCM_PETRA_SUPPORT */
   1672 
   1673     if (soc_feature(unit, soc_feature_controlled_counters)) {
   1674             rv = _soc_controlled_counter_get_info(unit, port, ctr_reg, base_index,
   1675                                              num_entries, cname);
   1676             return rv;
   1677     }
   1678 
   1679     if ((ctr_reg >= SOC_COUNTER_NON_DMA_START) &&
   1680         (ctr_reg < SOC_COUNTER_NON_DMA_END)) {
   1681 #ifdef BCM_TOMAHAWK_SUPPORT
   1682         if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   1683             /* TH has encodings for ctr_reg */
   1684             ctr_reg &= 0x80ffffff;
   1685         }
   1686 #endif /* BCM_TOMAHAWK_SUPPORT */
   1687 
   1688         if (ctr_reg >= SOC_COUNTER_NON_DMA_END) {
   1689             return SOC_E_PARAM;
   1690         }
   1691 
   1692 #ifdef BCM_TOMAHAWK_SUPPORT
   1693         if (SOC_IS_TOMAHAWKX(unit)) {
   1694             rv = soc_counter_tomahawk_get_info(unit, port, ctr_reg_offset,
   1695                                                 base_index, num_entries);
   1696         } else
   1697 #endif /* BCM_TOMAHAWK_SUPPORT */
   1698 #ifdef BCM_TRIDENT3_SUPPORT
   1699         if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) {
   1700             rv = soc_counter_trident3_get_info(unit, port, ctr_reg_offset,
   1701                                                 base_index, num_entries);
   1702         } else
   1703 #endif /* BCM_TRIDENT3_SUPPORT */
   1704 
   1705 #if defined (BCM_MONTEREY_SUPPORT) && defined (CPRIMOD_SUPPORT)
   1706         /*
   1707          * This will be used only for CPRI counters.
   1708          * For all the other counters info, Monterey uses Apache
   1709          * counter get info.
   1710          */
   1711         if ((SOC_IS_MONTEREY(unit)) &&
   1712             ((ctr_reg >= SOC_COUNTER_NON_DMA_CPRI_START) &&
   1713             (ctr_reg <= SOC_COUNTER_NON_DMA_CPRI_END))) {
   1714             rv = _soc_counter_monterey_cpri_get_info(unit, port, ctr_reg,
   1715                                                      base_index, num_entries);
   1716         } else
   1717 #endif /* BCM_MONTEREY_SUPPORT && CPRIMOD_SUPPORT */
   1718 
   1719 #ifdef BCM_HELIX5_SUPPORT
   1720         if (SOC_IS_HELIX5(unit)) {
   1721             rv = soc_counter_helix5_get_info(unit, port, ctr_reg_offset,
   1722                                                 base_index, num_entries);
   1723         } else
   1724 #endif /* BCM_HELIX5_SUPPORT */
   1725 #ifdef BCM_APACHE_SUPPORT
   1726         if (SOC_IS_APACHE(unit)) {
   1727             rv = _soc_counter_apache_get_info(unit, port, ctr_reg,
   1728                                                 base_index, num_entries);
   1729         } else
   1730 #endif /* BCM_APACHE_SUPPORT */
   1731 #if defined ( BCM_TRIDENT2_SUPPORT ) || defined ( BCM_TRIDENT2PLUS_SUPPORT )
   1732         if (SOC_IS_TD2_TT2(unit)) {
   1733             rv = _soc_counter_trident2_get_info(unit, port, ctr_reg, base_index,
   1734                                                num_entries);
   1735         } else
   1736 #endif /* BCM_TRIDENT2_SUPPORT || BCM_TRIDENT2PLUS_SUPPORT */
   1737 #ifdef BCM_TRIDENT_SUPPORT
   1738         if (SOC_IS_TD_TT(unit)) {
   1739             rv = _soc_counter_trident_get_info(unit, port, ctr_reg, base_index,
   1740                                                num_entries);
   1741         } else
   1742 #endif /* BCM_TRIDENT_SUPPORT */
   1743 #ifdef BCM_TRIUMPH3_SUPPORT
   1744         if (SOC_IS_TRIUMPH3(unit)) {
   1745             rv = _soc_counter_triumph3_get_info(unit, port, ctr_reg, base_index,
   1746                                                num_entries);
   1747         } else
   1748 #endif /* BCM_TRIUMPH3_SUPPORT */
   1749 #ifdef BCM_KATANA_SUPPORT
   1750         if (SOC_IS_KATANAX(unit)) {
   1751             rv = _soc_counter_katana_get_info(unit, port, ctr_reg, base_index,
   1752                                                num_entries);
   1753         } else
   1754 #endif /* BCM_KATANA_SUPPORT */
   1755 #ifdef BCM_GREYHOUND2_SUPPORT
   1756         if (SOC_IS_GREYHOUND2(unit)) {
   1757             rv = _soc_counter_gh2_get_info(unit, port, ctr_reg, base_index,
   1758                                            num_entries);
   1759         } else
   1760 #endif /* BCM_GREYHOUND2_SUPPORT */
   1761 #ifdef BCM_FIREBOLT_SUPPORT
   1762         if (SOC_IS_FBX(unit) && !(SOC_IS_SHADOW(unit))) {
   1763             rv = _soc_counter_fb_get_info(unit, port, ctr_reg, base_index,
   1764                                           num_entries);
   1765         } else
   1766 #endif /* BCM_FIREBOLT_SUPPORT */
   1767 #ifdef BCM_SHADOW_SUPPORT
   1768         if (SOC_IS_SHADOW(unit)) {
   1769             rv = _soc_counter_shadow_get_info(unit, port, ctr_reg, base_index,
   1770                                           num_entries);
   1771         } else
   1772 #endif /* BCM_SHADOW_SUPPORT */
   1773         {
   1774             rv = SOC_E_UNAVAIL;
   1775         }
   1776 
   1777         if (rv < 0) {
   1778             return rv;
   1779         }
   1780         if (cname) {
   1781             *cname = SOC_CONTROL(unit)->
   1782                 counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].cname;
   1783         }
   1784 
   1785     } else {
   1786         if ((ctr_reg < SOC_COUNTER_NON_DMA_START) &&
   1787             !SOC_REG_IS_ENABLED(unit, ctr_reg)) {
   1788             return SOC_E_PARAM;
   1789         }
   1790 #ifdef BCM_SHADOW_SUPPORT
   1791         if (SOC_IS_SHADOW(unit) && IS_IL_PORT(unit, port)) {
   1792             return SOC_E_PORT;
   1793         }
   1794 #endif /* BCM_SHADOW_SUPPORT */
   1795 
   1796 #ifdef SOC_COUNTER_TABLE_SUPPORT
   1797         if (SOC_IS_TOMAHAWK3(unit)) {
   1798             if(ctr_reg >= SOC_COUNTER_TABLE_FIELD_START) {
   1799                 SOC_IF_ERROR_RETURN(
   1800                     _soc_counter_tbl_get_info(unit, port, ctr_reg, &ctr_tbl_entry));
   1801                 *num_entries = 1;
   1802                 *base_index = COUNTER_IDX_PORTBASE(unit, port) + ctr_tbl_entry->ctr_idx;
   1803                 if (cname) {
   1804                     *cname = SOC_FIELD_NAME(unit, (ctr_tbl_entry->ctr_field - SOC_COUNTER_TABLE_FIELD_START));
   1805                 }
   1806                 return SOC_E_NONE;
   1807             }
   1808         }
   1809 #endif /* SOC_COUNTER_TABLE_SUPPORT */
   1810 
   1811         if(!SOC_REG_IS_VALID(unit, ctr_reg)) {
   1812             return SOC_E_PARAM;
   1813         }
   1814 
   1815         *base_index = COUNTER_IDX_PORTBASE(unit, port) +
   1816             SOC_REG_CTR_IDX(unit, ctr_reg);
   1817         if (SOC_IS_TRIUMPH3(unit)) {
   1818             *base_index -= 0x20;
   1819         }
   1820 #ifdef BCM_HURRICANE2_SUPPORT
   1821         if (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit) || \
   1822             SOC_IS_GREYHOUND(unit)) {
   1823             *base_index -= 0x37;
   1824         }
   1825 #endif /* BCM_HURRICANE2_SUPPORT */
   1826 #ifdef BCM_GREYHOUND2_SUPPORT
   1827         if (SOC_IS_GREYHOUND2(unit)) {
   1828             *base_index -= 0x6f;
   1829         }
   1830 #endif /* BCM_GREYHOUND2_SUPPORT */
   1831         *num_entries = SOC_REG_NUMELS(unit, ctr_reg);
   1832         if (cname) {
   1833             *cname = SOC_REG_NAME(unit, ctr_reg);
   1834         }
   1835     }
   1836 
   1837     return SOC_E_NONE;
   1838 }
   1839 
   1840 #ifdef SOC_COUNTER_TABLE_SUPPORT
   1841 STATIC int
   1842 _soc_ctr_tbl_field_get(int unit, soc_reg_t ctr_reg, int port,
   1843                        soc_ctr_tbl_entry_t *ctr_tbl_info_entry,
   1844                        uint64 *ctr_val) {
   1845     soc_mem_t       mem;
   1846     soc_field_t     ctr_fld;
   1847     soc_format_t    format;
   1848     int             copyno, index;
   1849     uint32          row_ent[16];            
   1850     uint32          fval[2];
   1851     int             phy_port;
   1852 
   1853     if(ctr_reg < SOC_COUNTER_TABLE_FIELD_START) {
   1854         return SOC_E_PARAM;
   1855     }
   1856 
   1857     if(ctr_tbl_info_entry == NULL || ctr_val == NULL) {
   1858         return SOC_E_PARAM;
   1859     }
   1860 
   1861     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   1862     phy_port -= SOC_COUNTER_TABLE_BASE_PORT;
   1863     ctr_fld = ctr_tbl_info_entry->ctr_field;
   1864     mem = ctr_tbl_info_entry->mem;
   1865     format = ctr_tbl_info_entry->format;
   1866     index = (phy_port % NUM_PORTS_PER_CDMIB_MEM) * NUM_CDMIB_MEM_ROWS_PER_PORT
   1867             + ctr_tbl_info_entry->row_offset;
   1868     copyno = SOC_MEM_BLOCK_MIN(unit, mem) +
   1869             (phy_port / NUM_PORTS_PER_CDMIB_MEM);
   1870 
   1871     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, copyno, index, row_ent));
   1872     soc_format_field_get(unit, format, row_ent, ctr_fld, fval);
   1873     COMPILER_64_SET(*ctr_val, fval[1], fval[0]);
   1874 
   1875     return SOC_E_NONE;
   1876 }
   1877 
   1878 STATIC int
   1879 _soc_ctr_tbl_field_set(int unit, soc_reg_t ctr_reg, int port,
   1880                        soc_ctr_tbl_entry_t *ctr_tbl_info_entry,
   1881                        uint64 *ctr_val) {
   1882     soc_mem_t       mem;
   1883     soc_field_t     ctr_fld;
   1884     soc_format_t    format;
   1885     int             copyno, index;
   1886     uint32          row_ent[16];        
   1887     uint32          fval[2];
   1888     int             phy_port;
   1889 
   1890     if(ctr_reg < SOC_COUNTER_TABLE_FIELD_START) {
   1891         return SOC_E_PARAM;
   1892     }
   1893 
   1894     if(ctr_tbl_info_entry == NULL || ctr_val == NULL) {
   1895         return SOC_E_PARAM;
   1896     }
   1897 
   1898     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   1899     phy_port -= SOC_COUNTER_TABLE_BASE_PORT;
   1900     ctr_fld = ctr_tbl_info_entry->ctr_field;
   1901     mem = ctr_tbl_info_entry->mem;
   1902     format = ctr_tbl_info_entry->format;
   1903     index = (phy_port % NUM_PORTS_PER_CDMIB_MEM) * NUM_CDMIB_MEM_ROWS_PER_PORT
   1904             + ctr_tbl_info_entry->row_offset;
   1905     copyno = SOC_MEM_BLOCK_MIN(unit, mem) +
   1906             (phy_port / NUM_PORTS_PER_CDMIB_MEM);
   1907 
   1908     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, copyno, index, row_ent));
   1909     COMPILER_64_TO_32_HI(fval[1], *ctr_val);
   1910     COMPILER_64_TO_32_LO(fval[0], *ctr_val);
   1911     soc_format_field_set(unit, format, row_ent, ctr_fld, fval);
   1912     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, copyno, index, row_ent));
   1913 
   1914     return SOC_E_NONE;
   1915 }
   1916 #endif /* SOC_COUNTER_TABLE_SUPPORT */
   1917 
   1918 /*
   1919  * Function:
   1920  *      soc_counter_idx_get
   1921  * Purpose:
   1922  *      Get the index of a counter given the counter and port
   1923  * Parameters:
   1924  *      unit - The SOC unit number
   1925  *      reg - The register number
   1926  *      port - The port for which index is being calculated
   1927  * Returns:
   1928  *      SOC_E_XXX, no it is not
   1929  * Notes:
   1930  */
   1931 
   1932 int
   1933 soc_counter_idx_get(int unit, soc_reg_t reg, int ar_idx, int port)
   1934 {
   1935     int base_index, num_entries;
   1936     if (_soc_counter_get_info(unit, port, reg, &base_index, &num_entries,
   1937                               NULL) < 0) {
   1938         return -1;
   1939     }
   1940 
   1941     if (ar_idx < 0) {
   1942         return base_index;
   1943     } else if (ar_idx < num_entries) {
   1944         return base_index + ar_idx;
   1945     } else {
   1946         return -1;
   1947     }
   1948 }
   1949 
   1950 /*
   1951  * Function:
   1952  *      _soc_counter_num_cosq_init
   1953  * Purpose:
   1954  *      Initialize the number of COSQ per port.
   1955  * Parameters:
   1956  *      unit - The SOC unit number
   1957  *      nports - Number of ports the unit has.
   1958  * Returns:
   1959  *      None.
   1960  */
   1961 STATIC void
   1962 _soc_counter_num_cosq_init(int unit, int nports)
   1963 {
   1964     /* Some compiler may generate false warning in partial build dead code */
   1965     if (nports > SOC_MAX_NUM_PORTS) {
   1966         return;
   1967     }
   1968 
   1969 #ifdef BCM_TRIUMPH_SUPPORT
   1970 #ifdef BCM_TRIDENT_SUPPORT
   1971     if (SOC_IS_TD_TT(unit)) {
   1972         return;
   1973     }
   1974 #endif /* BCM_TRIDENT_SUPPORT */
   1975 #ifdef BCM_SHADOW_SUPPORT
   1976     if (SOC_IS_SHADOW(unit)) {
   1977         return;
   1978     }
   1979 #endif /* BCM_SHADOW_SUPPORT */
   1980 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
   1981     if (SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit) || \
   1982         SOC_IS_GREYHOUND2(unit)) {
   1983         int port;
   1984 
   1985         /* all ports 8Q, including G, HG, CMIC and the reserved port 1 */
   1986         for (port = 0; port < nports; port++) {
   1987             num_cosq[unit][port] = 8;
   1988         }
   1989 
   1990     } else
   1991 #endif /* BCM_HURRICANE_SUPPORT || BCM_GREYHOUND_SUPPORT*/
   1992 #ifdef BCM_TRIUMPH2_SUPPORT
   1993     if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)){
   1994         const int port_24q[] = {26, 27, 28, 29, 30, 31, 34, 38, 39, 42, 43, 46, 50, 51};
   1995         const int port_16q = 54;
   1996         int port, i;
   1997 
   1998         for (port = 0; port < nports; port++) {
   1999             if (IS_CPU_PORT(unit, port)) {
   2000                 num_cosq[unit][port] = NUM_CPU_COSQ(unit);
   2001             } else {
   2002                 num_cosq[unit][port] = 8;
   2003                 for (i = 0; i < sizeof(port_24q) / sizeof(port_24q[1]); i++) {
   2004                     if (port == port_24q[i]) {
   2005                         num_cosq[unit][port] = 24;
   2006                         break;
   2007                     }
   2008                 }
   2009                 if ((port == port_16q) && (port < SOC_MAX_NUM_PORTS)) {
   2010                     num_cosq[unit][port] = 16;
   2011                 }
   2012             }
   2013         }
   2014 
   2015     } else
   2016 #endif /* BCM_TRIUMPH2_SUPPORT */
   2017 #ifdef BCM_ENDURO_SUPPORT
   2018     if (SOC_IS_ENDURO(unit)){
   2019         const int port_24q[] = {26, 27, 28, 29};
   2020         int port, i;
   2021 
   2022         for (port = 0; port < nports; port++) {
   2023             if (IS_CPU_PORT(unit, port)) {
   2024                 num_cosq[unit][port] = NUM_CPU_COSQ(unit);
   2025             } else {
   2026                 num_cosq[unit][port] = 8;
   2027                 for (i = 0; i < sizeof(port_24q) / sizeof(port_24q[1]); i++) {
   2028                     if (port == port_24q[i]) {
   2029                         num_cosq[unit][port] = 24;
   2030                         break;
   2031                     }
   2032                 }
   2033             }
   2034         }
   2035 
   2036     } else
   2037 #endif /* BCM_ENDURO_SUPPORT */
   2038 #ifdef BCM_KATANA_SUPPORT
   2039     if (SOC_IS_KATANA(unit)) {
   2040         int port;
   2041 
   2042         for (port = 0; port < nports; port++) {
   2043             if (IS_CPU_PORT(unit, port)) {
   2044                 num_cosq[unit][port] = NUM_CPU_COSQ(unit);
   2045             /* coverity[overrun-local] */
   2046             } else if (IS_HG_PORT(unit, port)) {
   2047                 num_cosq[unit][port] = 24;
   2048             } else {
   2049                 num_cosq[unit][port] = 8;
   2050             }
   2051         }
   2052     } else
   2053 #endif /* BCM_KATANA_SUPPORT */
   2054     if (SOC_IS_TR_VL(unit)) {
   2055         const int port_24q[] = {2, 3, 14, 15, 26, 27, 28, 29, 30, 31, 32, 43};
   2056         int port, i;
   2057 
   2058         for (port = 0; port < nports; port++) {
   2059             if (IS_CPU_PORT(unit, port)) {
   2060                 num_cosq[unit][port] = NUM_CPU_COSQ(unit);
   2061             } else {
   2062                 num_cosq[unit][port] = 8;
   2063                 for (i = 0; i < sizeof(port_24q) / sizeof(port_24q[1]); i++) {
   2064                     if (port == port_24q[i]) {
   2065                         num_cosq[unit][port] = 24;
   2066                         break;
   2067                     }
   2068                 }
   2069             }
   2070         }
   2071     } else
   2072 #endif /* BCM_TRIUMPH_SUPPORT */
   2073 #ifdef BCM_FIREBOLT_SUPPORT
   2074     if (SOC_IS_SC_CQ(unit) || SOC_IS_HB_GW(unit) || SOC_IS_FB_FX_HX(unit)) {
   2075         int port;
   2076 
   2077         for (port = 0; port < nports; port++) {
   2078             if (IS_CPU_PORT(unit, port)) {
   2079                 num_cosq[unit][port] = NUM_CPU_COSQ(unit);
   2080             } else {
   2081                 num_cosq[unit][port] = 8;
   2082             }
   2083         }
   2084     } else
   2085 #endif /* BCM_FIREBOLT_SUPPORT */
   2086     {
   2087         return;
   2088     }
   2089 
   2090     return;
   2091 }
   2092 
   2093 #ifdef BCM_TRIUMPH3_SUPPORT
   2094 STATIC int
   2095 _soc_counter_triumph3_non_dma_init(int unit, int nports,
   2096                                    int non_dma_start_index,
   2097                                    int *non_dma_entries)
   2098 {
   2099     soc_control_t *soc;
   2100     soc_counter_non_dma_t *non_dma0, *non_dma1, *non_dma2;
   2101     int num_entries, alloc_size;
   2102     uint32 *buf;
   2103 
   2104     soc = SOC_CONTROL(unit);
   2105     *non_dma_entries = 0;
   2106 
   2107     /* EGR_PERQ_XMT_COUNTERS size depends on user's portmap config */
   2108     num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm);
   2109     alloc_size = num_entries * sizeof(uint32) *
   2110                  soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm);
   2111 
   2112     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   2113     if (buf == NULL) {
   2114         return SOC_E_MEMORY;
   2115     }
   2116     sal_memset(buf, 0, alloc_size);
   2117 
   2118     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   2119                                      SOC_COUNTER_NON_DMA_START];
   2120     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2121         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   2122     non_dma0->pbmp = PBMP_ALL(unit);
   2123     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2124     non_dma0->entries_per_port = 48;
   2125     non_dma0->num_entries = num_entries;
   2126     non_dma0->mem = EGR_PERQ_XMT_COUNTERSm;
   2127     non_dma0->reg = INVALIDr;
   2128     non_dma0->field = PACKET_COUNTERf;
   2129     non_dma0->cname = "MC_PERQ_PKT";
   2130     non_dma0->dma_buf[0] = buf;
   2131     non_dma0->dma_index_max[0] = num_entries - 1;
   2132     non_dma0->dma_mem[0] = EGR_PERQ_XMT_COUNTERSm;
   2133     *non_dma_entries += non_dma0->num_entries;
   2134 
   2135     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   2136                                     SOC_COUNTER_NON_DMA_START];
   2137     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2138     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   2139     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2140     non_dma1->field = BYTE_COUNTERf;
   2141     non_dma1->cname = "MC_PERQ_BYTE";
   2142     *non_dma_entries += non_dma1->num_entries;
   2143 
   2144     non_dma2 =  &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC -
   2145                                      SOC_COUNTER_NON_DMA_START];
   2146     sal_memcpy(non_dma2, non_dma0, sizeof(soc_counter_non_dma_t));
   2147     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID;
   2148     non_dma2->pbmp = PBMP_ALL(unit);
   2149     non_dma2->entries_per_port = 10;
   2150     non_dma2->num_entries = 0;
   2151     non_dma2->cname = "UC_PERQ_PKT";
   2152 
   2153     non_dma2 =  &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC -
   2154                                      SOC_COUNTER_NON_DMA_START];
   2155     sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t));
   2156     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID;
   2157     non_dma2->pbmp = PBMP_ALL(unit);
   2158     non_dma2->entries_per_port = 10;
   2159     non_dma2->num_entries = 0;
   2160     non_dma2->cname = "UC_PERQ_BYTE";
   2161 
   2162     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   2163                                      SOC_COUNTER_NON_DMA_START];
   2164     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2165                       _SOC_COUNTER_NON_DMA_DO_DMA;
   2166     non_dma0->pbmp = PBMP_ALL(unit);
   2167     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2168     non_dma0->entries_per_port = 48; /* 48 for cpu port */
   2169     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_MC_DROP_MEMm);
   2170     non_dma0->mem = MMU_CTR_MC_DROP_MEMm;
   2171     non_dma0->reg = INVALIDr;
   2172     non_dma0->field = PKT_CNTf;
   2173     non_dma0->cname = "MCQ_DROP_PKT";
   2174     non_dma0->dma_buf[0] = buf;
   2175     non_dma0->dma_index_max[0] = non_dma0->num_entries - 1;
   2176     non_dma0->dma_mem[0] = non_dma0->mem;
   2177     *non_dma_entries += non_dma0->num_entries;
   2178 
   2179     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE -
   2180                                      SOC_COUNTER_NON_DMA_START];
   2181     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2182     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   2183     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2184     non_dma1->field = BYTE_COUNTf;
   2185     non_dma1->cname = "MCQ_DROP_BYTE";
   2186     *non_dma_entries += non_dma1->num_entries;
   2187 
   2188     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC -
   2189                                      SOC_COUNTER_NON_DMA_START];
   2190     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA;
   2191     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   2192     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2193     non_dma0->entries_per_port = 8;
   2194     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm);
   2195     non_dma0->mem = MMU_CTR_UC_DROP_MEMm;
   2196     non_dma0->reg = INVALIDr;
   2197     non_dma0->field = PKT_CNTf;
   2198     non_dma0->cname = "UCQ_DROP_PKT";
   2199     non_dma0->dma_buf[0] = buf;
   2200     non_dma0->dma_index_max[0] = non_dma0->num_entries - 1;
   2201     non_dma0->dma_mem[0] = non_dma0->mem;
   2202     *non_dma_entries += non_dma0->num_entries;
   2203 
   2204     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC -
   2205                                      SOC_COUNTER_NON_DMA_START];
   2206     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2207     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   2208     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2209     non_dma1->field = BYTE_COUNTf;
   2210     non_dma1->cname = "UCQ_DROP_BYTE";
   2211     *non_dma_entries += non_dma1->num_entries;
   2212 
   2213     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING -
   2214                                      SOC_COUNTER_NON_DMA_START];
   2215     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   2216     non_dma0->pbmp = PBMP_ALL(unit);
   2217     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2218     non_dma0->entries_per_port = 1;
   2219     non_dma0->num_entries = nports;
   2220     non_dma0->mem = INVALIDm;
   2221     non_dma0->reg = DROP_PKT_CNT_INGr;
   2222     non_dma0->field = COUNTf;
   2223     non_dma0->cname = "DROP_PKT_ING";
   2224     *non_dma_entries += non_dma0->num_entries;
   2225 
   2226     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING -
   2227                                      SOC_COUNTER_NON_DMA_START];
   2228     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2229     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2230     non_dma1->reg = DROP_BYTE_CNT_ING_64r;
   2231     non_dma1->cname = "DROP_BYTE_ING";
   2232     *non_dma_entries += non_dma1->num_entries;
   2233 
   2234     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   2235                                      SOC_COUNTER_NON_DMA_START];
   2236     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2237         _SOC_COUNTER_NON_DMA_DO_DMA;
   2238     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   2239     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2240     non_dma0->entries_per_port = 1;
   2241     non_dma0->num_entries = 63; /* one per port */
   2242     non_dma0->mem = MMU_CTR_COLOR_DROP_MEMm;
   2243     non_dma0->reg = INVALIDr;
   2244     non_dma0->field = PKT_CNTf;
   2245     non_dma0->cname = "DROP_PKT_YEL";
   2246     non_dma0->dma_buf[0] = buf;
   2247     non_dma0->dma_index_min[0] = 63 * 4;
   2248     non_dma0->dma_index_max[0] = 63 * 4 + 62;
   2249     non_dma0->dma_mem[0] = non_dma0->mem;
   2250     *non_dma_entries += non_dma0->num_entries;
   2251 
   2252     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   2253                                      SOC_COUNTER_NON_DMA_START];
   2254     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2255     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2256     non_dma1->cname = "DROP_PKT_RED";
   2257     non_dma1->dma_index_min[0] = 63 * 3;
   2258     non_dma1->dma_index_max[0] = 63 * 3 + 62;
   2259     *non_dma_entries += non_dma1->num_entries;
   2260 
   2261     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN -
   2262                                      SOC_COUNTER_NON_DMA_START];
   2263     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2264     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2265     non_dma1->cname = "WRED_PKT_GRE";
   2266     non_dma1->dma_index_min[0] = 63 * 2;
   2267     non_dma1->dma_index_max[0] = 63 * 2 + 62;
   2268     *non_dma_entries += non_dma1->num_entries;
   2269 
   2270     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW -
   2271                                      SOC_COUNTER_NON_DMA_START];
   2272     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2273     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2274     non_dma1->cname = "WRED_PKT_YEL";
   2275     non_dma1->dma_index_min[0] = 63 * 1;
   2276     non_dma1->dma_index_max[0] = 66 * 1 + 62;
   2277     *non_dma_entries += non_dma1->num_entries;
   2278 
   2279     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED -
   2280                                      SOC_COUNTER_NON_DMA_START];
   2281     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2282     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2283     non_dma1->cname = "WRED_PKT_RED";
   2284     non_dma1->dma_index_min[0] = 0;
   2285     non_dma1->dma_index_max[0] = 62;
   2286     *non_dma_entries += non_dma1->num_entries;
   2287 
   2288     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_PEAK -
   2289                                      SOC_COUNTER_NON_DMA_START];
   2290     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2291         _SOC_COUNTER_NON_DMA_PEAK;
   2292     SOC_PBMP_CLEAR(non_dma0->pbmp);
   2293     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2294     non_dma0->entries_per_port = 0;
   2295     non_dma0->num_entries = 4;
   2296     non_dma0->mem = INVALIDm;
   2297     non_dma0->reg = TOTAL_BUFFER_COUNT_CELL_SPr;
   2298     non_dma0->field = TOTAL_BUFFER_COUNTf;
   2299     non_dma0->cname = "POOL_PEAK";
   2300     non_dma0->dma_buf[0] = buf;
   2301     *non_dma_entries += non_dma0->num_entries;
   2302 
   2303     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_CURRENT -
   2304                                      SOC_COUNTER_NON_DMA_START];
   2305     sal_memcpy(non_dma2, non_dma0, sizeof(soc_counter_non_dma_t));
   2306     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   2307         _SOC_COUNTER_NON_DMA_CURRENT;
   2308     non_dma2->cname = "POOL_CUR";
   2309 
   2310     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_PEAK -
   2311                                      SOC_COUNTER_NON_DMA_START];
   2312     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2313         _SOC_COUNTER_NON_DMA_PEAK | _SOC_COUNTER_NON_DMA_DO_DMA;
   2314     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   2315     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2316     non_dma0->entries_per_port = 8;
   2317     non_dma0->num_entries = nports * non_dma0->entries_per_port;
   2318     non_dma0->dma_index_max[0] = non_dma0->num_entries - 1;
   2319     non_dma0->mem = THDI_PORT_PG_CNTRSm;
   2320     non_dma0->reg = INVALIDr;
   2321     non_dma0->field = PG_MIN_COUNTf;
   2322     non_dma0->dma_buf[0] = buf;
   2323     non_dma0->dma_mem[0] = non_dma0->mem;
   2324     non_dma0->dma_index_max[0] = non_dma0->num_entries - 1;
   2325     non_dma0->cname = "PG_MIN_PEAK";
   2326     *non_dma_entries += non_dma0->num_entries;
   2327 
   2328     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_CURRENT -
   2329                                      SOC_COUNTER_NON_DMA_START];
   2330     sal_memcpy(non_dma2, non_dma0, sizeof(soc_counter_non_dma_t));
   2331     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   2332             _SOC_COUNTER_NON_DMA_CURRENT;
   2333     non_dma2->cname = "PG_MIN_CUR";
   2334 
   2335     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_PEAK -
   2336                                      SOC_COUNTER_NON_DMA_START];
   2337     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2338     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2339     non_dma1->field = PG_SHARED_COUNTf;
   2340     non_dma1->cname = "PG_SHARED_PEAK";
   2341     *non_dma_entries += non_dma1->num_entries;
   2342 
   2343     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT -
   2344                                      SOC_COUNTER_NON_DMA_START];
   2345     sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t));
   2346     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_CURRENT;
   2347     non_dma2->cname = "PG_SHARED_CUR";
   2348 
   2349     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_PEAK -
   2350                                      SOC_COUNTER_NON_DMA_START];
   2351     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2352     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2353     non_dma1->field = PG_HDRM_COUNTf;
   2354     non_dma1->cname = "PG_HDRM_PEAK";
   2355     *non_dma_entries += non_dma1->num_entries;
   2356 
   2357     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT -
   2358                                      SOC_COUNTER_NON_DMA_START];
   2359     sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t));
   2360     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_CURRENT;
   2361     non_dma2->cname = "PG_HDRM_CUR";
   2362 
   2363     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_PEAK -
   2364                                      SOC_COUNTER_NON_DMA_START];
   2365     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID | 
   2366         _SOC_COUNTER_NON_DMA_PEAK | _SOC_COUNTER_NON_DMA_DO_DMA;
   2367     non_dma1->pbmp = PBMP_PORT_ALL(unit);
   2368     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2369     non_dma1->entries_per_port = 48;
   2370     non_dma1->num_entries = nports * non_dma1->entries_per_port;
   2371     non_dma1->reg = OP_QUEUE_TOTAL_COUNT_CELLr;
   2372     non_dma1->mem = INVALIDm;
   2373     non_dma1->field = Q_TOTAL_COUNT_CELLf;
   2374     non_dma1->cname = "MC_QUEUE_PEAK";
   2375     *non_dma_entries += non_dma1->num_entries;
   2376 
   2377     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_CURRENT -
   2378                                      SOC_COUNTER_NON_DMA_START];
   2379     sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t));
   2380     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_CURRENT;
   2381     non_dma2->cname = "MC_QUEUE_CUR";
   2382 
   2383     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK -
   2384                                      SOC_COUNTER_NON_DMA_START];
   2385     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   2386         _SOC_COUNTER_NON_DMA_PEAK | _SOC_COUNTER_NON_DMA_DO_DMA;
   2387     non_dma1->pbmp = PBMP_PORT_ALL(unit);
   2388     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2389     non_dma1->entries_per_port = 10;
   2390     non_dma1->num_entries = soc_mem_index_count(unit, MMU_THDO_COUNTER_QUEUEm);
   2391     non_dma1->reg = INVALIDr;
   2392     non_dma1->mem = MMU_THDO_COUNTER_QUEUEm;
   2393     non_dma1->field =  SHARED_COUNTf;
   2394     non_dma1->dma_buf[0] = buf;
   2395     non_dma1->cname = "UC_QUEUE_PEAK";
   2396     non_dma1->dma_mem[0] = non_dma1->mem;
   2397     non_dma1->dma_index_max[0] = non_dma1->num_entries - 1;
   2398     *non_dma_entries += non_dma1->num_entries;
   2399 
   2400     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT -
   2401                                      SOC_COUNTER_NON_DMA_START];
   2402     sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t));
   2403     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   2404         _SOC_COUNTER_NON_DMA_CURRENT;
   2405     non_dma2->cname = "UC_QUEUE_CUR";
   2406     return SOC_E_NONE;
   2407 }
   2408 #endif
   2409 
   2410 
   2411 #ifdef BCM_TRIDENT_SUPPORT
   2412 /*
   2413  * Function:
   2414  *      _soc_counter_trident_non_dma_init
   2415  * Purpose:
   2416  *      Initialize Trident's non-DMA counters.
   2417  * Parameters:
   2418  *      unit - The SOC unit number
   2419  *      nports - Number of ports.
   2420  *      non_dma_start_index - The starting index of non-DMA counter entries.
   2421  *      non_dma_entries - (OUT) The number of non-DMA counter entries.
   2422  * Returns:
   2423  *      SOC_E_NONE
   2424  *      SOC_E_MEMORY
   2425  */
   2426 STATIC int
   2427 _soc_counter_trident_non_dma_init(int unit, int nports, int non_dma_start_index,
   2428         int *non_dma_entries)
   2429 {
   2430     soc_control_t *soc;
   2431     soc_counter_non_dma_t *non_dma0, *non_dma1, *non_dma2;
   2432     int entry_words, num_entries[2], alloc_size, table_size;
   2433     uint32 *buf;
   2434 
   2435     soc = SOC_CONTROL(unit);
   2436     *non_dma_entries = 0;
   2437 
   2438     soc_trident_get_egr_perq_xmt_counters_size(unit, &num_entries[0],
   2439                                                &num_entries[1]);
   2440     entry_words = soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm);
   2441 
   2442     /* EGR_PERQ_XMT_COUNTERS size depends on user's portmap config */
   2443     alloc_size = (num_entries[0] + num_entries[1]) * entry_words * sizeof(uint32);
   2444 
   2445     /* MMU_CTR_UC_DROP_MEM is the largest among MMU_CTR_*_DROP_MEM tables */
   2446     table_size = soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm) *
   2447         soc_mem_entry_words(unit, MMU_CTR_UC_DROP_MEMm) * sizeof(uint32);
   2448     if (alloc_size < table_size) {
   2449         alloc_size = table_size;
   2450     }
   2451 
   2452     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   2453     if (buf == NULL) {
   2454         return SOC_E_MEMORY;
   2455     }
   2456     sal_memset(buf, 0, alloc_size);
   2457 
   2458     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   2459                                      SOC_COUNTER_NON_DMA_START];
   2460     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2461         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   2462     non_dma0->pbmp = PBMP_ALL(unit);
   2463     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2464     non_dma0->entries_per_port = 48; /* cpu port has max number of queues */
   2465     non_dma0->num_entries = num_entries[0] + num_entries[1];
   2466     non_dma0->mem = EGR_PERQ_XMT_COUNTERSm;
   2467     non_dma0->reg = INVALIDr;
   2468     non_dma0->field = PACKET_COUNTERf;
   2469     non_dma0->cname = "MC_PERQ_PKT";
   2470     non_dma0->dma_buf[0] = buf;
   2471     non_dma0->dma_index_max[0] = num_entries[0] - 1;
   2472     non_dma0->dma_mem[0] = EGR_PERQ_XMT_COUNTERS_Xm;
   2473 #if (SOC_MAX_NUM_PIPES > 1)
   2474     non_dma0->dma_buf[1] = &buf[num_entries[0] * entry_words];
   2475     non_dma0->dma_index_max[1] = num_entries[1] - 1;
   2476     non_dma0->dma_mem[1] = EGR_PERQ_XMT_COUNTERS_Ym;
   2477 #endif
   2478     *non_dma_entries += non_dma0->num_entries;
   2479 
   2480     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   2481                                      SOC_COUNTER_NON_DMA_START];
   2482     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2483     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   2484     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2485     non_dma1->field = BYTE_COUNTERf;
   2486     non_dma1->cname = "MC_PERQ_BYTE";
   2487     *non_dma_entries += non_dma1->num_entries;
   2488 
   2489     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC -
   2490                                      SOC_COUNTER_NON_DMA_START];
   2491     *non_dma2 = *non_dma0;
   2492     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID;
   2493     non_dma2->pbmp = PBMP_PORT_ALL(unit);
   2494     non_dma2->entries_per_port = 10;
   2495     non_dma2->num_entries = 0;
   2496     non_dma2->cname = "UC_PERQ_PKT";
   2497 
   2498     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC -
   2499                                      SOC_COUNTER_NON_DMA_START];
   2500     *non_dma2 = *non_dma1;
   2501     non_dma2->pbmp = PBMP_PORT_ALL(unit);
   2502     non_dma2->entries_per_port = 10;
   2503     non_dma2->num_entries = 0;
   2504     non_dma2->cname = "UC_PERQ_BYTE";
   2505 
   2506     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT -
   2507                                      SOC_COUNTER_NON_DMA_START];
   2508     *non_dma2 = *non_dma0;
   2509     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID;
   2510     non_dma2->pbmp = PBMP_PORT_ALL(unit);
   2511     non_dma2->entries_per_port = 64;
   2512     non_dma2->num_entries = 0;
   2513     non_dma2->cname = "EXT_PERQ_PKT";
   2514 
   2515     non_dma2 =
   2516         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT -
   2517                               SOC_COUNTER_NON_DMA_START];
   2518     *non_dma2 = *non_dma1;
   2519     non_dma2->pbmp = PBMP_PORT_ALL(unit);
   2520     non_dma2->entries_per_port = 64;
   2521     non_dma2->num_entries = 0;
   2522     non_dma2->cname = "EXT_PERQ_BYTE";
   2523 
   2524     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   2525                                      SOC_COUNTER_NON_DMA_START];
   2526     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2527         _SOC_COUNTER_NON_DMA_DO_DMA;
   2528     non_dma0->pbmp = PBMP_ALL(unit);
   2529     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2530     non_dma0->entries_per_port = 48; /* 48 for cpu port */
   2531     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_MC_DROP_MEMm);
   2532     non_dma0->mem = MMU_CTR_MC_DROP_MEMm;
   2533     non_dma0->reg = INVALIDr;
   2534     non_dma0->field = PKT_CNTf;
   2535     non_dma0->cname = "MCQ_DROP_PKT";
   2536     non_dma0->dma_buf[0] = buf;
   2537     non_dma0->dma_index_max[0] = non_dma0->num_entries - 1;
   2538     non_dma0->dma_mem[0] = non_dma0->mem;
   2539     *non_dma_entries += non_dma0->num_entries;
   2540 
   2541     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE -
   2542                                      SOC_COUNTER_NON_DMA_START];
   2543     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2544     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   2545     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2546     non_dma1->field = BYTE_COUNTf;
   2547     non_dma1->cname = "MCQ_DROP_BYTE";
   2548     *non_dma_entries += non_dma1->num_entries;
   2549 
   2550     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC -
   2551                                      SOC_COUNTER_NON_DMA_START];
   2552     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2553         _SOC_COUNTER_NON_DMA_DO_DMA;
   2554     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   2555     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2556     non_dma0->entries_per_port = 74; /*  10 ucast + 64 ext ucast */
   2557     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm);
   2558     non_dma0->mem = MMU_CTR_UC_DROP_MEMm;
   2559     non_dma0->reg = INVALIDr;
   2560     non_dma0->field = PKT_CNTf;
   2561     non_dma0->cname = "UCQ_DROP_PKT";
   2562     non_dma0->dma_buf[0] = buf;
   2563     non_dma0->dma_index_max[0] = non_dma0->num_entries - 1;
   2564     non_dma0->dma_mem[0] = non_dma0->mem;
   2565     *non_dma_entries += non_dma0->num_entries;
   2566 
   2567     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC -
   2568                                      SOC_COUNTER_NON_DMA_START];
   2569     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2570     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   2571     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2572     non_dma1->field = BYTE_COUNTf;
   2573     non_dma1->cname = "UCQ_DROP_BYTE";
   2574     *non_dma_entries += non_dma1->num_entries;
   2575 
   2576     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING -
   2577                                      SOC_COUNTER_NON_DMA_START];
   2578     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   2579     non_dma0->pbmp = PBMP_ALL(unit);
   2580     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2581     non_dma0->entries_per_port = 1;
   2582     non_dma0->num_entries = nports;
   2583     non_dma0->mem = INVALIDm;
   2584     non_dma0->reg = DROP_PKT_CNT_INGr;
   2585     non_dma0->field = COUNTf;
   2586     non_dma0->cname = "DROP_PKT_ING";
   2587     *non_dma_entries += non_dma0->num_entries;
   2588 
   2589     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING -
   2590                                      SOC_COUNTER_NON_DMA_START];
   2591     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2592     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2593     non_dma1->reg = DROP_BYTE_CNT_ING_64r;
   2594     non_dma1->cname = "DROP_BYTE_ING";
   2595     *non_dma_entries += non_dma1->num_entries;
   2596 
   2597     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   2598                                      SOC_COUNTER_NON_DMA_START];
   2599     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2600         _SOC_COUNTER_NON_DMA_DO_DMA;
   2601     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   2602     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2603     non_dma0->entries_per_port = 1;
   2604     non_dma0->num_entries = 66; /* one per port */
   2605     non_dma0->mem = MMU_CTR_COLOR_DROP_MEMm;
   2606     non_dma0->reg = INVALIDr;
   2607     non_dma0->field = PKT_CNTf;
   2608     non_dma0->cname = "DROP_PKT_YEL";
   2609     non_dma0->dma_buf[0] = buf;
   2610     non_dma0->dma_index_min[0] = 66 * 4;
   2611     non_dma0->dma_index_max[0] = 66 * 4 + 65;
   2612     non_dma0->dma_mem[0] = non_dma0->mem;
   2613     *non_dma_entries += non_dma0->num_entries;
   2614 
   2615     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   2616                                      SOC_COUNTER_NON_DMA_START];
   2617     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2618     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2619     non_dma1->cname = "DROP_PKT_RED";
   2620     non_dma1->dma_index_min[0] = 66 * 3;
   2621     non_dma1->dma_index_max[0] = 66 * 3 + 65;
   2622     *non_dma_entries += non_dma1->num_entries;
   2623 
   2624     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN -
   2625                                      SOC_COUNTER_NON_DMA_START];
   2626     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2627     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2628     non_dma1->cname = "WRED_PKT_GRE";
   2629     non_dma1->dma_index_min[0] = 66 * 2;
   2630     non_dma1->dma_index_max[0] = 66 * 2 + 65;
   2631     *non_dma_entries += non_dma1->num_entries;
   2632 
   2633     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW -
   2634                                      SOC_COUNTER_NON_DMA_START];
   2635     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2636     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2637     non_dma1->cname = "WRED_PKT_YEL";
   2638     non_dma1->dma_index_min[0] = 66 * 1;
   2639     non_dma1->dma_index_max[0] = 66 * 1 + 65;
   2640     *non_dma_entries += non_dma1->num_entries;
   2641 
   2642     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED -
   2643                                      SOC_COUNTER_NON_DMA_START];
   2644     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2645     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2646     non_dma1->cname = "WRED_PKT_RED";
   2647     non_dma1->dma_index_min[0] = 0;
   2648     non_dma1->dma_index_max[0] = 65;
   2649     *non_dma_entries += non_dma1->num_entries;
   2650 
   2651     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_PEAK -
   2652                                      SOC_COUNTER_NON_DMA_START];
   2653     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2654         _SOC_COUNTER_NON_DMA_PEAK;
   2655     SOC_PBMP_CLEAR(non_dma0->pbmp);
   2656     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2657     non_dma0->entries_per_port = 0;
   2658     non_dma0->num_entries = 4;
   2659     non_dma0->mem = INVALIDm;
   2660     non_dma0->reg = TOTAL_BUFFER_COUNT_CELL_SPr;
   2661     non_dma0->field = TOTAL_BUFFER_COUNTf;
   2662     non_dma0->cname = "POOL_PEAK";
   2663     *non_dma_entries += non_dma0->num_entries;
   2664 
   2665     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_CURRENT -
   2666                                      SOC_COUNTER_NON_DMA_START];
   2667     sal_memcpy(non_dma2, non_dma0, sizeof(soc_counter_non_dma_t));
   2668     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   2669         _SOC_COUNTER_NON_DMA_CURRENT;
   2670     non_dma2->cname = "POOL_CUR";
   2671 
   2672     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_PEAK -
   2673                                      SOC_COUNTER_NON_DMA_START];
   2674     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2675         _SOC_COUNTER_NON_DMA_PEAK;
   2676     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   2677     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2678     non_dma0->entries_per_port = 8;
   2679     non_dma0->num_entries = nports * non_dma0->entries_per_port;
   2680     non_dma0->mem = INVALIDm;
   2681     non_dma0->reg = PG_MIN_COUNT_CELLr;
   2682     non_dma0->field = PG_MIN_COUNTf;
   2683     non_dma0->cname = "PG_MIN_PEAK";
   2684     *non_dma_entries += non_dma0->num_entries;
   2685 
   2686     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_CURRENT -
   2687                                      SOC_COUNTER_NON_DMA_START];
   2688     sal_memcpy(non_dma2, non_dma0, sizeof(soc_counter_non_dma_t));
   2689     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   2690         _SOC_COUNTER_NON_DMA_CURRENT;
   2691     non_dma2->cname = "PG_MIN_CUR";
   2692 
   2693     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_PEAK -
   2694                                      SOC_COUNTER_NON_DMA_START];
   2695     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2696     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2697     non_dma1->reg = PG_SHARED_COUNT_CELLr;
   2698     non_dma1->field = PG_SHARED_COUNTf;
   2699     non_dma1->cname = "PG_SHARED_PEAK";
   2700     *non_dma_entries += non_dma1->num_entries;
   2701 
   2702     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT -
   2703                                      SOC_COUNTER_NON_DMA_START];
   2704     sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t));
   2705     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   2706         _SOC_COUNTER_NON_DMA_CURRENT;
   2707     non_dma2->cname = "PG_SHARED_CUR";
   2708 
   2709     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_PEAK -
   2710                                      SOC_COUNTER_NON_DMA_START];
   2711     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2712     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2713     non_dma1->reg = PG_HDRM_COUNT_CELLr;
   2714     non_dma1->field = PG_HDRM_COUNTf;
   2715     non_dma1->cname = "PG_HDRM_PEAK";
   2716     *non_dma_entries += non_dma1->num_entries;
   2717 
   2718     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT -
   2719                                      SOC_COUNTER_NON_DMA_START];
   2720     sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t));
   2721     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   2722         _SOC_COUNTER_NON_DMA_CURRENT;
   2723     non_dma2->cname = "PG_HDRM_CUR";
   2724 
   2725     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_PEAK -
   2726                                      SOC_COUNTER_NON_DMA_START];
   2727     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2728     non_dma1->pbmp = PBMP_ALL(unit);
   2729     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2730     non_dma1->entries_per_port = 5;
   2731     non_dma1->num_entries = nports * non_dma0->entries_per_port;
   2732     non_dma1->reg = OP_QUEUE_TOTAL_COUNT_CELLr;
   2733     non_dma1->field = Q_TOTAL_COUNT_CELLf;
   2734     non_dma1->cname = "MC_QUEUE_PEAK";
   2735     *non_dma_entries += non_dma1->num_entries;
   2736 
   2737     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_CURRENT -
   2738                                      SOC_COUNTER_NON_DMA_START];
   2739     sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t));
   2740     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   2741         _SOC_COUNTER_NON_DMA_CURRENT;
   2742     non_dma2->cname = "MC_QUEUE_CUR";
   2743 
   2744     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK -
   2745                                      SOC_COUNTER_NON_DMA_START];
   2746     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2747     non_dma1->pbmp = PBMP_PORT_ALL(unit);
   2748     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2749     non_dma1->entries_per_port = 10;
   2750     non_dma1->num_entries = nports * non_dma1->entries_per_port;
   2751     non_dma1->reg = OP_UC_QUEUE_TOTAL_COUNT_CELLr;
   2752     non_dma1->field =  Q_TOTAL_COUNT_CELLf;
   2753     non_dma1->cname = "UC_QUEUE_PEAK";
   2754     *non_dma_entries += non_dma1->num_entries;
   2755 
   2756     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT -
   2757                                      SOC_COUNTER_NON_DMA_START];
   2758     sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t));
   2759     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   2760         _SOC_COUNTER_NON_DMA_CURRENT;
   2761     non_dma2->cname = "UC_QUEUE_CUR";
   2762 
   2763     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EXT_QUEUE_PEAK -
   2764                                      SOC_COUNTER_NON_DMA_START];
   2765     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   2766     non_dma1->pbmp = PBMP_EQ(unit);
   2767     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2768     non_dma1->entries_per_port = 64;
   2769     non_dma1->num_entries = nports * non_dma1->entries_per_port;
   2770     non_dma1->reg = OP_EX_QUEUE_TOTAL_COUNT_CELLr;
   2771     non_dma1->cname = "EXT_QUEUE_PEAK";
   2772     non_dma1->field =  Q_TOTAL_COUNT_CELLf;
   2773     *non_dma_entries += non_dma1->num_entries;
   2774 
   2775     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EXT_QUEUE_CURRENT -
   2776                                      SOC_COUNTER_NON_DMA_START];
   2777     sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t));
   2778     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   2779         _SOC_COUNTER_NON_DMA_CURRENT;
   2780     non_dma2->cname = "EXT_QUEUE_CUR";
   2781 
   2782     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_MMU_QCN_CNM -
   2783                                      SOC_COUNTER_NON_DMA_START];
   2784     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2785         _SOC_COUNTER_NON_DMA_DO_DMA;
   2786     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   2787     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2788     non_dma0->entries_per_port = 2;
   2789     non_dma0->num_entries = soc_mem_index_count(unit, MMU_QCN_CNM_COUNTERm);
   2790     non_dma0->mem = MMU_QCN_CNM_COUNTERm;
   2791     non_dma0->reg = INVALIDr;
   2792     non_dma0->field = CNM_CNTf;
   2793     non_dma0->cname = "QCN_CNM_COUNTER";
   2794     non_dma0->dma_buf[0] = buf;
   2795     non_dma0->dma_mem[0] = non_dma0->mem;
   2796     non_dma0->dma_index_min[0] = 0;
   2797     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]);
   2798     *non_dma_entries += non_dma0->num_entries;
   2799 
   2800     return SOC_E_NONE;
   2801 }
   2802 #endif /* BCM_TRIDENT_SUPPORT */
   2803 
   2804 #if defined (BCM_MONTEREY_SUPPORT)
   2805 /* Function to initialize extra counters  for monterey*/
   2806 STATIC int
   2807 soc_counter_monterey_extra_obm_ctrs_init(int unit,
   2808                                    soc_counter_non_dma_t *non_dma_parent,
   2809                                    soc_counter_non_dma_t *non_dma_extra,
   2810                                    uint32 extra_ctr_ct,
   2811                                    int *total_entries)
   2812 {
   2813 #define LOSSY_LO  0
   2814 #define LOSSY_HI  1
   2815 #define LOSSLESS0 2
   2816 #define LOSSLESS1 3
   2817 #define EXPRESS   4
   2818 
   2819 #define COUNTER_TYPE_DROP    0
   2820 #define COUNTER_TYPE_ENQUEUE 1
   2821     char obm_type_str[][12] = {"LOSSY_LO", "LOSSY_HI",
   2822                                "LOSSLESS0", "LOSSLESS1", "EXPRESS"};
   2823     char obm_ctr_type_str[][10] = {"DROP", "ENQUEUE"};
   2824     int  i, byte_flag = 0, obm_type = LOSSY_LO, parent_base_index = 0;
   2825     int  counter_type = COUNTER_TYPE_DROP;
   2826     uint32 count = 0;
   2827 
   2828     soc_reg_t obm_drop_pkt_regs[][2][5] = {
   2829         {
   2830          {IDB_OBM0_LOSSY_LO_PKT_DROP_COUNTr,
   2831           IDB_OBM0_LOSSY_HI_PKT_DROP_COUNTr,
   2832           IDB_OBM0_LOSSLESS0_PKT_DROP_COUNTr,
   2833           IDB_OBM0_LOSSLESS1_PKT_DROP_COUNTr,
   2834           IDB_OBM0_EXPRESS_PKT_DROP_COUNTr},
   2835 
   2836          {IDB_OBM0_LOSSY_LO_ARRIVAL_PKT_COUNTr,
   2837           IDB_OBM0_LOSSY_HI_ARRIVAL_PKT_COUNTr,
   2838           IDB_OBM0_LOSSLESS0_ARRIVAL_PKT_COUNTr,
   2839           IDB_OBM0_LOSSLESS1_ARRIVAL_PKT_COUNTr,
   2840           IDB_OBM0_EXPRESS_ARRIVAL_PKT_COUNTr}
   2841         },
   2842         {
   2843          {IDB_OBM1_LOSSY_LO_PKT_DROP_COUNTr,
   2844           IDB_OBM1_LOSSY_HI_PKT_DROP_COUNTr,
   2845           IDB_OBM1_LOSSLESS0_PKT_DROP_COUNTr,
   2846           IDB_OBM1_LOSSLESS1_PKT_DROP_COUNTr,
   2847           IDB_OBM1_EXPRESS_PKT_DROP_COUNTr},
   2848 
   2849          {IDB_OBM1_LOSSY_LO_ARRIVAL_PKT_COUNTr,
   2850           IDB_OBM1_LOSSY_HI_ARRIVAL_PKT_COUNTr,
   2851           IDB_OBM1_LOSSLESS0_ARRIVAL_PKT_COUNTr,
   2852           IDB_OBM1_LOSSLESS1_ARRIVAL_PKT_COUNTr,
   2853           IDB_OBM1_EXPRESS_ARRIVAL_PKT_COUNTr}
   2854         },
   2855         {
   2856          {IDB_OBM2_LOSSY_LO_PKT_DROP_COUNTr,
   2857           IDB_OBM2_LOSSY_HI_PKT_DROP_COUNTr,
   2858           IDB_OBM2_LOSSLESS0_PKT_DROP_COUNTr,
   2859           IDB_OBM2_LOSSLESS1_PKT_DROP_COUNTr,
   2860           IDB_OBM2_EXPRESS_PKT_DROP_COUNTr},
   2861 
   2862          {IDB_OBM2_LOSSY_LO_ARRIVAL_PKT_COUNTr,
   2863           IDB_OBM2_LOSSY_HI_ARRIVAL_PKT_COUNTr,
   2864           IDB_OBM2_LOSSLESS0_ARRIVAL_PKT_COUNTr,
   2865           IDB_OBM2_LOSSLESS1_ARRIVAL_PKT_COUNTr,
   2866           IDB_OBM2_EXPRESS_ARRIVAL_PKT_COUNTr}
   2867         },
   2868         {
   2869          {IDB_OBM3_LOSSY_LO_PKT_DROP_COUNTr,
   2870           IDB_OBM3_LOSSY_HI_PKT_DROP_COUNTr,
   2871           IDB_OBM3_LOSSLESS0_PKT_DROP_COUNTr,
   2872           IDB_OBM3_LOSSLESS1_PKT_DROP_COUNTr,
   2873           IDB_OBM3_EXPRESS_PKT_DROP_COUNTr},
   2874 
   2875          {IDB_OBM3_LOSSY_LO_ARRIVAL_PKT_COUNTr,
   2876           IDB_OBM3_LOSSY_HI_ARRIVAL_PKT_COUNTr,
   2877           IDB_OBM3_LOSSLESS0_ARRIVAL_PKT_COUNTr,
   2878           IDB_OBM3_LOSSLESS1_ARRIVAL_PKT_COUNTr,
   2879           IDB_OBM3_EXPRESS_ARRIVAL_PKT_COUNTr}
   2880         },
   2881         {
   2882          {IDB_OBM4_LOSSY_LO_PKT_DROP_COUNTr,
   2883           IDB_OBM4_LOSSY_HI_PKT_DROP_COUNTr,
   2884           IDB_OBM4_LOSSLESS0_PKT_DROP_COUNTr,
   2885           IDB_OBM4_LOSSLESS1_PKT_DROP_COUNTr,
   2886           IDB_OBM4_EXPRESS_PKT_DROP_COUNTr},
   2887 
   2888          {IDB_OBM4_LOSSY_LO_ARRIVAL_PKT_COUNTr,
   2889           IDB_OBM4_LOSSY_HI_ARRIVAL_PKT_COUNTr,
   2890           IDB_OBM4_LOSSLESS0_ARRIVAL_PKT_COUNTr,
   2891           IDB_OBM4_LOSSLESS1_ARRIVAL_PKT_COUNTr,
   2892           IDB_OBM4_EXPRESS_ARRIVAL_PKT_COUNTr}
   2893         },
   2894         {
   2895          {IDB_OBM5_LOSSY_LO_PKT_DROP_COUNTr,
   2896           IDB_OBM5_LOSSY_HI_PKT_DROP_COUNTr,
   2897           IDB_OBM5_LOSSLESS0_PKT_DROP_COUNTr,
   2898           IDB_OBM5_LOSSLESS1_PKT_DROP_COUNTr,
   2899           IDB_OBM5_EXPRESS_PKT_DROP_COUNTr},
   2900 
   2901          {IDB_OBM5_LOSSY_LO_ARRIVAL_PKT_COUNTr,
   2902           IDB_OBM5_LOSSY_HI_ARRIVAL_PKT_COUNTr,
   2903           IDB_OBM5_LOSSLESS0_ARRIVAL_PKT_COUNTr,
   2904           IDB_OBM5_LOSSLESS1_ARRIVAL_PKT_COUNTr,
   2905           IDB_OBM5_EXPRESS_ARRIVAL_PKT_COUNTr}
   2906         },
   2907         {
   2908          {IDB_OBM6_LOSSY_LO_PKT_DROP_COUNTr,
   2909           IDB_OBM6_LOSSY_HI_PKT_DROP_COUNTr,
   2910           IDB_OBM6_LOSSLESS0_PKT_DROP_COUNTr,
   2911           IDB_OBM6_LOSSLESS1_PKT_DROP_COUNTr,
   2912           IDB_OBM6_EXPRESS_PKT_DROP_COUNTr},
   2913 
   2914          {IDB_OBM6_LOSSY_LO_ARRIVAL_PKT_COUNTr,
   2915           IDB_OBM6_LOSSY_HI_ARRIVAL_PKT_COUNTr,
   2916           IDB_OBM6_LOSSLESS0_ARRIVAL_PKT_COUNTr,
   2917           IDB_OBM6_LOSSLESS1_ARRIVAL_PKT_COUNTr,
   2918           IDB_OBM6_EXPRESS_ARRIVAL_PKT_COUNTr}
   2919         },
   2920         {
   2921          {IDB_OBM7_LOSSY_LO_PKT_DROP_COUNTr,
   2922           IDB_OBM7_LOSSY_HI_PKT_DROP_COUNTr,
   2923           IDB_OBM7_LOSSLESS0_PKT_DROP_COUNTr,
   2924           IDB_OBM7_LOSSLESS1_PKT_DROP_COUNTr,
   2925           IDB_OBM7_EXPRESS_PKT_DROP_COUNTr},
   2926 
   2927          {IDB_OBM7_LOSSY_LO_ARRIVAL_PKT_COUNTr,
   2928           IDB_OBM7_LOSSY_HI_ARRIVAL_PKT_COUNTr,
   2929           IDB_OBM7_LOSSLESS0_ARRIVAL_PKT_COUNTr,
   2930           IDB_OBM7_LOSSLESS1_ARRIVAL_PKT_COUNTr,
   2931           IDB_OBM7_EXPRESS_ARRIVAL_PKT_COUNTr}
   2932         }
   2933     };
   2934     soc_reg_t obm_drop_byte_regs[][2][5] = {
   2935         {
   2936          {IDB_OBM0_LOSSY_LO_BYTE_DROP_COUNTr,
   2937           IDB_OBM0_LOSSY_HI_BYTE_DROP_COUNTr,
   2938           IDB_OBM0_LOSSLESS0_BYTE_DROP_COUNTr,
   2939           IDB_OBM0_LOSSLESS1_BYTE_DROP_COUNTr,
   2940           IDB_OBM0_EXPRESS_BYTE_DROP_COUNTr},
   2941 
   2942          {IDB_OBM0_LOSSY_LO_ARRIVAL_BYTE_COUNTr,
   2943           IDB_OBM0_LOSSY_HI_ARRIVAL_BYTE_COUNTr,
   2944           IDB_OBM0_LOSSLESS0_ARRIVAL_BYTE_COUNTr,
   2945           IDB_OBM0_LOSSLESS1_ARRIVAL_BYTE_COUNTr,
   2946           IDB_OBM0_EXPRESS_ARRIVAL_BYTE_COUNTr}
   2947         },
   2948         {
   2949          {IDB_OBM1_LOSSY_LO_BYTE_DROP_COUNTr,
   2950           IDB_OBM1_LOSSY_HI_BYTE_DROP_COUNTr,
   2951           IDB_OBM1_LOSSLESS0_BYTE_DROP_COUNTr,
   2952           IDB_OBM1_LOSSLESS1_BYTE_DROP_COUNTr,
   2953           IDB_OBM1_EXPRESS_BYTE_DROP_COUNTr},
   2954 
   2955          {IDB_OBM1_LOSSY_LO_ARRIVAL_BYTE_COUNTr,
   2956           IDB_OBM1_LOSSY_HI_ARRIVAL_BYTE_COUNTr,
   2957           IDB_OBM1_LOSSLESS0_ARRIVAL_BYTE_COUNTr,
   2958           IDB_OBM1_LOSSLESS1_ARRIVAL_BYTE_COUNTr,
   2959           IDB_OBM1_EXPRESS_ARRIVAL_BYTE_COUNTr}
   2960         },
   2961         {
   2962          {IDB_OBM2_LOSSY_LO_BYTE_DROP_COUNTr,
   2963           IDB_OBM2_LOSSY_HI_BYTE_DROP_COUNTr,
   2964           IDB_OBM2_LOSSLESS0_BYTE_DROP_COUNTr,
   2965           IDB_OBM2_LOSSLESS1_BYTE_DROP_COUNTr,
   2966           IDB_OBM2_EXPRESS_BYTE_DROP_COUNTr},
   2967 
   2968          {IDB_OBM2_LOSSY_LO_ARRIVAL_BYTE_COUNTr,
   2969           IDB_OBM2_LOSSY_HI_ARRIVAL_BYTE_COUNTr,
   2970           IDB_OBM2_LOSSLESS0_ARRIVAL_BYTE_COUNTr,
   2971           IDB_OBM2_LOSSLESS1_ARRIVAL_BYTE_COUNTr,
   2972           IDB_OBM2_EXPRESS_ARRIVAL_BYTE_COUNTr}
   2973         },
   2974         {
   2975          {IDB_OBM3_LOSSY_LO_BYTE_DROP_COUNTr,
   2976           IDB_OBM3_LOSSY_HI_BYTE_DROP_COUNTr,
   2977           IDB_OBM3_LOSSLESS0_BYTE_DROP_COUNTr,
   2978           IDB_OBM3_LOSSLESS1_BYTE_DROP_COUNTr,
   2979           IDB_OBM3_EXPRESS_BYTE_DROP_COUNTr},
   2980 
   2981          {IDB_OBM3_LOSSY_LO_ARRIVAL_BYTE_COUNTr,
   2982           IDB_OBM3_LOSSY_HI_ARRIVAL_BYTE_COUNTr,
   2983           IDB_OBM3_LOSSLESS0_ARRIVAL_BYTE_COUNTr,
   2984           IDB_OBM3_LOSSLESS1_ARRIVAL_BYTE_COUNTr,
   2985           IDB_OBM3_EXPRESS_ARRIVAL_BYTE_COUNTr}
   2986         },
   2987         {
   2988          {IDB_OBM4_LOSSY_LO_BYTE_DROP_COUNTr,
   2989           IDB_OBM4_LOSSY_HI_BYTE_DROP_COUNTr,
   2990           IDB_OBM4_LOSSLESS0_BYTE_DROP_COUNTr,
   2991           IDB_OBM4_LOSSLESS1_BYTE_DROP_COUNTr,
   2992           IDB_OBM4_EXPRESS_BYTE_DROP_COUNTr},
   2993 
   2994          {IDB_OBM4_LOSSY_LO_ARRIVAL_BYTE_COUNTr,
   2995           IDB_OBM4_LOSSY_HI_ARRIVAL_BYTE_COUNTr,
   2996           IDB_OBM4_LOSSLESS0_ARRIVAL_BYTE_COUNTr,
   2997           IDB_OBM4_LOSSLESS1_ARRIVAL_BYTE_COUNTr,
   2998           IDB_OBM4_EXPRESS_ARRIVAL_BYTE_COUNTr}
   2999         },
   3000         {
   3001          {IDB_OBM5_LOSSY_LO_BYTE_DROP_COUNTr,
   3002           IDB_OBM5_LOSSY_HI_BYTE_DROP_COUNTr,
   3003           IDB_OBM5_LOSSLESS0_BYTE_DROP_COUNTr,
   3004           IDB_OBM5_LOSSLESS1_BYTE_DROP_COUNTr,
   3005           IDB_OBM5_EXPRESS_BYTE_DROP_COUNTr},
   3006 
   3007          {IDB_OBM5_LOSSY_LO_ARRIVAL_BYTE_COUNTr,
   3008           IDB_OBM5_LOSSY_HI_ARRIVAL_BYTE_COUNTr,
   3009           IDB_OBM5_LOSSLESS0_ARRIVAL_BYTE_COUNTr,
   3010           IDB_OBM5_LOSSLESS1_ARRIVAL_BYTE_COUNTr,
   3011           IDB_OBM5_EXPRESS_ARRIVAL_BYTE_COUNTr}
   3012         },
   3013         {
   3014          {IDB_OBM6_LOSSY_LO_BYTE_DROP_COUNTr,
   3015           IDB_OBM6_LOSSY_HI_BYTE_DROP_COUNTr,
   3016           IDB_OBM6_LOSSLESS0_BYTE_DROP_COUNTr,
   3017           IDB_OBM6_LOSSLESS1_BYTE_DROP_COUNTr,
   3018           IDB_OBM6_EXPRESS_BYTE_DROP_COUNTr},
   3019 
   3020          {IDB_OBM6_LOSSY_LO_ARRIVAL_BYTE_COUNTr,
   3021           IDB_OBM6_LOSSY_HI_ARRIVAL_BYTE_COUNTr,
   3022           IDB_OBM6_LOSSLESS0_ARRIVAL_BYTE_COUNTr,
   3023           IDB_OBM6_LOSSLESS1_ARRIVAL_BYTE_COUNTr,
   3024           IDB_OBM6_EXPRESS_ARRIVAL_BYTE_COUNTr}
   3025         },
   3026         {
   3027          {IDB_OBM7_LOSSY_LO_BYTE_DROP_COUNTr,
   3028           IDB_OBM7_LOSSY_HI_BYTE_DROP_COUNTr,
   3029           IDB_OBM7_LOSSLESS0_BYTE_DROP_COUNTr,
   3030           IDB_OBM7_LOSSLESS1_BYTE_DROP_COUNTr,
   3031           IDB_OBM7_EXPRESS_BYTE_DROP_COUNTr},
   3032 
   3033          {IDB_OBM7_LOSSY_LO_ARRIVAL_BYTE_COUNTr,
   3034           IDB_OBM7_LOSSY_HI_ARRIVAL_BYTE_COUNTr,
   3035           IDB_OBM7_LOSSLESS0_ARRIVAL_BYTE_COUNTr,
   3036           IDB_OBM7_LOSSLESS1_ARRIVAL_BYTE_COUNTr,
   3037           IDB_OBM7_EXPRESS_ARRIVAL_BYTE_COUNTr}
   3038         }
   3039     };
   3040     count = COUNTOF(obm_drop_byte_regs);
   3041     if (count > extra_ctr_ct) {
   3042         return SOC_E_PARAM;
   3043     }
   3044 
   3045     /* Do sanity check for input params */
   3046     if (!(non_dma_parent->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
   3047         return SOC_E_PARAM;
   3048     }
   3049     switch (non_dma_parent->id) {
   3050         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO:
   3051         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI:
   3052         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0:
   3053         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1:
   3054         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS:
   3055             byte_flag = 0;
   3056             counter_type = COUNTER_TYPE_DROP;
   3057             break;
   3058         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0:
   3059         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1:
   3060         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO:
   3061         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI:
   3062         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS:
   3063             byte_flag = 0;
   3064             counter_type = COUNTER_TYPE_ENQUEUE;
   3065             break;
   3066         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO:
   3067         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI:
   3068         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0:
   3069         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1:
   3070         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS:
   3071             byte_flag = 1;
   3072             counter_type = COUNTER_TYPE_DROP;
   3073             break;
   3074         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0:
   3075         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1:
   3076         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO:
   3077         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI:
   3078         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS:
   3079             byte_flag = 1;
   3080             counter_type = COUNTER_TYPE_ENQUEUE;
   3081             break;
   3082         default:
   3083             return SOC_E_PARAM;
   3084     }
   3085 
   3086     switch (non_dma_parent->id) {
   3087         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO:
   3088         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO:
   3089         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO:
   3090         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO:
   3091             obm_type = LOSSY_LO;
   3092             break;
   3093         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI:
   3094         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI:
   3095         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI:
   3096         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI:
   3097             obm_type = LOSSY_HI;
   3098             break;
   3099         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0:
   3100         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0:
   3101         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0:
   3102         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0:
   3103             obm_type = LOSSLESS0;
   3104             break;
   3105         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1:
   3106         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1:
   3107         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1:
   3108         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1:
   3109             obm_type = LOSSLESS1;
   3110             break;
   3111         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS:
   3112         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS:
   3113         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS:
   3114         case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS:
   3115             obm_type = EXPRESS;
   3116             break;
   3117     }
   3118 
   3119     parent_base_index = non_dma_parent->base_index;
   3120     *total_entries = 0;
   3121 
   3122     for (i = 0; i < extra_ctr_ct; i++) {
   3123         *non_dma_extra = *non_dma_parent;
   3124         if (byte_flag == 0) {
   3125             non_dma_extra->reg = obm_drop_pkt_regs[i][counter_type][obm_type];
   3126         } else {
   3127             non_dma_extra->reg = obm_drop_byte_regs[i][counter_type][obm_type];
   3128         }
   3129         non_dma_extra->extra_ctrs = NULL;
   3130         non_dma_extra->extra_ctr_ct = 0;
   3131         non_dma_extra->base_index = parent_base_index + *total_entries;
   3132         non_dma_extra->flags = (non_dma_parent->flags &
   3133                                 ~_SOC_COUNTER_NON_DMA_SUBSET_PARENT) |
   3134                                 _SOC_COUNTER_NON_DMA_SUBSET_CHILD;
   3135 
   3136         non_dma_extra->cname = sal_alloc(sal_strlen(non_dma_parent->cname) + 9,
   3137                                          "Extra ctrs cname");
   3138 
   3139         if (non_dma_extra->cname == NULL) {
   3140             return SOC_E_MEMORY;
   3141         }
   3142 
   3143         sal_sprintf(non_dma_extra->cname, "*OBM%d_%s_%s_%s",
   3144                     i, obm_type_str[obm_type],
   3145                     obm_ctr_type_str[counter_type],
   3146                     byte_flag ? "BYTE":"PKT");
   3147 
   3148         non_dma_extra->num_entries = non_dma_extra->entries_per_port;
   3149         *total_entries += non_dma_extra->num_entries;
   3150 
   3151         non_dma_extra += 2;
   3152     }
   3153     return SOC_E_NONE;
   3154 }
   3155 #endif /* BCM_MONTEREY_SUPPORT */
   3156 
   3157 #if defined (BCM_APACHE_SUPPORT)
   3158 /* Function to initialize extra counters */
   3159 STATIC int
   3160 soc_counter_apache_extra_obm_ctrs_init(int unit,
   3161                                    soc_counter_non_dma_t *non_dma_parent,
   3162                                    soc_counter_non_dma_t *non_dma_extra,
   3163                                    uint32 extra_ctr_ct,
   3164                                    int *total_entries)
   3165 {
   3166 #define LOSSY_LO 0
   3167 #define LOSSY_HI 1
   3168 #define LOSSLESS0 2
   3169 #define LOSSLESS1 3
   3170     char obm_type_str[][12] = {"LOSSY_LO", "LOSSY_HI",
   3171                                "LOSSLESS0", "LOSSLESS1"}; /* For CNAME */
   3172     int i, byte_flag = 0, obm_type = 0, parent_base_index = 0;
   3173     uint32 count = 0;
   3174 
   3175     soc_reg_t obm_drop_pkt_regs[][4] = {
   3176         {IDB_OBM0_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM0_LOSSY_HI_PKT_DROP_COUNTr,
   3177          IDB_OBM0_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM0_LOSSLESS1_PKT_DROP_COUNTr
   3178         },
   3179         {IDB_OBM1_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM1_LOSSY_HI_PKT_DROP_COUNTr,
   3180          IDB_OBM1_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM1_LOSSLESS1_PKT_DROP_COUNTr
   3181         },
   3182         {IDB_OBM2_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM2_LOSSY_HI_PKT_DROP_COUNTr,
   3183          IDB_OBM2_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM2_LOSSLESS1_PKT_DROP_COUNTr
   3184         },
   3185         {IDB_OBM3_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM3_LOSSY_HI_PKT_DROP_COUNTr,
   3186          IDB_OBM3_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM3_LOSSLESS1_PKT_DROP_COUNTr
   3187         },
   3188         {IDB_OBM4_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM4_LOSSY_HI_PKT_DROP_COUNTr,
   3189          IDB_OBM4_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM4_LOSSLESS1_PKT_DROP_COUNTr
   3190         },
   3191         {IDB_OBM5_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM5_LOSSY_HI_PKT_DROP_COUNTr,
   3192          IDB_OBM5_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM5_LOSSLESS1_PKT_DROP_COUNTr
   3193         },
   3194         {IDB_OBM6_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM6_LOSSY_HI_PKT_DROP_COUNTr,
   3195          IDB_OBM6_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM6_LOSSLESS1_PKT_DROP_COUNTr
   3196         },
   3197         {IDB_OBM7_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM7_LOSSY_HI_PKT_DROP_COUNTr,
   3198          IDB_OBM7_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM7_LOSSLESS1_PKT_DROP_COUNTr
   3199         },
   3200         {IDB_OBM8_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM8_LOSSY_HI_PKT_DROP_COUNTr,
   3201          IDB_OBM8_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM8_LOSSLESS1_PKT_DROP_COUNTr
   3202         },
   3203     };
   3204     soc_reg_t obm_drop_byte_regs[][4] = {
   3205         {IDB_OBM0_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM0_LOSSY_HI_BYTE_DROP_COUNTr,
   3206          IDB_OBM0_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM0_LOSSLESS1_BYTE_DROP_COUNTr
   3207         },
   3208         {IDB_OBM1_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM1_LOSSY_HI_BYTE_DROP_COUNTr,
   3209          IDB_OBM1_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM1_LOSSLESS1_BYTE_DROP_COUNTr
   3210         },
   3211         {IDB_OBM2_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM2_LOSSY_HI_BYTE_DROP_COUNTr,
   3212          IDB_OBM2_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM2_LOSSLESS1_BYTE_DROP_COUNTr
   3213         },
   3214         {IDB_OBM3_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM3_LOSSY_HI_BYTE_DROP_COUNTr,
   3215          IDB_OBM3_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM3_LOSSLESS1_BYTE_DROP_COUNTr
   3216         },
   3217         {IDB_OBM4_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM4_LOSSY_HI_BYTE_DROP_COUNTr,
   3218          IDB_OBM4_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM4_LOSSLESS1_BYTE_DROP_COUNTr
   3219         },
   3220         {IDB_OBM5_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM5_LOSSY_HI_BYTE_DROP_COUNTr,
   3221          IDB_OBM5_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM5_LOSSLESS1_BYTE_DROP_COUNTr
   3222         },
   3223         {IDB_OBM6_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM6_LOSSY_HI_BYTE_DROP_COUNTr,
   3224          IDB_OBM6_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM6_LOSSLESS1_BYTE_DROP_COUNTr
   3225         },
   3226         {IDB_OBM7_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM7_LOSSY_HI_BYTE_DROP_COUNTr,
   3227          IDB_OBM7_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM7_LOSSLESS1_BYTE_DROP_COUNTr
   3228         },
   3229         {IDB_OBM8_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM8_LOSSY_HI_BYTE_DROP_COUNTr,
   3230          IDB_OBM8_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM8_LOSSLESS1_BYTE_DROP_COUNTr
   3231         },
   3232     };
   3233 
   3234     count = COUNTOF(obm_drop_byte_regs);
   3235     if (count > extra_ctr_ct) {
   3236         return SOC_E_PARAM;
   3237     }
   3238 
   3239     /* Do sanity check for input params */
   3240     if (!(non_dma_parent->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
   3241         /* Only for Extra counters */
   3242         return SOC_E_PARAM;
   3243     }
   3244     switch (non_dma_parent->id) {
   3245         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO:
   3246         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI:
   3247         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0:
   3248         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1:
   3249             byte_flag = 0;
   3250             break;
   3251         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO:
   3252         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI:
   3253         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0:
   3254         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1:
   3255             byte_flag = 1;
   3256             break;
   3257         default:
   3258             return SOC_E_PARAM;
   3259     }
   3260 
   3261     switch (non_dma_parent->id) {
   3262         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO:
   3263         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO:
   3264             obm_type = LOSSY_LO;
   3265             break;
   3266         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI:
   3267         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI:
   3268             obm_type = LOSSY_HI;
   3269             break;
   3270         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0:
   3271         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0:
   3272             obm_type = LOSSLESS0;
   3273             break;
   3274         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1:
   3275         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1:
   3276             obm_type = LOSSLESS1;
   3277             break;
   3278     }
   3279 
   3280     parent_base_index = non_dma_parent->base_index;
   3281     *total_entries = 0;
   3282 
   3283     for (i = 0; i < extra_ctr_ct; i++) {
   3284         *non_dma_extra = *non_dma_parent;
   3285         if (byte_flag == 0) {
   3286             non_dma_extra->reg = obm_drop_pkt_regs[i][obm_type];
   3287         } else {
   3288             non_dma_extra->reg = obm_drop_byte_regs[i][obm_type];
   3289         }
   3290         non_dma_extra->extra_ctrs = NULL;
   3291         non_dma_extra->extra_ctr_ct = 0;
   3292         non_dma_extra->base_index = parent_base_index + *total_entries;
   3293         non_dma_extra->flags = (non_dma_parent->flags &
   3294                                 ~_SOC_COUNTER_NON_DMA_SUBSET_PARENT) |
   3295                                 _SOC_COUNTER_NON_DMA_SUBSET_CHILD;
   3296 
   3297         non_dma_extra->cname = sal_alloc(sal_strlen(non_dma_parent->cname) + 9,
   3298                                          "Extra ctrs cname");
   3299 
   3300         if (non_dma_extra->cname == NULL) {
   3301             return SOC_E_MEMORY;
   3302         }
   3303 
   3304         sal_sprintf(non_dma_extra->cname, "*OBM%d_%s_DRP_%s",
   3305                     i, obm_type_str[obm_type], byte_flag ? "BYTE":"PKT");
   3306 
   3307         non_dma_extra->num_entries = non_dma_extra->entries_per_port;
   3308         *total_entries += non_dma_extra->num_entries;
   3309 
   3310         /* Allocation of Child Control blocks.
   3311          * [0],..<even indices> - PKT_CTR non_dma ctrl block
   3312          * [1],..<odd indices> - BYTE_CTR non_dma ctrl block
   3313          * Hence in below code, jump by 2, so all similar control blocks are
   3314          * initilized at the same time.
   3315          */
   3316         non_dma_extra += 2;
   3317         /* coverity[check_after_deref] */
   3318         if (!non_dma_extra) {
   3319             /* ERR: Cannot be NULL, until 'i reaches 'extra_ctr_ct' */
   3320             /* This condition may not hit but intentional for defensive check */
   3321             /* coverity[dead_error_line] */
   3322             return SOC_E_INTERNAL;
   3323         }
   3324     }
   3325     return SOC_E_NONE;
   3326 }
   3327 
   3328 STATIC int
   3329 soc_counter_common_extra_obm_ctrs_init(int unit,
   3330                                        soc_counter_non_dma_t *non_dma_parent,
   3331                                        soc_counter_non_dma_t *non_dma_extra,
   3332                                        uint32 extra_ctr_ct,
   3333                                        int *total_entries)
   3334 {
   3335 #if defined(BCM_MONTEREY_SUPPORT)
   3336      if (SOC_IS_MONTEREY(unit)) {
   3337          return soc_counter_monterey_extra_obm_ctrs_init(unit,
   3338                                                          non_dma_parent,
   3339                                                          non_dma_extra,
   3340                                                          extra_ctr_ct,
   3341                                                          total_entries);
   3342      }
   3343 #endif
   3344      return soc_counter_apache_extra_obm_ctrs_init(unit,
   3345                                                      non_dma_parent,
   3346                                                      non_dma_extra,
   3347                                                      extra_ctr_ct,
   3348                                                      total_entries);
   3349 }
   3350 
   3351 #if defined(BCM_MONTEREY_SUPPORT) && defined (CPRIMOD_SUPPORT)
   3352 STATIC int
   3353 _soc_counter_monterey_non_dma_cpri_init(int unit, int nports,
   3354                                         int non_dma_start_index,
   3355                                         int *non_dma_entries)
   3356 {
   3357     soc_control_t *soc;
   3358     soc_counter_non_dma_t *non_dma0, *non_dma1, *non_dma2;
   3359     *non_dma_entries = 0;
   3360 
   3361     soc = SOC_CONTROL(unit);
   3362 
   3363     /*
   3364      * Adding CPRI counter information to the non dma info
   3365      * Although CPRI counters are DMA'able, it is inefficient
   3366      * because for DMA'ing the counters should be seperated by
   3367      * the same offset, else descriptors need to be created
   3368      * for each set of counters. There are only a few CPRI
   3369      * so not using dma.
   3370      * All the CPRI counters are
   3371      * 1. Read Only
   3372      * 2. Clear on Read
   3373      * 3. Saturate on Overflow
   3374      */
   3375 
   3376 
   3377     /*
   3378      *  symbol error counter that increments upon detecting symbol
   3379      *  error (due to invalid symbol or disparity error)
   3380      */
   3381     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_CPRI_RX_SYMBOL_ERR -
   3382                                      SOC_COUNTER_NON_DMA_START];
   3383 
   3384     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3385                       _SOC_COUNTER_NON_DMA_READ_ONLY |
   3386                       _SOC_COUNTER_NON_DMA_CLEAR_ON_READ |
   3387                       _SOC_COUNTER_NON_DMA_SATURATE_ON_OVERFLOW;
   3388 
   3389     SOC_PBMP_CLEAR(non_dma0->pbmp);
   3390     non_dma0->pbmp = PBMP_CPRI_ALL(unit);
   3391     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3392     non_dma0->entries_per_port = 1;
   3393     non_dma0->num_entries = nports;
   3394     non_dma0->mem = INVALIDm;
   3395     non_dma0->reg = CPRI_RXPCS_0_CNTR_STATUSr;
   3396     non_dma0->field = RXPCS_BER_COUNTf;
   3397     non_dma0->cname = "CPRI_RX_SYMBOL_ERR";
   3398     *non_dma_entries += non_dma0->num_entries;
   3399 
   3400     /*
   3401      * Counts the number of seed vector mismatches. It increments
   3402      * if the seed vector of the current hyperframe does not match
   3403      * the sts_rxpcs_seed_vector value.
   3404      */
   3405     non_dma1 =
   3406         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_CPRI_RX_SEED_VECTOR_MISMATCH -
   3407                               SOC_COUNTER_NON_DMA_START];
   3408 
   3409     *non_dma1 = *non_dma0;
   3410     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3411     non_dma1->reg = CPRI_RXPCS_1_CNTR_STATUSr;
   3412     non_dma1->field = RXPCS_SEED_MISMATCH_CNTf;
   3413     non_dma1->cname = "CPRI_RX_SEED_MISMATCH";
   3414     *non_dma_entries += non_dma1->num_entries;
   3415 
   3416 
   3417     /* Count number of state transitions into the error state */
   3418     non_dma1 =
   3419         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_CPRI_RX_STATE_TRANSITION_ERR -
   3420                               SOC_COUNTER_NON_DMA_START];
   3421 
   3422     *non_dma1 = *non_dma0;
   3423     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3424     non_dma1->reg = CPRI_RXPCS_2_CNTR_STATUSr;
   3425     non_dma1->field = RXPCS_64B66B_ERR_HF_CNTf;
   3426     non_dma1->cname = "CPRI_RX_STATE_TRANSITION_ERR";
   3427     *non_dma_entries += non_dma1->num_entries;
   3428 
   3429     /*
   3430      *  VSD Control Packet
   3431      *  Packet count with Flow-Id out of range(0-127)
   3432      */
   3433     non_dma1 = &soc->counter_non_dma[
   3434                     SOC_COUNTER_NON_DMA_CPRI_TX_VSD_CTRL_PKT_FLOW_ID_ERR -
   3435                     SOC_COUNTER_NON_DMA_START];
   3436 
   3437     *non_dma1 = *non_dma0;
   3438     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3439     non_dma1->reg = CPRI_TXFRM_CWA_VSD_CTRL_PACKET_SIZE_ERR_STATUSr;
   3440     non_dma1->field = TX_CWA_VSD_CTRL_PACKET_FLOW_ID_ERR_CNTf;
   3441     non_dma1->cname = "CPRI_TX_VSD_CTRL_FLOW_ID_ERR";
   3442     *non_dma_entries += non_dma1->num_entries;
   3443 
   3444     /*
   3445      *  VSD Control Packet
   3446      *  Counts the number of packets with packet size error.
   3447      *  Packet is longer than 16 bytes (1 decap data word).
   3448      */
   3449     non_dma2 = &soc->counter_non_dma[
   3450                     SOC_COUNTER_NON_DMA_CPRI_TX_VSD_CTRL_PKT_SIZE_ERR -
   3451                     SOC_COUNTER_NON_DMA_START];
   3452 
   3453     *non_dma2 = *non_dma1;
   3454     non_dma2->base_index = non_dma_start_index + *non_dma_entries;
   3455     non_dma2->field = TX_CWA_VSD_CTRL_PACKET_SIZE_ERR_CNTf;
   3456     non_dma2->cname = "CPRI_TX_VSD_CTRL_PKT_SIZE_ERR";
   3457     *non_dma_entries += non_dma2->num_entries;
   3458 
   3459     /*
   3460      * VSD Raw Packet
   3461      * Counts the number of packets with packet size error.
   3462      * Either packet is too short and ended before HF end, or
   3463      * packet is too long and extends past HF end.
   3464      */
   3465     non_dma1 = &soc->counter_non_dma[
   3466                     SOC_COUNTER_NON_DMA_CPRI_TX_VSD_RAW_PKT_SIZE_ERR -
   3467                     SOC_COUNTER_NON_DMA_START];
   3468 
   3469     *non_dma1 = *non_dma0;
   3470     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3471     non_dma1->reg = CPRI_TXFRM_CWA_VSD_RAW_PACKET_SIZE_ERR_STATUSr;
   3472     non_dma1->field = TX_CWA_VSD_RAW_PACKET_SIZE_ERR_CNTf;
   3473     non_dma1->cname = "CPRI_TX_VSD_RAW_PKT_SIZE_ERR";
   3474     *non_dma_entries += non_dma1->num_entries;
   3475 
   3476     /*
   3477      * Counts the number of packets dropped by RSVD5 due to CRC error.
   3478      */
   3479     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_RSVD5_TX_DROP_CRC_ERR -
   3480                                      SOC_COUNTER_NON_DMA_START];
   3481 
   3482     *non_dma1 = *non_dma0;
   3483     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3484     non_dma1->reg = BRCM_RESERVED_CPM_1r;
   3485     non_dma1->field = BRCM_RESERVED_CPM_1_1f;
   3486     non_dma1->cname = "CPRI_TX_RSVD5_DROP_CRC_ERR";
   3487     *non_dma_entries += non_dma1->num_entries;
   3488 
   3489     /*
   3490      * Counts the number of single message control streams
   3491      * dropped due to bad CRC.
   3492      */
   3493     non_dma1 = &soc->counter_non_dma[
   3494                     SOC_COUNTER_NON_DMA_RSVD4_RX_SINGLE_MSG_DROP_CRC_ERR -
   3495                     SOC_COUNTER_NON_DMA_START];
   3496 
   3497     *non_dma1 = *non_dma0;
   3498     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3499     non_dma1->reg = BRCM_RESERVED_CPM_323r;
   3500     non_dma1->field = BRCM_RESERVED_CPM_323_0f;
   3501     non_dma1->cname = "RSVD4_RX_SINGLE_MSG_DROP";
   3502     *non_dma_entries += non_dma1->num_entries;
   3503 
   3504     /*
   3505      * RSVD4 control message processing status counter.
   3506      * Counts the number of cases when the tag was not found during lookup.
   3507      */
   3508     non_dma1 = &soc->counter_non_dma[
   3509                     SOC_COUNTER_NON_DMA_RSVD4_RX_TAG_LKUP_FAIL -
   3510                     SOC_COUNTER_NON_DMA_START];
   3511 
   3512     *non_dma1 = *non_dma0;
   3513     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3514     non_dma1->reg = BRCM_RESERVED_CPM_324r;
   3515     non_dma1->field = BRCM_RESERVED_CPM_324_0f;
   3516     non_dma1->cname = "RSVD4_RX_TAG_LKUP_FAIL";
   3517     *non_dma_entries += non_dma1->num_entries;
   3518 
   3519     /* single message control streams including the error messages */
   3520     non_dma1 = &soc->counter_non_dma[
   3521                     SOC_COUNTER_NON_DMA_RSVD4_RX_SINGLE_MSG_CTRL_STREAMS -
   3522                     SOC_COUNTER_NON_DMA_START];
   3523 
   3524     *non_dma1 = *non_dma0;
   3525     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3526     non_dma1->reg = BRCM_RESERVED_CPM_325r;
   3527     non_dma1->field = BRCM_RESERVED_CPM_325_0f;
   3528     non_dma1->cname = "RSVD4_RX_SINGLE_MSG_CTRL_STREAMS";
   3529     *non_dma_entries += non_dma1->num_entries;
   3530 
   3531     /*
   3532      * Counts the number of multiple message control
   3533      * streams including the error messages.
   3534      */
   3535     non_dma1 = &soc->counter_non_dma[
   3536                     SOC_COUNTER_NON_DMA_RSVD4_RX_MULPILE_MSG_CTRL_STREAMS -
   3537                     SOC_COUNTER_NON_DMA_START];
   3538 
   3539     *non_dma1 = *non_dma0;
   3540     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3541     non_dma1->reg = BRCM_RESERVED_CPM_327r;
   3542     non_dma1->field = BRCM_RESERVED_CPM_327_0f;
   3543     non_dma1->cname = "RSVD4_RX_MULTIPLE_MSG_CTRL_STREAMS";
   3544     *non_dma_entries += non_dma1->num_entries;
   3545 
   3546     /*
   3547      * Counts the number of incorrect timestamp sequences.
   3548      * Increments once per incorrect timestamp sequence.
   3549      */
   3550     non_dma1 = &soc->counter_non_dma[
   3551                     SOC_COUNTER_NON_DMA_RSVD4_RX_INCORRECT_TIME_STAMP_SEQ -
   3552                     SOC_COUNTER_NON_DMA_START];
   3553 
   3554     *non_dma1 = *non_dma0;
   3555     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3556     non_dma1->reg = BRCM_RESERVED_CPM_326r;
   3557     non_dma1->field = BRCM_RESERVED_CPM_326_0f;
   3558     non_dma1->cname = "RSVD4_RX_INCORRECT_TS_SEQ";
   3559     *non_dma_entries += non_dma1->num_entries;
   3560 
   3561     /* Counts the number of data bytes in error. */
   3562     non_dma1 = &soc->counter_non_dma[
   3563                     SOC_COUNTER_NON_DMA_CPRI_RX_DATA_BYTES_ERR -
   3564                     SOC_COUNTER_NON_DMA_START];
   3565 
   3566     *non_dma1 = *non_dma0;
   3567     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3568     non_dma1->reg = CPRI_RX_STATS_CNTR_0_STATUSr;
   3569     non_dma1->field = RX_ERR_BYTE_CNTRf;
   3570     non_dma1->cname = "CPRI_RX_DATA_BYTE_ERR";
   3571     *non_dma_entries += non_dma1->num_entries;
   3572 
   3573     /* Counts the number of messages dropped due to header errors. */
   3574     non_dma1 = &soc->counter_non_dma[
   3575                     SOC_COUNTER_NON_DMA_CPRI_RX_RSVD4_HDR_MSG_ERR -
   3576                     SOC_COUNTER_NON_DMA_START];
   3577 
   3578     *non_dma1 = *non_dma0;
   3579     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3580     non_dma1->reg = CPRI_RX_STATS_CNTR_1_STATUSr;
   3581     non_dma1->field = BRCM_RESERVED_CPM_328_0f;
   3582     non_dma1->cname = "RSVD4_RX_HDR_ERR";
   3583     *non_dma_entries += non_dma1->num_entries;
   3584 
   3585     /*
   3586      * Counts the number of RSVD4 messages whose headers did not
   3587      * match any of the options in the look up table.
   3588      */
   3589     non_dma1 = &soc->counter_non_dma[
   3590                     SOC_COUNTER_NON_DMA_CPRI_RX_RSVD4_MSG_HDR_LKUP_FAIL -
   3591                     SOC_COUNTER_NON_DMA_START];
   3592 
   3593     *non_dma1 = *non_dma0;
   3594     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3595     non_dma1->reg = CPRI_RX_STATS_CNTR_2_STATUSr;
   3596     non_dma1->field = BRCM_RESERVED_CPM_329_0f;
   3597     non_dma1->cname = "RSVD4_RX_HDR_LKUP_FAIL";
   3598     *non_dma_entries += non_dma1->num_entries;
   3599 
   3600     /*
   3601      * Counts the total number of RSVD4 messages including
   3602      * the error and dropped messages.
   3603      */
   3604     non_dma1 = &soc->counter_non_dma[
   3605                     SOC_COUNTER_NON_DMA_CPRI_RX_RSVD4_TOTAL_MSG_COUNT -
   3606                     SOC_COUNTER_NON_DMA_START];
   3607 
   3608     *non_dma1 = *non_dma0;
   3609     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3610     non_dma1->reg = CPRI_RX_STATS_CNTR_3_STATUSr;
   3611     non_dma1->field = BRCM_RESERVED_CPM_330_0f;
   3612     non_dma1->cname = "RSVD4_RX_TOTAL_MSG_COUNT";
   3613     *non_dma_entries += non_dma1->num_entries;
   3614 
   3615     /* Counts the number of incorect HFN extracted */
   3616     non_dma1 = &soc->counter_non_dma[
   3617                     SOC_COUNTER_NON_DMA_CPRI_RX_INCORRECT_HFN_EXTRACT -
   3618                     SOC_COUNTER_NON_DMA_START];
   3619 
   3620     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   3621     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3622     non_dma1->reg = CPRI_RX_STATS_CNTR_4_STATUSr;
   3623     non_dma1->field = RXFRM_HFN_ERR_CNTRf;
   3624     non_dma1->cname = "CPRI_RX_INCORRECT_HFN";
   3625     *non_dma_entries += non_dma1->num_entries;
   3626 
   3627     /* Counts the number of incorect BFN extracted */
   3628     non_dma1 = &soc->counter_non_dma[
   3629                     SOC_COUNTER_NON_DMA_CPRI_RX_INCORRECT_BFN_EXTRACT -
   3630                     SOC_COUNTER_NON_DMA_START];
   3631 
   3632     *non_dma1 = *non_dma0;
   3633     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3634     non_dma1->reg = CPRI_RX_STATS_CNTR_5_STATUSr;
   3635     non_dma1->field = RXFRM_BFN_ERR_CNTRf;
   3636     non_dma1->cname = "CPRI_RX_INCORRECT_BFN";
   3637     *non_dma_entries += non_dma1->num_entries;
   3638 
   3639     /* Count of bytes in control words with error indication */
   3640     non_dma1 = &soc->counter_non_dma[
   3641                     SOC_COUNTER_NON_DMA_CPRI_RX_CTRL_WORD_ERR -
   3642                     SOC_COUNTER_NON_DMA_START];
   3643 
   3644     *non_dma1 = *non_dma0;
   3645     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3646     non_dma1->reg = CPRI_RX_STATS_CNTR_6_STATUSr;
   3647     non_dma1->field = RX_CW_ERR_CNTf;
   3648     non_dma1->cname = "CPRI_RX_CW_ERR";
   3649     *non_dma_entries += non_dma1->num_entries;
   3650 
   3651     /* count of Generic Control Word words dropped due to byte errors */
   3652     non_dma1 = &soc->counter_non_dma[
   3653                     SOC_COUNTER_NON_DMA_CPRI_RX_GENERIC_CTRL_WORD_ERR -
   3654                     SOC_COUNTER_NON_DMA_START];
   3655 
   3656     *non_dma1 = *non_dma0;
   3657     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3658     non_dma1->reg = CPRI_RX_GCW_ERR_CNTR_STATUSr;
   3659     non_dma1->field = RX_GCW_ERR_CNTf;
   3660     non_dma1->cname = "CPRI_RX_GCW_ERR";
   3661     *non_dma_entries += non_dma1->num_entries;
   3662 
   3663     /* VSD raw packets dropped due to byte errors */
   3664     non_dma1 = &soc->counter_non_dma[
   3665                     SOC_COUNTER_NON_DMA_CPRI_RX_VSD_RAW_PKT_DROP -
   3666                     SOC_COUNTER_NON_DMA_START];
   3667 
   3668     *non_dma1 = *non_dma0;
   3669     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3670     non_dma1->reg = CPRI_VSDRAW_ERR_CNTR_STATUSr;
   3671     non_dma1->field = RX_VSD_RAW_ERR_CNTf;
   3672     non_dma1->cname = "CPRI_RX_VSD_RAW_ERR";
   3673     *non_dma_entries += non_dma1->num_entries;
   3674 
   3675     /* Count of VSD control packets dropped due to byte error */
   3676     non_dma1 = &soc->counter_non_dma[
   3677                     SOC_COUNTER_NON_DMA_CPRI_RX_VSD_CTRL_PKT_DROP -
   3678                     SOC_COUNTER_NON_DMA_START];
   3679 
   3680     *non_dma1 = *non_dma0;
   3681     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3682     non_dma1->reg = CPRI_VSD_CTRL_ERR_CNTR_STATUSr;
   3683     non_dma1->field = RX_VSD_CTRL_ERR_CNTf;
   3684     non_dma1->cname = "CPRI_RX_VSD_CTRL_ERR";
   3685     *non_dma_entries += non_dma1->num_entries;
   3686 
   3687     /* Counts the number of RSVD4 data slots used as data messages. */
   3688     non_dma1 = &soc->counter_non_dma[
   3689                     SOC_COUNTER_NON_DMA_CPRI_TX_RSVD4_DATA_SLOT_DATA_MSG -
   3690                     SOC_COUNTER_NON_DMA_START];
   3691 
   3692     *non_dma1 = *non_dma0;
   3693     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3694     non_dma1->reg = BRCM_RESERVED_CPM_6r;
   3695     non_dma1->field = BRCM_RESERVED_CPM_6_0f;
   3696     non_dma1->cname = "RSVD4_DATA_SLOT_DATA_MSG_CNT";
   3697     *non_dma_entries += non_dma1->num_entries;
   3698 
   3699     /* Counts the number of RSVD4 data slots used as empty messages */
   3700     non_dma1 = &soc->counter_non_dma[
   3701                     SOC_COUNTER_NON_DMA_CPRI_TX_RSVD4_DATA_SLOT_EMPTY_MSG -
   3702                     SOC_COUNTER_NON_DMA_START];
   3703 
   3704     *non_dma1 = *non_dma0;
   3705     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3706     non_dma1->reg = BRCM_RESERVED_CPM_7r;
   3707     non_dma1->field = BRCM_RESERVED_CPM_7_0f;
   3708     non_dma1->cname = "RSVD4_DATA_SLOT_EMPTY_MSG_CNT";
   3709     *non_dma_entries += non_dma1->num_entries;
   3710 
   3711     /* Counts the number of RSVD4 control slots used as control messages */
   3712     non_dma1 = &soc->counter_non_dma[
   3713                     SOC_COUNTER_NON_DMA_CPRI_TX_RSVD4_CTRL_SLOT_CTRL_MSG -
   3714                     SOC_COUNTER_NON_DMA_START];
   3715 
   3716     *non_dma1 = *non_dma0;
   3717     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3718     non_dma1->reg = BRCM_RESERVED_CPM_8r;
   3719     non_dma1->field = BRCM_RESERVED_CPM_8_0f;
   3720     non_dma1->cname = "RSVD4_CTRL_SLOT_CTRL_MSG_CNT";
   3721     *non_dma_entries += non_dma1->num_entries;
   3722 
   3723     /* Counts the number of RSVD4 control slots used as empty messages */
   3724     non_dma1 = &soc->counter_non_dma[
   3725                     SOC_COUNTER_NON_DMA_CPRI_TX_RSVD4_CTRL_SLOT_EMPTY_MSG -
   3726                     SOC_COUNTER_NON_DMA_START];
   3727 
   3728     *non_dma1 = *non_dma0;
   3729     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3730     non_dma1->reg = BRCM_RESERVED_CPM_9r;
   3731     non_dma1->field = BRCM_RESERVED_CPM_9_0f;
   3732     non_dma1->cname = "RSVD4_CTRL_SLOT_EMPTY_MSG_CNT";
   3733     *non_dma_entries += non_dma1->num_entries;
   3734 
   3735     /* Count of RSVD5 messages with incorrect parity. */
   3736     non_dma1 = &soc->counter_non_dma[
   3737                     SOC_COUNTER_NON_DMA_RSVD5_RX_MSG_PARITY_ERR -
   3738                     SOC_COUNTER_NON_DMA_START];
   3739 
   3740     *non_dma1 = *non_dma0;
   3741     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3742     non_dma1->reg = BRCM_RESERVED_CPM_316r;
   3743     non_dma1->field = BRCM_RESERVED_CPM_316_0f;
   3744     non_dma1->cname = "RSVD5_MSG_PARITY_ERR";
   3745     *non_dma_entries += non_dma1->num_entries;
   3746 
   3747     /*
   3748      * HDLC error frame counter. Increments if the HDLC frame
   3749      * contains errors, abort sequence or FCS errors. Counts runt
   3750      * frames too that are dropped.
   3751      */
   3752     non_dma1 = &soc->counter_non_dma[
   3753                     SOC_COUNTER_NON_DMA_CPRI_RX_HDLC_FRAME_ERR -
   3754                     SOC_COUNTER_NON_DMA_START];
   3755 
   3756     *non_dma1 = *non_dma0;
   3757     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3758     non_dma1->reg = CPRI_HDLC_ERR_CNTR_STATUSr;
   3759     non_dma1->field = RX_HDLC_ERROR_FRAME_CNTf;
   3760     non_dma1->cname = "CPRI_RX_HDLC_FRM_ERR";
   3761     *non_dma_entries += non_dma1->num_entries;
   3762 
   3763     /* HDLC good frame counter. */
   3764     non_dma1 = &soc->counter_non_dma[
   3765                     SOC_COUNTER_NON_DMA_CPRI_RX_HDLC_FRAME_OK -
   3766                     SOC_COUNTER_NON_DMA_START];
   3767 
   3768     *non_dma1 = *non_dma0;
   3769     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3770     non_dma1->reg = CPRI_HDLC_CNTR_STATUSr;
   3771     non_dma1->field = RX_HDLC_GOOD_FRAME_CNTf;
   3772     non_dma1->cname = "CPRI_RX_HDLC_FRM_CNT";
   3773     *non_dma_entries += non_dma1->num_entries;
   3774 
   3775     /* Counts the error packets dropped in the MAC */
   3776     non_dma1 = &soc->counter_non_dma[
   3777                     SOC_COUNTER_NON_DMA_CPRI_RX_FAST_ETH_PKT_MAC_DROP -
   3778                     SOC_COUNTER_NON_DMA_START];
   3779 
   3780     *non_dma1 = *non_dma0;
   3781     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3782     non_dma1->reg = CPRI_FAST_ETH_ERR_CNTR_STATUSr;
   3783     non_dma1->field = RX_FAST_ETH_MAC_ERR_PKT_CNTf;
   3784     non_dma1->cname = "CPRI_RX_FAST_ETH_PKT_DROP_CNT";
   3785     *non_dma_entries += non_dma1->num_entries;
   3786 
   3787     /* Counts the number of valid packets forwarded to the encap block */
   3788     non_dma1 = &soc->counter_non_dma[
   3789                     SOC_COUNTER_NON_DMA_CPRI_RX_FAST_ETH_PKT_MAC_OK -
   3790                     SOC_COUNTER_NON_DMA_START];
   3791 
   3792     *non_dma1 = *non_dma0;
   3793     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3794     non_dma1->reg = CPRI_FAST_ETH_CNTR_STATUSr;
   3795     non_dma1->field = RX_FAST_ETH_MAC_PKT_CNTf;
   3796     non_dma1->cname = "CPRI_RX_FAST_ETH_PKT_CNT";
   3797     *non_dma_entries += non_dma1->num_entries;
   3798 
   3799     return SOC_E_NONE;
   3800 }
   3801 #endif /* BCM_MONTEREY_SUPPORT  && CPRIMOD_SUPPORT */
   3802 
   3803 STATIC int
   3804 _soc_counter_apache_non_dma_init(int unit, int nports, 
   3805                                    int non_dma_start_index, 
   3806                                    int *non_dma_entries)
   3807 {
   3808     soc_control_t *soc;
   3809     soc_counter_non_dma_t *non_dma0, *non_dma1, *non_dma2, *temp;
   3810     int  alloc_size;
   3811     uint32 *buf;
   3812     uint32 dma_num_entries=0,dma_num_index=0, dma_index_max = 0;
   3813     int full_chip = 1, rv, num_extra_ctr_entries;
   3814     soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit);
   3815 
   3816     soc = SOC_CONTROL(unit);
   3817     *non_dma_entries = 0;
   3818 
   3819     /* MMU_CTR_UC_DROP_MEM is the largest table to be DMA'ed */
   3820     if (SOC_IS_MONTEREY(unit)) {
   3821         alloc_size = 2 * soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm) *
   3822                       sizeof(uint32) *  soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm);
   3823         dma_num_entries=67;
   3824         dma_num_index=66;
   3825         dma_index_max = 639;
   3826     } else {
   3827     alloc_size = 2 * soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm) *
   3828                   sizeof(uint32) *  soc_mem_entry_words(unit, MMU_CTR_UC_DROP_MEMm);
   3829         dma_num_entries=74;
   3830         dma_num_index=74;
   3831         dma_index_max = 16383;
   3832     }
   3833 
   3834     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   3835     if (buf == NULL) {
   3836         return SOC_E_MEMORY;
   3837     }
   3838     sal_memset(buf, 0, alloc_size);
   3839 
   3840     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   3841                                      SOC_COUNTER_NON_DMA_START];
   3842     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3843         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   3844     non_dma0->pbmp = PBMP_ALL(unit);
   3845     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3846     non_dma0->entries_per_port = 48; /* cpu port has max number of queues */
   3847     non_dma0->num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm) / ((full_chip)? 1 : 2);
   3848     non_dma0->mem = EGR_PERQ_XMT_COUNTERSm;
   3849     non_dma0->reg = INVALIDr;
   3850     non_dma0->field = PACKET_COUNTERf;
   3851     non_dma0->cname = "MC_PERQ_PKT";
   3852     non_dma0->dma_buf[0] = buf;
   3853     non_dma0->dma_index_max[0] = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm) - 1;
   3854     non_dma0->dma_mem[0] = EGR_PERQ_XMT_COUNTERSm;
   3855     *non_dma_entries += non_dma0->num_entries;
   3856 
   3857     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   3858                                      SOC_COUNTER_NON_DMA_START];
   3859     *non_dma1 = *non_dma0;
   3860     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   3861     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3862     non_dma1->field = BYTE_COUNTERf;
   3863     non_dma1->cname = "MC_PERQ_BYTE";
   3864     *non_dma_entries += non_dma1->num_entries;
   3865 
   3866     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC -
   3867                                      SOC_COUNTER_NON_DMA_START];
   3868     *non_dma2 = *non_dma0;
   3869     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID;
   3870     non_dma2->pbmp = PBMP_PORT_ALL(unit);
   3871     non_dma2->entries_per_port = 10;
   3872     non_dma2->num_entries = 0; 
   3873     non_dma2->cname = "UC_PERQ_PKT";
   3874 
   3875     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC -
   3876                                      SOC_COUNTER_NON_DMA_START];
   3877     *non_dma2 = *non_dma1;
   3878     non_dma2->pbmp = PBMP_PORT_ALL(unit);
   3879     non_dma2->entries_per_port = 10;
   3880     non_dma2->num_entries = 0; 
   3881     non_dma2->cname = "UC_PERQ_BYTE";
   3882 
   3883     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT -
   3884                                      SOC_COUNTER_NON_DMA_START];
   3885     *non_dma2 = *non_dma0;
   3886     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID;
   3887 
   3888     non_dma2->entries_per_port = 0;
   3889     non_dma2->num_entries = 0;
   3890     SOC_PBMP_CLEAR(non_dma2->pbmp);
   3891 
   3892     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT -
   3893                                      SOC_COUNTER_NON_DMA_START];
   3894     *non_dma2 = *non_dma1;
   3895     non_dma2->entries_per_port = 0;
   3896     non_dma2->num_entries = 0;
   3897     SOC_PBMP_CLEAR(non_dma2->pbmp);
   3898 
   3899     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   3900                                      SOC_COUNTER_NON_DMA_START];
   3901     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3902                       _SOC_COUNTER_NON_DMA_DO_DMA;
   3903     non_dma0->pbmp = PBMP_ALL(unit);
   3904     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3905     non_dma0->entries_per_port = 48; /* APACHE 48 for cpu port */
   3906     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_MC_DROP_MEM0m);
   3907     non_dma0->mem = MMU_CTR_MC_DROP_MEM0m;
   3908     non_dma0->reg = INVALIDr;
   3909     non_dma0->field = PKTCNTf;
   3910     non_dma0->cname = "MCQ_DROP_PKT";
   3911     non_dma0->dma_mem[0] = MMU_CTR_MC_DROP_MEM0m;
   3912     non_dma0->dma_buf[0] = buf;
   3913     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]);
   3914     *non_dma_entries += non_dma0->num_entries;
   3915 
   3916     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE -
   3917                                      SOC_COUNTER_NON_DMA_START];
   3918     *non_dma1 = *non_dma0;
   3919     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   3920     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3921     non_dma1->field = BYTECNTf;
   3922     non_dma1->cname = "MCQ_DROP_BYTE";
   3923     *non_dma_entries += non_dma1->num_entries;
   3924 
   3925     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC -
   3926                                      SOC_COUNTER_NON_DMA_START];
   3927     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA;
   3928     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   3929     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3930     non_dma0->entries_per_port = 10;
   3931     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm);
   3932     non_dma0->mem = MMU_CTR_UC_DROP_MEMm;
   3933     non_dma0->reg = INVALIDr;
   3934     non_dma0->field = PKTCNTf;
   3935     non_dma0->cname = "UCQ_DROP_PKT";
   3936     non_dma0->dma_buf[0] = buf;
   3937     non_dma0->dma_index_max[0] = dma_index_max;
   3938     non_dma0->dma_mem[0] = non_dma0->mem;
   3939     *non_dma_entries += non_dma0->num_entries;
   3940 
   3941     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC -
   3942                                      SOC_COUNTER_NON_DMA_START];
   3943     *non_dma1 = *non_dma0;
   3944     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   3945     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3946     non_dma1->field = BYTECNTf;
   3947     non_dma1->cname = "UCQ_DROP_BYTE";
   3948     *non_dma_entries += non_dma1->num_entries;
   3949 
   3950     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING -
   3951                                      SOC_COUNTER_NON_DMA_START];
   3952     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA;
   3953     non_dma0->pbmp = PBMP_ALL(unit);
   3954     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3955     non_dma0->entries_per_port = 1;
   3956     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_ING_DROP_MEMm);
   3957     non_dma0->mem = MMU_CTR_ING_DROP_MEMm;
   3958     non_dma0->reg = INVALIDr;
   3959     non_dma0->field = PKTCNTf;
   3960     non_dma0->cname = "DROP_PKT_ING";
   3961     non_dma0->dma_buf[0] = buf;
   3962     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->mem);
   3963     non_dma0->dma_mem[0] = non_dma0->mem;
   3964     *non_dma_entries += non_dma0->num_entries;
   3965 
   3966     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING -
   3967                                      SOC_COUNTER_NON_DMA_START];
   3968     *non_dma1 = *non_dma0;
   3969     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   3970     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3971     non_dma1->field = BYTECNTf;
   3972     non_dma1->cname = "DROP_BYTE_ING";
   3973     *non_dma_entries += non_dma1->num_entries;
   3974 
   3975     non_dma0 =
   3976         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER -
   3977                               SOC_COUNTER_NON_DMA_START];
   3978     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA;
   3979     non_dma0->pbmp = PBMP_ALL(unit);
   3980     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3981     non_dma0->entries_per_port = 1;
   3982     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_ING_DROP_MEMm);
   3983     non_dma0->mem = MMU_CTR_MTRI_DROP_MEMm;
   3984     non_dma0->reg = INVALIDr;
   3985     non_dma0->field = PKTCNTf;
   3986     non_dma0->cname = "DROP_PKT_IMTR";
   3987     non_dma0->dma_buf[0] = buf;
   3988     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->mem);
   3989     non_dma0->dma_mem[0] = non_dma0->mem;
   3990     *non_dma_entries += non_dma0->num_entries;
   3991 
   3992     non_dma1 =
   3993         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER -
   3994                               SOC_COUNTER_NON_DMA_START];
   3995     *non_dma1 = *non_dma0;
   3996     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   3997     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3998     non_dma1->field = BYTECNTf;
   3999     non_dma1->cname = "DROP_BYTE_IMTR";
   4000     *non_dma_entries += non_dma1->num_entries;
   4001 
   4002     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   4003                                      SOC_COUNTER_NON_DMA_START];
   4004     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4005         _SOC_COUNTER_NON_DMA_DO_DMA;
   4006     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   4007     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4008     non_dma0->entries_per_port = 1;
   4009     /* TO DO: APACHE For this ver of regs file num of entries changed */
   4010     non_dma0->num_entries = dma_num_entries; /* one per port */
   4011     non_dma0->mem = MMU_CTR_COLOR_DROP_MEMm;
   4012     non_dma0->reg = INVALIDr;
   4013     non_dma0->field = PKTCNTf;
   4014     non_dma0->cname = "DROP_PKT_YEL";
   4015     non_dma0->dma_buf[0] = buf;
   4016     non_dma0->dma_index_min[0] = dma_num_index * 4;
   4017     non_dma0->dma_index_max[0] = (dma_num_index * 4) + (dma_num_index -1);
   4018     non_dma0->dma_mem[0] = non_dma0->mem;
   4019     *non_dma_entries += non_dma0->num_entries;
   4020 
   4021     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   4022                                      SOC_COUNTER_NON_DMA_START];
   4023     *non_dma1 = *non_dma0;
   4024     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4025     non_dma1->cname = "DROP_PKT_RED";
   4026     /* TO DO: APACHE For this ver of regs file num of entries changed */
   4027     non_dma1->dma_index_min[0] = dma_num_index * 3;
   4028     non_dma1->dma_index_max[0] = (dma_num_index * 3) + (dma_num_index - 1);
   4029     *non_dma_entries += non_dma1->num_entries;
   4030 
   4031     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN -
   4032                                      SOC_COUNTER_NON_DMA_START];
   4033     *non_dma1 = *non_dma0;
   4034     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4035     non_dma1->cname = "WRED_PKT_GRE";
   4036     /* TO DO: APACHE For this ver of regs file num of entries changed */
   4037     non_dma1->dma_index_min[0] = dma_num_index * 2;
   4038     non_dma1->dma_index_max[0] = (dma_num_index * 2) + (dma_num_index - 1);
   4039     *non_dma_entries += non_dma1->num_entries;
   4040 
   4041     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW -
   4042                                      SOC_COUNTER_NON_DMA_START];
   4043     *non_dma1 = *non_dma0;
   4044     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4045     non_dma1->cname = "WRED_PKT_YEL";
   4046     /* TO DO: APACHE For this ver of regs file num of entries changed */
   4047     non_dma1->dma_index_min[0] = dma_num_index * 1;
   4048     non_dma1->dma_index_max[0] = (dma_num_index * 1) + (dma_num_index - 1);
   4049     *non_dma_entries += non_dma1->num_entries;
   4050 
   4051     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED -
   4052                                      SOC_COUNTER_NON_DMA_START];
   4053     *non_dma1 = *non_dma0;
   4054     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4055     non_dma1->cname = "WRED_PKT_RED";
   4056     non_dma1->dma_index_min[0] = 0;
   4057     non_dma1->dma_index_max[0] = 65;
   4058     *non_dma_entries += non_dma1->num_entries;
   4059 
   4060     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT -
   4061                                      SOC_COUNTER_NON_DMA_START];
   4062     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4063         _SOC_COUNTER_NON_DMA_DO_DMA;
   4064     SOC_PBMP_CLEAR(non_dma0->pbmp);
   4065     non_dma0->pbmp = PBMP_ALL(unit);
   4066     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4067     non_dma0->entries_per_port = 0;
   4068     non_dma0->num_entries = 11;
   4069     non_dma0->mem = INVALIDm;
   4070     non_dma0->reg = DROP_PKT_CNT_RQE_PKTr;
   4071     non_dma0->field = PKTCNTf;
   4072     non_dma0->cname = "RQ_DROP_PKT";
   4073     non_dma0->dma_buf[0] = buf;
   4074     *non_dma_entries += non_dma0->num_entries;
   4075 
   4076     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_BYTE -
   4077                                      SOC_COUNTER_NON_DMA_START];
   4078     *non_dma1 = *non_dma0;
   4079     non_dma1->pbmp = PBMP_ALL(unit);
   4080     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4081     non_dma1->reg = DROP_PKT_CNT_RQE_BYTE_64r;
   4082     non_dma1->field = BYTECNTf;
   4083     non_dma1->cname = "RQ_DROP_BYTE";
   4084     *non_dma_entries += non_dma1->num_entries;
   4085 
   4086     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW -
   4087                                      SOC_COUNTER_NON_DMA_START];
   4088     *non_dma1 = *non_dma0;
   4089     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4090     non_dma1->reg = DROP_PKT_CNT_RQE_YELr;
   4091     non_dma1->field = PKTCNTf;
   4092     non_dma1->cname = "RQ_DROP_PKT_YEL";
   4093     *non_dma_entries += non_dma1->num_entries;
   4094 
   4095     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED -
   4096                                      SOC_COUNTER_NON_DMA_START];
   4097     *non_dma1 = *non_dma0;
   4098     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4099     non_dma1->reg = DROP_PKT_CNT_RQE_REDr;
   4100     non_dma1->field = PKTCNTf;
   4101     non_dma1->cname = "RQ_DROP_PKT_RED";
   4102     *non_dma_entries += non_dma1->num_entries;
   4103 
   4104     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_PEAK -
   4105                                      SOC_COUNTER_NON_DMA_START];
   4106     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4107         _SOC_COUNTER_NON_DMA_PEAK;
   4108     SOC_PBMP_CLEAR(non_dma0->pbmp);
   4109     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4110     non_dma0->entries_per_port = 0;
   4111     non_dma0->num_entries = 4;
   4112     non_dma0->mem = INVALIDm;
   4113     non_dma0->reg = THDI_POOL_SHARED_COUNT_SPr;
   4114     non_dma0->field = TOTAL_BUFFER_COUNTf;
   4115     non_dma0->cname = "POOL_PEAK";
   4116     non_dma0->dma_buf[0] = buf;
   4117     *non_dma_entries += non_dma0->num_entries;
   4118 
   4119     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_CURRENT -
   4120                                      SOC_COUNTER_NON_DMA_START];
   4121     *non_dma2 = *non_dma0;
   4122     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   4123         _SOC_COUNTER_NON_DMA_CURRENT;
   4124     non_dma2->cname = "POOL_CUR";
   4125 
   4126     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_PEAK -
   4127                                      SOC_COUNTER_NON_DMA_START];
   4128     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4129         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK;
   4130     non_dma0->pbmp = PBMP_ALL(unit);
   4131     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4132     non_dma0->entries_per_port = 8;
   4133     non_dma0->num_entries = nports * non_dma0->entries_per_port;
   4134     non_dma0->mem = THDI_PORT_PG_CNTRS_RT1_Xm;
   4135     non_dma0->reg = INVALIDr;
   4136     non_dma0->field = PG_MIN_COUNTf;
   4137     non_dma0->cname = "PG_MIN_PEAK";
   4138     non_dma0->dma_mem[0] = THDI_PORT_PG_CNTRS_RT1_Xm;
   4139     non_dma0->dma_buf[0] = buf;
   4140     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]);
   4141     *non_dma_entries += non_dma0->num_entries;
   4142 
   4143     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_CURRENT -
   4144                                      SOC_COUNTER_NON_DMA_START];
   4145     *non_dma2 = *non_dma0;
   4146     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   4147             _SOC_COUNTER_NON_DMA_CURRENT;
   4148     non_dma2->cname = "PG_MIN_CUR";
   4149 
   4150     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_PEAK -
   4151                                      SOC_COUNTER_NON_DMA_START];
   4152     *non_dma1 = *non_dma0;
   4153     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   4154         _SOC_COUNTER_NON_DMA_PEAK;
   4155     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4156     non_dma1->field = PG_SHARED_COUNTf;
   4157     non_dma1->cname = "PG_SHARED_PEAK";
   4158     *non_dma_entries += non_dma1->num_entries;
   4159 
   4160     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT -
   4161                                      SOC_COUNTER_NON_DMA_START];
   4162     *non_dma2 = *non_dma1;
   4163     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   4164         _SOC_COUNTER_NON_DMA_CURRENT;
   4165     non_dma2->cname = "PG_SHARED_CUR";
   4166 
   4167     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_PEAK -
   4168                                      SOC_COUNTER_NON_DMA_START];
   4169     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4170         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK;
   4171     non_dma0->pbmp = PBMP_ALL(unit);
   4172     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4173     non_dma0->entries_per_port = 8;
   4174     non_dma0->num_entries = nports * non_dma0->entries_per_port;
   4175     non_dma0->mem = THDI_PORT_PG_CNTRS_RT2_Xm;
   4176     non_dma0->reg = INVALIDr;
   4177     non_dma0->field = PG_HDRM_COUNTf;
   4178     non_dma0->cname = "PG_HDRM_PEAK";
   4179     non_dma0->dma_mem[0] = THDI_PORT_PG_CNTRS_RT2_Xm;
   4180     non_dma0->dma_buf[0] = buf;
   4181     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]);
   4182     *non_dma_entries += non_dma0->num_entries;
   4183 
   4184     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT -
   4185                                      SOC_COUNTER_NON_DMA_START];
   4186     *non_dma2 = *non_dma0;
   4187     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   4188         _SOC_COUNTER_NON_DMA_CURRENT;
   4189     non_dma2->cname = "PG_HDRM_CUR";
   4190 
   4191     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_PEAK -
   4192                                      SOC_COUNTER_NON_DMA_START];
   4193     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4194         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK;
   4195     non_dma0->pbmp = PBMP_ALL(unit);
   4196     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4197     non_dma0->entries_per_port = 48; /* 48 for cpu port */
   4198     non_dma0->num_entries = soc_mem_index_count(unit, MMU_THDM_DB_QUEUE_COUNT_0m);
   4199     non_dma0->mem = MMU_THDM_DB_QUEUE_COUNT_0m;
   4200     non_dma0->reg = INVALIDr;
   4201     non_dma0->field = SHARED_COUNTf;
   4202     non_dma0->cname = "QUEUE_PEAK";
   4203     non_dma0->dma_mem[0] = MMU_THDM_DB_QUEUE_COUNT_0m;
   4204     non_dma0->dma_buf[0] = buf;
   4205     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]);
   4206     *non_dma_entries += non_dma0->num_entries;
   4207 
   4208     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_CURRENT -
   4209                                      SOC_COUNTER_NON_DMA_START];
   4210     *non_dma2 = *non_dma0;
   4211     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   4212         _SOC_COUNTER_NON_DMA_CURRENT;
   4213     non_dma2->cname = "QUEUE_CUR";
   4214 
   4215     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK -
   4216                                      SOC_COUNTER_NON_DMA_START];
   4217     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4218         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK;
   4219     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   4220     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4221     non_dma0->entries_per_port = 10;
   4222     non_dma0->num_entries =
   4223         soc_mem_index_count(unit, MMU_THDU_XPIPE_COUNTER_QUEUEm);
   4224     non_dma0->mem = MMU_THDU_XPIPE_COUNTER_QUEUEm;
   4225     non_dma0->reg = INVALIDr;
   4226     non_dma0->field = SHARED_COUNTf;
   4227     non_dma0->cname = "UC_QUEUE_PEAK";
   4228     non_dma0->dma_mem[0] = MMU_THDU_XPIPE_COUNTER_QUEUEm;
   4229     non_dma0->dma_buf[0] = buf;
   4230     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]) - 1;
   4231     *non_dma_entries += non_dma0->num_entries;
   4232 
   4233     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT -
   4234                                      SOC_COUNTER_NON_DMA_START];
   4235     *non_dma2 = *non_dma0;
   4236     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   4237         _SOC_COUNTER_NON_DMA_CURRENT;
   4238     non_dma2->cname = "UC_QUEUE_CUR";
   4239     if (!SOC_IS_MONTEREY(unit)) {
   4240     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_MMU_QCN_CNM -
   4241                                      SOC_COUNTER_NON_DMA_START];
   4242     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4243         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_FLEX_MAPPING;
   4244     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   4245     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4246     non_dma0->entries_per_port = 10;
   4247     non_dma0->num_entries = 1 * soc_mem_index_count(unit, MMU_QCN_CNM_COUNTERm);
   4248 
   4249     non_dma0->mem = MMU_QCN_CNM_COUNTERm;
   4250     non_dma0->reg = INVALIDr;
   4251     non_dma0->field = CNM_CNTf;
   4252     non_dma0->cname = "QCN_CNM_COUNTER";
   4253     non_dma0->dma_buf[0] = buf;
   4254     non_dma0->dma_mem[0] = non_dma0->mem;
   4255     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]);
   4256     non_dma0->soc_counter_hw_idx_get = soc_apache_qcn_counter_hw_index_get;
   4257     *non_dma_entries += non_dma0->num_entries;
   4258     }
   4259     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_PEAK -
   4260                                      SOC_COUNTER_NON_DMA_START];
   4261     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4262         _SOC_COUNTER_NON_DMA_PEAK;
   4263     SOC_PBMP_CLEAR(non_dma0->pbmp);
   4264     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4265     non_dma0->entries_per_port = 0;
   4266     non_dma0->num_entries = 1;
   4267     non_dma0->mem = INVALIDm;
   4268     non_dma0->reg = THDI_GLOBAL_HDRM_COUNT_PIPEXr;
   4269     non_dma0->field = GLOBAL_HDRM_COUNTf;
   4270 
   4271     non_dma0->cname = "GLOBAL_HDRM_COUNT_PEAK";
   4272     non_dma0->dma_buf[0] = buf;
   4273     *non_dma_entries += non_dma0->num_entries;
   4274 
   4275     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_CURRENT -
   4276         SOC_COUNTER_NON_DMA_START];
   4277     *non_dma2 = *non_dma0;
   4278     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   4279         _SOC_COUNTER_NON_DMA_CURRENT;
   4280     non_dma2->cname = "GLOBAL_HDRM_COUNT_CURR";
   4281 
   4282     non_dma0 =
   4283         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_E2E_DROP_COUNT -
   4284                               SOC_COUNTER_NON_DMA_START];
   4285     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   4286     SOC_PBMP_CLEAR(non_dma0->pbmp);
   4287     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4288     non_dma0->reg = E2E_DROP_COUNTr;
   4289     non_dma0->mem = INVALIDm;
   4290     non_dma0->entries_per_port = 0;
   4291     non_dma0->num_entries = 1;
   4292     non_dma0->field = COUNTf;
   4293     non_dma0->cname = "E2E_DROP_COUNT";
   4294     *non_dma_entries += non_dma1->num_entries;
   4295 
   4296 
   4297 
   4298     soc_ctr_ctrl->port_obm_info_get = soc_apache_port_obm_info_get;
   4299     /* Control block for IDB OBM counters */
   4300     /* Lossy LO drop counters - Pkt Counters */
   4301     non_dma0 =
   4302         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO -
   4303                               SOC_COUNTER_NON_DMA_START];
   4304     non_dma0->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO;
   4305     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4306     non_dma0->reg = IDB_OBM0_LOSSY_LO_PKT_DROP_COUNTr;
   4307     non_dma0->cname = "OBM_LOSSY_LO_DRP_PKT";
   4308 
   4309     /* Common across all OBM structures */
   4310     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4311                       _SOC_COUNTER_NON_DMA_OBM;
   4312     /* Use Parent-Child model to cover all 8 OBMs */
   4313     non_dma0->flags |= _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   4314     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   4315     non_dma0->entries_per_port = 8;
   4316     non_dma0->num_entries = 1;
   4317     non_dma0->mem = INVALIDm;
   4318     non_dma0->field = COUNTERf;
   4319     non_dma0->dma_buf[0] = buf;
   4320     non_dma0->pbmp = PBMP_ALL(unit);
   4321     /* Remove CPU port as OBM counters not applicable to CPU port*/
   4322     SOC_PBMP_PORT_REMOVE(non_dma0->pbmp, 0);
   4323 
   4324     /*
   4325      * Below represents how Extra cntrs are arranged
   4326      * for OBM 0-8 Drop Counters.
   4327      * n = NUM_OBMs (9)
   4328      *
   4329      *   [0]     [2]        [2n-2]
   4330      *  ------  ------     ------
   4331      * |      ||      |...|      |
   4332      * | PKT  || PKT  |...| PKT  |
   4333      * | [0]  || [1]  |...| [n-1]|
   4334      *  ------  ------ ... ------
   4335      * |      ||      |...|      |
   4336      * | BYTE || BYTE |...| BYTE |
   4337      * | [0]  || [1]  |...| [n-1]|
   4338      *  ------  ------     ------
   4339      *   [1]     [3]        [2n-1]
   4340      */
   4341     non_dma0->extra_ctr_ct = SOC_IS_MONTEREY(unit) ? _MN_PBLKS_PER_PIPE :_AP_PBLKS_PER_PIPE; /* 9 OBMs per Pipe */
   4342     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   4343     temp = non_dma0->extra_ctrs = sal_alloc(alloc_size,
   4344                                             "non_dma_ctrs_obm_lossy_lo");
   4345     if (non_dma0->extra_ctrs == NULL) {
   4346         non_dma0->extra_ctr_ct = 0;
   4347         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4348         return SOC_E_MEMORY;
   4349     } else {
   4350         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   4351         rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4352                                                 non_dma0,
   4353                                                 non_dma0->extra_ctrs,
   4354                                                 non_dma0->extra_ctr_ct,
   4355                                                 &num_extra_ctr_entries);
   4356         if (rv != SOC_E_NONE) {
   4357             LOG_CLI((BSL_META_U(unit,
   4358                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4359                         non_dma0->id - SOC_COUNTER_NON_DMA_START));
   4360         }
   4361         non_dma0->num_entries = num_extra_ctr_entries;
   4362     }
   4363     *non_dma_entries += non_dma0->num_entries;
   4364 
   4365     /* Lossy LO drop counters - Byte Counters */
   4366     non_dma1 =
   4367         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO -
   4368                               SOC_COUNTER_NON_DMA_START];
   4369     *non_dma1 = *non_dma0;
   4370     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO;
   4371     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4372     non_dma1->reg = IDB_OBM0_LOSSY_LO_BYTE_DROP_COUNTr;
   4373     non_dma1->field = COUNTERf;
   4374     non_dma1->cname = "OBM_LOSSY_LO_DRP_BYTE";
   4375 
   4376     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   4377     non_dma1->extra_ctrs = temp + 1;
   4378     if (non_dma1->extra_ctrs) {
   4379         rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4380                                                 non_dma1,
   4381                                                 non_dma1->extra_ctrs,
   4382                                                 non_dma1->extra_ctr_ct,
   4383                                                 &num_extra_ctr_entries);
   4384         if (rv != SOC_E_NONE) {
   4385             LOG_CLI((BSL_META_U(unit,
   4386                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4387                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4388         }
   4389     }
   4390     *non_dma_entries += non_dma1->num_entries;
   4391 
   4392     /* Lossy HI drop counters - Packet Counters */
   4393     non_dma1 =
   4394         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI -
   4395                               SOC_COUNTER_NON_DMA_START];
   4396     *non_dma1 = *non_dma0;
   4397     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI;
   4398     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4399     non_dma1->reg = IDB_OBM0_LOSSY_HI_PKT_DROP_COUNTr;
   4400     non_dma1->cname = "OBM_LOSSY_HI_DRP_PKT";
   4401 
   4402     temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   4403                                             "non_dma_ctrs_obm_lossy_hi");
   4404 
   4405     if (non_dma1->extra_ctrs == NULL) {
   4406         non_dma1->extra_ctr_ct = 0;
   4407         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4408         return SOC_E_MEMORY;
   4409     } else {
   4410         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   4411         rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4412                                                 non_dma1,
   4413                                                 non_dma1->extra_ctrs,
   4414                                                 non_dma1->extra_ctr_ct,
   4415                                                 &num_extra_ctr_entries);
   4416         if (rv != SOC_E_NONE) {
   4417             LOG_CLI((BSL_META_U(unit,
   4418                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4419                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4420         }
   4421         non_dma1->num_entries = num_extra_ctr_entries;
   4422     }
   4423     *non_dma_entries += non_dma1->num_entries;
   4424 
   4425     /* Lossy HI drop counters - Byte Counters */
   4426     non_dma1 =
   4427         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI -
   4428                               SOC_COUNTER_NON_DMA_START];
   4429     *non_dma1 = *non_dma0;
   4430     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI;
   4431     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4432     non_dma1->reg = IDB_OBM0_LOSSY_HI_BYTE_DROP_COUNTr;
   4433     non_dma1->field = COUNTERf;
   4434     non_dma1->cname = "OBM_LOSSY_HI_DRP_BYTE";
   4435 
   4436     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   4437     non_dma1->extra_ctrs = temp + 1;
   4438     if (non_dma1->extra_ctrs) {
   4439         rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4440                                                 non_dma1,
   4441                                                 non_dma1->extra_ctrs,
   4442                                                 non_dma1->extra_ctr_ct,
   4443                                             &num_extra_ctr_entries);
   4444         if (rv != SOC_E_NONE) {
   4445             LOG_CLI((BSL_META_U(unit,
   4446                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4447                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4448         }
   4449     }
   4450     *non_dma_entries += non_dma1->num_entries;
   4451 
   4452     /* Lossless0 drop counters - Packet Counters */
   4453     non_dma1 =
   4454         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0 -
   4455                               SOC_COUNTER_NON_DMA_START];
   4456     *non_dma1 = *non_dma0;
   4457     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0;
   4458     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4459     non_dma1->reg = IDB_OBM0_LOSSLESS0_PKT_DROP_COUNTr;
   4460     non_dma1->cname = "OBM_LOSSLESS0_DRP_PKT";
   4461 
   4462     temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   4463                                             "non_dma_ctrs_obm_lossless0");
   4464 
   4465     if (non_dma1->extra_ctrs == NULL) {
   4466         non_dma1->extra_ctr_ct = 0;
   4467         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4468         return SOC_E_MEMORY;
   4469     } else {
   4470         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   4471         rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4472                                                 non_dma1,
   4473                                                 non_dma1->extra_ctrs,
   4474                                                 non_dma1->extra_ctr_ct,
   4475                                                 &num_extra_ctr_entries);
   4476         if (rv != SOC_E_NONE) {
   4477             LOG_CLI((BSL_META_U(unit,
   4478                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4479                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4480         }
   4481         non_dma1->num_entries = num_extra_ctr_entries;
   4482     }
   4483     *non_dma_entries += non_dma1->num_entries;
   4484 
   4485     /* Lossless0 drop counters - Byte Counters */
   4486     non_dma1 =
   4487         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0 -
   4488                               SOC_COUNTER_NON_DMA_START];
   4489     *non_dma1 = *non_dma0;
   4490     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0;
   4491     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4492     non_dma1->reg = IDB_OBM0_LOSSLESS0_BYTE_DROP_COUNTr;
   4493     non_dma1->field = COUNTERf;
   4494     non_dma1->cname = "OBM_LOSSLESS0_DRP_BYTE";
   4495 
   4496     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   4497     non_dma1->extra_ctrs = temp + 1;
   4498     if (non_dma1->extra_ctrs) {
   4499         rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4500                                                 non_dma1,
   4501                                                 non_dma1->extra_ctrs,
   4502                                                 non_dma1->extra_ctr_ct,
   4503                                                 &num_extra_ctr_entries);
   4504         if (rv != SOC_E_NONE) {
   4505             LOG_CLI((BSL_META_U(unit,
   4506                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4507                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4508         }
   4509     }
   4510     *non_dma_entries += non_dma1->num_entries;
   4511 
   4512     /* Lossless1 drop counters - Packet counters */
   4513     non_dma1 =
   4514         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1 -
   4515                               SOC_COUNTER_NON_DMA_START];
   4516     *non_dma1 = *non_dma0;
   4517     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1;
   4518     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4519     non_dma1->reg = IDB_OBM0_LOSSLESS1_PKT_DROP_COUNTr;
   4520     non_dma1->cname = "OBM_LOSSLESS1_DRP_PKT";
   4521 
   4522     temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   4523                                             "non_dma_ctrs_obm_lossless1");
   4524 
   4525     if (non_dma1->extra_ctrs == NULL) {
   4526         non_dma1->extra_ctr_ct = 0;
   4527         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4528         return SOC_E_MEMORY;
   4529     } else {
   4530         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   4531         rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4532                                                 non_dma1,
   4533                                                 non_dma1->extra_ctrs,
   4534                                                 non_dma1->extra_ctr_ct,
   4535                                                 &num_extra_ctr_entries);
   4536         if (rv != SOC_E_NONE) {
   4537             LOG_CLI((BSL_META_U(unit,
   4538                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4539                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4540         }
   4541         non_dma1->num_entries = num_extra_ctr_entries;
   4542     }
   4543     *non_dma_entries += non_dma1->num_entries;
   4544 
   4545     /* Lossless1 drop counters - Byte Counters */
   4546     non_dma1 =
   4547         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1 -
   4548                               SOC_COUNTER_NON_DMA_START];
   4549     *non_dma1 = *non_dma0;
   4550     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1;
   4551     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4552     non_dma1->reg = IDB_OBM0_LOSSLESS1_BYTE_DROP_COUNTr;
   4553     non_dma1->field = COUNTERf;
   4554     non_dma1->cname = "OBM_LOSSLESS1_DRP_BYTE";
   4555 
   4556     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   4557     non_dma1->extra_ctrs = temp + 1;
   4558     if (non_dma1->extra_ctrs) {
   4559         rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4560                                                 non_dma1,
   4561                                                 non_dma1->extra_ctrs,
   4562                                                 non_dma1->extra_ctr_ct,
   4563                                                 &num_extra_ctr_entries);
   4564         if (rv != SOC_E_NONE) {
   4565             LOG_CLI((BSL_META_U(unit,
   4566                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4567                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4568         }
   4569     }
   4570     *non_dma_entries += non_dma1->num_entries;
   4571 
   4572     /* Following counters are Monterey specific */
   4573     if (SOC_IS_MONTEREY(unit)) {
   4574         /* Express drop counters - Packet counters */
   4575         non_dma1 =
   4576            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS -
   4577                                 SOC_COUNTER_NON_DMA_START];
   4578         *non_dma1 = *non_dma0;
   4579         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS;
   4580         non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4581         non_dma1->reg = IDB_OBM0_EXPRESS_PKT_DROP_COUNTr;
   4582         non_dma1->cname = "OBM_EXPRESS_DRP_PKT";
   4583 
   4584         temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   4585                                                 "non_dma_ctrs_obm_express_drop");
   4586 
   4587         if (non_dma1->extra_ctrs == NULL) {
   4588             non_dma1->extra_ctr_ct = 0;
   4589             non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4590             return SOC_E_MEMORY;
   4591         } else {
   4592             sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   4593             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4594                                                   non_dma1,
   4595                                                   non_dma1->extra_ctrs,
   4596                                                   non_dma1->extra_ctr_ct,
   4597                                                   &num_extra_ctr_entries);
   4598             if (rv != SOC_E_NONE) {
   4599                 LOG_CLI((BSL_META_U(unit,
   4600                                     "ERR: Extra ctrs Init FAILED for id %d\n"),
   4601                          non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4602             }
   4603             non_dma1->num_entries = num_extra_ctr_entries;
   4604         }
   4605         *non_dma_entries += non_dma1->num_entries;
   4606 
   4607         /* Express drop counters - Byte Counters */
   4608         non_dma1 =
   4609            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS -
   4610                                 SOC_COUNTER_NON_DMA_START];
   4611         *non_dma1 = *non_dma0;
   4612         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS;
   4613         non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4614         non_dma1->reg = IDB_OBM0_EXPRESS_BYTE_DROP_COUNTr;
   4615         non_dma1->field = COUNTERf;
   4616         non_dma1->cname = "OBM_EXPRESS_DRP_BYTE";
   4617 
   4618         /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   4619         non_dma1->extra_ctrs = temp + 1;
   4620         if (non_dma1->extra_ctrs) {
   4621             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4622                                                         non_dma1,
   4623                                                         non_dma1->extra_ctrs,
   4624                                                         non_dma1->extra_ctr_ct,
   4625                                                         &num_extra_ctr_entries);
   4626             if (rv != SOC_E_NONE) {
   4627                 LOG_CLI((BSL_META_U(unit,
   4628                                     "ERR: Extra ctrs Init FAILED for id %d\n"),
   4629                                     non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4630             }
   4631         }
   4632         *non_dma_entries += non_dma1->num_entries;
   4633 
   4634         /* Lossy_lo enqueue counters - Packet counters */
   4635         non_dma1 =
   4636            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO -
   4637                               SOC_COUNTER_NON_DMA_START];
   4638         *non_dma1 = *non_dma0;
   4639         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO;
   4640         non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4641         non_dma1->reg = IDB_OBM0_LOSSY_LO_ARRIVAL_PKT_COUNTr;
   4642         non_dma1->cname = "OBM_LOSSY_LO_ENQ_PKT";
   4643 
   4644         temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   4645                                                 "non_dma_ctrs_obm_lossy_lo_drop");
   4646 
   4647         if (non_dma1->extra_ctrs == NULL) {
   4648             non_dma1->extra_ctr_ct = 0;
   4649             non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4650             return SOC_E_MEMORY;
   4651         } else {
   4652             sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   4653             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4654                                                   non_dma1,
   4655                                                   non_dma1->extra_ctrs,
   4656                                                   non_dma1->extra_ctr_ct,
   4657                                                   &num_extra_ctr_entries);
   4658             if (rv != SOC_E_NONE) {
   4659                 LOG_CLI((BSL_META_U(unit,
   4660                                     "ERR: Extra ctrs Init FAILED for id %d\n"),
   4661                          non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4662             }
   4663             non_dma1->num_entries = num_extra_ctr_entries;
   4664         }
   4665         *non_dma_entries += non_dma1->num_entries;
   4666 
   4667         /* Lossy_lo enqueue counters - Byte Counters */
   4668         non_dma1 =
   4669            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO -
   4670                               SOC_COUNTER_NON_DMA_START];
   4671         *non_dma1 = *non_dma0;
   4672         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO;
   4673         non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4674         non_dma1->reg = IDB_OBM0_LOSSY_LO_ARRIVAL_BYTE_COUNTr;
   4675         non_dma1->field = COUNTERf;
   4676         non_dma1->cname = "OBM_LOSSY_LO_ENQ_BYTE";
   4677 
   4678         /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   4679         non_dma1->extra_ctrs = temp + 1;
   4680         if (non_dma1->extra_ctrs) {
   4681             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4682                                                         non_dma1,
   4683                                                         non_dma1->extra_ctrs,
   4684                                                         non_dma1->extra_ctr_ct,
   4685                                                         &num_extra_ctr_entries);
   4686             if (rv != SOC_E_NONE) {
   4687                 LOG_CLI((BSL_META_U(unit,
   4688                                     "ERR: Extra ctrs Init FAILED for id %d\n"),
   4689                                     non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4690             }
   4691         }
   4692         *non_dma_entries += non_dma1->num_entries;
   4693 
   4694         /* Lossy_hi enqueue counters - Packet counters */
   4695         non_dma1 =
   4696            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI -
   4697                                  SOC_COUNTER_NON_DMA_START];
   4698         *non_dma1 = *non_dma0;
   4699         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI;
   4700         non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4701         non_dma1->reg = IDB_OBM0_LOSSY_HI_ARRIVAL_PKT_COUNTr;
   4702         non_dma1->cname = "OBM_LOSSY_HI_ENQ_PKT";
   4703 
   4704         temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   4705                                                 "non_dma_ctrs_obm_lossy_hi_drop");
   4706 
   4707         if (non_dma1->extra_ctrs == NULL) {
   4708             non_dma1->extra_ctr_ct = 0;
   4709             non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4710         return SOC_E_MEMORY;
   4711     } else {
   4712             sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   4713             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4714                                                   non_dma1,
   4715                                                   non_dma1->extra_ctrs,
   4716                                                   non_dma1->extra_ctr_ct,
   4717                                                 &num_extra_ctr_entries);
   4718         if (rv != SOC_E_NONE) {
   4719             LOG_CLI((BSL_META_U(unit,
   4720                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4721                          non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4722         }
   4723             non_dma1->num_entries = num_extra_ctr_entries;
   4724     }
   4725         *non_dma_entries += non_dma1->num_entries;
   4726 
   4727         /* Lossy_hi enqueue counters - Byte Counters */
   4728     non_dma1 =
   4729            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI -
   4730                               SOC_COUNTER_NON_DMA_START];
   4731     *non_dma1 = *non_dma0;
   4732         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI;
   4733     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4734         non_dma1->reg = IDB_OBM0_LOSSY_HI_ARRIVAL_BYTE_COUNTr;
   4735     non_dma1->field = COUNTERf;
   4736         non_dma1->cname = "OBM_LOSSY_HI_ENQ_BYTE";
   4737 
   4738     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   4739     non_dma1->extra_ctrs = temp + 1;
   4740     if (non_dma1->extra_ctrs) {
   4741             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4742                                                 non_dma1,
   4743                                                 non_dma1->extra_ctrs,
   4744                                                 non_dma1->extra_ctr_ct,
   4745                                                 &num_extra_ctr_entries);
   4746         if (rv != SOC_E_NONE) {
   4747             LOG_CLI((BSL_META_U(unit,
   4748                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4749                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4750         }
   4751     }
   4752     *non_dma_entries += non_dma1->num_entries;
   4753 
   4754         /* Lossless0 enqueue counters - Packet counters */
   4755     non_dma1 =
   4756            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0 -
   4757                               SOC_COUNTER_NON_DMA_START];
   4758     *non_dma1 = *non_dma0;
   4759         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0;
   4760     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4761         non_dma1->reg = IDB_OBM0_LOSSLESS0_ARRIVAL_PKT_COUNTr;
   4762         non_dma1->cname = "OBM_LOSSLESS0_ENQ_PKT";
   4763 
   4764     temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   4765                                                 "non_dma_ctrs_obm_lossless0_enqueue");
   4766 
   4767     if (non_dma1->extra_ctrs == NULL) {
   4768         non_dma1->extra_ctr_ct = 0;
   4769         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4770         return SOC_E_MEMORY;
   4771     } else {
   4772         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   4773             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4774                                                 non_dma1,
   4775                                                 non_dma1->extra_ctrs,
   4776                                                 non_dma1->extra_ctr_ct,
   4777                                                 &num_extra_ctr_entries);
   4778         if (rv != SOC_E_NONE) {
   4779             LOG_CLI((BSL_META_U(unit,
   4780                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4781                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4782         }
   4783         non_dma1->num_entries = num_extra_ctr_entries;
   4784     }
   4785     *non_dma_entries += non_dma1->num_entries;
   4786 
   4787         /* Lossless0 enqueue counters - Byte Counters */
   4788     non_dma1 =
   4789            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0 -
   4790                               SOC_COUNTER_NON_DMA_START];
   4791     *non_dma1 = *non_dma0;
   4792         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0;
   4793     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4794         non_dma1->reg = IDB_OBM0_LOSSLESS0_ARRIVAL_BYTE_COUNTr;
   4795     non_dma1->field = COUNTERf;
   4796         non_dma1->cname = "OBM_LOSSLESS0_ENQ_BYTE";
   4797 
   4798     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   4799     non_dma1->extra_ctrs = temp + 1;
   4800     if (non_dma1->extra_ctrs) {
   4801             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4802                                                 non_dma1,
   4803                                                 non_dma1->extra_ctrs,
   4804                                                 non_dma1->extra_ctr_ct,
   4805                                             &num_extra_ctr_entries);
   4806         if (rv != SOC_E_NONE) {
   4807             LOG_CLI((BSL_META_U(unit,
   4808                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4809                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4810         }
   4811     }
   4812     *non_dma_entries += non_dma1->num_entries;
   4813 
   4814         /* Lossless1 enqueue counters - Packet counters */
   4815     non_dma1 =
   4816            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1 -
   4817                               SOC_COUNTER_NON_DMA_START];
   4818     *non_dma1 = *non_dma0;
   4819         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1;
   4820     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4821         non_dma1->reg = IDB_OBM0_LOSSLESS1_ARRIVAL_PKT_COUNTr;
   4822         non_dma1->cname = "OBM_LOSSLESS1_ENQ_PKT";
   4823 
   4824     temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   4825                                                 "non_dma_ctrs_obm_lossless1_enqueue");
   4826 
   4827     if (non_dma1->extra_ctrs == NULL) {
   4828         non_dma1->extra_ctr_ct = 0;
   4829         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4830         return SOC_E_MEMORY;
   4831     } else {
   4832         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   4833             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4834                                                 non_dma1,
   4835                                                 non_dma1->extra_ctrs,
   4836                                                 non_dma1->extra_ctr_ct,
   4837                                                 &num_extra_ctr_entries);
   4838         if (rv != SOC_E_NONE) {
   4839             LOG_CLI((BSL_META_U(unit,
   4840                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4841                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4842         }
   4843         non_dma1->num_entries = num_extra_ctr_entries;
   4844     }
   4845     *non_dma_entries += non_dma1->num_entries;
   4846 
   4847         /* Lossless1 enqueue counters - Byte Counters */
   4848     non_dma1 =
   4849            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1 -
   4850                               SOC_COUNTER_NON_DMA_START];
   4851     *non_dma1 = *non_dma0;
   4852         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1;
   4853     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4854         non_dma1->reg = IDB_OBM0_LOSSLESS1_ARRIVAL_BYTE_COUNTr;
   4855     non_dma1->field = COUNTERf;
   4856         non_dma1->cname = "OBM_LOSSLESS1_ENQ_BYTE";
   4857 
   4858     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   4859     non_dma1->extra_ctrs = temp + 1;
   4860     if (non_dma1->extra_ctrs) {
   4861             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4862                                                 non_dma1,
   4863                                                 non_dma1->extra_ctrs,
   4864                                                 non_dma1->extra_ctr_ct,
   4865                                                 &num_extra_ctr_entries);
   4866         if (rv != SOC_E_NONE) {
   4867             LOG_CLI((BSL_META_U(unit,
   4868                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4869                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4870         }
   4871     }
   4872     *non_dma_entries += non_dma1->num_entries;
   4873 
   4874         /* Express enqueue counters - Packet counters */
   4875     non_dma1 =
   4876            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS -
   4877                               SOC_COUNTER_NON_DMA_START];
   4878     *non_dma1 = *non_dma0;
   4879         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS;
   4880     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4881         non_dma1->reg = IDB_OBM0_EXPRESS_ARRIVAL_PKT_COUNTr;
   4882         non_dma1->cname = "OBM_EXPRESS_ENQ_PKT";
   4883 
   4884     temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   4885                                                 "non_dma_ctrs_obm_express_enqueue");
   4886 
   4887     if (non_dma1->extra_ctrs == NULL) {
   4888         non_dma1->extra_ctr_ct = 0;
   4889         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4890         return SOC_E_MEMORY;
   4891     } else {
   4892         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   4893             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4894                                                 non_dma1,
   4895                                                 non_dma1->extra_ctrs,
   4896                                                 non_dma1->extra_ctr_ct,
   4897                                                 &num_extra_ctr_entries);
   4898         if (rv != SOC_E_NONE) {
   4899             LOG_CLI((BSL_META_U(unit,
   4900                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4901                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4902         }
   4903         non_dma1->num_entries = num_extra_ctr_entries;
   4904     }
   4905     *non_dma_entries += non_dma1->num_entries;
   4906 
   4907         /* Express enqueue counters - Byte Counters */
   4908     non_dma1 =
   4909            &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS -
   4910                               SOC_COUNTER_NON_DMA_START];
   4911     *non_dma1 = *non_dma0;
   4912         non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS;
   4913     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4914         non_dma1->reg = IDB_OBM0_EXPRESS_ARRIVAL_BYTE_COUNTr;
   4915     non_dma1->field = COUNTERf;
   4916         non_dma1->cname = "OBM_EXPRESS_ENQ_BYTE";
   4917 
   4918     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   4919     non_dma1->extra_ctrs = temp + 1;
   4920     if (non_dma1->extra_ctrs) {
   4921             rv = soc_counter_common_extra_obm_ctrs_init(unit,
   4922                                                 non_dma1,
   4923                                                 non_dma1->extra_ctrs,
   4924                                                 non_dma1->extra_ctr_ct,
   4925                                                 &num_extra_ctr_entries);
   4926         if (rv != SOC_E_NONE) {
   4927             LOG_CLI((BSL_META_U(unit,
   4928                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4929                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4930         }
   4931     }
   4932     *non_dma_entries += non_dma1->num_entries;
   4933     }
   4934     /* End of Control block for IDB OBM counters */
   4935 
   4936     return SOC_E_NONE;
   4937 }
   4938 #endif /* BCM_APACHE_SUPPORT */
   4939 
   4940 
   4941 
   4942 #if defined ( BCM_TRIDENT2_SUPPORT ) || defined ( BCM_TRIDENT2PLUS_SUPPORT )
   4943 STATIC int
   4944 _soc_counter_trident2_non_dma_init(int unit, int nports,
   4945                                    int non_dma_start_index,
   4946                                    int *non_dma_entries)
   4947 {
   4948     soc_control_t *soc;
   4949     soc_counter_non_dma_t *non_dma0, *non_dma1, *non_dma2;
   4950     int  alloc_size;
   4951     uint32 *buf;
   4952     int full_chip = 1;
   4953 
   4954     soc = SOC_CONTROL(unit);
   4955     *non_dma_entries = 0;
   4956 
   4957 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4958     if (SAL_BOOT_QUICKTURN) {
   4959         if ( !soc_td2p_if_full_chip(unit)) {
   4960             /* testing with half chip */
   4961             full_chip = 0;
   4962         }
   4963     }
   4964 #endif
   4965 
   4966     /* MMU_CTR_UC_DROP_MEM is the largest table to be DMA'ed */
   4967 
   4968     alloc_size = 2 * soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm) *
   4969                   sizeof(uint32) *  soc_mem_entry_words(unit, MMU_CTR_UC_DROP_MEMm);
   4970 
   4971     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   4972     if (buf == NULL) {
   4973         return SOC_E_MEMORY;
   4974     }
   4975     sal_memset(buf, 0, alloc_size);
   4976 
   4977     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   4978                                      SOC_COUNTER_NON_DMA_START];
   4979     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4980         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   4981     non_dma0->pbmp = PBMP_ALL(unit);
   4982     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4983     non_dma0->entries_per_port = 48; /* cpu port has max number of queues */
   4984     non_dma0->num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERS_Xm) * ((full_chip)? 2 : 1);
   4985     non_dma0->mem = EGR_PERQ_XMT_COUNTERSm;
   4986     non_dma0->reg = INVALIDr;
   4987     non_dma0->field = PACKET_COUNTERf;
   4988     non_dma0->cname = "MC_PERQ_PKT";
   4989     non_dma0->dma_buf[0] = buf;
   4990     non_dma0->dma_buf[1] = (full_chip)?
   4991               &buf[soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERS_Xm) * 
   4992                    soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERS_Xm)] : NULL;
   4993     non_dma0->dma_index_max[0] = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERS_Xm) - 1;
   4994     non_dma0->dma_index_max[1] = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERS_Xm) - 1;
   4995     non_dma0->dma_mem[0] = EGR_PERQ_XMT_COUNTERS_Xm;
   4996     non_dma0->dma_mem[1] = EGR_PERQ_XMT_COUNTERS_Ym;
   4997     *non_dma_entries += non_dma0->num_entries;
   4998 
   4999     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   5000                                      SOC_COUNTER_NON_DMA_START];
   5001     *non_dma1 = *non_dma0;
   5002     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   5003     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5004     non_dma1->field = BYTE_COUNTERf;
   5005     non_dma1->cname = "MC_PERQ_BYTE";
   5006     *non_dma_entries += non_dma1->num_entries;
   5007 
   5008     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC -
   5009                                      SOC_COUNTER_NON_DMA_START];
   5010     *non_dma2 = *non_dma0;
   5011     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID;
   5012     non_dma2->pbmp = PBMP_PORT_ALL(unit);
   5013     non_dma2->entries_per_port = 16; /* front pannel port has max 16 L2 UC queues */
   5014     non_dma2->num_entries = 0;
   5015     non_dma2->cname = "UC_PERQ_PKT";
   5016 
   5017     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC -
   5018                                      SOC_COUNTER_NON_DMA_START];
   5019     *non_dma2 = *non_dma1;
   5020     non_dma2->pbmp = PBMP_PORT_ALL(unit);
   5021     non_dma2->entries_per_port = 16; /* front pannel port has max 16 L2 UC queues */
   5022     non_dma2->num_entries = 0;
   5023     non_dma2->cname = "UC_PERQ_BYTE";
   5024 
   5025     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT -
   5026                                      SOC_COUNTER_NON_DMA_START];
   5027     *non_dma2 = *non_dma0;
   5028     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID;
   5029     non_dma2->entries_per_port = 0;
   5030     non_dma2->num_entries = 0;
   5031     SOC_PBMP_CLEAR(non_dma2->pbmp);
   5032 
   5033     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT -
   5034                                      SOC_COUNTER_NON_DMA_START];
   5035     *non_dma2 = *non_dma1;
   5036     non_dma2->entries_per_port = 0;
   5037     non_dma2->num_entries = 0;
   5038     SOC_PBMP_CLEAR(non_dma2->pbmp);
   5039 
   5040     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   5041                                      SOC_COUNTER_NON_DMA_START];
   5042     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5043                       _SOC_COUNTER_NON_DMA_DO_DMA;
   5044     non_dma0->pbmp = PBMP_ALL(unit);
   5045     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5046     non_dma0->entries_per_port = 48; /* 48 for cpu port */
   5047     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_MC_DROP_MEM0m) +
   5048         soc_mem_index_count(unit, MMU_CTR_MC_DROP_MEM1m);
   5049     non_dma0->mem = MMU_CTR_MC_DROP_MEM0m;
   5050     non_dma0->reg = INVALIDr;
   5051     non_dma0->field = PKTCNTf;
   5052     non_dma0->cname = "MCQ_DROP_PKT";
   5053     non_dma0->dma_mem[0] = MMU_CTR_MC_DROP_MEM0m;
   5054     non_dma0->dma_mem[1] = MMU_CTR_MC_DROP_MEM1m;
   5055     non_dma0->dma_buf[0] = buf;
   5056     non_dma0->dma_buf[1] =
   5057         &buf[soc_mem_index_count(unit, non_dma0->dma_mem[0]) *
   5058              soc_mem_entry_words(unit, non_dma0->dma_mem[0])];
   5059     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]);
   5060     non_dma0->dma_index_max[1] = soc_mem_index_max(unit, non_dma0->dma_mem[1]);
   5061     *non_dma_entries += non_dma0->num_entries;
   5062 
   5063     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE -
   5064                                      SOC_COUNTER_NON_DMA_START];
   5065     *non_dma1 = *non_dma0;
   5066     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   5067     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5068     non_dma1->field = BYTECNTf;
   5069     non_dma1->cname = "MCQ_DROP_BYTE";
   5070     *non_dma_entries += non_dma1->num_entries;
   5071 
   5072     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC -
   5073                                      SOC_COUNTER_NON_DMA_START];
   5074     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA;
   5075     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   5076     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5077     non_dma0->entries_per_port = 16; /* front pannel port has max 16 L2 UC queues */
   5078     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm);
   5079     non_dma0->mem = MMU_CTR_UC_DROP_MEMm;
   5080     non_dma0->reg = INVALIDr;
   5081     non_dma0->field = PKTCNTf;
   5082     non_dma0->cname = "UCQ_DROP_PKT";
   5083     non_dma0->dma_buf[0] = buf;
   5084     non_dma0->dma_buf[1] =
   5085         &buf[1480 * soc_mem_entry_words(unit, non_dma0->mem)];
   5086     non_dma0->dma_index_max[0] = 1479;
   5087     non_dma0->dma_index_min[1] = 1536;
   5088     non_dma0->dma_index_max[1] = 3015;
   5089     non_dma0->dma_mem[0] = non_dma0->mem;
   5090     non_dma0->dma_mem[1] = non_dma0->mem;
   5091     *non_dma_entries += non_dma0->num_entries;
   5092 
   5093     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC -
   5094                                      SOC_COUNTER_NON_DMA_START];
   5095     *non_dma1 = *non_dma0;
   5096     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   5097     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5098     non_dma1->field = BYTECNTf;
   5099     non_dma1->cname = "UCQ_DROP_BYTE";
   5100     *non_dma_entries += non_dma1->num_entries;
   5101 
   5102     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_EXT -
   5103                                      SOC_COUNTER_NON_DMA_START];
   5104     *non_dma2 = *non_dma0;
   5105     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID;
   5106     non_dma2->entries_per_port = 0;
   5107     non_dma2->num_entries = 0;
   5108     SOC_PBMP_CLEAR(non_dma2->pbmp);
   5109 
   5110     non_dma2 =
   5111         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_EXT -
   5112                               SOC_COUNTER_NON_DMA_START];
   5113     *non_dma2 = *non_dma1;
   5114     non_dma2->entries_per_port = 0;
   5115     non_dma2->num_entries = 0;
   5116     SOC_PBMP_CLEAR(non_dma2->pbmp);
   5117 
   5118     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING -
   5119                                      SOC_COUNTER_NON_DMA_START];
   5120     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA;
   5121     non_dma0->pbmp = PBMP_ALL(unit);
   5122     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5123     non_dma0->entries_per_port = 1;
   5124     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_ING_DROP_MEMm);
   5125     non_dma0->mem = MMU_CTR_ING_DROP_MEMm;
   5126     non_dma0->reg = INVALIDr;
   5127     non_dma0->field = PKTCNTf;
   5128     non_dma0->cname = "DROP_PKT_ING";
   5129     non_dma0->dma_buf[0] = buf;
   5130     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->mem);
   5131     non_dma0->dma_mem[0] = non_dma0->mem;
   5132     *non_dma_entries += non_dma0->num_entries;
   5133 
   5134     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING -
   5135                                      SOC_COUNTER_NON_DMA_START];
   5136     *non_dma1 = *non_dma0;
   5137     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   5138     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5139     non_dma1->field = BYTECNTf;
   5140     non_dma1->cname = "DROP_BYTE_ING";
   5141     *non_dma_entries += non_dma1->num_entries;
   5142 
   5143     non_dma0 =
   5144         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER -
   5145                               SOC_COUNTER_NON_DMA_START];
   5146     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA;
   5147     non_dma0->pbmp = PBMP_ALL(unit);
   5148     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5149     non_dma0->entries_per_port = 1;
   5150     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_ING_DROP_MEMm);
   5151     non_dma0->mem = MMU_CTR_MTRI_DROP_MEMm;
   5152     non_dma0->reg = INVALIDr;
   5153     non_dma0->field = PKTCNTf;
   5154     non_dma0->cname = "DROP_PKT_IMTR";
   5155     non_dma0->dma_buf[0] = buf;
   5156     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->mem);
   5157     non_dma0->dma_mem[0] = non_dma0->mem;
   5158     *non_dma_entries += non_dma0->num_entries;
   5159 
   5160     non_dma1 =
   5161         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER -
   5162                               SOC_COUNTER_NON_DMA_START];
   5163     *non_dma1 = *non_dma0;
   5164     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   5165     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5166     non_dma1->field = BYTECNTf;
   5167     non_dma1->cname = "DROP_BYTE_IMTR";
   5168     *non_dma_entries += non_dma1->num_entries;
   5169 
   5170     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   5171                                      SOC_COUNTER_NON_DMA_START];
   5172     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5173         _SOC_COUNTER_NON_DMA_DO_DMA;
   5174     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   5175     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5176     non_dma0->entries_per_port = 1;
   5177     non_dma0->num_entries = 106; /* one per port */
   5178     non_dma0->mem = MMU_CTR_COLOR_DROP_MEMm;
   5179     non_dma0->reg = INVALIDr;
   5180     non_dma0->field = PKTCNTf;
   5181     non_dma0->cname = "DROP_PKT_YEL";
   5182     non_dma0->dma_buf[0] = buf;
   5183     non_dma0->dma_index_min[0] = 106 * 4;
   5184     non_dma0->dma_index_max[0] = (106 * 4) + 105;
   5185     non_dma0->dma_mem[0] = non_dma0->mem;
   5186     *non_dma_entries += non_dma0->num_entries;
   5187 
   5188     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   5189                                      SOC_COUNTER_NON_DMA_START];
   5190     *non_dma1 = *non_dma0;
   5191     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5192     non_dma1->cname = "DROP_PKT_RED";
   5193     non_dma1->dma_index_min[0] = 106 * 3;
   5194     non_dma1->dma_index_max[0] = (106 * 3) + 105;
   5195     *non_dma_entries += non_dma1->num_entries;
   5196 
   5197     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN -
   5198                                      SOC_COUNTER_NON_DMA_START];
   5199     *non_dma1 = *non_dma0;
   5200     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5201     non_dma1->cname = "WRED_PKT_GRE";
   5202     non_dma1->dma_index_min[0] = 106 * 2;
   5203     non_dma1->dma_index_max[0] = (106 * 2) + 105;
   5204     *non_dma_entries += non_dma1->num_entries;
   5205 
   5206     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW -
   5207                                      SOC_COUNTER_NON_DMA_START];
   5208     *non_dma1 = *non_dma0;
   5209     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5210     non_dma1->cname = "WRED_PKT_YEL";
   5211     non_dma1->dma_index_min[0] = 106 * 1;
   5212     non_dma1->dma_index_max[0] = (106 * 1) + 105;
   5213     *non_dma_entries += non_dma1->num_entries;
   5214 
   5215     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED -
   5216                                      SOC_COUNTER_NON_DMA_START];
   5217     *non_dma1 = *non_dma0;
   5218     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5219     non_dma1->cname = "WRED_PKT_RED";
   5220     non_dma1->dma_index_min[0] = 0;
   5221     non_dma1->dma_index_max[0] = 105;
   5222     *non_dma_entries += non_dma1->num_entries;
   5223 
   5224     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT -
   5225                                      SOC_COUNTER_NON_DMA_START];
   5226     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5227         _SOC_COUNTER_NON_DMA_DO_DMA;
   5228     /* SDK-67053 : Setting the port bitmap so that this counter can 
   5229        be cleared by the "clear c" command */
   5230     non_dma0->pbmp = PBMP_ALL(unit); 
   5231     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5232     non_dma0->entries_per_port = 0;
   5233     non_dma0->num_entries = 11;
   5234     non_dma0->mem = INVALIDm;
   5235     non_dma0->reg = DROP_PKT_CNT_RQE_PKTr;
   5236     non_dma0->field = PKTCNTf;
   5237     non_dma0->cname = "RQ_DROP_PKT";
   5238     non_dma0->dma_buf[0] = buf;
   5239     *non_dma_entries += non_dma0->num_entries;
   5240 
   5241     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_BYTE -
   5242                                      SOC_COUNTER_NON_DMA_START];
   5243     *non_dma1 = *non_dma0;
   5244     /* SDK-67053 : Setting the port bitmap so that this counter can 
   5245        be cleared by the "clear c" command */
   5246     non_dma1->pbmp = PBMP_ALL(unit);
   5247     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5248     non_dma1->reg = DROP_PKT_CNT_RQE_BYTE_64r;
   5249     non_dma1->field = BYTECNTf;
   5250     non_dma1->cname = "RQ_DROP_BYTE";
   5251     *non_dma_entries += non_dma1->num_entries;
   5252 
   5253     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW -
   5254                                      SOC_COUNTER_NON_DMA_START];
   5255     *non_dma1 = *non_dma0;
   5256     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5257     non_dma1->reg = DROP_PKT_CNT_RQE_YELr;
   5258     non_dma1->field = PKTCNTf;
   5259     non_dma1->cname = "RQ_DROP_PKT_YEL";
   5260     *non_dma_entries += non_dma1->num_entries;
   5261 
   5262     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED -
   5263                                      SOC_COUNTER_NON_DMA_START];
   5264     *non_dma1 = *non_dma0;
   5265     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5266     non_dma1->reg = DROP_PKT_CNT_RQE_REDr;
   5267     non_dma1->field = PKTCNTf;
   5268     non_dma1->cname = "RQ_DROP_PKT_RED";
   5269     *non_dma_entries += non_dma1->num_entries;
   5270 
   5271     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_PEAK -
   5272                                      SOC_COUNTER_NON_DMA_START];
   5273     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5274         _SOC_COUNTER_NON_DMA_PEAK;
   5275     SOC_PBMP_CLEAR(non_dma0->pbmp);
   5276     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5277     non_dma0->entries_per_port = 0;
   5278     non_dma0->num_entries = 4;
   5279     non_dma0->mem = INVALIDm;
   5280     non_dma0->reg = THDI_POOL_SHARED_COUNT_SPr;
   5281     non_dma0->field = TOTAL_BUFFER_COUNTf;
   5282     non_dma0->cname = "POOL_PEAK";
   5283     non_dma0->dma_buf[0] = buf;
   5284     *non_dma_entries += non_dma0->num_entries;
   5285 
   5286     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_CURRENT -
   5287                                      SOC_COUNTER_NON_DMA_START];
   5288     *non_dma2 = *non_dma0;
   5289     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   5290         _SOC_COUNTER_NON_DMA_CURRENT;
   5291     non_dma2->cname = "POOL_CUR";
   5292 
   5293     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_PEAK -
   5294                                      SOC_COUNTER_NON_DMA_START];
   5295     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5296         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK;
   5297     non_dma0->pbmp = PBMP_ALL(unit);
   5298     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5299     non_dma0->entries_per_port = 8;
   5300     non_dma0->num_entries = nports * non_dma0->entries_per_port;
   5301     non_dma0->mem = THDI_PORT_PG_CNTRS_RT1_Xm;
   5302     non_dma0->reg = INVALIDr;
   5303     non_dma0->field = PG_MIN_COUNTf;
   5304     non_dma0->cname = "PG_MIN_PEAK";
   5305     non_dma0->dma_mem[0] = THDI_PORT_PG_CNTRS_RT1_Xm;
   5306     non_dma0->dma_mem[1] = THDI_PORT_PG_CNTRS_RT1_Ym;
   5307     non_dma0->dma_buf[0] = buf;
   5308     non_dma0->dma_buf[1] = (full_chip)?
   5309         &buf[soc_mem_index_count(unit, non_dma0->dma_mem[0]) *
   5310              soc_mem_entry_words(unit, non_dma0->dma_mem[0])] : NULL;
   5311     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]);
   5312     non_dma0->dma_index_max[1] = soc_mem_index_max(unit, non_dma0->dma_mem[1]);
   5313     *non_dma_entries += non_dma0->num_entries;
   5314 
   5315     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_CURRENT -
   5316                                      SOC_COUNTER_NON_DMA_START];
   5317     *non_dma2 = *non_dma0;
   5318     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   5319             _SOC_COUNTER_NON_DMA_CURRENT;
   5320     non_dma2->cname = "PG_MIN_CUR";
   5321 
   5322     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_PEAK -
   5323                                      SOC_COUNTER_NON_DMA_START];
   5324     *non_dma1 = *non_dma0;
   5325     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   5326         _SOC_COUNTER_NON_DMA_PEAK;
   5327     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5328     non_dma1->field = PG_SHARED_COUNTf;
   5329     non_dma1->cname = "PG_SHARED_PEAK";
   5330     *non_dma_entries += non_dma1->num_entries;
   5331 
   5332     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT -
   5333                                      SOC_COUNTER_NON_DMA_START];
   5334     *non_dma2 = *non_dma1;
   5335     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   5336         _SOC_COUNTER_NON_DMA_CURRENT;
   5337     non_dma2->cname = "PG_SHARED_CUR";
   5338 
   5339     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_PEAK -
   5340                                      SOC_COUNTER_NON_DMA_START];
   5341     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5342         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK;
   5343     non_dma0->pbmp = PBMP_ALL(unit);
   5344     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5345     non_dma0->entries_per_port = 8;
   5346     non_dma0->num_entries = nports * non_dma0->entries_per_port;
   5347     non_dma0->mem = THDI_PORT_PG_CNTRS_RT2_Xm;
   5348     non_dma0->reg = INVALIDr;
   5349     non_dma0->field = PG_HDRM_COUNTf;
   5350     non_dma0->cname = "PG_HDRM_PEAK";
   5351     non_dma0->dma_mem[0] = THDI_PORT_PG_CNTRS_RT2_Xm;
   5352     non_dma0->dma_mem[1] = THDI_PORT_PG_CNTRS_RT2_Ym;
   5353     non_dma0->dma_buf[0] = buf;
   5354     non_dma0->dma_buf[1] = (full_chip)?
   5355         &buf[soc_mem_index_count(unit, non_dma0->dma_mem[0]) *
   5356              soc_mem_entry_words(unit, non_dma0->dma_mem[0])] : NULL;
   5357     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]);
   5358     non_dma0->dma_index_max[1] = soc_mem_index_max(unit, non_dma0->dma_mem[1]);
   5359     *non_dma_entries += non_dma0->num_entries;
   5360 
   5361     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT -
   5362                                      SOC_COUNTER_NON_DMA_START];
   5363     *non_dma2 = *non_dma0;
   5364     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   5365         _SOC_COUNTER_NON_DMA_CURRENT;
   5366     non_dma2->cname = "PG_HDRM_CUR";
   5367 
   5368     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_PEAK -
   5369                                      SOC_COUNTER_NON_DMA_START];
   5370     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5371         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK;
   5372     non_dma0->pbmp = PBMP_ALL(unit);
   5373     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5374     non_dma0->entries_per_port = 48; /* 48 for cpu port */
   5375     non_dma0->num_entries =
   5376         soc_mem_index_count(unit, MMU_THDM_DB_QUEUE_COUNT_0m) +
   5377         soc_mem_index_count(unit, MMU_THDM_DB_QUEUE_COUNT_1m);
   5378     non_dma0->mem = MMU_THDM_DB_QUEUE_COUNT_0m;
   5379     non_dma0->reg = INVALIDr;
   5380     non_dma0->field = SHARED_COUNTf;
   5381     non_dma0->cname = "QUEUE_PEAK";
   5382     non_dma0->dma_mem[0] = MMU_THDM_DB_QUEUE_COUNT_0m;
   5383     non_dma0->dma_mem[1] = MMU_THDM_DB_QUEUE_COUNT_1m;
   5384     non_dma0->dma_buf[0] = buf;
   5385     non_dma0->dma_buf[1] =
   5386         &buf[soc_mem_index_count(unit, non_dma0->dma_mem[0]) *
   5387              soc_mem_entry_words(unit, non_dma0->dma_mem[0])];
   5388     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]);
   5389     non_dma0->dma_index_max[1] = soc_mem_index_max(unit, non_dma0->dma_mem[1]);
   5390     *non_dma_entries += non_dma0->num_entries;
   5391 
   5392     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_CURRENT -
   5393                                      SOC_COUNTER_NON_DMA_START];
   5394     *non_dma2 = *non_dma0;
   5395     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   5396         _SOC_COUNTER_NON_DMA_CURRENT;
   5397     non_dma2->cname = "QUEUE_CUR";
   5398 
   5399     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK -
   5400                                      SOC_COUNTER_NON_DMA_START];
   5401     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5402         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK;
   5403     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   5404     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5405     non_dma0->entries_per_port = 10;
   5406     non_dma0->num_entries =
   5407         soc_mem_index_count(unit, MMU_THDU_XPIPE_COUNTER_QUEUEm) +
   5408         soc_mem_index_count(unit, MMU_THDU_YPIPE_COUNTER_QUEUEm);
   5409     non_dma0->mem = MMU_THDU_XPIPE_COUNTER_QUEUEm;
   5410     non_dma0->reg = INVALIDr;
   5411     non_dma0->field = SHARED_COUNTf;
   5412     non_dma0->cname = "UC_QUEUE_PEAK";
   5413     non_dma0->dma_mem[0] = MMU_THDU_XPIPE_COUNTER_QUEUEm;
   5414     non_dma0->dma_mem[1] = MMU_THDU_YPIPE_COUNTER_QUEUEm;
   5415     non_dma0->dma_buf[0] = buf;
   5416     non_dma0->dma_buf[1] =
   5417         &buf[((soc_mem_index_count(unit, non_dma0->dma_mem[0])) - 1) *
   5418              soc_mem_entry_words(unit, non_dma0->dma_mem[0])];
   5419     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]) - 1;
   5420     non_dma0->dma_index_max[1] = soc_mem_index_max(unit, non_dma0->dma_mem[1]);
   5421     *non_dma_entries += non_dma0->num_entries;
   5422 
   5423     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT -
   5424                                      SOC_COUNTER_NON_DMA_START];
   5425     *non_dma2 = *non_dma0;
   5426     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   5427         _SOC_COUNTER_NON_DMA_CURRENT;
   5428     non_dma2->cname = "UC_QUEUE_CUR";
   5429 
   5430     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_MMU_QCN_CNM -
   5431                                      SOC_COUNTER_NON_DMA_START];
   5432     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5433         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_FLEX_MAPPING;
   5434     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   5435     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5436     non_dma0->entries_per_port = 10;
   5437     non_dma0->num_entries = 2 * soc_mem_index_count(unit, MMU_QCN_CNM_COUNTERm);
   5438 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5439     if (SAL_BOOT_QUICKTURN && SOC_IS_TD2P_TT2P(unit)) {
   5440         non_dma0->num_entries = 1;
   5441     }
   5442 #endif
   5443 
   5444     non_dma0->mem = MMU_QCN_CNM_COUNTERm;
   5445     non_dma0->reg = INVALIDr;
   5446     non_dma0->field = CNM_CNTf;
   5447     non_dma0->cname = "QCN_CNM_COUNTER";
   5448     non_dma0->dma_buf[0] = buf;
   5449     non_dma0->dma_mem[0] = non_dma0->mem;
   5450     non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]);
   5451     non_dma0->soc_counter_hw_idx_get = soc_td2_qcn_counter_hw_index_get;
   5452     *non_dma_entries += non_dma0->num_entries;
   5453 
   5454     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_HIGH_PRI -
   5455                                  SOC_COUNTER_NON_DMA_START];
   5456     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5457                       _SOC_COUNTER_NON_DMA_OBM;
   5458     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   5459     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5460     non_dma0->entries_per_port = 4;
   5461     non_dma0->num_entries = 32;
   5462     non_dma0->mem = INVALIDm;
   5463     non_dma0->reg = PGW_OBM0_HIGH_PRI_PKT_DROPr;
   5464     non_dma0->field = COUNTERf;
   5465     non_dma0->cname = "OBM0_HIGH_PRI_DROP_PKT";
   5466     non_dma0->dma_buf[0] = buf;
   5467     *non_dma_entries += non_dma0->num_entries;
   5468 
   5469     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_LOW_PRI -
   5470                                      SOC_COUNTER_NON_DMA_START];
   5471     *non_dma1 = *non_dma0;
   5472     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5473     non_dma1->reg = PGW_OBM0_LOW_PRI_PKT_DROPr;
   5474     non_dma1->field = COUNTERf;
   5475     non_dma1->cname = "OBM0_LOW_PRI_DROP_PKT";
   5476     *non_dma_entries += non_dma1->num_entries;
   5477 
   5478     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_HIGH_PRI -
   5479                                      SOC_COUNTER_NON_DMA_START];
   5480     *non_dma1 = *non_dma0;
   5481     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5482     non_dma1->reg = PGW_OBM0_HIGH_PRI_BYTE_DROPr;
   5483     non_dma1->field = COUNTERf;
   5484     non_dma1->cname = "OBM0_HIGH_PRI_DROP_BYTE";
   5485     *non_dma_entries += non_dma1->num_entries;
   5486 
   5487     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_LOW_PRI -
   5488                                      SOC_COUNTER_NON_DMA_START];
   5489     *non_dma1 = *non_dma0;
   5490     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5491     non_dma1->reg = PGW_OBM0_LOW_PRI_BYTE_DROPr;
   5492     non_dma1->field = COUNTERf;
   5493     non_dma1->cname = "OBM0_LOW_PRI_DROP_BYTE";
   5494     *non_dma_entries += non_dma1->num_entries;
   5495 
   5496     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_HIGH_PRI -
   5497                                      SOC_COUNTER_NON_DMA_START];
   5498     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5499                       _SOC_COUNTER_NON_DMA_OBM;
   5500     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   5501     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5502     non_dma0->entries_per_port = 4;
   5503     non_dma0->num_entries = 32;
   5504     non_dma0->mem = INVALIDm;
   5505     non_dma0->reg = PGW_OBM1_HIGH_PRI_PKT_DROPr;
   5506     non_dma0->field = COUNTERf;
   5507     non_dma0->cname = "OBM1_HIGH_PRI_DROP_PKT";
   5508     non_dma0->dma_buf[0] = buf;
   5509     *non_dma_entries += non_dma0->num_entries;
   5510 
   5511     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_LOW_PRI -
   5512                                      SOC_COUNTER_NON_DMA_START];
   5513     *non_dma1 = *non_dma0;
   5514     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5515     non_dma1->reg = PGW_OBM1_LOW_PRI_PKT_DROPr;
   5516     non_dma1->field = COUNTERf;
   5517     non_dma1->cname = "OBM1_LOW_PRI_DROP_PKT";
   5518     *non_dma_entries += non_dma1->num_entries;
   5519 
   5520     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_HIGH_PRI -
   5521                                      SOC_COUNTER_NON_DMA_START];
   5522     *non_dma1 = *non_dma0;
   5523     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5524     non_dma1->reg = PGW_OBM1_HIGH_PRI_BYTE_DROPr;
   5525     non_dma1->field = COUNTERf;
   5526     non_dma1->cname = "OBM1_HIGH_PRI_DROP_BYTE";
   5527     *non_dma_entries += non_dma1->num_entries;
   5528 
   5529     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_LOW_PRI -
   5530                                      SOC_COUNTER_NON_DMA_START];
   5531     *non_dma1 = *non_dma0;
   5532     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5533     non_dma1->reg = PGW_OBM1_LOW_PRI_BYTE_DROPr;
   5534     non_dma1->field = COUNTERf;
   5535     non_dma1->cname = "OBM1_LOW_PRI_DROP_BYTE";
   5536     *non_dma_entries += non_dma1->num_entries;
   5537 
   5538     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_HIGH_PRI -
   5539                                      SOC_COUNTER_NON_DMA_START];
   5540     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5541                       _SOC_COUNTER_NON_DMA_OBM;
   5542     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   5543     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5544     non_dma0->entries_per_port = 4;
   5545     non_dma0->num_entries = 32;
   5546     non_dma0->mem = INVALIDm;
   5547     non_dma0->reg = PGW_OBM2_HIGH_PRI_PKT_DROPr;
   5548     non_dma0->field = COUNTERf;
   5549     non_dma0->cname = "OBM2_HIGH_PRI_DROP_PKT";
   5550     non_dma0->dma_buf[0] = buf;
   5551     *non_dma_entries += non_dma0->num_entries;
   5552 
   5553     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_LOW_PRI -
   5554                                      SOC_COUNTER_NON_DMA_START];
   5555     *non_dma1 = *non_dma0;
   5556     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5557     non_dma1->reg = PGW_OBM2_LOW_PRI_PKT_DROPr;
   5558     non_dma1->field = COUNTERf;
   5559     non_dma1->cname = "OBM2_LOW_PRI_DROP_PKT";
   5560     *non_dma_entries += non_dma1->num_entries;
   5561 
   5562     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_HIGH_PRI -
   5563                                      SOC_COUNTER_NON_DMA_START];
   5564     *non_dma1 = *non_dma0;
   5565     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5566     non_dma1->reg = PGW_OBM2_HIGH_PRI_BYTE_DROPr;
   5567     non_dma1->field = COUNTERf;
   5568     non_dma1->cname = "OBM2_HIGH_PRI_DROP_BYTE";
   5569     *non_dma_entries += non_dma1->num_entries;
   5570 
   5571     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_LOW_PRI -
   5572                                      SOC_COUNTER_NON_DMA_START];
   5573     *non_dma1 = *non_dma0;
   5574     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5575     non_dma1->reg = PGW_OBM2_LOW_PRI_BYTE_DROPr;
   5576     non_dma1->field = COUNTERf;
   5577     non_dma1->cname = "OBM2_LOW_PRI_DROP_BYTE";
   5578     *non_dma_entries += non_dma1->num_entries;
   5579 
   5580     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_HIGH_PRI -
   5581                                      SOC_COUNTER_NON_DMA_START];
   5582     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5583                       _SOC_COUNTER_NON_DMA_OBM;
   5584     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   5585     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5586     non_dma0->entries_per_port = 4;
   5587     non_dma0->num_entries = 32;
   5588     non_dma0->mem = INVALIDm;
   5589     non_dma0->reg = PGW_OBM3_HIGH_PRI_PKT_DROPr;
   5590     non_dma0->field = COUNTERf;
   5591     non_dma0->cname = "OBM3_HIGH_PRI_DROP_PKT";
   5592     non_dma0->dma_buf[0] = buf;
   5593     *non_dma_entries += non_dma0->num_entries;
   5594 
   5595     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_LOW_PRI -
   5596                                      SOC_COUNTER_NON_DMA_START];
   5597     *non_dma1 = *non_dma0;
   5598     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5599     non_dma1->reg = PGW_OBM3_LOW_PRI_PKT_DROPr;
   5600     non_dma1->field = COUNTERf;
   5601     non_dma1->cname = "OBM3_LOW_PRI_DROP_PKT";
   5602     *non_dma_entries += non_dma1->num_entries;
   5603 
   5604     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_HIGH_PRI -
   5605                                      SOC_COUNTER_NON_DMA_START];
   5606     *non_dma1 = *non_dma0;
   5607     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5608     non_dma1->reg = PGW_OBM3_HIGH_PRI_BYTE_DROPr;
   5609     non_dma1->field = COUNTERf;
   5610     non_dma1->cname = "OBM3_HIGH_PRI_DROP_BYTE";
   5611     *non_dma_entries += non_dma1->num_entries;
   5612 
   5613     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_LOW_PRI -
   5614                                      SOC_COUNTER_NON_DMA_START];
   5615     *non_dma1 = *non_dma0;
   5616     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5617     non_dma1->reg = PGW_OBM3_LOW_PRI_BYTE_DROPr;
   5618     non_dma1->field = COUNTERf;
   5619     non_dma1->cname = "OBM3_LOW_PRI_DROP_BYTE";
   5620     *non_dma_entries += non_dma1->num_entries;
   5621 
   5622     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_PEAK -
   5623                                      SOC_COUNTER_NON_DMA_START];
   5624     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5625         _SOC_COUNTER_NON_DMA_PEAK;
   5626     SOC_PBMP_CLEAR(non_dma0->pbmp);
   5627     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5628     non_dma0->entries_per_port = 0;
   5629     non_dma0->num_entries = 1;
   5630     non_dma0->mem = INVALIDm;
   5631     non_dma0->reg = THDI_GLOBAL_HDRM_COUNT_PIPEXr;
   5632     non_dma0->field = GLOBAL_HDRM_COUNTf;
   5633 
   5634     non_dma0->cname = "GLOBAL_HDRM_COUNT_PEAK";
   5635     non_dma0->dma_buf[0] = buf;
   5636     *non_dma_entries += non_dma0->num_entries;
   5637 
   5638     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_CURRENT -
   5639         SOC_COUNTER_NON_DMA_START];
   5640     *non_dma2 = *non_dma0;
   5641     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   5642         _SOC_COUNTER_NON_DMA_CURRENT;
   5643     non_dma2->cname = "GLOBAL_HDRM_COUNT_CURR";
   5644 
   5645     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_Y_PEAK -
   5646         SOC_COUNTER_NON_DMA_START];
   5647     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5648         _SOC_COUNTER_NON_DMA_PEAK;
   5649     SOC_PBMP_CLEAR(non_dma0->pbmp);
   5650     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5651     non_dma0->entries_per_port = 0;
   5652     non_dma0->num_entries = 1;
   5653     non_dma0->mem = INVALIDm;
   5654     non_dma0->reg = THDI_GLOBAL_HDRM_COUNT_PIPEYr;
   5655     non_dma0->field = GLOBAL_HDRM_COUNTf;
   5656     non_dma0->cname = "GLOBAL_HDRM_COUNT_PEAK";
   5657     non_dma0->dma_buf[0] = buf;
   5658     *non_dma_entries += non_dma0->num_entries;
   5659 
   5660     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_Y_CURRENT -
   5661         SOC_COUNTER_NON_DMA_START];
   5662     *non_dma2 = *non_dma0;
   5663     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   5664         _SOC_COUNTER_NON_DMA_CURRENT;
   5665     non_dma2->cname = "GLOBAL_HDRM_COUNT_CURR";
   5666 
   5667 
   5668 
   5669 
   5670     return SOC_E_NONE;
   5671 
   5672 }
   5673 #endif /* BCM_TRIDENT2_SUPPORT || BCM_TRIDENT2PLUS_SUPPORT */
   5674 
   5675 #ifdef BCM_HURRICANE_SUPPORT
   5676 /*
   5677  * Function:
   5678  *      _soc_counter_hu_non_dma_init
   5679  * Purpose:
   5680  *      Initialize Hurricane's non-DMA counters.
   5681  * Parameters:
   5682  *      unit - The SOC unit number
   5683  *      nports - Number of ports.
   5684  *      non_dma_start_index - The starting index of non-DMA counter entries.
   5685  *      non_dma_entries - (OUT) The number of non-DMA counter entries.
   5686  * Returns:
   5687  *      SOC_E_NONE
   5688  *      SOC_E_MEMORY
   5689  */
   5690 STATIC int
   5691 _soc_counter_hu_non_dma_init(int unit, int nports, int non_dma_start_index,
   5692         int *non_dma_entries)
   5693 {
   5694     soc_control_t *soc;
   5695     soc_counter_non_dma_t *non_dma0, *non_dma1;
   5696     int max_cosq_per_port, total_num_cosq, port;
   5697     int num_entries, alloc_size;
   5698     uint32 *buf;
   5699 
   5700     soc = SOC_CONTROL(unit);
   5701     *non_dma_entries = 0;
   5702 
   5703     max_cosq_per_port = 0;
   5704     total_num_cosq = 0;
   5705     for (port = 0; port < nports; port++) {
   5706         if (num_cosq[unit][port] > max_cosq_per_port) {
   5707             max_cosq_per_port = num_cosq[unit][port];
   5708         }
   5709         total_num_cosq += num_cosq[unit][port];
   5710     }
   5711 
   5712     num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm);
   5713     alloc_size = num_entries *
   5714         soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm) * sizeof(uint32);
   5715 
   5716     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   5717     if (buf == NULL) {
   5718         return SOC_E_MEMORY;
   5719     }
   5720     sal_memset(buf, 0, alloc_size);
   5721 
   5722     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   5723                                      SOC_COUNTER_NON_DMA_START];
   5724     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5725         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   5726     non_dma0->pbmp = PBMP_ALL(unit);
   5727     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5728     non_dma0->entries_per_port = max_cosq_per_port;
   5729     non_dma0->num_entries = num_entries;
   5730     non_dma0->mem = EGR_PERQ_XMT_COUNTERSm;
   5731     non_dma0->reg = INVALIDr;
   5732     non_dma0->field = PACKET_COUNTERf;
   5733     non_dma0->cname = "PERQ_PKT";
   5734     non_dma0->dma_buf[0] = buf;
   5735     non_dma0->dma_index_max[0] = num_entries - 1;
   5736     non_dma0->dma_mem[0] = non_dma0->mem;
   5737     *non_dma_entries += non_dma0->num_entries;
   5738 
   5739     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   5740                                      SOC_COUNTER_NON_DMA_START];
   5741     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   5742     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   5743     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5744     non_dma1->field = BYTE_COUNTERf;
   5745     non_dma1->cname = "PERQ_BYTE";
   5746     *non_dma_entries += non_dma1->num_entries;
   5747 
   5748     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   5749                                      SOC_COUNTER_NON_DMA_START];
   5750     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   5751     non_dma0->pbmp = PBMP_ALL(unit);
   5752     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5753     non_dma0->entries_per_port = 1;
   5754     non_dma0->num_entries = nports;
   5755     non_dma0->mem = INVALIDm;
   5756     non_dma0->reg = CNGDROPCOUNT1r;
   5757     non_dma0->field = DROPPKTCOUNTf;
   5758     non_dma0->cname = "DROP_PKT_YEL";
   5759     *non_dma_entries += non_dma0->num_entries;
   5760 
   5761     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   5762                                      SOC_COUNTER_NON_DMA_START];
   5763     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   5764     non_dma0->pbmp = PBMP_ALL(unit);
   5765     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5766     non_dma0->entries_per_port = 1;
   5767     non_dma0->num_entries = nports;
   5768     non_dma0->mem = INVALIDm;
   5769     non_dma0->reg = CNGDROPCOUNT0r;
   5770     non_dma0->field = DROPPKTCOUNTf;
   5771     non_dma0->cname = "DROP_PKT_RED";
   5772     *non_dma_entries += non_dma0->num_entries;
   5773 
   5774     if (SOC_IS_HURRICANE2(unit)) {
   5775         non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   5776                                          SOC_COUNTER_NON_DMA_START];
   5777         non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   5778         non_dma0->pbmp = PBMP_ALL(unit);
   5779         non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5780         non_dma0->entries_per_port = max_cosq_per_port;
   5781         non_dma0->num_entries = total_num_cosq;
   5782         non_dma0->mem = INVALIDm;
   5783         non_dma0->reg = EGRDROPPKTCOUNT_COSr;
   5784         non_dma0->field = DROPPEDPKTCOUNTf;
   5785         non_dma0->cname = "PERQ_DROP_PKT_EGR";
   5786         *non_dma_entries += non_dma0->num_entries;
   5787     }
   5788 
   5789     return SOC_E_NONE;
   5790 }
   5791 #endif /* BCM_HURRICANE_SUPPORT */
   5792 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
   5793 /*
   5794  * Function:
   5795  *      _soc_counter_gh_non_dma_init
   5796  * Purpose:
   5797  *      Initialize Greyhound's non-DMA counters.
   5798  * Parameters:
   5799  *      unit - The SOC unit number
   5800  *      nports - Number of ports.
   5801  *      non_dma_start_index - The starting index of non-DMA counter entries.
   5802  *      non_dma_entries - (OUT) The number of non-DMA counter entries.
   5803  * Returns:
   5804  *      SOC_E_NONE
   5805  *      SOC_E_MEMORY
   5806  */
   5807 STATIC int
   5808 _soc_counter_gh_non_dma_init(int unit, int nports,
   5809         int non_dma_start_index, int *non_dma_entries)
   5810 {
   5811     soc_control_t *soc;
   5812     soc_counter_non_dma_t *non_dma0, *non_dma1;
   5813     int max_cosq_per_port, total_num_cosq, port;
   5814     int num_entries, alloc_size;
   5815     uint32 *buf;
   5816 
   5817     soc = SOC_CONTROL(unit);
   5818     *non_dma_entries = 0;
   5819 
   5820     max_cosq_per_port = 0;
   5821     total_num_cosq = 0;
   5822     for (port = 0; port < nports; port++) {
   5823         if (num_cosq[unit][port] > max_cosq_per_port) {
   5824             max_cosq_per_port = num_cosq[unit][port];
   5825         }
   5826         total_num_cosq += num_cosq[unit][port];
   5827     }
   5828 
   5829     num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm);
   5830     alloc_size = num_entries *
   5831         soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm) * sizeof(uint32);
   5832 
   5833     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   5834     if (buf == NULL) {
   5835         return SOC_E_MEMORY;
   5836     }
   5837     sal_memset(buf, 0, alloc_size);
   5838 
   5839     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   5840                                      SOC_COUNTER_NON_DMA_START];
   5841     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5842         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   5843     non_dma0->pbmp = PBMP_ALL(unit);
   5844     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5845     non_dma0->entries_per_port = max_cosq_per_port;
   5846     non_dma0->num_entries = num_entries;
   5847     non_dma0->mem = EGR_PERQ_XMT_COUNTERSm;
   5848     non_dma0->reg = INVALIDr;
   5849     non_dma0->field = PACKET_COUNTERf;
   5850     non_dma0->cname = "PERQ_PKT";
   5851     non_dma0->dma_buf[0] = buf;
   5852     non_dma0->dma_index_max[0] = num_entries - 1;
   5853     non_dma0->dma_mem[0] = non_dma0->mem;
   5854     *non_dma_entries += non_dma0->num_entries;
   5855 
   5856     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   5857                                      SOC_COUNTER_NON_DMA_START];
   5858     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   5859     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   5860     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   5861     non_dma1->field = BYTE_COUNTERf;
   5862     non_dma1->cname = "PERQ_BYTE";
   5863     *non_dma_entries += non_dma1->num_entries;
   5864 
   5865     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   5866                                      SOC_COUNTER_NON_DMA_START];
   5867     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   5868     non_dma0->pbmp = PBMP_ALL(unit);
   5869     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5870     non_dma0->entries_per_port = 1;
   5871     non_dma0->num_entries = nports;
   5872     non_dma0->mem = INVALIDm;
   5873     non_dma0->reg = CNGDROPCOUNT1r;
   5874     non_dma0->field = DROPPKTCOUNTf;
   5875     non_dma0->cname = "DROP_PKT_YEL";
   5876     *non_dma_entries += non_dma0->num_entries;
   5877 
   5878     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   5879                                      SOC_COUNTER_NON_DMA_START];
   5880     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   5881     non_dma0->pbmp = PBMP_ALL(unit);
   5882     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5883     non_dma0->entries_per_port = 1;
   5884     non_dma0->num_entries = nports;
   5885     non_dma0->mem = INVALIDm;
   5886     non_dma0->reg = CNGDROPCOUNT0r;
   5887     non_dma0->field = DROPPKTCOUNTf;
   5888     non_dma0->cname = "DROP_PKT_RED";
   5889     *non_dma_entries += non_dma0->num_entries;
   5890 
   5891     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING -
   5892                                      SOC_COUNTER_NON_DMA_START];
   5893     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   5894     non_dma0->pbmp = PBMP_ALL(unit);
   5895     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5896     non_dma0->entries_per_port = 1;
   5897     non_dma0->num_entries = nports;
   5898     non_dma0->mem = INVALIDm;
   5899     non_dma0->reg = ING_DROPPKT_CNTr;
   5900     non_dma0->field = FC_DROP_COUNTERf;
   5901     non_dma0->cname = "DROP_PKT_ING";
   5902     *non_dma_entries += non_dma0->num_entries;
   5903 
   5904     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   5905                                      SOC_COUNTER_NON_DMA_START];
   5906     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   5907     non_dma0->pbmp = PBMP_ALL(unit);
   5908     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5909     non_dma0->entries_per_port = max_cosq_per_port;
   5910     non_dma0->num_entries = total_num_cosq;
   5911     non_dma0->mem = INVALIDm;
   5912     non_dma0->reg = EGRDROPPKTCOUNT_COSr;
   5913     non_dma0->field = DROPPEDPKTCOUNTf;
   5914     non_dma0->cname = "PERQ_DROP_PKT_EGR";
   5915     *non_dma_entries += non_dma0->num_entries;
   5916 
   5917     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_DROP_PKT -
   5918                                      SOC_COUNTER_NON_DMA_START];
   5919     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   5920     non_dma0->pbmp = PBMP_ALL(unit);
   5921     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5922     non_dma0->entries_per_port = 1;
   5923     non_dma0->num_entries = nports;
   5924     non_dma0->mem = INVALIDm;
   5925     non_dma0->reg = WRED_DROP_COUNTERr;
   5926     non_dma0->field = COUNTERf;
   5927     non_dma0->cname = "WRED_DROP_CNT";
   5928     *non_dma_entries += non_dma0->num_entries;
   5929 
   5930     num_entries = soc_mem_index_count(unit, EGR_PER_Q_ECN_MARKEDm);
   5931     alloc_size = num_entries *
   5932         soc_mem_entry_words(unit, EGR_PER_Q_ECN_MARKEDm) * sizeof(uint32);
   5933 
   5934     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   5935     if (buf == NULL) {
   5936         return SOC_E_MEMORY;
   5937     }
   5938     sal_memset(buf, 0, alloc_size);
   5939 
   5940     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_ECN_MARKED -
   5941                                      SOC_COUNTER_NON_DMA_START];
   5942     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   5943         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   5944     non_dma0->pbmp = PBMP_ALL(unit);
   5945     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   5946     non_dma0->entries_per_port = max_cosq_per_port;
   5947     non_dma0->num_entries = num_entries;
   5948     non_dma0->mem = EGR_PER_Q_ECN_MARKEDm;
   5949     non_dma0->reg = INVALIDr;
   5950     non_dma0->field = PACKET_COUNTERf;
   5951     non_dma0->cname = "PERQ_ECN_MARKED";
   5952     non_dma0->dma_buf[0] = buf;
   5953     non_dma0->dma_index_max[0] = num_entries - 1;
   5954     non_dma0->dma_mem[0] = non_dma0->mem;
   5955     *non_dma_entries += non_dma0->num_entries;
   5956 
   5957     return SOC_E_NONE;
   5958 }
   5959 #endif /* BCM_GREYHOUND_SUPPORT || BCM_HURRICANE3_SUPPORT */
   5960 
   5961 #if defined(BCM_GREYHOUND2_SUPPORT)
   5962 /*
   5963  * Function:
   5964  *      _soc_counter_gh2_non_dma_init
   5965  * Purpose:
   5966  *      Initialize Greyhound2's non-DMA counters.
   5967  * Parameters:
   5968  *      unit - The SOC unit number
   5969  *      nports - Number of ports.
   5970  *      non_dma_start_index - The starting index of non-DMA counter entries.
   5971  *      non_dma_entries - (OUT) The number of non-DMA counter entries.
   5972  * Returns:
   5973  *      SOC_E_NONE
   5974  *      SOC_E_MEMORY
   5975  */
   5976 STATIC int
   5977 _soc_counter_gh2_non_dma_init(int unit, int nports,
   5978         int non_dma_start_index, int *non_dma_entries)
   5979 {
   5980     soc_control_t *soc;
   5981     soc_counter_non_dma_t *non_dma0, *non_dma1;
   5982     int max_cosq_per_port, total_num_cosq, port;
   5983     int num_entries, alloc_size;
   5984     uint32 *buf;
   5985 
   5986     soc = SOC_CONTROL(unit);
   5987     *non_dma_entries = 0;
   5988 
   5989     max_cosq_per_port = 0;
   5990     total_num_cosq = 0;
   5991     for (port = 0; port < nports; port++) {
   5992         if (num_cosq[unit][port] > max_cosq_per_port) {
   5993             max_cosq_per_port = num_cosq[unit][port];
   5994         }
   5995         total_num_cosq += num_cosq[unit][port];
   5996     }
   5997 
   5998     num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm);
   5999     alloc_size = num_entries *
   6000         soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm) * sizeof(uint32);
   6001 
   6002     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   6003     if (buf == NULL) {
   6004         return SOC_E_MEMORY;
   6005     }
   6006     sal_memset(buf, 0, alloc_size);
   6007 
   6008     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   6009                                      SOC_COUNTER_NON_DMA_START];
   6010     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6011         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   6012     non_dma0->pbmp = PBMP_ALL(unit);
   6013     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6014     non_dma0->entries_per_port = 64;
   6015     non_dma0->num_entries = num_entries;
   6016     non_dma0->mem = EGR_PERQ_XMT_COUNTERSm;
   6017     non_dma0->reg = INVALIDr;
   6018     non_dma0->field = PACKET_COUNTERf;
   6019     non_dma0->cname = "PERQ_PKT";
   6020     non_dma0->dma_buf[0] = buf;
   6021     non_dma0->dma_index_max[0] = num_entries - 1;
   6022     non_dma0->dma_mem[0] = non_dma0->mem;
   6023     *non_dma_entries += non_dma0->num_entries;
   6024 
   6025     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   6026                                      SOC_COUNTER_NON_DMA_START];
   6027     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6028     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   6029     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6030     non_dma1->field = BYTE_COUNTERf;
   6031     non_dma1->cname = "PERQ_BYTE";
   6032     *non_dma_entries += non_dma1->num_entries;
   6033 
   6034     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   6035                                      SOC_COUNTER_NON_DMA_START];
   6036     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   6037     non_dma0->pbmp = PBMP_ALL(unit);
   6038     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6039     non_dma0->entries_per_port = 1;
   6040     non_dma0->num_entries = nports;
   6041     non_dma0->mem = INVALIDm;
   6042     non_dma0->reg = CNGDROPCOUNT1r;
   6043     non_dma0->field = DROPPKTCOUNTf;
   6044     non_dma0->cname = "DROP_PKT_YEL";
   6045     *non_dma_entries += non_dma0->num_entries;
   6046 
   6047     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   6048                                      SOC_COUNTER_NON_DMA_START];
   6049     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   6050     non_dma0->pbmp = PBMP_ALL(unit);
   6051     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6052     non_dma0->entries_per_port = 1;
   6053     non_dma0->num_entries = nports;
   6054     non_dma0->mem = INVALIDm;
   6055     non_dma0->reg = CNGDROPCOUNT0r;
   6056     non_dma0->field = DROPPKTCOUNTf;
   6057     non_dma0->cname = "DROP_PKT_RED";
   6058     *non_dma_entries += non_dma0->num_entries;
   6059 
   6060     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING -
   6061                                      SOC_COUNTER_NON_DMA_START];
   6062     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   6063     non_dma0->pbmp = PBMP_ALL(unit);
   6064     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6065     non_dma0->entries_per_port = 1;
   6066     non_dma0->num_entries = nports;
   6067     non_dma0->mem = INVALIDm;
   6068     non_dma0->reg = ING_DROPPKT_CNTr;
   6069     non_dma0->field = FC_DROP_COUNTERf;
   6070     non_dma0->cname = "DROP_PKT_ING";
   6071     *non_dma_entries += non_dma0->num_entries;
   6072 
   6073     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   6074                                      SOC_COUNTER_NON_DMA_START];
   6075     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   6076     non_dma0->pbmp = PBMP_ALL(unit);
   6077     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6078     non_dma0->entries_per_port = 64;
   6079     non_dma0->num_entries = nports * non_dma0->entries_per_port;
   6080     non_dma0->mem = INVALIDm;
   6081     non_dma0->reg = EGRDROPPKTCOUNT_COSr;
   6082     non_dma0->field = DROPPEDPKTCOUNTf;
   6083     non_dma0->cname = "PERQ_DROP_PKT_EGR";
   6084     *non_dma_entries += non_dma0->num_entries;
   6085 
   6086     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_DROP_PKT -
   6087                                      SOC_COUNTER_NON_DMA_START];
   6088     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   6089     non_dma0->pbmp = PBMP_ALL(unit);
   6090     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6091     non_dma0->entries_per_port = 1;
   6092     non_dma0->num_entries = nports;
   6093     non_dma0->mem = INVALIDm;
   6094     non_dma0->reg = WRED_DROP_COUNTERr;
   6095     non_dma0->field = COUNTERf;
   6096     non_dma0->cname = "WRED_DROP_CNT";
   6097     *non_dma_entries += non_dma0->num_entries;
   6098 
   6099     num_entries = soc_mem_index_count(unit, EGR_PER_Q_ECN_MARKEDm);
   6100     alloc_size = num_entries *
   6101         soc_mem_entry_words(unit, EGR_PER_Q_ECN_MARKEDm) * sizeof(uint32);
   6102 
   6103     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   6104     if (buf == NULL) {
   6105         return SOC_E_MEMORY;
   6106     }
   6107     sal_memset(buf, 0, alloc_size);
   6108 
   6109     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_ECN_MARKED -
   6110                                      SOC_COUNTER_NON_DMA_START];
   6111     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6112         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   6113     non_dma0->pbmp = PBMP_ALL(unit);
   6114     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6115     non_dma0->entries_per_port = max_cosq_per_port;
   6116     non_dma0->num_entries = num_entries;
   6117     non_dma0->mem = EGR_PER_Q_ECN_MARKEDm;
   6118     non_dma0->reg = INVALIDr;
   6119     non_dma0->field = PACKET_COUNTERf;
   6120     non_dma0->cname = "PERQ_ECN_MARKED";
   6121     non_dma0->dma_buf[0] = buf;
   6122     non_dma0->dma_index_max[0] = num_entries - 1;
   6123     non_dma0->dma_mem[0] = non_dma0->mem;
   6124     *non_dma_entries += non_dma0->num_entries;
   6125 
   6126     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_EXPRESS-
   6127                                      SOC_COUNTER_NON_DMA_START];
   6128     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   6129     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   6130     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6131     non_dma0->entries_per_port = 1;
   6132     non_dma0->num_entries = nports;
   6133     non_dma0->mem = INVALIDm;
   6134     non_dma0->reg = TAS_OVERRUN_PKT_CNT_EXPRESSr;
   6135     non_dma0->field = CNTf;
   6136     non_dma0->cname = "TAS_TXOVERRUN_EXPRESS";
   6137     *non_dma_entries += non_dma0->num_entries;
   6138 
   6139     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_PREEMPT-
   6140                                      SOC_COUNTER_NON_DMA_START];
   6141     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   6142     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   6143     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6144     non_dma0->entries_per_port = 1;
   6145     non_dma0->num_entries = nports;
   6146     non_dma0->mem = INVALIDm;
   6147     non_dma0->reg = TAS_OVERRUN_PKT_CNT_PREEMPTr;
   6148     non_dma0->field = CNTf;
   6149     non_dma0->cname = "TAS_TXOVERRUN_PREEMPT";
   6150     *non_dma_entries += non_dma0->num_entries;
   6151 
   6152     non_dma0 =
   6153         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PREEMPT_MAC_MERGE_HOLD_CNT-
   6154                               SOC_COUNTER_NON_DMA_START];
   6155     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   6156     non_dma0->pbmp = PBMP_ALL(unit);
   6157     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6158     non_dma0->entries_per_port = 1;
   6159     non_dma0->num_entries = nports;
   6160     non_dma0->mem = INVALIDm;
   6161     non_dma0->reg = MACMERGERHOLDCOUNTr;
   6162     non_dma0->field = CNTf;
   6163     non_dma0->cname = "PREEMPT_MACMERGE_HOLD_CNT";
   6164     *non_dma_entries += non_dma0->num_entries;
   6165 
   6166     num_entries = soc_mem_index_count(unit, ING_RX_COUNTERm) >> 1;
   6167     alloc_size = num_entries *
   6168         soc_mem_entry_words(unit, ING_RX_COUNTERm) * sizeof(uint32);
   6169 
   6170     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   6171     if (buf == NULL) {
   6172         return SOC_E_MEMORY;
   6173     }
   6174     sal_memset(buf, 0, alloc_size);
   6175 
   6176     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_ING_RX_COUNTER_NON_PREEMPTABLE_CNT -
   6177                                      SOC_COUNTER_NON_DMA_START];
   6178     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6179         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   6180     non_dma0->pbmp = PBMP_ALL(unit);
   6181     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6182     non_dma0->entries_per_port = 1;
   6183     non_dma0->num_entries = num_entries;
   6184     non_dma0->mem = ING_RX_COUNTERm;
   6185     non_dma0->reg = INVALIDr;
   6186     non_dma0->field = COUNTf;
   6187     non_dma0->cname = "ING_RX_NON_PREEMPTABLE_CNT";
   6188     non_dma0->dma_buf[0] = buf;
   6189     non_dma0->dma_index_min[0] = 0;
   6190     non_dma0->dma_index_max[0] = num_entries - 1;
   6191     non_dma0->dma_mem[0] = non_dma0->mem;
   6192     *non_dma_entries += non_dma0->num_entries;
   6193 
   6194     num_entries = soc_mem_index_count(unit, ING_RX_COUNTERm) >> 1;
   6195     alloc_size = num_entries *
   6196         soc_mem_entry_words(unit, ING_RX_COUNTERm) * sizeof(uint32);
   6197 
   6198     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   6199     if (buf == NULL) {
   6200         return SOC_E_MEMORY;
   6201     }
   6202     sal_memset(buf, 0, alloc_size);
   6203 
   6204     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_ING_RX_COUNTER_PREEMPTABLE_CNT -
   6205                                      SOC_COUNTER_NON_DMA_START];
   6206     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6207         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   6208     non_dma0->pbmp = PBMP_ALL(unit);
   6209     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6210     non_dma0->entries_per_port = 1;
   6211     non_dma0->num_entries = num_entries;
   6212     non_dma0->mem = ING_RX_COUNTERm;
   6213     non_dma0->reg = INVALIDr;
   6214     non_dma0->field = COUNTf;
   6215     non_dma0->cname = "ING_RX_PREEMPTABLE_CNT";
   6216     non_dma0->dma_buf[0] = buf;
   6217     non_dma0->dma_index_min[0] = soc_mem_index_count(unit, ING_RX_COUNTERm) >> 1;
   6218     non_dma0->dma_index_max[0] = soc_mem_index_count(unit, ING_RX_COUNTERm) - 1;
   6219     non_dma0->dma_mem[0] = non_dma0->mem;
   6220     *non_dma_entries += non_dma0->num_entries;
   6221 
   6222     num_entries = soc_mem_index_count(unit, EGR_MFRAME_COUNTERm);
   6223     alloc_size = num_entries *
   6224         soc_mem_entry_words(unit, EGR_MFRAME_COUNTERm) * sizeof(uint32);
   6225 
   6226     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   6227     if (buf == NULL) {
   6228         return SOC_E_MEMORY;
   6229     }
   6230     sal_memset(buf, 0, alloc_size);
   6231 
   6232     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_TX_COUNTER_PREEMPTABLE_CNT -
   6233                                      SOC_COUNTER_NON_DMA_START];
   6234     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6235         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   6236     non_dma0->pbmp = PBMP_ALL(unit);
   6237     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6238     non_dma0->entries_per_port = 1;
   6239     non_dma0->num_entries = num_entries;
   6240     non_dma0->mem = EGR_MFRAME_COUNTERm;
   6241     non_dma0->reg = INVALIDr;
   6242     non_dma0->field = COUNTf;
   6243     non_dma0->cname = "EGR_TX_PREEMPTABLE_CNT";
   6244     non_dma0->dma_buf[0] = buf;
   6245     non_dma0->dma_index_min[0] = 0;
   6246     non_dma0->dma_index_max[0] = num_entries - 1;
   6247     non_dma0->dma_mem[0] = non_dma0->mem;
   6248     *non_dma_entries += non_dma0->num_entries;
   6249 
   6250     return SOC_E_NONE;
   6251 }
   6252 #endif /* BCM_GREYHOUND2_SUPPORT */
   6253 
   6254 #ifdef BCM_KATANA_SUPPORT
   6255 
   6256 STATIC int
   6257 _soc_counter_kt_cosq_gport_non_dma_init(int unit, int nports,
   6258                                         int non_dma_start_index,
   6259                                         int *non_dma_entries)
   6260 {
   6261     soc_control_t *soc;
   6262 #ifdef BCM_KATANA2_SUPPORT
   6263     soc_port_t my_port;
   6264 #endif
   6265     soc_counter_non_dma_t *non_dma0, *non_dma1;
   6266     _kt_cosq_counter_mem_map_t *mem_map;
   6267     int table_size, id;
   6268     uint32 *buf;
   6269     char *cname_pkt[] = { "DROP_PKT", "ACCEPT_PKT",
   6270                           "DROP_PKT_G", "DROP_PKT_Y",
   6271                           "DROP_PKT_R", "ACCEPT_PKT_G",
   6272                           "ACCEPT_PKT_Y", "ACCEPT_PKT_R",
   6273                           "PERQ_PKT" };
   6274     char *cname_byte[] = { "DROP_BYTE", "ACCEPT_BYTE",
   6275                           "DROP_BYTE_G", "DROP_BYTE_Y",
   6276                           "DROP_BYTE_R", "ACCEPT_BYTE_G",
   6277                           "ACCEPT_BYTE_Y", "ACCEPT_BYTE_R",
   6278                           "PERQ_BYTE" };
   6279 
   6280     soc = SOC_CONTROL(unit);
   6281     *non_dma_entries = 0;
   6282 
   6283     table_size = soc_mem_index_count(unit, CTR_FLEX_COUNT_0m) *
   6284         soc_mem_entry_words(unit, CTR_FLEX_COUNT_0m) * sizeof(uint32);
   6285 
   6286     buf = soc_cm_salloc(unit, table_size, "non_dma_counter");
   6287     if (buf == NULL) {
   6288         return SOC_E_MEMORY;
   6289     }
   6290     sal_memset(buf, 0, table_size);
   6291 
   6292     mem_map = _kt_cosq_gport_mem_map;
   6293 
   6294     /*
   6295      * CTR_FLEX_COUNT_0 = Total ENQ discarded
   6296      * CTR_FLEX_COUNT_1 = Total ENQ Accepted
   6297      * CTR_FLEX_COUNT_2 = Green ENQ discarded
   6298      * CTR_FLEX_COUNT_3 = Yellow ENQ discarded
   6299      * CTR_FLEX_COUNT_4 = Red packet ENQ discarded
   6300      * CTR_FLEX_COUNT_5 = Green ENQ Accepted
   6301      * CTR_FLEX_COUNT_6 = Yellow ENQ Accepted
   6302      * CTR_FLEX_COUNT_7 = Red ENQ Accepted
   6303      * CTR_FLEX_COUNT_8 = Total DEQ
   6304      */
   6305     for (id = 0; id < 9; id++) {
   6306         if (soc_feature(unit, soc_feature_counter_toggled_read) &&
   6307             (mem_map[id].non_dma_id == SOC_COUNTER_NON_DMA_COSQ_DROP_PKT ||
   6308              mem_map[id].non_dma_id == SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT)) {
   6309             continue;
   6310         }
   6311         non_dma0 = &soc->counter_non_dma[mem_map[id].non_dma_id -
   6312                                          SOC_COUNTER_NON_DMA_START];
   6313         non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6314                           _SOC_COUNTER_NON_DMA_DO_DMA |
   6315                           _SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   6316         if (id == 0) {
   6317             non_dma0->flags |= _SOC_COUNTER_NON_DMA_ALLOC;
   6318         }
   6319         if (!soc_feature(unit, soc_feature_counter_toggled_read)) {
   6320             /* adjust the extra count 1 in s/w counters */
   6321             if (!SOC_IS_KATANA2(unit)) {
   6322                 non_dma0->flags |= _SOC_COUNTER_NON_DMA_EXTRA_COUNT;
   6323             }
   6324         }
   6325         non_dma0->pbmp = PBMP_ALL(unit);
   6326 #ifdef BCM_KATANA2_SUPPORT
   6327         if (SOC_IS_KATANA2(unit)) {
   6328             SOC_PBMP_CLEAR(non_dma0->pbmp);
   6329             for (my_port =  SOC_INFO(unit).cmic_port;
   6330                  my_port <= SOC_INFO(unit).lb_port;
   6331                  my_port++) {
   6332                  if (SOC_INFO(unit).block_valid[SOC_PORT_BLOCK(unit,my_port)]) {
   6333                      SOC_PBMP_PORT_ADD(non_dma0->pbmp, my_port);
   6334                  }
   6335             }
   6336         }
   6337 #endif
   6338         non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6339         non_dma0->entries_per_port = 8;
   6340         non_dma0->num_entries = soc_mem_index_count(unit, CTR_FLEX_COUNT_0m);
   6341         non_dma0->mem = mem_map[id].mem;
   6342         non_dma0->reg = INVALIDr;
   6343         non_dma0->field = COUNTf;
   6344         non_dma0->cname = cname_pkt[id];
   6345         non_dma0->dma_buf[0] = buf;
   6346         non_dma0->dma_index_max[0] = non_dma0->num_entries - 1;
   6347         non_dma0->dma_mem[0] = non_dma0->mem;
   6348         *non_dma_entries += non_dma0->num_entries;
   6349 
   6350         non_dma1 = &soc->counter_non_dma[mem_map[id].non_dma_id -
   6351                                         SOC_COUNTER_NON_DMA_START + 1];
   6352         sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6353         non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   6354                           _SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   6355         non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6356         non_dma1->field = BYTE_COUNTf;
   6357         non_dma1->cname = cname_byte[id];
   6358         *non_dma_entries += non_dma1->num_entries;
   6359     }
   6360 
   6361     return SOC_E_NONE;
   6362 }
   6363 
   6364 /*
   6365  * Function:
   6366  *      _soc_counter_katana_non_dma_init
   6367  * Purpose:
   6368  *      Initialize Katana's non-DMA counters.
   6369  * Parameters:
   6370  *      unit - The SOC unit number
   6371  *      nports - Number of ports.
   6372  *      non_dma_start_index - The starting index of non-DMA counter entries.
   6373  *      non_dma_entries - (OUT) The number of non-DMA counter entries.
   6374  * Returns:
   6375  *      SOC_E_NONE
   6376  *      SOC_E_MEMORY
   6377  */
   6378 STATIC int
   6379 _soc_counter_katana_non_dma_init(int unit, int nports, int non_dma_start_index,
   6380                                  int *non_dma_entries)
   6381 {
   6382     soc_control_t *soc;
   6383 #ifdef BCM_KATANA2_SUPPORT
   6384     soc_port_t my_port;
   6385 #endif
   6386     soc_counter_non_dma_t *non_dma0, *non_dma1;
   6387     _kt_cosq_counter_mem_map_t *mem_map;
   6388     int table_size;
   6389     uint32 *buf;
   6390     int i, id;
   6391     int entry_words, buf_base;
   6392     char *cname_pkt[] = { "DROP_PKT", "DROP_PKT_R",
   6393                           "PERQ_PKT" };
   6394     char *cname_byte[] = { "DROP_BYTE", "DROP_BYTE_R",
   6395                            "PERQ_BYTE" };
   6396 
   6397     if (soc_feature(unit, soc_feature_cosq_gport_stat_ability)) {
   6398         SOC_IF_ERROR_RETURN
   6399             (_soc_counter_kt_cosq_gport_non_dma_init(unit, nports,
   6400                 non_dma_start_index, non_dma_entries));
   6401         return SOC_E_NONE;
   6402     }
   6403     mem_map = _kt_cosq_mem_map;
   6404     soc = SOC_CONTROL(unit);
   6405     *non_dma_entries = 0;
   6406 
   6407     entry_words = soc_mem_entry_words(unit, CTR_FLEX_COUNT_0m);
   6408     table_size = soc_mem_index_count(unit, CTR_FLEX_COUNT_0m) * 4 *
   6409                  entry_words * sizeof(uint32);
   6410     buf = soc_cm_salloc(unit, table_size, "non_dma_counter");
   6411     if (buf == NULL) {
   6412         return SOC_E_MEMORY;
   6413     }
   6414     sal_memset(buf, 0, table_size);
   6415 
   6416     /*
   6417      * CTR_FLEX_COUNT_0/1/2/3 = Total ENQ discarded
   6418      * CTR_FLEX_COUNT_4/5/6/7  = Red packet ENQ discarded
   6419      * CTR_FLEX_COUNT_8/9/10/11  = Total DEQ
   6420      */
   6421     for (id = 0; id < 12; id = id + 4) {
   6422         if (soc_feature(unit, soc_feature_counter_toggled_read) &&
   6423             mem_map[id].non_dma_id == SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED) {
   6424             continue;
   6425         }
   6426         non_dma0 = &soc->counter_non_dma[mem_map[id].non_dma_id -
   6427                                      SOC_COUNTER_NON_DMA_START];
   6428         non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6429                           _SOC_COUNTER_NON_DMA_DO_DMA |
   6430                           _SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   6431         if (id == 0) {
   6432             non_dma0->flags |= _SOC_COUNTER_NON_DMA_ALLOC;
   6433         }
   6434         if (!soc_feature(unit, soc_feature_counter_toggled_read)) {
   6435             /* adjust the extra count 1 in s/w counters */
   6436             if (!SOC_IS_KATANA2(unit)) {
   6437                 non_dma0->flags |= _SOC_COUNTER_NON_DMA_EXTRA_COUNT;
   6438             }
   6439         }
   6440         non_dma0->pbmp = PBMP_ALL(unit);
   6441 #ifdef BCM_KATANA2_SUPPORT
   6442         if (SOC_IS_KATANA2(unit)) {
   6443             SOC_PBMP_CLEAR(non_dma0->pbmp);
   6444             for (my_port =  SOC_INFO(unit).cmic_port;
   6445                  my_port <= SOC_INFO(unit).lb_port;
   6446                  my_port++) {
   6447                  if (SOC_INFO(unit).block_valid[SOC_PORT_BLOCK(unit,my_port)]) {
   6448                      SOC_PBMP_PORT_ADD(non_dma0->pbmp,my_port);
   6449                  }
   6450             }
   6451         }
   6452 #endif
   6453         non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6454         non_dma0->entries_per_port = 8; 
   6455         non_dma0->mem = mem_map[id].mem;
   6456         if (soc_feature(unit, soc_feature_counter_toggled_read) &&
   6457             (id == 8)) {
   6458             non_dma0->mem = mem_map[id].mem - 4;
   6459         }
   6460         non_dma0->num_entries = 4 * soc_mem_index_count(unit, non_dma0->mem);
   6461         non_dma0->reg = INVALIDr;
   6462         non_dma0->field = COUNTf;
   6463         non_dma0->cname = cname_pkt[id / 4];
   6464 
   6465         entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   6466         for (i = 0; i < 4; i++) {
   6467             buf_base = i * entry_words * soc_mem_index_count(unit, non_dma0->mem);
   6468             non_dma0->dma_buf[i] = &buf[buf_base];
   6469             non_dma0->dma_index_min[i] = 0;
   6470             non_dma0->dma_index_max[i] = soc_mem_index_count(unit, non_dma0->mem) - 1;
   6471             non_dma0->dma_mem[i] = mem_map[id + i].mem;
   6472             if (soc_feature(unit, soc_feature_counter_toggled_read) &&
   6473                 (id == 8)) {
   6474                 non_dma0->dma_mem[i] = mem_map[id + i].mem - 4;
   6475             }
   6476         }
   6477         *non_dma_entries += non_dma0->num_entries;
   6478 
   6479         non_dma1 = &soc->counter_non_dma[mem_map[id].non_dma_id -
   6480                                     SOC_COUNTER_NON_DMA_START + 1];
   6481         sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6482         non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   6483                           _SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   6484         non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6485         non_dma1->field = BYTE_COUNTf;
   6486         non_dma1->cname = cname_byte[id / 4];
   6487         *non_dma_entries += non_dma1->num_entries;
   6488     }
   6489 
   6490     return SOC_E_NONE;
   6491 }
   6492 #endif /* BCM_KATANA_SUPPORT */
   6493 
   6494 #ifdef BCM_KATANA2_SUPPORT
   6495 STATIC int
   6496 _soc_counter_sb2_cosq_gport_non_dma_init(int unit, int nports,
   6497                                         int non_dma_start_index,
   6498                                         int *non_dma_entries)
   6499 {
   6500     soc_control_t *soc;
   6501     soc_counter_non_dma_t *non_dma0, *non_dma1;
   6502     _sb2_cosq_counter_mem_map_t *mem_map;
   6503     int table_size, id, max_id = 9;
   6504     uint32 *buf;
   6505     char *cname_pkt[] = { "DROP_PKT", "ACCEPT_PKT",
   6506                           "DROP_PKT_G", "DROP_PKT_Y",
   6507                           "DROP_PKT_R", "ACCEPT_PKT_G",
   6508                           "ACCEPT_PKT_Y", "ACCEPT_PKT_R",
   6509                           "MC_PERQ_PKT" };
   6510     char *cname_byte[] = { "DROP_BYTE", "ACCEPT_BYTE",
   6511                           "DROP_BYTE_G", "DROP_BYTE_Y",
   6512                           "DROP_BYTE_R", "ACCEPT_BYTE_G",
   6513                           "ACCEPT_BYTE_Y", "ACCEPT_BYTE_R",
   6514                           "MC_PERQ_BYTE" };
   6515 
   6516     soc = SOC_CONTROL(unit);
   6517     *non_dma_entries = 0;
   6518 
   6519     table_size = soc_mem_index_count(unit, CTR_FLEX_COUNT_0m) *
   6520         soc_mem_entry_words(unit, CTR_FLEX_COUNT_0m) * sizeof(uint32);
   6521 
   6522     buf = soc_cm_salloc(unit, table_size, "non_dma_counter");
   6523     if (buf == NULL) {
   6524         return SOC_E_MEMORY;
   6525     }
   6526     sal_memset(buf, 0, table_size);
   6527 
   6528     if (SOC_IS_SABER2(unit)) {
   6529     mem_map = _sb2_cosq_gport_mem_map;
   6530         max_id = 6;
   6531     } else {
   6532         mem_map = _kt2_cosq_gport_mem_map;
   6533     }
   6534 
   6535     /*
   6536      * CTR_FLEX_COUNT_0 = Total ENQ discarded
   6537      * CTR_FLEX_COUNT_1 = Total ENQ Accepted
   6538      * CTR_FLEX_COUNT_2 = Green ENQ discarded
   6539      * CTR_FLEX_COUNT_3 = Yellow ENQ discarded
   6540      * CTR_FLEX_COUNT_4 = Red packet ENQ discarded
   6541      * CTR_FLEX_COUNT_5 = Total DEQ
   6542      */
   6543     for (id = 0; id < max_id; id++) {
   6544         non_dma0 = &soc->counter_non_dma[mem_map[id].non_dma_id -
   6545                                          SOC_COUNTER_NON_DMA_START];
   6546         non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6547                           _SOC_COUNTER_NON_DMA_DO_DMA |
   6548                           _SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   6549         if (id == 0) {
   6550             non_dma0->flags |= _SOC_COUNTER_NON_DMA_ALLOC;
   6551         }
   6552         if (!soc_feature(unit, soc_feature_counter_toggled_read)) {
   6553             /* adjust the extra count 1 in s/w counters */
   6554             non_dma0->flags |= _SOC_COUNTER_NON_DMA_EXTRA_COUNT;
   6555         }
   6556         non_dma0->pbmp = PBMP_ALL(unit);
   6557         non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6558         non_dma0->entries_per_port = 8;
   6559         non_dma0->num_entries = soc_mem_index_count(unit, CTR_FLEX_COUNT_0m);
   6560         non_dma0->mem = mem_map[id].mem;
   6561         non_dma0->reg = INVALIDr;
   6562         non_dma0->field = COUNTf;
   6563         non_dma0->cname = cname_pkt[id];
   6564         non_dma0->dma_buf[0] = buf;
   6565         non_dma0->dma_index_max[0] = non_dma0->num_entries - 1;
   6566         non_dma0->dma_mem[0] = non_dma0->mem;
   6567         *non_dma_entries += non_dma0->num_entries;
   6568 
   6569         non_dma1 = &soc->counter_non_dma[mem_map[id].non_dma_id -
   6570                                         SOC_COUNTER_NON_DMA_START + 1];
   6571         sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6572         non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   6573                           _SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   6574         non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6575         non_dma1->field = BYTE_COUNTf;
   6576         non_dma1->cname = cname_byte[id];
   6577         *non_dma_entries += non_dma1->num_entries;
   6578     }
   6579     return SOC_E_NONE;
   6580 }
   6581 
   6582 /*
   6583  * Function:
   6584  *      _soc_counter_saber2_non_dma_init
   6585  * Purpose:
   6586  *      Initialize Saber2's non-DMA counters.
   6587  * Parameters:
   6588  *      unit - The SOC unit number
   6589  *      nports - Number of ports.
   6590  *      non_dma_start_index - The starting index of non-DMA counter entries.
   6591  *      non_dma_entries - (OUT) The number of non-DMA counter entries.
   6592  * Returns:
   6593  *      SOC_E_NONE
   6594  *      SOC_E_MEMORY
   6595  */
   6596 STATIC int
   6597 _soc_counter_saber2_non_dma_init(int unit, int nports, int non_dma_start_index,
   6598                                  int *non_dma_entries)
   6599 {
   6600     soc_control_t *soc;
   6601     soc_counter_non_dma_t *non_dma0, *non_dma1;
   6602     _sb2_cosq_counter_mem_map_t *mem_map;
   6603     soc_port_t my_port;
   6604     int table_size;
   6605     uint32 *buf ;
   6606     int i, id, max_id = 6, increment = 2;
   6607     int entry_words, buf_base;
   6608     uint16 dev_id;
   6609     uint8 rev_id;
   6610 
   6611     if (soc_feature(unit, soc_feature_cosq_gport_stat_ability)) {
   6612         SOC_IF_ERROR_RETURN
   6613             (_soc_counter_sb2_cosq_gport_non_dma_init(unit, nports,
   6614                                                       non_dma_start_index, non_dma_entries));
   6615         return SOC_E_NONE;
   6616     }
   6617 #if defined (BCM_KATANA2_SUPPORT)
   6618     if (SOC_IS_SABER2(unit)) {
   6619     mem_map = _sb2_cosq_mem_map;
   6620     } else {
   6621         mem_map = _kt2_cosq_mem_map;
   6622         increment = 4;
   6623         max_id = 12;
   6624     }
   6625 #endif
   6626 #if defined (BCM_METROLITE_SUPPORT)
   6627     if (SOC_IS_METROLITE(unit)) {
   6628         mem_map = _ml_cosq_mem_map;
   6629         increment = 1;
   6630         max_id = 3;
   6631     }
   6632 #endif
   6633     soc_cm_get_id(unit, &dev_id, &rev_id);
   6634     if (dev_id == BCM56233_DEVICE_ID) {
   6635         /*
   6636          * CTR_FLEX_COUNT_0 = Total ENQ discarded
   6637          * CTR_FLEX_COUNT_1  = Red packet ENQ discarded
   6638          * CTR_FLEX_COUNT_2  = Total DEQ
   6639          */
   6640         mem_map = _dg2_cosq_mem_map;
   6641         max_id = 3;
   6642         increment = 1;
   6643     }
   6644     soc = SOC_CONTROL(unit);
   6645     *non_dma_entries = 0;
   6646 
   6647     entry_words = soc_mem_entry_words(unit, CTR_FLEX_COUNT_0m);
   6648     table_size = (soc_mem_index_count(unit, CTR_FLEX_COUNT_0m) * increment *
   6649             entry_words * sizeof(uint32));
   6650 
   6651     buf = soc_cm_salloc(unit, table_size, "non_dma_counter");
   6652     if (buf == NULL) {
   6653         return SOC_E_MEMORY;
   6654     }
   6655     sal_memset(buf, 0, table_size);
   6656 
   6657     /*
   6658      * CTR_FLEX_COUNT_0/1 = Total ENQ discarded
   6659      * CTR_FLEX_COUNT_2/3  = Red packet ENQ discarded
   6660      * CTR_FLEX_COUNT_4/5  = Total DEQ
   6661      */
   6662     for (id = 0; id < max_id; id = id + increment) {
   6663         if (soc_feature(unit, soc_feature_counter_toggled_read) &&
   6664                 mem_map[id].non_dma_id == SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED) {
   6665             continue;
   6666         }
   6667         non_dma0 = &soc->counter_non_dma[mem_map[id].non_dma_id -
   6668             SOC_COUNTER_NON_DMA_START];
   6669         non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6670             _SOC_COUNTER_NON_DMA_DO_DMA |
   6671             _SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   6672         if (id == 0) {
   6673             non_dma0->flags |= _SOC_COUNTER_NON_DMA_ALLOC;
   6674         }
   6675         SOC_PBMP_CLEAR(non_dma0->pbmp);
   6676         for (my_port =  SOC_INFO(unit).cmic_port;
   6677                 my_port <= SOC_INFO(unit).lb_port;
   6678                 my_port++) {
   6679             if (SOC_INFO(unit).block_valid[SOC_PORT_BLOCK(unit,my_port)]) {
   6680                 SOC_PBMP_PORT_ADD(non_dma0->pbmp, my_port);
   6681             }
   6682         }
   6683 
   6684         non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6685         non_dma0->entries_per_port = 48; /* Need 48 entries to display CPU queues */
   6686         non_dma0->mem = mem_map[id].mem;
   6687         non_dma0->num_entries = increment * soc_mem_index_count(unit, non_dma0->mem);
   6688         non_dma0->reg = INVALIDr;
   6689         non_dma0->field = COUNTf;
   6690         non_dma0->cname = mem_map[id].cname_pkt;
   6691 
   6692         entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   6693         for (i = 0; i < increment; i++) {
   6694             buf_base = i * entry_words * soc_mem_index_count(unit, non_dma0->mem);
   6695             non_dma0->dma_buf[i] = &buf[buf_base];
   6696             non_dma0->dma_index_min[i] = 0;
   6697             non_dma0->dma_index_max[i] = soc_mem_index_count(unit, non_dma0->mem) - 1;
   6698             non_dma0->dma_mem[i] = mem_map[id + i].mem;
   6699         }
   6700         *non_dma_entries += non_dma0->num_entries;
   6701 
   6702         non_dma1 = &soc->counter_non_dma[mem_map[id].non_dma_id -
   6703             SOC_COUNTER_NON_DMA_START + 1];
   6704         sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6705         non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   6706             _SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   6707         non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6708         non_dma1->field = BYTE_COUNTf;
   6709         non_dma1->cname = mem_map[id].cname_byte;
   6710         *non_dma_entries += non_dma1->num_entries;
   6711     }
   6712     return SOC_E_NONE;
   6713 }
   6714 #endif /* BCM_SABER2_SUPPORT */
   6715 
   6716 #ifdef BCM_TRIUMPH_SUPPORT
   6717 /*
   6718  * Function:
   6719  *      _soc_counter_tr_non_dma_init
   6720  * Purpose:
   6721  *      Initialize Triumph's non-DMA counters.
   6722  * Parameters:
   6723  *      unit - The SOC unit number
   6724  *      nports - Number of ports.
   6725  *      non_dma_start_index - The starting index of non-DMA counter entries.
   6726  *      non_dma_entries - (OUT) The number of non-DMA counter entries.
   6727  * Returns:
   6728  *      SOC_E_NONE
   6729  *      SOC_E_MEMORY
   6730  */
   6731 STATIC int
   6732 _soc_counter_tr_non_dma_init(int unit, int nports, int non_dma_start_index,
   6733         int *non_dma_entries)
   6734 {
   6735     soc_control_t *soc;
   6736     soc_counter_non_dma_t *non_dma0, *non_dma1;
   6737     int max_cosq_per_port, total_num_cosq, port;
   6738     int num_entries, alloc_size;
   6739     uint32 *buf;
   6740 
   6741     soc = SOC_CONTROL(unit);
   6742     *non_dma_entries = 0;
   6743 
   6744     max_cosq_per_port = 0;
   6745     total_num_cosq = 0;
   6746     for (port = 0; port < nports; port++) {
   6747         if (num_cosq[unit][port] > max_cosq_per_port) {
   6748             max_cosq_per_port = num_cosq[unit][port];
   6749         }
   6750         total_num_cosq += num_cosq[unit][port];
   6751     }
   6752 
   6753     num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm);
   6754     alloc_size = num_entries *
   6755         soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm) * sizeof(uint32);
   6756 
   6757     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   6758     if (buf == NULL) {
   6759         return SOC_E_MEMORY;
   6760     }
   6761     sal_memset(buf, 0, alloc_size);
   6762 
   6763     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   6764                                      SOC_COUNTER_NON_DMA_START];
   6765     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6766         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   6767     non_dma0->pbmp = PBMP_ALL(unit);
   6768     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6769     non_dma0->entries_per_port = max_cosq_per_port;
   6770     non_dma0->num_entries = num_entries;
   6771     non_dma0->mem = EGR_PERQ_XMT_COUNTERSm;
   6772     non_dma0->reg = INVALIDr;
   6773     non_dma0->field = PACKET_COUNTERf;
   6774     non_dma0->cname = "PERQ_PKT";
   6775     non_dma0->dma_buf[0] = buf;
   6776     non_dma0->dma_index_max[0] = num_entries - 1;
   6777     non_dma0->dma_mem[0] = non_dma0->mem;
   6778     *non_dma_entries += non_dma0->num_entries;
   6779 
   6780     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   6781                                      SOC_COUNTER_NON_DMA_START];
   6782     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6783     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   6784     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6785     non_dma1->field = BYTE_COUNTERf;
   6786     non_dma1->cname = "PERQ_BYTE";
   6787     *non_dma_entries += non_dma1->num_entries;
   6788 
   6789     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   6790                                      SOC_COUNTER_NON_DMA_START];
   6791     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6792         _SOC_COUNTER_NON_DMA_PERQ_REG;
   6793     non_dma0->pbmp = PBMP_ALL(unit);
   6794     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6795     non_dma0->entries_per_port = max_cosq_per_port;
   6796     non_dma0->num_entries = total_num_cosq;
   6797     non_dma0->mem = INVALIDm;
   6798     non_dma0->reg = DROP_PKT_CNTr;
   6799     non_dma0->field = COUNTf;
   6800     non_dma0->cname = "PERQ_DROP_PKT";
   6801     *non_dma_entries += non_dma0->num_entries;
   6802 
   6803     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE -
   6804                                      SOC_COUNTER_NON_DMA_START];
   6805     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6806     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6807     non_dma1->reg = DROP_BYTE_CNTr;
   6808     non_dma1->cname = "PERQ_DROP_BYTE";
   6809     *non_dma_entries += non_dma1->num_entries;
   6810 
   6811     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING -
   6812                                      SOC_COUNTER_NON_DMA_START];
   6813     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   6814     non_dma0->pbmp = PBMP_ALL(unit);
   6815     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6816     non_dma0->entries_per_port = 1;
   6817     non_dma0->num_entries = nports;
   6818     non_dma0->mem = INVALIDm;
   6819     non_dma0->reg = DROP_PKT_CNT_INGr;
   6820     non_dma0->field = COUNTf;
   6821     non_dma0->cname = "DROP_PKT_ING";
   6822     *non_dma_entries += non_dma0->num_entries;
   6823 
   6824     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING -
   6825                                      SOC_COUNTER_NON_DMA_START];
   6826     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6827     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6828     non_dma1->reg = DROP_BYTE_CNT_INGr;
   6829     non_dma1->cname = "DROP_BYTE_ING";
   6830     *non_dma_entries += non_dma1->num_entries;
   6831 
   6832     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   6833                                      SOC_COUNTER_NON_DMA_START];
   6834     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6835     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6836     non_dma1->reg = DROP_PKT_CNT_YELr;
   6837     non_dma1->cname = "DROP_PKT_YEL";
   6838     *non_dma_entries += non_dma1->num_entries;
   6839 
   6840     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   6841                                      SOC_COUNTER_NON_DMA_START];
   6842     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6843     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6844     non_dma1->reg = DROP_PKT_CNT_REDr;
   6845     non_dma1->cname = "DROP_PKT_RED";
   6846     *non_dma_entries += non_dma1->num_entries;
   6847 
   6848     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_TX_LLFC_MSG_CNT -
   6849                                      SOC_COUNTER_NON_DMA_START];
   6850     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6851     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   6852     non_dma1->pbmp = PBMP_ALL(unit);
   6853     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6854     non_dma1->mem = INVALIDm;
   6855     non_dma1->reg = TXLLFCMSGCNTr;
   6856     non_dma1->field = TXLLFCMSGCNT_STATSf;
   6857     non_dma1->cname = "MAC_TXLLFCMSG";
   6858     non_dma1->entries_per_port = 1;
   6859     non_dma1->num_entries = nports;
   6860     *non_dma_entries += non_dma1->num_entries;
   6861     return SOC_E_NONE;
   6862 }
   6863 #endif /* BCM_TRIUMPH_SUPPORT */
   6864 
   6865 #ifdef BCM_SCORPION_SUPPORT
   6866 /*
   6867  * Function:
   6868  *      _soc_counter_sc_non_dma_init
   6869  * Purpose:
   6870  *      Initialize Scorpion's non-DMA counters.
   6871  * Parameters:
   6872  *      unit - The SOC unit number
   6873  *      nports - Number of ports
   6874  *      non_dma_start_index - The starting index of non-DMA counter entries.
   6875  *      non_dma_entries - (OUT) The number of non-DMA counter entries.
   6876  * Returns:
   6877  *      SOC_E_NONE
   6878  */
   6879 STATIC int
   6880 _soc_counter_sc_non_dma_init(int unit, int nports, int non_dma_start_index,
   6881         int *non_dma_entries)
   6882 {
   6883     soc_control_t *soc;
   6884     soc_counter_non_dma_t *non_dma0, *non_dma1;
   6885     int max_cosq_per_port, total_num_cosq, port;
   6886 
   6887     soc = SOC_CONTROL(unit);
   6888     *non_dma_entries = 0;
   6889 
   6890     max_cosq_per_port = 0;
   6891     total_num_cosq = 0;
   6892     for (port = 0; port < nports; port++) {
   6893         if (num_cosq[unit][port] > max_cosq_per_port) {
   6894             max_cosq_per_port = num_cosq[unit][port];
   6895         }
   6896         total_num_cosq += num_cosq[unit][port];
   6897     }
   6898 
   6899     /* EGR_PERQ_XMT_COUNTERS register support in scorpion */
   6900     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   6901                                      SOC_COUNTER_NON_DMA_START];
   6902     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   6903     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   6904     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6905     non_dma0->entries_per_port = SOC_REG_NUMELS(unit, EGR_PERQ_XMT_COUNTERSr);
   6906     non_dma0->num_entries = nports * non_dma0->entries_per_port;
   6907     non_dma0->mem = INVALIDm;
   6908     non_dma0->reg = EGR_PERQ_XMT_COUNTERSr;
   6909     non_dma0->field = PACKET_COUNTERf;
   6910     non_dma0->cname = "PERQ_PKT";
   6911     *non_dma_entries += non_dma0->num_entries;
   6912 
   6913 
   6914     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   6915                                      SOC_COUNTER_NON_DMA_START];
   6916     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   6917         _SOC_COUNTER_NON_DMA_PERQ_REG;
   6918     non_dma0->pbmp = PBMP_ALL(unit);
   6919     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6920     non_dma0->entries_per_port = max_cosq_per_port;
   6921     non_dma0->num_entries = total_num_cosq;
   6922     non_dma0->mem = INVALIDm;
   6923     non_dma0->reg = HOLDROP_PKT_CNTr;
   6924     non_dma0->field = COUNTf;
   6925     non_dma0->cname = "PERQ_DROP_PKT";
   6926     *non_dma_entries += non_dma0->num_entries;
   6927 
   6928     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_IBP -
   6929                                      SOC_COUNTER_NON_DMA_START];
   6930     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   6931     non_dma0->pbmp = PBMP_ALL(unit);
   6932     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   6933     non_dma0->entries_per_port = 1;
   6934     non_dma0->num_entries = nports;
   6935     non_dma0->mem = INVALIDm;
   6936     non_dma0->reg = IBP_DROP_PKT_CNTr;
   6937     non_dma0->field = COUNTf;
   6938     non_dma0->cname = "DROP_PKT_IBP";
   6939     *non_dma_entries += non_dma0->num_entries;
   6940 
   6941     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_CFAP -
   6942                                      SOC_COUNTER_NON_DMA_START];
   6943     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6944     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6945     non_dma1->reg = CFAP_DROP_PKT_CNTr;
   6946     non_dma1->cname = "DROP_PKT_CFAP";
   6947     *non_dma_entries += non_dma1->num_entries;
   6948 
   6949     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   6950                                      SOC_COUNTER_NON_DMA_START];
   6951     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6952     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6953     non_dma1->reg = YELLOW_CNG_DROP_CNTr;
   6954     non_dma1->cname = "DROP_PKT_YEL";
   6955     *non_dma_entries += non_dma1->num_entries;
   6956 
   6957     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   6958                                      SOC_COUNTER_NON_DMA_START];
   6959     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6960     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6961     non_dma1->reg = RED_CNG_DROP_CNTr;
   6962     non_dma1->cname = "DROP_PKT_RED";
   6963     *non_dma_entries += non_dma1->num_entries;
   6964 
   6965     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_TX_LLFC_MSG_CNT -
   6966                                      SOC_COUNTER_NON_DMA_START];
   6967     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   6968     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   6969     non_dma1->pbmp = PBMP_ALL(unit);
   6970     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   6971     non_dma1->mem = INVALIDm;
   6972     non_dma1->reg = TXLLFCMSGCNTr;
   6973     non_dma1->field = TXLLFCMSGCNT_STATSf;
   6974     non_dma1->cname = "MAC_TXLLFCMSG";
   6975     non_dma1->entries_per_port = 1;
   6976     non_dma1->num_entries = nports;
   6977     *non_dma_entries += non_dma1->num_entries;
   6978 
   6979     return SOC_E_NONE;
   6980 }
   6981 #endif /* BCM_SCORPION_SUPPORT */
   6982 
   6983 #ifdef BCM_SHADOW_SUPPORT
   6984 /*
   6985  * Function:
   6986  *      _soc_counter_shadow_non_dma_init
   6987  * Purpose:
   6988  *      Initialize Shadow's non-DMA counters.
   6989  * Parameters:
   6990  *      unit - The SOC unit number
   6991  *      nports - Number of ports.
   6992  *      non_dma_start_index - The starting index of non-DMA counter entries.
   6993  *      non_dma_entries - (OUT) The number of non-DMA counter entries.
   6994  * Returns:
   6995  *      SOC_E_NONE
   6996  *      SOC_E_MEMORY
   6997  */
   6998 STATIC int
   6999 _soc_counter_shadow_non_dma_init(int unit, int nports, int non_dma_start_index,
   7000         int *non_dma_entries)
   7001 {
   7002     soc_control_t *soc;
   7003     soc_counter_non_dma_t *non_dma0,*non_dma1;
   7004     int num_entries,alloc_size;
   7005     uint32 *buf;
   7006 
   7007     soc = SOC_CONTROL(unit);
   7008     *non_dma_entries = 0;
   7009 
   7010     /* Reusing non_dma id for interlaken counters */
   7011 
   7012     /* IL_STAT_MEM_0 Entries */
   7013     num_entries = soc_mem_index_count(unit, IL_STAT_MEM_0m);
   7014     alloc_size = num_entries *
   7015         soc_mem_entry_words(unit, IL_STAT_MEM_0m) * sizeof(uint32);
   7016 
   7017     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   7018     if (buf == NULL) {
   7019         return SOC_E_MEMORY;
   7020     }
   7021     sal_memset(buf, 0, alloc_size);
   7022 
   7023 
   7024     /* IL_STAT_MEM_0: RX_STAT_PKT_COUNTf */
   7025     /* Overload SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT */
   7026     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   7027                                      SOC_COUNTER_NON_DMA_START];
   7028     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   7029         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   7030     non_dma0->pbmp = PBMP_IL_ALL(unit);
   7031     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   7032     non_dma0->entries_per_port = 1;
   7033     non_dma0->num_entries = 1;
   7034     non_dma0->mem = IL_STAT_MEM_0m;
   7035     non_dma0->reg = INVALIDr;
   7036     non_dma0->field = RX_STAT_PKT_COUNTf;
   7037     non_dma0->cname = "IL_RX_PKTCNT";
   7038     non_dma0->dma_buf[0] = buf;
   7039     non_dma0->dma_index_min[0] = 0;
   7040     non_dma0->dma_index_max[0] = num_entries - 1;
   7041     non_dma0->dma_mem[0] = non_dma0->mem;
   7042     *non_dma_entries += non_dma0->num_entries;
   7043 
   7044     /* IL_STAT_MEM_0: RX_STAT_BYTE_COUNTf */
   7045     /* Overload SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE */
   7046     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   7047                                      SOC_COUNTER_NON_DMA_START];
   7048     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   7049     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   7050     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   7051     non_dma1->field = RX_STAT_BYTE_COUNTf;
   7052     non_dma1->cname = "IL_RX_BYTECNT";
   7053     *non_dma_entries += non_dma1->num_entries;
   7054 
   7055     /* IL_STAT_MEM_0: RX_STAT_BAD_PKT_ILERR_COUNTf */
   7056     /* Overload SOC_COUNTER_NON_DMA_COSQ_DROP_PKT */
   7057     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   7058                                      SOC_COUNTER_NON_DMA_START];
   7059     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   7060     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   7061     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   7062     non_dma1->field = RX_STAT_BAD_PKT_ILERR_COUNTf;
   7063     non_dma1->cname = "IL_RX_ERRCNT";
   7064     *non_dma_entries += non_dma1->num_entries;
   7065 
   7066 
   7067     /* IL_STAT_MEM_1 Entries */
   7068     num_entries = soc_mem_index_count(unit, IL_STAT_MEM_1m);
   7069     alloc_size = num_entries *
   7070         soc_mem_entry_words(unit, IL_STAT_MEM_1m) * sizeof(uint32);
   7071 
   7072     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   7073     if (buf == NULL) {
   7074         return SOC_E_MEMORY;
   7075     }
   7076     sal_memset(buf, 0, alloc_size);
   7077 
   7078 
   7079     /* IL_STAT_MEM_1:  RX_STAT_GTMTU_PKT_COUNTf Greater that MTU size*/
   7080     /* Overload SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE */
   7081     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE -
   7082                                      SOC_COUNTER_NON_DMA_START];
   7083     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   7084         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   7085     non_dma0->pbmp = PBMP_IL_ALL(unit);
   7086     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   7087     non_dma0->entries_per_port = 1;
   7088     non_dma0->num_entries = 1;
   7089     non_dma0->mem = IL_STAT_MEM_1m;
   7090     non_dma0->reg = INVALIDr;
   7091     non_dma0->field =  RX_STAT_GTMTU_PKT_COUNTf;
   7092     non_dma0->cname = "IL_RX_GTMTUCNT";
   7093     non_dma0->dma_buf[0] = buf;
   7094     non_dma0->dma_index_min[0] = 0;
   7095     non_dma0->dma_index_max[0] = num_entries - 1;
   7096     non_dma0->dma_mem[0] = non_dma0->mem;
   7097     *non_dma_entries += non_dma0->num_entries;
   7098 
   7099     /* IL_STAT_MEM_1: RX_STAT_EQMTU_PKT_COUNTf - equal to MTU Size*/
   7100     /* Overload SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC */
   7101     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC -
   7102                                      SOC_COUNTER_NON_DMA_START];
   7103     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   7104     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   7105     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   7106     non_dma1->field = RX_STAT_EQMTU_PKT_COUNTf;
   7107     non_dma1->cname = "IL_RX_EQMTUCNT";
   7108     *non_dma_entries += non_dma1->num_entries;
   7109 
   7110 
   7111     /* IL_STAT_MEM_1: RX_STAT_IEEE_CRCERR_PKT_COUNTf - IEEE CRC err count*/
   7112     /* Overload SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC */
   7113     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC -
   7114                                      SOC_COUNTER_NON_DMA_START];
   7115     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   7116     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   7117     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   7118     non_dma1->field = RX_STAT_IEEE_CRCERR_PKT_COUNTf;
   7119     non_dma1->cname = "IL_RX_CRCERRCNT";
   7120     *non_dma_entries += non_dma1->num_entries;
   7121 
   7122     /* IL_STAT_MEM_2 Entries */
   7123     num_entries = soc_mem_index_count(unit, IL_STAT_MEM_2m);
   7124     alloc_size = num_entries *
   7125         soc_mem_entry_words(unit, IL_STAT_MEM_2m) * sizeof(uint32);
   7126 
   7127     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   7128     if (buf == NULL) {
   7129         return SOC_E_MEMORY;
   7130     }
   7131     sal_memset(buf, 0, alloc_size);
   7132 
   7133     /* IL_STAT_MEM_2:  RX_STAT_PKT_COUNTf Rx stat packet count*/
   7134     /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING */
   7135     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING -
   7136                                      SOC_COUNTER_NON_DMA_START];
   7137     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   7138         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   7139     non_dma0->pbmp = PBMP_IL_ALL(unit);
   7140     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   7141     non_dma0->entries_per_port = 1;
   7142     non_dma0->num_entries = 1;
   7143     non_dma0->mem = IL_STAT_MEM_2m;
   7144     non_dma0->reg = INVALIDr;
   7145     non_dma0->field =  RX_STAT_PKT_COUNTf;
   7146     non_dma0->cname = "IL_RX_STATCNT";
   7147     non_dma0->dma_buf[0] = buf;
   7148     non_dma0->dma_index_min[0] = 0;
   7149     non_dma0->dma_index_max[0] = num_entries - 1;
   7150     non_dma0->dma_mem[0] = non_dma0->mem;
   7151     *non_dma_entries += non_dma0->num_entries;
   7152 
   7153     /* IL_STAT_MEM_3 Entries */
   7154     num_entries = soc_mem_index_count(unit, IL_STAT_MEM_3m);
   7155     alloc_size = num_entries *
   7156         soc_mem_entry_words(unit, IL_STAT_MEM_3m) * sizeof(uint32);
   7157 
   7158     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   7159     if (buf == NULL) {
   7160         return SOC_E_MEMORY;
   7161     }
   7162     sal_memset(buf, 0, alloc_size);
   7163 
   7164     /* IL_STAT_MEM_3:  TX_STAT_PKT_COUNT */
   7165     /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING */
   7166     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING -
   7167                                      SOC_COUNTER_NON_DMA_START];
   7168     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   7169         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   7170     non_dma0->pbmp = PBMP_IL_ALL(unit);
   7171     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   7172     non_dma0->entries_per_port = 1;
   7173     non_dma0->num_entries = 1;
   7174     non_dma0->mem = IL_STAT_MEM_3m;
   7175     non_dma0->reg = INVALIDr;
   7176     non_dma0->field =  TX_STAT_PKT_COUNTf;
   7177     non_dma0->cname = "IL_TX_PKTCNT";
   7178     non_dma0->dma_buf[0] = buf;
   7179     non_dma0->dma_index_min[0] = 0;
   7180     non_dma0->dma_index_max[0] = 1;
   7181     non_dma0->dma_mem[0] = non_dma0->mem;
   7182     *non_dma_entries += non_dma0->num_entries;
   7183 
   7184     /* IL_STAT_MEM_3: TX_STAT_BYTE_COUNTf */
   7185     /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_PKT_IBP */
   7186     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_IBP -
   7187                                      SOC_COUNTER_NON_DMA_START];
   7188     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   7189     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   7190     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   7191     non_dma1->field = TX_STAT_BYTE_COUNTf;
   7192     non_dma1->cname = "IL_TX_BYTECNT";
   7193     *non_dma_entries += non_dma1->num_entries;
   7194 
   7195     /* IL_STAT_MEM_3: TX_STAT_BAD_PKT_PERR_COUNTf */
   7196     /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_PKT_CFAP */
   7197     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_CFAP -
   7198                                      SOC_COUNTER_NON_DMA_START];
   7199     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   7200     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   7201     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   7202     non_dma1->field = TX_STAT_BAD_PKT_PERR_COUNTf;
   7203     non_dma1->cname = "IL_TX_ERRCNT";
   7204     *non_dma_entries += non_dma1->num_entries;
   7205 
   7206     /* IL_STAT_MEM_3: TX_STAT_GTMTU_PKT_COUNTf */
   7207     /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_PKT */
   7208     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT -
   7209                                      SOC_COUNTER_NON_DMA_START];
   7210     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   7211     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   7212     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   7213     non_dma1->field = TX_STAT_GTMTU_PKT_COUNTf;
   7214     non_dma1->cname = "IL_TX_GTMTUCNT";
   7215     *non_dma_entries += non_dma1->num_entries;
   7216 
   7217     /* IL_STAT_MEM_3: TX_STAT_EQMTU_PKT_COUNT - Greater than mtu size */
   7218     /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW */
   7219     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   7220                                      SOC_COUNTER_NON_DMA_START];
   7221     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   7222     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   7223     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   7224     non_dma1->field = TX_STAT_EQMTU_PKT_COUNTf;
   7225     non_dma1->cname = "IL_TX_EQMTUCNT";
   7226     *non_dma_entries += non_dma1->num_entries;
   7227 
   7228     /* IL_STAT_MEM_4 Entries */
   7229     /* IL_STAT_MEM_4 overloaded on SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT */
   7230     num_entries = soc_mem_index_count(unit, IL_STAT_MEM_4m);
   7231     alloc_size = num_entries *
   7232         soc_mem_entry_words(unit, IL_STAT_MEM_4m) * sizeof(uint32);
   7233 
   7234     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   7235     if (buf == NULL) {
   7236         return SOC_E_MEMORY;
   7237     }
   7238     sal_memset(buf, 0, alloc_size);
   7239 
   7240     /* TX_STAT_PKT_COUNT */
   7241     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   7242                                      SOC_COUNTER_NON_DMA_START];
   7243     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   7244         _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC;
   7245     non_dma1->pbmp = PBMP_IL_ALL(unit);
   7246     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   7247     non_dma1->entries_per_port = 1;
   7248     non_dma1->num_entries = 1;
   7249     non_dma1->mem = IL_STAT_MEM_4m;
   7250     non_dma1->reg = INVALIDr;
   7251     non_dma1->field = TX_STAT_PKT_COUNTf;
   7252     non_dma1->cname = "IL_TX_STATCNT";
   7253     non_dma1->dma_buf[0] = buf;
   7254     non_dma1->dma_index_min[0] = 0;
   7255     non_dma1->dma_index_max[0] = num_entries - 1;
   7256     non_dma1->dma_mem[0] = non_dma1->mem;
   7257     *non_dma_entries += non_dma1->num_entries;
   7258 
   7259     return SOC_E_NONE;
   7260 }
   7261 #endif /* BCM_SHADOW_SUPPORT */
   7262 
   7263 #ifdef BCM_BRADLEY_SUPPORT
   7264 /*
   7265  * Function:
   7266  *      _soc_counter_hb_non_dma_init
   7267  * Purpose:
   7268  *      Initialize Bradley's non-DMA counters.
   7269  * Parameters:
   7270  *      unit - The SOC unit number
   7271  *      nports - Number of ports
   7272  *      non_dma_start_index - The starting index of non-DMA counter entries.
   7273  *      non_dma_entries - (OUT) The number of non-DMA counter entries.
   7274  * Returns:
   7275  *      SOC_E_NONE
   7276  */
   7277 STATIC int
   7278 _soc_counter_hb_non_dma_init(int unit, int nports, int non_dma_start_index,
   7279         int *non_dma_entries)
   7280 {
   7281     soc_control_t *soc;
   7282     soc_counter_non_dma_t *non_dma;
   7283 
   7284     soc = SOC_CONTROL(unit);
   7285     *non_dma_entries = 0;
   7286 
   7287     non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT -
   7288                                     SOC_COUNTER_NON_DMA_START];
   7289     non_dma->flags = _SOC_COUNTER_NON_DMA_VALID;
   7290     non_dma->pbmp = PBMP_ALL(unit);
   7291     non_dma->base_index = non_dma_start_index + *non_dma_entries;
   7292     non_dma->entries_per_port = 1;
   7293     non_dma->num_entries = nports;
   7294     non_dma->mem = INVALIDm;
   7295     non_dma->reg = DROP_PKT_CNTr;
   7296     non_dma->field = COUNTf;
   7297     non_dma->cname = "DROP_PKT_MMU";
   7298     *non_dma_entries += non_dma->num_entries;
   7299 
   7300     return SOC_E_NONE;
   7301 }
   7302 #endif /* BCM_BRADLEY_SUPPORT */
   7303 
   7304 #ifdef BCM_FIREBOLT_SUPPORT
   7305 /*
   7306  * Function:
   7307  *      _soc_counter_fb_non_dma_init
   7308  * Purpose:
   7309  *      Initialize Firebolt's non-DMA counters.
   7310  * Parameters:
   7311  *      unit - The SOC unit number
   7312  *      nports - Number of ports
   7313  *      non_dma_start_index - The starting index of non-DMA counter entries.
   7314  *      non_dma_entries - (OUT) The number of non-DMA counter entries.
   7315  * Returns:
   7316  *      SOC_E_NONE
   7317  */
   7318 STATIC int
   7319 _soc_counter_fb_non_dma_init(int unit, int nports, int non_dma_start_index,
   7320         int *non_dma_entries)
   7321 {
   7322     soc_control_t *soc;
   7323     soc_counter_non_dma_t *non_dma0, *non_dma1;
   7324 
   7325     soc = SOC_CONTROL(unit);
   7326     *non_dma_entries = 0;
   7327 
   7328     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   7329                                      SOC_COUNTER_NON_DMA_START];
   7330     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID;
   7331     non_dma0->pbmp = PBMP_ALL(unit);
   7332     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   7333     non_dma0->entries_per_port = 1;
   7334     non_dma0->num_entries = nports;
   7335     non_dma0->mem = INVALIDm;
   7336     non_dma0->reg = CNGDROPCOUNT1r;
   7337     non_dma0->field = DROPPKTCOUNTf;
   7338     non_dma0->cname = "DROP_PKT_YEL";
   7339     *non_dma_entries += non_dma0->num_entries;
   7340 
   7341     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   7342                                      SOC_COUNTER_NON_DMA_START];
   7343     sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t));
   7344     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   7345     non_dma1->reg = CNGDROPCOUNT0r;
   7346     non_dma1->cname = "DROP_PKT_RED";
   7347     *non_dma_entries += non_dma1->num_entries;
   7348 
   7349     return SOC_E_NONE;
   7350 }
   7351 #endif /* BCM_FIREBOLT_SUPPORT */
   7352 
   7353 #ifdef BCM_SBUSDMA_SUPPORT
   7354 static sbusdma_desc_handle_t *_soc_blk_counter_handles[SOC_MAX_NUM_DEVICES] = {NULL};
   7355 static soc_blk_ctr_process_t **_blk_ctr_process[SOC_MAX_NUM_DEVICES] = {NULL};
   7356 void _soc_sbusdma_blk_ctr_cb(int unit, int status, sbusdma_desc_handle_t handle,
   7357                              void *data)
   7358 {
   7359     uint16 i, j, arr, bufidx, hwidx;
   7360     uint64 ctr_new, ctr_prev, ctr_diff;
   7361     int wide, width, f;
   7362     volatile uint64 *vptr;
   7363     uint32 *hwptr;
   7364     soc_control_t *soc = SOC_CONTROL(unit);
   7365     soc_reg_t ctr_reg;
   7366     soc_blk_ctr_process_t *ctr_process = _blk_ctr_process[unit][PTR_TO_INT(data)];
   7367     LOG_DEBUG(BSL_LS_SOC_COUNTER,
   7368                 (BSL_META_U(unit,
   7369                             "In blk counter cb [%d]\n"), handle));
   7370     if (status == SOC_E_NONE) {
   7371         LOG_DEBUG(BSL_LS_SOC_COUNTER,
   7372                     (BSL_META_U(unit,
   7373                                 "Complete: blk:%d, index: %d, entries: %d.\n"),
   7374                      ctr_process->blk, ctr_process->bindex, ctr_process->entries));
   7375         /* Process data (need bindex, count) */
   7376         hwptr = (uint32*)ctr_process->buff;
   7377         for (i=0, bufidx = 0, hwidx = 0; i<ctr_process->entries; i++) {
   7378             arr = soc->blk_ctr_desc[ctr_process->bindex].desc[i].entries;
   7379             ctr_reg = soc->blk_ctr_desc[ctr_process->bindex].desc[i].reg;
   7380             wide = (soc->blk_ctr_desc[ctr_process->bindex].desc[i].width > 1) ? 1 : 0;
   7381             for (j=0; j<arr; j++, bufidx++, hwidx++) {
   7382                 uint32 *ptr = &hwptr[hwidx];
   7383                 if (wide) {
   7384                     if (soc->counter_flags & SOC_COUNTER_F_SWAP64) {
   7385                         COMPILER_64_SET(ctr_new, ptr[0], ptr[1]);
   7386                     } else {
   7387                         COMPILER_64_SET(ctr_new, ptr[1], ptr[0]);
   7388                     }
   7389                     hwidx++;
   7390                 } else {
   7391                     COMPILER_64_SET(ctr_new, 0, ptr[0]);
   7392                 }
   7393                 if (!COMPILER_64_IS_ZERO(ctr_new)) {
   7394                     LOG_DEBUG(BSL_LS_SOC_COUNTER,
   7395                                 (BSL_META_U(unit,
   7396                                             "idx: %d, bufidx: %d, :val: %x_%x\n"),
   7397                                  i, bufidx, COMPILER_64_HI(ctr_new),
   7398                                  COMPILER_64_LO(ctr_new)));
   7399                 }
   7400                 ctr_prev = ctr_process->hwval[bufidx];
   7401                 vptr = &ctr_process->swval[bufidx];
   7402                 if (COMPILER_64_EQ(ctr_new, ctr_prev)) {
   7403                     /* clear delta. (not maintaining delta for now) */
   7404                 } else {
   7405                     ctr_diff = ctr_new;
   7406                     if (COMPILER_64_LT(ctr_diff, ctr_prev)) { /* handle rollover */
   7407                         uint64 wrap_amt;
   7408                         f = 0;
   7409                         width = SOC_REG_INFO(unit, ctr_reg).fields[f].len;
   7410                         while((SOC_REG_INFO(unit, ctr_reg).fields + f) != NULL) {
   7411                             if (SOC_REG_INFO(unit, ctr_reg).fields[f].field ==
   7412                                 COUNTf) {
   7413                                 width = SOC_REG_INFO(unit, ctr_reg).fields[f].len;
   7414                                 break;
   7415                             }
   7416                             f++;
   7417                         }
   7418                         if (width < 32) {
   7419                             COMPILER_64_SET(wrap_amt, 0, 1UL << width);
   7420                             COMPILER_64_ADD_64(ctr_diff, wrap_amt);
   7421                         } else if (width < 64) {
   7422                             COMPILER_64_SET(wrap_amt, 1UL << (width - 32), 0);
   7423                             COMPILER_64_ADD_64(ctr_diff, wrap_amt);
   7424                         }
   7425                     }
   7426                     COMPILER_64_SUB_64(ctr_diff, ctr_prev);
   7427                     ctr_process->hwval[bufidx] = ctr_new;
   7428                     COMPILER_64_ADD_64(*vptr, ctr_diff);
   7429                 }
   7430             }
   7431         }
   7432     } else {
   7433         LOG_ERROR(BSL_LS_SOC_COMMON,
   7434                   (BSL_META_U(unit,
   7435                               "Counter SBUSDMA failed: blk:%d, index: %d, entries: %d.\n"),
   7436                    ctr_process->blk, ctr_process->bindex, ctr_process->entries));
   7437         if (status == SOC_E_TIMEOUT) {
   7438             /* delete this handles desc */
   7439             (void)soc_sbusdma_desc_delete(unit, handle);
   7440             _soc_blk_counter_handles[unit][ctr_process->bindex] = 0;
   7441         }
   7442     }
   7443 }
   7444 #endif
   7445 
   7446 /* Function to Set all Sw maintained counter values to 0 */
   7447 void
   7448 soc_counter_ctr_reset_to_zero(int unit)
   7449 {
   7450     soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit);
   7451     soc_control_t         *soc = SOC_CONTROL(unit);
   7452 
   7453     if (soc->counter_sw_val != NULL) {
   7454         sal_memset(soc->counter_sw_val, 0,
   7455                    soc_ctr_ctrl->total_dma_entries * sizeof(uint64));
   7456     }
   7457     if (soc->counter_hw_val != NULL) {
   7458         sal_memset(soc->counter_hw_val, 0,
   7459                    soc_ctr_ctrl->total_dma_entries * sizeof(uint64));
   7460     }
   7461     if (soc->counter_delta != NULL) {
   7462         sal_memset(soc->counter_delta, 0,
   7463                    soc_ctr_ctrl->total_dma_entries * sizeof(uint64));
   7464     }
   7465     return;
   7466 }
   7467 
   7468 /*
   7469  * Function:
   7470  *      soc_counter_attach
   7471  * Purpose:
   7472  *      Initialize counter module.
   7473  * Notes:
   7474  *      Allocates counter collection buffers.
   7475  *      We need to work with the true data for the chip, not the current
   7476  *      pbmp_valid settings.  They may be changed after attach, but the
   7477  *      memory won't be reallocated at that time.
   7478  */
   7479 
   7480 int
   7481 soc_counter_attach(int unit)
   7482 {
   7483     soc_control_t         *soc;
   7484     int                   n_entries, n_bytes;
   7485     int                   non_dma_entries = 0;
   7486     int                   portsize, nports, ports64;
   7487     int                   blk, bindex, port, phy_port;
   7488     int                   blktype, ctype, idx;
   7489     uint32                array_idx;
   7490     char                  *counter_level;
   7491     soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit);
   7492 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   7493     int                   ct;
   7494 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_APACHE_SUPPORT*/
   7495 #if defined(BCM_TOMAHAWK2_SUPPORT)
   7496     soc_info_t *si = &SOC_INFO(unit);
   7497 #endif
   7498 #if defined(BCM_PETRA_SUPPORT)
   7499     int                   nof_entries_to_alloacte;
   7500 #endif /* BCM_PETRA_SUPPORT */
   7501 
   7502     assert(SOC_UNIT_VALID(unit));
   7503 
   7504     soc = SOC_CONTROL(unit);
   7505         soc->ctr_evict_pid = SAL_THREAD_ERROR;
   7506         soc->ctr_evict_interval = 0;
   7507         soc->counter_pid = SAL_THREAD_ERROR;
   7508         soc->counter_interval = 0;
   7509         SOC_PBMP_CLEAR(soc->counter_pbmp);
   7510         soc->counter_trigger = NULL;
   7511         soc->counter_intr = NULL;
   7512         /* Note that flags will be reinitialized in soc_counter_start */
   7513         if (soc_feature(unit, soc_feature_stat_dma) && !SOC_IS_RCPU_ONLY(unit)) {
   7514             soc->counter_flags = SOC_COUNTER_F_DMA;
   7515         } else {
   7516             soc->counter_flags = 0;
   7517         }
   7518         soc->counter_coll_prev = soc->counter_coll_cur = sal_time_usecs();
   7519 
   7520         /*For soc_feature_controlled_counters feture (use only the relevant)*/
   7521         if (soc_feature(unit, soc_feature_controlled_counters)) {
   7522             /*For not soc_feature_ignore_controlled_counter_priority feture (use only the relevant)*/
   7523             if (!soc_feature(unit, soc_feature_ignore_controlled_counter_priority)) {
   7524                 counter_level = soc_property_get_str(unit, spn_SOC_COUNTER_CONTROL_LEVEL);
   7525                 if(NULL == counter_level) {
   7526                     soc->soc_controlled_counter_flags |= _SOC_CONTROLLED_COUNTER_FLAG_HIGH;
   7527                 } else if (sal_strcmp(counter_level, "HIGH_LEVEL")) {
   7528                     soc->soc_controlled_counter_flags |= _SOC_CONTROLLED_COUNTER_FLAG_HIGH;
   7529                 } else if (sal_strcmp(counter_level, "MEDIUM_LEVEL")) {
   7530                     soc->soc_controlled_counter_flags |= (_SOC_CONTROLLED_COUNTER_FLAG_HIGH | _SOC_CONTROLLED_COUNTER_FLAG_MEDIUM);
   7531                 } else if (sal_strcmp(counter_level, "LOW_LEVEL")) {
   7532                     soc->soc_controlled_counter_flags |= (_SOC_CONTROLLED_COUNTER_FLAG_HIGH | _SOC_CONTROLLED_COUNTER_FLAG_MEDIUM | _SOC_CONTROLLED_COUNTER_FLAG_LOW);
   7533                 } else { /*default*/
   7534                     LOG_ERROR(BSL_LS_SOC_COMMON,
   7535                             (BSL_META_U(unit,
   7536                                         "soc_counter_attach: unit %d:illegal counter level \n"), unit));
   7537                     return SOC_E_FAIL;
   7538                 }
   7539             }
   7540             /*count the relevant counters (according to level)*/
   7541             soc->soc_controlled_counter_num = 0;
   7542             soc->soc_controlled_counter_all_num = 0;
   7543             if (soc->controlled_counters) {
   7544                 for (array_idx = 0; soc->controlled_counters[array_idx].controlled_counter_f != NULL; array_idx++) {
   7545 
   7546 #ifdef BCM_PETRA_SUPPORT
   7547                 if (SOC_IS_ARAD(unit)) {
   7548                     /*do not collect NIF counters - the register are not cleared on read*/
   7549                     if ( (soc->controlled_counters[array_idx].flags & _SOC_CONTROLLED_COUNTER_FLAG_NIF) || (soc->controlled_counters[array_idx].flags & _SOC_CONTROLLED_COUNTER_FLAG_ILKN) ) {
   7550                             continue;
   7551                         }
   7552                     }
   7553 #endif
   7554                 (soc->soc_controlled_counter_all_num)++;
   7555                 if (soc_feature(unit, soc_feature_ignore_controlled_counter_priority)) {
   7556                     (soc->soc_controlled_counter_num)++;
   7557                     soc->controlled_counters[array_idx].counter_idx = soc->soc_controlled_counter_all_num - 1;
   7558                     LOG_DEBUG(BSL_LS_SOC_COMMON,
   7559                                 (BSL_META_U(unit,
   7560                                             "counter_idx, %d. counter_id,%d.\n"),
   7561                                             soc->controlled_counters[array_idx].counter_idx,
   7562                                             soc->controlled_counters[array_idx].counter_id));
   7563                 } else {
   7564                     if (soc->controlled_counters[array_idx].flags & soc->soc_controlled_counter_flags) {
   7565                         (soc->soc_controlled_counter_num)++;
   7566                         soc->controlled_counters[array_idx].counter_idx = soc->soc_controlled_counter_all_num - 1;
   7567                     }
   7568                 }
   7569             }
   7570         }
   7571         }
   7572     portsize = 0;
   7573     port = 0;
   7574     /* We can't use pbmp_valid calculations, so we must do this manually. */
   7575     for (phy_port = 0; ; phy_port++) {
   7576         blk = SOC_PORT_BLOCK(unit, phy_port);
   7577 #if defined(BCM_MONTEREY_SUPPORT)
   7578        if (SOC_IS_MONTEREY(unit) ) { 
   7579            if ((((phy_port > 0) && (phy_port < 13)) ||
   7580                  ((phy_port > 52) && (phy_port < 65)))
   7581                && !(IS_CPRI_PORT(unit, port))) {
   7582                 blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,1);
   7583            }
   7584       } 
   7585 #endif
   7586         bindex = SOC_PORT_BINDEX(unit, phy_port);
   7587         if (blk < 0 && bindex < 0) {                    /* end of list */
   7588             break;
   7589         }
   7590         if (soc_feature(unit, soc_feature_logical_port_num)) {
   7591             if (port < SOC_INFO(unit).port_p2l_mapping[phy_port]) {
   7592                 port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   7593             }
   7594         } else {
   7595             port = phy_port;
   7596         }
   7597     }
   7598 
   7599     port++;
   7600 
   7601 #if defined(BCM_TOMAHAWK2_SUPPORT)
   7602     /* for flex port, should reserve enough counter resources */
   7603     if (SOC_IS_TOMAHAWK2(unit)) {
   7604         if (!SHR_BITNULL_RANGE(si->flexible_pm_bitmap, 1, _TH2_PBLKS_PER_DEV)) {
   7605             int num_pipe = soc_property_get(unit, "num_pipe", 4);
   7606             port = num_pipe * _TH2_DEV_PORTS_PER_PIPE;
   7607         }
   7608     }
   7609 #endif
   7610 
   7611     /* Don't count last port if CMIC */
   7612     if (CMIC_PORT(unit) == (port - 1)) {
   7613         /*
   7614          * On XGS3 switch CMIC port stats are DMAable. Allocate space
   7615          * in case these stats need to be DMAed as well.
   7616          */
   7617         if (!soc_feature(unit, soc_feature_cpuport_stat_dma)) {
   7618             port--;
   7619         }
   7620     }
   7621 
   7622     nports = port;      /* 0..max_port_num */
   7623     ports64 = 0;
   7624 
   7625     if (SOC_IS_HB_GW(unit)) {
   7626         portsize = 2048;
   7627         ports64 = nports;
   7628     } else if (SOC_IS_APACHE(unit)) {
   7629         portsize = 17 * 1024;
   7630         ports64 = nports;
   7631     } else if (SOC_IS_TRX(unit)) {
   7632         portsize = 4096;
   7633         ports64 = nports;
   7634     } else if (SOC_IS_HERCULES(unit) || SOC_IS_XGS3_SWITCH(unit)) {
   7635         portsize = 1024;
   7636         ports64 = nports;
   7637 #if defined(BCM_PETRA_SUPPORT)
   7638     } else if (SOC_IS_ARAD(unit)) {
   7639         nof_entries_to_alloacte = FABRIC_LOGICAL_PORT_BASE(unit) + SOC_DPP_DEFS_GET(unit, first_fabric_link_id) + SOC_DPP_DEFS_GET(unit, nof_fabric_links);
   7640         if (nof_entries_to_alloacte < nports){
   7641             LOG_ERROR(BSL_LS_SOC_COMMON,
   7642                       (BSL_META_U(unit,
   7643                                   "Number of counters (%d) is larger than counters allowed in database (%d)!\n"),
   7644                               nports, nof_entries_to_alloacte));
   7645         }
   7646         nports = nof_entries_to_alloacte;
   7647         ports64 = nports;
   7648         portsize = sizeof(uint64) * (soc->soc_controlled_counter_all_num + 160 /*nof non controlled counters*/);
   7649 #endif
   7650 #if defined(BCM_DNX_SUPPORT)
   7651     } else if (SOC_IS_DNX(unit)) {
   7652         nports = dnx_data_port.general.fabric_port_base_get(unit) + dnx_data_fabric.links.nof_links_get(unit);
   7653         ports64 = nports;
   7654         portsize = sizeof(uint64)*(soc->soc_controlled_counter_all_num);
   7655 #endif
   7656 #if defined(BCM_DFE_SUPPORT)
   7657     } else if (SOC_IS_DFE(unit)) {
   7658         ports64 = nports;
   7659         portsize = sizeof(uint64)*(soc->soc_controlled_counter_all_num);
   7660 #endif
   7661 #if defined(BCM_DNXF_SUPPORT)
   7662     } else if (SOC_IS_DNXF(unit)) {
   7663         ports64 = nports;
   7664         portsize = sizeof(uint64)*(soc->soc_controlled_counter_all_num);
   7665 #endif
   7666     } else {
   7667         LOG_ERROR(BSL_LS_SOC_COMMON,
   7668                   (BSL_META_U(unit,
   7669                               "soc_counter_attach: unit %d: unexpected chip type\n"),
   7670                    unit));
   7671         return SOC_E_FAIL;
   7672     }
   7673 
   7674     soc->counter_perport = portsize / sizeof(uint64);
   7675     soc->counter_n32 = 0;
   7676     soc->counter_n64 = (portsize / sizeof(uint64)) * ports64;
   7677     soc->counter_ports32 = 0;
   7678     if(soc->counter_flags & SOC_COUNTER_F_DMA) {
   7679         soc->counter_ports64 = ports64;
   7680     }
   7681     n_bytes = portsize * nports;
   7682 
   7683     n_entries = soc->counter_n32 + soc->counter_n64;
   7684     soc->counter_portsize = portsize;
   7685     soc->counter_bufsize = n_bytes;
   7686 
   7687     LOG_DEBUG(BSL_LS_SOC_COMMON,
   7688                 (BSL_META_U(unit,
   7689                             "soc_counter_attach: %d bytes/port, %d ports, %d ctrs/port, "
   7690                             "%d ports with %d ctrs\n"),
   7691                  portsize, nports, soc->counter_perport,
   7692                  ports64, soc->counter_n64));
   7693 
   7694     /* Initialize SOC Counter Control Structure */
   7695     if (SOC_CTR_CTRL(unit) != NULL) {
   7696         sal_free(soc_ctr_ctrl);
   7697         SOC_CTR_CTRL(unit) = NULL;
   7698     }
   7699 
   7700     if (SOC_CTR_CTRL(unit) == NULL) {
   7701         soc_ctr_ctrl = sal_alloc(sizeof(soc_counter_control_t),
   7702                                  "cntr_ctrl_s");
   7703         if (!soc_ctr_ctrl) {
   7704             return SOC_E_MEMORY;
   7705         }
   7706     }
   7707     sal_memset(soc_ctr_ctrl, 0, sizeof(soc_counter_control_t));
   7708     SOC_CTR_CTRL(unit) = soc_ctr_ctrl;
   7709 
   7710 #ifdef BCM_TOMAHAWK_SUPPORT
   7711     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   7712         soc_ctr_ctrl->collect_non_stat_dma = soc_counter_collect_th_non_dma_entries;
   7713     } else
   7714 #endif /* BCM_TOMAHAWK_SUPPORT */
   7715     { 
   7716         soc_ctr_ctrl->collect_non_stat_dma = soc_counter_collect_non_dma_entries;
   7717     }
   7718 
   7719     /* Initialize Non-DMA counters */
   7720 
   7721     if (soc->counter_non_dma == NULL) {
   7722         soc->counter_non_dma = sal_alloc((SOC_COUNTER_NON_DMA_END -
   7723                                          SOC_COUNTER_NON_DMA_START) *
   7724                                          sizeof(soc_counter_non_dma_t),
   7725                                          "cntr_non_dma");
   7726         if (soc->counter_non_dma == NULL) {
   7727             goto error;
   7728         }
   7729     } else {
   7730         for (idx = 0; idx < SOC_COUNTER_NON_DMA_END - SOC_COUNTER_NON_DMA_START;
   7731              idx++) {
   7732             if (soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_ALLOC) {
   7733                 soc_cm_sfree(unit, soc->counter_non_dma[idx].dma_buf[0]);
   7734             }
   7735 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   7736             if((soc->counter_non_dma[idx].extra_ctrs != NULL) &&
   7737                ((soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_DO_DMA) ||
   7738                 (soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_OBM))){
   7739                 uint32 ct2, ctr_offset;
   7740                 uint32 fld_ct = 2; /* TH/TH2 has default fld_ct = 2 */
   7741 #ifdef BCM_TOMAHAWK3_SUPPORT
   7742                 if(SOC_IS_TOMAHAWK3(unit)) {
   7743                     fld_ct = soc->counter_non_dma[idx].extra_ctr_fld_ct;
   7744                 }
   7745 #endif /* BCM_TOMAHAWK3_SUPPORT */
   7746                 for(ct = 0; ct < soc->counter_non_dma[idx].extra_ctr_ct; ct++) {
   7747                     for(ct2 = 0; ct2 < fld_ct; ct2++) {
   7748                         ctr_offset = ct * fld_ct + ct2;
   7749                         if((soc->counter_non_dma[idx].extra_ctrs[ctr_offset].cname != NULL) &&
   7750                            (soc->counter_non_dma[idx].extra_ctrs[ctr_offset].cname[0] == '*')){
   7751                             sal_free(soc->counter_non_dma[idx].extra_ctrs[ctr_offset].cname);
   7752                             soc->counter_non_dma[idx].extra_ctrs[ctr_offset].cname = NULL;
   7753                     }
   7754                     }
   7755                 }
   7756 
   7757                 sal_free(soc->counter_non_dma[idx].extra_ctrs);
   7758                 soc->counter_non_dma[idx].extra_ctrs = NULL;
   7759                 if((soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_OBM) &&
   7760                    (soc->counter_non_dma[idx].id != SOC_COUNTER_NON_DMA_PORT_OBM_FC_EVENTS)) {
   7761                     soc->counter_non_dma[idx+1].extra_ctrs = NULL;
   7762                 }
   7763             }
   7764 #endif /* BCM_TOMAHAWK_SUPPORT */
   7765         }
   7766     }
   7767     sal_memset(soc->counter_non_dma, 0,
   7768                (SOC_COUNTER_NON_DMA_END - SOC_COUNTER_NON_DMA_START) *
   7769                sizeof(soc_counter_non_dma_t));
   7770 
   7771     /* Controlled counters */
   7772     if (!soc_feature(unit, soc_feature_controlled_counters)) {
   7773         soc->controlled_counters = NULL;
   7774     }
   7775 
   7776     /* Initialize the number of cosq counters per port */
   7777     _soc_counter_num_cosq_init(unit, nports);
   7778 
   7779 #ifdef BCM_TRIUMPH_SUPPORT
   7780 #ifdef BCM_TRIUMPH3_SUPPORT
   7781     if (SOC_IS_TRIUMPH3(unit)) {
   7782         if (SOC_FAILURE(_soc_counter_triumph3_non_dma_init(unit,
   7783                             nports, n_entries, &non_dma_entries))) {
   7784             goto error;
   7785         }
   7786     } else
   7787 #endif /* BCM_TRIUMPH3_SUPPORT */
   7788 #ifdef BCM_TOMAHAWK_SUPPORT
   7789     if (SOC_IS_TOMAHAWKX(unit)) {
   7790 #ifdef BCM_TOMAHAWK3_SUPPORT
   7791         if (SOC_IS_TOMAHAWK3(unit)) {
   7792             if (SOC_FAILURE(soc_counter_tomahawk3_non_dma_init
   7793                             (unit, nports, n_entries, &non_dma_entries))) {
   7794                 goto error;
   7795             }
   7796         } else
   7797 #endif
   7798         if (SOC_FAILURE(soc_counter_tomahawk_non_dma_init
   7799                         (unit, nports, n_entries, &non_dma_entries))) {
   7800             goto error;
   7801         }
   7802     } else
   7803 #endif /* BCM_TOMAHAWK_SUPPORT */
   7804 #ifdef BCM_TRIDENT3_SUPPORT
   7805     if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) {
   7806         if (SOC_FAILURE(soc_counter_trident3_non_dma_init
   7807                         (unit, nports, n_entries, &non_dma_entries))) {
   7808             goto error;
   7809         }
   7810     } else
   7811 #endif /* BCM_TOMAHAWK_SUPPORT */
   7812 #ifdef BCM_HELIX5_SUPPORT
   7813     if (SOC_IS_HELIX5(unit)) {
   7814         if (SOC_FAILURE(soc_counter_helix5_non_dma_init
   7815                         (unit, nports, n_entries, &non_dma_entries))) {
   7816             goto error;
   7817         }
   7818     } else
   7819 #endif /* BCM_HELIX5_SUPPORT */
   7820 #ifdef BCM_APACHE_SUPPORT
   7821     if (SOC_IS_APACHE(unit)) {
   7822         if (SOC_FAILURE(_soc_counter_apache_non_dma_init(unit,
   7823                         nports, n_entries, &non_dma_entries))) {
   7824             goto error;
   7825         }
   7826 #if defined(BCM_MONTEREY_SUPPORT) && defined (CPRIMOD_SUPPORT)
   7827         /* Add CPRI counters if supported */
   7828         if (SOC_IS_MONTEREY(unit)) {
   7829             int cpri_non_dma_entries = 0;
   7830             if (SOC_FAILURE(_soc_counter_monterey_non_dma_cpri_init(unit,
   7831                                         nports, n_entries + non_dma_entries,
   7832                                         &cpri_non_dma_entries))) {
   7833                 goto error;
   7834             }
   7835             non_dma_entries += cpri_non_dma_entries;
   7836         }
   7837 #endif /* BCM_MONTEREY_SUPPORT && CPRIMOD_SUPPORT */
   7838     } else
   7839 #endif /* BCM_APACHE_SUPPORT */
   7840 #if defined ( BCM_TRIDENT2_SUPPORT ) || defined ( BCM_TRIDENT2PLUS_SUPPORT )
   7841     if (SOC_IS_TD2_TT2(unit)) {
   7842         if (SOC_FAILURE(_soc_counter_trident2_non_dma_init(unit,
   7843                             nports, n_entries, &non_dma_entries))) {
   7844             goto error;
   7845         }
   7846     } else
   7847 #endif /* BCM_TRIDENT2_SUPPORT */
   7848 #ifdef BCM_TRIDENT_SUPPORT
   7849     if (SOC_IS_TD_TT(unit)) {
   7850         if (SOC_FAILURE(_soc_counter_trident_non_dma_init(unit, nports, n_entries,
   7851                         &non_dma_entries))) {
   7852             goto error;
   7853         }
   7854     } else
   7855 #endif /* BCM_TRIDENT_SUPPORT */
   7856 #ifdef BCM_HURRICANE_SUPPORT
   7857     if (SOC_IS_HURRICANE(unit) || SOC_IS_HURRICANE2(unit)) {
   7858         if (SOC_FAILURE(_soc_counter_hu_non_dma_init(unit, nports, n_entries,
   7859                         &non_dma_entries))) {
   7860             goto error;
   7861         }
   7862     } else
   7863 #endif /* BCM_HURRICANE_SUPPORT */
   7864 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
   7865     if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) {
   7866         if (SOC_FAILURE(_soc_counter_gh_non_dma_init(unit, nports, n_entries,
   7867                         &non_dma_entries))) {
   7868             goto error;
   7869         }
   7870     } else
   7871 #endif /* BCM_GREYHOUND_SUPPORT || BCM_HURRICANE3_SUPPORT */
   7872 #if defined(BCM_GREYHOUND2_SUPPORT)
   7873     if (SOC_IS_GREYHOUND2(unit)) {
   7874         if (SOC_FAILURE(_soc_counter_gh2_non_dma_init(unit, nports, n_entries,
   7875                                                       &non_dma_entries))) {
   7876             goto error;
   7877         }
   7878     } else
   7879 #endif /* BCM_GREYHOUND2_SUPPORT */
   7880 #ifdef BCM_KATANA2_SUPPORT
   7881  /*we may not need separate saber2_non_dma() function */
   7882     if (SOC_IS_KATANA2(unit)) {
   7883         if (SOC_FAILURE(_soc_counter_saber2_non_dma_init(unit, nports, n_entries,
   7884                         &non_dma_entries))) {
   7885             goto error;
   7886         }
   7887     } else
   7888 #endif /* BCM_SABER2_SUPPORT */
   7889 #ifdef BCM_KATANA_SUPPORT
   7890     if (SOC_IS_KATANAX(unit)) {
   7891         if (SOC_FAILURE(_soc_counter_katana_non_dma_init(unit, nports, n_entries,
   7892                         &non_dma_entries))) {
   7893             goto error;
   7894         }
   7895     } else
   7896 #endif /* BCM_KATANA_SUPPORT */
   7897     if (SOC_IS_TR_VL(unit)) {
   7898         if (SOC_FAILURE(_soc_counter_tr_non_dma_init(unit, nports, n_entries,
   7899                         &non_dma_entries))) {
   7900             goto error;
   7901         }
   7902     } else
   7903 #endif /* BCM_TRIUMPH_SUPPORT */
   7904 #ifdef BCM_SCORPION_SUPPORT
   7905     if (SOC_IS_SC_CQ(unit) && (!(SOC_IS_SHADOW(unit)))) {
   7906         if (SOC_FAILURE(_soc_counter_sc_non_dma_init(unit, nports, n_entries,
   7907                         &non_dma_entries))) {
   7908             goto error;
   7909         }
   7910     } else
   7911 #endif /* BCM_SCORPION_SUPPORT */
   7912 #ifdef BCM_SHADOW_SUPPORT
   7913     if (SOC_IS_SHADOW(unit)) {
   7914         if (!SOC_PBMP_IS_NULL(PBMP_IL_ALL(unit))) {
   7915             if (SOC_FAILURE(_soc_counter_shadow_non_dma_init(unit, nports,
   7916                             n_entries, &non_dma_entries))) {
   7917                 goto error;
   7918             }
   7919         }
   7920     } else
   7921 #endif /* BCM_SHADOW_SUPPORT */
   7922 #ifdef BCM_BRADLEY_SUPPORT
   7923     if (SOC_IS_HB_GW(unit)) {
   7924         if (SOC_FAILURE(_soc_counter_hb_non_dma_init(unit, nports, n_entries,
   7925                         &non_dma_entries))) {
   7926             goto error;
   7927         }
   7928     } else
   7929 #endif /* BCM_BRADLEY_SUPPORT */
   7930 #ifdef BCM_FIREBOLT_SUPPORT
   7931     if (SOC_IS_FB_FX_HX(unit)) {
   7932         if (SOC_FAILURE(_soc_counter_fb_non_dma_init(unit, nports, n_entries,
   7933                         &non_dma_entries))) {
   7934             goto error;
   7935         }
   7936     } else
   7937 #endif /* BCM_FIREBOLT_SUPPORT */
   7938     {
   7939         non_dma_entries = 0;
   7940     }
   7941 
   7942     soc->counter_n64_non_dma = non_dma_entries;
   7943 
   7944     /*
   7945      * Counter DMA buffer allocation (32 and 64 bit allocated together)
   7946      */
   7947 
   7948     assert(n_bytes > 0);
   7949 
   7950     /* Hardware DMA buf */
   7951     if(soc->counter_flags & SOC_COUNTER_F_DMA) {
   7952         if (soc->counter_buf32 == NULL) {
   7953             soc->counter_buf32 = soc_cm_salloc(unit, n_bytes, "cntr_dma_buf");
   7954             if (soc->counter_buf32 == NULL) {
   7955                 goto error;
   7956             }
   7957             soc->counter_buf64 = (uint64 *)&soc->counter_buf32[soc->counter_n32];
   7958         }
   7959         sal_memset(soc->counter_buf32, 0, n_bytes);
   7960     }
   7961 
   7962     n_entries += non_dma_entries;
   7963 
   7964     /* Hardware value buf */
   7965     if (soc->counter_hw_val != NULL) {
   7966         sal_free(soc->counter_hw_val);
   7967         soc->counter_hw_val = NULL;
   7968     }
   7969     if (soc->counter_hw_val == NULL) {
   7970         soc->counter_hw_val = sal_alloc(n_entries * sizeof(uint64),
   7971                                         "cntr_hw_val");
   7972         if (soc->counter_hw_val == NULL) {
   7973             goto error;
   7974         }
   7975     }
   7976     sal_memset(soc->counter_hw_val, 0, n_entries * sizeof(uint64));
   7977 
   7978     /* Software value buf */
   7979     if (soc->counter_sw_val != NULL) {
   7980         sal_free(soc->counter_sw_val);
   7981         soc->counter_sw_val = NULL;
   7982     }
   7983     if (soc->counter_sw_val == NULL) {
   7984         soc->counter_sw_val = sal_alloc(n_entries * sizeof(uint64),
   7985                                         "cntr_sw_val");
   7986         if (soc->counter_sw_val == NULL) {
   7987             goto error;
   7988         }
   7989     }
   7990     sal_memset(soc->counter_sw_val, 0, n_entries * sizeof(uint64));
   7991 
   7992     /* Delta buf */
   7993     if (soc->counter_delta != NULL) {
   7994         sal_free(soc->counter_delta);
   7995         soc->counter_delta = NULL;
   7996     }
   7997     if (soc->counter_delta == NULL) {
   7998         soc->counter_delta = sal_alloc(n_entries * sizeof(uint64),
   7999                                        "cntr_delta");
   8000         if (soc->counter_delta == NULL) {
   8001             goto error;
   8002         }
   8003     }
   8004     sal_memset(soc->counter_delta, 0, n_entries * sizeof(uint64));
   8005     soc_ctr_ctrl->total_dma_entries = n_entries;
   8006 
   8007 #ifdef BCM_SBUSDMA_SUPPORT
   8008     _soc_counter_pending[unit] = 0;
   8009 #endif
   8010 
   8011     /* Set up and install counter maps */
   8012 
   8013     /* We can't use pbmp_valid calculations, so we must do this manually. */
   8014     for (phy_port = 0; ; phy_port++) {
   8015 #if defined(BCM_DNX_SUPPORT)
   8016         if (SOC_IS_DNX(unit)) {
   8017             break;            /*skip due to dnx using controlled counter */
   8018         }
   8019 #endif
   8020         blk = SOC_PORT_BLOCK(unit, phy_port);
   8021         bindex = SOC_PORT_BINDEX(unit, phy_port);
   8022         if (blk < 0 && bindex < 0) {                    /* end of list */
   8023             break;
   8024         }
   8025         if (blk < 0) {                                  /* empty slot */
   8026             continue;
   8027         }
   8028         if (soc_feature(unit, soc_feature_logical_port_num)) {
   8029             port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   8030             if (port < 0) {
   8031                 continue;
   8032             }
   8033         } else {
   8034             port = phy_port;
   8035             if (port >= nports) {
   8036                 continue;
   8037             }
   8038         }
   8039 #if defined(BCM_MONTEREY_SUPPORT)
   8040         if (!(IS_CPRI_PORT(unit, port)) && SOC_IS_MONTEREY(unit)) {
   8041             if (((phy_port > 0) && (phy_port < 13)) ||
   8042                  ((phy_port > 52) && (phy_port < 65))) {
   8043                 blk = SOC_PORT_IDX_BLOCK(unit, phy_port,1);
   8044                 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port,1);
   8045                 if (blk < 0 && bindex < 0) {                    /* end of list */
   8046                     break;
   8047                 }
   8048                 if (blk < 0) {                                  /* empty slot */
   8049                     continue;
   8050                 }
   8051             }   
   8052         } 
   8053 #endif
   8054         blktype = SOC_BLOCK_INFO(unit, blk).type;
   8055         switch (blktype) {
   8056         case SOC_BLK_EPIC:
   8057             ctype = SOC_CTR_TYPE_FE;
   8058             break;
   8059         case SOC_BLK_GPIC:
   8060         case SOC_BLK_GPORT:
   8061         case SOC_BLK_QGPORT:
   8062         case SOC_BLK_SPORT:
   8063             ctype = SOC_CTR_TYPE_GE;
   8064             break;
   8065         case SOC_BLK_XQPORT:
   8066         case SOC_BLK_XGPORT:
   8067             if (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port)) {
   8068                 ctype = SOC_CTR_TYPE_XE;
   8069             } else {
   8070                 ctype = SOC_CTR_TYPE_GE;
   8071             }
   8072             break;
   8073         case SOC_BLK_IPIC:
   8074         case SOC_BLK_HPIC:
   8075             ctype = SOC_CTR_TYPE_HG;
   8076             break;
   8077         case SOC_BLK_XPIC:
   8078         case SOC_BLK_XPORT:
   8079         case SOC_BLK_GXPORT:
   8080         case SOC_BLK_XLPORT:
   8081         case SOC_BLK_XLPORTB0:
   8082         case SOC_BLK_XTPORT:
   8083         case SOC_BLK_CLPORT:
   8084         case SOC_BLK_MXQPORT:
   8085         case SOC_BLK_XWPORT:
   8086         case SOC_BLK_CDPORT:
   8087             if (SOC_IS_GREYHOUND(unit) && blktype == SOC_BLK_GXPORT){
   8088                 if (SOC_BLOCK_PORT(unit, blk) < 0){
   8089                     ctype = SOC_CTR_TYPE_XE;
   8090                 } else {
   8091                     /* Greyhound GE port with SOC_BLK_GXPORT case*/
   8092                     ctype = SOC_CTR_TYPE_GE;
   8093                 }
   8094             } else {
   8095                 ctype = SOC_CTR_TYPE_XE;
   8096             }
   8097 
   8098 #ifdef BCM_SABER2_SUPPORT
   8099             if (SOC_IS_SABER2(unit)) {
   8100                 if (blktype == SOC_BLK_MXQPORT) {
   8101                     ctype = SOC_CTR_TYPE_GE;
   8102                     break;
   8103                 }
   8104                 if (blktype == SOC_BLK_XLPORT) {
   8105                     ctype = SOC_CTR_TYPE_XE;
   8106                     break;
   8107                 }
   8108                 LOG_WARN(BSL_LS_SOC_COMMON,
   8109                          (BSL_META_U(unit, " UNKNOWN TYPE \n")));
   8110             }
   8111             if (SOC_IS_GREYHOUND2(unit) && blktype == SOC_BLK_CLPORT) {
   8112                 ctype = SOC_CTR_TYPE_CE; 
   8113             } 
   8114 #endif /* BCM_SABER2_SUPPORT */
   8115 #ifdef BCM_HELIX5_SUPPORT
   8116             if (SOC_IS_HELIX5(unit)) {
   8117                 if (IS_QSGMII_PORT(unit, port)) {
   8118                     ctype = SOC_CTR_TYPE_GE;
   8119                 } else {
   8120                     ctype = SOC_CTR_TYPE_XE;
   8121                 }
   8122                 if (blktype == SOC_BLK_CLPORT) {
   8123                     ctype = SOC_CTR_TYPE_CE;
   8124                 }
   8125                 break;
   8126             }
   8127 #endif
   8128 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWKPLUS_SUPPORT) || defined (BCM_TOMAHAWK2_SUPPORT) || defined (BCM_TOMAHAWK3_SUPPORT)
   8129             if ((SOC_IS_TRIDENT3X(unit)) || (SOC_IS_TOMAHAWKPLUS(unit)) ||
   8130                 (SOC_IS_TOMAHAWK2(unit)) || (SOC_IS_TOMAHAWK3(unit))) {
   8131                 if (blktype == SOC_BLK_CLPORT) {
   8132                     ctype = SOC_CTR_TYPE_CE;
   8133                     break;
   8134                 }
   8135                 if (blktype == SOC_BLK_CDPORT) {
   8136                     ctype = SOC_CTR_TYPE_CD;
   8137                     break;
   8138                 }
   8139                 if (blktype == SOC_BLK_XLPORT) {
   8140                     ctype = SOC_CTR_TYPE_XE;
   8141                     break;
   8142                 }
   8143                 LOG_WARN(BSL_LS_SOC_COMMON,
   8144                     (BSL_META_U(unit, " UNKNOWN TYPE \n")));
   8145             }
   8146 #endif 
   8147             break;
   8148         case SOC_BLK_CLG2PORT:
   8149             ctype = SOC_CTR_TYPE_CE;
   8150             break;
   8151         case SOC_BLK_CLP:
   8152         case SOC_BLK_XLP:
   8153             if (IS_IL_PORT(unit, port)) {
   8154                 continue;
   8155             } else if (IS_CE_PORT(unit, port)) {
   8156                 ctype = SOC_CTR_TYPE_CE;
   8157             } else if (IS_QSGMII_PORT(unit,port)) {
   8158                 ctype = SOC_CTR_TYPE_GE;
   8159             } else {
   8160                 ctype = SOC_CTR_TYPE_XE;
   8161             }
   8162             break;
   8163         case SOC_BLK_MXQ:
   8164             ctype = SOC_CTR_TYPE_GE;
   8165             break;
   8166         case SOC_BLK_CMIC:
   8167 #if defined(BCM_MONTEREY_SUPPORT)
   8168         case SOC_BLK_CPRI:
   8169 #endif
   8170             if (soc_feature(unit, soc_feature_cpuport_stat_dma)) {
   8171                 ctype = SOC_CTR_TYPE_CPU;
   8172                 break;
   8173             }
   8174         case SOC_BLK_CPIC:
   8175         default:
   8176             continue;
   8177         }
   8178 
   8179         if (!SOC_CONTROL(unit)->counter_map[port]) {
   8180             SOC_CONTROL(unit)->counter_map[port] =
   8181                 &SOC_CTR_DMA_MAP(unit, ctype);
   8182             assert(SOC_CONTROL(unit)->counter_map[port]);
   8183         }
   8184 
   8185 #ifdef BCM_WARM_BOOT_SUPPORT
   8186         /* Flexport operation can change port mappings.
   8187          * counter_map should be reassigned based on recovered port info
   8188          * from scache, especially for devices using multiple counter maps of
   8189          * different sizes
   8190          */
   8191         if (SOC_WARM_BOOT(unit)) {
   8192             SOC_CONTROL(unit)->counter_map[port] =
   8193                 &SOC_CTR_DMA_MAP(unit, ctype);
   8194             assert(SOC_CONTROL(unit)->counter_map[port]);
   8195         }
   8196 #endif
   8197         assert(SOC_CONTROL(unit)->counter_map[port]->cmap_base);
   8198 
   8199 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
   8200         /* We need this done in a port loop like this one, so we're
   8201          * piggybacking on it. */
   8202 
   8203         if (soc_feature(unit, soc_feature_timestamp_counter) &&
   8204             SOC_CONTROL(unit)->sw_timestamp_fifo_enable) {
   8205             /* A HW register implemented as a FIFO-pop on read is in the
   8206              * counter collection space.  We must copy the DMA'd values
   8207              * into a SW FIFO and make them available to the application
   8208              * on request.
   8209              */
   8210             if (soc->counter_timestamp_fifo[port] == NULL) {
   8211                 soc->counter_timestamp_fifo[port] =
   8212                     sal_alloc(sizeof(shr_fifo_t), "Timestamp counter FIFO");
   8213                 if (soc->counter_timestamp_fifo[port] == NULL) {
   8214                     goto error;
   8215                 }
   8216             } else {
   8217                 SHR_FIFO_FREE(soc->counter_timestamp_fifo[port]);
   8218             }
   8219             sal_memset(soc->counter_timestamp_fifo[port], 0,
   8220                        sizeof(shr_fifo_t));
   8221             SHR_FIFO_ALLOC(soc->counter_timestamp_fifo[port],
   8222                            COUNTER_TIMESTAMP_FIFO_SIZE, sizeof(uint32),
   8223                            SHR_FIFO_FLAG_DO_NOT_PUSH_DUPLICATE);
   8224         }
   8225 #endif /* BCM_TRIUMPH2_SUPPORT */
   8226     }
   8227 #ifdef BCM_SBUSDMA_SUPPORT
   8228     /* Init blk counters */
   8229     if (soc->blk_ctr_desc_count) {
   8230         uint16 ctr;
   8231         /* Calc size */
   8232         n_entries = 0;
   8233         for (idx = 0; idx < soc->blk_ctr_desc_count; idx++) {
   8234             ctr = 0;
   8235             while (soc->blk_ctr_desc[idx].desc[ctr].reg != INVALIDr) {
   8236                 n_entries += soc->blk_ctr_desc[idx].desc[ctr].entries;
   8237                 ctr++;
   8238             }
   8239         }
   8240         soc->blk_ctr_count = n_entries;
   8241         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
   8242                  (BSL_META_U(unit,
   8243                              "Total ctr blks: %d, Total entries: %d\n"),
   8244                   soc->blk_ctr_desc_count, n_entries));
   8245         if (_soc_blk_counter_handles[unit] == NULL) {
   8246             _soc_blk_counter_handles[unit] = sal_alloc(n_entries * sizeof(sbusdma_desc_handle_t),
   8247                                                  "blk_ctr_desc_handles");
   8248             if (_soc_blk_counter_handles[unit] == NULL) {
   8249                 goto error;
   8250             }
   8251         }
   8252         sal_memset(_soc_blk_counter_handles[unit], 0, n_entries * sizeof(sbusdma_desc_handle_t));
   8253 
   8254         if (soc->blk_ctr_buf == NULL) {
   8255             soc->blk_ctr_buf = soc_cm_salloc(unit, n_entries * sizeof(uint64),
   8256                                              "blk_ctr_hw_buff");
   8257             if (soc->blk_ctr_buf == NULL) {
   8258                 goto error;
   8259             }
   8260         }
   8261         sal_memset(soc->blk_ctr_buf, 0, n_entries * sizeof(uint64));
   8262 
   8263         if (soc->blk_counter_hw_val == NULL) {
   8264             soc->blk_counter_hw_val = sal_alloc(n_entries * sizeof(uint64),
   8265                                                 "blk_ctr_hw_vals");
   8266             if (soc->blk_counter_hw_val == NULL) {
   8267                 goto error;
   8268             }
   8269         }
   8270         sal_memset(soc->blk_counter_hw_val, 0, n_entries * sizeof(uint64));
   8271 
   8272         if (soc->blk_counter_sw_val == NULL) {
   8273             soc->blk_counter_sw_val = sal_alloc(n_entries * sizeof(uint64),
   8274                                                 "blk_ctr_sw_vals");
   8275             if (soc->blk_counter_sw_val == NULL) {
   8276                 goto error;
   8277             }
   8278         }
   8279         sal_memset(soc->blk_counter_sw_val, 0, n_entries * sizeof(uint64));
   8280     }
   8281 #endif
   8282     return SOC_E_NONE;
   8283 
   8284  error:
   8285 
   8286 #ifdef BCM_SBUSDMA_SUPPORT
   8287     if (soc->blk_counter_sw_val != NULL) {
   8288         sal_free(soc->blk_counter_sw_val);
   8289         soc->blk_counter_sw_val = NULL;
   8290     }
   8291 
   8292     if (soc->blk_counter_hw_val != NULL) {
   8293         sal_free(soc->blk_counter_hw_val);
   8294         soc->blk_counter_hw_val = NULL;
   8295     }
   8296 
   8297     if (soc->blk_ctr_buf != NULL) {
   8298         soc_cm_sfree(unit, soc->blk_ctr_buf);
   8299         soc->blk_ctr_buf = NULL;
   8300     }
   8301 
   8302     if (_soc_blk_counter_handles[unit] != NULL) {
   8303         sal_free(_soc_blk_counter_handles[unit]);
   8304         _soc_blk_counter_handles[unit] = NULL;
   8305     }
   8306 #endif
   8307 
   8308 #ifdef BCM_TRIUMPH2_SUPPORT
   8309     for (port = 0; port < SOC_MAX_NUM_PORTS; port++) {
   8310         if (soc->counter_timestamp_fifo[port] != NULL) {
   8311             SHR_FIFO_FREE(soc->counter_timestamp_fifo[port]);
   8312             sal_free(soc->counter_timestamp_fifo[port]);
   8313             soc->counter_timestamp_fifo[port] = NULL;
   8314         }
   8315     }
   8316 #endif /* BCM_TRIUMPH2_SUPPORT */
   8317 
   8318     if (soc->counter_evict != NULL) {
   8319         sal_free(soc->counter_evict);
   8320         soc->counter_evict = NULL;
   8321     }
   8322 
   8323     if (soc->counter_non_dma != NULL) {
   8324         for (idx = 0;
   8325              idx < SOC_COUNTER_NON_DMA_END - SOC_COUNTER_NON_DMA_START;
   8326              idx++) {
   8327             if (soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_ALLOC) {
   8328                 soc_cm_sfree(unit, soc->counter_non_dma[idx].dma_buf[0]);
   8329             }
   8330 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   8331             if((soc->counter_non_dma[idx].extra_ctrs != NULL) &&
   8332                ((soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_DO_DMA) ||
   8333                 (soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_OBM))){
   8334                 for(ct = 0; ct < soc->counter_non_dma[idx].extra_ctr_ct; ct++) {
   8335                     if((soc->counter_non_dma[idx].extra_ctrs[ct*2].cname != NULL) &&
   8336                        (soc->counter_non_dma[idx].extra_ctrs[ct*2].cname[0] == '*')){
   8337                         sal_free(soc->counter_non_dma[idx].extra_ctrs[ct*2].cname);
   8338                         soc->counter_non_dma[idx].extra_ctrs[ct*2].cname = NULL;
   8339                     }
   8340 
   8341                     if((soc->counter_non_dma[idx].extra_ctrs[ct*2+1].cname != NULL) &&
   8342                        (soc->counter_non_dma[idx].extra_ctrs[ct*2+1].cname[0] == '*')){
   8343                         sal_free(soc->counter_non_dma[idx].extra_ctrs[ct*2+1].cname);
   8344                         soc->counter_non_dma[idx].extra_ctrs[ct*2+1].cname = NULL;
   8345                     }
   8346                 }
   8347 
   8348                 sal_free(soc->counter_non_dma[idx].extra_ctrs);
   8349                 soc->counter_non_dma[idx].extra_ctrs = NULL;
   8350                 if((soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_OBM) &&
   8351                    (soc->counter_non_dma[idx].id != SOC_COUNTER_NON_DMA_PORT_OBM_FC_EVENTS)) {
   8352                     soc->counter_non_dma[idx+1].extra_ctrs = NULL;
   8353                 }
   8354             }
   8355 #endif /* BCM_TOMAHAWK_SUPPORT */
   8356         }
   8357         sal_free(soc->counter_non_dma);
   8358         soc->counter_non_dma = NULL;
   8359     }
   8360 
   8361     if (soc->counter_buf32 != NULL) {
   8362         soc_cm_sfree(unit, soc->counter_buf32);
   8363         soc->counter_buf32 = NULL;
   8364         soc->counter_buf64 = NULL;
   8365     }
   8366 
   8367     if (soc->counter_hw_val != NULL) {
   8368         sal_free(soc->counter_hw_val);
   8369         soc->counter_hw_val = NULL;
   8370     }
   8371 
   8372     if (soc->counter_sw_val != NULL) {
   8373         sal_free(soc->counter_sw_val);
   8374         soc->counter_sw_val = NULL;
   8375     }
   8376 
   8377     if (soc->counter_delta != NULL) {
   8378         sal_free(soc->counter_delta);
   8379         soc->counter_delta = NULL;
   8380     }
   8381 
   8382     return SOC_E_MEMORY;
   8383 }
   8384 
   8385 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   8386 int
   8387 _soc_counter_trident2p_non_dma_pbmp_update(int unit)
   8388 {
   8389     int id, i;
   8390     soc_control_t *soc = SOC_CONTROL(unit);
   8391     soc_counter_non_dma_t *non_dma;
   8392     int soc_counter_non_dma1[] = {
   8393         SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT, /* MC_PERQ_PKT   */
   8394         SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE, /* MC_PERQ_BYTE  */
   8395         SOC_COUNTER_NON_DMA_COSQ_DROP_PKT, /* MCQ_DROP_PKT  */
   8396         SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE, /* MCQ_DROP_BYTE */
   8397         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING, /* DROP_PKT_ING  */
   8398         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING, /* DROP_BYTE_ING */
   8399         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER, /* DROP_PKT_IMTR */
   8400         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER, /* DROP_BYTE_IMTR */
   8401         SOC_COUNTER_NON_DMA_DROP_RQ_PKT, /* RQ_DROP_PKT */
   8402         SOC_COUNTER_NON_DMA_DROP_RQ_BYTE, /* RQ_DROP_BYTE */
   8403         SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW, /* RQ_DROP_PKT_YEL */
   8404         SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED, /* RQ_DROP_PKT_RED */
   8405         SOC_COUNTER_NON_DMA_PG_MIN_PEAK, /* PG_MIN_PEAK */
   8406         SOC_COUNTER_NON_DMA_PG_MIN_CURRENT, /* PG_MIN_CUR */
   8407         SOC_COUNTER_NON_DMA_PG_SHARED_PEAK, /* PG_SHARED_PEAK */
   8408         SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT, /* PG_SHARED_CUR */
   8409         SOC_COUNTER_NON_DMA_PG_HDRM_PEAK, /* PG_HDRM_PEAK */
   8410         SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT, /* PG_HDRM_CUR */
   8411         SOC_COUNTER_NON_DMA_QUEUE_PEAK, /* QUEUE_PEAK */
   8412         SOC_COUNTER_NON_DMA_QUEUE_CURRENT /* QUEUE_CUR */
   8413     };
   8414 
   8415     int soc_counter_non_dma2[] = {
   8416         SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC, /* UC_PERQ_PKT */
   8417         SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC, /* UC_PERQ_BYTE */
   8418         SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC, /* UCQ_DROP_PKT */
   8419         SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC, /* UCQ_DROP_BYTE */
   8420         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW, /* DROP_PKT_YEL */
   8421         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED, /* DROP_PKT_RED */
   8422         SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN, /* WRED_PKT_GRE */
   8423         SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW, /* WRED_PKT_YEL */
   8424         SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED, /* WRED_PKT_RED */
   8425         SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK, /* UC_QUEUE_PEAK */
   8426         SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT, /* UC_QUEUE_CUR */
   8427         SOC_COUNTER_NON_DMA_MMU_QCN_CNM, /* QCN_CNM_COUNTER */
   8428         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_HIGH_PRI, /* OBM0_HIGH_PRI_DROP_PKT */
   8429         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_LOW_PRI, /* OBM0_LOW_PRI_DROP_PKT */
   8430         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_HIGH_PRI, /* OBM0_HIGH_PRI_DROP_BYTE */
   8431         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_LOW_PRI, /* OBM0_LOW_PRI_DROP_BYTE */
   8432         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_HIGH_PRI, /* OBM1_HIGH_PRI_DROP_PKT */
   8433         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_LOW_PRI, /* OBM1_LOW_PRI_DROP_PKT */
   8434         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_HIGH_PRI, /* OBM1_HIGH_PRI_DROP_BYTE */
   8435         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_LOW_PRI, /* OBM1_LOW_PRI_DROP_BYTE */
   8436         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_HIGH_PRI, /* OBM2_HIGH_PRI_DROP_PKT */
   8437         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_LOW_PRI, /* OBM2_LOW_PRI_DROP_PKT */
   8438         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_HIGH_PRI, /* OBM2_HIGH_PRI_DROP_BYTE */
   8439         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_LOW_PRI, /* OBM2_LOW_PRI_DROP_BYTE */
   8440         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_HIGH_PRI, /* OBM3_HIGH_PRI_DROP_PKT */
   8441         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_LOW_PRI, /* OBM3_LOW_PRI_DROP_PKT */
   8442         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_HIGH_PRI, /* OBM3_HIGH_PRI_DROP_BYTE */
   8443         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_LOW_PRI /* OBM3_LOW_PRI_DROP_BYTE */
   8444     };
   8445 
   8446     for (i = 0; i < sizeof(soc_counter_non_dma1)/sizeof(int); ++i) {
   8447         id = soc_counter_non_dma1[i];
   8448         non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
   8449         non_dma->pbmp = PBMP_ALL(unit);
   8450     }
   8451 
   8452     for (i = 0; i < sizeof(soc_counter_non_dma2)/sizeof(int); ++i) {
   8453         id = soc_counter_non_dma2[i];
   8454         non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
   8455         non_dma->pbmp = PBMP_PORT_ALL(unit);
   8456     }
   8457 
   8458     return SOC_E_NONE;
   8459 }
   8460 #endif /* defined(BCM_TRIDENT2PLUS_SUPPORT) */
   8461 
   8462 #if defined (BCM_APACHE_SUPPORT)
   8463 int
   8464 _soc_counter_apache_non_dma_pbmp_update(int unit)
   8465 {
   8466     int id, i;
   8467     soc_control_t *soc = SOC_CONTROL(unit);
   8468     soc_counter_non_dma_t *non_dma;
   8469     int soc_counter_non_dma1[] = {
   8470         SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT, /* MC_PERQ_PKT   */
   8471         SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE, /* MC_PERQ_BYTE  */
   8472         SOC_COUNTER_NON_DMA_COSQ_DROP_PKT, /* MCQ_DROP_PKT  */
   8473         SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE, /* MCQ_DROP_BYTE */
   8474         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING, /* DROP_PKT_ING  */
   8475         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING, /* DROP_BYTE_ING */
   8476         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER, /* DROP_PKT_IMTR */
   8477         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER, /* DROP_BYTE_IMTR */
   8478         SOC_COUNTER_NON_DMA_PG_MIN_PEAK, /* PG_MIN_PEAK */
   8479         SOC_COUNTER_NON_DMA_PG_MIN_CURRENT, /* PG_MIN_CUR */
   8480         SOC_COUNTER_NON_DMA_PG_SHARED_PEAK, /* PG_SHARED_PEAK */
   8481         SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT, /* PG_SHARED_CUR */
   8482         SOC_COUNTER_NON_DMA_PG_HDRM_PEAK, /* PG_HDRM_PEAK */
   8483         SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT, /* PG_HDRM_CUR */
   8484         SOC_COUNTER_NON_DMA_QUEUE_PEAK, /* QUEUE_PEAK */
   8485         SOC_COUNTER_NON_DMA_QUEUE_CURRENT /* QUEUE_CUR */
   8486     };
   8487 
   8488     int soc_counter_non_dma2[] = {
   8489         SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC, /* UC_PERQ_PKT */
   8490         SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC, /* UC_PERQ_BYTE */
   8491         SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC, /* UCQ_DROP_PKT */
   8492         SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC, /* UCQ_DROP_BYTE */
   8493         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW, /* DROP_PKT_YEL */
   8494         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED, /* DROP_PKT_RED */
   8495         SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN, /* WRED_PKT_GRE */
   8496         SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW, /* WRED_PKT_YEL */
   8497         SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED, /* WRED_PKT_RED */
   8498         SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK, /* UC_QUEUE_PEAK */
   8499         SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT, /* UC_QUEUE_CUR */
   8500         SOC_COUNTER_NON_DMA_MMU_QCN_CNM, /* QCN_CNM_COUNTER */
   8501         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO, /* OBM_LOSSY_LO_DRP_PKT */
   8502         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO, /* OBM_LOSSY_LO_DRP_BYTE */
   8503         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI, /* OBM_LOSSY_HI_DRP_PKT */
   8504         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI, /* OBM_LOSSY_HI_DRP_BYTE */
   8505         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0, /* OBM_LOSSLESS0_DRP_PKT */
   8506         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0, /* OBM_LOSSLESS0_DRP_BYTE */
   8507         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1, /* OBM_LOSSLESS1_DRP_PKT */
   8508         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1, /* OBM_LOSSLESS1_DRP_BYTE */
   8509         SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS, /* OBM_EXPRESS_DRP_PKT */
   8510         SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS, /* OBM_EXPRESS_DRP_BYTE */
   8511         SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO, /* OBM_LOSSY_LO_ENQ_PKT */
   8512         SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO, /* OBM_LOSSY_LO_ENQ_BYTE */
   8513         SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI, /* OBM_LOSSY_HI_ENQ_PKT */
   8514         SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI, /* OBM_LOSSY_HI_ENQ_BYTE */
   8515         SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0, /* OBM_LOSSLESS0_ENQ_PKT */
   8516         SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0, /* OBM_LOSSLESS0_ENQ_BYTE */
   8517         SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1, /* OBM_LOSSLESS1_ENQ_PKT */
   8518         SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1, /* OBM_LOSSLESS0_ENQ_BYTE */
   8519         SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS, /* OBM_EXPRESS_ENQ_PKT */
   8520         SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS /* OBM_EXPRESS_ENQ_BYTE */
   8521     };
   8522 
   8523     for (i = 0; i < sizeof(soc_counter_non_dma1)/sizeof(int); ++i) {
   8524         id = soc_counter_non_dma1[i];
   8525         non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
   8526         non_dma->pbmp = PBMP_ALL(unit);
   8527     }
   8528 
   8529     for (i = 0; i < sizeof(soc_counter_non_dma2)/sizeof(int); ++i) {
   8530         id = soc_counter_non_dma2[i];
   8531         non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
   8532         non_dma->pbmp = PBMP_PORT_ALL(unit);
   8533     }
   8534 
   8535     return SOC_E_NONE;
   8536 }
   8537 #endif /* BCM_APACHE_SUPPORT */
   8538 
   8539 /*
   8540  * Function:
   8541  *      soc_counter_non_dma_pbmp_update
   8542  * Purpose:
   8543  *      Update non_dma->pbmp
   8544  * Notes:
   8545  */
   8546 int
   8547 soc_counter_non_dma_pbmp_update(int unit)
   8548 {
   8549 #ifdef BCM_APACHE_SUPPORT
   8550     if (SOC_IS_APACHE(unit)) {
   8551         SOC_IF_ERROR_RETURN(_soc_counter_apache_non_dma_pbmp_update(unit));
   8552     }
   8553 #endif /* BCM_APACHE_SUPPORT */
   8554 #if defined ( BCM_TRIDENT2PLUS_SUPPORT )
   8555     if (SOC_IS_TD2P_TT2P(unit)) {
   8556         SOC_IF_ERROR_RETURN(_soc_counter_trident2p_non_dma_pbmp_update(unit));
   8557     }
   8558 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   8559 
   8560     return SOC_E_NONE;
   8561 }
   8562 
   8563 /*
   8564  * Function:
   8565  *      soc_port_cmap_get/set
   8566  * Purpose:
   8567  *      Access the counter map structure per port
   8568  */
   8569 
   8570 soc_cmap_t *
   8571 soc_port_cmap_get(int unit, soc_port_t port)
   8572 {
   8573     if (!SOC_UNIT_VALID(unit)) {
   8574         return NULL;
   8575     }
   8576     if (!SOC_IS_KATANA2(unit)) {
   8577         if (!SOC_PORT_VALID(unit, port) ||
   8578             (!IS_PORT(unit, port) &&
   8579              (!soc_feature(unit, soc_feature_cpuport_stat_dma)))) {
   8580             return NULL;
   8581         }
   8582     }
   8583     return SOC_CONTROL(unit)->counter_map[port];
   8584 }
   8585 
   8586 int
   8587 soc_port_cmap_set(int unit, soc_port_t port, soc_ctr_type_t ctype)
   8588 {
   8589     if (!SOC_UNIT_VALID(unit)) {
   8590         return SOC_E_UNIT;
   8591     }
   8592     if (!SOC_IS_KATANA2(unit)) {
   8593         if (!SOC_PORT_VALID(unit, port) ||
   8594             (!IS_PORT(unit, port) &&
   8595              (!soc_feature(unit, soc_feature_cpuport_stat_dma)))) {
   8596             return SOC_E_PARAM;
   8597         }
   8598     }
   8599     SOC_CONTROL(unit)->counter_map[port] = &SOC_CTR_DMA_MAP(unit, ctype);
   8600     return SOC_E_NONE;
   8601 }
   8602 
   8603 /*
   8604  * Function:
   8605  *      soc_counter_detach
   8606  * Purpose:
   8607  *      Finalize counter module.
   8608  * Notes:
   8609  *      Stops counter task if running.
   8610  *      Deallocates counter collection buffers.
   8611  */
   8612 
   8613 int
   8614 soc_counter_detach(int unit)
   8615 {
   8616     soc_control_t       *soc;
   8617     int                 i;
   8618 #ifdef BCM_TRIUMPH2_SUPPORT
   8619     soc_port_t          port;
   8620 #endif /* BCM_TRIUMPH2_SUPPORT */
   8621 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   8622     int                   ct;
   8623 #endif /* BCM_TOMAHAWK_SUPPORT */
   8624     soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit);
   8625 
   8626     assert(SOC_UNIT_VALID(unit));
   8627 
   8628     /*
   8629      * COVERITY
   8630      *
   8631      * assert validates the input
   8632      */
   8633     /* coverity[overrun-local : FALSE] */
   8634     soc = SOC_CONTROL(unit);
   8635 
   8636     /*
   8637      * COVERITY
   8638      *
   8639      * assert validates the input
   8640      */
   8641     /* coverity[overrun-local : FALSE] */
   8642     SOC_IF_ERROR_RETURN(soc_counter_stop(unit));
   8643 
   8644 #ifdef BCM_TRIUMPH2_SUPPORT
   8645     for (port = 0; port < SOC_MAX_NUM_PORTS; port++) {
   8646         if (soc->counter_timestamp_fifo[port] != NULL) {
   8647             SHR_FIFO_FREE(soc->counter_timestamp_fifo[port]);
   8648             sal_free(soc->counter_timestamp_fifo[port]);
   8649             soc->counter_timestamp_fifo[port] = NULL;
   8650         }
   8651     }
   8652 #endif /* BCM_TRIUMPH2_SUPPORT */
   8653 
   8654     if (soc->counter_evict != NULL) {
   8655         sal_free(soc->counter_evict);
   8656         soc->counter_evict = NULL;
   8657     }
   8658 
   8659     if (soc_ctr_ctrl != NULL) {
   8660         sal_free(soc_ctr_ctrl);
   8661         SOC_CTR_CTRL(unit) = NULL;
   8662     }
   8663 
   8664     if (soc->counter_non_dma != NULL) {
   8665         for (i = 0; i < SOC_COUNTER_NON_DMA_END - SOC_COUNTER_NON_DMA_START;
   8666              i++) {
   8667             if (soc->counter_non_dma[i].flags & _SOC_COUNTER_NON_DMA_ALLOC) {
   8668                 soc_cm_sfree(unit, soc->counter_non_dma[i].dma_buf[0]);
   8669             }
   8670 
   8671 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   8672             if((soc->counter_non_dma[i].extra_ctrs != NULL) &&
   8673                ((soc->counter_non_dma[i].flags & _SOC_COUNTER_NON_DMA_DO_DMA) ||
   8674                 (soc->counter_non_dma[i].flags & _SOC_COUNTER_NON_DMA_OBM))){
   8675                 for(ct = 0; ct < soc->counter_non_dma[i].extra_ctr_ct; ct++) {
   8676                     if((soc->counter_non_dma[i].extra_ctrs[ct*2].cname != NULL) &&
   8677                        (soc->counter_non_dma[i].extra_ctrs[ct*2].cname[0] == '*')){
   8678                         sal_free(soc->counter_non_dma[i].extra_ctrs[ct*2].cname);
   8679                         soc->counter_non_dma[i].extra_ctrs[ct*2].cname = NULL;
   8680                     }
   8681 
   8682                     if((soc->counter_non_dma[i].extra_ctrs[ct*2+1].cname != NULL) &&
   8683                        (soc->counter_non_dma[i].extra_ctrs[ct*2+1].cname[0] == '*')){
   8684                         sal_free(soc->counter_non_dma[i].extra_ctrs[ct*2+1].cname);
   8685                         soc->counter_non_dma[i].extra_ctrs[ct*2+1].cname = NULL;
   8686                     }
   8687                 }
   8688 
   8689                 sal_free(soc->counter_non_dma[i].extra_ctrs);
   8690                 soc->counter_non_dma[i].extra_ctrs = NULL;
   8691                 if((soc->counter_non_dma[i].flags & _SOC_COUNTER_NON_DMA_OBM) &&
   8692                    (soc->counter_non_dma[i].id != SOC_COUNTER_NON_DMA_PORT_OBM_FC_EVENTS)) {
   8693                     soc->counter_non_dma[i+1].extra_ctrs = NULL;
   8694                 }
   8695             }
   8696 #endif /* BCM_TOMAHAWK_SUPPORT */
   8697         }
   8698         sal_free(soc->counter_non_dma);
   8699         soc->counter_non_dma = NULL;
   8700     }
   8701 
   8702     if (soc->counter_buf32 != NULL) {
   8703         soc_cm_sfree(unit, soc->counter_buf32);
   8704         soc->counter_buf32 = NULL;
   8705         soc->counter_buf64 = NULL;
   8706     }
   8707 
   8708     if (soc->counter_hw_val != NULL) {
   8709         sal_free(soc->counter_hw_val);
   8710         soc->counter_hw_val = NULL;
   8711     }
   8712 
   8713     if (soc->counter_sw_val != NULL) {
   8714         sal_free(soc->counter_sw_val);
   8715         soc->counter_sw_val = NULL;
   8716     }
   8717 
   8718     if (soc->counter_delta != NULL) {
   8719         sal_free(soc->counter_delta);
   8720         soc->counter_delta = NULL;
   8721     }
   8722 
   8723 #ifdef BCM_SBUSDMA_SUPPORT
   8724     if (_soc_blk_counter_handles[unit] != NULL) {
   8725         sal_free(_soc_blk_counter_handles[unit]);
   8726         _soc_blk_counter_handles[unit] = NULL;
   8727     }
   8728 
   8729     if (soc->blk_ctr_buf != NULL) {
   8730         soc_cm_sfree(unit, soc->blk_ctr_buf);
   8731         soc->blk_ctr_buf = NULL;
   8732     }
   8733 
   8734     if (soc->blk_counter_hw_val != NULL) {
   8735         sal_free(soc->blk_counter_hw_val);
   8736         soc->blk_counter_hw_val = NULL;
   8737     }
   8738 
   8739     if (soc->blk_counter_sw_val != NULL) {
   8740         sal_free(soc->blk_counter_sw_val);
   8741         soc->blk_counter_sw_val = NULL;
   8742     }
   8743 
   8744     _soc_counter_pending[unit] = 0;
   8745 #endif
   8746     return SOC_E_NONE;
   8747 }
   8748 
   8749 /*
   8750  * StrataSwitch counter register map
   8751  *
   8752  * NOTE: soc_attach verifies this map is correct and prints warnings if
   8753  * not.  The map should contain only registers with a single field named
   8754  * COUNT, and all such registers should be in the map.
   8755  *
   8756  * The soc_counter_map[] array is a list of counter registers in the
   8757  * order found in the internal address map and counter DMA buffer.
   8758  * soc_counter_map[0] corresponds to S-Channel address
   8759  * COUNTER_OFF_MIN, and contains SOC_CTR_MAP_SIZE(unit) entries.
   8760  *
   8761  * This map structure, contents, and size are exposed only to provide a
   8762  * convenient way to loop through all available counters.
   8763  *
   8764  * Accumulated counters are stored as 64-bit values and may be written
   8765  * and read by multiple tasks on a 32-bit processor.  This requires
   8766  * atomic operation to get correct values.  Also, to fetch-and-clear a
   8767  * counter requires atomic operation.
   8768  *
   8769  * These atomic operations are very brief, so rather than using an
   8770  * inefficient mutex we use splhi to lock out interrupts and task
   8771  * switches.  In theory, splhi is only a few instructions on most
   8772  * processors.
   8773  */
   8774 
   8775 #define COUNTER_ATOMIC_DEF soc_control_t *
   8776 #define COUNTER_ATOMIC_BEGIN(_soc) \
   8777     do { \
   8778         if ((_soc) && (_soc)->counter_lock) { \
   8779             sal_spinlock_lock((_soc)->counter_lock); \
   8780         } \
   8781     } while (0)
   8782 #define COUNTER_ATOMIC_END(_soc) \
   8783     do { \
   8784         if ((_soc) && (_soc)->counter_lock) { \
   8785             sal_spinlock_unlock((_soc)->counter_lock); \
   8786         } \
   8787     } while (0)
   8788 
   8789 #ifdef BROADCOM_DEBUG
   8790 
   8791 char *soc_ctr_type_names[] = SOC_CTR_TYPE_NAMES_INITIALIZER;
   8792 
   8793 /*
   8794  * Function:
   8795  *      _soc_counter_verify (internal)
   8796  * Purpose:
   8797  *      Verify contents of soc_counter_map[] array
   8798  */
   8799 void
   8800 _soc_counter_verify(int unit)
   8801 {
   8802     int                 i, errors, num_ctrs, found;
   8803     soc_ctr_type_t      ctype;
   8804     soc_reg_t           reg;
   8805     int                 ar_idx;
   8806     uint32              skip_offset = 0;
   8807 
   8808     LOG_DEBUG(BSL_LS_SOC_COMMON,
   8809                 (BSL_META_U(unit,
   8810                             "soc_counter_verify: unit %d begins\n"), unit));
   8811     errors = 0;
   8812     if (SOC_IS_TRIUMPH3(unit)) {
   8813         skip_offset = 32;
   8814     }
   8815 #if defined(BCM_HURRICANE2_SUPPORT)
   8816     if (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit) || \
   8817         SOC_IS_GREYHOUND(unit)) {
   8818         skip_offset = 55;
   8819     }
   8820 #endif
   8821 
   8822 #ifdef BCM_GREYHOUND2_SUPPORT
   8823     if (SOC_IS_GREYHOUND2(unit)) {
   8824         skip_offset = 111;
   8825     }
   8826 #endif /* BCM_GREYHOUND2_SUPPORT */
   8827 
   8828     for (ctype = SOC_CTR_TYPE_FE; ctype < SOC_CTR_NUM_TYPES; ctype++) {
   8829         if (SOC_HAS_CTR_TYPE(unit, ctype)) {
   8830             num_ctrs = SOC_CTR_MAP_SIZE(unit, ctype);
   8831             for (i = 0; i < num_ctrs; i++) {
   8832                 reg = SOC_CTR_TO_REG(unit, ctype, i);
   8833                 ar_idx = SOC_CTR_TO_REG_IDX(unit, ctype, i);
   8834                 if (SOC_COUNTER_INVALID(unit, reg)) {
   8835                     continue;
   8836                 }
   8837                 if (reg >= SOC_COUNTER_TABLE_FIELD_START) {
   8838                     continue; 
   8839                 };
   8840                 if (!SOC_REG_IS_COUNTER(unit, reg)) {
   8841                     LOG_DEBUG(BSL_LS_SOC_COMMON,
   8842                                 (BSL_META_U(unit,
   8843                                             "soc_counter_verify: "
   8844                                             "%s cntr %s (%d) index %d "
   8845                                             "is not a counter\n"),
   8846                                  soc_ctr_type_names[ctype],
   8847                                  SOC_REG_NAME(unit, reg), reg, i));
   8848                     errors = 1;
   8849                 }
   8850                 if (((SOC_REG_CTR_IDX(unit, reg) + ar_idx) -
   8851                      COUNTER_IDX_OFFSET(unit) - skip_offset)
   8852                     != i) {
   8853                     LOG_DEBUG(BSL_LS_SOC_COMMON,
   8854                                 (BSL_META_U(unit,
   8855                                             "soc_counter_verify: "
   8856                                             "%s cntr %s (%d) index mismatch.\n"
   8857                                             "    (ctr_idx %d + ar_idx %d) - offset %d != "
   8858                                             "index in ctr array %d\n"),
   8859                                  soc_ctr_type_names[ctype],
   8860                                  SOC_REG_NAME(unit, reg), reg,
   8861                                  SOC_REG_CTR_IDX(unit, reg),
   8862                                  ar_idx,
   8863                                  COUNTER_IDX_OFFSET(unit),
   8864                                  i));
   8865                     errors = 1;
   8866                 }
   8867             }
   8868         }
   8869     }
   8870 
   8871     for (reg = 0; reg < NUM_SOC_REG; reg++) {
   8872         if (SOC_REG_IS_VALID(unit, reg) && SOC_REG_IS_COUNTER(unit, reg)) {
   8873             found = FALSE;
   8874             i = -1;
   8875             for (ctype = SOC_CTR_TYPE_FE; ctype < SOC_CTR_NUM_TYPES; ctype++) {
   8876                 if (SOC_HAS_CTR_TYPE(unit, ctype)) {
   8877                     num_ctrs = SOC_CTR_MAP_SIZE(unit, ctype);
   8878                     for (i = 0; i < num_ctrs; i++) {
   8879                         if (SOC_CTR_TO_REG(unit, ctype, i) == reg) {
   8880                             if ((SOC_REG_CTR_IDX(unit, reg) -
   8881                                  COUNTER_IDX_OFFSET(unit) - skip_offset) != i) {
   8882                                 LOG_DEBUG(BSL_LS_SOC_COMMON,
   8883                                             (BSL_META_U(unit,
   8884                                                         "soc_counter_verify: "
   8885                                                         "%s cntr %s (%d) index mismatch.\n"
   8886                                                         "    (ctr_idx %d - offset %d) != "
   8887                                                         "index in ctr array %d\n"),
   8888                                              soc_ctr_type_names[ctype],
   8889                                              SOC_REG_NAME(unit, reg), reg,
   8890                                              SOC_REG_CTR_IDX(unit, reg),
   8891                                              COUNTER_IDX_OFFSET(unit),
   8892                                              i));
   8893                                 errors = 1;
   8894                             }
   8895                             found = TRUE;
   8896                             break;
   8897                         }
   8898                     }
   8899                 }
   8900                 if (found) {
   8901                     break;
   8902                 }
   8903             }
   8904 
   8905 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA_SUPPORT)
   8906             if(SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit) || 
   8907                 SOC_IS_HURRICANE2(unit) || SOC_IS_KATANAX(unit)) {
   8908                 /* OAM_SEC_NS_COUNTER_64 is a general purpose counter
   8909                    which counts time for entire chip */
   8910                 if ((!found) && (OAM_SEC_NS_COUNTER_64r == reg)) {
   8911                     found = TRUE;
   8912                 }
   8913             }
   8914 #endif
   8915 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
   8916             if(SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit) || \
   8917                SOC_IS_GREYHOUND2(unit)) {
   8918                 if( (!found) && (
   8919                     (HOLD_COS0r == reg) ||
   8920                     (HOLD_COS1r == reg) ||
   8921                     (HOLD_COS2r == reg) ||
   8922                     (HOLD_COS3r == reg) ||
   8923                     (HOLD_COS4r == reg) ||
   8924                     (HOLD_COS5r == reg) ||
   8925                     (HOLD_COS6r == reg) ||
   8926                     (HOLD_COS7r == reg) ) ) {
   8927                     found = TRUE;
   8928                 }
   8929             }
   8930 #endif
   8931 #ifdef BCM_KATANA2_SUPPORT
   8932             if (SOC_IS_KATANA2(unit)) {
   8933                 if ((!found) && (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_RXLP))) {
   8934                     found = TRUE;
   8935                 }
   8936             }
   8937 #endif
   8938             /*  Few RTS registers are marked as counters.. (ISCOUNTER => 1) */
   8939             if (SOC_IS_APACHE(unit)) {
   8940                 if ((!found) &&
   8941                     (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_IPROC))) {
   8942                     found = TRUE;
   8943                 }
   8944             }
   8945 
   8946 #ifdef BCM_MONTEREY_SUPPORT
   8947             if (SOC_IS_MONTEREY(unit)) {
   8948                 if ((!found) &&
   8949                     (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CPRI))) {
   8950                     found = TRUE;
   8951                 }
   8952             }
   8953 #endif
   8954 
   8955 /* Workaround for SDK-130624. Remove this block after ARCHTH3-423 
   8956    is resolved and integrated */
   8957 #ifdef BCM_TOMAHAWK3_SUPPORT
   8958             if (SOC_IS_TOMAHAWK3(unit)) {
   8959                 if (!found) {
   8960                     switch (reg) {
   8961                         case CPU_MASQUERADE_COUNTER_DEST_TYPEr:
   8962                         case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE0r:
   8963                         case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE1r:
   8964                         case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE2r:
   8965                         case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE3r:
   8966                         case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE4r:
   8967                         case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE5r:
   8968                         case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE6r:
   8969                         case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE7r:
   8970                         case IS_PKSCH_PKT_CREDITS_PER_PIPEr:
   8971                         case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE0r:
   8972                         case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE1r:
   8973                         case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE2r:
   8974                         case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE3r:
   8975                         case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE4r:
   8976                         case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE5r:
   8977                         case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE6r:
   8978                         case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE7r:
   8979                         case MMU_CRB_CREDIT_DROP_PKT_COUNTr:
   8980                         case MMU_CRB_INVALID_DESTINATION_PKT_COUNTr:
   8981                         case MMU_CRB_PKT_DROP_CNTR_STATr:
   8982                         case MMU_EBCFG_ECC_SINGLE_BIT_ERRORSr:
   8983                         case MMU_EBCFG_MEM_FAIL_INT_CTRr:
   8984                         case MMU_EBCTM_BURST_CTRL_STSr:
   8985                         case MMU_EBCTM_CT_FSM_STSr:
   8986                         case MMU_EBPTS_EDB_CREDIT_COUNTERr:
   8987                         case MMU_EBPTS_PKSCH_PKT_CREDITS_PER_PIPEr:
   8988                         case MMU_GLBCFG_ECC_SINGLE_BIT_ERRORSr:
   8989                         case MMU_GLBCFG_MEM_FAIL_INT_CTRr:
   8990                         case MMU_INTFO_OOBFC_MSG_TX_CNTr:
   8991                         case MMU_ITMCFG_ECC_SINGLE_BIT_ERRORSr:
   8992                         case MMU_ITMCFG_MEM_FAIL_INT_CTRr:
   8993                         case MMU_PTSCH_EB_CREDIT_CONFIGr:
   8994                         case MMU_RL_DEBUG_PKT_CNTr:
   8995                             found = TRUE;
   8996                             break;
   8997                         default:
   8998                             break;
   8999                     }
   9000 
   9001                 }
   9002             }
   9003 #endif /* BCM_TOMAHAWK3_SUPPORT */
   9004 
   9005             if (!found) {
   9006                 LOG_DEBUG(BSL_LS_SOC_COMMON,
   9007                             (BSL_META_U(unit,
   9008                                         "soc_counter_verify: "
   9009                                         "counter %d %s is missing (i=%d, 0x%x)\n"),
   9010                              (int)reg, SOC_REG_NAME(unit, reg), i, i));
   9011                 errors = 1;
   9012             }
   9013         }
   9014     }
   9015 
   9016     if (errors) {
   9017         LOG_CLI((BSL_META_U(unit,
   9018                             "\nERRORS found during counter initialization.  "
   9019                             "Set debug verbose for more info.\n\n")));
   9020     }
   9021 
   9022     LOG_DEBUG(BSL_LS_SOC_COMMON,
   9023                 (BSL_META_U(unit,
   9024                             "soc_counter_verify: unit %d ends\n"), unit));
   9025 }
   9026 
   9027 /*
   9028  * Function:
   9029  *      _soc_counter_illegal
   9030  * Purpose:
   9031  *      Routine to display info about bad counter and halt.
   9032  */
   9033 
   9034 void
   9035 _soc_counter_illegal(int unit, soc_reg_t ctr_reg)
   9036 {
   9037     LOG_CLI((BSL_META_U(unit,
   9038                         "soc_counter_get: unit %d: "
   9039                         "ctr_reg %d (%s) is not a counter\n"),
   9040              unit, ctr_reg, SOC_REG_NAME(unit, ctr_reg)));
   9041     /* assert(0); */
   9042 }
   9043 
   9044 #endif /* BROADCOM_DEBUG */
   9045 
   9046 #ifdef BCM_TOMAHAWK_SUPPORT
   9047 extern uint32 soc_mem_fifo_delay_value;
   9048 
   9049 
   9050 STATIC void
   9051 _soc_counter_fifo_process(int unit, central_ctr_eviction_fifo_entry_t *entry)
   9052 {
   9053     soc_control_t *soc;
   9054     soc_counter_non_dma_t *pkt_ctr_dma, *byte_ctr_dma;
   9055     soc_counter_evict_t *evict;
   9056     soc_mem_t mem;
   9057     int index, mem_id, pipe;
   9058     uint32 fval[2];
   9059     int pkt_ctr_id, byte_ctr_id, offset, base_index;
   9060     uint64 ctr_diff;
   9061 
   9062     COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit);
   9063 
   9064     soc = SOC_CONTROL(unit);
   9065 
   9066     mem = CENTRAL_CTR_EVICTION_FIFOm;
   9067     if (SOC_IS_TRIDENT3X(unit)) {
   9068         index = soc_format_field32_get(unit, CTR_EVICTION_MESSAGEfmt, entry, INDEXf);
   9069         mem_id = soc_format_field32_get(unit, CTR_EVICTION_MESSAGEfmt, entry, POOL_NUMf);
   9070         pipe = soc_format_field32_get(unit, CTR_EVICTION_MESSAGEfmt, entry, PIPE_NUMf);
   9071     } else {
   9072         if(SOC_IS_TOMAHAWK2(unit) || SOC_IS_TOMAHAWK3(unit)) {
   9073         index = soc_mem_field32_get(unit, mem, entry, INDEXf);
   9074     } else {
   9075     index = soc_mem_field32_get(unit, mem, entry, CEV_INDEXf);
   9076     }
   9077     mem_id = soc_mem_field32_get(unit, mem, entry, POOL_NUMf);
   9078     pipe = soc_mem_field32_get(unit, mem, entry, PIPE_NUMf);
   9079     }
   9080     /* Check if pool number is within the range */
   9081     if ((mem_id < 1) || (mem_id > soc->counter_evict_max_mem_id)) {
   9082         soc->counter_evict_inval_poolid_count++;
   9083         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
   9084                     (BSL_META_U(unit,
   9085                      "Invalid eviction pool# = %d\n"), mem_id));
   9086         return;
   9087     }
   9088 
   9089     evict = &soc->counter_evict[mem_id];
   9090     pkt_ctr_id = evict->pkt_counter_id;
   9091     byte_ctr_id = evict->byte_counter_id;
   9092     offset = evict->offset[pipe];
   9093 
   9094     pkt_ctr_dma = &soc->counter_non_dma[pkt_ctr_id - SOC_COUNTER_NON_DMA_START];
   9095 
   9096     if (SOC_IS_TRIDENT3X(unit)) {
   9097         fval[0] = soc_format_field32_get(unit, CTR_EVICTION_MESSAGEfmt, 
   9098                                          entry, PKT_CNTf);
   9099     } else {
   9100     fval[0] = soc_mem_field32_get(unit, mem, entry, PKT_CNTf);
   9101     }
   9102 
   9103     COMPILER_64_SET(ctr_diff, 0, fval[0]);
   9104     base_index = pkt_ctr_dma->base_index + offset;
   9105 
   9106     COUNTER_ATOMIC_BEGIN(s);
   9107     COMPILER_64_ADD_64(soc->counter_sw_val[base_index + index], ctr_diff);
   9108     soc->counter_delta[base_index + index] = ctr_diff;
   9109     COUNTER_ATOMIC_END(s);
   9110 
   9111     byte_ctr_dma = &soc->counter_non_dma[byte_ctr_id - SOC_COUNTER_NON_DMA_START];
   9112     if (SOC_IS_TRIDENT3X(unit)) {
   9113         soc_format_field_get(unit, CTR_EVICTION_MESSAGEfmt, entry->entry_data,
   9114                              BYTE_CNTf, fval);
   9115     } else {
   9116     soc_mem_field_get(unit, mem, entry->entry_data, BYTE_CNTf, fval);
   9117     }
   9118     COMPILER_64_SET(ctr_diff, fval[1], fval[0]);
   9119     base_index = byte_ctr_dma->base_index + offset;
   9120 
   9121     COUNTER_ATOMIC_BEGIN(s);
   9122     COMPILER_64_ADD_64(soc->counter_sw_val[base_index + index], ctr_diff);
   9123     soc->counter_delta[base_index + index] = ctr_diff;
   9124     COUNTER_ATOMIC_END(s);
   9125 
   9126 }
   9127 
   9128 void
   9129 _soc_ctr_evict_fifo_dma_thread(void *unit_vp)
   9130 {
   9131     int unit = PTR_TO_INT(unit_vp);
   9132     soc_control_t *soc = SOC_CONTROL(unit);
   9133     int cmc = SOC_PCI_CMC(unit);
   9134     soc_mem_t mem;
   9135     int i, count, adv_threshold;
   9136     uint32 rval, stat_fail_mask;
   9137     uint32 hostmem_timeout, done, error;
   9138     int rv, interval, non_empty, fail;
   9139     uint8 chan;
   9140     int entries_per_buf, entry_words, yield_entries, yield_num;
   9141     uint32 stat_fail_ovrflw_mask;
   9142 
   9143 #if defined(BCM_TOMAHAWK3_SUPPORT)
   9144     if (SOC_IS_TOMAHAWK3(unit)) {
   9145         chan = SOC_MEM_FIFO_DMA_CHANNEL_0;
   9146     }else
   9147 #endif
   9148     {
   9149     chan = SOC_MEM_FIFO_DMA_CHANNEL_1;
   9150     }
   9151 
   9152     /* Maximum possible counter evictions per second is 2700. Hostbuf size is
   9153      * set to double the value to account for load conditions */
   9154     entries_per_buf = soc_property_get(unit, "spn_COUNTER_EVICT_HOSTBUF_SIZE",
   9155                                        _SOC_CTR_EVICT_HOSTBUF_SIZE);
   9156     adv_threshold = entries_per_buf / 2;
   9157     yield_entries = soc_property_get(unit, "spn_COUNTER_EVICT_ENTRIES_MAX",
   9158                                      _SOC_CTR_EVICT_ENTRIES_MAX);
   9159     yield_num = yield_entries;
   9160 
   9161     mem = CENTRAL_CTR_EVICTION_FIFOm;
   9162     entry_words = soc_mem_entry_words(unit, mem);
   9163     host_buff[unit] = soc_cm_salloc(unit, entries_per_buf * entry_words *
   9164                               sizeof(uint32), "Counter Eviction DMA Buffer");
   9165     if (host_buff[unit] == NULL) {
   9166         soc_event_generate(unit, SOC_SWITCH_EVENT_THREAD_ERROR,
   9167                            SOC_SWITCH_EVENT_THREAD_CTR_EVICT_DMA, __LINE__,
   9168                            SOC_E_MEMORY);
   9169         goto cleanup_exit;
   9170     }
   9171 
   9172     rv = soc_fifodma_masks_get(unit, &hostmem_timeout, &stat_fail_ovrflw_mask, &error, &done);
   9173 
   9174     rv = soc_fifodma_start(unit, chan, TRUE, mem, 0, MEM_BLOCK_ANY, 0,
   9175                                       entries_per_buf, host_buff[unit]);
   9176     if (SOC_FAILURE(rv)) {
   9177         soc_event_generate(unit, SOC_SWITCH_EVENT_THREAD_ERROR,
   9178                            SOC_SWITCH_EVENT_THREAD_CTR_EVICT_DMA, __LINE__,
   9179                            rv);
   9180         goto cleanup_exit;
   9181     }
   9182 
   9183     host_entry[unit] = host_buff[unit];
   9184     buff_max[unit] = (uint32 *)(host_entry[unit]) + (entries_per_buf * entry_words);
   9185 
   9186     stat_fail_mask = hostmem_timeout | stat_fail_ovrflw_mask;
   9187     soc->counter_evict_inval_poolid_count = 0;
   9188     while ((interval = soc->ctr_evict_interval)) {
   9189         fail = FALSE;
   9190         /* Interrupt */
   9191         if (soc->ctrEvictDmaIntrEnb) {
   9192             soc_fifodma_intr_enable(unit, chan);
   9193             if (sal_sem_take(soc->ctrEvictIntr, interval) < 0) {
   9194                 LOG_DEBUG(BSL_LS_SOC_EVICT,
   9195                             (BSL_META_U(unit,
   9196                                         "%s polling timeout "
   9197                                         "soc_mem_fifo_delay_value=%d\n"),
   9198                              soc->ctr_evict_name, soc_mem_fifo_delay_value));
   9199             } else {
   9200                 LOG_DEBUG(BSL_LS_SOC_EVICT,
   9201                             (BSL_META_U(unit,
   9202                                         "%s woken up soc_mem_fifo_delay_value=%d\n"),
   9203                              soc->ctr_evict_name, soc_mem_fifo_delay_value));
   9204                 /* check for timeout or overflow and either process or continue */
   9205                 soc_fifodma_status_get(unit, chan, &rval);
   9206                 if (rval & stat_fail_mask) {
   9207                     fail = TRUE;
   9208                 }
   9209             }
   9210         /* Polling */
   9211         } else {
   9212             /* Sleep for counter eviction interval */
   9213             sal_usleep(interval);
   9214         }
   9215 
   9216         EVICT_LOCK(unit);
   9217         do {
   9218             non_empty = FALSE;
   9219 
   9220             /* get entry count, process if nonzero else continue */
   9221             rv = soc_fifodma_num_entries_get(unit, chan, &count);
   9222             if (SOC_SUCCESS(rv)) {
   9223                 non_empty = TRUE;
   9224                 if (count > adv_threshold) {
   9225                     count = adv_threshold;
   9226                 }
   9227 
   9228                 for (i = 0; i < count; i++, yield_num--) {
   9229                     if(!soc->counter_interval) {
   9230                         EVICT_UNLOCK(unit);
   9231                         goto cleanup_exit;
   9232                     }
   9233                     /* Yield if value set in counter_evict_entries_max config variable is
   9234                      * not default value and if number specified in config variable has been
   9235                      * reached
   9236                      */
   9237                     if (yield_entries) {
   9238                         if (yield_num == 0) {
   9239                             yield_num = yield_entries;
   9240                             sal_thread_yield();
   9241                         }
   9242                     }
   9243 
   9244                     _soc_counter_fifo_process(unit, host_entry[unit]);
   9245                     host_entry[unit] = (uint32 *)(host_entry[unit]) + entry_words;
   9246                     /* handle roll over */
   9247                     if ((uint32 *)(host_entry[unit]) >= buff_max[unit]) {
   9248                         host_entry[unit] = host_buff[unit];
   9249                     }
   9250                 }
   9251                 soc_fifodma_set_entries_read(unit, chan, i);
   9252             }
   9253 
   9254             /* check and clear error */
   9255             soc_fifodma_status_get(unit, chan, &rval);
   9256             if (rval & done) {
   9257                 LOG_ERROR(BSL_LS_SOC_COMMON,
   9258                           (BSL_META_U(unit,
   9259                                       "FIFO DMA engine terminated for "
   9260                                       "cmc[%d]:chan[%d]\n"),
   9261                            cmc, chan));
   9262                 if (rval & error) {
   9263                     LOG_ERROR(BSL_LS_SOC_COMMON,
   9264                               (BSL_META_U(unit,
   9265                                           "FIFO DMA engine encountered error: "
   9266                                           "[0x%x]\n"),
   9267                                rval));
   9268                 }
   9269                 EVICT_UNLOCK(unit);
   9270                 goto cleanup_exit;
   9271             }
   9272         } while (non_empty);
   9273         EVICT_UNLOCK(unit);
   9274 
   9275         /* Clearing of the FIFO_CH_DMA_INT interrupt by resetting
   9276            overflow & timeout status in FIFO_CHy_RD_DMA_STAT_CLR reg */
   9277         if (fail) {
   9278             soc_fifodma_status_clear(unit, chan);
   9279         }
   9280     }
   9281 
   9282 cleanup_exit:
   9283     soc_fifodma_stop(unit, chan);
   9284 
   9285     if (host_buff[unit] != NULL) {
   9286         soc_cm_sfree(unit, host_buff[unit]);
   9287         host_buff[unit] = NULL;
   9288         host_entry[unit] = NULL;
   9289     }
   9290     soc->ctr_evict_pid = SAL_THREAD_ERROR;
   9291     sal_thread_exit(0);
   9292 }
   9293 
   9294 int
   9295 soc_ctr_evict_stop(int unit)
   9296 {
   9297     soc_control_t *soc;
   9298     int                 rv = SOC_E_NONE;
   9299     soc_timeout_t       to;
   9300     int chan;
   9301 
   9302     if (!soc_feature(unit, soc_feature_counter_eviction)) {
   9303         return SOC_E_UNAVAIL;
   9304     }
   9305 
   9306     soc = SOC_CONTROL(unit);
   9307 
   9308     SOC_IF_ERROR_RETURN(soc_counter_tomahawk_eviction_enable(unit, FALSE));
   9309 
   9310     if (!soc_feature(unit, soc_feature_fifo_dma) || SOC_IS_HELIX5(unit)) {
   9311         chan = SOC_MEM_FIFO_DMA_CHANNEL_1;
   9312         soc_fifodma_intr_disable(unit, chan);
   9313     }
   9314 
   9315     soc->ctr_evict_interval = 0; /* Request exit */
   9316     if (soc->ctr_evict_pid && (soc->ctr_evict_pid != SAL_THREAD_ERROR)) {
   9317     /* Wake up thread so it will check the exit flag */
   9318     if (soc->ctrEvictIntr != NULL) {
   9319         sal_sem_give(soc->ctrEvictIntr);
   9320     }
   9321         /* Give thread a few seconds to wake up and exit */
   9322         if (SAL_BOOT_SIMULATION) {
   9323             soc_timeout_init(&to, 300 * 1000000, 0);
   9324         } else {
   9325             soc_timeout_init(&to, 60 * 1000000, 0);
   9326         }
   9327         while (soc->ctr_evict_pid != SAL_THREAD_ERROR) {
   9328             if (soc_timeout_check(&to)) {
   9329                 LOG_ERROR(BSL_LS_SOC_COMMON,
   9330                           (BSL_META_U(unit,
   9331                                   "thread will not exit\n")));
   9332                 rv = SOC_E_INTERNAL;
   9333                 break;
   9334             }
   9335         }
   9336     }
   9337     return rv;
   9338 }
   9339 
   9340 int
   9341 soc_ctr_evict_start(int unit, uint32 flags, sal_usecs_t interval)
   9342 {
   9343     soc_control_t *soc;
   9344     uint32 flag = _SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   9345     int pri, chan;
   9346 
   9347     if (!soc_feature(unit, soc_feature_counter_eviction)) {
   9348         return SOC_E_UNAVAIL;
   9349     }
   9350 
   9351     if (!soc_property_get(unit, "ctr_evict_enable", 1)) {
   9352         LOG_CLI((BSL_META_U(unit,
   9353                             "*** skip counter eviction start for now\n")));
   9354         soc_counter_tomahawk_eviction_flags_update(unit, flag, 0);
   9355         return SOC_E_NONE;
   9356     }
   9357 
   9358     soc = SOC_CONTROL(unit);
   9359 
   9360     if (soc->ctr_evict_interval != 0) {
   9361         SOC_IF_ERROR_RETURN(soc_ctr_evict_stop(unit));
   9362     }
   9363 
   9364     sal_snprintf(soc->ctr_evict_name, sizeof(soc->ctr_evict_name),
   9365                  "CtrEvict.%d", unit);
   9366     soc->ctr_evict_flags = flags;
   9367     soc->ctr_evict_interval = interval;
   9368 
   9369     if (interval == 0) {
   9370         return SOC_E_NONE;
   9371     }
   9372 
   9373 
   9374     if (soc->ctr_evict_pid == SAL_THREAD_ERROR) {
   9375         pri = soc_property_get(unit, "spn_COUNTER_EVICT_THREAD_PRI",
   9376                                _SOC_CTR_EVICT_THREAD_PRI);
   9377 
   9378         soc->ctr_evict_pid =
   9379             sal_thread_create(soc->ctr_evict_name, SAL_THREAD_STKSZ, pri,
   9380                               _soc_ctr_evict_fifo_dma_thread,
   9381                               INT_TO_PTR(unit));
   9382         if (soc->ctr_evict_pid == SAL_THREAD_ERROR) {
   9383             LOG_ERROR(BSL_LS_SOC_COMMON,
   9384                       (BSL_META_U(unit,
   9385                                   "soc_ctr_evict_start: Could not start thread\n")));
   9386             return SOC_E_MEMORY;
   9387         }
   9388     }
   9389 
   9390     if (!soc_feature(unit, soc_feature_fifo_dma)) {
   9391         chan = SOC_MEM_FIFO_DMA_CHANNEL_1;
   9392         soc_fifodma_intr_enable(unit, chan);
   9393     }
   9394 
   9395     /* coverity[dead_error_line] */
   9396     SOC_IF_ERROR_RETURN(soc_counter_tomahawk_eviction_enable(unit, TRUE));
   9397 
   9398     return SOC_E_NONE;
   9399 }
   9400 
   9401 /*
   9402  * Function:
   9403  *      soc_counter_eviction_sync
   9404  * Purpose:
   9405  *      Sync values stored in Eviction Fifo to the SW val
   9406  * Parameters:
   9407  *      unit - StrataSwitch unit #.
   9408  * Returns:
   9409  *      SOC_E_XXX
   9410  * Notes:
   9411  *      This is to ensure counter values in Transit(in Eviction FIFO) to be
   9412  *      synced when stat sync is issue.
   9413  *      Ensures that ALL counter activity that occurred before the sync
   9414  *      is reflected in the results of any soc_counter_get()-type
   9415  *      routine that is called after the sync.
   9416  */
   9417 int
   9418 soc_counter_eviction_sync(int unit)
   9419 {
   9420     soc_control_t       *soc = SOC_CONTROL(unit);
   9421     uint8 chan = SOC_MEM_FIFO_DMA_CHANNEL_1;
   9422 
   9423     /* disable interrupt before releasing semaphore, which causes eviction
   9424      * thread to sync stat from Eviction fifo to Sw_val
   9425      */
   9426     soc_fifodma_intr_disable(unit, chan);
   9427 
   9428     if (soc->ctrEvictIntr != NULL) {
   9429         sal_sem_give(soc->ctrEvictIntr);
   9430     }
   9431 
   9432     return SOC_E_NONE;
   9433 }
   9434 
   9435 #endif /* BCM_TOMAHAWK_SUPPORT */
   9436 
   9437 /*
   9438  * Function:
   9439  *      soc_counter_autoz
   9440  * Purpose:
   9441  *      Set or clear AUTOZ mode for all MAC counter registers (all ports)
   9442  * Parameters:
   9443  *      unit - StrataSwitch unit #.
   9444  *      enable - if TRUE, enable, otherwise disable AUTOZ mode
   9445  * Returns:
   9446  *      SOC_E_XXX.
   9447  * Notes:
   9448  *      This module requires AUTOZ is off to accumulate counters properly.
   9449  *      On 5665, this also turns on/off the MMU counters AUTOZ mode.
   9450  */
   9451 
   9452 int
   9453 soc_counter_autoz(int unit, int enable)
   9454 {
   9455     soc_port_t          port;
   9456 
   9457     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
   9458              (BSL_META_U(unit,
   9459                          "soc_counter_autoz: unit=%d enable=%d\n"), unit, enable));
   9460 
   9461     PBMP_PORT_ITER(unit, port) {
   9462 #if defined(BCM_ESW_SUPPORT)
   9463         SOC_IF_ERROR_RETURN(soc_autoz_set(unit, port, enable));
   9464 #endif
   9465     }
   9466 
   9467     return (SOC_E_NONE);
   9468 }
   9469 
   9470 /*
   9471  * Function:
   9472  *      _soc_counter_get
   9473  * Purpose:
   9474  *      Given a counter register number and port number, fetch the
   9475  *      64-bit software-accumulated counter value or read from device counter
   9476  *      register. The software-accumulated counter value is zeroed if requested.
   9477  * Parameters:
   9478  *      unit - StrataSwitch unit #.
   9479  *      port - StrataSwitch port #.
   9480  *      ctr_reg - counter register
   9481  *      zero - if TRUE, current counter is zeroed after reading.
   9482  *      sync_mode - if TRUE, read from device else software accumulated value
   9483  *      val - (OUT) 64-bit counter value.
   9484  * Returns:
   9485  *      SOC_E_XXX.
   9486  * Notes:
   9487  *      Returns 0 if ctr_reg is INVALIDr or not enabled.
   9488  */
   9489 
   9490 STATIC INLINE int
   9491 _soc_counter_get(int unit, soc_port_t port, soc_reg_t ctr_reg, int ar_idx,
   9492                  int zero, int sync_mode, uint64 *val)
   9493 {
   9494     soc_control_t       *soc = SOC_CONTROL(unit);
   9495     int                 port_index, num_entries;
   9496     char                *cname;
   9497     uint64              *vptr;
   9498     uint64              value;
   9499     COUNTER_ATOMIC_DEF  s = SOC_CONTROL(unit);
   9500     soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit);
   9501 
   9502 #ifdef BCM_TOMAHAWK_SUPPORT
   9503     if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) &&
   9504         (ctr_reg >= SOC_COUNTER_NON_DMA_START) &&
   9505         (ctr_reg < SOC_COUNTER_NON_DMA_END)) {
   9506         soc_counter_non_dma_t *non_dma = 
   9507                     &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START];
   9508         soc_ctr_control_info_t ctrl_info;
   9509         if (soc_tomahawk_mem_is_xpe(unit, non_dma->mem)) {
   9510             ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_XPE;
   9511         }
   9512 #ifdef BCM_FLOWTRACKER_SUPPORT
   9513         else if ((ctr_reg >=
   9514             SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_NUM_EXCEEDED_CNT) &&
   9515             (ctr_reg <= SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_METER_EXCEEDED_CNT)) {
   9516             ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_FT_GROUP;
   9517             sync_mode = 1;
   9518         }
   9519 #endif
   9520 #ifdef BCM_TOMAHAWK3_SUPPORT
   9521         else if (soc_tomahawk3_mem_is_itm(unit, non_dma->mem) ||
   9522                  soc_tomahawk3_reg_is_itm(unit, non_dma->reg)) {
   9523             ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_ITM;
   9524 
   9525             /* some exceptions here */
   9526             if(SOC_MEM_IS_VALID(unit, non_dma->mem)) {
   9527                 switch(non_dma->mem) {
   9528                     case MMU_THDO_SRC_PORT_DROP_COUNTm:
   9529                         ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
   9530                     break;
   9531                     default:
   9532                     break;
   9533                 }
   9534             }
   9535         }
   9536 #endif /* BCM_TOMAHAWK3_SUPPORT */
   9537         else {
   9538             ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
   9539         }
   9540         ctrl_info.instance = port;
   9541         return soc_counter_generic_get(unit, ctr_reg, ctrl_info,
   9542                                        sync_mode ? SOC_COUNTER_SYNC_ENABLE : 0,
   9543                                        ar_idx, val);
   9544     }
   9545 #endif /* BCM_TOMAHAWK_SUPPORT */
   9546 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   9547     /*when port is invalid, rely on ar_idx to get ind*/
   9548     if ((port == SOC_PORT_INVALID) && SOC_IS_TRIDENT2PLUS(unit) &&
   9549         (ctr_reg >= SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC &&
   9550          ctr_reg <= SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC )) {
   9551        SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, SOC_PORT_MIN(unit,all),
   9552                                     ctr_reg, &port_index, &num_entries, &cname));
   9553        port_index += ar_idx;
   9554      } else
   9555 #endif
   9556     {
   9557         /* coverity[negative_returns] */
   9558     SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, ctr_reg,
   9559                                               &port_index, &num_entries,
   9560                                               &cname));
   9561     if (ar_idx >= num_entries) {
   9562         return SOC_E_PARAM;
   9563     }
   9564 
   9565     if (sync_mode == TRUE) {
   9566         COUNTER_LOCK(unit);
   9567 
   9568         /* sync the software counter with hardware counter */
   9569         if (!SOC_COUNTER_INVALID(unit, ctr_reg)) {
   9570 #if defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT)
   9571             soc_counter_collect64(unit, FALSE, port, ctr_reg);
   9572 #endif
   9573             } else if (ctr_reg >= SOC_COUNTER_NON_DMA_START &&
   9574                        ctr_reg < SOC_COUNTER_NON_DMA_END) {
   9575             if(soc_ctr_ctrl->collect_non_stat_dma) {
   9576                 soc_ctr_ctrl->collect_non_stat_dma(unit, port, port_index,
   9577                                                    ar_idx, ctr_reg);
   9578           }
   9579 #ifdef BCM_TOMAHAWK_SUPPORT
   9580           if (soc_feature(unit, soc_feature_counter_eviction)) {
   9581  	      SOC_IF_ERROR_RETURN(soc_counter_eviction_sync(unit));
   9582 	  }
   9583 #endif
   9584 
   9585           LOG_DEBUG(BSL_LS_SOC_COUNTER,
   9586                       (BSL_META_U(unit,
   9587                                   "port[%d], ctr_reg[%d],"
   9588                                   "port_index[%d], ar_idx[%d]"
   9589                                   "num_entries[%d], cname[%s] "),
   9590                        port, ctr_reg, port_index, ar_idx,
   9591                        num_entries, cname));
   9592         }
   9593         COUNTER_UNLOCK(unit);
   9594     }
   9595 
   9596     if (ar_idx > 0 && ar_idx < num_entries) {
   9597         port_index += ar_idx;
   9598     }
   9599     }
   9600 
   9601     /* Try to minimize the atomic section as much as possible */
   9602     if (ctr_reg >= SOC_COUNTER_NON_DMA_START &&
   9603         ctr_reg < SOC_COUNTER_NON_DMA_END &&
   9604         (soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].flags &
   9605          _SOC_COUNTER_NON_DMA_CURRENT)) {
   9606         vptr = &soc->counter_hw_val[port_index];
   9607     } else {
   9608         vptr = &soc->counter_sw_val[port_index];
   9609     }
   9610     if (zero) {
   9611         COUNTER_ATOMIC_BEGIN(s);
   9612         value = *vptr;
   9613         COMPILER_64_ZERO(*vptr);
   9614         COUNTER_ATOMIC_END(s);
   9615     } else {
   9616         COUNTER_ATOMIC_BEGIN(s);
   9617         value = *vptr;
   9618         COUNTER_ATOMIC_END(s);
   9619     }
   9620 
   9621      LOG_DEBUG(BSL_LS_SOC_COUNTER,
   9622                  (BSL_META_U(unit,
   9623                              "cntr get %s port=%d "
   9624                              "port_index=%d vptr=%p val=0x%08x_%08x\n"),
   9625                   cname,
   9626                   port,
   9627                   port_index,
   9628                   (void *)vptr, COMPILER_64_HI(value), COMPILER_64_LO(value)));
   9629 
   9630     *val = value;
   9631 
   9632     return SOC_E_NONE;
   9633 }
   9634 
   9635 /*
   9636  * Function:
   9637  *      _soc_counter_instance_encode
   9638  * Purpose:
   9639  *      Given an input array of heterogeneous soc_ctr_control_info_t
   9640  *      data structures, encode them into one single output
   9641  *      soc_ctr_control_info_t data structure.
   9642  * Parameters:
   9643  *      input_ctrl_info  - (IN) Input array of ctrl_info variables to be 
   9644  *                          encoded.
   9645  *      count            - (IN) Number of ctrl_info variables to be encoded.
   9646  *      output_ctrl_info - (OUT) Encoded output ctrl_info data structure.
   9647  * Returns:
   9648  *      SOC_E_XXX.
   9649  * Notes:
   9650  *      Encoding support currently exists for SOC_CTR_INSTANCE_TYPE_POOL_PIPE
   9651  *      and SOC_CTR_INSTANCE_TYPE_XPE_PORT
   9652  *      Decoding is done inside soc_tomahawk_counter_generic_get_info function.
   9653  *      Encoding scheme 
   9654  *      Bits 0-3 PIPE
   9655  *           4-9 POOL
   9656  *         10-13 XPE
   9657  *         14-23 PORT
   9658  *         24-25 ITM
   9659  */
   9660 int
   9661 soc_counter_instance_encode(soc_ctr_control_info_t *input_ctrl_info, int count, 
   9662                              soc_ctr_control_info_t *output_ctrl_info)
   9663 {
   9664     switch (count) {
   9665         case 1:
   9666             *output_ctrl_info = input_ctrl_info[0];
   9667             return SOC_E_NONE;
   9668             break;
   9669 
   9670         case 2:
   9671             if ((input_ctrl_info[0].instance_type == SOC_CTR_INSTANCE_TYPE_POOL)
   9672                     && (input_ctrl_info[1].instance_type ==
   9673                         SOC_CTR_INSTANCE_TYPE_PIPE)) {
   9674                 if (input_ctrl_info[1].instance == -1) {
   9675                     *output_ctrl_info = input_ctrl_info[1];
   9676                 } else {
   9677                     output_ctrl_info->instance_type = SOC_CTR_INSTANCE_TYPE_POOL_PIPE;
   9678                     /* First 4 bits allocated to Pipe and next 6 allocated to 
   9679                      * Pool */
   9680                     output_ctrl_info->instance = ((input_ctrl_info[0].instance << 4)
   9681                                                     | (input_ctrl_info[1].instance));  
   9682                 }
   9683                 return SOC_E_NONE;
   9684             } else if ((input_ctrl_info[0].instance_type == 
   9685                         SOC_CTR_INSTANCE_TYPE_PIPE)
   9686                         && (input_ctrl_info[1].instance_type ==
   9687                         SOC_CTR_INSTANCE_TYPE_POOL)) {
   9688                 if (input_ctrl_info[0].instance == -1) {
   9689                     *output_ctrl_info = input_ctrl_info[0];
   9690                 } else {
   9691                     output_ctrl_info->instance_type = SOC_CTR_INSTANCE_TYPE_POOL_PIPE;
   9692                     output_ctrl_info->instance = ((input_ctrl_info[1].instance << 4)
   9693                                                 | (input_ctrl_info[0].instance));      
   9694                 }
   9695                 return SOC_E_NONE;
   9696             } else if ((input_ctrl_info[0].instance_type == 
   9697                         SOC_CTR_INSTANCE_TYPE_XPE)
   9698                        && (input_ctrl_info[1].instance_type ==
   9699                        SOC_CTR_INSTANCE_TYPE_PORT)) {
   9700                     output_ctrl_info->instance_type = SOC_CTR_INSTANCE_TYPE_XPE_PORT;
   9701                     /*Bits 10-13 allocated to XPE and next 10 allocated to 
   9702                      * Port */
   9703                     output_ctrl_info->instance = ((input_ctrl_info[0].instance << 10)
   9704                                                     |(input_ctrl_info[1].instance << 14));  
   9705                 return SOC_E_NONE; 
   9706             } else if ((input_ctrl_info[0].instance_type == 
   9707                         SOC_CTR_INSTANCE_TYPE_PORT)
   9708                        && (input_ctrl_info[1].instance_type ==
   9709                        SOC_CTR_INSTANCE_TYPE_XPE)) {
   9710                     output_ctrl_info->instance_type = SOC_CTR_INSTANCE_TYPE_XPE_PORT;
   9711                     /*Bits 10-13 allocated to XPE and next 10 allocated to 
   9712                      * Port */
   9713                     output_ctrl_info->instance = ((input_ctrl_info[0].instance << 14)
   9714                                                     |(input_ctrl_info[1].instance << 10));  
   9715                 return SOC_E_NONE; 
   9716             } else if ((input_ctrl_info[0].instance_type ==
   9717                         SOC_CTR_INSTANCE_TYPE_ITM)
   9718                        && (input_ctrl_info[1].instance_type ==
   9719                        SOC_CTR_INSTANCE_TYPE_PORT)) {
   9720                     output_ctrl_info->instance_type = SOC_CTR_INSTANCE_TYPE_ITM_PORT;
   9721                     output_ctrl_info->instance = 
   9722                         ((input_ctrl_info[0].instance << CTR_INSTANCE_BIT_SHIFT_ITM) |
   9723                          (input_ctrl_info[1].instance << CTR_INSTANCE_BIT_SHIFT_PORT));
   9724                 return SOC_E_NONE;
   9725             } else {
   9726                 return SOC_E_PARAM;
   9727             }
   9728             break;
   9729 
   9730         default:
   9731             return SOC_E_PARAM;
   9732 
   9733     }
   9734 }
   9735 
   9736 static INLINE int
   9737 _soc_counter_generic_get(int unit, soc_ctr_control_info_t ctrl_info, soc_reg_t ctr_reg,
   9738                          int ar_idx, int zero, int sync_mode, uint64 *val)
   9739 {
   9740     soc_control_t       *soc = SOC_CONTROL(unit);
   9741     int                 base_index, num_entries,i, pipe_max_idx = 0;
   9742     uint64              *vptr;
   9743     uint64              value;
   9744 #ifdef BCM_TOMAHAWK3_SUPPORT
   9745     soc_info_t * si = &SOC_INFO(unit);
   9746 #endif
   9747 
   9748     COUNTER_ATOMIC_DEF  s = SOC_CONTROL(unit);
   9749     COMPILER_64_SET(*val, 0, 0);
   9750     SOC_IF_ERROR_RETURN(soc_counter_generic_get_info(unit, ctrl_info,ctr_reg,
   9751                                                      &base_index,&num_entries));
   9752     if (ar_idx >= num_entries) {
   9753         return SOC_E_PARAM;
   9754     }
   9755     /* Retrieve ar_idx across all pipes */
   9756     if (((ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) &&
   9757         (ctrl_info.instance == -1)) || (ctrl_info.instance_type ==
   9758         SOC_CTR_INSTANCE_TYPE_POOL)) {
   9759         pipe_max_idx = base_index + (NUM_PIPE(unit) * num_entries);
   9760     }
   9761 
   9762     if (sync_mode == TRUE) {
   9763         COUNTER_LOCK(unit);
   9764 
   9765         /* sync the software counter with hardware counter */
   9766         if (!SOC_COUNTER_INVALID(unit, ctr_reg)) {
   9767 #if defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT)
   9768             if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PORT) {
   9769                 soc_counter_collect64(unit, FALSE, ctrl_info.instance, ctr_reg);
   9770             }
   9771 #endif
   9772         } else if (ctr_reg >= SOC_COUNTER_NON_DMA_START &&
   9773                    ctr_reg < SOC_COUNTER_NON_DMA_END) {
   9774             if (pipe_max_idx == 0) {
   9775                soc_counter_generic_collect_non_dma_entries(unit, ctrl_info,
   9776                                                            base_index,
   9777                                                            ar_idx, ctr_reg);
   9778             } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) {
   9779                 for (i = 0; i < NUM_PIPE(unit); i++) {
   9780 #ifdef BCM_TOMAHAWK3_SUPPORT
   9781                     if (SOC_PBMP_IS_NULL(si->pipe_pbm[i])) {
   9782                         continue;
   9783                     }
   9784 #endif
   9785                     ctrl_info.instance = i;
   9786                     soc_counter_generic_collect_non_dma_entries(unit,
   9787                                                                 ctrl_info,
   9788                                                                 base_index + i * num_entries,
   9789                                                                 ar_idx,
   9790                                                                 ctr_reg);
   9791                 }
   9792             }
   9793             else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL ||
   9794                     ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL_PIPE) {
   9795                 int pipe_start = 0, pipe_end = 0, i = 0;
   9796                 soc_ctr_control_info_t     ctrl_info_in[2], ctrl_info_out;
   9797 
   9798                 ctrl_info_in[0].instance_type = SOC_CTR_INSTANCE_TYPE_POOL;
   9799                 ctrl_info_in[0].instance = 0;
   9800                 ctrl_info_in[1].instance_type = SOC_CTR_INSTANCE_TYPE_PIPE;
   9801                 ctrl_info_in[1].instance = 0;
   9802 
   9803                 if (ctrl_info.instance_type
   9804                     == SOC_CTR_INSTANCE_TYPE_POOL) {
   9805                     pipe_start = 0;
   9806                     pipe_end = NUM_PIPE(unit) - 1;
   9807                     ctrl_info_in[0].instance = ctrl_info.instance;
   9808                 } else {
   9809                     if (ctrl_info.instance != -1) {
   9810                         pipe_start = pipe_end = (ctrl_info.instance & 0xF);
   9811                         ctrl_info_in[0].instance = (ctrl_info.instance >> 4) & 0x3F;
   9812                     } else {
   9813                         pipe_start = 0;
   9814                         pipe_end = NUM_PIPE(unit) - 1;
   9815                     }
   9816                 }
   9817 
   9818                 for(i = pipe_start; i <= pipe_end; i++) {
   9819 #ifdef BCM_TOMAHAWK3_SUPPORT
   9820                     if (SOC_PBMP_IS_NULL(si->pipe_pbm[i])) {
   9821                         continue;
   9822                     }
   9823 #endif
   9824                     ctrl_info_in[1].instance = i;
   9825                     soc_counter_instance_encode(ctrl_info_in, 2, &ctrl_info_out);
   9826                     soc_counter_generic_collect_non_dma_entries(unit,
   9827                                                                 ctrl_info_out,
   9828                                                                 base_index,
   9829                                                                 ar_idx,
   9830                                                                 ctr_reg);
   9831                 }
   9832             }
   9833         }
   9834 
   9835         COUNTER_UNLOCK(unit);
   9836 
   9837 #ifdef BCM_TOMAHAWK_SUPPORT
   9838         if (soc_feature(unit, soc_feature_counter_eviction)) {
   9839             int i = 0;
   9840             int rv = 0;
   9841             int count = 0;
   9842             uint8 chan = SOC_MEM_FIFO_DMA_CHANNEL_1;
   9843             soc_mem_t mem = CENTRAL_CTR_EVICTION_FIFOm;
   9844             int entry_words = soc_mem_entry_words(unit, mem);
   9845 
   9846 #if defined(BCM_TOMAHAWK3_SUPPORT)
   9847             if (SOC_IS_TOMAHAWK3(unit)) {
   9848                 chan = SOC_MEM_FIFO_DMA_CHANNEL_0;
   9849             }
   9850 #endif
   9851             EVICT_LOCK(unit);
   9852             if (host_entry[unit]) {
   9853                 rv = soc_fifodma_num_entries_get(unit, chan, &count);
   9854                 if (SOC_SUCCESS(rv)) {
   9855                     for (i = 0; i < count; i++) {
   9856                         if (!soc->counter_interval) {
   9857                             break;
   9858                         }
   9859                         _soc_counter_fifo_process(unit, host_entry[unit]);
   9860                         host_entry[unit] = (uint32*)(host_entry[unit]) + entry_words;
   9861                         if ((uint32*)(host_entry[unit]) >= buff_max[unit]) {
   9862                             host_entry[unit] = host_buff[unit];
   9863                         }
   9864                     }
   9865                     soc_fifodma_set_entries_read(unit, chan, i);
   9866                 }
   9867             }
   9868             EVICT_UNLOCK(unit);
   9869         }
   9870 #endif
   9871     }
   9872 
   9873     if (ar_idx > 0 && ar_idx < num_entries) {
   9874         base_index += ar_idx;
   9875     }
   9876 
   9877     do {
   9878         /* Try to minimize the atomic section as much as possible */
   9879         if ((ctr_reg >= NUM_SOC_REG) &&
   9880             (soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].flags &
   9881             _SOC_COUNTER_NON_DMA_CURRENT)) {
   9882             vptr = &soc->counter_hw_val[base_index];
   9883         } else {
   9884             vptr = &soc->counter_sw_val[base_index];
   9885         }
   9886         if (zero) {
   9887             COUNTER_ATOMIC_BEGIN(s);
   9888             value = *vptr;
   9889             COMPILER_64_ZERO(*vptr);
   9890             COUNTER_ATOMIC_END(s);
   9891         } else {
   9892             COUNTER_ATOMIC_BEGIN(s);
   9893             value = *vptr;
   9894             COUNTER_ATOMIC_END(s);
   9895         }
   9896         base_index += num_entries;
   9897         COMPILER_64_ADD_64(*val, value);
   9898     } while (base_index < pipe_max_idx);
   9899 
   9900     return SOC_E_NONE;
   9901 }
   9902 
   9903 int soc_counter_sync_mode_get(int unit)
   9904 {
   9905 #ifdef BCM_PETRA_SUPPORT
   9906 #ifdef CRASH_RECOVERY_SUPPORT
   9907     if (SOC_IS_ARAD(unit))
   9908     {
   9909         /* In case crash recovery is enabled - read the values from HW instead of SW */
   9910         if (SOC_CR_ENABALED(unit))
   9911             {
   9912                 return TRUE; /* read hw accumulated */
   9913             }
   9914         return FALSE; /* read sw accumulated */
   9915     }
   9916     else
   9917 #endif /* CRASH_RECOVERY_SUPPORT */
   9918 #endif
   9919     {
   9920         return FALSE; /* read sw accumulated */
   9921     }
   9922 }
   9923 
   9924 /*
   9925  * Function:
   9926  *      soc_counter_generic_get
   9927  * Purpose:
   9928  *      Given a counter register number, instance type, instance and a counter
   9929  *      value, get both the software-accumulated value from the counter.
   9930  * Parameters:
   9931  *      unit - StrataSwitch unit #.
   9932  *      ctr_reg - counter register to retrieve.
   9933  *      ctrl_info - Counter Control Info Structure
   9934  *                  Contains Instance type and instance.
   9935  *      val(OUT) - 64-bit counter value.
   9936  * Returns:
   9937  *      SOC_E_XXX
   9938  * Notes:
   9939  *  *   Currently supported instance types are
   9940  *      1. SOC_CTR_INSTANCE_TYPE_PORT
   9941  *      2. SOC_CTR_INSTANCE_TYPE_POOL
   9942  *      3. SOC_CTR_INSTANCE_TYPE_PIPE
   9943  *      4. SOC_CTR_INSTANCE_TYPE_POOL_PIPE
   9944  *      5. SOC_CTR_INSTANCE_TYPE_XPE
   9945  *      6. SOC_CTR_INSTANCE_TYPE_XPE_PORT
   9946  */
   9947 int
   9948 soc_counter_generic_get(int unit, soc_reg_t ctr_reg,
   9949         soc_ctr_control_info_t ctrl_info, uint32 flags,
   9950         int ar_idx, uint64 *val)
   9951 {
   9952     int sync_mode = soc_counter_sync_mode_get(unit);
   9953     int rv = SOC_E_NONE;
   9954     soc_control_t *soc = SOC_CONTROL(unit);
   9955     soc_info_t *si = &SOC_INFO(unit);
   9956     int pipe, xpe, port;
   9957 #ifdef BCM_TOMAHAWK3_SUPPORT
   9958     uint16 dev_id;
   9959     uint8 rev_id;
   9960 #endif
   9961     uint64 value;
   9962     COMPILER_64_ZERO(*val);
   9963     if (ctr_reg < SOC_COUNTER_NON_DMA_START ||
   9964         ctr_reg >= SOC_COUNTER_NON_DMA_END) {
   9965         return SOC_E_PARAM;
   9966     }
   9967 
   9968     if (soc->counter_non_dma == NULL) {
   9969         return SOC_E_RESOURCE;
   9970     }
   9971 
   9972     if (!(soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].flags)) {
   9973         return SOC_E_UNAVAIL;
   9974     }
   9975 
   9976     if ((ctr_reg >= SOC_COUNTER_NON_DMA_START) && 
   9977         (ctr_reg < SOC_COUNTER_NON_DMA_END)) {
   9978         soc_counter_non_dma_t *non_dma =
   9979             &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START];
   9980         soc_mem_t mem = non_dma->mem;
   9981         soc_reg_t reg = non_dma->reg;
   9982         soc_ctr_control_info_t input_ctrl_info [2], output_ctrl_info;
   9983         if (flags & SOC_COUNTER_SYNC_ENABLE) {
   9984             sync_mode = TRUE;
   9985         }
   9986 #ifdef BCM_TOMAHAWK3_SUPPORT
   9987         soc_cm_get_id(unit, &dev_id, &rev_id);
   9988         if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_ITM) {
   9989             int itm;
   9990             port = ctrl_info.instance;
   9991             pipe = si->port_pipe[port];
   9992             input_ctrl_info[0].instance_type = ctrl_info.instance_type;
   9993             input_ctrl_info[1].instance = ctrl_info.instance;
   9994             input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
   9995             if (mem != INVALIDm) {
   9996                 for (itm = 0; itm < NUM_ITM(unit) ; itm++) {
   9997                     if (itm == 1 && (dev_id == BCM56983_DEVICE_ID)) {
   9998                         continue;
   9999                     }
  10000                     input_ctrl_info[0].instance = itm;
  10001 
  10002                     if (SOC_MEM_UNIQUE_ACC_ITM(unit,mem,itm) == INVALIDm) {
  10003                         continue;
  10004                     }
  10005 
  10006                     if(itm > 0 &&
  10007                        !(non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
  10008                         /* skip if ITM memories that has non-ITM base type */
  10009                         continue;
  10010                     }
  10011 
  10012                     soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info);
  10013                     rv = _soc_counter_generic_get(unit, output_ctrl_info,
  10014                                                   ctr_reg, ar_idx, FALSE,
  10015                                                   sync_mode, &value);
  10016                     if (rv != SOC_E_NONE) {
  10017                         return rv;
  10018                     }
  10019                     /* Sum values from all valid itm-port combinations */
  10020                     COMPILER_64_ADD_64(*val, value);
  10021                 }
  10022             } else if (reg != INVALIDr) {
  10023 
  10024                 for (itm = 0; itm < NUM_ITM(unit) ; itm++) {
  10025                     if (itm == 1 && (dev_id == BCM56983_DEVICE_ID)) {
  10026                         continue;
  10027                     }
  10028                     input_ctrl_info[0].instance = itm;
  10029 
  10030                     soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info);
  10031                     rv = _soc_counter_generic_get(unit, output_ctrl_info,
  10032                                                   ctr_reg, ar_idx, FALSE,
  10033                                                   sync_mode, &value);
  10034 
  10035                     if (rv != SOC_E_NONE) {
  10036                         return rv;
  10037                     }
  10038                     /* Sum values from all valid itm-port combinations */
  10039                     COMPILER_64_ADD_64(*val, value);
  10040                 }
  10041             }
  10042         } else
  10043 #endif /* BCM_TOMAHAWK3_SUPPORT */
  10044 
  10045         /* Each XPE maps to a pair of IPIPE or EPIPE based on memory type. 
  10046          * Hence loop through all applicable XPEs for a given pipe and return
  10047          * accumulated value*/
  10048         if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_XPE) {
  10049             port = ctrl_info.instance;
  10050             pipe = si->port_pipe[port];
  10051             if (mem != INVALIDm) {
  10052                 input_ctrl_info[0].instance_type = ctrl_info.instance_type;
  10053                 input_ctrl_info[1].instance = ctrl_info.instance;
  10054                 input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
  10055 
  10056                 for (xpe = 0; xpe < NUM_XPE(unit) ; xpe++) {
  10057                     input_ctrl_info[0].instance = xpe;
  10058                     if ((mem == MMU_CTR_COLOR_DROP_MEMm) && !SOC_IS_TOMAHAWK2(unit)) {
  10059                         /* Get valid XPE/Pipe Combination */
  10060                         if(!((si->epipe_xpe_map[pipe] >> xpe) & 1)) {
  10061                             continue;
  10062                         }
  10063                     } else {
  10064                         if (SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit,mem,xpe,pipe) == INVALIDm) {
  10065                             /* Invalid XPE/Pipe Combination */
  10066                             continue;
  10067                         }
  10068                     }
  10069                     soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info);
  10070                     rv = _soc_counter_generic_get(unit, output_ctrl_info,
  10071                                                   ctr_reg, ar_idx, FALSE,
  10072                                                   sync_mode, &value);
  10073                     if (rv != SOC_E_NONE) {
  10074                         return rv;
  10075                     }
  10076                     /* Sum values from all valid xpe-port combinations */
  10077                     COMPILER_64_ADD_64(*val, value);
  10078 
  10079                 }
  10080             } else if (reg != INVALIDr) {
  10081                 input_ctrl_info[0].instance_type = ctrl_info.instance_type;
  10082 
  10083                 for (xpe = 0; xpe < NUM_XPE(unit) ; xpe++) {
  10084                     input_ctrl_info[0].instance = xpe;
  10085                     if (reg == THDI_POOL_SHARED_COUNT_SPr) {
  10086                         /* Get valid XPE/Pipe Combination */
  10087                         if(!((si->ipipe_xpe_map[pipe] >> xpe) & 1)) {
  10088                             continue;
  10089                         }
  10090                     }
  10091                     rv = _soc_counter_generic_get(unit, input_ctrl_info[0],
  10092                                                   ctr_reg, ar_idx, FALSE,
  10093                                                   sync_mode, &value);
  10094                     if (rv != SOC_E_NONE) {
  10095                         return rv;
  10096                     }
  10097                     /* Sum values from all valid xpe-port combinations */
  10098                     COMPILER_64_ADD_64(*val, value);
  10099                 }
  10100             }
  10101         } else {
  10102             rv = _soc_counter_generic_get(unit, ctrl_info, ctr_reg, ar_idx,
  10103                                           FALSE, sync_mode, val);
  10104         }
  10105     }
  10106 
  10107     return rv;
  10108 }
  10109 
  10110 #ifdef BCM_APACHE_SUPPORT
  10111 int
  10112 soc_counter_apache_generic_get_info(int unit,soc_ctr_control_info_t ctrl_info,
  10113                                       soc_reg_t id, int *base_index,
  10114                                       int *num_entries)
  10115 {
  10116     soc_info_t *si = &SOC_INFO(unit);
  10117     soc_control_t *soc = SOC_CONTROL(unit);
  10118     soc_counter_non_dma_t *non_dma;
  10119     soc_port_t port;
  10120 
  10121     if ((id < NUM_SOC_REG) || (id >= SOC_COUNTER_NON_DMA_END)) {
  10122         return SOC_E_PARAM;
  10123     }
  10124 
  10125     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
  10126 
  10127     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID) &&
  10128             !(non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
  10129         /* For Parent-Child model, return E_UNAVAIL if child non_dma is INVALID.
  10130          */
  10131         return SOC_E_UNAVAIL;
  10132     }
  10133 
  10134     *base_index = 0;
  10135     switch (ctrl_info.instance_type) {
  10136         case SOC_CTR_INSTANCE_TYPE_PORT: 
  10137             port = ctrl_info.instance;
  10138             if (si->port_l2p_mapping[port] == -1) {
  10139                 *base_index = 0;
  10140                 *num_entries = 0;
  10141                 return SOC_E_PARAM;
  10142             }
  10143 
  10144             switch (id) {
  10145                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO:
  10146                 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO:
  10147                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI:
  10148                 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI:
  10149                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0:
  10150                 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0:
  10151                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1:
  10152                 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1:
  10153                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS:
  10154                 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS:
  10155                 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO:
  10156                 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO:
  10157                 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI:
  10158                 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI:
  10159                 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0:
  10160                 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0:
  10161                 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1:
  10162                 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1:
  10163                 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS:
  10164                 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS:
  10165                     if (IS_RDB_PORT(unit, port) ||
  10166                         IS_LB_PORT(unit, port)) {
  10167                         return SOC_E_PARAM;
  10168                     }
  10169                     return _soc_counter_apache_get_info(unit, port, id,
  10170                                                          base_index,
  10171                                                          num_entries);
  10172                     break;
  10173                 default:
  10174                     return SOC_E_PARAM;
  10175             }
  10176             break;
  10177 
  10178         default:
  10179             return SOC_E_PARAM;
  10180     }
  10181     return SOC_E_NONE;
  10182 }
  10183 #endif
  10184 
  10185 int
  10186 soc_counter_generic_get_info(int unit, soc_ctr_control_info_t ctrl_info,
  10187                              soc_reg_t id, int *base_index, int *num_entries)
  10188 {
  10189     int rv = SOC_E_UNAVAIL;
  10190 #ifdef BCM_TOMAHAWK_SUPPORT
  10191     if (SOC_IS_TOMAHAWKX(unit)) {
  10192         rv = soc_counter_tomahawk_generic_get_info(unit, ctrl_info, id,
  10193                 base_index, num_entries);
  10194     }
  10195 #endif
  10196 #ifdef BCM_TRIDENT3_SUPPORT
  10197     if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) {
  10198         rv = soc_counter_trident3_generic_get_info(unit, ctrl_info, id,
  10199                 base_index, num_entries);
  10200     }
  10201 #endif
  10202 #ifdef BCM_HELIX5_SUPPORT
  10203     if (SOC_IS_HELIX5(unit)) {
  10204         rv = soc_counter_helix5_generic_get_info(unit, ctrl_info, id,
  10205                 base_index, num_entries);
  10206     }
  10207 #endif
  10208 #ifdef BCM_APACHE_SUPPORT
  10209     if (SOC_IS_APACHE(unit)) {
  10210         rv = soc_counter_apache_generic_get_info(unit, ctrl_info, id,
  10211                 base_index, num_entries);
  10212     }
  10213 #endif
  10214     return rv;
  10215 }
  10216 
  10217 /*
  10218  * Function:
  10219  *      soc_counter_get, soc_counter_get32
  10220  *      soc_counter_get_zero, soc_counter_get32_zero
  10221  * Purpose:
  10222  *      Given a counter register number and port number, fetch the
  10223  *      64-bit software-accumulated counter value (normal versions)
  10224  *      or the 64-bit software-accumulated counter value truncated to
  10225  *      32 bits (32-bit versions).  The software-accumulated counter
  10226  *      value is zeroed if requested.
  10227  * Parameters:
  10228  *      unit - StrataSwitch unit #.
  10229  *      port - StrataSwitch port #.
  10230  *      ctr_reg - counter register to retrieve.
  10231  *      val - (OUT) 64/32-bit counter value.
  10232  * Returns:
  10233  *      SOC_E_XXX.
  10234  * Notes:
  10235  *      The 32-bit version returns only the lower 32 bits of the 64-bit
  10236  *      counter value.
  10237  */
  10238 
  10239 
  10240 int
  10241 soc_counter_get(int unit, soc_port_t port, soc_reg_t ctr_reg,
  10242                 int ar_idx, uint64 *val)
  10243 {
  10244     int sync_mode = soc_counter_sync_mode_get(unit);
  10245     return _soc_counter_get(unit, port, ctr_reg, ar_idx,
  10246                             FALSE, sync_mode, val);
  10247 }
  10248 
  10249 int
  10250 soc_counter_get32(int unit, soc_port_t port, soc_reg_t ctr_reg,
  10251                   int ar_idx, uint32 *val)
  10252 {
  10253     uint64              val64;
  10254     int                 rv;
  10255     int sync_mode = soc_counter_sync_mode_get(unit);
  10256 
  10257     rv = _soc_counter_get(unit, port, ctr_reg, ar_idx,
  10258                           FALSE, sync_mode, &val64);
  10259 
  10260     if (rv >= 0) {
  10261         COMPILER_64_TO_32_LO(*val, val64);
  10262     }
  10263 
  10264     return rv;
  10265 }
  10266 
  10267 int
  10268 soc_counter_get_zero(int unit, soc_port_t port,
  10269                      soc_reg_t ctr_reg, int ar_idx, uint64 *val)
  10270 {
  10271     int sync_mode = soc_counter_sync_mode_get(unit);
  10272     return _soc_counter_get(unit, port, ctr_reg, ar_idx,
  10273                             TRUE, sync_mode, val);
  10274 }
  10275 
  10276 int
  10277 soc_counter_get32_zero(int unit, soc_port_t port,
  10278                        soc_reg_t ctr_reg, int ar_idx, uint32 *val)
  10279 {
  10280     uint64              val64;
  10281     int                 rv;
  10282     int sync_mode = soc_counter_sync_mode_get(unit);
  10283 
  10284     rv = _soc_counter_get(unit, port, ctr_reg, ar_idx,
  10285                           TRUE, sync_mode, &val64);
  10286 
  10287     if (rv >= 0) {
  10288         COMPILER_64_TO_32_LO(*val, val64);
  10289     }
  10290 
  10291     return rv;
  10292 }
  10293 
  10294 /*
  10295  * Function:
  10296  *      soc_counter_sync_get, soc_counter_sync_get32
  10297  * Purpose:
  10298  *      Given a counter register and port number, sync the
  10299  *      counter value from the device register to the sw accumulated
  10300  *      value.
  10301  * Parameters:
  10302  *      unit - StrataSwitch unit #.
  10303  *      port - StrataSwitch port #.
  10304  *      ctr_reg - counter register to retrieve.
  10305  *      val - (OUT) 64/32-bit counter value.
  10306  * Returns:
  10307  *      SOC_E_XXX.
  10308  */
  10309 
  10310 int
  10311 soc_counter_sync_get(int unit, soc_port_t port, soc_reg_t ctr_reg,
  10312                      int ar_idx, uint64 *val)
  10313 {
  10314     int sync_mode = TRUE; /* read register */
  10315     return _soc_counter_get(unit, port, ctr_reg, ar_idx,
  10316                             FALSE, sync_mode, val);
  10317 }
  10318 
  10319 int
  10320 soc_counter_sync_get32(int unit, soc_port_t port, soc_reg_t ctr_reg,
  10321                        int ar_idx, uint32 *val)
  10322 {
  10323     uint64              val64;
  10324     int                 rv;
  10325     int                 sync_mode = TRUE; /* read register */
  10326 
  10327     rv = _soc_counter_get(unit, port, ctr_reg, ar_idx,
  10328                           FALSE, sync_mode, &val64);
  10329 
  10330     if (rv >= 0) {
  10331         COMPILER_64_TO_32_LO(*val, val64);
  10332     }
  10333 
  10334     return rv;
  10335 }
  10336 
  10337 int
  10338 soc_counter_direct_get(int unit, soc_port_t port, soc_reg_t ctr_reg,
  10339                        int ar_idx, uint64 *val)
  10340 {
  10341     int                 port_index, num_entries;
  10342     int                 port_base, index;
  10343     char                *cname;
  10344     uint64              value = COMPILER_64_INIT(0, 0);
  10345 
  10346     port_base = COUNTER_MIN_IDX_GET(unit, port);
  10347     SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, ctr_reg,
  10348                                               &port_index, &num_entries,
  10349                                               &cname));
  10350     if (ar_idx >= num_entries) {
  10351         return SOC_E_PARAM;
  10352     }
  10353     index = port_index - port_base;
  10354     ctr_reg = PORT_CTR_REG(unit, port, index)->reg;
  10355     ar_idx = PORT_CTR_REG(unit, port, index)->index;
  10356     if (!SOC_COUNTER_INVALID(unit, ctr_reg)) {
  10357 #ifdef SOC_COUNTER_TABLE_SUPPORT
  10358 #if defined (BCM_TOMAHAWK3_SUPPORT)
  10359         if (SOC_IS_TOMAHAWK3(unit) &&
  10360             SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) {
  10361             soc_ctr_tbl_entry_t *ctr_tbl_info_entry = NULL;
  10362             SOC_IF_ERROR_RETURN
  10363                 (_soc_counter_tbl_get_info(unit, port, ctr_reg, &ctr_tbl_info_entry));
  10364             SOC_IF_ERROR_RETURN
  10365                 (_soc_ctr_tbl_field_get(unit, ctr_reg, port, ctr_tbl_info_entry, &value));
  10366         } else
  10367 #endif /* BCM_TOMAHAWK3_SUPPORT */
  10368 #endif /* SOC_COUNTER_TABLE_SUPPORT */
  10369         {
  10370             SOC_IF_ERROR_RETURN(soc_reg_get(unit, ctr_reg, port, ar_idx,
  10371                                             &value));
  10372         }
  10373     }
  10374 
  10375     *val = value;
  10376 
  10377     return SOC_E_NONE;
  10378 }
  10379 
  10380 #ifdef BCM_TOMAHAWK_SUPPORT
  10381 STATIC int
  10382 _soc_counter_generic_get_delta(int unit, soc_ctr_control_info_t ctrl_info,
  10383                               soc_reg_t ctr_reg, int ar_idx, uint64 *value)
  10384 {
  10385     int base_index, num_entries;
  10386     soc_control_t   *soc = SOC_CONTROL(unit);
  10387     COUNTER_ATOMIC_DEF  s = SOC_CONTROL(unit);
  10388     int pipe_max_idx = 0;
  10389     uint64 *vptr;
  10390     uint64 val;
  10391 
  10392     COMPILER_64_ZERO(*value);
  10393 
  10394     SOC_IF_ERROR_RETURN
  10395         (soc_counter_generic_get_info(unit, ctrl_info, ctr_reg,
  10396                                       &base_index, &num_entries));
  10397 
  10398     if (ar_idx >= num_entries) {
  10399         return SOC_E_PARAM;
  10400     }
  10401 
  10402     if (((ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) &&
  10403         (ctrl_info.instance == -1)) || (ctrl_info.instance_type ==
  10404         SOC_CTR_INSTANCE_TYPE_POOL)) {
  10405         pipe_max_idx = base_index + (NUM_PIPE(unit) * num_entries);
  10406     }
  10407 
  10408     if (ar_idx > 0 && ar_idx < num_entries) {
  10409         base_index += ar_idx;
  10410     }
  10411 
  10412     if (soc->counter_interval == 0) {
  10413         COMPILER_64_ZERO(*value);
  10414     } else {
  10415         do {
  10416             if ((ctr_reg >= NUM_SOC_REG) &&
  10417                 (soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].flags &
  10418                 _SOC_COUNTER_NON_DMA_CURRENT)) {
  10419                 return SOC_E_PARAM;
  10420             } else {
  10421                 vptr = &soc->counter_delta[base_index];
  10422             }
  10423             COUNTER_ATOMIC_BEGIN(s);
  10424             val = *vptr;
  10425             COUNTER_ATOMIC_END(s);
  10426             base_index += num_entries;
  10427             COMPILER_64_ADD_64(*value, val);
  10428         } while (base_index < pipe_max_idx);
  10429     }
  10430     return SOC_E_NONE;
  10431 
  10432 }
  10433 
  10434 STATIC int
  10435 soc_counter_generic_get_delta(int unit, soc_ctr_control_info_t ctrl_info,
  10436                               soc_reg_t ctr_reg, int ar_idx, uint64 *value)
  10437 {
  10438     soc_control_t   *soc = SOC_CONTROL(unit);
  10439     int rv = SOC_E_NONE;
  10440     soc_info_t *si = &SOC_INFO(unit);
  10441     uint64 val;
  10442     int pipe, xpe, port;
  10443 
  10444     COMPILER_64_ZERO(*value);
  10445     COMPILER_64_ZERO(val);
  10446 
  10447     if (ctr_reg >= SOC_COUNTER_NON_DMA_END) {
  10448         return SOC_E_PARAM;
  10449     }
  10450 
  10451     if (!(soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].flags)) {
  10452         return SOC_E_UNAVAIL;
  10453     }
  10454 
  10455     if ((ctr_reg >= SOC_COUNTER_NON_DMA_START) &&
  10456         (ctr_reg < SOC_COUNTER_NON_DMA_END)) {
  10457         soc_mem_t mem = soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].mem;
  10458         soc_reg_t reg = soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].reg;
  10459         soc_ctr_control_info_t input_ctrl_info[2], output_ctrl_info;
  10460         /* Each XPE maps to a pair of IPIPE or EPIPE based on memory type.
  10461          * Hence loop through all applicable XPEs for a given pipe and return
  10462          * accumulated value*/
  10463         if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_XPE) {
  10464             port = ctrl_info.instance;
  10465             pipe = si->port_pipe[port];
  10466             if (mem != INVALIDm) {
  10467                 input_ctrl_info[0].instance_type = ctrl_info.instance_type;
  10468                 input_ctrl_info[1].instance = ctrl_info.instance;
  10469                 input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
  10470 
  10471                 for (xpe = 0; xpe < NUM_XPE(unit) ; xpe++) {
  10472                     input_ctrl_info[0].instance = xpe;
  10473                     if (mem == MMU_CTR_COLOR_DROP_MEMm) {
  10474                         /* Get valid XPE/Pipe Combination */
  10475                         if(!((si->epipe_xpe_map[pipe] >> xpe) & 1)) {
  10476                             continue;
  10477                         }
  10478                     } else {
  10479                         if (SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit,mem,xpe,pipe) == INVALIDm) {
  10480                             /* Invalid XPE/Pipe Combination */
  10481                             continue;
  10482                         }
  10483                     }
  10484                     soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info);
  10485                     rv = _soc_counter_generic_get_delta(unit, output_ctrl_info,
  10486                                                   ctr_reg, ar_idx,
  10487                                                   &val);
  10488                     if (rv != SOC_E_NONE) {
  10489                         return rv;
  10490                     }
  10491                     /* Sum values from all valid xpe-port combinations */
  10492                     COMPILER_64_ADD_64(*value, val);
  10493                 }
  10494             } else if (reg != INVALIDr) {
  10495                 input_ctrl_info[0].instance_type = ctrl_info.instance_type;
  10496 
  10497                 for (xpe = 0; xpe < NUM_XPE(unit) ; xpe++) {
  10498                     input_ctrl_info[0].instance = xpe;
  10499                     if (reg == THDI_POOL_SHARED_COUNT_SPr) {
  10500                         /* Get valid XPE/Pipe Combination */
  10501                         if(!((si->ipipe_xpe_map[pipe] >> xpe) & 1)) {
  10502                             continue;
  10503                         }
  10504                     }
  10505                     rv = _soc_counter_generic_get_delta(unit, input_ctrl_info[0],
  10506                                                   ctr_reg, ar_idx,
  10507                                                   &val);
  10508                     if (rv != SOC_E_NONE) {
  10509                         return rv;
  10510                     }
  10511                     /* Sum values from all valid xpe-port combinations */
  10512                     COMPILER_64_ADD_64(*value, val);
  10513                 }
  10514             }
  10515 #ifdef BCM_TOMAHAWK3_SUPPORT
  10516         } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_ITM) {
  10517             uint16 itm;
  10518             port = ctrl_info.instance;
  10519             pipe = si->port_pipe[port];
  10520             input_ctrl_info[0].instance_type = ctrl_info.instance_type;
  10521             input_ctrl_info[1].instance = ctrl_info.instance;
  10522             input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
  10523             for (itm = 0; itm < NUM_ITM(unit) ; itm++) {
  10524                 input_ctrl_info[0].instance = itm;
  10525 
  10526                 soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info);
  10527                 rv = _soc_counter_generic_get_delta(unit, output_ctrl_info,
  10528                                               ctr_reg, ar_idx,
  10529                                               &val);
  10530                 if (rv != SOC_E_NONE) {
  10531                     return rv;
  10532                 }
  10533                 /* Sum values for a counter from all ITMs */
  10534                 COMPILER_64_ADD_64(*value, val);
  10535             }
  10536 #endif
  10537         } else {
  10538             rv = _soc_counter_generic_get_delta(unit, ctrl_info, ctr_reg, ar_idx,
  10539                                                 value);
  10540         }
  10541     } else {
  10542             rv = _soc_counter_generic_get_delta(unit, ctrl_info, ctr_reg, ar_idx,
  10543                                                 value);
  10544     }
  10545 
  10546     return rv;
  10547 }
  10548 
  10549 STATIC int
  10550 soc_counter_generic_get_rate(int unit, soc_ctr_control_info_t ctrl_info,
  10551                              soc_reg_t ctr_reg, int ar_idx, uint64 *rate)
  10552 {
  10553     soc_control_t   *soc = SOC_CONTROL(unit);
  10554     uint64 value;
  10555 
  10556     COMPILER_64_ZERO(value);
  10557     COMPILER_64_ZERO(*rate);
  10558 
  10559     SOC_IF_ERROR_RETURN
  10560         (soc_counter_generic_get_delta(unit, ctrl_info, ctr_reg, ar_idx,
  10561                                         &value));
  10562 
  10563     if (soc->counter_interval == 0) {
  10564         COMPILER_64_ZERO(*rate);
  10565     } else {
  10566 #ifdef  COMPILER_HAS_DOUBLE
  10567         /*
  10568          * This uses floating point right now because uint64 multiply/divide
  10569          * support is missing from many compiler libraries.
  10570          */
  10571 
  10572         #define UINT32_MAX_VALUE (4294967296.0)
  10573         uint32          ratedblHI, ratedblLO;
  10574         double          interval, delta, ratedbl;
  10575 
  10576         delta = COMPILER_64_HI(value) * UINT32_MAX_VALUE +
  10577                 COMPILER_64_LO(value);
  10578 
  10579         interval = SAL_USECS_SUB(soc->counter_coll_cur,
  10580                                  soc->counter_coll_prev) / 1000000.0;
  10581 
  10582         if (interval < 0.0001) {
  10583             COMPILER_64_SET(*rate, 0, 0);
  10584         } else {
  10585             ratedbl = (delta / interval + 0.5);
  10586             ratedblHI = (uint32)(ratedbl / UINT32_MAX_VALUE);
  10587             ratedblLO = (uint32)(ratedbl - ratedblHI * UINT32_MAX_VALUE);
  10588 
  10589             COMPILER_64_SET(*rate, ratedblHI, ratedblLO);
  10590         }
  10591 
  10592 #else   /* !COMPILER_HAS_DOUBLE */
  10593         uint32          delta32, rate32;
  10594         int             interval;
  10595 
  10596         COMPILER_64_TO_32_LO(delta32, value);
  10597 
  10598         interval = SAL_USECS_SUB(soc->counter_coll_cur, soc->counter_coll_prev);
  10599 
  10600         if (interval < 100) {
  10601             rate32 = 0;
  10602         } else {
  10603             rate32 = _shr_div_exp10(delta32, interval, 6);
  10604         }
  10605 
  10606         COMPILER_64_SET(*rate, 0, rate32);
  10607 #endif  /* !COMPILER_HAS_DOUBLE */
  10608     }
  10609     return SOC_E_NONE;
  10610 }
  10611 #endif  /* BCM_TOMAHAWK_SUPPORT */
  10612 
  10613 /*
  10614  * Function:
  10615  *      soc_counter_get_rate
  10616  * Purpose:
  10617  *      Returns the counter incrementing rate in units of 1/sec.
  10618  * Parameters:
  10619  *      unit - StrataSwitch unit #.
  10620  *      port - StrataSwitch port #.
  10621  *      ctr_reg - counter register to retrieve.
  10622  *      rate - (OUT) 64-bit rate value.
  10623  * Returns:
  10624  *      SOC_E_XXX.
  10625  */
  10626 
  10627 int
  10628 soc_counter_get_rate(int unit, soc_port_t port,
  10629                      soc_reg_t ctr_reg, int ar_idx, uint64 *rate)
  10630 {
  10631     soc_control_t       *soc = SOC_CONTROL(unit);
  10632     int                 port_index, num_entries;
  10633 
  10634 #ifdef BCM_TOMAHAWK_SUPPORT
  10635     if (SOC_IS_TOMAHAWKX(unit) &&
  10636         (ctr_reg >= SOC_COUNTER_NON_DMA_START) &&
  10637         (ctr_reg < SOC_COUNTER_NON_DMA_END)) {
  10638         soc_ctr_control_info_t ctrl_info;
  10639         int mem = soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].mem;
  10640 
  10641         if (soc_tomahawk_mem_is_xpe(unit, mem)) {
  10642             ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_XPE;
  10643         }
  10644 #ifdef BCM_TOMAHAWK3_SUPPORT
  10645         else if (soc_tomahawk3_mem_is_itm(unit, mem)) {
  10646             ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_ITM;
  10647 
  10648             /* some exceptions here */
  10649             if(SOC_MEM_IS_VALID(unit, mem)) {
  10650                 switch(mem) {
  10651                     case MMU_THDO_SRC_PORT_DROP_COUNTm:
  10652                         ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
  10653                     break;
  10654                     default:
  10655                     break;
  10656                 }
  10657             }
  10658         }
  10659 #endif /* BCM_TOMAHAWK3_SUPPORT */
  10660         else {
  10661             ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
  10662         }
  10663         ctrl_info.instance = port;
  10664         return soc_counter_generic_get_rate(unit, ctrl_info, ctr_reg,
  10665                                             ar_idx, rate);
  10666     }
  10667 #endif
  10668     SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, ctr_reg,
  10669                                               &port_index, &num_entries,
  10670                                               NULL));
  10671     if (ar_idx >= num_entries) {
  10672         return SOC_E_PARAM;
  10673     }
  10674 
  10675     if (ar_idx > 0 && ar_idx < num_entries) {
  10676         port_index += ar_idx;
  10677     }
  10678 
  10679     if (soc->counter_interval == 0) {
  10680         COMPILER_64_ZERO(*rate);
  10681     } else {
  10682 #ifdef  COMPILER_HAS_DOUBLE
  10683         /*
  10684          * This uses floating point right now because uint64 multiply/divide
  10685          * support is missing from many compiler libraries.
  10686          */
  10687 
  10688         #define UINT32_MAX_VALUE (4294967296.0)
  10689         uint32          ratedblHI, ratedblLO;
  10690         double          interval, delta, ratedbl;
  10691 
  10692         delta = COMPILER_64_HI(soc->counter_delta[port_index]) * UINT32_MAX_VALUE +
  10693                 COMPILER_64_LO(soc->counter_delta[port_index]);
  10694 
  10695         interval = SAL_USECS_SUB(soc->counter_coll_cur,
  10696                                  soc->counter_coll_prev) / 1000000.0;
  10697 
  10698         if (interval < 0.0001) {
  10699             COMPILER_64_SET(*rate, 0, 0);
  10700         } else {
  10701             ratedbl = (delta / interval + 0.5);
  10702             ratedblHI = (uint32)(ratedbl / UINT32_MAX_VALUE);
  10703             ratedblLO = (uint32)(ratedbl - ratedblHI * UINT32_MAX_VALUE);
  10704 
  10705             COMPILER_64_SET(*rate, ratedblHI, ratedblLO);
  10706         }
  10707 
  10708 #else   /* !COMPILER_HAS_DOUBLE */
  10709         uint32          delta32, rate32;
  10710         int             interval;
  10711 
  10712         COMPILER_64_TO_32_LO(delta32, soc->counter_delta[port_index]);
  10713 
  10714         interval = SAL_USECS_SUB(soc->counter_coll_cur, soc->counter_coll_prev);
  10715 
  10716         if (interval < 100) {
  10717             rate32 = 0;
  10718         } else {
  10719             rate32 = _shr_div_exp10(delta32, interval, 6);
  10720         }
  10721 
  10722         COMPILER_64_SET(*rate, 0, rate32);
  10723 #endif  /* !COMPILER_HAS_DOUBLE */
  10724     }
  10725 
  10726     return SOC_E_NONE;
  10727 }
  10728 
  10729 /*
  10730  * Function:
  10731  *      soc_counter_get32_rate
  10732  * Purpose:
  10733  *      Returns the counter incrementing rate in units of 1/sec.
  10734  * Parameters:
  10735  *      unit - StrataSwitch unit #.
  10736  *      port - StrataSwitch port #.
  10737  *      ctr_reg - counter register to retrieve.
  10738  *      rate - (OUT) 32-bit delta value.
  10739  * Returns:
  10740  *      SOC_E_XXX.
  10741  */
  10742 
  10743 int
  10744 soc_counter_get32_rate(int unit, soc_port_t port,
  10745                        soc_reg_t ctr_reg, int ar_idx, uint32 *rate)
  10746 {
  10747     uint64              rate64;
  10748 
  10749     SOC_IF_ERROR_RETURN(soc_counter_get_rate(unit, port, ctr_reg,
  10750                                              ar_idx, &rate64));
  10751 
  10752     COMPILER_64_TO_32_LO(*rate, rate64);
  10753 
  10754     return SOC_E_NONE;
  10755 }
  10756 
  10757 /* Function:
  10758  *      soc_counter_generic_multi_get
  10759  * Purpose:
  10760  *      Given a counter register number, count, instance type and instance,
  10761  *      fetch multiple 64-bit software-accumulated counter values from
  10762  *      ar_idx to ar_idx + count.
  10763  * Parameter:
  10764  *      unit  - StrataSwitch Unit #.
  10765  *      ctr_reg - Counter Register to retrieve.
  10766  *      ctrl_info - Counter Control Info Structure
  10767  *                  Contains the instance type and instance.
  10768  *      flags - not yet implemented.
  10769  *      ar_idx - Base index of counter to be retrieved.
  10770  *      count - Number of entries to retrieve.
  10771  *      val - (OUT) Base address of array holding the 64-bit counter values.
  10772  *Returns:
  10773  *      SOC_E_XXX
  10774  *Notes:
  10775  *      If count is set to 0, nothing is retrieved
  10776 */
  10777 int
  10778 soc_counter_generic_multi_get(int unit, soc_reg_t ctr_reg,
  10779                               soc_ctr_control_info_t ctrl_info,
  10780                               uint32 flags, int ar_idx, int count,
  10781                               uint64 *val)
  10782 {
  10783     int sync_mode = soc_counter_sync_mode_get(unit);
  10784     int rv = SOC_E_NONE;
  10785     int i = 0; /* return value and iterator */
  10786     soc_control_t *soc = SOC_CONTROL(unit);
  10787     uint64 counter_val; /* value holder for each _soc_counter_generic_get call */
  10788     COMPILER_64_ZERO(counter_val);
  10789     
  10790     if (flags & SOC_COUNTER_SYNC_ENABLE) {
  10791         sync_mode = TRUE;
  10792     }
  10793     if (count < 0) {
  10794         return SOC_E_PARAM;
  10795     }
  10796 
  10797     if (soc->counter_non_dma == NULL) {
  10798         return SOC_E_RESOURCE;
  10799     }
  10800 
  10801     for (i = 0; i < count; i++) {
  10802         rv = _soc_counter_generic_get(unit, ctrl_info, ctr_reg, (ar_idx+i),
  10803                                         FALSE, sync_mode, &counter_val);
  10804         val[i] = counter_val;
  10805         if (rv!= SOC_E_NONE) {
  10806             return rv;
  10807         }
  10808     }
  10809     return rv;
  10810 
  10811 }
  10812 
  10813 STATIC int
  10814 _soc_distribute_u64(uint64 value, uint64 *l, uint64 *r)
  10815 {
  10816     uint64 tmp, tmp1; 
  10817     tmp = value;
  10818     COMPILER_64_SHR(tmp, 1);
  10819     *l = tmp;   
  10820     COMPILER_64_SET(tmp1, 0, 1);
  10821     COMPILER_64_AND(tmp1, value);
  10822     COMPILER_64_ADD_64(tmp1, tmp);
  10823     *r = tmp1;
  10824     return 0;
  10825 }
  10826 
  10827 /*
  10828  * Function:
  10829  *      soc_counter_set, soc_counter_set32
  10830  * Purpose:
  10831  *      Given a counter register number, port number, and a counter
  10832  *      value, set both the hardware and software-accumulated counters
  10833  *      to the value.
  10834  * Parameters:
  10835  *      unit - StrataSwitch unit #.
  10836  *      port - StrataSwitch port #.
  10837  *      ctr_reg - counter register to retrieve.
  10838  *      val - 64/32-bit counter value.
  10839  * Returns:
  10840  *      SOC_E_XXX
  10841  * Notes:
  10842  *      The 32-bit version sets the upper 32-bits of the 64-bit
  10843  *      software counter to zero.  The specified value is truncated
  10844  *      to the width of the hardware register when storing to hardware.
  10845  *      Use the value 0 to clear counters.
  10846  */
  10847 
  10848 STATIC int
  10849 _soc_counter_set(int unit, soc_port_t port, soc_reg_t ctr_reg,
  10850                  int ar_idx, uint64 val64)
  10851 {
  10852     soc_control_t       *soc = SOC_CONTROL(unit);
  10853     int                 port_index, num_entries;
  10854     int                 index_min, index_max, index;
  10855     soc_counter_non_dma_t *non_dma;
  10856     uint32              entry[SOC_MAX_MEM_FIELD_WORDS], fval[2];
  10857     int                 dma_base_index;
  10858     soc_mem_t           dma_mem;
  10859     COUNTER_ATOMIC_DEF  s = SOC_CONTROL(unit);
  10860     int         rv = SOC_E_NONE;
  10861     int                 prime_ctr_write, i;
  10862     uint32              val32;
  10863     int numpipe = 0;     
  10864     int ctr_is_readonly = 0;
  10865 #ifdef BCM_KATANA_SUPPORT
  10866     uint32              pkt_count = 0;
  10867 #endif /* BCM_KATANA_SUPPORT */
  10868     int qindex = -1;
  10869 #ifdef BCM_KATANA2_SUPPORT
  10870       int j=0;
  10871 #endif 
  10872 #if defined(BCM_SABER2_SUPPORT) || defined(BCM_KATANA_SUPPORT)
  10873     uint16 dev_id;
  10874     uint8 rev_id;
  10875 #endif
  10876 #ifdef BCM_TRIUMPH3_SUPPORT
  10877     int skip_hw_set = 0;
  10878 #endif
  10879 
  10880 #ifdef BCM_TOMAHAWK_SUPPORT
  10881     if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit))&&
  10882         (ctr_reg >= SOC_COUNTER_NON_DMA_START) &&
  10883         (ctr_reg < SOC_COUNTER_NON_DMA_END)) {
  10884         soc_ctr_control_info_t ctrl_info;
  10885         if (IS_LB_PORT(unit, port)) {
  10886             /* Do nothing for LB port */
  10887             return SOC_E_NONE;
  10888         }
  10889         non_dma = &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START];
  10890         if (soc_tomahawk_mem_is_xpe(unit, non_dma->mem)) {
  10891             ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_XPE;
  10892         }
  10893 #ifdef BCM_FLOWTRACKER_SUPPORT
  10894         else if ((ctr_reg >=
  10895             SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_NUM_EXCEEDED_CNT) &&
  10896             (ctr_reg <= SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_METER_EXCEEDED_CNT)) {
  10897             ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_FT_GROUP;
  10898         }
  10899 #endif
  10900 #ifdef BCM_TOMAHAWK3_SUPPORT
  10901         else if (soc_tomahawk3_mem_is_itm(unit, non_dma->mem) ||
  10902                  soc_tomahawk3_reg_is_itm(unit, non_dma->reg)) {
  10903             ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_ITM;
  10904 
  10905             /* some exceptions here */
  10906             if(SOC_MEM_IS_VALID(unit, non_dma->mem)) {
  10907                 switch(non_dma->mem) {
  10908                     case MMU_THDO_SRC_PORT_DROP_COUNTm:
  10909                         ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
  10910                     break;
  10911                     default:
  10912                     break;
  10913                 }
  10914             }
  10915         }
  10916 #endif /* BCM_TOMAHAWK3_SUPPORT */
  10917         else {
  10918             ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
  10919         }
  10920         ctrl_info.instance = port;
  10921 
  10922         if (ctr_reg == SOC_COUNTER_NON_DMA_SFLOW_ING_PKT ||
  10923             ctr_reg == SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT)
  10924         {
  10925             if (ar_idx == -1) {
  10926                 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_SFLOW;
  10927                 ctrl_info.instance = -1;
  10928                 ar_idx = port;
  10929             }
  10930         }
  10931         return soc_counter_generic_set(unit, ctr_reg, ctrl_info, 0,
  10932                                        ar_idx, val64);
  10933     }
  10934 #endif /* BCM_TOMAHAWK_SUPPORT */
  10935 #ifdef BCM_MONTEREY_SUPPORT
  10936     if (SOC_IS_MONTEREY(unit) &&
  10937         (ctr_reg >= SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO) &&
  10938         (ctr_reg <= SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS)) {
  10939         soc_ctr_control_info_t ctrl_info;
  10940         if (IS_LB_PORT(unit, port) ||
  10941             IS_RDB_PORT(unit, port) ||
  10942             IS_MACSEC_PORT(unit, port) ||
  10943             IS_CPU_PORT(unit, port)) {
  10944             /* Do nothing for LB port */
  10945             return SOC_E_NONE;
  10946         }
  10947         ctrl_info.instance = port;
  10948         ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
  10949         return soc_counter_generic_set(unit, ctr_reg, ctrl_info, 0,
  10950                                        ar_idx, val64);
  10951     }
  10952 #endif
  10953 #ifdef BCM_APACHE_SUPPORT
  10954     if (SOC_IS_APACHE(unit) && 
  10955         (ctr_reg >= SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO) &&
  10956         (ctr_reg <= SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1)) {
  10957         soc_ctr_control_info_t ctrl_info;
  10958         if (IS_LB_PORT(unit, port) ||
  10959             IS_CPU_PORT(unit, port)) {
  10960             /* Do nothing for LB port */
  10961             return SOC_E_NONE;
  10962         }
  10963         ctrl_info.instance = port;
  10964         ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
  10965         return soc_counter_generic_set(unit, ctr_reg, ctrl_info, 0,
  10966                                        ar_idx, val64);
  10967     }
  10968 #endif
  10969     SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, ctr_reg,
  10970                                               &port_index, &num_entries,
  10971                                               NULL));
  10972     if (ar_idx >= num_entries) {
  10973         return SOC_E_PARAM;
  10974     }
  10975 
  10976     if (ar_idx < 0) {
  10977         index_min = 0;
  10978         index_max = num_entries - 1;
  10979     } else {
  10980         index_min = index_max = ar_idx;
  10981     }
  10982 
  10983 /*
  10984  * Wait for dma counter processing completion
  10985  */
  10986 #ifdef BCM_SBUSDMA_SUPPORT
  10987         while (_soc_counter_pending[unit] && soc->counter_interval) {
  10988             sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 100);
  10989         }
  10990 #endif
  10991 
  10992     COUNTER_LOCK(unit);
  10993 #ifdef BCM_KATANA2_SUPPORT
  10994 /* 
  10995  * We are looping twice to set the mc stats in case of packing mode 
  10996 */
  10997     for (j=0; j<2; j++) { 
  10998         if( j == 1) {
  10999             if( SOC_IS_KATANA2(unit) && soc_feature(unit, 
  11000                                   soc_feature_mmu_packing) ) {
  11001                rv = _soc_counter_katana2_get_mcindex(unit, port, ctr_reg,
  11002                                             &port_index, &num_entries);
  11003                if (SOC_FAILURE(rv)) {
  11004                    goto counter_set_done;
  11005                }
  11006                if(port_index == -1) { 
  11007                   continue; 
  11008                }
  11009             }
  11010             else {
  11011                continue;
  11012             } 
  11013          }
  11014 #else 
  11015       { 
  11016 #endif       
  11017 
  11018     for (index = index_min; index <= index_max; index++) {
  11019         ctr_is_readonly = 0;
  11020 #ifdef BCM_TRIUMPH3_SUPPORT
  11021         skip_hw_set = 0;
  11022 #endif
  11023 #if defined(BCM_PETRA_SUPPORT)
  11024     if (!_SOC_CONTROLLED_COUNTER_USE(unit, port)) {
  11025 #endif
  11026         if ((ctr_reg >= SOC_COUNTER_NON_DMA_START) &&
  11027             (ctr_reg < SOC_COUNTER_NON_DMA_END)) {
  11028             non_dma = &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START];
  11029             if (non_dma->flags & (_SOC_COUNTER_NON_DMA_PEAK |
  11030                                   _SOC_COUNTER_NON_DMA_CURRENT)) {
  11031                 continue;
  11032             }
  11033 
  11034             if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
  11035                 goto counter_set_done;
  11036             } else if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
  11037                 (non_dma->extra_ctrs != NULL)) {
  11038                 goto counter_set_done;
  11039             }
  11040 
  11041             if (non_dma->mem != INVALIDm) {
  11042                 dma_mem = non_dma->dma_mem[0];
  11043                 dma_base_index = port_index - non_dma->base_index +
  11044                     non_dma->dma_index_min[0];
  11045 #if defined (BCM_METROLITE_SUPPORT)
  11046                if (SOC_IS_METROLITE(unit)) {
  11047                    numpipe = 1;
  11048                } else 
  11049 #endif
  11050 #ifdef BCM_SABER2_SUPPORT
  11051                if ( SOC_IS_SABER2(unit) ) {
  11052                    soc_cm_get_id(unit, &dev_id, &rev_id);
  11053                    if (dev_id == BCM56233_DEVICE_ID) {
  11054                        numpipe = 1;
  11055                    } else {
  11056                     numpipe = 2; 
  11057                    }
  11058                } else 
  11059 #endif
  11060 
  11061 #if defined (BCM_KATANA2_SUPPORT)
  11062                if ( SOC_IS_KATANA2(unit) ) {
  11063                     numpipe = 4;
  11064                } else 
  11065 #endif
  11066 #if defined (BCM_KATANA_SUPPORT) 
  11067               if ( SOC_IS_KATANA(unit)) {
  11068                     numpipe = 4;
  11069                     soc_cm_get_id(unit, &dev_id, &rev_id);
  11070                     if ((dev_id == BCM56445_DEVICE_ID)|| (dev_id == BCM56446_DEVICE_ID)||
  11071                         (dev_id == BCM56447_DEVICE_ID)|| (dev_id == BCM56448_DEVICE_ID)|| 
  11072                         (dev_id == BCM55441_DEVICE_ID)) {
  11073                         numpipe = 1;
  11074                     }
  11075                } else 
  11076 #endif
  11077                {  
  11078                     numpipe = SOC_INFO(unit).num_pipe;  
  11079                }
  11080                 for (i = 1; i < numpipe; i++) {
  11081                     if (non_dma->dma_mem[i] != INVALIDm &&
  11082                             dma_base_index > non_dma->dma_index_max[i - 1]) {
  11083                         dma_mem = non_dma->dma_mem[i];
  11084                         dma_base_index -= non_dma->dma_index_max[i - 1] + 1;
  11085                         dma_base_index += non_dma->dma_index_min[i];
  11086                     }
  11087                 }
  11088 
  11089                 /* Need to retrieve the table index 
  11090                  * for flexible mapping Non-DMA counter*/
  11091                 if (non_dma->flags & _SOC_COUNTER_NON_DMA_FLEX_MAPPING) {
  11092                     if (non_dma->soc_counter_hw_idx_get == NULL) {
  11093                         continue;
  11094                     }                     
  11095                     rv = non_dma->soc_counter_hw_idx_get(unit, port, 
  11096                             dma_base_index + index, &qindex);
  11097                     if (SOC_FAILURE(rv)) {
  11098                         goto counter_set_done;
  11099                     }
  11100                     if (-1 == qindex) {
  11101                         continue;
  11102                     }
  11103                 } else {
  11104                     qindex = dma_base_index + index;
  11105                 }
  11106 
  11107                 rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY, qindex, entry);
  11108                 if (SOC_FAILURE(rv)) {
  11109                     goto counter_set_done;
  11110                 }
  11111 #ifdef BCM_KATANA_SUPPORT
  11112                 if ((SOC_IS_KATANA(unit)) &&
  11113                         (!soc_feature(unit, soc_feature_counter_toggled_read))) {
  11114                     soc_mem_field_get(unit, dma_mem, entry, COUNTf, &pkt_count);
  11115                     if (!SAL_BOOT_BCMSIM) {
  11116                         if (pkt_count) {
  11117                             pkt_count -= 1;
  11118                         }
  11119                     }
  11120                     soc_mem_field_set(unit, dma_mem, entry,
  11121                             COUNTf, &pkt_count);
  11122 
  11123                 }
  11124 #endif
  11125                 fval[0] = COMPILER_64_LO(val64);
  11126                 fval[1] = COMPILER_64_HI(val64);
  11127                 soc_mem_field_set(unit, dma_mem, entry,
  11128                         non_dma->field, fval);
  11129 
  11130                 /*
  11131                  * If parity is not enabled on the device
  11132                  * set the parity bit in the MMU_CTR_UC_DROP_MEMm
  11133                  * during counter set as suggested by DE.
  11134                  */
  11135                 if (SOC_IS_TRIDENT(unit) || SOC_IS_TRIUMPH3(unit)) {
  11136                     uint32 rval = 0; 
  11137                     if (dma_mem == MMU_CTR_UC_DROP_MEMm) {
  11138                         rv = READ_MISCCONFIGr(unit, &rval);
  11139                         if (SOC_SUCCESS(rv)) {
  11140                             if (!soc_reg_field_get(unit, MISCCONFIGr, 
  11141                                                    rval, PARITY_GEN_ENf)) {
  11142                                 soc_mem_field32_set(unit, dma_mem, entry,
  11143                                                     PARITYf, 0);
  11144                                 if (COMPILER_64_IS_ZERO(val64)) {
  11145 	  	  	 	                        sal_memset(entry, 0, sizeof(entry));
  11146                                 }
  11147                             }
  11148                         }
  11149                     }
  11150                 }
  11151 
  11152                 rv = soc_mem_write(unit, dma_mem, MEM_BLOCK_ALL, qindex, entry);
  11153                 if (SOC_FAILURE(rv)) {
  11154                     goto counter_set_done;
  11155                 }
  11156 
  11157                 /* Check non-DMA counters (memory) is read-only or not */
  11158                 if (soc_mem_flags(unit, dma_mem) & SOC_MEM_FLAG_READONLY) {
  11159                     ctr_is_readonly = 1;
  11160                 }
  11161             } else if (non_dma->reg != INVALIDr) {
  11162                 if (port < 0) {
  11163                     rv = SOC_E_PARAM;
  11164                     goto counter_set_done;
  11165                 }
  11166 
  11167                 /* Check non-DMA counters (register) is read-only or not */
  11168                 if (SOC_REG_INFO(unit, non_dma->reg).flags & SOC_REG_FLAG_RO) {
  11169                     ctr_is_readonly = 1;
  11170                 }
  11171 
  11172                 /* For Per port -> PBMP_MEMBER(non_dma->pbmp, port) is valid
  11173                  * and for system level counters it is invalid
  11174                  * For system level counters -> SOC_PBMP_IS_NULL is valid
  11175                  * and invalid for per port cases.
  11176                  */
  11177                 if (PBMP_MEMBER(non_dma->pbmp, port) ||
  11178                     (SOC_PBMP_IS_NULL(non_dma->pbmp) &&
  11179                     (non_dma->num_entries == 1))) {
  11180                     uint64 regval64;
  11181                     uint32 regval32;
  11182                     int base_index = 0;
  11183 
  11184                     if (SOC_IS_TR_VL(unit) || SOC_IS_SC_CQ(unit)) {
  11185                         if (non_dma->reg == TXLLFCMSGCNTr) {
  11186                             if (!IS_HG_PORT( unit, port)) {
  11187                                 continue;
  11188                             }
  11189                         }
  11190                     }
  11191 
  11192                     if (!ctr_is_readonly) { /* non-DMA counters (register) is not readonly */
  11193                     rv = soc_reg_get(unit, non_dma->reg,
  11194                             port, index, &regval64);
  11195                     if (SOC_FAILURE(rv)) {
  11196                         goto counter_set_done;
  11197                     }
  11198 
  11199                     if (SOC_REG_IS_64(unit, non_dma->reg)) {
  11200                         soc_reg64_field_set(unit, non_dma->reg, &regval64,
  11201                                 non_dma->field, val64);
  11202                     } else {
  11203                         regval32 = COMPILER_64_LO(regval64);
  11204                         soc_reg_field_set(unit, non_dma->reg, &regval32,
  11205                                 non_dma->field, COMPILER_64_LO(val64));
  11206                         COMPILER_64_SET(regval64, 0, regval32);
  11207                     }
  11208 
  11209                     rv = soc_reg_set(unit, non_dma->reg,
  11210                             port, index, regval64);
  11211                     if (SOC_FAILURE(rv)) {
  11212                         goto counter_set_done;
  11213                     }
  11214                     } else { /* non-DMA counters (register) is readonly */
  11215                         if (soc_feature(unit, soc_feature_tas)) {
  11216                             if (ctr_reg == SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_EXPRESS ||
  11217                                 ctr_reg == SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_PREEMPT) {
  11218                                 /* read-only register, only take value=0 to clear it */
  11219                                 if (!COMPILER_64_IS_ZERO(val64)) {
  11220                                     rv = SOC_E_UNAVAIL;
  11221                                     goto counter_set_done;
  11222                 }
  11223 
  11224                                 /*
  11225                                  * Both TAS_OVERRUN_PKT_CNT_EXPRESS/PREEMPT will be clear to 0
  11226                                  * by set 1 to TAS_OVERRUN_CNT_CLRf.
  11227                                  */
  11228                                 rv = soc_reg32_get(unit, TAS_GATE_PURGE_ENABLEr,
  11229                                                    port, index, &regval32);
  11230                                 if (SOC_FAILURE(rv)) {
  11231                                     goto counter_set_done;
  11232                                 }
  11233 
  11234                                 soc_reg_field_set(unit, TAS_GATE_PURGE_ENABLEr, &regval32,
  11235                                                   TAS_OVERRUN_CNT_CLRf, TRUE);
  11236 
  11237                                 rv = soc_reg32_set(unit, TAS_GATE_PURGE_ENABLEr,
  11238                                                    port, index, regval32);
  11239                                 if (SOC_FAILURE(rv)) {
  11240                                     goto counter_set_done;
  11241                                 }
  11242 
  11243                                 if (ctr_reg == SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_EXPRESS) {
  11244                                     /*
  11245                                       * Also need to clear software based counter value bufs
  11246                                       * sw_val/hw_val/delta for PREEMPT
  11247                                       */
  11248                                     rv = _soc_counter_get_info(
  11249                                              unit, port,
  11250                                              SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_PREEMPT,
  11251                                              &base_index, &num_entries, NULL);
  11252                                 } else {
  11253                                     /*
  11254                                       * Also need to clear software based counter value bufs
  11255                                       * sw_val/hw_val/delta for EXPRESS
  11256                                       */
  11257                                     rv = _soc_counter_get_info(
  11258                                              unit, port,
  11259                                              SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_EXPRESS,
  11260                                              &base_index, &num_entries, NULL);
  11261                                 }
  11262 
  11263                                 if (SOC_FAILURE(rv)) {
  11264                                     goto counter_set_done;
  11265                                 }
  11266 
  11267                                 /* The following section updates 64-bit values and must be atomic */
  11268                                 COUNTER_ATOMIC_BEGIN(s);
  11269                                 soc->counter_sw_val[base_index + index] = val64;
  11270                                 soc->counter_hw_val[base_index + index] = val64;
  11271                                 COMPILER_64_SET(soc->counter_delta[base_index + index], 0, 0);
  11272                                 COUNTER_ATOMIC_END(s);
  11273 
  11274                                 /* need to clear soc->counter_hw_val to match the hardware value */
  11275                                 ctr_is_readonly = 0;
  11276                             }
  11277                         }
  11278                     }
  11279                 }
  11280             }
  11281         } else if (ctr_reg != INVALIDr) {
  11282             if (port < 0) {
  11283                 rv = SOC_E_PARAM;
  11284                 goto counter_set_done;
  11285             }
  11286 
  11287 #ifdef BCM_TRIUMPH3_SUPPORT
  11288             if (SOC_IS_TRIUMPH3(unit) && (IS_HG_PORT(unit, port))
  11289                           && ((ctr_reg == RRPKTr) || (ctr_reg == RRBYTr)) ) {
  11290                     skip_hw_set = 1;
  11291                     ctr_is_readonly = 1;
  11292             }
  11293 #endif
  11294 
  11295 #ifdef SOC_COUNTER_TABLE_SUPPORT
  11296             if (SOC_REG_IS_COUNTER_TABLE (unit, ctr_reg)) {
  11297                 if (SOC_IS_TOMAHAWK3(unit)) {
  11298                     soc_ctr_tbl_entry_t *ctr_tbl_info_entry = NULL;
  11299                     SOC_IF_ERROR_RETURN
  11300                         (_soc_counter_tbl_get_info(unit, port, ctr_reg, &ctr_tbl_info_entry));
  11301                     SOC_IF_ERROR_RETURN
  11302                         (_soc_ctr_tbl_field_set(unit, ctr_reg, port, ctr_tbl_info_entry, &val64));
  11303                 } else {
  11304                     return SOC_E_PARAM;
  11305                 }
  11306             }
  11307             else 
  11308 #endif /* SOC_COUNTER_TABLE_SUPPORT */
  11309             if (!(SOC_REG_INFO(unit, ctr_reg).flags & SOC_REG_FLAG_64_BITS) &&
  11310                 !SOC_IS_XGS3_SWITCH(unit)) {
  11311                 val32 = COMPILER_64_LO(val64);
  11312                 rv = soc_reg32_set(unit, ctr_reg, port, index, val32);
  11313                 if (SOC_FAILURE(rv)) {
  11314                     goto counter_set_done;
  11315                 }
  11316             } else {
  11317                 if (soc_feature(unit, soc_feature_prime_ctr_writes) &&
  11318                     /*SOC_REG_INFO(unit, ctr_reg).block == SOC_BLK_EGR) {*/
  11319                     SOC_BLOCK_IS(SOC_REG_INFO(unit, ctr_reg).block, SOC_BLK_EGR)) {
  11320                     prime_ctr_write = TRUE;
  11321                 } else {
  11322                     prime_ctr_write = FALSE;
  11323                 }
  11324 
  11325                 if (prime_ctr_write) {
  11326                     rv = soc_reg32_get(unit, ctr_reg, port, index, &val32);
  11327                     if (SOC_FAILURE(rv)) {
  11328                         goto counter_set_done;
  11329                     }
  11330                 }
  11331 #ifdef BCM_TRIUMPH3_SUPPORT
  11332                 if (!skip_hw_set) {
  11333 #else
  11334                 {
  11335 #endif
  11336                 rv = soc_reg_set(unit, ctr_reg, port, index, val64);
  11337                 if (SOC_FAILURE(rv)) {
  11338                     goto counter_set_done;
  11339                 }
  11340                 }
  11341                 if (prime_ctr_write) {
  11342                     rv = soc_reg32_get(unit, ctr_reg, port, index, &val32);
  11343                     if (SOC_FAILURE(rv)) {
  11344                         goto counter_set_done;
  11345                     }
  11346                 }
  11347             }
  11348 
  11349             /* Check DMA counters (register) is read-only or not */
  11350             if (SOC_REG_IS_VALID(unit, ctr_reg) &&
  11351                 SOC_REG_INFO(unit, ctr_reg).flags & SOC_REG_FLAG_RO) {
  11352                 ctr_is_readonly = 1;
  11353             }
  11354         }
  11355 #if defined(BCM_PETRA_SUPPORT)
  11356     }
  11357 #endif
  11358         /* The following section updates 64-bit values and must be atomic */
  11359         COUNTER_ATOMIC_BEGIN(s);
  11360         soc->counter_sw_val[port_index + index] = val64;
  11361         /* 
  11362          * It checks if the counter is read-only. If so, only the soc->counter_sw_val is set and 
  11363          * soc->counter_hw_val is left untouched to match the hardware value.
  11364          */
  11365         if (!ctr_is_readonly) {
  11366             soc->counter_hw_val[port_index + index] = val64;
  11367         }
  11368         COMPILER_64_SET(soc->counter_delta[port_index + index], 0, 0);
  11369         COUNTER_ATOMIC_END(s);
  11370         /*
  11371           * For counter sync operation update the dma buffer
  11372           * for the port index with the value read from hardware
  11373           * counter register.
  11374           */
  11375          if ((ctr_reg != INVALIDr) &&
  11376              (!SOC_COUNTER_INVALID(unit, ctr_reg)) &&
  11377              (soc->counter_flags & SOC_COUNTER_F_DMA)) {
  11378              int ctr_idx;
  11379              uint32 *ptr;
  11380              int port_base_dma, port_base;
  11381              int  port_index, num_entries;
  11382              char *cname;
  11383 
  11384              /* get index of counter register */
  11385              SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, ctr_reg,
  11386                                                        &port_index,
  11387                                                        &num_entries,
  11388                                                        &cname));
  11389              port_base = COUNTER_MIN_IDX_GET(unit, port);
  11390              port_base_dma = COUNTER_MIN_IDX_GET(unit,
  11391                                                  port - soc->counter_ports32);
  11392              ctr_idx = port_index - port_base;
  11393 #ifdef BCM_SBUSDMA_SUPPORT
  11394              if (soc_feature(unit, soc_feature_sbusdma) &&
  11395                  (ctr_reg < NUM_SOC_REG) &&
  11396                  !SOC_REG_IS_64(unit, ctr_reg)) {
  11397                  uint32 *buf32 ;
  11398                      if (SOC_IS_TOMAHAWKX(unit)) {
  11399                          if (ctr_idx < soc->counter_egr_first) {
  11400                              buf32 = (uint32 *)&soc->counter_buf64[
  11401                                                      port_base_dma +
  11402                                                      soc->counter_ing_first];
  11403                              ptr = &buf32[ctr_idx - soc->counter_ing_first];
  11404                          } else {
  11405                              buf32 = (uint32 *)&soc->counter_buf64[
  11406                                                      port_base_dma +
  11407                                                      soc->counter_egr_first];
  11408                              ptr = &buf32[ctr_idx - soc->counter_egr_first];
  11409                          }
  11410                      } else {
  11411                          if (ctr_idx < soc->counter_egr_first) {
  11412                              buf32 = (uint32 *)&soc->counter_buf64[
  11413                                                      port_base_dma +
  11414                                                      soc->counter_ing_first];
  11415                              ptr = &buf32[ctr_idx - soc->counter_ing_first];
  11416                          } else if (ctr_idx < soc->counter_mac_first) {
  11417                              buf32 = (uint32 *)&soc->counter_buf64[
  11418                                                      port_base_dma +
  11419                                                      soc->counter_egr_first];
  11420                              ptr = &buf32[ctr_idx - soc->counter_egr_first];
  11421                          } else {
  11422                              buf32 = (uint32 *)&soc->counter_buf64[
  11423                                                      port_base_dma +
  11424                                                      soc->counter_mac_first];
  11425                              ptr = &buf32[ctr_idx - soc->counter_mac_first];
  11426                          }
  11427                      }
  11428                      COUNTER_ATOMIC_BEGIN(s);
  11429                      if (soc_reg_field_length(
  11430                                 unit, ctr_reg, COUNTf) == 32) {
  11431                          COMPILER_64_TO_32_LO(ptr[0], val64);
  11432                      } else {
  11433                          ptr[0] = COMPILER_64_LO(val64) &
  11434                                      ((1 << soc_reg_field_length
  11435                                              (unit, ctr_reg, COUNTf)) - 1);
  11436                      }
  11437                      COUNTER_ATOMIC_END(s);
  11438              } else
  11439 #endif /* BCM_SBUSDMA_SUPPORT */
  11440              {
  11441                  ptr = (uint32 *)&soc->counter_buf64[port_base_dma + ctr_idx];
  11442                  if (SOC_IS_TOMAHAWK3(unit) &&
  11443                      SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg) &&
  11444                      soc->counter_mib_tbl_first > 0) {
  11445                      /* For counter tables, dma_offset is obtained from SOC_CTR_TBL_INFO */
  11446                      int dma_offset = SOC_CTR_TBL_INFO(unit)->tables[ctr_idx - soc->counter_mib_tbl_first].dma_offset;
  11447                      ptr = (uint32 *)&soc->counter_buf64[port_base_dma + soc->counter_mib_tbl_first + dma_offset];
  11448                  }
  11449                  COUNTER_ATOMIC_BEGIN(s);
  11450                  /* Update the DMA location */
  11451                  if (soc->counter_flags & SOC_COUNTER_F_SWAP64) {
  11452                      COMPILER_64_TO_32_HI(ptr[0], val64);
  11453                      COMPILER_64_TO_32_LO(ptr[1], val64);
  11454                  } else {
  11455                      COMPILER_64_TO_32_LO(ptr[0], val64);
  11456                      COMPILER_64_TO_32_HI(ptr[1], val64);
  11457                  }
  11458                  COUNTER_ATOMIC_END(s);
  11459              }
  11460          }/* ctr_reg != INVALIDr */
  11461     }
  11462  }
  11463  counter_set_done:
  11464     COUNTER_UNLOCK(unit);
  11465     return rv;
  11466 }
  11467 
  11468 int
  11469 soc_counter_set(int unit, soc_port_t port, soc_reg_t ctr_reg,
  11470                 int ar_idx, uint64 val)
  11471 {
  11472     return _soc_counter_set(unit, port, ctr_reg, ar_idx, val);
  11473 }
  11474 
  11475 int
  11476 soc_counter_set32(int unit, soc_port_t port, soc_reg_t ctr_reg,
  11477                   int ar_idx, uint32 val)
  11478 {
  11479     uint64              val64;
  11480 
  11481     COMPILER_64_SET(val64, 0, val);
  11482 
  11483     return _soc_counter_set(unit, port, ctr_reg, ar_idx, val64);
  11484 }
  11485 
  11486 STATIC int
  11487 _soc_counter_generic_set(int unit, soc_ctr_control_info_t ctrl_info, soc_reg_t id,
  11488         int ar_idx, uint64 val)
  11489 {
  11490     soc_control_t       *soc = SOC_CONTROL(unit);
  11491     soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit);
  11492     int                 base_index, base_index_temp, num_entries,
  11493                         entries_per_pipe = 0;
  11494     int                 index_min, index_max, index;
  11495     soc_counter_non_dma_t *non_dma;
  11496     uint32              entry[SOC_MAX_MEM_FIELD_WORDS], fval[2];
  11497     int                 dma_base_index = 0;
  11498     soc_mem_t           dma_mem;
  11499     COUNTER_ATOMIC_DEF  s = SOC_CONTROL(unit);
  11500     int         rv = SOC_E_NONE;
  11501     int                 prime_ctr_write, i;
  11502     uint32              val32;
  11503     soc_port_t port = -1 ;
  11504     int subset_ct = 0, pipe = 0, pipe_start = 0, pipe_end = 0, all_pipe = 0;
  11505     uint8 clear_on_read = 0;
  11506     int field_len = 0;
  11507     uint64 masked_val;
  11508 #ifdef BCM_TOMAHAWK3_SUPPORT
  11509     uint16 dev_id;
  11510     uint8 rev_id;
  11511 
  11512     soc_cm_get_id(unit, &dev_id, &rev_id);
  11513 #endif
  11514     COMPILER_64_ZERO(masked_val);
  11515     if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PORT) {
  11516         port = ctrl_info.instance;
  11517 #ifdef BCM_TOMAHAWK3_SUPPORT
  11518         if (SOC_IS_TOMAHAWK3(unit) &&
  11519             SOC_CONTROL(unit)->em_halfchip == 1) {
  11520             pipe = SOC_INFO(unit).port_pipe[port];
  11521             if (pipe == 2 || pipe == 3 || pipe == 4 || pipe == 5) {
  11522                 return SOC_E_PARAM;
  11523             }
  11524         }
  11525 #endif
  11526     }
  11527 
  11528     SOC_IF_ERROR_RETURN
  11529         (soc_counter_generic_get_info(unit, ctrl_info, id,
  11530                                       &base_index, &num_entries));
  11531     base_index_temp = base_index;
  11532 
  11533     if ((ar_idx >= num_entries) || (ar_idx < -1)) {
  11534         return SOC_E_PARAM;
  11535     }
  11536 
  11537     if (ar_idx == -1) {
  11538         index_min = 0;
  11539         index_max = num_entries - 1;
  11540     } else {
  11541         index_min = index_max = ar_idx;
  11542     }
  11543 
  11544     COUNTER_LOCK(unit);
  11545     for (index = index_min; index <= index_max; index++) {
  11546         if (id >= NUM_SOC_REG) {
  11547             non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
  11548             if (non_dma->flags & (_SOC_COUNTER_NON_DMA_PEAK |
  11549                         _SOC_COUNTER_NON_DMA_CURRENT)) {
  11550                 continue;
  11551             }
  11552 
  11553             /* To iterate across pipes */
  11554             if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL_PIPE) {
  11555                 pipe = ctrl_info.instance & 0xF;
  11556                 if (pipe == -1) {
  11557                     all_pipe = 1;
  11558                 } else if (pipe >= NUM_PIPE(unit)) {
  11559                     return SOC_E_PARAM;
  11560                 }
  11561             } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL) {
  11562                    all_pipe = 1;
  11563             } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) {
  11564                 pipe = ctrl_info.instance;
  11565                 if (pipe == -1) {
  11566                     all_pipe = 1;
  11567                 } else if (pipe >= NUM_PIPE(unit)) {
  11568                     return SOC_E_PARAM;
  11569                 }
  11570 
  11571                 entries_per_pipe = num_entries;
  11572             }
  11573 
  11574             if (all_pipe == 1) {
  11575                 pipe_start = 0;
  11576                 pipe_end = NUM_PIPE(unit) - 1;
  11577             } else {
  11578                 pipe_start = pipe_end = pipe;
  11579             }
  11580 
  11581             if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID) &&
  11582                 !(non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
  11583                 goto counter_set_done;
  11584             } else if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
  11585                        (non_dma->extra_ctrs != NULL)) {
  11586                 /* If there is subset of counters, use subset info for DMA */
  11587                 non_dma = non_dma->extra_ctrs;
  11588 
  11589                 if ((ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL) ||
  11590                     (ctrl_info.instance_type ==
  11591                         SOC_CTR_INSTANCE_TYPE_POOL_PIPE)) {
  11592                     /* Decoding for POOL_PIPE and multiply by 2 for
  11593                      * parent-child model */
  11594                     entries_per_pipe = num_entries;
  11595                     if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL) {
  11596                         subset_ct = ctrl_info.instance << 1;
  11597                     } else {
  11598                         subset_ct = (ctrl_info.instance & 0x3F0) >> 3;
  11599                     }
  11600                 } else if (ctrl_info.instance_type ==
  11601                            SOC_CTR_INSTANCE_TYPE_ITM_PORT) {
  11602                     subset_ct =
  11603                         (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_ITM) >>
  11604                         CTR_INSTANCE_BIT_SHIFT_ITM;
  11605                     entries_per_pipe = non_dma->num_entries;
  11606                 } else if (ctrl_info.instance_type ==
  11607                            SOC_CTR_INSTANCE_TYPE_XPE_PORT) {
  11608                     /* Decoding for XPE_PORT and multiply by 2 for parent-child
  11609                      * model */
  11610                     subset_ct = (ctrl_info.instance & 0x3C00) >> 9;
  11611                     if ((non_dma->mem == MMU_CTR_COLOR_DROP_MEMm) && !SOC_IS_TOMAHAWK2(unit)) {  
  11612                         if (SOC_IS_TRIDENT3(unit)) {
  11613                             entries_per_pipe = non_dma->num_entries / 2;
  11614                         } else {
  11615                             entries_per_pipe = non_dma->num_entries;
  11616                         }
  11617                     } else {
  11618                         if (SOC_IS_HELIX5(unit) || SOC_IS_MAVERICK2(unit)) {
  11619                             entries_per_pipe = non_dma->num_entries;
  11620                         } else {
  11621                             entries_per_pipe = non_dma->num_entries / 2;
  11622                         }
  11623                     }
  11624                 } else if (ctrl_info.instance_type ==
  11625                            SOC_CTR_INSTANCE_TYPE_SFLOW) {
  11626                     subset_ct = ctrl_info.instance << 1;
  11627                     entries_per_pipe = non_dma->num_entries;
  11628                 } else if (ctrl_info.instance_type ==
  11629                            SOC_CTR_INSTANCE_TYPE_FT_GROUP) {
  11630                     subset_ct = ctrl_info.instance << 1;
  11631                     entries_per_pipe = non_dma->num_entries;
  11632 
  11633                 } else 
  11634 #ifdef BCM_APACHE_SUPPORT
  11635                 if (SOC_IS_APACHE(unit) &&
  11636                             (ctrl_info.instance_type ==
  11637                                 SOC_CTR_INSTANCE_TYPE_PORT)) {
  11638                     int obm_id, lane;
  11639                     SOC_IF_ERROR_RETURN
  11640                         (soc_apache_port_obm_info_get(unit, port, 
  11641                                                       &obm_id, &lane));
  11642                     entries_per_pipe = non_dma->num_entries;
  11643                     subset_ct = (obm_id << 1);
  11644                 } else 
  11645 #endif
  11646                 {
  11647                     entries_per_pipe = non_dma->num_entries;
  11648                     if (non_dma->mem != INVALIDm) {
  11649                         entries_per_pipe =
  11650                             soc_mem_index_count(unit, non_dma->dma_mem[0]);
  11651                     }
  11652                 }
  11653                 non_dma = non_dma + subset_ct;
  11654 
  11655                 if (!non_dma ||
  11656                     !(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
  11657                     goto counter_set_done;
  11658                 }
  11659             } else {
  11660                 if (non_dma->mem != INVALIDm) {
  11661                     if ((non_dma->mem == MMU_CTR_COLOR_DROP_MEMm) &&
  11662                         SOC_IS_TRIDENT3X(unit)) {
  11663                         entries_per_pipe = (non_dma->num_entries)/2;
  11664                     } else {
  11665                     entries_per_pipe =
  11666                         soc_mem_index_count(unit, non_dma->dma_mem[0]);
  11667                 }
  11668                 } else {
  11669                     entries_per_pipe = non_dma->num_entries;
  11670                 }
  11671             }
  11672 
  11673             if (non_dma->flags & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ) {
  11674                 clear_on_read = 1;
  11675             }
  11676             if (non_dma->mem != INVALIDm) {
  11677                 /* If CLR_ON_READ is enabled for the Counter, perform only 
  11678                  * Software updation.
  11679                  */
  11680                 /* Iterate across pipes for POOL and PIPE = -1 case */
  11681 
  11682                 field_len = soc_mem_field_length(unit, non_dma->mem,
  11683                                                  non_dma->field);
  11684                 if (field_len < 32) {
  11685                     COMPILER_64_SET(masked_val, 0, ((1 << field_len) - 1));
  11686                     COMPILER_64_AND(masked_val, val);
  11687                 } else {
  11688                     COMPILER_64_SET(masked_val, ((1 << (field_len - 32)) - 1),
  11689                                     0xffffffff);
  11690                     COMPILER_64_AND(masked_val, val);
  11691                 }
  11692                 if (all_pipe) {
  11693                     dma_base_index = base_index;
  11694                     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
  11695                         /* Skip if no enabled ports in pipe */
  11696                         if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, pipe))) {
  11697                             continue;
  11698                         }
  11699                         dma_mem = non_dma->dma_mem[pipe];
  11700                         rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY,
  11701                                           index, entry);
  11702                         if (SOC_FAILURE(rv)) {
  11703                             goto counter_set_done;
  11704                         }
  11705 
  11706                         if (clear_on_read) {
  11707                             /* Intent is to set All pipe value to 0.
  11708                              * Since Clear on read is true, reading clears the
  11709                              * values in Hardware.
  11710                              * Optimization - to not set the value to zero again.
  11711                              */
  11712                             continue;
  11713                         }
  11714                         if (pipe == 0) {
  11715                             fval[0] = COMPILER_64_LO(masked_val);
  11716                             fval[1] = COMPILER_64_HI(masked_val);
  11717                         } else {
  11718                             fval[0] = 0;
  11719                             fval[1] = 0;
  11720                         }
  11721                         soc_mem_field_set(unit, dma_mem, entry,
  11722                                 non_dma->field, fval);
  11723 
  11724                         rv = soc_mem_write(unit, dma_mem, MEM_BLOCK_ALL,
  11725                                            index, entry);
  11726                         if (SOC_FAILURE(rv)) {
  11727                             goto counter_set_done;
  11728                         }
  11729 
  11730                         if(non_dma->dma_num_entries[pipe] != 0) {
  11731                             base_index += non_dma->dma_num_entries[pipe];
  11732                         } else {
  11733                             base_index += entries_per_pipe;
  11734                         }
  11735                     }
  11736                     base_index = base_index_temp;
  11737                 } else {
  11738                     int pipe_offset = 0;
  11739                     dma_mem = non_dma->dma_mem[0];
  11740                     base_index = base_index_temp;
  11741 
  11742                     for (i = 0; i < NUM_PIPE(unit); i++) {
  11743                         if (non_dma->dma_mem[i] != INVALIDm) {
  11744                             dma_mem = non_dma->dma_mem[i];
  11745                             dma_base_index = base_index - non_dma->base_index;
  11746                             pipe_offset = dma_base_index / entries_per_pipe;
  11747 
  11748                             if (non_dma->dma_index_min[i]) {
  11749                                 dma_base_index += non_dma->dma_index_min[i];
  11750                             }
  11751                             break;
  11752                         }
  11753                     }
  11754                     if (pipe_offset) {
  11755                         for (; i < NUM_PIPE(unit); i++) {
  11756                             if (non_dma->dma_mem[i] != INVALIDm) {
  11757                                 /* Choose the appropriate index where pipes are
  11758                                  * applicable. In XPE case, each XPE is valid
  11759                                  * for only pair of pipes(and can have holes in
  11760                                  * between.
  11761                                  */
  11762                                 if (pipe_offset) {
  11763                                     pipe_offset--;
  11764                                     continue;
  11765                                 } else {
  11766                                     break;
  11767                                 }
  11768                             }
  11769                         }
  11770                         i %= NUM_PIPE(unit);
  11771                         dma_mem = non_dma->dma_mem[i];
  11772                         dma_base_index = (dma_base_index % entries_per_pipe) +
  11773                                          non_dma->dma_index_min[i];
  11774                     }
  11775 
  11776                     rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY,
  11777                             dma_base_index + index, entry);
  11778                     if (SOC_FAILURE(rv)) {
  11779                         goto counter_set_done;
  11780                     }
  11781 
  11782                     if (!clear_on_read) {
  11783                         /* Set Hardware only when Clear On Read is False.
  11784                          * Else Hardware will be cleared by Read operation
  11785                          * above.
  11786                          */
  11787                         fval[0] = COMPILER_64_LO(masked_val);
  11788                         fval[1] = COMPILER_64_HI(masked_val);
  11789                         soc_mem_field_set(unit, dma_mem, entry,
  11790                                 non_dma->field, fval);
  11791 
  11792                         /*
  11793                          * If parity is not enabled on the device
  11794                          * set the parity bit in the MMU_CTR_UC_DROP_MEMm
  11795                          * during counter set as suggested by DE.
  11796                          */
  11797 
  11798                         rv = soc_mem_write(unit, dma_mem, MEM_BLOCK_ALL,
  11799                                 dma_base_index + index, entry);
  11800                         if (SOC_FAILURE(rv)) {
  11801                             goto counter_set_done;
  11802                         }
  11803                     }
  11804                 }
  11805             } else if (non_dma->reg != INVALIDr) {
  11806                 if (ctrl_info.instance_type ==
  11807                            SOC_CTR_INSTANCE_TYPE_ITM_PORT) {
  11808                     port =
  11809                         (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_ITM) >>
  11810                         CTR_INSTANCE_BIT_SHIFT_ITM;
  11811                     /* port means ITM instance# but not used here, where
  11812                        base_index already reflect the ITM# offset */
  11813                     entries_per_pipe = 0;
  11814                     pipe_start = 0;
  11815                     pipe_end = 0;
  11816                     base_index = base_index_temp;
  11817                 }
  11818                 if (port < 0) {
  11819                     rv = SOC_E_PARAM;
  11820                     goto counter_set_done;
  11821                 }
  11822                 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_OBM) &&
  11823                     (soc_ctr_ctrl->port_obm_info_get)) {
  11824                     /* Set for OBM based counters.
  11825                      * Lossy_Lo, Lossy_Hi, Lossless0, Lossless1
  11826                      */
  11827                     uint64 regval64;
  11828                     uint32 regval32;
  11829                     int obm_id = 0, lane = 0;
  11830                     soc_reg_t reg = INVALIDr;
  11831                     soc_info_t *si = &SOC_INFO(unit);;
  11832 
  11833                     rv = soc_ctr_ctrl->port_obm_info_get(unit, port,
  11834                                                          &obm_id, &lane);
  11835                     if (SOC_FAILURE(rv)) {
  11836                         goto counter_set_done;
  11837                     }
  11838 #ifdef BCM_APACHE_SUPPORT
  11839                     if (SOC_IS_APACHE(unit)) {
  11840                         int pgw_inst = 0;
  11841 
  11842                         _soc_counter_apache_get_pgw_inst(unit, port, &pgw_inst, &lane);
  11843                         rv = soc_reg_get(unit, non_dma->reg,
  11844                                 pgw_inst, lane, &regval64);
  11845                         if (SOC_FAILURE(rv)) {
  11846                             goto counter_set_done;
  11847                         }
  11848                         if (SOC_REG_IS_64(unit, non_dma->reg)) {
  11849                             soc_reg64_field_set(unit, non_dma->reg, &regval64,
  11850                                     non_dma->field, val);
  11851                         } else {
  11852                             regval32 = COMPILER_64_LO(regval64);
  11853                             soc_reg_field_set(unit, non_dma->reg, &regval32,
  11854                                     non_dma->field, COMPILER_64_LO(val));
  11855                             COMPILER_64_SET(regval64, 0, regval32);
  11856                         }
  11857                         rv = soc_reg_set(unit, non_dma->reg,
  11858                                 pgw_inst, lane, regval64);
  11859 
  11860                     } else 
  11861 #endif
  11862                     {
  11863                     pipe = si->port_pipe[port];
  11864                     if (obm_id) {
  11865                         subset_ct = obm_id << 1;
  11866                         non_dma = non_dma + subset_ct;
  11867                     }
  11868 
  11869                     reg = SOC_REG_UNIQUE_ACC(unit, non_dma->reg)[pipe];
  11870                     rv = soc_reg_get(unit, reg, pipe, lane, &regval64);
  11871                     if (SOC_FAILURE(rv)) {
  11872                         goto counter_set_done;
  11873                     }
  11874 
  11875                     if (SOC_REG_IS_64(unit, non_dma->reg)) {
  11876                         soc_reg64_field_set(unit, non_dma->reg, &regval64,
  11877                                 non_dma->field, val);
  11878                     } else {
  11879                         regval32 = COMPILER_64_LO(regval64);
  11880                         soc_reg_field_set(unit, non_dma->reg, &regval32,
  11881                                 non_dma->field, COMPILER_64_LO(val));
  11882                         COMPILER_64_SET(regval64, 0, regval32);
  11883                     }
  11884 
  11885                     rv = soc_reg_set(unit, reg, pipe, lane, regval64);
  11886                     if (SOC_FAILURE(rv)) {
  11887                         goto counter_set_done;
  11888                     }
  11889                     }
  11890                 } else {
  11891                     if (PBMP_MEMBER(non_dma->pbmp, port)) {
  11892                         uint64 regval64;
  11893                         uint32 regval32;
  11894 
  11895                         rv = soc_reg_get(unit, non_dma->reg,
  11896                                 port, index, &regval64);
  11897                         if (SOC_FAILURE(rv)) {
  11898                             goto counter_set_done;
  11899                         }
  11900                         if (SOC_REG_IS_64(unit, non_dma->reg)) {
  11901                             soc_reg64_field_set(unit, non_dma->reg, &regval64,
  11902                                     non_dma->field, val);
  11903                         } else {
  11904                             regval32 = COMPILER_64_LO(regval64);
  11905                             soc_reg_field_set(unit, non_dma->reg, &regval32,
  11906                                     non_dma->field, COMPILER_64_LO(val));
  11907                             COMPILER_64_SET(regval64, 0, regval32);
  11908                         }
  11909                         rv = soc_reg_set(unit, non_dma->reg,
  11910                                 port, index, regval64);
  11911                         if (SOC_FAILURE(rv)) {
  11912                             goto counter_set_done;
  11913                         }
  11914                     }
  11915                 }
  11916             }
  11917         } else {
  11918             if (port < 0) {
  11919                 rv = SOC_E_PARAM;
  11920                 goto counter_set_done;
  11921             }
  11922 
  11923             if (!(SOC_REG_INFO(unit, id).flags & SOC_REG_FLAG_64_BITS) &&
  11924                     !SOC_IS_XGS3_SWITCH(unit)) {
  11925                 val32 = COMPILER_64_LO(val);
  11926                 rv = soc_reg32_set(unit, id, port, index, val32);
  11927                 if (SOC_FAILURE(rv)) {
  11928                     goto counter_set_done;
  11929                 }
  11930             } else {
  11931                 if (soc_feature(unit, soc_feature_prime_ctr_writes) &&
  11932                         /*SOC_REG_INFO(unit, id).block == SOC_BLK_EGR) */
  11933                     SOC_BLOCK_IS(SOC_REG_INFO(unit, id).block, SOC_BLK_EGR)) {
  11934                     prime_ctr_write = TRUE;
  11935                 } else {
  11936                     prime_ctr_write = FALSE;
  11937                 }
  11938 
  11939                 if (prime_ctr_write) {
  11940                     rv = soc_reg32_get(unit, id, port, index, &val32);
  11941                     if (SOC_FAILURE(rv)) {
  11942                         goto counter_set_done;
  11943                     }
  11944                 }
  11945                 rv = soc_reg_set(unit, id, port, index, val);
  11946                 if (SOC_FAILURE(rv)) {
  11947                     goto counter_set_done;
  11948                 }
  11949                 if (prime_ctr_write) {
  11950                     rv = soc_reg32_get(unit, id, port, index, &val32);
  11951                     if (SOC_FAILURE(rv)) {
  11952                         goto counter_set_done;
  11953                     }
  11954                 }
  11955             }
  11956         }
  11957 
  11958         for (pipe = pipe_start; pipe <= pipe_end; pipe++) {
  11959             /* The following section updates 64-bit values and must be atomic */
  11960             COUNTER_ATOMIC_BEGIN(s);
  11961             soc->counter_sw_val[base_index + index] = val;
  11962             soc->counter_hw_val[base_index + index] = val;
  11963             COMPILER_64_SET(soc->counter_delta[base_index + index], 0, 0);
  11964             COUNTER_ATOMIC_END(s);
  11965             base_index += entries_per_pipe;
  11966 
  11967             /* When Set is called with value with Pipe = -1
  11968              * Set given value for Pipe 0 and set other pipe values to 0
  11969              */
  11970             if (all_pipe) {
  11971                 COMPILER_64_SET(val, 0, 0);
  11972             }
  11973         }
  11974     }
  11975 
  11976 counter_set_done:
  11977     COUNTER_UNLOCK(unit);
  11978     return rv;
  11979 
  11980 }
  11981 
  11982 /*
  11983  * Function:
  11984  *      soc_counter_generic_set
  11985  * Purpose:
  11986  *      Given a counter register number, instance type, instance and a counter
  11987  *      value, set both the hardware and software-accumulated counters to the
  11988  *      value.
  11989  * Parameters:
  11990  *      unit - StrataSwitch unit #.
  11991  *      ctrl_info - Counter Control Info Structure.
  11992  *                  Contains the instance type and instance.
  11993  *      id - counter register id to set.
  11994  *      val - 64 bit counter value.
  11995  * Returns:
  11996  *      SOC_E_XXX
  11997  * Notes:
  11998  *      Currently supported instance types are
  11999  *      1. SOC_CTR_INSTANCE_TYPE_PORT
  12000  *      2. SOC_CTR_INSTANCE_TYPE_POOL
  12001  *      3. SOC_CTR_INSTANCE_TYPE_PIPE
  12002  */
  12003 int
  12004 soc_counter_generic_set(int unit, soc_reg_t id,
  12005                         soc_ctr_control_info_t ctrl_info, uint32 flags,
  12006                         int ar_idx, uint64 val)
  12007 {
  12008     int xpe,i,port,pipe,rv=0;
  12009     soc_ctr_control_info_t input_ctrl_info[2], output_ctrl_info;
  12010     soc_info_t *si = &SOC_INFO(unit);
  12011     soc_control_t *soc = SOC_CONTROL(unit);
  12012     soc_mem_t mem = INVALIDm;
  12013 #ifdef BCM_TOMAHAWK3_SUPPORT
  12014     uint16 dev_id;
  12015     uint8 rev_id;
  12016 #endif
  12017     if (id < SOC_COUNTER_NON_DMA_START ||
  12018         id >= SOC_COUNTER_NON_DMA_END) {
  12019         return SOC_E_PARAM;
  12020     }
  12021 
  12022     if (soc->counter_non_dma == NULL) {
  12023         return SOC_E_RESOURCE;
  12024     }
  12025 
  12026     if (!(soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START].flags)) {
  12027         return SOC_E_UNAVAIL;
  12028     }
  12029     mem = soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START].mem;
  12030     if ((ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) &&
  12031         (ctrl_info.instance == -1)) {
  12032         for (i = 0; i < NUM_PIPE(unit) ; i++) {
  12033 #ifdef BCM_TOMAHAWK3_SUPPORT
  12034             if (SOC_PBMP_IS_NULL(si->pipe_pbm[i])) {
  12035                 continue;
  12036             }
  12037 #endif
  12038             ctrl_info.instance = i;
  12039             rv =  _soc_counter_generic_set(unit, ctrl_info, id, ar_idx, val);
  12040             if (rv < 0) {
  12041                 return rv;
  12042             }
  12043         }
  12044     }
  12045 
  12046 #ifdef BCM_TOMAHAWK3_SUPPORT
  12047     soc_cm_get_id(unit, &dev_id, &rev_id);
  12048     if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_ITM) {
  12049         uint64 setval[2];
  12050         int setval_iterate = 0, itm;
  12051         port = ctrl_info.instance;
  12052         pipe = si->port_pipe[port];
  12053 
  12054         input_ctrl_info[0].instance_type = ctrl_info.instance_type;
  12055         input_ctrl_info[1].instance = ctrl_info.instance;
  12056         input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
  12057 
  12058         if ((NUM_ITM(unit) == 1) || (dev_id == BCM56983_DEVICE_ID)) {
  12059             COMPILER_64_COPY(setval[0], val);
  12060         } else {
  12061             _soc_distribute_u64(val, &setval[0], &setval[1]);
  12062         }
  12063 
  12064         for (itm = 0; itm < NUM_ITM(unit) ; itm++) {
  12065             if (itm == 1 && (dev_id == BCM56983_DEVICE_ID)) {
  12066                 continue;
  12067             }
  12068             input_ctrl_info[0].instance = itm;
  12069 
  12070             soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info);
  12071             rv = _soc_counter_generic_set(unit, output_ctrl_info, id,
  12072                                           ar_idx, setval[setval_iterate]);
  12073             setval_iterate++;
  12074             if (rv != SOC_E_NONE) {
  12075                 break;
  12076             }
  12077         }
  12078 
  12079         return rv;
  12080     }
  12081 #endif /* BCM_TOMAHAWK3_SUPPORT */
  12082 
  12083     if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_XPE) {
  12084         uint64 setval[2];
  12085         int setval_iterate = 0;
  12086         port = ctrl_info.instance;
  12087         pipe = si->port_pipe[port];
  12088         input_ctrl_info[0].instance_type = ctrl_info.instance_type;
  12089         input_ctrl_info[1].instance = ctrl_info.instance;
  12090         input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT;
  12091         if (NUM_XPE(unit) == 1) {
  12092             COMPILER_64_COPY(setval[0], val);
  12093         } else {
  12094         _soc_distribute_u64(val, &setval[0], &setval[1]);
  12095         }
  12096         
  12097         for (xpe = 0; xpe < NUM_XPE(unit) ; xpe++) {
  12098             input_ctrl_info[0].instance = xpe;
  12099             if ((mem == MMU_CTR_COLOR_DROP_MEMm) && !SOC_IS_TOMAHAWK2(unit)) {
  12100                 if(!((si->epipe_xpe_map[pipe] >> xpe) & 1)) {
  12101                     continue;
  12102                 }
  12103 
  12104             } else {
  12105                 if (SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit,mem,xpe,pipe) == INVALIDm) {
  12106                     /* Invalid XPE/Pipe Combination */
  12107                     continue;
  12108                 }
  12109             }
  12110             soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info);
  12111             rv = _soc_counter_generic_set(unit, output_ctrl_info, id,
  12112                                           ar_idx, setval[setval_iterate]  );
  12113             setval_iterate++;
  12114             if (rv < 0) {
  12115                 return rv;
  12116             }
  12117         }
  12118         return rv;
  12119     } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_SFLOW &&
  12120                ctrl_info.instance == -1) {
  12121        for (i = 0; i < SOC_SFLOW_CTR_TYPE_COUNT ; i++) {
  12122            ctrl_info.instance = i;
  12123            rv = _soc_counter_generic_set(unit, ctrl_info, id, ar_idx, val);
  12124            if (rv < 0) {
  12125                return rv;
  12126             }
  12127        }
  12128        return rv;
  12129     } else {
  12130         return _soc_counter_generic_set(unit, ctrl_info, id, ar_idx, val);
  12131     }
  12132 }
  12133 
  12134 /* Function:
  12135  *      soc_counter_generic_multi_set
  12136  * Purpose:
  12137  *      Given a counter register number, count, instance type, instance and
  12138  *      array of values, set multiple hardware and software-accumulated counter
  12139  *      values to values specified in input val array.
  12140  * Parameter:
  12141  *      unit  - StrataSwitch Unit #.
  12142  *      ctr_reg - Counter Register to retrieve.
  12143  *      ctrl_info - Counter Control Info Structure
  12144  *                  Contains the instance type and instance.
  12145  *      flags - not yet implemented.
  12146  *      ar_idx - Base index of counter to be set.
  12147  *      count - Number of consecutive entries to be set.
  12148  *      val - Base address of array holding the values to be set in
  12149  *      counters.
  12150  *Returns:
  12151  *      SOC_E_XXX
  12152  *Notes:
  12153  *      If count is set to 0, nothing is set.
  12154 */
  12155 int
  12156 soc_counter_generic_multi_set(int unit,  soc_reg_t ctr_reg,
  12157                               soc_ctr_control_info_t ctrl_info,
  12158                               uint32 flags, int ar_idx, int count,
  12159                               uint64 *val)
  12160 {
  12161     int i;
  12162     int rv = SOC_E_NONE;
  12163     soc_control_t *soc = SOC_CONTROL(unit);
  12164 
  12165     if (count < 0) {
  12166         return SOC_E_PARAM;
  12167     }
  12168 
  12169     if (soc->counter_non_dma == NULL) {
  12170         return SOC_E_RESOURCE;
  12171     }
  12172 
  12173     for (i = 0; i<count; i++) {
  12174         rv = _soc_counter_generic_set(unit, ctrl_info, ctr_reg, (ar_idx+i),
  12175                                         val[i]);
  12176         if (rv!=SOC_E_NONE) {
  12177             return rv;
  12178         }
  12179     }
  12180     return rv;
  12181 }
  12182 
  12183 STATIC int
  12184 _soc_counter_non_dma_is_invalid(int unit, soc_reg_t reg, soc_port_t port)
  12185 {
  12186     int pgw_index = -1, xlp = 0, xlp_index, blk;
  12187 
  12188     switch (reg) {
  12189     case PGW_OBM0_HIGH_PRI_PKT_DROPr:
  12190     case PGW_OBM0_LOW_PRI_PKT_DROPr:
  12191     case PGW_OBM0_HIGH_PRI_BYTE_DROPr:
  12192     case PGW_OBM0_LOW_PRI_BYTE_DROPr:
  12193         xlp = 0;
  12194         break;
  12195     case PGW_OBM1_HIGH_PRI_PKT_DROPr:
  12196     case PGW_OBM1_LOW_PRI_PKT_DROPr:
  12197     case PGW_OBM1_HIGH_PRI_BYTE_DROPr:
  12198     case PGW_OBM1_LOW_PRI_BYTE_DROPr:
  12199         xlp = 1;
  12200         break;
  12201     case PGW_OBM2_HIGH_PRI_PKT_DROPr:
  12202     case PGW_OBM2_LOW_PRI_PKT_DROPr:
  12203     case PGW_OBM2_HIGH_PRI_BYTE_DROPr:
  12204     case PGW_OBM2_LOW_PRI_BYTE_DROPr:
  12205         xlp = 2;
  12206         break;
  12207     case PGW_OBM3_HIGH_PRI_PKT_DROPr:
  12208     case PGW_OBM3_LOW_PRI_PKT_DROPr:
  12209     case PGW_OBM3_HIGH_PRI_BYTE_DROPr:
  12210     case PGW_OBM3_LOW_PRI_BYTE_DROPr:
  12211         xlp = 3;
  12212         break;
  12213     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW:
  12214     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED:
  12215     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN:
  12216     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW:
  12217     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED:
  12218         if (IS_RDB_PORT(unit, port) || IS_MACSEC_PORT(unit,port)) {
  12219             return TRUE;
  12220         }
  12221         break;
  12222     default:
  12223         return FALSE;
  12224     }
  12225 
  12226     pgw_index = SOC_INFO(unit).port_group[port]; 
  12227     if (pgw_index == -1) {
  12228         return FALSE;
  12229     }
  12230     xlp_index = pgw_index * 4 + xlp;
  12231     for (blk = 0; SOC_BLOCK_TYPE(unit, blk) >= 0; blk++) {
  12232         if (SOC_BLOCK_TYPE(unit, blk) != SOC_BLK_XLPORT) {
  12233             continue;
  12234         }
  12235         if (SOC_BLOCK_NUMBER(unit, blk) == xlp_index) {
  12236             if (!SOC_INFO(unit).block_valid[blk]) {
  12237                 return TRUE;
  12238             }
  12239         }
  12240     }
  12241 
  12242     return FALSE;
  12243 }
  12244 
  12245 /*
  12246  * Function:
  12247  *      _soc_counter_set_by_port
  12248  * Purpose:
  12249  *      Given a port bit map, set all counters for the specified ports to
  12250  *      the requested value.  Useful mainly to clear all the counters.
  12251  * Parameters:
  12252  *      unit - StrataSwitch unit #.
  12253  *      pbmp  - Bit map of all ports to set counters on.
  12254  *      ctr_reg - if !INVALIDr set only a specified counter
  12255  *                else all the counters for a port
  12256  *      val  - 64/32-bit counter value.
  12257  * Returns:
  12258  *      SOC_E_XXX
  12259  */
  12260 
  12261 int
  12262 _soc_counter_set_by_port(int unit, pbmp_t pbmp, soc_reg_t ctr_reg, 
  12263                          int ar_idx, uint64 val)
  12264 {
  12265     int                 i, rv = 0;
  12266     soc_port_t          port;
  12267     soc_ctr_ref_t       *ctr_ref;
  12268     soc_control_t *soc = SOC_CONTROL(unit);
  12269     soc_counter_non_dma_t *non_dma = NULL;
  12270     int                 min_index = 0;
  12271     int                 max_ctr = 0;
  12272     int                 num_idx = 0;
  12273     int                 dma_id = 0;
  12274     int                 non_dma_counter_end = 0;
  12275     int                 port_base;
  12276     int                 port_index, num_entries;
  12277     char                *cname;
  12278     int                 dma_counters = 1;
  12279     int                 non_dma_counters = 1;
  12280 
  12281     PBMP_ITER(pbmp, port) {
  12282         /*
  12283          * Flexing operations on certain devices can create new ports,
  12284          * or delete existing ports. This can happen when the counter
  12285          * thread is not running. So we make a check here before proceeding
  12286          * with further processing. We ignore processing for ports which no
  12287          * longer exist.
  12288          */
  12289         if (!SOC_CONTROL(unit)->counter_map[port]) {
  12290             continue;
  12291         }
  12292 
  12293 if (IS_MACSEC_PORT(unit, port)) { 
  12294     continue; 
  12295 }
  12296         if (!SOC_PORT_VALID(unit, port)) {
  12297             continue;
  12298         }
  12299 
  12300         /* 
  12301          * If ctr_reg != INVALIDr the request is for 
  12302          * setting a specific counter register for 
  12303          * a port.
  12304          */      
  12305         if (ctr_reg != INVALIDr) {
  12306             if ((ctr_reg < NUM_SOC_REG) ||
  12307                 SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) {
  12308                 /* No DMA counters for the loopback port */
  12309                 if (IS_LB_PORT(unit, port)
  12310 #if defined(BCM_SHADOW_SUPPORT)
  12311                     || IS_IL_PORT(unit, port)
  12312 #endif
  12313                 ) { 
  12314                     continue;
  12315                 }
  12316                 SOC_IF_ERROR_RETURN(
  12317                         _soc_counter_get_info(unit, port, ctr_reg,
  12318                                               &port_index, &num_entries,
  12319                                               &cname));
  12320 
  12321                 port_base = COUNTER_IDX_PORTBASE(unit, port);
  12322                 min_index = port_index - port_base;
  12323                 max_ctr = min_index + 1;
  12324                 non_dma_counters = 0; 
  12325 
  12326                 dma_id = 0;
  12327                 non_dma_counter_end = 0;
  12328             } else {
  12329                 /*
  12330                  * if ctr_reg >= NUM_SOC_REG, set stats for a
  12331                  * specific port and queue in the hardware
  12332                  * and the sw copy of the same.
  12333                  */
  12334                 min_index = 0;
  12335                 max_ctr = 0;
  12336                 dma_counters = 0; 
  12337 
  12338                 dma_id = ctr_reg - SOC_COUNTER_NON_DMA_START;
  12339                 non_dma_counter_end = dma_id + 1;
  12340                 
  12341             }
  12342         } else {
  12343             /* 
  12344              * The request is for setting all the 
  12345              * counter registers for a port.
  12346              */ 
  12347             dma_id = 0;
  12348             non_dma_counter_end = SOC_COUNTER_NON_DMA_END - 
  12349                                   SOC_COUNTER_NON_DMA_START;
  12350 
  12351             /* No DMA counters for the loopback port */
  12352             if (IS_LB_PORT(unit, port) ||
  12353                 IS_RDB_PORT(unit, port) ||
  12354                 IS_MACSEC_PORT(unit, port)
  12355 #if defined(BCM_SHADOW_SUPPORT)
  12356                 || IS_IL_PORT(unit, port)
  12357 #endif
  12358                ) { 
  12359                 min_index = 0;
  12360                 max_ctr =  0;
  12361             } else {
  12362                 min_index = 0;
  12363                 max_ctr =  PORT_CTR_NUM(unit, port);
  12364             }
  12365         } 
  12366      
  12367 
  12368         if (!IS_LB_PORT(unit, port)
  12369             && !IS_RDB_PORT(unit, port) 
  12370             && !IS_MACSEC_PORT(unit,port) 
  12371 #if defined(BCM_SHADOW_SUPPORT)
  12372             && !IS_IL_PORT(unit, port)
  12373 #endif
  12374         ) 
  12375         {
  12376 
  12377             if (dma_counters ) {
  12378                 /* No DMA counters for the loopback port */
  12379                 for (i = min_index; i < max_ctr; i++) {
  12380                     ctr_ref = PORT_CTR_REG(unit, port, i);
  12381                     num_idx = (ctr_reg == INVALIDr)? ctr_ref->index: ar_idx;
  12382                     if (!SOC_COUNTER_INVALID(unit, ctr_ref->reg)) {
  12383                         if (!SOC_REG_IS_COUNTER_TABLE(unit,ctr_ref->reg) &&
  12384                             !SOC_REG_PORT_VALID(unit,ctr_ref->reg, port)) {
  12385                             continue;
  12386                         }
  12387                         rv = _soc_counter_set(unit, port, ctr_ref->reg,
  12388                                               num_idx, val);
  12389 
  12390                         if (rv == SOC_E_FAIL) {
  12391                             LOG_ERROR(BSL_LS_SOC_COMMON,
  12392                                       (BSL_META_U(unit,
  12393                                               "Error %d calling "
  12394                                               "soc_counter_set for"
  12395                                               "port: %d, reg: %d, "
  12396                                               "index: %d\n"), rv,
  12397                                    port, ctr_ref->reg, ctr_ref->index));
  12398                         }
  12399                     }
  12400                 }
  12401             }/* dma_counters */
  12402        }
  12403     
  12404        if (non_dma_counters) {
  12405             for (i = dma_id; i < non_dma_counter_end ; i++) {
  12406                  non_dma = &soc->counter_non_dma[i];
  12407                 /* Clear counters should not clear Non Port based counters (like
  12408                  * Flex and Field counters) - they are to be cleared by the
  12409                  * corresponding module */
  12410                 if (SOC_PBMP_IS_NULL(non_dma->pbmp)) {
  12411                     continue;
  12412                 }
  12413 
  12414 	            if (_soc_counter_non_dma_is_invalid(unit, non_dma->reg, port)) {
  12415 	                continue;
  12416 	            }
  12417 
  12418 if (!IS_MACSEC_PORT(unit, port)) { 
  12419 #if defined (BCM_APACHE_SUPPORT)
  12420                   if (SOC_IS_APACHE(unit)) {
  12421                       if (((SOC_COUNTER_NON_DMA_START + i) == SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT) 
  12422                             || ((SOC_COUNTER_NON_DMA_START + i) == SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT) ) {
  12423                          continue;
  12424                       } 
  12425                   }
  12426 #endif 
  12427                 rv = _soc_counter_set(unit, port, 
  12428                                       SOC_COUNTER_NON_DMA_START + i, -1,
  12429                                       val);
  12430 }
  12431                 if (rv == SOC_E_FAIL) {
  12432                     LOG_ERROR(BSL_LS_SOC_COMMON,
  12433                               (BSL_META_U(unit,
  12434                                           "Error %d calling soc_counter_set "
  12435                                           "for port: %d, "
  12436                                            "non-DMA index: %d\n"), 
  12437                                            rv, port, i));
  12438                 }
  12439             }
  12440         }
  12441 #ifdef BCM_BRADLEY_SUPPORT
  12442         /*
  12443          * The HOLD register is not supported by DMA on HUMV/Bradley,
  12444          * so we cannot use the standard counter_set function.
  12445          */
  12446         if (SOC_IS_HBX(unit)) {
  12447             if (SOC_REG_IS_VALID(unit, HOLD_Xr) &&
  12448                 SOC_REG_IS_VALID(unit, HOLD_Yr)) {
  12449             SOC_IF_ERROR_RETURN
  12450                 (WRITE_HOLD_Xr(unit, port, COMPILER_64_LO(val) / 2));
  12451             SOC_IF_ERROR_RETURN
  12452                 (WRITE_HOLD_Yr(unit, port, COMPILER_64_LO(val) / 2));
  12453             }
  12454         }
  12455 #endif
  12456     }
  12457 
  12458     return SOC_E_NONE;
  12459 }
  12460 
  12461 /*
  12462  * Function:
  12463  *      soc_counter_clear_by_port_reg
  12464  * Purpose:
  12465  *      Given a port,counter register.  clear counters for the specified ports
  12466  *      Useful mainly to clear individual snmp counters.
  12467  * Parameters:
  12468  *      unit - StrataSwitch unit #.
  12469  *      port - Bit map of all ports to set counters on.
  12470  *      ctr_reg - counter register to clear.
  12471  *      val  - 64bit counter value(set to 0).
  12472  * Returns:
  12473  *      SOC_E_XXX
  12474  */
  12475 
  12476 int
  12477 soc_counter_clear_by_port_reg(int unit, soc_port_t port, soc_reg_t ctr_reg, 
  12478                             int ar_idx, uint64 val)
  12479 {
  12480     pbmp_t      pbmp;
  12481 
  12482     SOC_PBMP_CLEAR(pbmp);
  12483     SOC_PBMP_PORT_SET(pbmp, port);
  12484     COMPILER_64_ZERO(val);
  12485     return _soc_counter_set_by_port(unit, pbmp, ctr_reg, ar_idx, val); 
  12486 }
  12487 
  12488 
  12489 /*
  12490  * Function:
  12491  *      soc_counter_set_by_port, soc_counter_set32_by_port
  12492  * Purpose:
  12493  *      Given a port bit map, set all counters for the specified ports to
  12494  *      the requested value.  Useful mainly to clear all the counters.
  12495  * Parameters:
  12496  *      unit - StrataSwitch unit #.
  12497  *      pbm  - Bit map of all ports to set counters on.
  12498  *      val  - 64/32-bit counter value.
  12499  * Returns:
  12500  *      SOC_E_XXX
  12501  * Notes:
  12502  *      The 32-bit version sets the upper 32-bits of the 64-bit
  12503  *      software counters to zero.  The specified value is truncated
  12504  *      to the size of the hardware register when storing to hardware.
  12505  */
  12506 
  12507 int
  12508 soc_counter_set_by_port(int unit, pbmp_t pbmp, uint64 val)
  12509 {
  12510     return _soc_counter_set_by_port(unit, pbmp, INVALIDr, 0, val);
  12511 }
  12512 
  12513 int
  12514 soc_counter_set32_by_port(int unit, pbmp_t pbmp, uint32 val)
  12515 {
  12516     uint64              val64;
  12517 
  12518     COMPILER_64_SET(val64, 0, val);
  12519 
  12520     return soc_counter_set_by_port(unit, pbmp, val64);
  12521 }
  12522 
  12523 int
  12524 soc_controlled_counter_clear(int unit, soc_port_t port)
  12525 {
  12526     soc_control_t       *soc = SOC_CONTROL(unit);
  12527     uint64              ctr_new;
  12528     int                 index, port_base;
  12529     soc_controlled_counter_t* ctr;
  12530 
  12531     LOG_DEBUG(BSL_LS_SOC_COUNTER,
  12532                 (BSL_META_U(unit,
  12533                             "soc_controlled_counter_clear: unit=%d "
  12534                             "port=%d\n"), unit, port));
  12535 
  12536     if ((!soc_feature(unit, soc_feature_controlled_counters)) ||
  12537          (!soc->controlled_counters)) {
  12538         return SOC_E_NONE;
  12539     }
  12540 
  12541     port_base = COUNTER_IDX_PORTBASE(unit, port);
  12542 
  12543     COUNTER_LOCK(unit);
  12544 
  12545 #ifdef BCM_PETRA_SUPPORT
  12546     if (SOC_IS_ARAD(unit) && !SOC_IS_JERICHO(unit)) {
  12547         SOC_IF_ERROR_RETURN(soc_arad_stat_clear_on_read_set(unit , 1));
  12548     }
  12549 #endif
  12550 #ifdef BCM_JERICHO_SUPPORT
  12551     /*Jericho collected counters are not cleared on read*/
  12552     if (SOC_IS_JERICHO(unit)) {
  12553         SOC_IF_ERROR_RETURN(soc_jer_nif_controlled_counter_clear(unit, port));
  12554     }
  12555 #endif
  12556     for (index = 0; soc->controlled_counters[index].controlled_counter_f != NULL; index++) {
  12557         COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit);
  12558         uint32 clear_on_read;
  12559 
  12560         ctr = &soc->controlled_counters[index];
  12561         if (ctr->controlled_counter_clear_f != NULL) {
  12562             ctr->controlled_counter_clear_f(unit, ctr->counter_id, port);
  12563         } else {
  12564             /* assume clear on read */
  12565             ctr->controlled_counter_f(unit, ctr->counter_id, port, &ctr_new, &clear_on_read);
  12566             if(!clear_on_read) {
  12567                 LOG_WARN(BSL_LS_SOC_COMMON,
  12568                          (BSL_META_U(unit,
  12569                                      "Counter Id(%d) is not cleared!\n"), ctr->counter_id));
  12570             }
  12571         }
  12572         /*check if counter is relevant*/
  12573         if(!COUNTER_IS_COLLECTED(soc->controlled_counters[index])) {
  12574             continue;
  12575         }
  12576         /* The following section updates 64-bit values and must be atomic */
  12577         COUNTER_ATOMIC_BEGIN(s);
  12578         COMPILER_64_SET(soc->counter_sw_val[port_base + ctr->counter_idx], 0, 0);
  12579         COMPILER_64_SET(soc->counter_hw_val[port_base + ctr->counter_idx], 0, 0);
  12580         COMPILER_64_SET(soc->counter_delta[port_base + ctr->counter_idx], 0, 0);
  12581         COUNTER_ATOMIC_END(s);
  12582 
  12583     }
  12584 
  12585 #ifdef BCM_PETRA_SUPPORT
  12586         if (SOC_IS_ARAD(unit) && !SOC_IS_JERICHO(unit)) {
  12587             SOC_IF_ERROR_RETURN(soc_arad_stat_clear_on_read_set(unit , 0));
  12588         }
  12589 #endif
  12590 
  12591     COUNTER_UNLOCK(unit);
  12592 
  12593     return SOC_E_NONE;
  12594 }
  12595 
  12596 /*
  12597  * Function:
  12598  *      soc_counter_set_by_reg, soc_counter_set32_by_reg
  12599  * Purpose:
  12600  *      Given a counter register number and a counter value, set both
  12601  *      the hardware and software-accumulated counters to the value
  12602  *      for all ports.
  12603  * Parameters:
  12604  *      unit - StrataSwitch unit #.
  12605  *      ctr_reg - counter register to set.
  12606  *      val - 64/32-bit counter value.
  12607  * Returns:
  12608  *      SOC_E_XXX
  12609  * Notes:
  12610  *      The 32-bit version sets the upper 32-bits of the 64-bit
  12611  *      software counters to zero.  The specified value is truncated
  12612  *      to the size of the hardware register when storing to hardware.
  12613  */
  12614 
  12615 int
  12616 soc_counter_set_by_reg(int unit, soc_reg_t ctr_reg, int ar_idx, uint64 val)
  12617 {
  12618     soc_port_t          port;
  12619 
  12620     if (SOC_COUNTER_INVALID(unit, ctr_reg)) {
  12621         return SOC_E_NONE;
  12622     }
  12623 
  12624 #ifdef BROADCOM_DEBUG
  12625     if (!SOC_REG_IS_COUNTER(unit, ctr_reg)) {
  12626         _soc_counter_illegal(unit, ctr_reg);
  12627         return SOC_E_NONE;
  12628     }
  12629 #endif /* BROADCOM_DEBUG */
  12630 
  12631 
  12632     PBMP_PORT_ITER(unit, port) {
  12633         SOC_IF_ERROR_RETURN(_soc_counter_set(unit, port, ctr_reg,
  12634                                              ar_idx, val));
  12635     }
  12636 
  12637     return SOC_E_NONE;
  12638 }
  12639 
  12640 int
  12641 soc_counter_set32_by_reg(int unit, soc_reg_t ctr_reg, int ar_idx, uint32 val)
  12642 {
  12643     uint64              val64;
  12644 
  12645     COMPILER_64_SET(val64, 0, val);
  12646 
  12647     return soc_counter_set_by_reg(unit, ctr_reg, ar_idx, val64);
  12648 }
  12649 
  12650 /* Function:
  12651  *      soc_counter_config_multi_get
  12652  * Purpose:
  12653  *      Given a counter register number, count, instance type, instance...
  12654  * Parameter:
  12655  *      unit        - StrataSwitch Unit #.
  12656  *      ctr_reg     - Counter Register to retrieve.
  12657  *      count       - Number of consecutive entries to be set.
  12658  *      ctrl_info   - Counter Control Info Structure 
  12659  *                    Contains the instance type and instance.
  12660  *      ctrl_config - Counter Control config structure to Get Dma attributes.
  12661  *                    Refer soc_ctr_ctrl_config_s.
  12662  *Returns:
  12663  *      SOC_E_XXX
  12664  *Notes:
  12665  *      If count is set to 0, nothing is retrieved.
  12666 */
  12667 int
  12668 soc_counter_config_multi_get(int unit, soc_reg_t ctr_reg, int count,
  12669                              soc_ctr_control_info_t *ctrl_info,
  12670                              soc_ctr_ctrl_config_t *ctrl_config)
  12671 {
  12672     int i;
  12673     soc_control_t *soc = SOC_CONTROL(unit);
  12674     soc_counter_non_dma_t *non_dma = NULL;
  12675     soc_counter_non_dma_t *parent_dma = NULL;
  12676     int value = -1, config_type = 0;
  12677     int instance_type = -1, in_pipe = -1;
  12678     int c_offset, rv = SOC_E_NONE;
  12679     soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit);
  12680 
  12681     if (soc_ctr_ctrl == NULL) {
  12682         return SOC_E_INIT;
  12683     }
  12684 
  12685     if ((count < 0) || (!ctrl_config) || (!ctrl_info)) {
  12686         return SOC_E_PARAM;
  12687     }
  12688 
  12689     if (soc->counter_non_dma == NULL) {
  12690         return SOC_E_RESOURCE;
  12691     }
  12692 
  12693     if ((ctr_reg < SOC_COUNTER_NON_DMA_START) || 
  12694         (ctr_reg >= SOC_COUNTER_NON_DMA_END)) {
  12695         return SOC_E_PARAM;
  12696     }
  12697 
  12698     for (i = 0; i < count; i++) {
  12699         /* Check sanity of Ctrl_info */
  12700         instance_type = ctrl_info[i].instance_type;
  12701 
  12702         if (!((instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) || 
  12703              (instance_type == SOC_CTR_INSTANCE_TYPE_POOL) || 
  12704              (instance_type == SOC_CTR_INSTANCE_TYPE_POOL_PIPE))) {
  12705             return SOC_E_PARAM;
  12706         }
  12707 
  12708         parent_dma = &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START];
  12709         non_dma = parent_dma;
  12710 
  12711         if (soc_ctr_ctrl->get_child_dma) {
  12712             rv = soc_ctr_ctrl->get_child_dma(unit, ctr_reg,
  12713                                              ctrl_info[i], &non_dma);
  12714             if (rv != SOC_E_NONE) {
  12715                 return rv;
  12716             }
  12717         }
  12718 
  12719         switch (instance_type) {
  12720             case SOC_CTR_INSTANCE_TYPE_PIPE:
  12721                 in_pipe = ctrl_info[i].instance;
  12722                 if ((in_pipe >=  NUM_PIPE(unit)) || (in_pipe < -1)) {
  12723                    return SOC_E_PARAM;
  12724                 }
  12725                 break;
  12726             case SOC_CTR_INSTANCE_TYPE_POOL:
  12727                 c_offset = ctrl_info[i].instance;
  12728                 if ((c_offset < 0) || (c_offset >= parent_dma->extra_ctr_ct)) {
  12729                     return SOC_E_PARAM;
  12730                 }
  12731                 in_pipe = -1;
  12732                 break;
  12733             case SOC_CTR_INSTANCE_TYPE_POOL_PIPE:
  12734                 return SOC_E_UNAVAIL;
  12735             /* coverity[dead_error_begin] */
  12736             default:
  12737                 return SOC_E_PARAM;
  12738         }
  12739 
  12740         config_type = ctrl_config[i].config_type;
  12741         value = -1;
  12742         switch (config_type) {
  12743             case SOC_CTR_CTRL_CONFIG_DMA_ENABLE:
  12744                 value = (non_dma->flags & _SOC_COUNTER_NON_DMA_VALID);
  12745                 break;
  12746             case SOC_CTR_CTRL_CONFIG_DMA_MINIDX:
  12747                 if (in_pipe == -1) {
  12748                     in_pipe = 0;
  12749                 }
  12750                 value = non_dma->dma_index_min[in_pipe];
  12751                 break;
  12752             case SOC_CTR_CTRL_CONFIG_DMA_MAXIDX:
  12753                 if (in_pipe == -1) {
  12754                     in_pipe = 0;
  12755                 }
  12756                 value = non_dma->dma_index_max[in_pipe];
  12757                 break;
  12758             case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_ALL:
  12759                 if (non_dma->dma_rate_profile == _SOC_COUNTER_DMA_RATE_PROFILE_MASK) {
  12760                     value = 1;
  12761                 } else {
  12762                     value = 0;
  12763                 }
  12764                 break;
  12765             case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_AUTO:
  12766             case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_WFS:
  12767                 return SOC_E_UNAVAIL;
  12768                 break;
  12769             default:
  12770                 return SOC_E_PARAM;
  12771         }
  12772         ctrl_config[i].config_val = value;
  12773     }
  12774     return rv;
  12775 }
  12776  
  12777 /* Function:
  12778  *      soc_counter_config_multi_set
  12779  * Purpose:
  12780  *      Given a counter register number, count, instance type, instance...
  12781  * Parameter:
  12782  *      unit        - StrataSwitch Unit #.
  12783  *      ctr_reg     - Counter Register to retrieve.
  12784  *      count       - Number of consecutive entries to be set.
  12785  *      ctrl_info   - Counter Control Info Structure 
  12786  *                    Contains the instance type and instance.
  12787  *      ctrl_config - Counter Control config structure to set Dma attributes.
  12788  *                    Refer soc_ctr_ctrl_config_s.
  12789  *Returns:
  12790  *      SOC_E_XXX
  12791  *Notes:
  12792  *      If count is set to 0, nothing is set.
  12793 */
  12794 int
  12795 soc_counter_config_multi_set(int unit, soc_reg_t ctr_reg, int count,
  12796                              soc_ctr_control_info_t *ctrl_info,
  12797                              soc_ctr_ctrl_config_t *ctrl_config)
  12798 {
  12799     int i, max_idx = 0;
  12800     soc_control_t *soc = SOC_CONTROL(unit);
  12801     soc_counter_non_dma_t *non_dma = NULL;
  12802     soc_counter_non_dma_t *parent_dma = NULL;
  12803     int value = -1, config_type = 0;
  12804     int instance_type = -1, in_pipe = -1, pipe = -1;
  12805     int c_offset, rv = SOC_E_NONE;
  12806     soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit);
  12807     
  12808     if (soc_ctr_ctrl == NULL) {
  12809         return SOC_E_INIT;
  12810     }
  12811 
  12812     if ((count < 0) || (!ctrl_config) || (!ctrl_info)) {
  12813         return SOC_E_PARAM;
  12814     }
  12815 
  12816     if ((ctr_reg < SOC_COUNTER_NON_DMA_START) || 
  12817         (ctr_reg >= SOC_COUNTER_NON_DMA_END)) {
  12818         return SOC_E_PARAM;
  12819     }
  12820 
  12821     if (soc->counter_non_dma == NULL) {
  12822         return SOC_E_RESOURCE;
  12823     }
  12824 
  12825     for (i = 0; i < count; i++) {
  12826         /* Check sanity of Ctrl_info */
  12827         instance_type = ctrl_info[i].instance_type;
  12828 
  12829         if (!((instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) || 
  12830              (instance_type == SOC_CTR_INSTANCE_TYPE_POOL) || 
  12831              (instance_type == SOC_CTR_INSTANCE_TYPE_POOL_PIPE))) {
  12832             return SOC_E_PARAM;
  12833         }
  12834 
  12835         parent_dma = &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START];
  12836         non_dma = parent_dma;
  12837         /* Get child dma if this falls under Parent-child model. */
  12838         if (soc_ctr_ctrl->get_child_dma) {
  12839             rv = soc_ctr_ctrl->get_child_dma(unit, ctr_reg,
  12840                                              ctrl_info[i], &non_dma);
  12841         }
  12842         max_idx = non_dma->num_entries / NUM_PIPE(unit);
  12843 
  12844         switch (instance_type) {
  12845             case SOC_CTR_INSTANCE_TYPE_PIPE:
  12846                 in_pipe = ctrl_info[i].instance;
  12847                 if ((in_pipe >=  NUM_PIPE(unit)) || (in_pipe < -1)) {
  12848                    return SOC_E_PARAM;
  12849                 }
  12850                 break;
  12851             case SOC_CTR_INSTANCE_TYPE_POOL:
  12852                 c_offset = ctrl_info[i].instance;
  12853                 if ((c_offset < 0) || (c_offset >= parent_dma->extra_ctr_ct)) {
  12854                     return SOC_E_PARAM;
  12855                 }
  12856                 in_pipe = -1;
  12857                 break;
  12858             case SOC_CTR_INSTANCE_TYPE_POOL_PIPE:
  12859                 return SOC_E_UNAVAIL;
  12860             /* coverity[dead_error_begin] */
  12861             default:
  12862                 return SOC_E_PARAM;
  12863         }
  12864 
  12865         value = ctrl_config[i].config_val;
  12866         config_type = ctrl_config[i].config_type;
  12867 
  12868         switch (config_type) {
  12869             case SOC_CTR_CTRL_CONFIG_DMA_ENABLE:
  12870                 if (value) {
  12871                     non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  12872                     if ((parent_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
  12873                         (!(parent_dma->flags & _SOC_COUNTER_NON_DMA_VALID))  &&
  12874                         (ctr_reg != SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE) &&
  12875                         (ctr_reg != SOC_COUNTER_NON_DMA_ING_FLEX_BYTE)) {
  12876                         parent_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  12877                     }
  12878                 } else {
  12879                     non_dma->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
  12880                 }
  12881                 break;
  12882             case SOC_CTR_CTRL_CONFIG_DMA_MINIDX:
  12883                 if ((value < 0) || (value > max_idx)) {
  12884                     return SOC_E_PARAM;
  12885                 }
  12886                 if (in_pipe == -1) {
  12887                     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
  12888                         non_dma->dma_index_min[pipe] = value;
  12889                     }
  12890                 } else {
  12891                     non_dma->dma_index_min[in_pipe] = value;
  12892                 }
  12893                 break;
  12894             case SOC_CTR_CTRL_CONFIG_DMA_MAXIDX:
  12895                 if ((value < 0) || (value > max_idx)) {
  12896                     return SOC_E_PARAM;
  12897                 }
  12898                 if (in_pipe == -1) {
  12899                     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
  12900                         non_dma->dma_index_max[pipe] = value;
  12901                     }
  12902                 } else {
  12903                     non_dma->dma_index_max[in_pipe] = value;
  12904                 }
  12905                 break;
  12906             case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_ALL:
  12907                 if (soc_ctr_ctrl->dma_config_update) {
  12908                     rv = soc_ctr_ctrl->dma_config_update(unit, non_dma,
  12909                                                          config_type, value);
  12910                 }
  12911                 break;
  12912             case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_AUTO:
  12913             case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_WFS:
  12914                 return SOC_E_UNAVAIL;
  12915                 break;
  12916             default:
  12917                 return SOC_E_PARAM;
  12918         }
  12919     }
  12920     return rv;
  12921 }
  12922 
  12923 /*
  12924  * Function:
  12925  *      soc_counter_collect32
  12926  * Purpose:
  12927  *      This routine gets called each time the counter transfer has
  12928  *      completed a cycle.  It collects the 32-bit counters.
  12929  * Parameters:
  12930  *      unit - StrataSwitch unit #.
  12931  *      discard - If TRUE, the software counters are not updated; this
  12932  *              results in only synchronizing the previous hardware
  12933  *              count buffer.
  12934  * Returns:
  12935  *      SOC_E_XXX
  12936  * Notes:
  12937  *      Computes the deltas in the hardware counters from the last
  12938  *      time it was called and adds them to the high resolution (64-bit)
  12939  *      software counters in counter_sw_val[].  It takes wrapping into
  12940  *      account for counters that are less than 32 bits wide.
  12941  *      It also computes counter_delta[].
  12942  */
  12943 
  12944 STATIC int
  12945 soc_counter_collect32(int unit, int discard)
  12946 {
  12947     soc_control_t       *soc = SOC_CONTROL(unit);
  12948     soc_port_t          port;
  12949     soc_reg_t           ctr_reg;
  12950     soc_ctr_ref_t       *ctr_ref;
  12951     uint32              ctr_new, ctr_prev, ctr_diff;
  12952     int                 index;
  12953     int                 port_index;
  12954     int                 dma;
  12955     int                 recheck_cntrs;
  12956     int                 ar_idx;
  12957 
  12958     LOG_DEBUG(BSL_LS_SOC_COUNTER,
  12959                 (BSL_META_U(unit,
  12960                             "soc_counter_collect32: unit=%d discard=%d\n"),
  12961                  unit, discard));
  12962 
  12963     dma = ((soc->counter_flags & SOC_COUNTER_F_DMA) &&
  12964            !discard);
  12965 
  12966     recheck_cntrs = soc_feature(unit, soc_feature_recheck_cntrs);
  12967 
  12968     PBMP_ITER(soc->counter_pbmp, port) {
  12969         /*
  12970          * Flexing operations on certain devices can create new ports,
  12971          * or delete existing ports. This can happen when the counter
  12972          * thread is not running. So we make a check here before proceeding
  12973          * with further processing. We ignore processing for ports which no
  12974          * longer exist.
  12975          */
  12976         if (!SOC_CONTROL(unit)->counter_map[port]) {
  12977             continue;
  12978         }
  12979 
  12980         if ((IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)) &&
  12981             (!SOC_IS_XGS3_SWITCH(unit))) {
  12982                 continue;
  12983         }
  12984 #if defined(BCM_SHADOW_SUPPORT)
  12985         if (SOC_IS_SHADOW(unit) && IS_IL_PORT(unit, port)) {
  12986                 continue;
  12987         }
  12988 #endif /* BCM_SHADOW_SUPPORT */
  12989 
  12990 
  12991         port_index = COUNTER_MIN_IDX_GET(unit, port);
  12992 
  12993         for (index = 0; index < PORT_CTR_NUM(unit, port);
  12994              index++, port_index++) {
  12995             volatile uint64 *vptr;
  12996             COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit);
  12997 
  12998             ctr_ref = PORT_CTR_REG(unit, port, index);
  12999             ctr_reg = ctr_ref->reg;
  13000             ar_idx = ctr_ref->index;
  13001 
  13002             if (SOC_COUNTER_INVALID(unit, ctr_reg)) {
  13003                 continue;
  13004             }
  13005             if (!SOC_REG_PORT_VALID(unit,ctr_reg, port)) {
  13006                 continue;
  13007             }
  13008 
  13009             ctr_prev = COMPILER_64_LO(soc->counter_hw_val[port_index]);
  13010 
  13011             if (dma) {
  13012                 ctr_new = soc->counter_buf32[port_index];
  13013             } else {                   /* Not DMA.  Just read register */
  13014                 SOC_IF_ERROR_RETURN
  13015                     (soc_reg32_get(unit, ctr_reg, port, ar_idx,
  13016                                    &ctr_new));
  13017             }
  13018 
  13019             if ( (recheck_cntrs == TRUE) && (ctr_new != ctr_prev) ) {
  13020                 /* Seeds of doubt, double-check */
  13021                 uint32 ctr_new2;
  13022                 int suspicious = 0;
  13023                 SOC_IF_ERROR_RETURN
  13024                   (soc_reg32_get(unit, ctr_reg, port, 0, &ctr_new2));
  13025 
  13026                 /* Check for partial ordering, with wrap */
  13027                 if (ctr_new < ctr_prev) {
  13028                     if ((ctr_new2 < ctr_new) || (ctr_new2 > ctr_prev)) {
  13029                         /* prev < new2 < new, bad data */
  13030                         /* Try again next time */
  13031                         ctr_new = ctr_prev;
  13032                         suspicious = 1;
  13033                     }
  13034                 } else {
  13035                     if ((ctr_new2 < ctr_new) && (ctr_new2 > ctr_prev)) {
  13036                         /* prev < new2 < new, bad data */
  13037                         /* Try again next time */
  13038                         ctr_new = ctr_prev;
  13039                         suspicious = 1;
  13040                     }
  13041                 }
  13042                 /* Otherwise believe ctr_new */
  13043 
  13044                 if (suspicious) {
  13045 #if !defined(SOC_NO_NAMES)
  13046                     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  13047                              (BSL_META_U(unit,
  13048                                          "soc_counter_collect32: "
  13049                                          "unit %d, port%d: suspicious %s "
  13050                                          "counter read (%s)\n"),
  13051                               unit, port,
  13052                               dma?"DMA":"manual",
  13053                               SOC_REG_NAME(unit, ctr_reg)));
  13054 #else
  13055                     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  13056                              (BSL_META_U(unit,
  13057                                          "soc_counter_collect32: "
  13058                                          "unit %d, port%d: suspicious %s "
  13059                                          "counter read (Counter%d)\n"),
  13060                               unit, port,
  13061                               dma?"DMA":"manual",
  13062                               ctr_reg));
  13063 #endif /* SOC_NO_NAMES */
  13064                 } /* Suspicious counter change */
  13065             } /* recheck_cntrs == TRUE */
  13066 
  13067             if (ctr_new == ctr_prev) {
  13068                 COUNTER_ATOMIC_BEGIN(s);
  13069                 COMPILER_64_SET(soc->counter_delta[port_index], 0, 0);
  13070                 COUNTER_ATOMIC_END(s);
  13071                 continue;
  13072             }
  13073 
  13074             if (discard) {
  13075                 COUNTER_ATOMIC_BEGIN(s);
  13076                 /* Update the DMA location */
  13077                 soc->counter_buf32[port_index] = ctr_new;
  13078                 /* Update the previous value buffer */
  13079                 COMPILER_64_SET(soc->counter_hw_val[port_index], 0, ctr_new);
  13080                 COMPILER_64_SET(soc->counter_delta[port_index], 0, 0);
  13081                 COUNTER_ATOMIC_END(s);
  13082                 continue;
  13083             }
  13084 
  13085             LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  13086                      (BSL_META_U(unit,
  13087                                  "soc_counter_collect32: ctr %d => %u\n"),
  13088                       port_index, ctr_new));
  13089 
  13090             vptr = &soc->counter_sw_val[port_index];
  13091 
  13092             ctr_diff = ctr_new;
  13093 
  13094             if (ctr_diff < ctr_prev) {
  13095                 int             width, i = 0;
  13096 
  13097                 /*
  13098                  * Counter must have wrapped around.  Add the proper
  13099                  * wrap-around amount.  Full 32-bit wide counters do not
  13100                  * need anything added.
  13101                  */
  13102                 width = SOC_REG_INFO(unit, ctr_reg).fields[0].len;
  13103                 if (soc_feature(unit, soc_feature_counter_parity)
  13104 #ifdef BCM_HURRICANE2_SUPPORT
  13105                     || soc_reg_field_valid(unit, ctr_reg, PARITYf)
  13106 #endif
  13107                    )
  13108                 {
  13109                     while((SOC_REG_INFO(unit, ctr_reg).fields + i) != NULL) {
  13110                         if (SOC_REG_INFO(unit, ctr_reg).fields[i].field ==
  13111                             COUNTf) {
  13112                             width = SOC_REG_INFO(unit, ctr_reg).fields[i].len;
  13113                             break;
  13114                         }
  13115                         i++;
  13116                     }
  13117                 }
  13118                 if (width < 32) {
  13119                     ctr_diff += (1UL << width);
  13120                 }
  13121             }
  13122 
  13123             ctr_diff -= ctr_prev;
  13124 
  13125             COUNTER_ATOMIC_BEGIN(s);
  13126             COMPILER_64_ADD_32(*vptr, ctr_diff);
  13127             COMPILER_64_SET(soc->counter_delta[port_index], 0, ctr_diff);
  13128             COMPILER_64_SET(soc->counter_hw_val[port_index], 0, ctr_new);
  13129             COUNTER_ATOMIC_END(s);
  13130 
  13131         }
  13132 
  13133         /* If signaled to exit then return  */
  13134         if (!soc->counter_interval) {
  13135             return SOC_E_NONE;
  13136         }
  13137 
  13138         /*
  13139          * Allow other tasks to run between processing each port.
  13140          */
  13141 
  13142         sal_thread_yield();
  13143     }
  13144 
  13145     return SOC_E_NONE;
  13146 }
  13147 
  13148 #ifdef BCM_SBUSDMA_SUPPORT
  13149 
  13150 #ifdef SOC_COUNTER_TABLE_SUPPORT
  13151 #define COUNTER_SBUSDMA_DESC_SIZE     5
  13152 #elif defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  13153 #define COUNTER_SBUSDMA_DESC_SIZE     4
  13154 #else
  13155 #define COUNTER_SBUSDMA_DESC_SIZE     3
  13156 #endif
  13157 
  13158 #if defined(BCM_ESW_SUPPORT) && (SOC_MAX_NUM_PP_PORTS > SOC_MAX_NUM_PORTS)
  13159 STATIC sbusdma_desc_handle_t
  13160        _soc_port_counter_handles[SOC_MAX_NUM_DEVICES][SOC_MAX_NUM_PP_PORTS][COUNTER_SBUSDMA_DESC_SIZE];
  13161 #else
  13162 STATIC sbusdma_desc_handle_t
  13163           _soc_port_counter_handles[SOC_MAX_NUM_DEVICES][SOC_MAX_NUM_PORTS][COUNTER_SBUSDMA_DESC_SIZE];
  13164 #endif
  13165 
  13166 #endif /* BCM_SBUSDMA_SUPPORT */
  13167 
  13168 int soc_controlled_counter_update_by_port(int unit, soc_port_t dst_port, soc_port_t src_port)
  13169 {
  13170     soc_control_t       *soc = SOC_CONTROL(unit);
  13171     int                  dst_port_base, src_port_base;
  13172     int                  number_of_port_counters;
  13173 
  13174     COUNTER_LOCK(unit);
  13175 
  13176     dst_port_base = COUNTER_IDX_PORTBASE(unit, dst_port);
  13177     src_port_base = COUNTER_IDX_PORTBASE(unit, src_port);
  13178     /*
  13179      * get number of counters per port
  13180      */
  13181     number_of_port_counters = SOC_CONTROL(unit)->counter_perport;
  13182     /*Copy SW counter data from src port to dst port*/
  13183     sal_memcpy(&soc->counter_delta[dst_port_base],  &soc->counter_delta[src_port_base],
  13184                sizeof(uint64) * number_of_port_counters);
  13185     sal_memcpy(&soc->counter_hw_val[dst_port_base],  &soc->counter_hw_val[src_port_base],
  13186                sizeof(uint64) * number_of_port_counters);
  13187     sal_memcpy(&soc->counter_sw_val[dst_port_base],  &soc->counter_sw_val[src_port_base],
  13188                sizeof(uint64) * number_of_port_counters);
  13189     /*Clear SW counter data on src port*/
  13190     sal_memset(&soc->counter_delta[src_port_base],  0x0, sizeof(uint64) * number_of_port_counters);
  13191     sal_memset(&soc->counter_hw_val[src_port_base], 0x0, sizeof(uint64) * number_of_port_counters);
  13192     sal_memset(&soc->counter_sw_val[src_port_base], 0x0, sizeof(uint64) * number_of_port_counters);
  13193 
  13194     COUNTER_UNLOCK(unit);
  13195 
  13196     return SOC_E_NONE;
  13197 }
  13198 
  13199 int soc_controlled_counter_length_get(int unit, soc_controlled_counter_t* ctr, int *length)
  13200 {
  13201     if (ctr && ctr->controlled_counter_length_f != NULL) {
  13202         ctr->controlled_counter_length_f(unit, ctr->counter_id, length);
  13203     } else {
  13204 
  13205         LOG_ERROR(BSL_LS_SOC_COMMON,
  13206               (BSL_META_U(unit,
  13207                           "soc_controlled_counter_length_get: unit %d:"
  13208                           "please define controlled_counter_length_get() function.\n"),
  13209                unit));
  13210         return SOC_E_FAIL;
  13211     }
  13212 
  13213     return SOC_E_NONE;
  13214 }
  13215 /*
  13216  * Function:
  13217  *      soc_controlled_counters_collect64
  13218  * Purpose:
  13219  *      This routine gets called each time the counter transfer has
  13220  *      completed a cycle.  It collects the 64-bit controlled counters.
  13221  */
  13222 int
  13223 soc_controlled_counters_collect64(int unit, int discard)
  13224 {
  13225     soc_control_t       *soc = SOC_CONTROL(unit);
  13226     soc_port_t          port;
  13227     uint64              ctr_new;
  13228     uint64              ctr_diff,ctr_prev;
  13229     uint64              ctr_delta;
  13230     int                 index, port_base;
  13231     soc_controlled_counter_t* ctr;
  13232     uint32 clear_on_read;
  13233 
  13234     LOG_DEBUG(BSL_LS_SOC_COUNTER,
  13235                 (BSL_META_U(unit,
  13236                             "soc_controlled_counters_collect64: unit=%d "
  13237                             "discard=%d\n"), unit, discard));
  13238 
  13239      if (!soc_feature(unit, soc_feature_controlled_counters)) {
  13240         return SOC_E_NONE;
  13241     }
  13242 
  13243     PBMP_ITER(soc->counter_pbmp, port) {
  13244         if (!soc->controlled_counters) {
  13245             break;
  13246         }
  13247         for (index = 0; soc->controlled_counters[index].controlled_counter_f != NULL; index++) {
  13248             volatile uint64 *vptr;
  13249             COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit);
  13250 
  13251             ctr = &soc->controlled_counters[index];
  13252 
  13253             if(!COUNTER_IS_COLLECTED(soc->controlled_counters[index])) {
  13254                 continue;
  13255             }
  13256 
  13257             ctr->controlled_counter_f(unit, ctr->counter_id, port, &ctr_new, &clear_on_read);
  13258 
  13259             if(clear_on_read) {
  13260                 /* Counters are Clear-on-Read. Add ctr_new to
  13261                  * previously stored sw value if discard is not set
  13262                  */
  13263 
  13264                 port_base = COUNTER_IDX_PORTBASE(unit, port);
  13265                 /* In order to improve access efficiency. Here we didn't take atomic lock first,
  13266                  * and get the delta value directly. In case the delta value was messed up, it
  13267                  * doesn't matter. Because the delta vaule was not used to update SOC DB.
  13268                  */
  13269                 ctr_delta = soc->counter_delta[port_base + ctr->counter_idx];
  13270 
  13271                 if (COMPILER_64_IS_ZERO(ctr_new) && COMPILER_64_IS_ZERO(ctr_delta)) {
  13272                     continue;
  13273                 }
  13274 
  13275                 if (discard) {
  13276                     /* Update the previous value buffer */
  13277                     COUNTER_ATOMIC_BEGIN(s);
  13278                     soc->counter_hw_val[port_base + ctr->counter_idx] = ctr_new;
  13279                     COMPILER_64_ZERO(soc->counter_delta[port_base + ctr->counter_idx]);
  13280                     COUNTER_ATOMIC_END(s);
  13281                     continue;
  13282                 }
  13283                 LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  13284                          (BSL_META_U(unit,
  13285                                      "soc_controlled_counters_collect64: ctr %d => "
  13286                                      "0x%08x_%08x\n"), port_base + ctr->counter_idx,
  13287                           COMPILER_64_HI(ctr_new), COMPILER_64_LO(ctr_new)));
  13288 
  13289                 vptr = &soc->counter_sw_val[port_base + ctr->counter_idx];
  13290                 COUNTER_ATOMIC_BEGIN(s);
  13291                 COMPILER_64_ADD_64(*vptr, ctr_new);
  13292                 soc->counter_delta[port_base + ctr->counter_idx] = ctr_new;
  13293                 soc->counter_hw_val[port_base + ctr->counter_idx] = ctr_new;
  13294                 COUNTER_ATOMIC_END(s);
  13295             } else {
  13296                 /* Counters are NOT Clear-on-Read. Add ctr_new to
  13297                  * previously stored sw value if discard is not set.
  13298                  * Should consider the HW reg roll back.
  13299                  */
  13300                 port_base = COUNTER_IDX_PORTBASE(unit, port);
  13301                 /* Atomic because soc_counter_set may update 64-bit value */
  13302                 COUNTER_ATOMIC_BEGIN(s);
  13303                 ctr_prev = soc->counter_hw_val[port_base + ctr->counter_idx];
  13304                 COUNTER_ATOMIC_END(s);
  13305 
  13306                 if (COMPILER_64_EQ(ctr_new, ctr_prev)) {
  13307                     COUNTER_ATOMIC_BEGIN(s);
  13308                     COMPILER_64_ZERO(soc->counter_delta[port_base + ctr->counter_idx]);
  13309                     COUNTER_ATOMIC_END(s);
  13310                     continue;
  13311                 }
  13312 
  13313                 vptr = &soc->counter_sw_val[port_base + ctr->counter_idx];
  13314                 ctr_diff = ctr_new;
  13315                 if (COMPILER_64_LT(ctr_diff, ctr_prev)) {
  13316                     int             width;
  13317                     uint64          wrap_amt;
  13318                     /*
  13319                      * Counter must have wrapped around.
  13320                      * Add the proper wrap-around amount.
  13321                      */
  13322                     SOC_IF_ERROR_RETURN(soc_controlled_counter_length_get(unit, ctr, &width));
  13323 
  13324                     if (width < 32) {
  13325                         COMPILER_64_SET(wrap_amt, 0, 1UL << width);
  13326                         COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  13327                     } else if (width < 64) {
  13328                         COMPILER_64_SET(wrap_amt, 1UL << (width - 32), 0);
  13329                         COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  13330                     }
  13331                 }
  13332 
  13333                 COMPILER_64_SUB_64(ctr_diff, ctr_prev);
  13334 
  13335                 COUNTER_ATOMIC_BEGIN(s);
  13336                 COMPILER_64_ADD_64(*vptr, ctr_diff);
  13337                 soc->counter_delta[port_base + ctr->counter_idx ] = ctr_diff;
  13338                 soc->counter_hw_val[port_base + ctr->counter_idx ] = ctr_new;
  13339                 COUNTER_ATOMIC_END(s);
  13340             }
  13341 
  13342         }
  13343 
  13344         /* If signaled to exit then return  */
  13345         if (!soc->counter_interval) {
  13346             return SOC_E_NONE;
  13347         }
  13348 
  13349         /* Allow other tasks to run between processing each port */
  13350         COUNTER_UNLOCK(unit);
  13351         sal_thread_yield();
  13352         COUNTER_LOCK(unit);
  13353     }
  13354 
  13355     return SOC_E_NONE;
  13356 }
  13357 
  13358 #ifdef BCM_XGS_SUPPORT
  13359 
  13360 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  13361 /*
  13362  * Function:
  13363  *      _soc_xgs3_update_link_activity
  13364  * Purpose:
  13365  *      Report the link activities to LED processor.
  13366  * Parameters:
  13367  *      unit     - switch unit
  13368  *      port     - port number
  13369  *      tx_byte  - transmitted byte during counter DMA interval
  13370  *      rx_byte  - received byte during counter DMA interval
  13371  *
  13372  * Returns:
  13373  *      SOC_E_*
  13374  */
  13375 static int
  13376 _soc_xgs3_update_link_activity(int unit, soc_port_t port,
  13377                                uint32 tx_byte, uint32 rx_byte)
  13378 {
  13379     soc_control_t       *soc = SOC_CONTROL(unit);
  13380     int                  port_speed, interval, byte;
  13381     uint32               portdata, act_byte;
  13382     soc_info_t *si = &SOC_INFO(unit);
  13383 
  13384     if (si->port_speed_max[port] >= 100000) {
  13385         port_speed = si->port_speed_max[port];
  13386     } else {
  13387     SOC_IF_ERROR_RETURN(soc_mac_speed_get(unit, port, &port_speed));
  13388     }
  13389 
  13390     portdata = 0;
  13391     interval = soc->counter_interval;
  13392 
  13393     if (tx_byte < rx_byte) {
  13394         act_byte = rx_byte;
  13395     } else {
  13396         act_byte = tx_byte;
  13397     }
  13398 
  13399     if (act_byte > (uint32)(((port_speed / 8) * interval) / 2)) {
  13400         /* transmitting or receiving more than 50% */
  13401         portdata |= 0x2;
  13402     } else if (act_byte > (uint32)(((port_speed / 8) * interval) / 4)) {
  13403         /* transmitting or receiving more than 25% */
  13404         portdata |= 0x4;
  13405     } else if (act_byte > 0) {
  13406         /* some transmitting or receiving activity on the link */
  13407         portdata |= 0x8;
  13408     }
  13409 
  13410     if (tx_byte) {
  13411         /* Indicate TX activity */
  13412         portdata |= 0x10;
  13413     }
  13414     if (rx_byte) {
  13415         /* Indicate RX activity */
  13416         portdata |= 0x20;
  13417     }
  13418 
  13419 #ifdef BCM_TRIDENT_SUPPORT
  13420 #define MONTEREY_LEDUP_PORT_MAX        64 
  13421 #define APACHE_LEDUP_PORT_MAX          36
  13422 #define TRIDENT_LEDUP0_PORT_MAX        36
  13423 #define TRIDENT2_LEDUP0_PORT_MAX       64
  13424 
  13425     if (SOC_IS_TD_TT(unit)) {
  13426         soc_info_t *si;
  13427         int phy_port;  /* physical port number */
  13428         uint32 dram_base;
  13429         uint32 prev_data;
  13430 
  13431         si = &SOC_INFO(unit);
  13432         phy_port = si->port_l2p_mapping[port];
  13433 
  13434         /* trident first 36 ports in ledproc0, the other 36 ports in ledproc1*/
  13435         if (phy_port > TRIDENT_LEDUP0_PORT_MAX) {
  13436             phy_port -= TRIDENT_LEDUP0_PORT_MAX;
  13437             dram_base = CMICE_LEDUP1_DATA_RAM_BASE;
  13438         } else {
  13439             dram_base = CMICE_LEDUP0_DATA_RAM_BASE;
  13440         }
  13441 #ifdef BCM_CMICM_SUPPORT
  13442         if (soc_feature(unit, soc_feature_cmicm)) {
  13443             if (SOC_IS_TRIDENT2X(unit) && !SOC_IS_APACHE(unit)) {
  13444             int i, skip_count = 0;
  13445             int led_ix = (phy_port > TRIDENT2_LEDUP0_PORT_MAX)? 1:0;
  13446             for (i=1; i<phy_port; i++) {
  13447                 skip_count += ((si->port_p2l_mapping[i+(led_ix*TRIDENT2_LEDUP0_PORT_MAX)] == -1) ? 1: 0);
  13448             }
  13449             if (phy_port > TRIDENT2_LEDUP0_PORT_MAX) {
  13450                 phy_port -= TRIDENT2_LEDUP0_PORT_MAX;
  13451                 dram_base = CMIC_LEDUP1_DATA_RAM_OFFSET;
  13452             } else {
  13453                 dram_base = CMIC_LEDUP0_DATA_RAM_OFFSET;
  13454             }
  13455             phy_port -= skip_count;
  13456             } else if (SOC_IS_MONTEREY(unit) ) {
  13457                 phy_port = si->port_l2p_mapping[port];
  13458                     dram_base = CMIC_LEDUP0_DATA_RAM_OFFSET;
  13459             } else if (SOC_IS_APACHE(unit) ) {
  13460                 phy_port = si->port_l2p_mapping[port];
  13461                 /* Apache first 36 ports in ledproc0, the other 36 ports in ledproc1*/
  13462                 if (phy_port > APACHE_LEDUP_PORT_MAX) {
  13463                     phy_port -= APACHE_LEDUP_PORT_MAX;
  13464                     dram_base = CMIC_LEDUP1_DATA_RAM_OFFSET;
  13465                 } else {
  13466                     dram_base = CMIC_LEDUP0_DATA_RAM_OFFSET;
  13467                 }
  13468             }
  13469         }
  13470 #endif /* BCM_CMICM_SUPPORT */
  13471         if (soc_feature(unit, soc_feature_led_data_offset_a0)) {
  13472             byte = LS_LED_DATA_OFFSET_A0 + phy_port;
  13473             if (SOC_IS_APACHE(unit)) {
  13474                 byte -= 1; /* Start from A0 offset */
  13475             }
  13476         } else {
  13477             byte = LS_LED_DATA_OFFSET + phy_port;
  13478         }
  13479 
  13480         prev_data = soc_pci_read(unit, dram_base + CMIC_LED_REG_SIZE * byte);
  13481         prev_data &= ~0x3e;
  13482         portdata |= prev_data;
  13483         soc_pci_write(unit, dram_base + CMIC_LED_REG_SIZE * byte, portdata);
  13484 
  13485     } else
  13486 #ifdef BCM_SABER2_SUPPORT
  13487     if (SOC_IS_SABER2(unit)) {
  13488         uint32 lastdata = 0;
  13489         byte = LS_LED_DATA_OFFSET_A0 + port;
  13490         lastdata = soc_pci_read(unit, CMIC_LEDUP0_DATA_RAM_OFFSET + CMIC_LED_REG_SIZE * byte);
  13491         lastdata &= ~0x30;
  13492         portdata |= lastdata;
  13493         soc_pci_write(unit, CMIC_LEDUP0_DATA_RAM_OFFSET + CMIC_LED_REG_SIZE * byte, portdata);
  13494     } else
  13495 #endif
  13496 #endif
  13497     {
  13498         /* 20 bytes from LS_LED_DATA_OFFSET is used by linkscan callback */
  13499         byte = LS_LED_DATA_OFFSET + 20 + port;
  13500         soc_pci_write(unit, CMIC_LED_DATA_RAM(byte), portdata);
  13501     }
  13502     return SOC_E_NONE;
  13503 }
  13504 #endif
  13505 #endif /* BCM_XGS_SUPPORT */
  13506 
  13507 #if defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT)
  13508 /*
  13509  * Function:
  13510  *      soc_counter_collect64
  13511  * Purpose:
  13512  *      This routine gets called each time the counter transfer has
  13513  *      completed a cycle.  It collects the 64-bit counters.
  13514  * Parameters:
  13515  *      unit - StrataSwitch unit #.
  13516  *      discard - If true, the software counters are not updated; this
  13517  *              results in only synchronizing the previous hardware
  13518  *              count buffer.
  13519  *      tmp_port - if -1 sw accumulation of all the counters done.
  13520  *             port valid when hw_ctr_reg is valid
  13521  *      hw_ctr_reg - if -1 sw accumulation of all the counters done.
  13522  *                   else hw register value of the tmp_port synced
  13523  *                   to sw counter.
  13524  * Returns:
  13525  *      SOC_E_XXX
  13526  * Notes:
  13527  *      It computes the deltas in the hardware counters from the last
  13528  *      time it was called and adds them to the high resolution (64-bit)
  13529  *      software counters in counter_sw_val[].  It takes wrapping into
  13530  *      account for counters that are less than 64 bits wide.
  13531  *      It also computes counter_delta[].
  13532  */
  13533 
  13534 STATIC int
  13535 soc_counter_collect64(int unit, int discard, soc_port_t tmp_port, soc_reg_t hw_ctr_reg)
  13536 {
  13537     soc_control_t       *soc = SOC_CONTROL(unit);
  13538     soc_port_t          port;
  13539     soc_reg_t           ctr_reg;
  13540     uint64              ctr_new, ctr_prev, ctr_diff;
  13541     int                 index, max_index;
  13542     int                 port_base, port_base_dma;
  13543     int                 dma = 0;
  13544     int                 recheck_cntrs;
  13545     int                 ar_idx;
  13546     pbmp_t              counter_pbmp;
  13547 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT)
  13548     int                 pio_hold, pio_hold_enable;
  13549     uint64              *counter_tmp = NULL;
  13550     uint32              tx_byt_to_led = 0;
  13551     uint32              rx_byt_to_led = 0;
  13552     int                 rxcnt_xaui = 0;
  13553     int                 skip_xaui_rx_counters;
  13554     soc_reg_t           reg_1a = INVALIDr;
  13555     soc_reg_t           reg_1b = INVALIDr;
  13556     soc_reg_t           reg_2a = INVALIDr;
  13557     soc_reg_t           reg_2b = INVALIDr;
  13558 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */
  13559 
  13560     LOG_DEBUG(BSL_LS_SOC_COUNTER,
  13561                 (BSL_META_U(unit,
  13562                             "soc_counter_collect64: unit=%d discard=%d\n"),
  13563                  unit, discard));
  13564 
  13565     COMPILER_64_ZERO(ctr_new);
  13566     COMPILER_64_ZERO(ctr_prev);
  13567     COMPILER_64_ZERO(ctr_diff);
  13568 
  13569     /* hw_ctr_reg is INVALIDr for normal sw counter accumulation */
  13570     if (hw_ctr_reg == INVALIDr) {
  13571         dma = ((soc->counter_flags & SOC_COUNTER_F_DMA) && (discard != TRUE));
  13572     }
  13573     recheck_cntrs = soc_feature(unit, soc_feature_recheck_cntrs);
  13574 
  13575 #ifdef BCM_BRADLEY_SUPPORT
  13576     pio_hold = SOC_IS_HBX(unit);
  13577     pio_hold_enable = (soc->counter_flags & SOC_COUNTER_F_HOLD);
  13578 
  13579     if (SOC_IS_HBX(unit) && soc_feature(unit, soc_feature_bigmac_rxcnt_bug)) {
  13580         
  13581         rxcnt_xaui = 1;
  13582         reg_1a = MAC_TXPSETHRr;
  13583         reg_1b = IRFCSr;
  13584         reg_2a = MAC_TXMAXSZr;
  13585         reg_2b = IROVRr;
  13586         if (dma) {
  13587             counter_tmp = soc_counter_tbuf[unit];
  13588         }
  13589     }
  13590 #endif /* BCM_BRADLEY_SUPPORT */
  13591 
  13592 #ifdef BCM_TRX_SUPPORT
  13593     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_bigmac_rxcnt_bug)) {
  13594         
  13595         rxcnt_xaui = 1;
  13596         reg_1a = MAC_TXPSETHRr;
  13597 #ifdef BCM_ENDURO_SUPPORT
  13598         if(SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit)) {
  13599             reg_1b = IRUCAr;
  13600         } else
  13601 #endif /* BCM_ENDURO_SUPPORT */
  13602         {
  13603             reg_1b = IRUCr;
  13604         }
  13605         reg_2a = MAC_TXMAXSZr;
  13606         reg_2b = IRFCSr;
  13607         if (dma) {
  13608             counter_tmp = soc_counter_tbuf[unit];
  13609         }
  13610     }
  13611 #endif /* BCM_TRX_SUPPORT */
  13612 
  13613     if (hw_ctr_reg == INVALIDr) {
  13614         /* accumulate sw counters for all ports */
  13615         SOC_PBMP_CLEAR(counter_pbmp);
  13616         SOC_PBMP_ASSIGN(counter_pbmp, soc->counter_pbmp);
  13617     } else {
  13618         /* sync and accumulate sw counter for specified register of port */
  13619         SOC_PBMP_CLEAR(counter_pbmp);
  13620         port = tmp_port;
  13621         SOC_PBMP_PORT_ADD(counter_pbmp, port);
  13622     }
  13623 
  13624     PBMP_ITER(counter_pbmp, port) {
  13625         /*
  13626          * Flexing operations on certain devices can create new ports,
  13627          * or delete existing ports. This can happen when the counter
  13628          * thread is not running. So we make a check here before proceeding
  13629          * with further processing. We ignore processing for ports which no
  13630          * longer exist.
  13631          */
  13632         if (!SOC_CONTROL(unit)->counter_map[port]) {
  13633             continue;
  13634         }
  13635 
  13636         if (!SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_ARAD(unit) &&
  13637             !IS_HG_PORT(unit, port) && !IS_XE_PORT(unit, port)) {
  13638                 continue;
  13639         }
  13640 
  13641         port_base = COUNTER_MIN_IDX_GET(unit, port);
  13642         port_base_dma = COUNTER_MIN_IDX_GET(unit, port - soc->counter_ports32);
  13643 
  13644 #ifdef BCM_PETRA_SUPPORT
  13645         if (SOC_IS_ARAD(unit)) {
  13646             if (_SOC_CONTROLLED_COUNTER_USE(unit, port)) {
  13647                 continue;
  13648             }
  13649             port_base += _SOC_CONTROLLED_COUNTER_NOF(unit);
  13650         }
  13651 #endif /*BCM_PETRA_SUPPORT*/
  13652 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT)
  13653         /*
  13654          * Handle XAUI Rx counter bug.
  13655          *
  13656          * If the IRFCS counter returns the contents of the
  13657          * MAC_TXPSETHR register, and the IROVR counter returns the
  13658          * contents of the MAC_TXMAXSZ register, we assume that the
  13659          * counters are bogus.
  13660          *
  13661          * By using two counters we significantly reduce the chance of
  13662          * getting stuck if the real counter value matches the bogus
  13663          * reference.
  13664          *
  13665          * To protect ourselves from the error condition happening
  13666          * while the counter DMA is in progress, we manually check the
  13667          * counters before and after we copy the DMA buffer contents.
  13668          */
  13669         skip_xaui_rx_counters = 1;
  13670         if (rxcnt_xaui &&
  13671             (IS_GX_PORT(unit, port) ||
  13672              (IS_XG_PORT(unit, port) &&
  13673               (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port))))) {
  13674             uint64 val_1a, val_1b, val_2a, val_2b;
  13675             uint32 *p1, *p2;
  13676             int rxcnt_appear_valid = 0;
  13677 
  13678             /* Read reference values and counter values */
  13679             if (soc_reg_get(unit, reg_1a, port, 0, &val_1a) == 0 &&
  13680                 soc_reg_get(unit, reg_1b, port, 0, &val_1b) == 0 &&
  13681                 soc_reg_get(unit, reg_2a, port, 0, &val_2a) == 0 &&
  13682                 soc_reg_get(unit, reg_2b, port, 0, &val_2b) == 0) {
  13683 
  13684                 /* Check for bogus values */
  13685                 if (COMPILER_64_NE(val_1a, val_1b) ||
  13686                     COMPILER_64_NE(val_2a, val_2b)) {
  13687                     rxcnt_appear_valid = 1;
  13688                 }
  13689                 if (rxcnt_appear_valid && counter_tmp) {
  13690                     /* Copy DMA buffer */
  13691                     sal_memcpy(counter_tmp, &soc->counter_buf64[port_base_dma],
  13692                                SOC_COUNTER_TBUF_SIZE(unit));
  13693                     p1 = (uint32 *)&counter_tmp[SOC_REG_CTR_IDX(unit, reg_1b)];
  13694                     p2 = (uint32 *)&counter_tmp[SOC_REG_CTR_IDX(unit, reg_2b)];
  13695                     /* Read counter values again */
  13696                     if (soc_reg_get(unit, reg_1b, port, 0, &val_1b) == 0 &&
  13697                         soc_reg_get(unit, reg_2b, port, 0, &val_2b) == 0) {
  13698                         /* Check for bogus value again, including DMA buffer */
  13699                         if ((COMPILER_64_NE(val_1a, val_1b) ||
  13700                              COMPILER_64_NE(val_2a, val_2b)) &&
  13701                             (p1[0] != COMPILER_64_LO(val_1a) ||
  13702                              p2[0] != COMPILER_64_LO(val_2a))) {
  13703                             /* Counters appears to be valid */
  13704                             skip_xaui_rx_counters = 0;
  13705                         }
  13706                     }
  13707                 } else if (rxcnt_appear_valid && !dma) {
  13708                     /* If not DMA we take the chance and read the counters */
  13709                     skip_xaui_rx_counters = 0;
  13710                 }
  13711             }
  13712         }
  13713 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */
  13714 
  13715         if (hw_ctr_reg == INVALIDr) {
  13716             index = 0;
  13717             max_index = PORT_CTR_NUM(unit, port);
  13718         } else {
  13719             int  port_index1, num_entries1;
  13720             char *cname;
  13721 
  13722             /* get index of counter register */
  13723             SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, hw_ctr_reg,
  13724                                                       &port_index1, &num_entries1,
  13725                                                       &cname));
  13726 
  13727             index = port_index1 - port_base;
  13728             max_index = index + 1;
  13729         }
  13730 
  13731         for ( ; index < max_index; index++) {
  13732             volatile uint64 *vptr;
  13733             COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit);
  13734 
  13735             ctr_reg = PORT_CTR_REG(unit, port, index)->reg;
  13736             ar_idx = PORT_CTR_REG(unit, port, index)->index;
  13737 
  13738             if (SOC_COUNTER_INVALID(unit, ctr_reg)) {
  13739                 continue;
  13740             }
  13741             if ((ctr_reg < NUM_SOC_REG) && !SOC_REG_PORT_IDX_VALID(unit,ctr_reg, port, ar_idx)) {
  13742                 continue;
  13743             }
  13744 
  13745 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  13746             /* Trap for BigMAC TX Timestamp FIFO reads
  13747              *
  13748              * MAC_TXTIMESTAMPFIFOREADr is immediately after
  13749              * MAC_RXLLFCMSGCNTr.  It is a single register exposing
  13750              * a HW FIFO which pops on read.  And it is in the counter
  13751              * DMA range.  So we detect MAC_RXLLFCMSGCNTr and record
  13752              * the value of the next piece of data in a SW FIFO for
  13753              * use by the API.
  13754              */
  13755             if (soc_feature(unit, soc_feature_timestamp_counter) &&
  13756                 dma && (ctr_reg == MAC_RXLLFCMSGCNTr) &&
  13757                 (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port)) &&
  13758                 (soc->counter_timestamp_fifo[port] != NULL) &&
  13759                 !SHR_FIFO_IS_FULL(soc->counter_timestamp_fifo[port])) {
  13760                 uint32 *ptr =
  13761                     (uint32 *)&soc->counter_buf64[port_base_dma + index + 1];
  13762 
  13763                 if (ptr[0] != 0) { /* Else, HW FIFO empty */
  13764                     SHR_FIFO_PUSH(soc->counter_timestamp_fifo[port], &(ptr[0]));
  13765                 }
  13766             }
  13767             /*If spn_SW_TIMESTAMP_FIFO_ENABLE is 0, the counter DMA will not
  13768              *read register MAC_TXTIMESTAMPFIFOREAD. 
  13769              */
  13770             if (!SOC_CONTROL(unit)->sw_timestamp_fifo_enable &&
  13771                 IS_XE_PORT(unit, port) &&
  13772                 (index >= (DIRECT_TIMESTAMP_DMA_COUNTER_NUM +
  13773                            XMAC_DMA_COUNTER_BASE))) {
  13774                 dma = FALSE;                
  13775             }
  13776 
  13777 #endif /* BCM_TRIUMPH2_SUPPORT */
  13778 
  13779             /* Atomic because soc_counter_set may update 64-bit value */
  13780             COUNTER_ATOMIC_BEGIN(s);
  13781             ctr_prev = soc->counter_hw_val[port_base + index];
  13782             COUNTER_ATOMIC_END(s);
  13783 
  13784 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT)
  13785             if (pio_hold && ctr_reg == HOLDr) {
  13786                 if (pio_hold_enable) {
  13787                     uint64 ctr_prev_x, ctr_prev_y;
  13788                     uint32 ctr_x, ctr_y;
  13789                     int idx_x, idx_y;
  13790                     /*
  13791                      * We need to account for the two values of HOLD
  13792                      * separately to get correct rollover behavior.
  13793                      * Use holes in counter space to store HOLD_X/Y values
  13794                      * HOLD_X at RDBGC4r, hole, IUNHGIr
  13795                      * HOLD_Y at IUNKOPCr, hole, RDBGC5r
  13796                      */
  13797 
  13798                     idx_x = SOC_REG_CTR_IDX(unit, RDBGC4r) + 1;
  13799                     idx_y = SOC_REG_CTR_IDX(unit, IUNKOPCr) + 1;
  13800 
  13801                     COUNTER_ATOMIC_BEGIN(s);
  13802                     ctr_prev_x = soc->counter_hw_val[port_base + idx_x];
  13803                     ctr_prev_y = soc->counter_hw_val[port_base + idx_y];
  13804                     COUNTER_ATOMIC_END(s);
  13805 
  13806                     SOC_IF_ERROR_RETURN
  13807                         (soc_reg32_get(unit, HOLD_Xr, port, ar_idx,
  13808                                        &ctr_x));
  13809                     SOC_IF_ERROR_RETURN
  13810                         (soc_reg32_get(unit, HOLD_Yr, port, ar_idx,
  13811                                        &ctr_y));
  13812 
  13813                     if (discard) {
  13814                         /* Just save the new sum to be used below */
  13815                         COMPILER_64_SET(ctr_new, 0, ctr_x + ctr_y);
  13816                     } else {
  13817                         int             width = 0;
  13818                         uint64          wrap_amt;
  13819 
  13820                         COMPILER_64_SET(ctr_diff, 0, ctr_x);
  13821                         /* We know the width of HOLDr is < 32 */
  13822                         if (COMPILER_64_LT(ctr_diff, ctr_prev_x)) {
  13823                             width =
  13824                                 SOC_REG_INFO(unit, ctr_reg).fields[0].len;
  13825                             COMPILER_64_SET(wrap_amt, 0, 1UL << width);
  13826                             COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  13827                         }
  13828                         /* Calculate HOLD_X diff from previous */
  13829                         COMPILER_64_SUB_64(ctr_diff, ctr_prev_x);
  13830                         ctr_new = ctr_diff;
  13831 
  13832                         COMPILER_64_SET(ctr_diff, 0, ctr_y);
  13833                         if (COMPILER_64_LT(ctr_diff, ctr_prev_y)) {
  13834                             width =
  13835                                 SOC_REG_INFO(unit, ctr_reg).fields[0].len;
  13836                             COMPILER_64_SET(wrap_amt, 0, 1UL << width);
  13837                             COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  13838                         }
  13839                         /* Calculate HOLD_Y diff from previous */
  13840                         COMPILER_64_SUB_64(ctr_diff, ctr_prev_y);
  13841 
  13842                         /* Combine diffs */
  13843                         COMPILER_64_ADD_64(ctr_new, ctr_diff);
  13844                         /* Add previous value so logic below handles
  13845                          * all of the other updates */
  13846                         COMPILER_64_ADD_64(ctr_new, ctr_prev);
  13847                     }
  13848 
  13849                     /* Update previous values with new values.
  13850                      * Since these are INVALID registers, the other
  13851                      * counter logic will not touch them. */
  13852                     COMPILER_64_SET(soc->counter_hw_val[port_base + idx_x], 0, ctr_x);
  13853                     COMPILER_64_SET(soc->counter_hw_val[port_base + idx_y], 0, ctr_y);
  13854                 } else {
  13855                     /*
  13856                      * The counter collected by DMA is not reliable
  13857                      * due to incorrect access type, so force zero.
  13858                      */
  13859                     COMPILER_64_ZERO(ctr_new);
  13860                 }
  13861             } else if (IS_HYPLITE_PORT(unit, port) && is_xaui_rx_counter(ctr_reg)) {
  13862                 SOC_IF_ERROR_RETURN
  13863                     (soc_reg_read(unit, ctr_reg,
  13864                                     soc_reg_addr(unit, ctr_reg, port, ar_idx),
  13865                                     &ctr_new));
  13866             } else if (rxcnt_xaui && is_xaui_rx_counter(ctr_reg)) {
  13867                 if (skip_xaui_rx_counters) {
  13868                     ctr_new = ctr_prev;
  13869                 } else if (counter_tmp) {
  13870                     uint32 *ptr = (uint32 *)&counter_tmp[index];
  13871                     /* No need to check for SWAP64 flag */
  13872                     COMPILER_64_SET(ctr_new, ptr[1], ptr[0]);
  13873                 } else {
  13874                     SOC_IF_ERROR_RETURN
  13875                         (soc_reg_get(unit, ctr_reg, port, ar_idx,
  13876                                      &ctr_new));
  13877                 }
  13878             } else
  13879 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */
  13880             if (dma) {
  13881 #ifdef BCM_SBUSDMA_SUPPORT
  13882 #ifdef SOC_COUNTER_TABLE_SUPPORT
  13883                 if (SOC_IS_TOMAHAWK3(unit) &&
  13884                     soc_feature(unit, soc_feature_sbusdma) &&
  13885                          SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) {
  13886                     uint32 *ptr;
  13887                     int dma_offset = SOC_CTR_TBL_INFO(unit)->tables[index - soc->counter_mib_tbl_first].dma_offset;
  13888                     ptr = (uint32 *)&soc->counter_buf64[port_base_dma + soc->counter_mib_tbl_first + dma_offset];
  13889                     if (soc->counter_flags & SOC_COUNTER_F_SWAP64) {
  13890                         COMPILER_64_SET(ctr_new, ptr[0], ptr[1]);
  13891                     } else {
  13892                         COMPILER_64_SET(ctr_new, ptr[1], ptr[0]);
  13893                     }
  13894                 } else
  13895 #endif /* SOC_COUNTER_TABLE_SUPPORT */
  13896                 if (soc_feature(unit, soc_feature_sbusdma) &&
  13897                     (ctr_reg < NUM_SOC_REG) &&
  13898                     !SOC_REG_IS_64(unit, ctr_reg)) {
  13899                     uint32 *buf32, *ptr, temp = 0;
  13900                     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) {
  13901                         if (index < soc->counter_egr_first) {
  13902                             buf32 = (uint32 *)&soc->counter_buf64[port_base_dma +
  13903                                                                   soc->counter_ing_first];
  13904                             ptr = &buf32[index - soc->counter_ing_first];
  13905                         } else {
  13906                             buf32 = (uint32 *)&soc->counter_buf64[port_base_dma +
  13907                                                                   soc->counter_egr_first];
  13908                             ptr = &buf32[index - soc->counter_egr_first];
  13909                         }
  13910                         temp = *ptr & ((1 << soc_reg_field_length
  13911                                (unit, ctr_reg, COUNTf)) - 1);
  13912                     } else {
  13913                         if (index < soc->counter_egr_first) {
  13914                             buf32 = (uint32 *)&soc->counter_buf64[port_base_dma +
  13915                                                                   soc->counter_ing_first];
  13916                             ptr = &buf32[index - soc->counter_ing_first];
  13917                         } else if (index < soc->counter_mac_first) {
  13918                             buf32 = (uint32 *)&soc->counter_buf64[port_base_dma +
  13919                                                                   soc->counter_egr_first];
  13920                             ptr = &buf32[index - soc->counter_egr_first];
  13921                         } else {
  13922                             buf32 = (uint32 *)&soc->counter_buf64[port_base_dma +
  13923                                                                   soc->counter_mac_first];
  13924                             ptr = &buf32[index - soc->counter_mac_first];
  13925                         }
  13926 
  13927                         if (soc_reg_field_length(unit, ctr_reg, COUNTf) == 32) {
  13928                             temp = *ptr & 0xffffffff;
  13929                         } else {
  13930                             temp = *ptr & ((1 << soc_reg_field_length
  13931                                    (unit, ctr_reg, COUNTf)) - 1);
  13932                         }
  13933                     }
  13934                     COMPILER_64_SET(ctr_new, 0, temp);
  13935                 } else
  13936 #endif /* BCM_SBUSDMA_SUPPORT */
  13937                 {
  13938                     uint32 *ptr =
  13939                         (uint32 *)&soc->counter_buf64[port_base_dma + index];
  13940                     if (soc->counter_flags & SOC_COUNTER_F_SWAP64) {
  13941                         COMPILER_64_SET(ctr_new, ptr[0], ptr[1]);
  13942                     } else {
  13943                         COMPILER_64_SET(ctr_new, ptr[1], ptr[0]);
  13944                     }
  13945                 }
  13946             } else {
  13947                 if(ctr_reg < NUM_SOC_REG) {
  13948                 SOC_IF_ERROR_RETURN
  13949                     (soc_reg_get(unit, ctr_reg, port, ar_idx,
  13950                                  &ctr_new));
  13951             }
  13952 #ifdef SOC_COUNTER_TABLE_SUPPORT
  13953                 else if (SOC_IS_TOMAHAWK3(unit) &&
  13954                          SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) {
  13955                     soc_ctr_tbl_entry_t *ctr_tbl_info_entry = NULL;
  13956                     SOC_IF_ERROR_RETURN
  13957                         (_soc_counter_tbl_get_info(unit, port, ctr_reg, &ctr_tbl_info_entry));
  13958                     SOC_IF_ERROR_RETURN
  13959                         (_soc_ctr_tbl_field_get(unit, ctr_reg, port, ctr_tbl_info_entry, &ctr_new));
  13960                 }
  13961 #endif /* SOC_COUNTER_TABLE_SUPPORT */
  13962             }
  13963 
  13964             /*
  13965              * For counter sync operation update the dma buffer
  13966              * for the port index with the value read from hardware
  13967              * counter register.
  13968              */
  13969             if ((hw_ctr_reg != INVALIDr) &&
  13970                 (soc->counter_flags & SOC_COUNTER_F_DMA)) {
  13971                 uint32 *ptr;
  13972 #ifdef BCM_SBUSDMA_SUPPORT
  13973                 if (soc_feature(unit, soc_feature_sbusdma) &&
  13974                     (ctr_reg < NUM_SOC_REG) &&
  13975                     !SOC_REG_IS_64(unit, ctr_reg)) {
  13976                     uint32 *buf32;
  13977                         if (SOC_IS_TOMAHAWKX(unit)) {
  13978                             if (index < soc->counter_egr_first) {
  13979                                 buf32 = (uint32 *)&soc->counter_buf64[
  13980                                                         port_base_dma +
  13981                                                         soc->counter_ing_first];
  13982                                 ptr = &buf32[index - soc->counter_ing_first];
  13983                             } else {
  13984                                 buf32 = (uint32 *)&soc->counter_buf64[
  13985                                                         port_base_dma +
  13986                                                         soc->counter_egr_first];
  13987                                 ptr = &buf32[index - soc->counter_egr_first];
  13988                             }
  13989                         } else {
  13990                             if (index < soc->counter_egr_first) {
  13991                                 buf32 = (uint32 *)&soc->counter_buf64[
  13992                                                         port_base_dma +
  13993                                                         soc->counter_ing_first];
  13994                                 ptr = &buf32[index - soc->counter_ing_first];
  13995                             } else if (index < soc->counter_mac_first) {
  13996                                 buf32 = (uint32 *)&soc->counter_buf64[
  13997                                                         port_base_dma +
  13998                                                         soc->counter_egr_first];
  13999                                 ptr = &buf32[index - soc->counter_egr_first];
  14000                             } else {
  14001                                 buf32 = (uint32 *)&soc->counter_buf64[
  14002                                                         port_base_dma +
  14003                                                         soc->counter_mac_first];
  14004                                 ptr = &buf32[index - soc->counter_mac_first];
  14005                             }
  14006                         }
  14007                         COUNTER_ATOMIC_BEGIN(s);
  14008                         if (soc_reg_field_length(
  14009                                    unit, ctr_reg, COUNTf) == 32) {
  14010                             COMPILER_64_TO_32_LO(ptr[0], ctr_new);
  14011                         } else {
  14012                             ptr[0] = COMPILER_64_LO(ctr_new) &
  14013                                         ((1 << soc_reg_field_length
  14014                                                 (unit, ctr_reg, COUNTf)) - 1);
  14015                         }
  14016                         COUNTER_ATOMIC_END(s);
  14017 
  14018                 } else
  14019 #endif /* BCM_SBUSDMA_SUPPORT */
  14020                 {
  14021 #ifdef BCM_TOMAHAWK3_SUPPORT
  14022                     if (SOC_IS_TOMAHAWK3(unit) &&
  14023                         soc_feature(unit, soc_feature_sbusdma) &&
  14024                         SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) {
  14025                         int dma_offset = SOC_CTR_TBL_INFO(unit)->tables[index - soc->counter_mib_tbl_first].dma_offset;
  14026                         ptr = (uint32 *)&soc->counter_buf64[port_base_dma + soc->counter_mib_tbl_first + dma_offset];
  14027                     } else
  14028 #endif
  14029                     {
  14030                         ptr = (uint32 *)&soc->counter_buf64[port_base_dma + index];
  14031                     }
  14032                 COUNTER_ATOMIC_BEGIN(s);
  14033                 /* Update the DMA location */
  14034                 if (soc->counter_flags & SOC_COUNTER_F_SWAP64) {
  14035                     COMPILER_64_TO_32_HI(ptr[0], ctr_new);
  14036                     COMPILER_64_TO_32_LO(ptr[1], ctr_new);
  14037                 } else {
  14038                     COMPILER_64_TO_32_LO(ptr[0], ctr_new);
  14039                     COMPILER_64_TO_32_HI(ptr[1], ctr_new);
  14040                 }
  14041                 COUNTER_ATOMIC_END(s);
  14042                 }
  14043             }/* hw_ctr_reg != INVALIDr */
  14044 
  14045             if (soc_feature(unit, soc_feature_counter_parity)
  14046 #ifdef BCM_HURRICANE2_SUPPORT
  14047                 || soc_reg_field_valid(unit, ctr_reg, PARITYf)
  14048 #endif
  14049                )
  14050             {
  14051                 uint32 temp;
  14052                 uint32 temp_len;
  14053                 if (soc_reg_field_valid(unit, ctr_reg, EVEN_PARITYf) ||
  14054                     soc_reg_field_valid(unit, ctr_reg, PARITYf)) {
  14055                     temp_len = soc_reg_field_length(unit, ctr_reg, COUNTf);
  14056                     if (temp_len < 32) {
  14057                         temp = COMPILER_64_LO(ctr_new) & ((1 << temp_len) - 1);
  14058                         COMPILER_64_SET(ctr_new, 0, temp);
  14059                     } else {
  14060                         temp = COMPILER_64_HI(ctr_new) &
  14061                                ((1 << (temp_len - 32)) - 1);
  14062                         COMPILER_64_SET(ctr_new, temp, COMPILER_64_LO(ctr_new));
  14063                     }
  14064                 }
  14065             }
  14066 
  14067             if ( (recheck_cntrs == TRUE) &&
  14068                  COMPILER_64_NE(ctr_new, ctr_prev) ) {
  14069                 /* Seeds of doubt, double-check */
  14070                 uint64 ctr_new2;
  14071                 int suspicious = 0;
  14072                 SOC_IF_ERROR_RETURN
  14073                   (soc_reg_get(unit, ctr_reg, port, 0,
  14074                                 &ctr_new2));
  14075 
  14076                 /* Check for partial ordering, with wrap */
  14077                 if (COMPILER_64_LT(ctr_new, ctr_prev)) {
  14078                     if (COMPILER_64_LT(ctr_new2, ctr_new) ||
  14079                         COMPILER_64_GE(ctr_new2, ctr_prev)) {
  14080                         /* prev < new2 < new, bad data */
  14081                         /* Try again next time */
  14082                         ctr_new = ctr_prev;
  14083                         suspicious = 1;
  14084                     }
  14085                 } else {
  14086                     if (COMPILER_64_LT(ctr_new2, ctr_new) &&
  14087                         COMPILER_64_GE(ctr_new2, ctr_prev)) {
  14088                         /* prev < new2 < new, bad data */
  14089                         /* Try again next time */
  14090                         ctr_new = ctr_prev;
  14091                         suspicious = 1;
  14092                     }
  14093                 }
  14094                 /* Otherwise believe ctr_new */
  14095 
  14096                 if (suspicious) {
  14097 #if !defined(SOC_NO_NAMES)
  14098                     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  14099                              (BSL_META_U(unit,
  14100                                          "soc_counter_collect64: "
  14101                                          "unit %d, port%d: suspicious %s "
  14102                                          "counter read (%s)\n"),
  14103                               unit, port,
  14104                               dma?"DMA":"manual",
  14105                               SOC_REG_NAME(unit, ctr_reg)));
  14106 #else
  14107                     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  14108                              (BSL_META_U(unit,
  14109                                          "soc_counter_collect64: "
  14110                                          "unit %d, port%d: suspicious %s "
  14111                                          "counter read (Counter%d)\n"),
  14112                               unit, port,
  14113                               dma?"DMA":"manual",
  14114                               ctr_reg));
  14115 #endif /* SOC_NO_NAMES */
  14116                 } /* Suspicious counter change */
  14117             } /* recheck_cntrs == TRUE */
  14118 
  14119             if (COMPILER_64_EQ(ctr_new, ctr_prev)) {
  14120                 COUNTER_ATOMIC_BEGIN(s);
  14121                 COMPILER_64_ZERO(soc->counter_delta[port_base + index]);
  14122                 COUNTER_ATOMIC_END(s);
  14123                 continue;
  14124             }
  14125 
  14126             if (discard) {
  14127                 if (dma) {
  14128                     uint32 *ptr;
  14129 #ifdef BCM_SBUSDMA_SUPPORT
  14130                     if (soc_feature(unit, soc_feature_sbusdma) &&
  14131                         (ctr_reg < NUM_SOC_REG) &&
  14132                         !SOC_REG_IS_64(unit, ctr_reg)) {
  14133                         uint32 *buf32;
  14134                         if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) {
  14135                             if (index < soc->counter_egr_first) {
  14136                                 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma +
  14137                                                                       soc->counter_ing_first];
  14138                                 ptr = &buf32[index - soc->counter_ing_first];
  14139                             } else {
  14140                                 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma +
  14141                                                                       soc->counter_egr_first];
  14142                                 ptr = &buf32[index - soc->counter_egr_first];
  14143                             }
  14144                         } else {
  14145                             if (index < soc->counter_egr_first) {
  14146                                 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma +
  14147                                                                       soc->counter_ing_first];
  14148                                 ptr = &buf32[index - soc->counter_ing_first];
  14149                             } else if (index < soc->counter_mac_first) {
  14150                                 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma +
  14151                                                                       soc->counter_egr_first];
  14152                                 ptr = &buf32[index - soc->counter_egr_first];
  14153                             } else {
  14154                                 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma +
  14155                                                                       soc->counter_mac_first];
  14156                                 ptr = &buf32[index - soc->counter_mac_first];
  14157                             }
  14158                         }
  14159                     } else
  14160 #endif
  14161                     {
  14162                         ptr = (uint32 *)&soc->counter_buf64[port_base_dma + index];
  14163                     }
  14164                     COUNTER_ATOMIC_BEGIN(s);
  14165                     /* Update the DMA location */
  14166                     if (soc->counter_flags & SOC_COUNTER_F_SWAP64) {
  14167                         COMPILER_64_TO_32_HI(ptr[0], ctr_new);
  14168                         COMPILER_64_TO_32_LO(ptr[1], ctr_new);
  14169                     } else {
  14170                         COMPILER_64_TO_32_LO(ptr[0], ctr_new);
  14171                         COMPILER_64_TO_32_HI(ptr[1], ctr_new);
  14172                     }
  14173                 } else {
  14174                     COUNTER_ATOMIC_BEGIN(s);
  14175                 }
  14176                 /* Update the previous value buffer */
  14177                 soc->counter_hw_val[port_base + index] = ctr_new;
  14178                 COMPILER_64_ZERO(soc->counter_delta[port_base + index]);
  14179                 COUNTER_ATOMIC_END(s);
  14180                 continue;
  14181             }
  14182 
  14183             LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  14184                      (BSL_META_U(unit,
  14185                                  "soc_counter_collect64: ctr %d => 0x%08x_%08x\n"),
  14186                       port_base + index,
  14187                       COMPILER_64_HI(ctr_new), COMPILER_64_LO(ctr_new)));
  14188 
  14189             vptr = &soc->counter_sw_val[port_base + index];
  14190 
  14191             ctr_diff = ctr_new;
  14192 
  14193             if (COMPILER_64_LT(ctr_diff, ctr_prev)) {
  14194                 int             width, i = 0;
  14195                 uint64          wrap_amt;
  14196 
  14197                 /*
  14198                  * Counter must have wrapped around.
  14199                  * Add the proper wrap-around amount.
  14200                  */
  14201 #ifdef SOC_COUNTER_TABLE_SUPPORT
  14202                 if(SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) {
  14203                     soc_ctr_tbl_entry_t *ctr_tbl_info_entry = NULL;
  14204 
  14205                     SOC_IF_ERROR_RETURN
  14206                         (_soc_counter_tbl_get_info(unit, port, ctr_reg, &ctr_tbl_info_entry));
  14207                     width = soc_format_field_length(unit,
  14208                                 ctr_tbl_info_entry->format,
  14209                                 ctr_tbl_info_entry->ctr_field);
  14210                 } else
  14211 #endif
  14212                 {
  14213                     width = SOC_REG_INFO(unit, ctr_reg).fields[0].len;
  14214                     if (soc_feature(unit, soc_feature_counter_parity)
  14215 #ifdef BCM_HURRICANE2_SUPPORT
  14216                     || soc_reg_field_valid(unit, ctr_reg, PARITYf)
  14217 #endif
  14218                    )
  14219                 {
  14220                     while((SOC_REG_INFO(unit, ctr_reg).fields + i) != NULL) {
  14221                         if (SOC_REG_INFO(unit, ctr_reg).fields[i].field ==
  14222                             COUNTf) {
  14223                             width = SOC_REG_INFO(unit, ctr_reg).fields[i].len;
  14224                             break;
  14225                         }
  14226                         i++;
  14227                     }
  14228                 }
  14229                 }
  14230                 if (width < 32) {
  14231                     COMPILER_64_SET(wrap_amt, 0, 1UL << width);
  14232                     COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  14233                 } else if (width < 64) {
  14234                     COMPILER_64_SET(wrap_amt, 1UL << (width - 32), 0);
  14235                     COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  14236                 }
  14237             }
  14238 
  14239             COMPILER_64_SUB_64(ctr_diff, ctr_prev);
  14240 
  14241             COUNTER_ATOMIC_BEGIN(s);
  14242             COMPILER_64_ADD_64(*vptr, ctr_diff);
  14243             soc->counter_delta[port_base + index] = ctr_diff;
  14244             soc->counter_hw_val[port_base + index] = ctr_new;
  14245             COUNTER_ATOMIC_END(s);
  14246 
  14247 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  14248             if (soc_feature(unit, soc_feature_ctr_xaui_activity)) {
  14249 #ifdef BCM_TRIDENT_SUPPORT
  14250                 if (SOC_IS_TD_TT(unit)) {
  14251                     if (ctr_reg == RPKTr) {
  14252                         COMPILER_64_TO_32_LO(rx_byt_to_led, ctr_diff);
  14253                     } else if (ctr_reg == TPKTr) {
  14254                         COMPILER_64_TO_32_LO(tx_byt_to_led, ctr_diff);
  14255                     }
  14256                 } else
  14257 #ifdef BCM_SABER2_SUPPORT
  14258  if (SOC_IS_SABER2(unit)) {
  14259                     if (IS_MXQ_PORT(unit, port)) {
  14260                     if (ctr_reg == MXQ_RPKTr) {
  14261                         COMPILER_64_TO_32_LO(rx_byt_to_led, ctr_diff);
  14262                     } else if (ctr_reg == MXQ_TPKTr) {
  14263                         COMPILER_64_TO_32_LO(tx_byt_to_led, ctr_diff);
  14264                     }
  14265                    } else {
  14266                          if (ctr_reg == RPKTr) {
  14267                         COMPILER_64_TO_32_LO(rx_byt_to_led, ctr_diff);
  14268                     } else if (ctr_reg == TPKTr) {
  14269                         COMPILER_64_TO_32_LO(tx_byt_to_led, ctr_diff);
  14270                     }
  14271                   }
  14272 
  14273                 } else
  14274 #endif
  14275 #endif
  14276                 {
  14277 #ifdef BCM_BRADLEY_SUPPORT
  14278                     if (ctr_reg == IRBYTr) {
  14279                         COMPILER_64_TO_32_LO(rx_byt_to_led, ctr_diff);
  14280                     } else if (ctr_reg == ITBYTr) {
  14281                         COMPILER_64_TO_32_LO(tx_byt_to_led, ctr_diff);
  14282                     }
  14283 #endif
  14284                 }
  14285             }
  14286 #endif
  14287         }
  14288 
  14289 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  14290         if (soc_feature(unit, soc_feature_ctr_xaui_activity)) {
  14291             _soc_xgs3_update_link_activity(unit, port, tx_byt_to_led,
  14292                                            rx_byt_to_led);
  14293             tx_byt_to_led = 0;
  14294             rx_byt_to_led = 0;
  14295         }
  14296 #endif
  14297 
  14298 #if defined(INCLUDE_PHY_8806X)
  14299         phy_mt2_update_led_speed_activity(unit, port);
  14300 #endif
  14301 
  14302         /* If signaled to exit then return  */
  14303         if (!soc->counter_interval) {
  14304             return SOC_E_NONE;
  14305         }
  14306 
  14307         /*
  14308          * Allow other tasks to run between processing each port.
  14309          */
  14310 
  14311         if (hw_ctr_reg == INVALIDr) {
  14312             COUNTER_UNLOCK(unit);
  14313             sal_thread_yield();
  14314             COUNTER_LOCK(unit);
  14315         }
  14316 
  14317         if (!soc->counter_interval) {
  14318             return SOC_E_NONE;
  14319         }
  14320     }
  14321 
  14322     return SOC_E_NONE;
  14323 }
  14324 #endif /*defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT)*/
  14325 
  14326 #ifdef BCM_KATANA_SUPPORT 
  14327 STATIC int
  14328 _soc_counter_katana_a0_non_dma_entries(int unit, int dma_id, int port_idx, 
  14329                                        int idx, soc_reg_t ctr_reg) 
  14330 
  14331 {
  14332     soc_control_t *soc;
  14333     soc_counter_non_dma_t *non_dma, *non_dma1;
  14334     int base_index, id, width, i, index;
  14335     int rv, entry_words;
  14336     uint32 fval[2];
  14337     uint64 ctr_new;
  14338     int buffer_seg, seg_addr;
  14339     soc_mem_t buffer_mem, dma_mem;
  14340     uint32 rval = 0;
  14341     COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit);
  14342     int field_count;
  14343     soc_field_t field;
  14344     int dma_base_index;
  14345     int num_non_dma_entries = 0;
  14346     LOG_DEBUG(BSL_LS_SOC_COUNTER,
  14347                 (BSL_META_U(unit,
  14348                             "_soc_counter_katana_a0_non_dma_entries: unit=%d id=%d\n"),
  14349                  unit, dma_id));
  14350 
  14351     soc = SOC_CONTROL(unit);
  14352 
  14353     if (soc->counter_non_dma == NULL) {
  14354         return SOC_E_RESOURCE;
  14355     }
  14356 
  14357     non_dma = &soc->counter_non_dma[dma_id];
  14358 
  14359     if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) {
  14360         non_dma1 = &soc->counter_non_dma[dma_id + 1];
  14361     } else {
  14362         return SOC_E_NONE;
  14363     }
  14364 
  14365     entry_words = soc_mem_entry_words(unit, non_dma->mem);
  14366     if (non_dma->field != INVALIDf) {
  14367         width = soc_mem_field_length(unit, non_dma->mem,
  14368                                      non_dma->field);
  14369     } else {
  14370         width = 32;
  14371     }
  14372 
  14373     buffer_seg = (soc_feature(unit, soc_feature_cosq_gport_stat_ability)) ?
  14374                  (11 * 1024) : (8 * 1024);
  14375     buffer_mem = (soc_feature(unit, soc_feature_cosq_gport_stat_ability)) ?
  14376                  CTR_FLEX_COUNT_11m : CTR_FLEX_COUNT_8m;
  14377 
  14378     for (id = 0; id < 2; id++) {
  14379         index = non_dma->mem - CTR_FLEX_COUNT_0m;
  14380         seg_addr = (id == 0) ? buffer_seg : (index * 1024);
  14381         soc_reg_field_set(unit, CTR_SEGMENT_STARTr, &rval, SEG_STARTf,
  14382                           seg_addr);
  14383         SOC_IF_ERROR_RETURN
  14384             (soc_reg32_set(unit,CTR_SEGMENT_STARTr, REG_PORT_ANY,index, rval));
  14385         LOG_DEBUG(BSL_LS_SOC_COUNTER,
  14386                     (BSL_META_U(unit,
  14387                                 "id=%d index=%d seg_addr=%d \n"),
  14388                      id, index, seg_addr));
  14389         if (ctr_reg == INVALIDr) {
  14390            for (i = 0; i < 4; i++) {
  14391                if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) {
  14392                   if (non_dma->dma_buf[i] == NULL) {
  14393                       continue;
  14394                   }
  14395 
  14396                   dma_mem = (id == 0) ? non_dma->dma_mem[i] : (buffer_mem + i);
  14397                   rv = soc_mem_read_range(unit, dma_mem,
  14398                                          MEM_BLOCK_ANY,
  14399                                          non_dma->dma_index_min[i],
  14400                                          non_dma->dma_index_max[i],
  14401                                          non_dma->dma_buf[i]);
  14402                   if (SOC_FAILURE(rv)) {
  14403                      return rv;
  14404                   }
  14405                }
  14406            }
  14407            dma_mem = non_dma->mem;
  14408            base_index = non_dma->base_index;
  14409            num_non_dma_entries = non_dma->num_entries;
  14410         }
  14411         else {
  14412            /* Collect counter values for a specific port */
  14413            dma_mem = non_dma->dma_mem[0];
  14414            dma_base_index = port_idx - non_dma->base_index +
  14415                             non_dma->dma_index_min[0];
  14416         
  14417            for (i = 1; i < 4; i++) {
  14418                 if (non_dma->dma_buf[i] == NULL) {
  14419                     continue;
  14420                 }
  14421                 if (dma_base_index > non_dma->dma_index_max[i - 1]) {
  14422                     dma_mem = non_dma->dma_mem[i];
  14423                     dma_base_index -= non_dma->dma_index_max[i - 1] + 1;
  14424                     dma_base_index += non_dma->dma_index_min[i];
  14425 
  14426                 }
  14427            }
  14428        
  14429            rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY,
  14430                              dma_base_index + idx,
  14431                              non_dma->dma_buf[0]);
  14432         
  14433         
  14434            if (SOC_FAILURE(rv)) {
  14435                return rv;
  14436            }
  14437         
  14438            base_index = port_idx + idx;
  14439            num_non_dma_entries = 1;
  14440 
  14441         }
  14442         for (field_count = 0; field_count < 2; field_count++) {    
  14443             base_index = (field_count == 0) ? base_index : 
  14444                                               non_dma1->base_index;
  14445             field  = (field_count == 0) ? non_dma->field :
  14446                                           non_dma1->field;
  14447             for (i = 0; i < num_non_dma_entries; i++) {
  14448                 soc_mem_field_get(unit, dma_mem,
  14449                                   &non_dma->dma_buf[0][entry_words * i],
  14450                                   field, fval);
  14451                 if (width <= 32) {
  14452                     COMPILER_64_SET(ctr_new, 0, fval[0]);
  14453                 } else {
  14454                     COMPILER_64_SET(ctr_new, fval[1], fval[0]);
  14455                 }
  14456 
  14457                 COUNTER_ATOMIC_BEGIN(s);
  14458                 COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i],
  14459                                    ctr_new);
  14460                 soc->counter_hw_val[base_index + i] = ctr_new;
  14461                 soc->counter_delta[base_index + i] = ctr_new;
  14462                 COUNTER_ATOMIC_END(s);
  14463             }
  14464         }
  14465     }
  14466     return SOC_E_NONE;
  14467 }
  14468 #endif /* BCM_KATANA_SUPPORT */
  14469 
  14470 STATIC int
  14471 soc_counter_non_dma_ready(int unit, soc_counter_non_dma_t *non_dma, int *ctr_dma_ct)
  14472 {
  14473     soc_control_t *soc;
  14474     int max_profile, curr_profile_pick, given_profiles;
  14475 
  14476     soc = SOC_CONTROL(unit);
  14477 
  14478     if (soc->counter_sync_req) {
  14479         /* Return True for all Counters when sync is in Progress */
  14480         return 1;
  14481     }
  14482 
  14483     if ((!(non_dma->flags & _SOC_COUNTER_NON_DMA_CTR_EVICT)) ||
  14484         (soc->ctr_evict_interval == 0)) {
  14485         /* Traditional DMA. Hence return true.
  14486          */
  14487         return 1;
  14488     }
  14489 
  14490     if (non_dma->dma_rate_profile & _SOC_COUNTER_DMA_RATE_PROFILE_ALL) {
  14491         /* Enabled for All profiles */
  14492         return 1;
  14493     }
  14494 
  14495 
  14496     /* get max profile value */
  14497     max_profile = _SOC_COUNTER_DMA_RATE_PROFILE_MAX;
  14498 
  14499     *ctr_dma_ct = *ctr_dma_ct % max_profile;
  14500     curr_profile_pick = 1 << *ctr_dma_ct;
  14501 
  14502     given_profiles =
  14503         (non_dma->dma_rate_profile & _SOC_COUNTER_DMA_RATE_PROFILE_MASK) >>
  14504                     _SOC_COUNTER_DMA_RATE_PROFILE_OFFSET;
  14505 
  14506     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  14507              (BSL_META_U(unit,
  14508                          "dma_prof 0x%x, pick_prof 0x%x, ctr_dma_ct %d\n"),
  14509               given_profiles, curr_profile_pick, *ctr_dma_ct));
  14510     if (given_profiles & curr_profile_pick) {
  14511         return 1;
  14512     }
  14513 
  14514     return 0;
  14515 }
  14516 
  14517 /*
  14518  * Function:
  14519  *      soc_counter_collect_non_dma_entries
  14520  * Purpose:
  14521  *      This routine collects and accumulates all the non-dmaable counters.
  14522  *      Gets invoked from the counter thread and _soc_counter_get.
  14523  *      Based on arg the ctr_reg
  14524  * Parameters:
  14525  *      unit - StrataSwitch unit #.
  14526  *      tmp_port - StrataSwitch port #.
  14527  *      port_idx - port index
  14528  *      ar_idx -  index
  14529  *      ctr_reg - if INVALIDr, collects and accumulates counter values for all
  14530  *                else collects and accumulates for a specified port.
  14531  * Returns:
  14532  *      NONE
  14533  * Notes:
  14534  */
  14535 
  14536 STATIC void
  14537 soc_counter_collect_non_dma_entries(int unit,
  14538                                     int tmp_port,
  14539                                     int port_idx,
  14540                                     int ar_idx,
  14541                                     soc_reg_t ctr_reg)
  14542 {
  14543     soc_control_t *soc;
  14544     soc_counter_non_dma_t *non_dma;
  14545     int base_index, width, i;
  14546     int id = 0;
  14547     int idx = 0;
  14548     int port;
  14549     uint32 fval[2];
  14550     uint64 ctr_new, ctr_prev, ctr_diff, wrap_amt;
  14551     int rv, count, entry_words;
  14552     COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit);
  14553     int dma_base_index;
  14554     int num_non_dma_entries = 0;
  14555     soc_mem_t dma_mem;
  14556     int non_dma_counter_end = SOC_COUNTER_NON_DMA_END -
  14557                                SOC_COUNTER_NON_DMA_START;
  14558 
  14559     int index_max = 0;
  14560     int j, subset_ct; /* For Parent-Child Model */
  14561 
  14562     int qindex;
  14563     int port_index, num_entries;
  14564     char *cname;
  14565     soc_reg_t ctr_tmp_reg;     
  14566 
  14567     soc = SOC_CONTROL(unit);
  14568 
  14569     if (soc->counter_non_dma == NULL) {
  14570         return;
  14571     }
  14572 
  14573     /*
  14574      * if ctr_reg != -1, retrieve stats for a
  14575      * specific port and queue from the hardware
  14576      * update the sw copy of the same.
  14577      */
  14578     if (ctr_reg >= NUM_SOC_REG) {
  14579         id = ctr_reg - SOC_COUNTER_NON_DMA_START;
  14580         non_dma_counter_end = id + 1;
  14581         idx = (ar_idx < 0)? 0: ar_idx;
  14582     }
  14583 
  14584     for (; id < non_dma_counter_end; id++) {
  14585         non_dma = &soc->counter_non_dma[id];
  14586 
  14587         if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
  14588             continue;
  14589         }
  14590 
  14591         /* If signaled to exit then return  */
  14592         if (!soc->counter_interval) {
  14593             return;
  14594         }
  14595 
  14596         width = entry_words = 0;
  14597 
  14598         if (non_dma->mem != INVALIDm) {
  14599 
  14600 #ifdef BCM_KATANA_SUPPORT 
  14601             if ((SOC_IS_KATANA(unit) || SOC_IS_KATANA2(unit)) &&
  14602                 (soc_feature(unit, soc_feature_counter_toggled_read))) { 
  14603 
  14604                 rv = _soc_counter_katana_a0_non_dma_entries(unit, id, port_idx, 
  14605                                                             idx, ctr_reg);   
  14606 
  14607                 if (SOC_FAILURE(rv)) {
  14608                     return;
  14609                 } else {
  14610                     continue;
  14611                 }
  14612             }
  14613 #endif
  14614 
  14615 
  14616             entry_words = soc_mem_entry_words(unit, non_dma->mem);
  14617             if (non_dma->field != INVALIDf) {
  14618                 width = soc_mem_field_length(unit, non_dma->mem,
  14619                                              non_dma->field);
  14620             } else {
  14621                 width = 32;
  14622             }
  14623 
  14624             if (ctr_reg == INVALIDr) {
  14625 #ifdef BCM_KATANA2_SUPPORT
  14626                 for (i = 0; i < (SOC_IS_SABER2(unit) ? 2 : 4); i++)
  14627 #else
  14628                 for (i = 0; i < NUM_PIPE(unit); i++)
  14629 #endif
  14630                 {
  14631                     /* Do only if the Pipe mem is VALID. */
  14632                     if (non_dma->dma_mem[i] == INVALIDm) {
  14633                         continue;
  14634                     }
  14635                     if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) {
  14636 
  14637                         if (non_dma->dma_buf[i] == NULL) {
  14638                             continue;
  14639                         }
  14640 
  14641                         rv = soc_mem_read_range(unit, non_dma->dma_mem[i],
  14642                                                 MEM_BLOCK_ANY,
  14643                                                 non_dma->dma_index_min[i],
  14644                                                 non_dma->dma_index_max[i],
  14645                                                 non_dma->dma_buf[i]);
  14646 
  14647                         if (SOC_FAILURE(rv)) {
  14648                             return;
  14649                         }
  14650                     }
  14651                 }
  14652                 dma_mem = non_dma->mem;
  14653                 base_index = non_dma->base_index;
  14654                 index_max = non_dma->num_entries;
  14655 
  14656                 num_non_dma_entries = index_max;
  14657 
  14658             } else {
  14659 
  14660                 /* Collect counter values for a specific port */
  14661                 dma_mem = non_dma->dma_mem[0];
  14662                 dma_base_index = port_idx - non_dma->base_index +
  14663                                  non_dma->dma_index_min[0];
  14664 
  14665                 for (i = 1; i < NUM_PIPE(unit); i++) {
  14666                      if (non_dma->dma_buf[i] == NULL) {
  14667                          continue;
  14668                      }
  14669 
  14670                      if (dma_base_index > non_dma->dma_index_max[i - 1]) {
  14671                          dma_mem = non_dma->dma_mem[i];
  14672                          dma_base_index -= non_dma->dma_index_max[i - 1] + 1;
  14673                          dma_base_index += non_dma->dma_index_min[i];
  14674                      }
  14675                 }
  14676             
  14677                 /* Need to retrieve the table index 
  14678                  * for flexible mapping Non-DMA counter*/
  14679                 if (non_dma->flags & _SOC_COUNTER_NON_DMA_FLEX_MAPPING) {
  14680                     if (non_dma->soc_counter_hw_idx_get == NULL) {
  14681                         continue;
  14682                     }                    
  14683                     rv = non_dma->soc_counter_hw_idx_get(unit, tmp_port, 
  14684                                                          dma_base_index + idx, 
  14685                                                          &qindex);
  14686                     if (SOC_FAILURE(rv)) {
  14687                         return;
  14688                     }
  14689                     if (-1 == qindex) {
  14690                         continue;
  14691                     }
  14692                 } else {
  14693                     qindex = dma_base_index + idx;
  14694                 }
  14695 
  14696                 rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY,
  14697                                   qindex, non_dma->dma_buf[0]);
  14698 
  14699 
  14700                 if (SOC_FAILURE(rv)) {
  14701                     return;
  14702                 }
  14703 
  14704                 base_index = port_idx + idx;
  14705                 num_non_dma_entries = 1;
  14706 
  14707             }
  14708 
  14709             /* For flexible mapping Non-DMA counter, need to assign the counter 
  14710              * value to SW structure based the table index retrieved 
  14711              * when the routine is to collect all the values  
  14712              * for all Non-DMA counters*/
  14713             if ((non_dma->flags & _SOC_COUNTER_NON_DMA_FLEX_MAPPING)
  14714                     && (ctr_reg == INVALIDr)) {
  14715                 ctr_tmp_reg = SOC_COUNTER_NON_DMA_START + id;
  14716                 PBMP_ITER(soc->counter_pbmp, port) {
  14717                     rv = _soc_counter_get_info(unit, port, ctr_tmp_reg,
  14718                                                &port_index, &num_entries,
  14719                                                &cname);
  14720                     if (SOC_FAILURE(rv)) {
  14721                         return;
  14722                     }
  14723                     dma_base_index = port_index - non_dma->base_index +
  14724                                      non_dma->dma_index_min[0];
  14725                     for (i = 0; i < num_entries; i++) {
  14726                         if (non_dma->soc_counter_hw_idx_get == NULL) {
  14727                             continue;
  14728                         }                         
  14729                         rv = non_dma->soc_counter_hw_idx_get(unit, port, 
  14730                              dma_base_index + i, &qindex);
  14731                         if (SOC_FAILURE(rv)) {
  14732                             return;
  14733                         }
  14734                         if (-1 == qindex) {
  14735                             continue;
  14736                         }   
  14737                         
  14738                         soc_mem_field_get(unit, dma_mem,
  14739                             &non_dma->dma_buf[0][entry_words * qindex],
  14740                             non_dma->field, fval);
  14741                         if (width <= 32) {
  14742                             COMPILER_64_SET(ctr_new, 0, fval[0]);
  14743                         } else {
  14744                             COMPILER_64_SET(ctr_new, fval[1], fval[0]);
  14745                         }
  14746                         if (non_dma->flags & _SOC_COUNTER_NON_DMA_EXTRA_COUNT) {
  14747                             COMPILER_64_SUB_32(ctr_new, 1);
  14748                         } 
  14749                     
  14750                         COUNTER_ATOMIC_BEGIN(s);
  14751                         ctr_prev = soc->counter_hw_val[port_index + i];
  14752                         COUNTER_ATOMIC_END(s);
  14753                     
  14754                         if (!(non_dma->flags 
  14755                             & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) {
  14756                             if (COMPILER_64_EQ(ctr_new, ctr_prev)) {
  14757                                 COUNTER_ATOMIC_BEGIN(s);
  14758                                 COMPILER_64_ZERO
  14759                                     (soc->counter_delta[port_index + i]);
  14760                                 COUNTER_ATOMIC_END(s);
  14761                                 continue;
  14762                             }
  14763                         }
  14764                     
  14765                         ctr_diff = ctr_new;
  14766                     
  14767                         if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) {
  14768                             COUNTER_ATOMIC_BEGIN(s);
  14769                             if (COMPILER_64_GT(ctr_new, 
  14770                                     soc->counter_sw_val[port_index + i])) {
  14771                                 soc->counter_sw_val[port_index + i] = ctr_new;
  14772                             }
  14773                             soc->counter_hw_val[port_index + i] = ctr_new;
  14774                             COMPILER_64_ZERO
  14775                                 (soc->counter_delta[port_index + i]);
  14776                             COUNTER_ATOMIC_END(s);
  14777                             continue;
  14778                         }
  14779                     
  14780                         if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) {
  14781                             COUNTER_ATOMIC_BEGIN(s);
  14782                             soc->counter_sw_val[port_index + i] = ctr_new;
  14783                             soc->counter_hw_val[port_index + i] = ctr_new;
  14784                             COMPILER_64_ZERO(soc->counter_delta[port_index + i]);
  14785                             COUNTER_ATOMIC_END(s);
  14786                             continue;
  14787                         }
  14788                     
  14789                         if (!(non_dma->flags 
  14790                             & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) {
  14791                             if (COMPILER_64_LT(ctr_diff, ctr_prev)) {
  14792                                 if (width < 32) {
  14793                                     COMPILER_64_ADD_32(ctr_diff, 1U << width);
  14794                                 } else if (width < 64) {
  14795                                     COMPILER_64_SET(
  14796                                         wrap_amt, 1U << (width - 32), 0);
  14797                                     COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  14798                                 }
  14799                             }
  14800                     
  14801                             COMPILER_64_SUB_64(ctr_diff, ctr_prev);
  14802                         }
  14803                     
  14804                         COUNTER_ATOMIC_BEGIN(s);
  14805                         COMPILER_64_ADD_64(soc->counter_sw_val[port_index + i],
  14806                                            ctr_diff);
  14807                         soc->counter_hw_val[port_index + i] = ctr_new;
  14808                         soc->counter_delta[port_index + i] = ctr_diff;
  14809                         COUNTER_ATOMIC_END(s);
  14810                     }
  14811                 }
  14812             } else {
  14813                 for (i = 0; i < num_non_dma_entries; i++) {
  14814                     soc_mem_field_get(unit, non_dma->mem,
  14815                                       &non_dma->dma_buf[0][entry_words *
  14816                                       i],
  14817                                       non_dma->field, fval);
  14818                     if (width <= 32) {
  14819                         COMPILER_64_SET(ctr_new, 0, fval[0]);
  14820                     } else {
  14821                         COMPILER_64_SET(ctr_new, fval[1], fval[0]);
  14822                     }
  14823                     if (non_dma->flags & _SOC_COUNTER_NON_DMA_EXTRA_COUNT) {
  14824                         COMPILER_64_SUB_32(ctr_new, 1);
  14825                     }
  14826 
  14827                     COUNTER_ATOMIC_BEGIN(s);
  14828                     ctr_prev = soc->counter_hw_val[base_index + i];
  14829                     COUNTER_ATOMIC_END(s);
  14830 
  14831                     if (!(non_dma->flags 
  14832                         & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) {
  14833                         if (COMPILER_64_EQ(ctr_new, ctr_prev)) {
  14834                             COUNTER_ATOMIC_BEGIN(s);
  14835                             COMPILER_64_ZERO
  14836                                 (soc->counter_delta[base_index + i]);
  14837                             COUNTER_ATOMIC_END(s);
  14838                             continue;
  14839                         }
  14840                     }
  14841 
  14842                     ctr_diff = ctr_new;
  14843 
  14844                     if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) {
  14845                         COUNTER_ATOMIC_BEGIN(s);
  14846                         if (COMPILER_64_GT
  14847                                 (ctr_new, 
  14848                                  soc->counter_sw_val[base_index + i])) {
  14849                             soc->counter_sw_val[base_index + i] = ctr_new;
  14850                         }
  14851                         soc->counter_hw_val[base_index + i] = ctr_new;
  14852                         COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  14853                         COUNTER_ATOMIC_END(s);
  14854                         continue;
  14855                     }
  14856 
  14857                     if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) {
  14858                         COUNTER_ATOMIC_BEGIN(s);
  14859                         soc->counter_sw_val[base_index + i] = ctr_new;
  14860                         soc->counter_hw_val[base_index + i] = ctr_new;
  14861                         COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  14862                         COUNTER_ATOMIC_END(s);
  14863                         continue;
  14864                     }
  14865 
  14866                     if (!(non_dma->flags 
  14867                         & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) {
  14868                         if (COMPILER_64_LT(ctr_diff, ctr_prev)) {
  14869                             if (width < 32) {
  14870                                 COMPILER_64_ADD_32(ctr_diff, 1U << width);
  14871                             } else if (width < 64) {
  14872                                 COMPILER_64_SET
  14873                                     (wrap_amt, 1U << (width - 32), 0);
  14874                                 COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  14875                             }
  14876                         }
  14877 
  14878                         COMPILER_64_SUB_64(ctr_diff, ctr_prev);
  14879                     }
  14880 
  14881                     COUNTER_ATOMIC_BEGIN(s);
  14882                     COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i],
  14883                                        ctr_diff);
  14884                     soc->counter_hw_val[base_index + i] = ctr_new;
  14885                     soc->counter_delta[base_index + i] = ctr_diff;
  14886                     COUNTER_ATOMIC_END(s);
  14887                 }
  14888             }
  14889         } else if (non_dma->reg != INVALIDr) {
  14890             pbmp_t counter_pbmp;
  14891 
  14892             count = 0;
  14893             if (non_dma->field != INVALIDf) {
  14894                 width = soc_reg_field_length(unit, non_dma->reg,
  14895                                              non_dma->field);
  14896             } else {
  14897                 width = 32;
  14898             }
  14899 
  14900             /*
  14901              * If stats retrieval is for a specific
  14902              * port, set the pbmp for counter collection.
  14903              */
  14904             if (ctr_reg >= NUM_SOC_REG) {
  14905                 SOC_PBMP_CLEAR(counter_pbmp);
  14906                 port = tmp_port;
  14907                 SOC_PBMP_PORT_ADD(counter_pbmp, port);
  14908             } else {
  14909                 SOC_PBMP_CLEAR(counter_pbmp);
  14910                 SOC_PBMP_ASSIGN(counter_pbmp, soc->counter_pbmp);
  14911             }
  14912 
  14913             PBMP_ITER(counter_pbmp, port) {
  14914                 /*
  14915                  * stats retrieval for a specific port.
  14916                  */
  14917                 if (_soc_counter_non_dma_is_invalid(unit, non_dma->reg, port)) {
  14918                     continue;
  14919                 }
  14920                 j = 0;
  14921                 subset_ct = 0;
  14922 
  14923                 if (ctr_reg >= NUM_SOC_REG) {
  14924                     if (!SOC_PBMP_MEMBER(counter_pbmp, port)) {
  14925                         continue;
  14926                     }
  14927 
  14928                     if (SOC_IS_TR_VL(unit) || SOC_IS_SC_CQ(unit)) {
  14929                         if (non_dma->reg == TXLLFCMSGCNTr) {
  14930                             if (!IS_HG_PORT( unit, port)) {
  14931                                 continue;
  14932                             }
  14933                         }
  14934                     }
  14935 
  14936                     i = idx;
  14937                     count = i + 1;
  14938                     base_index = port_idx;
  14939                 } else {
  14940                     if (non_dma->entries_per_port == 0) {
  14941                         /*
  14942                          * OK to over-write port variable as loop
  14943                          * breaks after 1 iter.  Check below for
  14944                          * the same codition.
  14945                          */
  14946                         port = REG_PORT_ANY;
  14947                         count = non_dma->num_entries;
  14948                         base_index = non_dma->base_index;
  14949                     } else {
  14950                         if (!SOC_PBMP_MEMBER(non_dma->pbmp, port)) {
  14951                             continue;
  14952                         }
  14953 
  14954                         if (SOC_IS_TR_VL(unit) || SOC_IS_SC_CQ(unit)) {
  14955                             if (non_dma->reg == TXLLFCMSGCNTr) {
  14956                                 if (!IS_HG_PORT( unit, port)) {
  14957                                     continue;
  14958                                 }
  14959                             }
  14960                         }
  14961 
  14962                         if (non_dma->flags & _SOC_COUNTER_NON_DMA_PERQ_REG) {
  14963                             count = num_cosq[unit][port];
  14964                             base_index = non_dma->base_index;
  14965                             for (i = 0; i < port; i++) {
  14966                                 base_index += num_cosq[unit][i];
  14967                             }
  14968 #ifdef BCM_APACHE_SUPPORT
  14969                         } else if (SOC_IS_APACHE(unit) &&
  14970                                 (non_dma->flags & 
  14971                                    _SOC_COUNTER_NON_DMA_OBM)) {
  14972                             count = non_dma->entries_per_port;
  14973                             base_index = non_dma->base_index;
  14974                             subset_ct = non_dma->extra_ctr_ct;
  14975                             if (non_dma->extra_ctrs) {
  14976                                 non_dma = non_dma->extra_ctrs;
  14977                             }
  14978 #endif
  14979                         } else if (non_dma->flags & 
  14980                                    _SOC_COUNTER_NON_DMA_OBM) {
  14981                             count = non_dma->entries_per_port;
  14982                             base_index = non_dma->base_index + 
  14983                                          SOC_INFO(unit).port_group[port] * count;
  14984                         } else {
  14985                             count = non_dma->entries_per_port;
  14986                             base_index = non_dma->base_index + port * count;
  14987                         }
  14988                     }
  14989                 }
  14990 
  14991                 do {
  14992                 for (i = 0; i < count; i++) {
  14993 #ifdef BCM_APACHE_SUPPORT
  14994                         if (SOC_IS_APACHE(unit) &&
  14995                             (non_dma->flags & _SOC_COUNTER_NON_DMA_OBM)) {
  14996                                 soc_reg_t reg = non_dma->reg;
  14997                                 int pgw_inst = (i / _APACHE_PORTS_PER_XLP);
  14998                                 pgw_inst = (pgw_inst | SOC_REG_ADDR_INSTANCE_MASK);
  14999                                 base_index = non_dma->base_index;
  15000                                 rv = soc_reg_get(unit, reg, pgw_inst, 
  15001                                                 (i % _APACHE_PORTS_PER_XLP), &ctr_new);
  15002                         } else 
  15003 #endif
  15004                         {
  15005                     /* coverity[negative_returns : FALSE] */
  15006                     rv = soc_reg_get(unit, non_dma->reg, port, i, &ctr_new);
  15007                         }
  15008                     if (SOC_FAILURE(rv)) {
  15009                         return;
  15010                     }
  15011                     COUNTER_ATOMIC_BEGIN(s);
  15012                     ctr_prev = soc->counter_hw_val[base_index + i];
  15013                     COUNTER_ATOMIC_END(s);
  15014 
  15015                     if (COMPILER_64_EQ(ctr_new, ctr_prev)) {
  15016                         COUNTER_ATOMIC_BEGIN(s);
  15017                         COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  15018                         COUNTER_ATOMIC_END(s);
  15019                         continue;
  15020                     }
  15021 
  15022                     ctr_diff = ctr_new;
  15023 
  15024                     if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) {
  15025                         COUNTER_ATOMIC_BEGIN(s);
  15026                         if (COMPILER_64_GT(ctr_new, ctr_prev)) {
  15027                             soc->counter_sw_val[base_index + i] = ctr_new;
  15028                         }
  15029                         soc->counter_hw_val[base_index + i] = ctr_new;
  15030                         COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  15031                        COUNTER_ATOMIC_END(s);
  15032                         continue;
  15033                     }
  15034 
  15035                     if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) {
  15036                         COUNTER_ATOMIC_BEGIN(s);
  15037                         soc->counter_sw_val[base_index + i] = ctr_new;
  15038                         soc->counter_hw_val[base_index + i] = ctr_new;
  15039                         COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  15040                         COUNTER_ATOMIC_END(s);
  15041                         continue;
  15042                     }
  15043 
  15044                     if (COMPILER_64_LT(ctr_diff, ctr_prev)) {
  15045                         if (width < 32) {
  15046                             COMPILER_64_ADD_32(ctr_diff, 1U << width);
  15047                         } else if (width < 64) {
  15048                             COMPILER_64_SET(wrap_amt, 1U << (width - 32), 0);
  15049                             COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  15050                         }
  15051                     }
  15052 
  15053                     COMPILER_64_SUB_64(ctr_diff, ctr_prev);
  15054 
  15055                     COUNTER_ATOMIC_BEGIN(s);
  15056                     COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i],
  15057                                        ctr_diff);
  15058                     soc->counter_hw_val[base_index + i] = ctr_new;
  15059                     soc->counter_delta[base_index + i] = ctr_diff;
  15060                     COUNTER_ATOMIC_END(s);
  15061                 }
  15062                     j++;
  15063                     if ((subset_ct > 1) && (j < subset_ct)) {
  15064                         non_dma += 2;
  15065                     }
  15066                 } while ((j < subset_ct) && non_dma);
  15067                 if ((non_dma->entries_per_port == 0) ||
  15068                     (subset_ct != 0)) {
  15069                     break;
  15070                 }
  15071             }
  15072         } else {
  15073             continue;
  15074         }
  15075     }
  15076 }
  15077 
  15078 #ifdef BCM_TOMAHAWK_SUPPORT
  15079 STATIC void
  15080 soc_counter_collect_th_non_dma_entries(int unit,
  15081                                     int tmp_port,
  15082                                     int port_idx,
  15083                                     int ar_idx,
  15084                                     soc_reg_t ctr_reg)
  15085 {
  15086     soc_control_t *soc;
  15087     soc_counter_non_dma_t *non_dma;
  15088     COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit);
  15089     soc_mem_t dma_mem;
  15090     int base_index, width, i, j, id = 0, idx = 0, obm_flag = 0, port;
  15091     uint32 fval[2], efp_ctr_rval;
  15092     uint64 ctr_new, ctr_prev, ctr_diff, wrap_amt;
  15093     int rv, count, entry_words;
  15094     int dma_base_index, num_non_dma_entries = 0;
  15095     int non_dma_counter_end = SOC_COUNTER_NON_DMA_END -
  15096                               SOC_COUNTER_NON_DMA_START;
  15097     static int ctr_dma_ct = 0;
  15098     int index_max = 0, max_pipe, pipe, default_entries_per_pipe = 0;
  15099     uint32 subset_ct = 0; /* For Parent-Child Model */
  15100     int qindex, port_index, num_entries;
  15101     char *cname;
  15102     soc_reg_t ctr_tmp_reg;     
  15103     uint8 error_return = 0;
  15104 
  15105     soc = SOC_CONTROL(unit);
  15106 
  15107     if (soc->counter_non_dma == NULL) {
  15108         return;
  15109     }
  15110 
  15111     max_pipe = SOC_CONTROL(unit)->max_num_pipe; /* store locally */
  15112 
  15113     if (soc_feature(unit, soc_feature_th_a0_sw_war) &&
  15114         soc->ctr_evict_interval) {
  15115         soc_reg_t reg = EGR_EFP_CNTR_UPDATE_CONTROLr;
  15116         efp_ctr_rval = 0;
  15117         rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &efp_ctr_rval);
  15118         if (SOC_FAILURE(rv)) {
  15119             return;
  15120         }
  15121         soc_reg_field_set(unit, reg, &efp_ctr_rval, CLR_ON_READf, 1);
  15122         rv = soc_reg32_set(unit, reg, REG_PORT_ANY, 0, efp_ctr_rval);
  15123         if (SOC_FAILURE(rv)) {
  15124             return;
  15125         }
  15126     }
  15127 
  15128     /*
  15129      * if ctr_reg != -1, retrieve stats for a
  15130      * specific port and queue from the hardware
  15131      * update the sw copy of the same.
  15132      */
  15133     if (ctr_reg >= NUM_SOC_REG) {
  15134         id = ctr_reg - SOC_COUNTER_NON_DMA_START;
  15135         non_dma_counter_end = id + 1;
  15136         idx = (ar_idx < 0)? 0: ar_idx;
  15137     }
  15138 
  15139     for (; id < non_dma_counter_end; id++) {
  15140         default_entries_per_pipe = 0;
  15141         non_dma = &soc->counter_non_dma[id];
  15142 
  15143         if(non_dma == NULL) {
  15144             continue;
  15145         }
  15146 
  15147         if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
  15148             continue;
  15149         }
  15150 
  15151         /* If signaled to exit then return  */
  15152         if (!soc->counter_interval) {
  15153             error_return = 1;
  15154             goto done;
  15155         }
  15156 
  15157         width = entry_words = 0;
  15158 
  15159         if (non_dma->mem != INVALIDm) {
  15160             count = 0;
  15161             /* If there is subset of counters, use subset info for DMA */
  15162             if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
  15163                 (non_dma->extra_ctrs != NULL)) {
  15164 #ifdef BCM_TOMAHAWK3_SUPPORT
  15165                 if(SOC_IS_TOMAHAWK3(unit) && (non_dma->extra_ctr_fld_ct != 0)) {
  15166                     subset_ct = non_dma->extra_ctr_ct;
  15167                 } else
  15168 #endif
  15169                 {
  15170                 /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */
  15171                 subset_ct = non_dma->extra_ctr_ct << 1;
  15172                 }
  15173                 non_dma = non_dma->extra_ctrs;
  15174             } else {
  15175                 subset_ct = 1;
  15176             }
  15177 
  15178             do {
  15179                 /* If signaled to exit then return  */
  15180                 if (!soc->counter_interval) {
  15181                     error_return = 1;
  15182                     goto done;
  15183                 }
  15184                 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
  15185                     count++;
  15186                     non_dma++;
  15187                     continue;
  15188                 }
  15189 
  15190                 /* Check if this Counter is up for DMA.
  15191                  * During Slow-DMA, not all counters are up for DMA at the same
  15192                  * time/frequency.
  15193                  */
  15194                 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_CTR_EVICT) &&
  15195                     (!soc_counter_non_dma_ready(unit, non_dma, &ctr_dma_ct))) {
  15196                     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  15197                              (BSL_META_U(unit,
  15198                                          "id %d(%d): NOT pickd for DMA(pipes %d). Ct %d,mem %d/%d/%d\n"),
  15199                               id, SOC_COUNTER_NON_DMA_START, count,
  15200                               max_pipe, non_dma->mem,
  15201                               non_dma->dma_mem[0], non_dma->dma_mem[1]));
  15202                     count++;
  15203                     non_dma++;
  15204                     continue;
  15205                 }
  15206 #ifdef BCM_TOMAHAWK3_SUPPORT
  15207                 if (SOC_IS_TOMAHAWK3(unit)) {
  15208                     if ((non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) &&
  15209                         count == 0) {
  15210                         COUNTER_UNLOCK(unit);
  15211                         sal_thread_yield();
  15212                         COUNTER_LOCK(unit);
  15213                     }
  15214                 } else
  15215 #endif
  15216                 {
  15217                     if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) {
  15218                         COUNTER_UNLOCK(unit);
  15219                         sal_thread_yield();
  15220                         COUNTER_LOCK(unit);
  15221                     }
  15222                 }
  15223                 LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  15224                          (BSL_META_U(unit,
  15225                                      "id %d(%d): picked for DMA(Pipes %d). mem %d/%d/%d\n"),
  15226                           id, SOC_COUNTER_NON_DMA_START, max_pipe,
  15227                           non_dma->mem, non_dma->dma_mem[0],
  15228                           non_dma->dma_mem[1]));
  15229 
  15230                 entry_words = soc_mem_entry_words(unit, non_dma->mem);
  15231                 if (non_dma->field != INVALIDf) {
  15232                     width = soc_mem_field_length(unit, non_dma->mem,
  15233                                                  non_dma->field);
  15234                 } else {
  15235                     width = 32;
  15236                 }
  15237 
  15238                     if (non_dma->dma_mem[0] != INVALIDm) {
  15239                     default_entries_per_pipe =
  15240                         soc_mem_index_count(unit, non_dma->dma_mem[0]);
  15241                     }
  15242 
  15243 
  15244                 if (ctr_reg == INVALIDr) {
  15245                     for (i = 0; i < max_pipe; i++) {
  15246                         /* Do only if the Pipe mem is VALID. */
  15247                         if (non_dma->dma_mem[i] == INVALIDm) {
  15248                             continue;
  15249                         }
  15250                         /* Skip if no enabled ports in pipe */
  15251                         if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, i))) {
  15252                             continue;
  15253                         }
  15254                         if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) {
  15255 
  15256                             if (non_dma->dma_buf[i] == NULL) {
  15257                                 continue;
  15258                             }
  15259 
  15260                             rv = soc_mem_read_range(unit, non_dma->dma_mem[i],
  15261                                                     MEM_BLOCK_ANY,
  15262                                                     non_dma->dma_index_min[i],
  15263                                                     non_dma->dma_index_max[i],
  15264                                                     non_dma->dma_buf[i]);
  15265 
  15266                             if (SOC_FAILURE(rv)) {
  15267                                 error_return = 1;
  15268                                 goto done;
  15269                             }
  15270                         }
  15271                     }
  15272                     dma_mem = non_dma->mem;
  15273                     base_index = non_dma->base_index;
  15274                     index_max = non_dma->num_entries;
  15275                     num_non_dma_entries = index_max;
  15276                     
  15277                     /* Set range over which field values from h/w are to be
  15278                      * extracted for color drop counters*/
  15279                     if (non_dma->mem == MMU_CTR_COLOR_DROP_MEMm) {
  15280                         if(SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) {
  15281                             default_entries_per_pipe = 66;
  15282                         } else if (SOC_IS_TOMAHAWK2(unit)) {
  15283                             default_entries_per_pipe = 34;
  15284                         } else if (SOC_IS_HELIX5(unit)) {
  15285                             default_entries_per_pipe = 68;
  15286                         } else {
  15287                             default_entries_per_pipe = 68;
  15288                         }
  15289                         num_non_dma_entries = default_entries_per_pipe;
  15290                     }
  15291 
  15292                 } else {
  15293 
  15294                     /* Collect counter values for a specific port */
  15295                     dma_mem = non_dma->dma_mem[0];
  15296                     dma_base_index = port_idx - non_dma->base_index +
  15297                                      non_dma->dma_index_min[0];
  15298 
  15299                     for (i = 1; i < NUM_PIPE(unit); i++) {
  15300                          if (non_dma->dma_buf[i] == NULL) {
  15301                              continue;
  15302                          }
  15303 
  15304                          if (dma_base_index > non_dma->dma_index_max[i - 1]) {
  15305                              dma_mem = non_dma->dma_mem[i];
  15306                              dma_base_index -= non_dma->dma_index_max[i - 1] + 1;
  15307                              dma_base_index += non_dma->dma_index_min[i];
  15308                          }
  15309                     }
  15310                 
  15311                     /* Need to retrieve the table index 
  15312                      * for flexible mapping Non-DMA counter*/
  15313                     if (non_dma->flags & _SOC_COUNTER_NON_DMA_FLEX_MAPPING) {
  15314                         if (non_dma->soc_counter_hw_idx_get == NULL) {
  15315                             continue;
  15316                         }                    
  15317                         rv = non_dma->soc_counter_hw_idx_get(unit, tmp_port, 
  15318                                                              dma_base_index + idx, 
  15319                                                              &qindex);
  15320                         if (SOC_FAILURE(rv)) {
  15321                             error_return = 1;
  15322                             goto done;
  15323                         }
  15324                         if (-1 == qindex) {
  15325                             continue;
  15326                         }
  15327                     } else {
  15328                         qindex = dma_base_index + idx;
  15329                     }
  15330 
  15331                     rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY,
  15332                                       qindex, non_dma->dma_buf[0]);
  15333 
  15334 
  15335                     if (SOC_FAILURE(rv)) {
  15336                         error_return = 1;
  15337                         goto done;
  15338                     }
  15339 
  15340                     /* coverity[UNUSED_VALUE: FALSE] */
  15341                     base_index = port_idx + idx;
  15342                     num_non_dma_entries = 1;
  15343                 }
  15344 
  15345                 /* For flexible mapping Non-DMA counter, need to assign the counter 
  15346                  * value to SW structure based the table index retrieved 
  15347                  * when the routine is to collect all the values  
  15348                  * for all Non-DMA counters*/
  15349                 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_FLEX_MAPPING)
  15350                         && (ctr_reg == INVALIDr)) {
  15351                     ctr_tmp_reg = SOC_COUNTER_NON_DMA_START + id;
  15352                     PBMP_ITER(soc->counter_pbmp, port) {
  15353                         rv = _soc_counter_get_info(unit, port, ctr_tmp_reg,
  15354                                                    &port_index, &num_entries,
  15355                                                    &cname);
  15356                         if (SOC_FAILURE(rv)) {
  15357                             error_return = 1;
  15358                             goto done;
  15359                         }
  15360                         dma_base_index = port_index - non_dma->base_index +
  15361                                          non_dma->dma_index_min[0];
  15362                         for (i = 0; i < num_entries; i++) {
  15363                             if (non_dma->soc_counter_hw_idx_get == NULL) {
  15364                                 continue;
  15365                             }                         
  15366                             rv = non_dma->soc_counter_hw_idx_get(unit, port, 
  15367                                  dma_base_index + i, &qindex);
  15368                             if (SOC_FAILURE(rv)) {
  15369                                 error_return = 1;
  15370                                 goto done;
  15371                             }
  15372                             if (-1 == qindex) {
  15373                                 continue;
  15374                             }   
  15375                             
  15376                             soc_mem_field_get(unit, dma_mem,
  15377                                 &non_dma->dma_buf[0][entry_words * qindex],
  15378                                 non_dma->field, fval);
  15379                             if (width <= 32) {
  15380                                 COMPILER_64_SET(ctr_new, 0, fval[0]);
  15381                             } else {
  15382                                 COMPILER_64_SET(ctr_new, fval[1], fval[0]);
  15383                             }
  15384                             if (non_dma->flags & _SOC_COUNTER_NON_DMA_EXTRA_COUNT) {
  15385                                 COMPILER_64_SUB_32(ctr_new, 1);
  15386                             } 
  15387                         
  15388                             COUNTER_ATOMIC_BEGIN(s);
  15389                             ctr_prev = soc->counter_hw_val[port_index + i];
  15390                             COUNTER_ATOMIC_END(s);
  15391                         
  15392                             if (!(non_dma->flags 
  15393                                 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) {
  15394                                 if (COMPILER_64_EQ(ctr_new, ctr_prev)) {
  15395                                     COUNTER_ATOMIC_BEGIN(s);
  15396                                     COMPILER_64_ZERO
  15397                                         (soc->counter_delta[port_index + i]);
  15398                                     COUNTER_ATOMIC_END(s);
  15399                                     continue;
  15400                                 }
  15401                             }
  15402                         
  15403                             ctr_diff = ctr_new;
  15404                         
  15405                             if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) {
  15406                                 COUNTER_ATOMIC_BEGIN(s);
  15407                                 if (COMPILER_64_GT(ctr_new, 
  15408                                         soc->counter_sw_val[port_index + i])) {
  15409                                     soc->counter_sw_val[port_index + i] = ctr_new;
  15410                                 }
  15411                                 soc->counter_hw_val[port_index + i] = ctr_new;
  15412                                 COMPILER_64_ZERO
  15413                                     (soc->counter_delta[port_index + i]);
  15414                                 COUNTER_ATOMIC_END(s);
  15415                                 continue;
  15416                             }
  15417                         
  15418                             if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) {
  15419                                 COUNTER_ATOMIC_BEGIN(s);
  15420                                 soc->counter_sw_val[port_index + i] = ctr_new;
  15421                                 soc->counter_hw_val[port_index + i] = ctr_new;
  15422                                 COMPILER_64_ZERO(soc->counter_delta[port_index + i]);
  15423                                 COUNTER_ATOMIC_END(s);
  15424                                 continue;
  15425                             }
  15426                         
  15427                             if (!(non_dma->flags 
  15428                                 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) {
  15429                                 if (COMPILER_64_LT(ctr_diff, ctr_prev)) {
  15430                                     if (width < 32) {
  15431                                         COMPILER_64_ADD_32(ctr_diff, 1U << width);
  15432                                     } else if (width < 64) {
  15433                                         COMPILER_64_SET(
  15434                                             wrap_amt, 1U << (width - 32), 0);
  15435                                         COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  15436                                     }
  15437                                 }
  15438                         
  15439                                 COMPILER_64_SUB_64(ctr_diff, ctr_prev);
  15440                             }
  15441                         
  15442                             COUNTER_ATOMIC_BEGIN(s);
  15443                             COMPILER_64_ADD_64(soc->counter_sw_val[port_index + i],
  15444                                                ctr_diff);
  15445                             soc->counter_hw_val[port_index + i] = ctr_new;
  15446                             soc->counter_delta[port_index + i] = ctr_diff;
  15447                             COUNTER_ATOMIC_END(s);
  15448                         }
  15449                     }
  15450                 } else {
  15451                     int invalid_pipe_ct = 0;
  15452                     int entries_per_pipe[SOC_MAX_NUM_PIPES];
  15453                     for (pipe = 0; pipe < max_pipe; pipe++) {
  15454                         if (!num_non_dma_entries) {
  15455                             break;
  15456                         }
  15457                         if (!non_dma->dma_buf[pipe]) {
  15458                             /* Skip the pipe indices if dma_buf for given pipe
  15459                              * is NULL.
  15460                              */
  15461                             invalid_pipe_ct++;
  15462                             continue;
  15463                         }
  15464 
  15465                         entries_per_pipe[pipe] = default_entries_per_pipe;
  15466                         base_index = non_dma->base_index +
  15467                                     (pipe - invalid_pipe_ct) * default_entries_per_pipe;
  15468 
  15469 #ifdef BCM_TOMAHAWK3_SUPPORT
  15470                         if (SOC_IS_TOMAHAWK3(unit)) {
  15471                             int pipe2 = 0;
  15472                             if (SOC_CONTROL(unit)->em_halfchip == 1 &&
  15473                                 non_dma->dma_mem[pipe] == INVALIDm) {
  15474                                 continue;
  15475                             }
  15476                             entries_per_pipe[pipe] = non_dma->dma_num_entries[pipe];
  15477                             base_index = non_dma->base_index;
  15478                             for(pipe2 = 1; pipe2 <= pipe; pipe2++) {
  15479                                 base_index += non_dma->dma_num_entries[pipe2 - 1];
  15480                             }
  15481                         }
  15482 #endif
  15483                         /* Skip if no enabled ports in pipe */
  15484                         if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, pipe))) {
  15485                             continue;
  15486                         }
  15487 
  15488                         for (i = 0 ; i < entries_per_pipe[pipe]; i++) {
  15489                             soc_mem_field_get(unit, non_dma->mem,
  15490                                       &non_dma->dma_buf[pipe][entry_words * i],
  15491                                       non_dma->field, fval);
  15492                             if (width <= 32) {
  15493                                 COMPILER_64_SET(ctr_new, 0, fval[0]);
  15494                             } else {
  15495                                 COMPILER_64_SET(ctr_new, fval[1], fval[0]);
  15496                             }
  15497                             if (non_dma->flags & _SOC_COUNTER_NON_DMA_EXTRA_COUNT) {
  15498                                 COMPILER_64_SUB_32(ctr_new, 1);
  15499                             }
  15500 
  15501                             COUNTER_ATOMIC_BEGIN(s);
  15502                             ctr_prev = soc->counter_hw_val[base_index + i];
  15503                             COUNTER_ATOMIC_END(s);
  15504 
  15505                             if (!(non_dma->flags 
  15506                                 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) {
  15507                                 if (COMPILER_64_EQ(ctr_new, ctr_prev)) {
  15508                                     COUNTER_ATOMIC_BEGIN(s);
  15509                                     COMPILER_64_ZERO
  15510                                         (soc->counter_delta[base_index + i]);
  15511                                     COUNTER_ATOMIC_END(s);
  15512                                     continue;
  15513                                 }
  15514                             }
  15515 
  15516                             ctr_diff = ctr_new;
  15517 
  15518                             if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) {
  15519                                 COUNTER_ATOMIC_BEGIN(s);
  15520                                 if (COMPILER_64_GT
  15521                                         (ctr_new, 
  15522                                          soc->counter_sw_val[base_index + i])) {
  15523                                     soc->counter_sw_val[base_index + i] = ctr_new;
  15524                                 }
  15525                                 soc->counter_hw_val[base_index + i] = ctr_new;
  15526                                 COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  15527                                 COUNTER_ATOMIC_END(s);
  15528                                 continue;
  15529                             }
  15530 
  15531                             if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) {
  15532                                 COUNTER_ATOMIC_BEGIN(s);
  15533                                 soc->counter_sw_val[base_index + i] = ctr_new;
  15534                                 soc->counter_hw_val[base_index + i] = ctr_new;
  15535                                 COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  15536                                 COUNTER_ATOMIC_END(s);
  15537                                 continue;
  15538                             }
  15539 
  15540                             if (!(non_dma->flags 
  15541                                 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) {
  15542                                 if (COMPILER_64_LT(ctr_diff, ctr_prev)) {
  15543                                     if (width < 32) {
  15544                                         COMPILER_64_ADD_32(ctr_diff, 1U << width);
  15545                                     } else if (width < 64) {
  15546                                         COMPILER_64_SET
  15547                                             (wrap_amt, 1U << (width - 32), 0);
  15548                                         COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  15549                                     }
  15550                                 }
  15551 
  15552                                 COMPILER_64_SUB_64(ctr_diff, ctr_prev);
  15553                             }
  15554 
  15555                             COUNTER_ATOMIC_BEGIN(s);
  15556                             COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i],
  15557                                                ctr_diff);
  15558                             soc->counter_hw_val[base_index + i] = ctr_new;
  15559                             soc->counter_delta[base_index + i] = ctr_diff;
  15560                             COUNTER_ATOMIC_END(s);
  15561                         }
  15562                     }
  15563                 }
  15564                 count++;
  15565                 non_dma++;
  15566             } while ((count < subset_ct) && non_dma);
  15567         } else if (non_dma->reg != INVALIDr) {
  15568             int mmu_xpe_ctr = 0;
  15569             int mmu_itm_ctr = 0;
  15570             pbmp_t counter_pbmp;
  15571             soc_counter_non_dma_t *non_dma_tmp = non_dma;
  15572 
  15573             count = 0;
  15574             if (non_dma->field != INVALIDf) {
  15575                 width = soc_reg_field_length(unit, non_dma->reg,
  15576                                              non_dma->field);
  15577             } else {
  15578                 width = 32;
  15579             }
  15580 
  15581             /*
  15582              * If stats retrieval is for a specific
  15583              * port, set the pbmp for counter collection.
  15584              */
  15585             if (ctr_reg >= NUM_SOC_REG) {
  15586                 SOC_PBMP_CLEAR(counter_pbmp);
  15587                 port = tmp_port;
  15588                 SOC_PBMP_PORT_ADD(counter_pbmp, port);
  15589             } else {
  15590                 SOC_PBMP_CLEAR(counter_pbmp);
  15591                 SOC_PBMP_ASSIGN(counter_pbmp, soc->counter_pbmp);
  15592             }
  15593 
  15594             obm_flag = 0;
  15595             PBMP_ITER(counter_pbmp, port) {
  15596                 subset_ct = 1;
  15597                 /*
  15598                  * stats retrieval for a specific port.
  15599                  */
  15600 
  15601                 j = 0;
  15602                 if (ctr_reg >= NUM_SOC_REG) {
  15603                     if (!SOC_PBMP_MEMBER(counter_pbmp, port)) {
  15604                         continue;
  15605                     }
  15606 
  15607                     i = idx;
  15608                     count = i + 1;
  15609                     base_index = port_idx;
  15610                 } else {
  15611                     if (non_dma->entries_per_port == 0) {
  15612                         /*
  15613                          * OK to over-write port variable as loop
  15614                          * breaks after 1 iter.  Check below for
  15615                          * the same codition.
  15616                          */
  15617                         port = REG_PORT_ANY;
  15618                         count = non_dma->num_entries;
  15619                         base_index = non_dma->base_index;
  15620                         if ((non_dma->id == SOC_COUNTER_NON_DMA_DROP_RQ_PKT) ||
  15621                             (non_dma->id == SOC_COUNTER_NON_DMA_DROP_RQ_BYTE) ||
  15622                             (non_dma->id == SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW) ||
  15623                             (non_dma->id == SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED) ||
  15624                             (non_dma->id == SOC_COUNTER_NON_DMA_POOL_PEAK) ||
  15625                             (non_dma->id == SOC_COUNTER_NON_DMA_POOL_CURRENT)) {
  15626                             mmu_xpe_ctr = 1;
  15627                         } else if ((non_dma->id == SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT) ||
  15628                                    (non_dma->id == SOC_COUNTER_NON_DMA_PRIQ_DROP_BYTE) ||
  15629                                    (non_dma->id == SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT_YELLOW) ||
  15630                                    (non_dma->id == SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT_RED) ||
  15631                                    (non_dma->id == SOC_COUNTER_NON_DMA_HDRM_POOL_DROP_PKT)) {
  15632                             mmu_itm_ctr = 1;
  15633                         }
  15634                     } else {
  15635                         if (!SOC_PBMP_MEMBER(non_dma->pbmp, port)) {
  15636                             continue;
  15637                         }
  15638 
  15639                         if (non_dma->flags & _SOC_COUNTER_NON_DMA_PERQ_REG) {
  15640                             count = num_cosq[unit][port];
  15641                             base_index = non_dma->base_index;
  15642                             for (i = 0; i < port; i++) {
  15643                                 base_index += num_cosq[unit][i];
  15644                             }
  15645                         } else if (non_dma->flags &
  15646                                    _SOC_COUNTER_NON_DMA_OBM) {
  15647                             if (obm_flag == 0) {
  15648                                 count = non_dma->entries_per_port * max_pipe;
  15649                                 base_index = non_dma->base_index;
  15650                                 obm_flag = 1; /* covers all ports for the
  15651                                                * current obm */
  15652                                 subset_ct = non_dma->extra_ctr_ct;
  15653                                 if (non_dma->extra_ctrs) {
  15654                                     non_dma_tmp = non_dma->extra_ctrs;
  15655                                 }
  15656                             } else {
  15657                                 break;
  15658                             }
  15659                         } else {
  15660                             count = non_dma->entries_per_port;
  15661                             base_index = non_dma->base_index + port * count;
  15662                         }
  15663                     }
  15664                 }
  15665 
  15666                 do {
  15667                     for (i = 0; i < count; i++) {
  15668                         if (non_dma_tmp->flags & _SOC_COUNTER_NON_DMA_OBM) {
  15669                             soc_reg_t reg = non_dma_tmp->reg;
  15670 #ifdef BCM_TOMAHAWK3_SUPPORT
  15671                             int phy_port, obm_port, is_active;
  15672 #endif
  15673                             /* coverity[divide_by_zero : FALSE] */
  15674                             pipe = i / non_dma->entries_per_port;
  15675                             /* Skip if no enabled ports in pipe */
  15676                             if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, pipe))) {
  15677                                 continue;
  15678                             }
  15679                             reg = SOC_REG_UNIQUE_ACC(unit, non_dma_tmp->reg)[pipe];
  15680                             base_index = non_dma_tmp->base_index;
  15681 #ifdef BCM_TOMAHAWK3_SUPPORT
  15682                             if (SOC_IS_TOMAHAWK3(unit)) {
  15683                                 obm_port = i % non_dma->entries_per_port;
  15684                                 phy_port =
  15685                                     soc_counter_tomahawk3_obm_drop_to_phy_port(unit, pipe, reg, obm_port);
  15686                                 if (phy_port < 0 ||
  15687                                         SOC_INFO(unit).port_p2l_mapping[phy_port] == -1) {
  15688                                     continue;
  15689                                 }
  15690 
  15691                                 rv = soc_th3_portctrl_pm_is_active(unit, phy_port, &is_active);
  15692                                 if (SOC_FAILURE(rv)) {
  15693                                     error_return = 1;
  15694                                     goto done;
  15695                                 }
  15696 
  15697                                 /* Skip counters for this PM if it's not initialized */
  15698                                 if (!is_active) {
  15699                                     continue;
  15700                                 }
  15701 
  15702                                 rv = soc_reg_get(unit, reg, pipe, obm_port, &ctr_new);
  15703                             } else
  15704 #endif
  15705                             {
  15706                                 rv = soc_reg_get(unit, reg, pipe,
  15707                                              i % non_dma->entries_per_port, &ctr_new);
  15708                             }
  15709                         } else {
  15710                             /* coverity[negative_returns : FALSE] */
  15711                             if (mmu_xpe_ctr == 1) {
  15712                                 rv = soc_reg_get(unit, non_dma_tmp->reg,
  15713                                                  (i / (count / NUM_XPE(unit))),
  15714                                                  (i % (count / NUM_XPE(unit))), &ctr_new);
  15715                             } else if (mmu_itm_ctr == 1) {
  15716                                 /* Skip if inactive ITM */
  15717                                 if(((1 << (i / (count / NUM_ITM(unit)))) &
  15718                                    soc->info.itm_map) == 0) {
  15719                                     continue;
  15720                                 }
  15721 
  15722                                 rv = soc_reg_get(unit, non_dma_tmp->reg,
  15723                                                  (i / (count / NUM_ITM(unit))),
  15724                                                  (i % (count / NUM_ITM(unit))), &ctr_new);
  15725                             } else {
  15726                                 rv = soc_reg_get(unit, non_dma_tmp->reg, port, i, &ctr_new);
  15727                             }
  15728                         }
  15729                         if (SOC_FAILURE(rv)) {
  15730                             error_return = 1;
  15731                             goto done;
  15732                         }
  15733                         COUNTER_ATOMIC_BEGIN(s);
  15734                         ctr_prev = soc->counter_hw_val[base_index + i];
  15735                         COUNTER_ATOMIC_END(s);
  15736 
  15737                         if (COMPILER_64_EQ(ctr_new, ctr_prev)) {
  15738                             COUNTER_ATOMIC_BEGIN(s);
  15739                             COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  15740                             COUNTER_ATOMIC_END(s);
  15741                             continue;
  15742                         }
  15743 
  15744                         ctr_diff = ctr_new;
  15745 
  15746                         if (non_dma_tmp->flags & _SOC_COUNTER_NON_DMA_PEAK) {
  15747                             COUNTER_ATOMIC_BEGIN(s);
  15748                             if (COMPILER_64_GT(ctr_new,
  15749                                                soc->counter_sw_val[base_index + i])) {
  15750                                 soc->counter_sw_val[base_index + i] = ctr_new;
  15751                             }
  15752                             soc->counter_hw_val[base_index + i] = ctr_new;
  15753                             COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  15754                             COUNTER_ATOMIC_END(s);
  15755                             continue;
  15756                         }
  15757 
  15758                         if (non_dma_tmp->flags & _SOC_COUNTER_NON_DMA_CURRENT) {
  15759                             COUNTER_ATOMIC_BEGIN(s);
  15760                             soc->counter_sw_val[base_index + i] = ctr_new;
  15761                             soc->counter_hw_val[base_index + i] = ctr_new;
  15762                             COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  15763                             COUNTER_ATOMIC_END(s);
  15764                             continue;
  15765                         }
  15766 
  15767                         if (COMPILER_64_LT(ctr_diff, ctr_prev)) {
  15768                             if (width < 32) {
  15769                                 COMPILER_64_ADD_32(ctr_diff, 1U << width);
  15770                             } else if (width < 64) {
  15771                                 COMPILER_64_SET(wrap_amt, 1U << (width - 32), 0);
  15772                                 COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  15773                             }
  15774                         }
  15775 
  15776                         COMPILER_64_SUB_64(ctr_diff, ctr_prev);
  15777 
  15778                         COUNTER_ATOMIC_BEGIN(s);
  15779                         COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i],
  15780                                            ctr_diff);
  15781                         soc->counter_hw_val[base_index + i] = ctr_new;
  15782                         soc->counter_delta[base_index + i] = ctr_diff;
  15783                         COUNTER_ATOMIC_END(s);
  15784                     }
  15785                     j++;
  15786                     if (subset_ct > 1) {
  15787                         non_dma_tmp += 2;
  15788                     }
  15789                 } while ((j < subset_ct) && non_dma_tmp);
  15790 
  15791                 if (non_dma->entries_per_port == 0) {
  15792                     break;
  15793                 }
  15794             }
  15795         COUNTER_UNLOCK(unit);
  15796         sal_thread_yield();
  15797         COUNTER_LOCK(unit);
  15798     }
  15799     }
  15800 
  15801 done:
  15802     if (soc_feature(unit, soc_feature_th_a0_sw_war) &&
  15803         soc->ctr_evict_interval) {
  15804         soc_reg_t reg = EGR_EFP_CNTR_UPDATE_CONTROLr;
  15805         efp_ctr_rval = 0;
  15806         rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &efp_ctr_rval);
  15807         if (SOC_FAILURE(rv)) {
  15808             return;
  15809         }
  15810 
  15811         soc_reg_field_set(unit, reg, &efp_ctr_rval, CLR_ON_READf, 0);
  15812         rv = soc_reg32_set(unit, reg, REG_PORT_ANY, 0, efp_ctr_rval);
  15813         if (SOC_FAILURE(rv)) {
  15814             return;
  15815         }
  15816     }
  15817 
  15818     if (error_return) {
  15819         return;
  15820     }
  15821     ctr_dma_ct++;
  15822 }
  15823 #endif /* BCM_TOMAHAWK_SUPPORT */
  15824 
  15825 #ifdef BCM_XGS3_SWITCH_SUPPORT
  15826 /*
  15827  * Function:
  15828  *      _soc_xgs3_counter_dma_setup
  15829  * Purpose:
  15830  *      Configure hardware registers for counter collection.  Used during
  15831  *      soc_counter_thread initialization.
  15832  * Parameters:
  15833  *      unit    - switch unit
  15834  * Returns:
  15835  *      SOC_E_*
  15836  */
  15837 STATIC int
  15838 _soc_xgs3_counter_dma_setup(int unit)
  15839 {
  15840     soc_control_t       *soc;
  15841     int                 csize;
  15842     pbmp_t              pbmp;
  15843     soc_reg_t           reg;
  15844     soc_ctr_type_t      ctype;
  15845     uint32              val;
  15846     uint32              ing_blk, ing_blkoff, ing_pstage, ing_c_cnt;
  15847     uint32              egr_blk, egr_blkoff, egr_pstage, egr_c_cnt;
  15848 #ifdef BCM_SHADOW_SUPPORT
  15849     uint32              inv_c_cnt = 0;
  15850 #endif
  15851     uint32              gmac_c_cnt, xmac_c_cnt;
  15852     int                 blk, bindex, blk_num, port, phy_port;
  15853     soc_reg_t           blknum_reg, portnum_reg;
  15854     int                 num_blknum, num_portnum, blknum_offset, portnum_offset;
  15855     uint32              blknum_mask, portnum_mask;
  15856     uint32              blknum_map[20];
  15857     uint32              portnum_map[24];
  15858 #ifdef BCM_CMICM_SUPPORT
  15859     int cmc = SOC_PCI_CMC(unit);
  15860 #endif
  15861     ing_blk = ing_blkoff = ing_pstage = 0;
  15862     egr_blk = egr_blkoff = egr_pstage = 0;
  15863 
  15864 #ifdef BCM_FIREBOLT_SUPPORT
  15865     if (SOC_IS_FBX(unit)) {
  15866         ing_blk = SOC_BLK_IPIPE;
  15867         egr_blk = SOC_BLK_EPIPE;
  15868         ing_blkoff = SOC_BLOCK2OFFSET(unit, IPIPE_BLOCK(unit));
  15869         egr_blkoff = SOC_BLOCK2OFFSET(unit, EPIPE_BLOCK(unit));
  15870     }
  15871 #endif
  15872 
  15873     soc = SOC_CONTROL(unit);
  15874     SOC_PBMP_ASSIGN(pbmp, soc->counter_pbmp);
  15875     /*
  15876      * Calculate the number of counters from each block
  15877      */
  15878     ing_c_cnt = egr_c_cnt = gmac_c_cnt = xmac_c_cnt = 0;
  15879 #ifdef BCM_SHADOW_SUPPORT
  15880     if (SOC_IS_SHADOW(unit)) {
  15881         inv_c_cnt = ing_c_cnt;
  15882     }
  15883 #endif
  15884     for (ctype = 0; ctype < SOC_CTR_NUM_TYPES; ctype++) {
  15885         if (!SOC_HAS_CTR_TYPE(unit, ctype)) {
  15886             continue;
  15887         }
  15888         for (csize = SOC_CTR_MAP_SIZE(unit, ctype) - 1; csize > 0; csize--) {
  15889             reg = SOC_CTR_TO_REG(unit, ctype, csize);
  15890             if (SOC_COUNTER_INVALID(unit, reg)) {
  15891                 continue;                       /* skip trailing invalids */
  15892             }
  15893             if (SOC_REG_BLOCK_IS(unit, reg, ing_blk) &&
  15894                                  (ing_c_cnt == 0)) {
  15895                 ing_c_cnt = csize + 1;
  15896                 if (soc_feature(unit, soc_feature_new_sbus_format)) {
  15897                     ing_pstage = (SOC_REG_INFO(unit, reg).offset >> 26) & 0x3F;
  15898                 } else {
  15899                     ing_pstage = (SOC_REG_INFO(unit, reg).offset >> 24) & 0xFF;
  15900                 }
  15901             }
  15902             if (SOC_REG_BLOCK_IS(unit, reg, egr_blk) &&
  15903                                  (egr_c_cnt == 0)) {
  15904                 egr_c_cnt = csize + 1;
  15905                 if (soc_feature(unit, soc_feature_new_sbus_format)) {
  15906                     egr_pstage = (SOC_REG_INFO(unit, reg).offset >> 26) & 0x3F;
  15907                 } else {
  15908                     egr_pstage = (SOC_REG_INFO(unit, reg).offset >> 24) & 0xFF;
  15909                 }
  15910             }
  15911             if ((SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GPORT) ||
  15912                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_QGPORT) ||
  15913                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_SPORT) ||
  15914                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XGPORT) ||
  15915                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XQPORT) ||
  15916                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT) ||
  15917                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT) ||
  15918                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORTB0) ||
  15919                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XTPORT) ||
  15920                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XWPORT) ||
  15921                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT) ||
  15922                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLG2PORT)) &&
  15923                 (gmac_c_cnt == 0)) {
  15924                 gmac_c_cnt = csize + 1;
  15925             }
  15926             if ((SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XPORT) ||
  15927                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XGPORT) ||
  15928                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XQPORT) ||
  15929                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT) ||
  15930                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT) ||
  15931                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORTB0) ||
  15932                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XTPORT) ||
  15933                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XWPORT) ||
  15934                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_MXQPORT) ||
  15935                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT) ||
  15936                  SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLG2PORT)) &&
  15937                 (xmac_c_cnt == 0)) {
  15938                 xmac_c_cnt = csize + 1;
  15939             }
  15940         }
  15941     }
  15942 #ifdef BCM_SHADOW_SUPPORT
  15943     if (SOC_IS_SHADOW(unit)) {
  15944         /* Remove leading invalids (Shadow) */
  15945         for (csize = 0; csize < SOC_CTR_MAP_SIZE(unit, SOC_CTR_TYPE_XE); csize++) {
  15946             reg = SOC_CTR_TO_REG(unit, SOC_CTR_TYPE_XE, csize);
  15947             if (SOC_COUNTER_INVALID(unit, reg)) {
  15948                 inv_c_cnt++;
  15949             } else {
  15950                 break;
  15951             }
  15952         }
  15953     }
  15954 #endif /* BCM_SHADOW_SUPPORT */
  15955 
  15956     egr_c_cnt = (egr_c_cnt) ? (egr_c_cnt - ing_c_cnt) : 0;
  15957     gmac_c_cnt = (gmac_c_cnt) ? (gmac_c_cnt - egr_c_cnt - ing_c_cnt) : 0;
  15958 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  15959     if (!SOC_CONTROL(unit)->sw_timestamp_fifo_enable) {
  15960         xmac_c_cnt = DIRECT_TIMESTAMP_DMA_COUNTER_NUM;
  15961     } else
  15962 #endif
  15963     {
  15964         xmac_c_cnt = (xmac_c_cnt) ? (xmac_c_cnt - egr_c_cnt - ing_c_cnt) : 0;
  15965     }
  15966 #ifdef BCM_SHADOW_SUPPORT
  15967     if (SOC_IS_SHADOW(unit)) {
  15968         ing_c_cnt -= inv_c_cnt;
  15969     }
  15970 #endif
  15971 
  15972     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  15973              (BSL_META_U(unit,
  15974                          "ing_c_cnt = %d egr_c_cnt = %d "
  15975                          "gmac_c_cnt = %d xmac_c_cnt = %d\n"
  15976                          "ing_pstage = %d egr_pstage = %d "
  15977                          "ing_blkoff = %d egr_blkoff = %d\n"),
  15978               ing_c_cnt, egr_c_cnt, gmac_c_cnt, xmac_c_cnt,
  15979               ing_pstage, egr_pstage, ing_blkoff, egr_blkoff));
  15980 
  15981     /* Prepare for CMIC_STAT_DMA_PORTNUM_MAP and BLKNUM_MAP */
  15982     if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTNUM_MAP_3_0r)) {
  15983         portnum_reg = CMIC_STAT_DMA_PORTNUM_MAP_3_0r;
  15984         num_portnum = 4;
  15985         portnum_offset = 8;
  15986 #if defined(BCM_HB_GW_SUPPORT)
  15987     } else if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTNUM_MAP_5_0r)) {
  15988         portnum_reg = CMIC_STAT_DMA_PORTNUM_MAP_5_0r;
  15989         num_portnum = 6;
  15990         portnum_offset = 5;
  15991 #endif
  15992     } else if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTNUM_MAP_7_0r)) {
  15993         portnum_reg = CMIC_STAT_DMA_PORTNUM_MAP_7_0r;
  15994         num_portnum = 8;
  15995         portnum_offset = 4;
  15996     } else {
  15997         return SOC_E_INTERNAL;
  15998     }
  15999     portnum_mask =
  16000         (1 << soc_reg_field_length(unit, portnum_reg, SBUS_PORTNUM_0f)) - 1;
  16001 
  16002     if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_BLKNUM_MAP_4_0r)) {
  16003         blknum_reg = CMIC_STAT_DMA_BLKNUM_MAP_4_0r;
  16004         num_blknum = 5;
  16005         blknum_offset = 6;
  16006     } else if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_BLKNUM_MAP_7_0r)) {
  16007         blknum_reg = CMIC_STAT_DMA_BLKNUM_MAP_7_0r;
  16008         num_blknum = 8;
  16009         blknum_offset = 4;
  16010     } else {
  16011         return SOC_E_INTERNAL;
  16012     }
  16013     blknum_mask =
  16014         (1 << soc_reg_field_length(unit, blknum_reg, SBUS_BLKNUM_0f)) - 1;
  16015 
  16016     sal_memset(portnum_map, 0, sizeof(portnum_map));
  16017     sal_memset(blknum_map, 0, sizeof(blknum_map));
  16018     PBMP_ITER(pbmp, port) {
  16019         /* Check port value to avoid out of bound array access */
  16020         if ((port / num_blknum) >= 20) {
  16021             return SOC_E_INTERNAL;
  16022         }
  16023         if ((port / num_portnum) >= 24) {
  16024             return SOC_E_INTERNAL;
  16025         }
  16026         if (soc_feature(unit, soc_feature_logical_port_num)) {
  16027             phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  16028         } else {
  16029             phy_port = port;
  16030         }
  16031         blk = SOC_PORT_BLOCK(unit, phy_port);
  16032         bindex = SOC_PORT_BINDEX(unit, phy_port);
  16033         blk_num = SOC_BLOCK2OFFSET(unit, blk);
  16034         /* coverity[overrun-local] */
  16035         blknum_map[port / num_blknum] |=
  16036             (blk_num & blknum_mask) << (blknum_offset * (port % num_blknum));
  16037         /* coverity[overrun-local] */
  16038         portnum_map[port / num_portnum] |=
  16039             (bindex & portnum_mask) << (portnum_offset * (port % num_portnum));
  16040     }
  16041 
  16042     switch (portnum_reg) {
  16043     case CMIC_STAT_DMA_PORTNUM_MAP_3_0r:
  16044         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_3_0r(unit, portnum_map[0]);
  16045         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_7_4r(unit, portnum_map[1]);
  16046         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_11_8r(unit, portnum_map[2]);
  16047         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_15_12r(unit, portnum_map[3]);
  16048         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_19_16r(unit, portnum_map[4]);
  16049         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_23_20r(unit, portnum_map[5]);
  16050         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_27_24r(unit, portnum_map[6]);
  16051         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_31_28r(unit, portnum_map[7]);
  16052         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_35_32r(unit, portnum_map[8]);
  16053         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_39_36r(unit, portnum_map[9]);
  16054         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_43_40r(unit, portnum_map[10]);
  16055         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_47_44r(unit, portnum_map[11]);
  16056         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_51_48r(unit, portnum_map[12]);
  16057         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_55_52r(unit, portnum_map[13]);
  16058         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_59_56r(unit, portnum_map[14]);
  16059         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_63_60r(unit, portnum_map[15]);
  16060         if (!SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTNUM_MAP_67_64r)) {
  16061             break;
  16062         }
  16063         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_67_64r(unit, portnum_map[16]);
  16064         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_71_68r(unit, portnum_map[17]);
  16065         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_75_72r(unit, portnum_map[18]);
  16066         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_79_76r(unit, portnum_map[19]);
  16067         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_83_80r(unit, portnum_map[20]);
  16068         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_87_84r(unit, portnum_map[21]);
  16069         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_91_88r(unit, portnum_map[22]);
  16070         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_95_92r(unit, portnum_map[23]);
  16071         break;
  16072 #if defined(BCM_HB_GW_SUPPORT)
  16073     case CMIC_STAT_DMA_PORTNUM_MAP_5_0r:
  16074         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_5_0r(unit, portnum_map[0]);
  16075         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_11_6r(unit, portnum_map[1]);
  16076         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_17_12r(unit, portnum_map[2]);
  16077         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_23_18r(unit, portnum_map[3]);
  16078         break;
  16079 #endif
  16080     case CMIC_STAT_DMA_PORTNUM_MAP_7_0r:
  16081         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_7_0r(unit, portnum_map[0]);
  16082         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_15_8r(unit, portnum_map[1]);
  16083         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_23_16r(unit, portnum_map[2]);
  16084         WRITE_CMIC_STAT_DMA_PORTNUM_MAP_31_24r(unit, portnum_map[3]);
  16085         break;
  16086     }
  16087 
  16088     switch (blknum_reg) {
  16089     case CMIC_STAT_DMA_BLKNUM_MAP_4_0r:
  16090         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_4_0r(unit, blknum_map[0]);
  16091         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_9_5r(unit, blknum_map[1]);
  16092         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_14_10r(unit, blknum_map[2]);
  16093         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_19_15r(unit, blknum_map[3]);
  16094         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_24_20r(unit, blknum_map[4]);
  16095         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_29_25r(unit, blknum_map[5]);
  16096         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_34_30r(unit, blknum_map[6]);
  16097         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_39_35r(unit, blknum_map[7]);
  16098         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_44_40r(unit, blknum_map[8]);
  16099         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_49_45r(unit, blknum_map[9]);
  16100         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_54_50r(unit, blknum_map[10]);
  16101         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_59_55r(unit, blknum_map[11]);
  16102         if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_BLKNUM_MAP_63_60r)) {
  16103             WRITE_CMIC_STAT_DMA_BLKNUM_MAP_63_60r(unit, blknum_map[12]);
  16104             break;
  16105         }
  16106         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_64_60r(unit, blknum_map[12]);
  16107         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_69_65r(unit, blknum_map[13]);
  16108         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_74_70r(unit, blknum_map[14]);
  16109         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_79_75r(unit, blknum_map[15]);
  16110         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_84_80r(unit, blknum_map[16]);
  16111         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_89_85r(unit, blknum_map[17]);
  16112         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_94_90r(unit, blknum_map[18]);
  16113         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_95r(unit, blknum_map[19]);
  16114         break;
  16115     case CMIC_STAT_DMA_BLKNUM_MAP_7_0r:
  16116         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_7_0r(unit, blknum_map[0]);
  16117         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_15_8r(unit, blknum_map[1]);
  16118         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_23_16r(unit, blknum_map[2]);
  16119         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_31_24r(unit, blknum_map[3]);
  16120         if (!SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_BLKNUM_MAP_39_32r)) {
  16121             break;
  16122         }
  16123         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_39_32r(unit, blknum_map[4]);
  16124         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_47_40r(unit, blknum_map[5]);
  16125         WRITE_CMIC_STAT_DMA_BLKNUM_MAP_55_48r(unit, blknum_map[6]);
  16126 
  16127         break;
  16128     }
  16129 
  16130     /*
  16131      * Reset value in CMIC_STAT_DMA_SETUP register is good. No
  16132      * additional setup necessary for FB/ER
  16133      */
  16134 #ifdef BCM_CMICM_SUPPORT
  16135     if(soc_feature(unit, soc_feature_cmicm)) {
  16136         soc_pci_write(unit,CMIC_CMCx_STAT_DMA_ADDR_OFFSET(cmc),soc_cm_l2p(unit, soc->counter_buf64));
  16137         soc_pci_write(unit,CMIC_CMCx_STAT_DMA_PORTS_0_OFFSET(cmc),SOC_PBMP_WORD_GET(pbmp, 0));
  16138         if (SOC_REG_IS_VALID(unit, CMIC_CMC0_STAT_DMA_PORTS_1r)) { 
  16139             soc_pci_write(unit,CMIC_CMCx_STAT_DMA_PORTS_1_OFFSET(cmc),SOC_PBMP_WORD_GET(pbmp, 1));
  16140         }
  16141         if (SOC_REG_IS_VALID(unit, CMIC_CMC0_STAT_DMA_PORTS_2r)) {  
  16142             soc_pci_write(unit,CMIC_CMCx_STAT_DMA_PORTS_2_OFFSET(cmc),SOC_PBMP_WORD_GET(pbmp, 2));
  16143         }
  16144         SOC_PBMP_ASSIGN(pbmp, PBMP_HG_ALL(unit));
  16145         SOC_PBMP_OR(pbmp, PBMP_XE_ALL(unit));
  16146         SOC_PBMP_AND(pbmp, soc->counter_pbmp);
  16147 
  16148         WRITE_CMIC_STAT_DMA_PORT_TYPE_MAP_0r(unit, SOC_PBMP_WORD_GET(pbmp, 0));
  16149         if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORT_TYPE_MAP_1r)) {
  16150             WRITE_CMIC_STAT_DMA_PORT_TYPE_MAP_1r
  16151                 (unit, SOC_PBMP_WORD_GET(pbmp, 1));
  16152         }
  16153         if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORT_TYPE_MAP_2r)) {
  16154             WRITE_CMIC_STAT_DMA_PORT_TYPE_MAP_2r
  16155                 (unit, SOC_PBMP_WORD_GET(pbmp, 2));
  16156         }
  16157     } else
  16158 #endif /* CMICM Support */
  16159     {
  16160         WRITE_CMIC_STAT_DMA_ADDRr(unit, soc_cm_l2p(unit, soc->counter_buf64));
  16161 
  16162         WRITE_CMIC_STAT_DMA_PORTSr(unit, SOC_PBMP_WORD_GET(pbmp, 0));
  16163         if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTS_HIr)) {
  16164             WRITE_CMIC_STAT_DMA_PORTS_HIr(unit, SOC_PBMP_WORD_GET(pbmp, 1));
  16165         }
  16166         if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTS_HI_2r)) {
  16167             WRITE_CMIC_STAT_DMA_PORTS_HI_2r(unit, SOC_PBMP_WORD_GET(pbmp, 2));
  16168         }
  16169 
  16170         if (SOC_IS_HB_GW(unit)) {
  16171             SOC_PBMP_ASSIGN(pbmp, PBMP_PORT_ALL(unit));
  16172         } else {
  16173             SOC_PBMP_ASSIGN(pbmp, PBMP_HG_ALL(unit));
  16174             SOC_PBMP_OR(pbmp, PBMP_XE_ALL(unit));
  16175         }
  16176         SOC_PBMP_AND(pbmp, soc->counter_pbmp);
  16177 
  16178         WRITE_CMIC_STAT_DMA_PORT_TYPE_MAPr(unit, SOC_PBMP_WORD_GET(pbmp, 0));
  16179         if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORT_TYPE_MAP_HIr)) {
  16180             WRITE_CMIC_STAT_DMA_PORT_TYPE_MAP_HIr
  16181                 (unit, SOC_PBMP_WORD_GET(pbmp, 1));
  16182         }
  16183         if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORT_TYPE_MAP_HI_2r)) {
  16184             WRITE_CMIC_STAT_DMA_PORT_TYPE_MAP_HI_2r
  16185                 (unit, SOC_PBMP_WORD_GET(pbmp, 2));
  16186         }
  16187     }
  16188     val = 0;
  16189     soc_reg_field_set(unit, CMIC_STAT_DMA_ING_STATS_CFGr,
  16190                       &val, ING_ETH_BLK_NUMf, ing_blkoff);
  16191     soc_reg_field_set(unit, CMIC_STAT_DMA_ING_STATS_CFGr,
  16192                       &val, ING_STAT_COUNTERS_NUMf, ing_c_cnt);
  16193     soc_reg_field_set(unit, CMIC_STAT_DMA_ING_STATS_CFGr,
  16194                       &val, ING_STATS_PIPELINE_STAGE_NUMf, ing_pstage);
  16195     WRITE_CMIC_STAT_DMA_ING_STATS_CFGr(unit, val);
  16196 
  16197     val = 0;
  16198     soc_reg_field_set(unit, CMIC_STAT_DMA_EGR_STATS_CFGr,
  16199                       &val, EGR_ETH_BLK_NUMf, egr_blkoff);
  16200     soc_reg_field_set(unit, CMIC_STAT_DMA_EGR_STATS_CFGr,
  16201                       &val, EGR_STAT_COUNTERS_NUMf, egr_c_cnt);
  16202     soc_reg_field_set(unit, CMIC_STAT_DMA_EGR_STATS_CFGr,
  16203                       &val, EGR_STATS_PIPELINE_STAGE_NUMf, egr_pstage);
  16204     WRITE_CMIC_STAT_DMA_EGR_STATS_CFGr(unit, val);
  16205 
  16206     val = 0;
  16207     soc_reg_field_set(unit, CMIC_STAT_DMA_MAC_STATS_CFGr,
  16208                       &val, MAC_G_STAT_COUNTERS_NUMf, gmac_c_cnt);
  16209     soc_reg_field_set(unit, CMIC_STAT_DMA_MAC_STATS_CFGr,
  16210                       &val, MAC_X_STAT_COUNTERS_NUMf, xmac_c_cnt);
  16211     soc_reg_field_set(unit, CMIC_STAT_DMA_MAC_STATS_CFGr,
  16212                       &val, CPU_STATS_PORT_NUMf, CMIC_PORT(unit));
  16213     WRITE_CMIC_STAT_DMA_MAC_STATS_CFGr(unit, val);
  16214 
  16215 #ifdef BCM_CMICM_SUPPORT
  16216     if(soc_feature(unit, soc_feature_cmicm)) {
  16217         val = soc_pci_read(unit,CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc));
  16218         soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val,
  16219                           ST_DMA_ITER_DONE_CLRf, 1);
  16220         if (soc_feature(unit, soc_feature_new_sbus_format)) {
  16221             soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val,
  16222                               EN_TR3_SBUS_STYLEf, 1);
  16223         }
  16224         soc_pci_write(unit,CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc),val);
  16225         soc_cmicm_intr0_enable(unit, IRQ_CMCx_STAT_ITER_DONE);
  16226     } else
  16227 #endif
  16228     {
  16229         WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_ITER_DONE_CLR);
  16230         soc_intr_enable(unit, IRQ_STAT_ITER_DONE);
  16231     }
  16232     return SOC_E_NONE;
  16233 }
  16234 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  16235 
  16236 #ifdef BCM_SBUSDMA_SUPPORT
  16237 void _soc_sbusdma_port_ctr_cb(int unit, int status, sbusdma_desc_handle_t handle,
  16238                               void *data)
  16239 {
  16240     int  phy_port;
  16241     COUNTER_ATOMIC_DEF  s = SOC_CONTROL(unit);
  16242 
  16243     if (soc_feature(unit, soc_feature_logical_port_num)) {
  16244         phy_port = SOC_INFO(unit).port_p2l_mapping[PTR_TO_INT(data)];
  16245     } else {
  16246         phy_port = PTR_TO_INT(data);
  16247     }
  16248 
  16249     LOG_DEBUG(BSL_LS_SOC_COUNTER,
  16250                 (BSL_META_U(unit,
  16251                             "In port counter cb [%d]\n"), handle));
  16252     if (status == SOC_E_NONE) {
  16253         LOG_DEBUG(BSL_LS_SOC_COUNTER,
  16254                     (BSL_META_U(unit,
  16255                                 "Complete: port:%d.\n"),phy_port));
  16256     } else {
  16257         uint8 i;
  16258         int blk;
  16259         LOG_ERROR(BSL_LS_SOC_COMMON,
  16260                   (BSL_META_U(unit,
  16261                               "Counter SBUSDMA failed: Handle:%d port:%d.\n"), handle,phy_port));
  16262         if (status == SOC_E_TIMEOUT) {
  16263             (void)soc_sbusdma_desc_delete(unit, handle);
  16264             for (i=0; i<=(COUNTER_SBUSDMA_DESC_SIZE-1); i++) {
  16265 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  16266                 if ((i == 3) && (!(SOC_IS_GREYHOUND2(unit) || SOC_IS_MONTEREY(unit)))) {
  16267                     break;
  16268                 }
  16269 #endif
  16270                 if (_soc_port_counter_handles[unit][PTR_TO_INT(data)][i] == handle) {
  16271                     _soc_port_counter_handles[unit][PTR_TO_INT(data)][i] = 0;
  16272                     break;
  16273                 }
  16274                 blk = SOC_PORT_BLOCK(unit, PTR_TO_INT(data));
  16275                 if ((i == 2) &&
  16276                     (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT) &&
  16277                      !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORTB0) &&
  16278                      !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XTPORT) &&
  16279                      !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XWPORT) &&
  16280                      !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_MXQPORT) &&
  16281                      !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GPORT) &&
  16282                      !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLPORT) &&
  16283                      !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLG2PORT) &&
  16284                      !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CDPORT))) {
  16285                     break;
  16286                 }
  16287             }
  16288         }
  16289     }
  16290     COUNTER_ATOMIC_BEGIN(s);
  16291     _soc_counter_pending[unit]--;
  16292     COUNTER_ATOMIC_END(s);
  16293 }
  16294 
  16295 int
  16296 _soc_counter_sbusdma_setup(int unit)
  16297 {
  16298     soc_control_t       *soc;
  16299     int                 csize;
  16300     soc_ctr_type_t      ctype;
  16301     soc_reg_t           reg, ing_reg, egr_reg, mac_reg, gmac_reg;
  16302     int                 ing_c_cnt, egr_c_cnt, mac_c_cnt, gmac_c_cnt;
  16303     int                 ing_first, egr_first, mac_first, gmac_first;
  16304     int                 ing_last, egr_last, mac_last, gmac_last;
  16305     uint32              ing_addr, egr_addr, mac_addr;
  16306     int                 ing_blkoff, egr_blkoff, mac_blkoff;
  16307     uint8               ing_acc_type, egr_acc_type, mac_acc_type;
  16308     int                 blk, port, phy_port, i;
  16309 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  16310     soc_reg_t           mac_xlpmib_reg;
  16311     int                 mac_xlpmib_c_cnt, mac_xlpmib_first, mac_xlpmib_last;
  16312 #endif /* BCM_GREYHOUND2_SUPPORT */
  16313 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_HELIX5_SUPPORT)
  16314     soc_reg_t           mac_clmib_reg;
  16315     int                 mac_clmib_c_cnt, mac_clmib_first, mac_clmib_last;
  16316 #endif /* BCM_GREYHOUND2_SUPPORT */
  16317 #ifdef BCM_KATANA2_SUPPORT
  16318     soc_port_t          my_port;
  16319 #endif
  16320     int                 port_num_blktype;
  16321     soc_pbmp_t          all_pbmp;
  16322 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  16323     int                 use_gmac, gmac_c_width;
  16324 #endif
  16325 #ifdef SOC_COUNTER_TABLE_SUPPORT
  16326     int mib_tbl_first = 10000; /* a huge number */
  16327     int mib_tbl_last = -1;
  16328     int mib_tbl_c_cnt = 0;
  16329     uint32 mib_tbl_addr = 0;
  16330     uint8 mib_tbl_acc_type = 0;
  16331 #endif
  16332 
  16333     soc = SOC_CONTROL(unit);
  16334     port_num_blktype = SOC_DRIVER(unit)->port_num_blktype > 1 ?
  16335         SOC_DRIVER(unit)->port_num_blktype : 1;
  16336 
  16337     sal_memset(_soc_port_counter_handles[unit], 0, sizeof(_soc_port_counter_handles[unit]));
  16338     ing_reg = INVALIDr;
  16339     egr_reg = INVALIDr;
  16340     mac_reg = INVALIDr;
  16341     gmac_reg = INVALIDr;
  16342     ing_first = 10000; /* a huge number */
  16343     egr_first = 10000;
  16344     mac_first = 10000;
  16345     gmac_first = 10000;
  16346     ing_last = -1;
  16347     egr_last = -1;
  16348     mac_last = -1;
  16349     gmac_last = -1;
  16350 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  16351     mac_xlpmib_reg = INVALIDr;
  16352     mac_xlpmib_first = 10000;
  16353     mac_xlpmib_last = -1;
  16354 #endif /* BCM_GREYHOUND2_SUPPORT */
  16355 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_HELIX5_SUPPORT)
  16356     mac_clmib_reg = INVALIDr;
  16357     mac_clmib_first = 10000;
  16358     mac_clmib_last = -1;
  16359 #endif /* BCM_GREYHOUND2_SUPPORT */
  16360     ing_reg = INVALIDr;
  16361     egr_reg = INVALIDr;
  16362     mac_reg = INVALIDr;
  16363     gmac_reg = INVALIDr;
  16364     for (ctype = 0; ctype < SOC_CTR_NUM_TYPES; ctype++) {
  16365         if (!SOC_HAS_CTR_TYPE(unit, ctype)) {
  16366             continue;
  16367         }
  16368         for (csize = SOC_CTR_MAP_SIZE(unit, ctype) - 1; csize >= 0; csize--) {
  16369             reg = SOC_CTR_TO_REG(unit, ctype, csize);
  16370             if (SOC_COUNTER_INVALID(unit, reg)) {
  16371                 continue;                       /* skip trailing invalids */
  16372             }
  16373 #ifdef SOC_COUNTER_TABLE_SUPPORT
  16374             if (SOC_IS_TOMAHAWK3(unit) &&
  16375                 SOC_REG_IS_COUNTER_TABLE(unit, reg)) {
  16376                 if (mib_tbl_first > csize) {
  16377                     mib_tbl_first = csize;
  16378                 }
  16379                 if (mib_tbl_last < csize) {
  16380                     mib_tbl_last = csize;
  16381                 }
  16382                 continue;
  16383             }
  16384 #endif
  16385             if (SOC_REG_BLOCK_IS(unit, reg, SOC_BLK_IPIPE)) {
  16386                 if (ing_first > csize) {
  16387                     ing_first = csize;
  16388                     ing_reg = reg;
  16389                 }
  16390                 if (ing_last < csize) {
  16391                     ing_last = csize;
  16392                 }
  16393             }
  16394             if (SOC_REG_BLOCK_IS(unit, reg, SOC_BLK_EPIPE)) {
  16395                 if (egr_first > csize) {
  16396                     egr_first = csize;
  16397                     egr_reg = reg;
  16398                 }
  16399                 if (egr_last < csize) {
  16400                     egr_last = csize;
  16401                 }
  16402             }
  16403 
  16404 #ifdef BCM_SABER2_SUPPORT
  16405             if (SOC_IS_SABER2(unit)) {
  16406                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_MXQPORT)) {
  16407                     if (mac_first > csize) {
  16408                         mac_first = csize;
  16409                         mac_reg = reg;
  16410                     }
  16411                     if (mac_last < csize) {
  16412                         mac_last = csize;
  16413                     }
  16414                     mac_reg = reg;
  16415                     continue;
  16416                 }
  16417                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) {
  16418                     if (gmac_first > csize) {
  16419                         gmac_first = csize;
  16420                         gmac_reg = reg;
  16421                     }
  16422                     if (gmac_last < csize) {
  16423                         gmac_last = csize;
  16424                     }
  16425                     continue;
  16426                 }
  16427             }
  16428 #endif /* BCM_SABER2_SUPPORT */
  16429 #ifdef BCM_HELIX5_SUPPORT
  16430             if (SOC_IS_HELIX5(unit)) {
  16431                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) {
  16432                     if (mac_first > csize) {
  16433                         mac_first = csize;
  16434                     }
  16435                     if (mac_last < csize) {
  16436                         mac_last = csize;
  16437                     }
  16438                     mac_reg = reg;
  16439                     continue;
  16440                 }
  16441                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT)) {
  16442                     if (gmac_first > csize) {
  16443                         gmac_first = csize;
  16444                     }
  16445                     if (gmac_last < csize) {
  16446                         gmac_last = csize;
  16447                     }
  16448                     gmac_reg = reg;
  16449                     continue;
  16450                 }
  16451 
  16452                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT)) {
  16453                     if (mac_clmib_first > csize) {
  16454                         mac_clmib_first = csize;
  16455                     }
  16456                     if (mac_clmib_last < csize) {
  16457                         mac_clmib_last = csize;
  16458                     }
  16459                     mac_clmib_reg = reg;
  16460                     continue;
  16461                 }
  16462             }
  16463 #endif /* BCM_HELIX5_SUPPORT */
  16464 #if defined(BCM_TOMAHAWKPLUS_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT)
  16465             if (SOC_IS_TOMAHAWKPLUS(unit) || SOC_IS_TRIDENT3X(unit) ||
  16466                 SOC_IS_TOMAHAWK2(unit)) {
  16467                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT)) {
  16468                     if (mac_first > csize) {
  16469                         mac_first = csize;
  16470                         mac_reg = reg;
  16471                     }
  16472                     if (mac_last < csize) {
  16473                         mac_last = csize;
  16474                     }
  16475                     mac_reg = reg;
  16476                     continue;
  16477                 }
  16478                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) {
  16479                     if (gmac_first > csize) {
  16480                         gmac_first = csize;
  16481                         gmac_reg = reg;
  16482                     }
  16483                     if (gmac_last < csize) {
  16484                         gmac_last = csize;
  16485                     }
  16486                     continue;
  16487                 }
  16488             }
  16489 #endif /* BCM_TRIDENT3_SUPPORT || BCM_TOMAHAWKPLUS_SUPPORT || BCM_TOMAHAWK2_SUPPORT */
  16490 
  16491 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  16492             if (SOC_IS_GREYHOUND2(unit) || SOC_IS_MONTEREY(unit)) {
  16493                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) {
  16494                     /* The first XLPMIB_XXXr offset = 0x10000 (XLPMIB_R64r) */
  16495                     if (SOC_REG_INFO(unit, reg).offset & 0x10000) {
  16496                         if (mac_xlpmib_first > csize) {
  16497                             mac_xlpmib_first = csize;
  16498                             mac_xlpmib_reg = reg;
  16499                         }
  16500                         if (mac_xlpmib_last < csize) {
  16501                             mac_xlpmib_last = csize;
  16502                         }
  16503                         mac_xlpmib_reg = reg;
  16504                     } else {
  16505                         if (mac_first > csize) {
  16506                             mac_first = csize;
  16507                             mac_reg = reg;
  16508                         }
  16509                         if (mac_last < csize) {
  16510                             mac_last = csize;
  16511                         }
  16512                         mac_reg = reg;
  16513                     }
  16514                     continue;
  16515                 }
  16516             }
  16517 
  16518 #endif /* BCM_GREYHOUND2_SUPPORT */
  16519 #if defined(BCM_GREYHOUND2_SUPPORT) 
  16520             if (SOC_IS_GREYHOUND2(unit)) {
  16521                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT)) {
  16522                     if (mac_clmib_first > csize) {
  16523                         mac_clmib_first = csize;
  16524                         mac_clmib_reg = reg;
  16525                     }
  16526                     if (mac_clmib_last < csize) {
  16527                         mac_clmib_last = csize;
  16528                     }
  16529                     mac_clmib_reg = reg;
  16530                     continue;
  16531                 }
  16532             }
  16533 #endif /* BCM_GREYHOUND2_SUPPORT */
  16534 
  16535             if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT) ||
  16536                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORTB0) ||
  16537                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XTPORT) ||
  16538                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XWPORT) ||
  16539                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT) ||
  16540                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_MXQPORT) ||
  16541                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_PGW_CL)) {
  16542                 if (mac_first > csize) {
  16543                     mac_first = csize;
  16544                     mac_reg = reg;
  16545                 }
  16546                 if (mac_last < csize) {
  16547                     mac_last = csize;
  16548                 }
  16549                 mac_reg = reg;
  16550             } else if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GPORT)||
  16551                        SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT)) {
  16552                 if (gmac_first > csize) {
  16553                     gmac_first = csize;
  16554                     gmac_reg = reg;
  16555                 }
  16556                 if (gmac_last < csize) {
  16557                     gmac_last = csize;
  16558                 }
  16559             }
  16560             /* CLG2 MIB have some new unique registers which are added
  16561              * in seperate counter map. So we use gmac for CLG2.
  16562              */
  16563             if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLG2PORT)) {
  16564                 if (gmac_first > csize) {
  16565                     gmac_first = csize;
  16566                     gmac_reg = reg;
  16567                 }
  16568                 if (gmac_last < csize) {
  16569                     gmac_last = csize;
  16570                 }
  16571             }
  16572         }
  16573     }
  16574 
  16575     ing_c_cnt = ing_last != -1 ? ing_last - ing_first + 1 : 0;
  16576     egr_c_cnt = egr_last != -1 ? egr_last - egr_first + 1 : 0;
  16577     mac_c_cnt = mac_last != -1 ? mac_last - mac_first + 1 : 0;
  16578     gmac_c_cnt = gmac_last != -1 ? gmac_last - gmac_first + 1 : 0;
  16579     soc->counter_ing_first = ing_first;
  16580     soc->counter_egr_first = egr_first;
  16581     soc->counter_mac_first = mac_last != -1 ? mac_first : gmac_first;
  16582 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  16583     mac_xlpmib_c_cnt = mac_xlpmib_first != -1 ? mac_xlpmib_last - mac_xlpmib_first + 1 : 0;
  16584 #endif
  16585 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_HELIX5_SUPPORT)
  16586     mac_clmib_c_cnt = mac_clmib_first != -1 ? mac_clmib_last - mac_clmib_first + 1 : 0;
  16587 #endif /* BCM_GREYHOUND2_SUPPORT */
  16588 
  16589     assert(SOC_REG_IS_VALID(unit, ing_reg));
  16590     assert(SOC_REG_IS_VALID(unit, egr_reg));
  16591     ing_addr = soc_reg_addr_get(unit, ing_reg, REG_PORT_ANY, 0,
  16592                                 SOC_REG_ADDR_OPTION_NONE, &ing_blkoff,
  16593                                 &ing_acc_type);
  16594     egr_addr = soc_reg_addr_get(unit, egr_reg, REG_PORT_ANY, 0,
  16595                                 SOC_REG_ADDR_OPTION_NONE, &egr_blkoff,
  16596                                 &egr_acc_type);
  16597 
  16598     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  16599              (BSL_META_U(unit,
  16600                          "ing_c_cnt = %d egr_c_cnt = %d mac_c_cnt = %d gmac_c_cnt = %d\n"
  16601                          "ing_blkoff = %d ing_acc_type = %d ing_addr = %08x \n"
  16602                          "egr_blkoff = %d egr_acc_type = %d egr_addr = %08x \n"),
  16603               ing_c_cnt, egr_c_cnt, mac_c_cnt, gmac_c_cnt,
  16604               ing_blkoff, ing_acc_type, ing_addr,
  16605               egr_blkoff, egr_acc_type, egr_addr));
  16606 #if defined(BCM_MONTEREY_SUPPORT)
  16607     if (SOC_IS_MONTEREY(unit)) {
  16608         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  16609                  (BSL_META_U(unit,
  16610                              "mac_xlpmib_c_cnt = %d "),
  16611                   mac_xlpmib_c_cnt));
  16612     }
  16613 #endif
  16614 #if defined(BCM_GREYHOUND2_SUPPORT) 
  16615     if (SOC_IS_GREYHOUND2(unit))  {
  16616         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  16617                  (BSL_META_U(unit,
  16618                              "mac_xlpmib_c_cnt = %d mac_clmib_c_cnt = %d\n"),
  16619                   mac_xlpmib_c_cnt, mac_clmib_c_cnt));
  16620     }
  16621 #endif /* BCM_GREYHOUND2_SUPPORT */
  16622 
  16623 #ifdef SOC_COUNTER_TABLE_SUPPORT
  16624     if (SOC_IS_TOMAHAWK3(unit)) {
  16625         mib_tbl_c_cnt = mib_tbl_first != -1 ? mib_tbl_last - mib_tbl_first + 1 : 0;
  16626         mib_tbl_addr = soc_mem_addr_get(unit, CDMIB_MEMm, 0, 0, 0, &mib_tbl_acc_type);
  16627         soc->counter_mib_tbl_first = mib_tbl_first;
  16628         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  16629                  (BSL_META_U(unit, "mib_tbl_c_cnt = %d\n"), mib_tbl_c_cnt));
  16630     }
  16631 #endif
  16632 
  16633         SOC_PBMP_CLEAR(all_pbmp);
  16634         SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  16635 #ifdef BCM_KATANA2_SUPPORT
  16636         if (SOC_IS_KATANA2(unit)) {
  16637             SOC_PBMP_CLEAR(all_pbmp);
  16638             for (my_port =  SOC_INFO(unit).cmic_port;
  16639                  my_port <= SOC_INFO(unit).lb_port;
  16640                  my_port++) {
  16641                  if (SOC_INFO(unit).block_valid[SOC_PORT_BLOCK(unit,my_port)]) {
  16642                      SOC_PBMP_PORT_ADD(all_pbmp,my_port);
  16643                  }
  16644             }
  16645         }
  16646 #endif
  16647 
  16648 #if defined(BCM_KATANA2_SUPPORT)
  16649         if (!(soc_feature(unit, soc_feature_discontinuous_pp_port))) {
  16650         if (soc_feature(unit, soc_feature_linkphy_coe) &&
  16651             SOC_INFO(unit).linkphy_enabled) {
  16652             SOC_PBMP_REMOVE(all_pbmp, SOC_INFO(unit).linkphy_pp_port_pbm);
  16653         }
  16654         if (soc_feature(unit, soc_feature_subtag_coe) &&
  16655             SOC_INFO(unit).subtag_enabled) {
  16656             SOC_PBMP_REMOVE(all_pbmp, SOC_INFO(unit).subtag_pp_port_pbm);
  16657         }
  16658         }
  16659 #endif
  16660         PBMP_ITER(all_pbmp, port) {
  16661 
  16662         soc_sbusdma_desc_ctrl_t ctrl = {0};
  16663         soc_sbusdma_desc_cfg_t cfg;
  16664         uint64 *buff;
  16665 
  16666         if (soc_feature(unit, soc_feature_logical_port_num)) {
  16667             phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  16668         } else {
  16669             phy_port = port;
  16670         }
  16671         buff = &soc->counter_buf64[port * soc->counter_perport];
  16672 
  16673         /* IPIPE */
  16674         ctrl.flags = 0;
  16675         ctrl.cfg_count = 1;
  16676         ctrl.buff = &buff[ing_first];
  16677         ctrl.cb = _soc_sbusdma_port_ctr_cb;
  16678         ctrl.data = INT_TO_PTR(phy_port);
  16679 #define _IP_COUNTERS "IP COUNTERS"
  16680         sal_strncpy(ctrl.name, _IP_COUNTERS, sizeof(_IP_COUNTERS));
  16681         cfg.acc_type = ing_acc_type;
  16682         cfg.blk = ing_blkoff;
  16683         cfg.addr = ing_addr + port;
  16684         cfg.width = SOC_REG_IS_64(unit, ing_reg) ? 2 : 1;
  16685         cfg.count = ing_c_cnt;
  16686         cfg.addr_shift = 8;
  16687         SOC_IF_ERROR_RETURN
  16688             (soc_sbusdma_desc_create(unit, &ctrl, &cfg,
  16689                                      &_soc_port_counter_handles[unit][phy_port][0]));
  16690         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  16691                  (BSL_META_U(unit,
  16692                              "port %d phy_port %d handle ip: %d\n"),
  16693                   port, phy_port, _soc_port_counter_handles[unit][phy_port][0]));
  16694 
  16695         /* EPIPE */
  16696         ctrl.buff = &buff[egr_first];
  16697 #define _EP_COUNTERS "EP COUNTERS"
  16698         sal_strncpy(ctrl.name, _EP_COUNTERS, sizeof(_EP_COUNTERS));
  16699         cfg.acc_type = egr_acc_type;
  16700         cfg.blk = egr_blkoff;
  16701         cfg.addr = egr_addr + port;
  16702         cfg.width = SOC_REG_IS_64(unit, egr_reg) ? 2 : 1;
  16703         cfg.count = egr_c_cnt;
  16704         cfg.addr_shift = 8;
  16705         SOC_IF_ERROR_RETURN
  16706             (soc_sbusdma_desc_create(unit, &ctrl, &cfg,
  16707                                      &_soc_port_counter_handles[unit][phy_port][1]));
  16708         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  16709                  (BSL_META_U(unit,
  16710                              "port %d phy_port %d handle ep: %d\n"),
  16711                   port, phy_port, _soc_port_counter_handles[unit][phy_port][1]));
  16712 
  16713 #ifdef SOC_COUNTER_TABLE_SUPPORT
  16714         /* MIB_TABLE */
  16715         if (SOC_IS_TOMAHAWK3(unit) &&
  16716             SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CDPORT) &&
  16717             PBMP_MEMBER(soc->counter_pbmp, port)) {
  16718             ctrl.flags = SOC_SBUSDMA_MEMORY_CMD_MSG;
  16719             ctrl.cfg_count = 1;
  16720             ctrl.buff = &buff[mib_tbl_first];
  16721             ctrl.cb = _soc_sbusdma_port_ctr_cb;
  16722             ctrl.data = INT_TO_PTR(phy_port);
  16723 #define _MIB_TABLE_COUNTERS "MIB TBL CTRS"
  16724             sal_strncpy(ctrl.name, _MIB_TABLE_COUNTERS, sizeof(_MIB_TABLE_COUNTERS));
  16725             cfg.acc_type = mib_tbl_acc_type;
  16726             cfg.blk = SOC_PORT_BLOCK(unit, phy_port);
  16727             cfg.blk = SOC_BLOCK2SCH(unit, cfg.blk);
  16728             cfg.addr = mib_tbl_addr + SOC_PORT_BINDEX(unit, phy_port) * NUM_CDMIB_MEM_ROWS_PER_PORT;
  16729             cfg.width = 16; /* treat one row (8 counters) as one here */
  16730             cfg.count = mib_tbl_c_cnt / 8; /* 8 counters per row in table */
  16731             cfg.addr_shift = 0;
  16732             SOC_IF_ERROR_RETURN
  16733                 (soc_sbusdma_desc_create(unit, &ctrl, &cfg,
  16734                                          &_soc_port_counter_handles[unit][phy_port][4]));
  16735             LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  16736                      (BSL_META_U(unit,
  16737                                  "port %d phy_port %d handle mib_table: %d\n"),
  16738                       port, phy_port, _soc_port_counter_handles[unit][phy_port][4]));
  16739         }
  16740 #endif
  16741 
  16742         /* MAC */
  16743         for (i = 0; i < port_num_blktype; i++) {
  16744             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
  16745             if (blk < 0) {
  16746                 continue;
  16747             }
  16748             assert(SOC_REG_IS_VALID(unit, mac_reg) ||
  16749                 SOC_REG_IS_VALID(unit, gmac_reg));
  16750 
  16751             if (SOC_REG_IS_VALID(unit, mac_reg)) {
  16752                 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, mac_reg).block,
  16753                                       SOC_BLOCK_TYPE(unit, blk))) {
  16754                     if (SOC_BLOCK_PORT(unit, blk) < 0) {
  16755                         /* Greyhound phy_port 2-5 have both GXPORT and
  16756                            XLPORT block attribute. Need to check block_port
  16757                            to identify the valid attribute */
  16758                         continue;
  16759                     }
  16760                     break;
  16761                 }
  16762             }
  16763             if (SOC_REG_IS_VALID(unit, gmac_reg)) {
  16764                 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, gmac_reg).block,
  16765                                       SOC_BLOCK_TYPE(unit, blk))) {
  16766                     if (SOC_BLOCK_PORT(unit, blk) < 0) {
  16767                         /* Greyhound phy_port 2-5 have both GXPORT and
  16768                            XLPORT block attribute. Need to check block_port
  16769                            to identify the valid attribute */
  16770                         continue;
  16771                     }
  16772                     break;
  16773                 }
  16774             }
  16775 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_HELIX5_SUPPORT)
  16776             if (SOC_REG_IS_VALID(unit, mac_clmib_reg)) {
  16777                 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, mac_clmib_reg).block,
  16778                                       SOC_BLOCK_TYPE(unit, blk))) {
  16779                     if (SOC_BLOCK_PORT(unit, blk) < 0) {
  16780                         continue;
  16781                     }
  16782                     break;
  16783                 }
  16784             }
  16785 #endif /* BCM_GREYHOUND2_SUPPORT */
  16786         }
  16787         if (i == port_num_blktype) {
  16788             continue;
  16789         }
  16790 
  16791         mac_blkoff = 0;
  16792         mac_addr = 0;
  16793         mac_acc_type = 0;
  16794 #if defined (BCM_METROLITE_SUPPORT)
  16795         if (SOC_IS_METROLITE(unit)) {
  16796             if(SOC_PORT_VALID(unit, port)) {
  16797                 if (phy_port == 0) {
  16798                     continue;
  16799                 }
  16800                 if (phy_port >= 1 && phy_port <= 4) {
  16801                     mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, FALSE,
  16802                                                 &mac_blkoff, &mac_acc_type);
  16803                     cfg.count = mac_c_cnt;
  16804                 } else {
  16805                     mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, FALSE,
  16806                                                 &mac_blkoff, &mac_acc_type);
  16807                     cfg.count = gmac_c_cnt;
  16808                 }
  16809                 cfg.width = 2;
  16810             }
  16811         } else 
  16812 #endif
  16813 
  16814 #if defined (BCM_SABER2_SUPPORT)
  16815         if (SOC_IS_SABER2(unit)) {
  16816             if(SOC_PORT_VALID(unit, port)) {
  16817                 if (phy_port == 0) {
  16818                     continue;
  16819                 }
  16820                 if (phy_port >= 1 && phy_port <= 24) {
  16821                     mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0,
  16822                                                 SOC_REG_ADDR_OPTION_NONE,
  16823                                                 &mac_blkoff, &mac_acc_type);
  16824                     cfg.count = mac_c_cnt;
  16825                 } else {
  16826                     mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0,
  16827                                                 SOC_REG_ADDR_OPTION_NONE,
  16828                                                 &mac_blkoff, &mac_acc_type);
  16829                     cfg.count = gmac_c_cnt;
  16830                 }
  16831                 cfg.width = 2;
  16832             }
  16833         } else 
  16834 #endif
  16835 #if defined(BCM_HELIX5_SUPPORT)
  16836         if (SOC_IS_HELIX5(unit)) {
  16837             use_gmac = IS_QSGMII_PORT(unit, port) ? 1 : 0;
  16838             cfg.width = 2;
  16839             if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CLPORT)) {
  16840                 mac_addr = soc_reg_addr_get(unit, mac_clmib_reg, port, 0, FALSE,
  16841                                             &mac_blkoff, &mac_acc_type);
  16842                 cfg.count = mac_clmib_c_cnt;
  16843             } else if (use_gmac) {
  16844                 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, FALSE,
  16845                                             &mac_blkoff, &mac_acc_type);
  16846                 cfg.count = gmac_c_cnt;
  16847                 cfg.width = 1;
  16848             } else {
  16849                 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, FALSE,
  16850                                             &mac_blkoff, &mac_acc_type);
  16851                 cfg.count = mac_c_cnt;
  16852             }
  16853         } else
  16854 #endif /* HELIX5 */
  16855 #if defined(BCM_TRIDENT3_SUPPORT)
  16856         if (SOC_IS_TRIDENT3X(unit)) {
  16857             use_gmac =
  16858                 SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port),
  16859                                     SOC_BLK_XLPORT) ? TRUE : FALSE;
  16860             gmac_c_width = 2;
  16861             if (use_gmac) {
  16862                 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, FALSE,
  16863                                             &mac_blkoff, &mac_acc_type);
  16864                 cfg.count = gmac_c_cnt;
  16865                 cfg.width = gmac_c_width;
  16866             } else {
  16867                 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, FALSE,
  16868                                             &mac_blkoff, &mac_acc_type);
  16869                 cfg.count = mac_c_cnt;
  16870                 cfg.width = 2;
  16871             }
  16872         } else
  16873 #endif /* TRIDENT3 */
  16874 #if defined BCM_TOMAHAWKPLUS_SUPPORT
  16875         if (SOC_IS_TOMAHAWKPLUS(unit) &&
  16876             (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_XLPORT))) {
  16877                 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0,
  16878                                             SOC_REG_ADDR_OPTION_NONE,
  16879                                             &mac_blkoff, &mac_acc_type);
  16880                 cfg.count = gmac_c_cnt;
  16881                 cfg.width = 2;
  16882         } else
  16883 #endif /* BCM_TOMAHAWKPLUS_SUPPORT */
  16884 #if defined BCM_TOMAHAWK2_SUPPORT
  16885         if (SOC_IS_TOMAHAWK2(unit)) {
  16886             use_gmac = SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_XLPORT) ? TRUE : FALSE;
  16887             gmac_c_width = 2;
  16888 
  16889             if (use_gmac) {
  16890                 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0,
  16891                                             SOC_REG_ADDR_OPTION_NONE,
  16892                                             &mac_blkoff, &mac_acc_type);
  16893                 cfg.count = gmac_c_cnt;
  16894                 cfg.width = gmac_c_width;
  16895             } else {
  16896                 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0,
  16897                                             SOC_REG_ADDR_OPTION_NONE,
  16898                                             &mac_blkoff, &mac_acc_type);
  16899                 cfg.count = mac_c_cnt;
  16900                 cfg.width = 2;
  16901             }
  16902         } else
  16903 #endif /* BCM_TOMAHAWK2_SUPPORT */
  16904         if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CLG2PORT)) {
  16905             mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0,
  16906                                         SOC_REG_ADDR_OPTION_NONE,
  16907                                         &mac_blkoff, &mac_acc_type);
  16908             cfg.count = gmac_c_cnt;
  16909             cfg.width = 2;
  16910         } else if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_GPORT)||
  16911             SOC_BLOCK_IS_CMP(unit, SOC_PORT_IDX_BLOCK(unit, phy_port,i),
  16912                                  SOC_BLK_GXPORT)) {
  16913 
  16914             mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0,
  16915                                         SOC_REG_ADDR_OPTION_NONE, &mac_blkoff,
  16916                                         &mac_acc_type);
  16917             cfg.count = gmac_c_cnt;
  16918             cfg.width = 1;
  16919         } else {
  16920 #ifdef BCM_GREYHOUND2_SUPPORT
  16921             if ((SOC_IS_GREYHOUND2(unit)) &&
  16922                 SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CLPORT)) {
  16923                 mac_addr = soc_reg_addr_get(unit, mac_clmib_reg, port, 0,
  16924                                             SOC_REG_ADDR_OPTION_NONE, &mac_blkoff,
  16925                                             &mac_acc_type);
  16926                 cfg.count = mac_clmib_c_cnt;
  16927                 cfg.width = 2;
  16928             } else 
  16929 #endif /* BCM_GREYHOUND2_SUPPORT */
  16930             {
  16931             mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0,
  16932                                         SOC_REG_ADDR_OPTION_NONE, &mac_blkoff,
  16933                                         &mac_acc_type);
  16934             cfg.count = mac_c_cnt;
  16935             cfg.width = 2;
  16936         }
  16937         }
  16938         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  16939                  (BSL_META_U(unit,
  16940                              "port %d mac_blkoff = %d, mac_addr = %08x\n"),
  16941                   port, mac_blkoff, mac_addr));
  16942 
  16943         /* MAC or port group */
  16944         ctrl.buff = &buff[soc->counter_mac_first];
  16945 #define _MIBS "MIBS"
  16946         sal_strncpy(ctrl.name, _MIBS, sizeof(_MIBS));
  16947         cfg.acc_type = mac_acc_type;
  16948         cfg.blk = mac_blkoff;
  16949         cfg.addr = mac_addr;
  16950         cfg.addr_shift = 8;
  16951         SOC_IF_ERROR_RETURN
  16952             (soc_sbusdma_desc_create(unit, &ctrl, &cfg,
  16953                                      &_soc_port_counter_handles[unit][phy_port][2]));
  16954         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  16955                  (BSL_META_U(unit,
  16956                              "port %d phy_port %d handle mib: %d\n"),
  16957                   port, phy_port, _soc_port_counter_handles[unit][phy_port][2]));
  16958 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  16959         /* MAC for XLPMIB */
  16960         if ((SOC_IS_GREYHOUND2(unit) &&
  16961             (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_XLPORT))) ||
  16962             (SOC_IS_MONTEREY(unit))){
  16963             mac_addr = soc_reg_addr_get(unit, mac_xlpmib_reg, port, 0,
  16964                                         SOC_REG_ADDR_OPTION_NONE, &mac_blkoff,
  16965                                         &mac_acc_type);
  16966             cfg.count = mac_xlpmib_c_cnt;
  16967             cfg.width = 2;
  16968 
  16969             LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  16970                      (BSL_META_U(unit,
  16971                                  "port %d mac_xlpmib_c_cnt = %d\n"
  16972                                  "mac_blkoff = %d, mac_addr = %08x\n"),
  16973                       port, mac_xlpmib_c_cnt, mac_blkoff, mac_addr));
  16974 
  16975             ctrl.buff = &buff[mac_xlpmib_first];
  16976 #define _XLPMIBS "XLPMIBS"
  16977             sal_strncpy(ctrl.name, _XLPMIBS, sizeof(_XLPMIBS));
  16978             cfg.acc_type = mac_acc_type;
  16979             cfg.blk = mac_blkoff;
  16980             cfg.addr = mac_addr;
  16981             cfg.addr_shift = 8;
  16982             SOC_IF_ERROR_RETURN
  16983                 (soc_sbusdma_desc_create(unit, &ctrl, &cfg,
  16984                                          &_soc_port_counter_handles[unit][phy_port][3]));
  16985             LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  16986                      (BSL_META_U(unit,
  16987                                  "port %d phy_port %d handle xlpmib: %d\n"),
  16988                       port, phy_port, _soc_port_counter_handles[unit][phy_port][3]));
  16989         }
  16990 #endif /* BCM_GREYHOUND2_SUPPORT */
  16991     }
  16992 
  16993 
  16994 
  16995     if (soc->blk_ctr_desc_count) {
  16996         int rc;
  16997         uint16 cnt, bindex;
  16998         soc_sbusdma_desc_ctrl_t ctrl = {0};
  16999         soc_sbusdma_desc_cfg_t *cfg;
  17000         uint64 *buff, *hwval, *swval;
  17001         sal_memset(_soc_blk_counter_handles[unit], 0,
  17002                    soc->blk_ctr_desc_count * sizeof(sbusdma_desc_handle_t));
  17003         _blk_ctr_process[unit] = sal_alloc(soc->blk_ctr_desc_count *
  17004                                      sizeof(soc_blk_ctr_process_t*),
  17005                                      "blk_ctr_process_ptr");
  17006         buff = soc->blk_ctr_buf;
  17007         hwval = soc->blk_counter_hw_val;
  17008         swval = soc->blk_counter_sw_val;
  17009         for (bindex = 0; bindex < soc->blk_ctr_desc_count; bindex++) {
  17010             cnt = 0;
  17011             while (soc->blk_ctr_desc[bindex].desc[cnt].reg != INVALIDr) {
  17012                 cnt++;
  17013             }
  17014             if (cnt) {
  17015                 uint8 at;
  17016                 uint16 i;
  17017                 int ctr_blk;
  17018                 soc_blk_ctr_process_t *ctr_process;
  17019                 cfg = sal_alloc(cnt * sizeof(soc_sbusdma_desc_cfg_t),
  17020                       "sbusdma_desc_cfg");
  17021                 if (cfg == NULL) {
  17022                     return SOC_E_MEMORY;
  17023                 }
  17024                 ctrl.flags = 0;
  17025                 ctrl.cfg_count = cnt;
  17026                 ctrl.buff = buff;
  17027                 ctrl.cb = _soc_sbusdma_blk_ctr_cb;
  17028 #define _BLK_CTRS "BLK CTRS"
  17029                 sal_strncpy(ctrl.name, _BLK_CTRS, sizeof(_BLK_CTRS));
  17030                 ctr_process = sal_alloc(sizeof(soc_blk_ctr_process_t), "blk_ctr_process");
  17031                 if (cfg == NULL) {
  17032                     sal_free(cfg);
  17033                     return SOC_E_MEMORY;
  17034                 }
  17035                 ctr_process->blk = soc->blk_ctr_desc[bindex].blk;
  17036                 ctr_process->bindex = bindex;
  17037                 ctr_process->entries = cnt;
  17038                 ctr_process->buff = buff;
  17039                 ctr_process->hwval = hwval;
  17040                 ctr_process->swval = swval;
  17041                 ctrl.data = INT_TO_PTR((uint32)bindex);
  17042                 _blk_ctr_process[unit][bindex] = ctr_process;
  17043                 for (i=0; i<cnt; i++) {
  17044                     cfg[i].addr = soc_reg_addr_get(unit,
  17045                                                    soc->blk_ctr_desc[bindex].desc[i].reg,
  17046                                                    REG_PORT_ANY, 0,
  17047                                                    SOC_REG_ADDR_OPTION_NONE,
  17048                                                    &ctr_blk, &at);
  17049                     cfg[i].blk = ctr_blk;
  17050                     cfg[i].width = soc->blk_ctr_desc[bindex].desc[i].width;
  17051                     cfg[i].count = soc->blk_ctr_desc[bindex].desc[i].entries;
  17052                     cfg[i].addr_shift = soc->blk_ctr_desc[bindex].desc[i].shift;
  17053                 }
  17054                 rc = soc_sbusdma_desc_create(unit, &ctrl, cfg,
  17055                                              &_soc_blk_counter_handles[unit][bindex]);
  17056                 sal_free(cfg);
  17057                 if (rc != SOC_E_NONE) {
  17058                     LOG_ERROR(BSL_LS_SOC_COMMON,
  17059                               (BSL_META_U(unit,
  17060                                           "Desc creation error for handle blk: %d\n"),
  17061                                _soc_blk_counter_handles[unit][bindex]));
  17062                     return rc;
  17063                 }
  17064                 LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17065                          (BSL_META_U(unit,
  17066                                      "handle blk: %d\n"),
  17067                           _soc_blk_counter_handles[unit][bindex]));
  17068             }
  17069             buff += cnt; hwval += cnt; swval += cnt;
  17070         }
  17071     }
  17072     return SOC_E_NONE;
  17073 }
  17074 
  17075 #if defined(BCM_XGS5_SWITCH_PORT_SUPPORT)
  17076 /*
  17077  * Function:
  17078  *      soc_counter_port_sbusdma_desc_alloc
  17079  * Purpose:
  17080  *      Allocate the Sbus DMA descriptors for the port.
  17081  *      .
  17082  * Parameters:
  17083  *      unit    -  (IN) Unit number.
  17084  *      port    -  (IN) Logical port.
  17085  * Returns:
  17086  *      SOC_E_NONE              Success
  17087  *      SOC_E_*
  17088  */
  17089 int
  17090 soc_counter_port_sbusdma_desc_alloc(int unit, soc_port_t port)
  17091 {
  17092     soc_control_t       *soc;
  17093     int                 csize;
  17094     soc_ctr_type_t      ctype;
  17095     soc_reg_t           reg, ing_reg, egr_reg, mac_reg, gmac_reg;
  17096     int                 ing_c_cnt, egr_c_cnt, mac_c_cnt, gmac_c_cnt;
  17097     int                 ing_first, egr_first, mac_first, gmac_first;
  17098     int                 ing_last, egr_last, mac_last, gmac_last;
  17099     uint32              ing_addr, egr_addr, mac_addr;
  17100     int                 ing_blkoff, egr_blkoff, mac_blkoff;
  17101     uint8               ing_acc_type, egr_acc_type, mac_acc_type;
  17102     int                 blk, phy_port, i;
  17103     int                 port_num_blktype;
  17104     soc_sbusdma_desc_ctrl_t   ctrl = {0};
  17105     soc_sbusdma_desc_cfg_t    cfg;
  17106     uint64              *buff;
  17107 #if defined(BCM_TOMAHAWK2_SUPPORT)
  17108     int                 use_gmac, gmac_c_width;
  17109 #endif
  17110 #ifdef SOC_COUNTER_TABLE_SUPPORT
  17111     int mib_tbl_first = 10000; /* a huge number */
  17112     int mib_tbl_last = -1;
  17113     int mib_tbl_c_cnt = 0;
  17114     uint32 mib_tbl_addr = 0;
  17115     uint8 mib_tbl_acc_type = 0;
  17116 #endif
  17117 #if  defined(BCM_MONTEREY_SUPPORT)
  17118     soc_reg_t           mac_xlpmib_reg;
  17119     int                 mac_xlpmib_c_cnt, mac_xlpmib_first, mac_xlpmib_last;
  17120 #endif 
  17121 #if defined(BCM_HELIX5_SUPPORT)
  17122     soc_reg_t           mac_clmib_reg;
  17123     int                 mac_clmib_c_cnt, mac_clmib_first, mac_clmib_last;
  17124 #endif
  17125     soc = SOC_CONTROL(unit);
  17126 
  17127     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  17128     if (phy_port == -1) {
  17129         return SOC_E_INTERNAL;
  17130     }
  17131 
  17132     port_num_blktype = SOC_DRIVER(unit)->port_num_blktype > 1 ?
  17133         SOC_DRIVER(unit)->port_num_blktype : 1;
  17134 
  17135     ing_reg = INVALIDr;
  17136     egr_reg = INVALIDr;
  17137     mac_reg = INVALIDr;
  17138     gmac_reg = INVALIDr;
  17139     ing_first = 10000; /* a huge number */
  17140     egr_first = 10000;
  17141     mac_first = 10000;
  17142     gmac_first = 10000;
  17143     ing_last = -1;
  17144     egr_last = -1;
  17145     mac_last = -1;
  17146     gmac_last = -1;
  17147     ing_reg = INVALIDr;
  17148     egr_reg = INVALIDr;
  17149     mac_reg = INVALIDr;
  17150     gmac_reg = INVALIDr;
  17151 #if defined(BCM_MONTEREY_SUPPORT)
  17152     mac_xlpmib_reg = INVALIDr;
  17153     mac_xlpmib_first = 10000;
  17154     mac_xlpmib_last = -1;
  17155 #endif
  17156 #if defined(BCM_HELIX5_SUPPORT)
  17157     mac_clmib_reg = INVALIDr;
  17158     mac_clmib_first = 10000;
  17159     mac_clmib_last = -1;
  17160 #endif
  17161     for (ctype = 0; ctype < SOC_CTR_NUM_TYPES; ctype++) {
  17162         if (!SOC_HAS_CTR_TYPE(unit, ctype)) {
  17163             continue;
  17164         }
  17165         for (csize = SOC_CTR_MAP_SIZE(unit, ctype) - 1; csize >= 0; csize--) {
  17166             reg = SOC_CTR_TO_REG(unit, ctype, csize);
  17167             if (SOC_COUNTER_INVALID(unit, reg)) {
  17168                 continue;                       /* skip trailing invalids */
  17169             }
  17170 #ifdef SOC_COUNTER_TABLE_SUPPORT
  17171             if (SOC_IS_TOMAHAWK3(unit) &&
  17172                 SOC_REG_IS_COUNTER_TABLE(unit, reg)) {
  17173                 if (mib_tbl_first > csize) {
  17174                     mib_tbl_first = csize;
  17175                 }
  17176                 if (mib_tbl_last < csize) {
  17177                     mib_tbl_last = csize;
  17178                 }
  17179                 continue;
  17180             }
  17181 #endif
  17182             if (SOC_REG_BLOCK_IS(unit, reg, SOC_BLK_IPIPE)) {
  17183                 if (ing_first > csize) {
  17184                     ing_first = csize;
  17185                     ing_reg = reg;
  17186                 }
  17187                 if (ing_last < csize) {
  17188                     ing_last = csize;
  17189                 }
  17190             }
  17191             if (SOC_REG_BLOCK_IS(unit, reg, SOC_BLK_EPIPE)) {
  17192                 if (egr_first > csize) {
  17193                     egr_first = csize;
  17194                     egr_reg = reg;
  17195                 }
  17196                 if (egr_last < csize) {
  17197                     egr_last = csize;
  17198                 }
  17199             }
  17200 #if defined(BCM_TOMAHAWK2_SUPPORT)
  17201             if (SOC_IS_TOMAHAWK2(unit)) {
  17202                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT)) {
  17203                     if (mac_first > csize) {
  17204                         mac_first = csize;
  17205                         mac_reg = reg;
  17206                     }
  17207                     if (mac_last < csize) {
  17208                         mac_last = csize;
  17209                     }
  17210                     mac_reg = reg;
  17211                     continue;
  17212                 }
  17213                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) {
  17214                     if (gmac_first > csize) {
  17215                         gmac_first = csize;
  17216                         gmac_reg = reg;
  17217                     }
  17218                     if (gmac_last < csize) {
  17219                         gmac_last = csize;
  17220                     }
  17221                     continue;
  17222                 }
  17223             }
  17224 #endif /* BCM_TOMAHAWK2_SUPPORT */
  17225 #if  defined(BCM_MONTEREY_SUPPORT)
  17226             if (SOC_IS_MONTEREY(unit)) {
  17227                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) {
  17228                     /* The first XLPMIB_XXXr offset = 0x10000 (XLPMIB_R64r) */
  17229                     if (SOC_REG_INFO(unit, reg).offset & 0x10000) {
  17230                         if (mac_xlpmib_first > csize) {
  17231                             mac_xlpmib_first = csize;
  17232                             mac_xlpmib_reg = reg;
  17233                         }
  17234                         if (mac_xlpmib_last < csize) {
  17235                             mac_xlpmib_last = csize;
  17236                         }
  17237                         mac_xlpmib_reg = reg;
  17238 
  17239                   } else  { 
  17240                         if (mac_first > csize) {
  17241                             mac_first = csize;
  17242                             mac_reg = reg;
  17243                         }
  17244                         if (mac_last < csize) {
  17245                             mac_last = csize;
  17246                         }
  17247                         mac_reg = reg;
  17248                     }
  17249                         continue; 
  17250                 }
  17251             }
  17252 #endif
  17253 #ifdef BCM_HELIX5_SUPPORT
  17254             if (SOC_IS_HELIX5(unit)) {
  17255                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) {
  17256                     if (mac_first > csize) {
  17257                         mac_first = csize;
  17258                     }
  17259                     if (mac_last < csize) {
  17260                         mac_last = csize;
  17261                     }
  17262                     mac_reg = reg;
  17263                     continue;
  17264                 }
  17265 
  17266                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT)) {
  17267                     if (gmac_first > csize) {
  17268                         gmac_first = csize;
  17269                     }
  17270                     if (gmac_last < csize) {
  17271                         gmac_last = csize;
  17272                     }
  17273                     gmac_reg = reg;
  17274                     continue;
  17275                 }
  17276 
  17277                 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT)) {
  17278                     if (mac_clmib_first > csize) {
  17279                         mac_clmib_first = csize;
  17280                     }
  17281                     if (mac_clmib_last < csize) {
  17282                         mac_clmib_last = csize;
  17283                     }
  17284                     mac_clmib_reg = reg;
  17285                     continue;
  17286                 }
  17287             }
  17288 #endif /* BCM_HELIX5_SUPPORT */
  17289 
  17290             if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT) ||
  17291                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORTB0) ||
  17292                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XTPORT) ||
  17293                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XWPORT) ||
  17294                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT) ||
  17295                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_MXQPORT) ||
  17296                 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_PGW_CL)) {
  17297                 if (mac_first > csize) {
  17298                     mac_first = csize;
  17299                     mac_reg = reg;
  17300                 }
  17301                 if (mac_last < csize) {
  17302                     mac_last = csize;
  17303                 }
  17304                 mac_reg = reg;
  17305             } else if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GPORT)||
  17306                        SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT)) {
  17307                 if (gmac_first > csize) {
  17308                     gmac_first = csize;
  17309                     gmac_reg = reg;
  17310                 }
  17311                 if (gmac_last < csize) {
  17312                     gmac_last = csize;
  17313                 }
  17314             }
  17315             /* CLG2 MIB have some new unique registers which are added
  17316              * in seperate counter map. So we use gmac for CLG2.
  17317              */
  17318             if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLG2PORT)) {
  17319                 if (gmac_first > csize) {
  17320                     gmac_first = csize;
  17321                     gmac_reg = reg;
  17322                 }
  17323                 if (gmac_last < csize) {
  17324                     gmac_last = csize;
  17325                 }
  17326             }
  17327         }
  17328     }
  17329 
  17330     ing_c_cnt = ing_first != -1 ? ing_last - ing_first + 1 : 0;
  17331     egr_c_cnt = egr_first != -1 ? egr_last - egr_first + 1 : 0;
  17332     mac_c_cnt = mac_first != -1 ? mac_last - mac_first + 1 : 0;
  17333     gmac_c_cnt = gmac_first != -1 ? gmac_last - gmac_first + 1 : 0;
  17334 #if  defined(BCM_HELIX5_SUPPORT)
  17335     mac_clmib_c_cnt = mac_clmib_first != -1 ? mac_clmib_last - mac_clmib_first + 1 : 0;
  17336 #endif /* BCM_MONTEREY_SUPPORT */
  17337     soc->counter_ing_first = ing_first;
  17338     soc->counter_egr_first = egr_first;
  17339     soc->counter_mac_first = mac_first;
  17340 #if  defined(BCM_MONTEREY_SUPPORT)
  17341     mac_xlpmib_c_cnt = mac_xlpmib_first != -1 ? mac_xlpmib_last - mac_xlpmib_first + 1 : 0;
  17342 #endif /* BCM_MONTEREY_SUPPORT */
  17343     assert(SOC_REG_IS_VALID(unit, ing_reg));
  17344     assert(SOC_REG_IS_VALID(unit, egr_reg));
  17345     ing_addr = soc_reg_addr_get(unit, ing_reg, REG_PORT_ANY, 0,
  17346                                 SOC_REG_ADDR_OPTION_NONE, &ing_blkoff,
  17347                                 &ing_acc_type);
  17348     egr_addr = soc_reg_addr_get(unit, egr_reg, REG_PORT_ANY, 0,
  17349                                 SOC_REG_ADDR_OPTION_NONE, &egr_blkoff,
  17350                                 &egr_acc_type);
  17351 
  17352     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17353              (BSL_META_U(unit,
  17354                          "ing_c_cnt = %d egr_c_cnt = %d mac_c_cnt = %d gmac_c_cnt = %d\n"
  17355                          "ing_blkoff = %d ing_acc_type = %d ing_addr = %08x \n"
  17356                          "egr_blkoff = %d egr_acc_type = %d egr_addr = %08x \n"),
  17357               ing_c_cnt, egr_c_cnt, mac_c_cnt, gmac_c_cnt,
  17358               ing_blkoff, ing_acc_type, ing_addr,
  17359               egr_blkoff, egr_acc_type, egr_addr));
  17360 #if defined(BCM_MONTEREY_SUPPORT)
  17361     if ( SOC_IS_MONTEREY(unit)) {
  17362         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17363                  (BSL_META_U(unit,
  17364                              "mac_xlpmib_c_cnt = %d \n"),
  17365                   mac_xlpmib_c_cnt ));
  17366     }
  17367 #endif /* BCM_MONTEREY_SUPPORT */
  17368 #ifdef SOC_COUNTER_TABLE_SUPPORT
  17369     if (SOC_IS_TOMAHAWK3(unit)) {
  17370         mib_tbl_c_cnt = mib_tbl_first != -1 ? mib_tbl_last - mib_tbl_first + 1 : 0;
  17371         mib_tbl_addr = soc_mem_addr_get(unit, CDMIB_MEMm, 0, 0, 0, &mib_tbl_acc_type);
  17372         soc->counter_mib_tbl_first = mib_tbl_first;
  17373         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17374                  (BSL_META_U(unit, "mib_tbl_c_cnt = %d\n"), mib_tbl_c_cnt));
  17375     }
  17376 #endif
  17377     buff = &soc->counter_buf64[port * soc->counter_perport];
  17378 
  17379     /* IPIPE */
  17380     ctrl.flags = 0;
  17381     ctrl.cfg_count = 1;
  17382     ctrl.buff = &buff[ing_first];
  17383     ctrl.cb = _soc_sbusdma_port_ctr_cb;
  17384     ctrl.data = INT_TO_PTR(phy_port);
  17385     ctrl.pc = 0;
  17386     ctrl.pc_data = 0;
  17387 #define _IP_COUNTERS "IP COUNTERS"
  17388     sal_strncpy(ctrl.name, _IP_COUNTERS, sizeof(_IP_COUNTERS));
  17389     cfg.acc_type = ing_acc_type;
  17390     cfg.blk = ing_blkoff;
  17391     cfg.addr = ing_addr + port;
  17392     cfg.width = SOC_REG_IS_64(unit, ing_reg) ? 2 : 1;
  17393     cfg.count = ing_c_cnt;
  17394     cfg.addr_shift = 8;
  17395     SOC_IF_ERROR_RETURN
  17396         (soc_sbusdma_desc_create(unit, &ctrl, &cfg,
  17397                                  &_soc_port_counter_handles[unit][phy_port][0]));
  17398     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17399              (BSL_META_U(unit,
  17400                          "port %d phy_port %d handle ip: %d\n"),
  17401               port, phy_port, _soc_port_counter_handles[unit][phy_port][0]));
  17402 
  17403     /* EPIPE */
  17404     ctrl.buff = &buff[egr_first];
  17405 #define _EP_COUNTERS "EP COUNTERS"
  17406     sal_strncpy(ctrl.name, _EP_COUNTERS, sizeof(_EP_COUNTERS));
  17407     cfg.acc_type = egr_acc_type;
  17408     cfg.blk = egr_blkoff;
  17409     cfg.addr = egr_addr + port;
  17410     cfg.width = SOC_REG_IS_64(unit, egr_reg) ? 2 : 1;
  17411     cfg.count = egr_c_cnt;
  17412     cfg.addr_shift = 8;
  17413     SOC_IF_ERROR_RETURN
  17414         (soc_sbusdma_desc_create(unit, &ctrl, &cfg,
  17415                                  &_soc_port_counter_handles[unit][phy_port][1]));
  17416     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17417              (BSL_META_U(unit,
  17418                          "port %d phy_port %d handle ep: %d\n"),
  17419               port, phy_port, _soc_port_counter_handles[unit][phy_port][1]));
  17420 
  17421 #ifdef SOC_COUNTER_TABLE_SUPPORT
  17422     /* MIB_TABLE */
  17423     if (SOC_IS_TOMAHAWK3(unit) &&
  17424         SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CDPORT)) {
  17425         ctrl.flags = SOC_SBUSDMA_MEMORY_CMD_MSG;
  17426         ctrl.cfg_count = 1;
  17427         ctrl.buff = &buff[mib_tbl_first];
  17428         ctrl.cb = _soc_sbusdma_port_ctr_cb;
  17429         ctrl.data = INT_TO_PTR(phy_port);
  17430 #define _MIB_TABLE_COUNTERS "MIB TBL CTRS"
  17431         sal_strncpy(ctrl.name, _MIB_TABLE_COUNTERS, sizeof(_MIB_TABLE_COUNTERS));
  17432         cfg.acc_type = mib_tbl_acc_type;
  17433         cfg.blk = SOC_PORT_BLOCK(unit, phy_port);
  17434         cfg.blk = SOC_BLOCK2SCH(unit, cfg.blk);
  17435         cfg.addr = mib_tbl_addr + SOC_PORT_BINDEX(unit, phy_port) * NUM_CDMIB_MEM_ROWS_PER_PORT;
  17436         cfg.width = 16; /* treat one row (8 counters) as one here */
  17437         cfg.count = mib_tbl_c_cnt / 8; /* 8 counters per row in table */
  17438         cfg.addr_shift = 0;
  17439         SOC_IF_ERROR_RETURN
  17440             (soc_sbusdma_desc_create(unit, &ctrl, &cfg,
  17441                                      &_soc_port_counter_handles[unit][phy_port][4]));
  17442         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17443                  (BSL_META_U(unit,
  17444                              "port %d phy_port %d handle mib_table: %d\n"),
  17445                   port, phy_port, _soc_port_counter_handles[unit][phy_port][4]));
  17446     }
  17447 #endif
  17448 
  17449     /* MAC */
  17450     for (i = 0; i < port_num_blktype; i++) {
  17451         blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
  17452         if (blk < 0) {
  17453             continue;
  17454         }
  17455         assert(SOC_REG_IS_VALID(unit, mac_reg) ||
  17456             SOC_REG_IS_VALID(unit, gmac_reg));
  17457 
  17458         if (SOC_REG_IS_VALID(unit, mac_reg)) {
  17459             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, mac_reg).block,
  17460                                   SOC_BLOCK_TYPE(unit, blk))) {
  17461                 if (SOC_BLOCK_PORT(unit, blk) < 0) {
  17462                     /* Greyhound phy_port 2-5 have both GXPORT and
  17463                        XLPORT block attribute. Need to check block_port
  17464                        to identify the valid attribute */
  17465                     continue;
  17466                 }
  17467                 break;
  17468             }
  17469         } 
  17470         if (SOC_REG_IS_VALID(unit, gmac_reg)) {
  17471             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, gmac_reg).block,
  17472                                   SOC_BLOCK_TYPE(unit, blk))) {
  17473                 if (SOC_BLOCK_PORT(unit, blk) < 0) {
  17474                     /* Greyhound phy_port 2-5 have both GXPORT and
  17475                        XLPORT block attribute. Need to check block_port
  17476                        to identify the valid attribute */
  17477                     continue;
  17478                 }
  17479                 break;
  17480             }
  17481         }
  17482 
  17483 #if defined(BCM_HELIX5_SUPPORT)
  17484         if (SOC_REG_IS_VALID(unit, mac_clmib_reg)) {
  17485             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, mac_clmib_reg).block,
  17486                                   SOC_BLOCK_TYPE(unit, blk))) {
  17487                 if (SOC_BLOCK_PORT(unit, blk) < 0) {
  17488                     continue;
  17489                 }
  17490                 break;
  17491             }
  17492         }
  17493 #endif /* BCM_HELIX5_SUPPORT */
  17494 
  17495     }
  17496     if (i == port_num_blktype) {
  17497         return SOC_E_NONE;
  17498     }
  17499 
  17500     mac_blkoff = 0;
  17501     mac_addr = 0;
  17502     mac_acc_type = 0;
  17503 
  17504 #if defined(BCM_TOMAHAWK2_SUPPORT)
  17505     if (SOC_IS_TOMAHAWK2(unit)) {
  17506         use_gmac = SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_XLPORT) ? TRUE : FALSE;
  17507         gmac_c_width = 2;
  17508 
  17509         if (use_gmac) {
  17510             mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0,
  17511                                         SOC_REG_ADDR_OPTION_NONE, &mac_blkoff,
  17512                                         &mac_acc_type);
  17513             cfg.count = gmac_c_cnt;
  17514             cfg.width = gmac_c_width;
  17515         } else {
  17516             mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0,
  17517                                         SOC_REG_ADDR_OPTION_NONE, &mac_blkoff,
  17518                                         &mac_acc_type);
  17519             cfg.count = mac_c_cnt;
  17520             cfg.width = 2;
  17521         }
  17522     } else
  17523 #endif /* BCM_TOMAHAWK2_SUPPORT */
  17524 #if defined(BCM_HELIX5_SUPPORT)
  17525     if (SOC_IS_HELIX5(unit)) {
  17526         cfg.width = 2;
  17527         if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CLPORT)) {
  17528             mac_addr = soc_reg_addr_get(unit, mac_clmib_reg, port, 0, FALSE,
  17529                                         &mac_blkoff, &mac_acc_type);
  17530             cfg.count = mac_clmib_c_cnt;
  17531         } else if (IS_QSGMII_PORT(unit, port)) {
  17532             mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, FALSE,
  17533                                         &mac_blkoff, &mac_acc_type);
  17534             cfg.count = gmac_c_cnt;
  17535             cfg.width = 1;
  17536         } else {
  17537             mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, FALSE,
  17538                                         &mac_blkoff, &mac_acc_type);
  17539             cfg.count = mac_c_cnt;
  17540         }
  17541     } else
  17542 #endif /* BCM_HELIX5_SUPPORT */
  17543     if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CLG2PORT)) {
  17544         mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0,
  17545                                     SOC_REG_ADDR_OPTION_NONE,
  17546                                     &mac_blkoff, &mac_acc_type);
  17547         cfg.count = gmac_c_cnt;
  17548         cfg.width = 2;
  17549     } else if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_GPORT)||
  17550                SOC_BLOCK_IS_CMP(unit, SOC_PORT_IDX_BLOCK(unit, phy_port,i),
  17551                                 SOC_BLK_GXPORT)) {
  17552         mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0,
  17553                                     SOC_REG_ADDR_OPTION_NONE, &mac_blkoff,
  17554                                     &mac_acc_type);
  17555         cfg.count = gmac_c_cnt;
  17556         cfg.width = 1;
  17557     } else {
  17558       
  17559         mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0,
  17560                                     SOC_REG_ADDR_OPTION_NONE, &mac_blkoff,
  17561                                     &mac_acc_type);
  17562         cfg.count = mac_c_cnt;
  17563         cfg.width = 2;
  17564       
  17565     }
  17566     
  17567     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17568              (BSL_META_U(unit,
  17569                          "port %d mac_blkoff = %d, mac_addr = %08x\n"),
  17570               port, mac_blkoff, mac_addr));
  17571     ctrl.buff = &buff[mac_first];
  17572 #define _MIBS "MIBS"
  17573     sal_strncpy(ctrl.name, _MIBS, sizeof(_MIBS));
  17574     cfg.acc_type = mac_acc_type;
  17575     cfg.blk = mac_blkoff;
  17576     cfg.addr = mac_addr;
  17577     cfg.addr_shift = 8;
  17578     SOC_IF_ERROR_RETURN
  17579         (soc_sbusdma_desc_create(unit, &ctrl, &cfg,
  17580                                  &_soc_port_counter_handles[unit][phy_port][2]));
  17581     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17582              (BSL_META_U(unit,
  17583                          "port %d phy_port %d handle mib: %d\n"),
  17584               port, phy_port, _soc_port_counter_handles[unit][phy_port][2]));
  17585 
  17586 #if  defined(BCM_MONTEREY_SUPPORT)
  17587         /* MAC for XLPMIB */
  17588         if (SOC_IS_MONTEREY(unit)) 
  17589         {
  17590             mac_addr = soc_reg_addr_get(unit, mac_xlpmib_reg, port, 0,
  17591                                         SOC_REG_ADDR_OPTION_NONE, &mac_blkoff,
  17592                                         &mac_acc_type);
  17593             cfg.count = mac_xlpmib_c_cnt;
  17594             cfg.width = 2;
  17595 
  17596             LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17597                      (BSL_META_U(unit,
  17598                                  "port %d mac_xlpmib_c_cnt = %d\n"
  17599                                  "mac_blkoff = %d, mac_addr = %08x\n"),
  17600                       port, mac_xlpmib_c_cnt, mac_blkoff, mac_addr));
  17601 
  17602             ctrl.buff = &buff[mac_xlpmib_first];
  17603 #define _XLPMIBS "XLPMIBS"
  17604             sal_strncpy(ctrl.name, _XLPMIBS, sizeof(_XLPMIBS));
  17605             cfg.acc_type = mac_acc_type;
  17606             cfg.blk = mac_blkoff;
  17607             cfg.addr = mac_addr;
  17608             cfg.addr_shift = 8;
  17609             SOC_IF_ERROR_RETURN
  17610                 (soc_sbusdma_desc_create(unit, &ctrl, &cfg,
  17611                                          &_soc_port_counter_handles[unit][phy_port][3]));
  17612             LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17613                      (BSL_META_U(unit,
  17614                                  "port %d phy_port %d handle xlpmib: %d\n"),
  17615                       port, phy_port, _soc_port_counter_handles[unit][phy_port][3]));
  17616         }
  17617 #endif /* BCM_MONTEREY_SUPPORT*/ 
  17618     return SOC_E_NONE;
  17619 }
  17620 
  17621 /*
  17622  * Function:
  17623  *      soc_counter_port_sbusdma_desc_free
  17624  * Purpose:
  17625  *      Deallocte or free the Sbus DMA descriptors
  17626  *      associated with the port.
  17627  *
  17628  * Parameters:
  17629  *      unit    -  (IN) Unit number.
  17630  *      port    -  (IN) Logical port.
  17631  * Returns:
  17632  *      SOC_E_NONE              Success
  17633  *      SOC_E_*
  17634  */
  17635 int
  17636 soc_counter_port_sbusdma_desc_free(int unit, soc_port_t port)
  17637 {
  17638     soc_control_t *soc = SOC_CONTROL(unit);
  17639     uint8 i, state = 0;
  17640     int ret, err = 0;
  17641     int blk, bindex, phy_port;
  17642 
  17643     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  17644     if (phy_port == -1 ) {
  17645        return SOC_E_INTERNAL;
  17646     }
  17647 
  17648     blk = SOC_PORT_BLOCK(unit, phy_port);
  17649     bindex = SOC_PORT_BINDEX(unit, phy_port);
  17650     if (_soc_port_counter_handles[unit][phy_port][0] && soc->counter_interval) {
  17651         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17652                  (BSL_META_U(unit,
  17653                              "port: %d blk: %d, bindex: %d\n"),
  17654                   port, blk, bindex));
  17655     }
  17656     for (i = 0; i <= (COUNTER_SBUSDMA_DESC_SIZE-1); i++) {
  17657         if ((i == 2) &&
  17658             (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT) &&
  17659              !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORTB0) &&
  17660              !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XTPORT) &&
  17661              !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XWPORT) &&
  17662              !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_MXQPORT) &&
  17663              !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GPORT) &&
  17664              !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GXPORT) &&
  17665              !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLPORT) &&
  17666              !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLG2PORT) &&
  17667              !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CDPORT))) {
  17668             continue;
  17669         }
  17670 #if  defined(BCM_MONTEREY_SUPPORT)
  17671             if (i == 3) {
  17672                 if (!SOC_IS_MONTEREY(unit)) {
  17673                     continue;
  17674                 }
  17675             }
  17676 #endif
  17677         if (_soc_port_counter_handles[unit][phy_port][i]) {
  17678             do {
  17679                 (void)soc_sbusdma_desc_get_state(unit, _soc_port_counter_handles[unit][phy_port][i],
  17680                                                  &state);
  17681                 if (state) {
  17682                     sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10);
  17683                 }
  17684             } while (state);
  17685 
  17686             ret = soc_sbusdma_desc_delete(unit, _soc_port_counter_handles[unit][phy_port][i]);
  17687             if (ret) {
  17688                 err++;
  17689             }
  17690             _soc_port_counter_handles[unit][phy_port][i] = 0;
  17691         }
  17692     }
  17693 
  17694     return err;
  17695 }
  17696 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT*/
  17697 
  17698 int
  17699 _soc_counter_sbudma_desc_free_all(int unit)
  17700 {
  17701     soc_control_t *soc = SOC_CONTROL(unit);
  17702     uint8 i, state = 0;
  17703     int ret, err = 0;
  17704     soc_port_t port;
  17705     int blk, bindex, phy_port;
  17706     soc_pbmp_t all_pbmp;
  17707 #ifdef BCM_KATANA2_SUPPORT
  17708     soc_port_t my_port;
  17709 #endif
  17710 
  17711     SOC_PBMP_CLEAR(all_pbmp);
  17712     SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  17713 #ifdef BCM_KATANA2_SUPPORT
  17714     if (SOC_IS_KATANA2(unit)) {
  17715         SOC_PBMP_CLEAR(all_pbmp);
  17716         for (my_port =  SOC_INFO(unit).cmic_port;
  17717              my_port <= SOC_INFO(unit).lb_port;
  17718              my_port++) {
  17719              if (SOC_INFO(unit).block_valid[SOC_PORT_BLOCK(unit,my_port)]) {
  17720                  SOC_PBMP_PORT_ADD(all_pbmp,my_port);
  17721              }
  17722         }
  17723     }
  17724 #endif
  17725 #if defined(BCM_KATANA2_SUPPORT)
  17726     if (!(soc_feature(unit, soc_feature_discontinuous_pp_port))) {
  17727     if (soc_feature(unit, soc_feature_linkphy_coe) &&
  17728         SOC_INFO(unit).linkphy_enabled) {
  17729         SOC_PBMP_REMOVE(all_pbmp, SOC_INFO(unit).linkphy_pp_port_pbm);
  17730     }
  17731     if (soc_feature(unit, soc_feature_subtag_coe) &&
  17732         SOC_INFO(unit).subtag_enabled) {
  17733         SOC_PBMP_REMOVE(all_pbmp, SOC_INFO(unit).subtag_pp_port_pbm);
  17734     }
  17735     }
  17736 #endif
  17737     PBMP_ITER(all_pbmp, port) {
  17738         if (soc_feature(unit, soc_feature_logical_port_num)) {
  17739             phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  17740         } else {
  17741             phy_port = port;
  17742         }
  17743 
  17744         blk = SOC_PORT_BLOCK(unit, phy_port);
  17745 #if defined(BCM_MONTEREY_SUPPORT)
  17746        if (SOC_IS_MONTEREY(unit) ) { 
  17747            if ((((phy_port > 0) && (phy_port < 13)) ||
  17748                  ((phy_port > 52) && (phy_port < 65)))
  17749                && !(IS_CPRI_PORT(unit, port))) {
  17750                 blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,1);
  17751            } else { 
  17752                 blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,0);
  17753            }
  17754       } 
  17755 #endif
  17756         bindex = SOC_PORT_BINDEX(unit, phy_port);
  17757         if (_soc_port_counter_handles[unit][phy_port][0] && soc->counter_interval) {
  17758             LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  17759                      (BSL_META_U(unit,
  17760                                  "port: %d blk: %d, bindex: %d\n"),
  17761                       port, blk, bindex));
  17762         }
  17763         for (i=0; i<=(COUNTER_SBUSDMA_DESC_SIZE-1); i++) {
  17764             if ((i == 2) &&
  17765                 (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT) &&
  17766                  !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORTB0) &&
  17767                  !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XTPORT) &&
  17768                  !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XWPORT) &&
  17769                  !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_MXQPORT) &&
  17770                  !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GPORT) &&
  17771                  !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GXPORT) &&
  17772                  !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLPORT) &&
  17773                  !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CPRI) &&
  17774                  !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLG2PORT &&
  17775                  !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CDPORT)))) {
  17776                 continue;
  17777             }
  17778 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  17779             if (i == 3) {
  17780                 if (!(SOC_IS_GREYHOUND2(unit) || SOC_IS_MONTEREY(unit))) {
  17781                     continue;
  17782                 }
  17783                 if (SOC_IS_GREYHOUND2(unit) &&
  17784                     (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT))) {
  17785                 continue;
  17786             }
  17787             }
  17788 #endif
  17789             if (_soc_port_counter_handles[unit][phy_port][i]) {
  17790                 do {
  17791                     (void)soc_sbusdma_desc_get_state(unit, _soc_port_counter_handles[unit][phy_port][i],
  17792                                                      &state);
  17793                     if (state) {
  17794                         sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10);
  17795                     }
  17796                 } while (state);
  17797 
  17798                 ret = soc_sbusdma_desc_delete(unit, _soc_port_counter_handles[unit][phy_port][i]);
  17799                 if (ret) {
  17800                     err++;
  17801                 }
  17802                 _soc_port_counter_handles[unit][phy_port][i] = 0;
  17803             }
  17804         }
  17805     }
  17806     if (soc->blk_ctr_desc_count && _soc_blk_counter_handles[unit]) {
  17807         uint16 bindex;
  17808         for (bindex = 0; bindex < soc->blk_ctr_desc_count; bindex++) {
  17809             if (_soc_blk_counter_handles[unit][bindex]) {
  17810                 do {
  17811                     (void)soc_sbusdma_desc_get_state(unit, _soc_blk_counter_handles[unit][bindex],
  17812                                                      &state);
  17813                     if (state) {
  17814                         sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10);
  17815                     }
  17816                 } while (state);
  17817                 ret = soc_sbusdma_desc_delete(unit, _soc_blk_counter_handles[unit][bindex]);
  17818                 if (ret) {
  17819                     err++;
  17820                 }
  17821                 _soc_blk_counter_handles[unit][bindex] = 0;
  17822                 if (_blk_ctr_process[unit][bindex]) {
  17823                     sal_free(_blk_ctr_process[unit][bindex]);
  17824                     _blk_ctr_process[unit][bindex] = NULL;
  17825                 }
  17826             }
  17827         }
  17828         if (_blk_ctr_process[unit]) {
  17829             sal_free(_blk_ctr_process[unit]);
  17830             _blk_ctr_process[unit] = NULL;
  17831         }
  17832     }
  17833     return err;
  17834 }
  17835 
  17836 int
  17837 soc_blk_counter_get(int unit, soc_block_t blk, soc_reg_t ctr_reg, int ar_idx,
  17838                     uint64 *val)
  17839 {
  17840     uint16 bindex, rindex;
  17841     soc_blk_ctr_process_t *ctr_process;
  17842     soc_ctr_reg_desc_t *reg_desc;
  17843     soc_control_t *soc = SOC_CONTROL(unit);
  17844 
  17845     if (soc->blk_ctr_desc_count && _blk_ctr_process[unit]) {
  17846         for (bindex = 0; bindex < soc->blk_ctr_desc_count; bindex++) {
  17847             if (_blk_ctr_process[unit][bindex]) {
  17848                 ctr_process = _blk_ctr_process[unit][bindex];
  17849                 if (ctr_process->blk == blk) {
  17850                     reg_desc = soc->blk_ctr_desc[ctr_process->bindex].desc;
  17851                     for (rindex = 0; reg_desc[rindex].reg != INVALIDr;
  17852                          rindex++) {
  17853                         if (reg_desc[rindex].reg == ctr_reg) {
  17854                             if (ar_idx < reg_desc[rindex].entries) {
  17855                                 *val = ctr_process->swval[ar_idx];
  17856                                 return SOC_E_NONE;
  17857                             } else {
  17858                                 return SOC_E_PARAM;
  17859                             }
  17860                         }
  17861                     }
  17862                     return SOC_E_PARAM;
  17863                 }
  17864             }
  17865         }
  17866         return SOC_E_PARAM;
  17867     }
  17868     return SOC_E_INIT;
  17869 }
  17870 
  17871 #endif /* BCM_SBUSDMA_SUPPORT */
  17872 
  17873 #ifdef BCM_XGS_SUPPORT
  17874 /*
  17875  * Function:
  17876  *      _soc_counter_dma_setup
  17877  * Purpose:
  17878  *      Configure hardware registers for counter collection.  Used during
  17879  *      soc_counter_thread initialization.
  17880  * Parameters:
  17881  *      unit    - switch unit
  17882  * Returns:
  17883  *      SOC_E_*
  17884  */
  17885 
  17886 static int
  17887 _soc_counter_dma_setup(int unit)
  17888 {
  17889     soc_control_t       *soc;
  17890     uint32              creg_first, creg_last, cireg_first, cireg_last;
  17891     int                 csize;
  17892     pbmp_t              pbmp;
  17893     soc_reg_t           reg;
  17894     soc_ctr_type_t      ctype;
  17895     uint32              offset;
  17896 #ifdef BCM_HERCULES_SUPPORT
  17897     uint32              val;
  17898 #endif
  17899 #ifdef BCM_XGS3_SWITCH_SUPPORT
  17900     if (SOC_IS_XGS3_SWITCH(unit)) {
  17901 #ifdef BCM_SBUSDMA_SUPPORT
  17902         if (soc_feature(unit, soc_feature_sbusdma)) {
  17903             int rv = _soc_counter_sbusdma_setup(unit);
  17904             if (rv) {
  17905                 (void)_soc_counter_sbudma_desc_free_all(unit);
  17906             }
  17907             return rv;
  17908         } else
  17909 #endif
  17910         {
  17911             return(_soc_xgs3_counter_dma_setup(unit));
  17912         }
  17913     }
  17914 #endif
  17915 
  17916     soc = SOC_CONTROL(unit);
  17917     SOC_PBMP_ASSIGN(pbmp, soc->counter_pbmp);
  17918 
  17919     WRITE_CMIC_STAT_DMA_ADDRr(unit, soc_cm_l2p(unit, soc->counter_buf32));
  17920     WRITE_CMIC_STAT_DMA_PORTSr(unit, SOC_PBMP_WORD_GET(pbmp, 0));
  17921 
  17922     /*
  17923      * Calculate the first and last register offsets for collection
  17924      * Higig offsets are kept separately
  17925      */
  17926     creg_first = creg_last = cireg_first = cireg_last = 0;
  17927     for (ctype = 0; ctype < SOC_CTR_NUM_TYPES; ctype++) {
  17928         if (!SOC_HAS_CTR_TYPE(unit, ctype)) {
  17929             continue;
  17930         }
  17931         if (ctype == SOC_CTR_TYPE_GFE) {        /* offsets screwed up */
  17932             continue;
  17933         }
  17934         reg = SOC_CTR_TO_REG(unit, ctype, 0);
  17935         if (!SOC_COUNTER_INVALID(unit, reg)) {
  17936             if (ctype == SOC_CTR_TYPE_HG) {
  17937                 cireg_first = SOC_REG_INFO(unit, reg).offset;
  17938             } else {
  17939                 creg_first = SOC_REG_INFO(unit, reg).offset;
  17940                 if (cireg_first == 0) {
  17941                     cireg_first = creg_first;
  17942                 }
  17943             }
  17944         }
  17945         csize = SOC_CTR_MAP_SIZE(unit, ctype) - 1;
  17946         for (; csize > 0; csize--) {
  17947             reg = SOC_CTR_TO_REG(unit, ctype, csize);
  17948             if (SOC_COUNTER_INVALID(unit, reg)) {
  17949                 continue;                       /* skip trailing invalids */
  17950             }
  17951             offset = SOC_REG_INFO(unit, reg).offset;
  17952             csize = SOC_REG_IS_64(unit, reg) ?
  17953                 sizeof(uint64) : sizeof(uint32);
  17954             csize = (soc->counter_portsize / csize) - 1;
  17955             if (ctype == SOC_CTR_TYPE_HG) {
  17956                 if (offset > cireg_last) {
  17957                     cireg_last = offset;
  17958                     if (cireg_last > cireg_first + csize) {
  17959                         cireg_last = cireg_first + csize;
  17960                     }
  17961                 }
  17962             } else {
  17963                 if (offset > creg_last) {
  17964                     creg_last = offset;
  17965                     if (creg_last > creg_first + csize) {
  17966                         creg_last = creg_first + csize;
  17967                     }
  17968                 }
  17969             }
  17970             break;
  17971         }
  17972     }
  17973 
  17974     /*
  17975      * Set the various configuration registers
  17976      */
  17977 #ifdef BCM_HERCULES_SUPPORT
  17978     if (SOC_IS_HERCULES15(unit)) {
  17979         val = 0;
  17980         creg_first = cireg_first;
  17981         creg_last = cireg_last;
  17982         soc_reg_field_set(unit, CMIC_64BIT_STATS_CFGr, &val,
  17983                           L_STAT_REGf, creg_last);
  17984         soc_reg_field_set(unit, CMIC_64BIT_STATS_CFGr, &val,
  17985                           F_STAT_REGf, creg_first);
  17986         WRITE_CMIC_64BIT_STATS_CFGr(unit, val);
  17987     } else {
  17988         val = 0;
  17989         soc_reg_field_set(unit, CMIC_STAT_DMA_SETUPr, &val,
  17990                           L_STAT_REGf, creg_last);
  17991         soc_reg_field_set(unit, CMIC_STAT_DMA_SETUPr, &val,
  17992                           F_STAT_REGf, creg_first);
  17993         WRITE_CMIC_STAT_DMA_SETUPr(unit, val);
  17994     }
  17995 #endif
  17996     WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_ITER_DONE_CLR);
  17997 
  17998 
  17999 #ifdef BCM_CMICM_SUPPORT
  18000         if(soc_feature(unit, soc_feature_cmicm)) {
  18001             soc_cmicm_intr0_enable(unit, IRQ_CMCx_STAT_ITER_DONE);
  18002         } else
  18003 #endif
  18004         {
  18005             soc_intr_enable(unit, IRQ_STAT_ITER_DONE);
  18006         }
  18007 
  18008     return SOC_E_NONE;
  18009 }
  18010 #endif /*BCM_XGS_SUPPORT*/
  18011 /*
  18012  * Function:
  18013  *      soc_counter_thread
  18014  * Purpose:
  18015  *      Master counter collection and accumulation thread.
  18016  * Parameters:
  18017  *      unit_vp - StrataSwitch unit # (as a void *).
  18018  * Returns:
  18019  *      Nothing, does not return.
  18020  */
  18021 
  18022 void
  18023 soc_counter_thread(void *unit_vp)
  18024 {
  18025     int                 unit = PTR_TO_INT(unit_vp);
  18026     soc_control_t       *soc = SOC_CONTROL(unit);
  18027     int                 rv = SOC_E_NONE;
  18028     int                 interval;
  18029 #if defined(WRITE_CMIC_DMA_STATr) || (defined(BCM_CMICM_SUPPORT) && defined(BCM_ESW_SUPPORT))
  18030     uint32              val;
  18031 #endif
  18032     int                 dma;
  18033     sal_usecs_t         cdma_timeout, now;
  18034     COUNTER_ATOMIC_DEF  s = SOC_CONTROL(unit);
  18035     int                 sync_gnt = FALSE;
  18036     int                 i;
  18037     soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit);
  18038 #if defined(BCM_ESW_SUPPORT)
  18039 #ifdef BCM_CMICM_SUPPORT
  18040     int cmc = SOC_PCI_CMC(unit);
  18041 #endif
  18042 #endif
  18043 #if defined(BCM_XGS3_SWITCH_SUPPORT) || defined(BCM_ESW_SUPPORT)
  18044     static int          _stat_err[SOC_MAX_NUM_DEVICES] = {0};
  18045 #endif
  18046 #ifdef BCM_SBUSDMA_SUPPORT
  18047     soc_timeout_t       to;
  18048     int                 timer_started = 0;
  18049 #endif
  18050 #ifdef BCM_TRIDENT2_SUPPORT
  18051     int                 age_sync = FALSE;
  18052 #endif
  18053 
  18054     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  18055              (BSL_META_U(unit,
  18056                          "soc_counter_thread: unit=%d\n"), unit));
  18057 
  18058     DNXC_MTA(dnxc_multithread_analyzer_declare_api_in_play(unit, __FUNCTION__, MTA_FLAG_THREAD_MAIN_FUNC, TRUE));
  18059 
  18060     /*
  18061      * Create a semaphore used to time the trigger scans, and if DMA is
  18062      * used, monitor for the Stats DMA Iteration Done interrupt.
  18063      */
  18064     cdma_timeout = soc_property_get(unit, spn_CDMA_TIMEOUT_USEC, 1000000);
  18065 
  18066     dma = ((soc->counter_flags & SOC_COUNTER_F_DMA) != 0);
  18067 
  18068 #ifdef BCM_DNX_SUPPORT
  18069     while(SOC_WARM_BOOT(unit) && SOC_IS_DNX(unit))
  18070     {
  18071         /** Busy wait */
  18072         sal_usleep(10000);
  18073     }
  18074 
  18075     if(SOC_IS_DNX(unit))
  18076     {
  18077         DNX_ERR_RECOVERY_UTILS_EXCLUDED_THREAD_ADD(unit);
  18078     }
  18079 #endif /*BCM_DNX_SUPPORT*/
  18080 
  18081     if (dma) {
  18082 #ifdef BCM_XGS_SUPPORT
  18083         rv = _soc_counter_dma_setup(unit);
  18084 #endif /* BCM_XGS_SUPPORT */
  18085         if (rv < 0) {
  18086             goto done;
  18087         }
  18088     }
  18089 
  18090     /*
  18091      * The hardware timer can only be used for intervals up to about
  18092      * 1.048 seconds.  This implementation uses a software timer (via
  18093      * semaphore timeout) instead of the hardware timer.
  18094      */
  18095 
  18096     while ((interval = soc->counter_interval) != 0) {
  18097 #ifdef COUNTER_BENCH
  18098         sal_usecs_t     start_time;
  18099 #endif
  18100         int             err = 0;
  18101 
  18102         /*
  18103          * Use a semaphore timeout instead of a sleep to achieve the
  18104          * desired delay between scans.  This allows this thread to exit
  18105          * immediately when soc_counter_stop wants it to.
  18106          */
  18107 
  18108         LOG_DEBUG(BSL_LS_SOC_COUNTER,
  18109                     (BSL_META_U(unit,
  18110                                 "soc_counter_thread: sleep %d\n"), interval));
  18111 
  18112         (void)sal_sem_take(soc->counter_trigger, interval);
  18113 
  18114         if (soc->counter_interval == 0) {       /* Exit signaled */
  18115             break;
  18116         }
  18117 
  18118 #ifdef BCM_TRIDENT2_SUPPORT
  18119         if (soc->l2x_sw_aging && soc->l2x_age_sync != NULL) {
  18120             sal_sem_take(soc->l2x_age_sync, sal_sem_FOREVER);
  18121             age_sync = TRUE;
  18122         }
  18123 #endif
  18124 
  18125         if (soc->counter_sync_req) {
  18126             sync_gnt = TRUE;
  18127         }
  18128 
  18129 #ifdef COUNTER_BENCH
  18130         start_time = sal_time_usecs();
  18131 #endif
  18132 
  18133 
  18134         /*
  18135          * If in DMA mode, use DMA to transfer the counters into
  18136          * memory.  Start a DMA pass by enabling DMA and clearing
  18137          * STAT_DMA_DONE bit.  Wait for the pass to finish.
  18138          */
  18139         COUNTER_LOCK(unit);
  18140 
  18141 #ifdef BCM_SBUSDMA_SUPPORT
  18142         if (dma && soc_feature(unit, soc_feature_sbusdma)) {
  18143             uint8 i;
  18144             int ret;
  18145             soc_port_t port;
  18146             int blk, bindex, phy_port;
  18147 
  18148             PBMP_ITER(soc->counter_pbmp, port) {
  18149                 if (soc_feature(unit, soc_feature_logical_port_num)) {
  18150                     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  18151                 } else {
  18152                     phy_port = port;
  18153                 }
  18154 #ifdef BCM_KATANA2_SUPPORT
  18155                 if (SOC_IS_KATANA2(unit)) {
  18156                     if (!SOC_PORT_VALID(unit, phy_port)) {
  18157                         continue;
  18158                     }
  18159                 }
  18160 #endif
  18161                 blk = SOC_PORT_BLOCK(unit, phy_port);
  18162                 bindex = SOC_PORT_BINDEX(unit, phy_port);
  18163                 if (SOC_IS_MONTEREY(unit)) {
  18164                     if ( ((phy_port > 0) && (phy_port < 13)) || 
  18165                        ((phy_port > 52) && (phy_port < 65))) { 
  18166                         blk = SOC_PORT_IDX_BLOCK(unit, phy_port,1);
  18167                         bindex = SOC_PORT_IDX_BINDEX(unit, phy_port,1);
  18168                     }   
  18169                 }
  18170                 if (_soc_port_counter_handles[unit][phy_port][0] && soc->counter_interval) {
  18171                     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  18172                              (BSL_META_U(unit,
  18173                                          "port: %d blk: %d, bindex: %d\n"),
  18174                               port, blk, bindex));
  18175                 }
  18176                 for (i=0; i<=(COUNTER_SBUSDMA_DESC_SIZE-1); i++) {
  18177                     if ((i == 2) &&
  18178                         (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT) &&
  18179                          !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORTB0) &&
  18180                          !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XTPORT) &&
  18181                          !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XWPORT) &&
  18182                          !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_MXQPORT) &&
  18183                          !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GPORT) &&
  18184                          !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GXPORT) &&
  18185                          !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLPORT) &&
  18186                          !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLG2PORT) &&
  18187                          !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CDPORT))) {
  18188                         break;
  18189                     }
  18190 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  18191                     if (i == 3) {
  18192                         if (!(SOC_IS_GREYHOUND2(unit) || SOC_IS_MONTEREY(unit))) {
  18193                             continue;
  18194                         }
  18195                         if (SOC_IS_GREYHOUND2(unit) &&
  18196                             (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT))) {
  18197                         continue;
  18198                     }
  18199                     }
  18200 #endif
  18201                     if (_soc_port_counter_handles[unit][phy_port][i] && soc->counter_interval) {
  18202                         do {
  18203                             ret = soc_sbusdma_desc_run(unit, _soc_port_counter_handles[unit][phy_port][i]);
  18204                             if ((ret == SOC_E_BUSY) || (ret == SOC_E_INIT)) {
  18205                                 if (ret == SOC_E_INIT) {
  18206                                     /* sbus dma thread not running!! */
  18207                                     break;
  18208                                 }
  18209 
  18210                                 /*
  18211                                  * timeout if sbus dma has been busy
  18212                                  * for too long.
  18213                                  */
  18214                                 if (!timer_started) {
  18215                                  soc_timeout_init(&to, 2 * cdma_timeout, 0);
  18216                                     timer_started = 1;
  18217                                 }
  18218 
  18219                                 if (soc_timeout_check(&to)) {
  18220                                     LOG_WARN(BSL_LS_SOC_COMMON,
  18221                                              (BSL_META_U(unit,
  18222                                                          "Counters read operation timedout\n")));
  18223                                     break;
  18224                                 }
  18225                                 COUNTER_UNLOCK(unit);
  18226                                 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 100);
  18227                                 COUNTER_LOCK(unit);
  18228                             } else {
  18229                                 COUNTER_ATOMIC_BEGIN(s);
  18230                                 _soc_counter_pending[unit]++;
  18231                                 COUNTER_ATOMIC_END(s);
  18232                             }
  18233                         } while(((ret == SOC_E_BUSY) || (ret == SOC_E_INIT)) && 
  18234                                 _soc_port_counter_handles[unit][phy_port][i] &&
  18235                                 soc->counter_interval);
  18236 
  18237                         if (timer_started) {
  18238                             timer_started = 0;
  18239                         }
  18240                     } else {
  18241                         if (soc->counter_interval == 0) {   /* Exit signaled */
  18242                             break;
  18243                         }
  18244                     }
  18245                 }
  18246             }
  18247 
  18248             if (soc->blk_ctr_desc_count && soc->counter_interval) {
  18249                 for (i=0; i<soc->blk_ctr_desc_count; i++) {
  18250                     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  18251                              (BSL_META_U(unit,
  18252                                          "blk ctr %d\n"), i));
  18253                     if (_soc_blk_counter_handles[unit][i] && soc->counter_interval) {
  18254                         do {
  18255                             ret = soc_sbusdma_desc_run(unit, _soc_blk_counter_handles[unit][i]);
  18256                             if ((ret == SOC_E_BUSY) || (ret == SOC_E_INIT)) {
  18257                                 COUNTER_UNLOCK(unit);
  18258                                 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10);
  18259                                 COUNTER_LOCK(unit);
  18260                             }
  18261                         } while(((ret == SOC_E_BUSY) || (ret == SOC_E_INIT)) && soc->counter_interval);
  18262                     } else {
  18263                         if (soc->counter_interval == 0) {   /* Exit signaled */
  18264                             break;
  18265                         }
  18266                     }
  18267                 }
  18268             }
  18269             if (soc->counter_interval == 0) {   /* Exit signaled */
  18270                 COUNTER_UNLOCK(unit);
  18271                 break;
  18272             }
  18273         }
  18274 #endif
  18275         if (dma && !soc_feature(unit, soc_feature_sbusdma)) {
  18276             LOG_DEBUG(BSL_LS_SOC_COUNTER,
  18277                         (BSL_META_U(unit,
  18278                                     "soc_counter_thread: trigger DMA\n")));
  18279 
  18280 #ifdef BCM_CMICM_SUPPORT
  18281 #if defined(BCM_ESW_SUPPORT)
  18282 
  18283             if(soc_feature(unit, soc_feature_cmicm)) {
  18284                 /* Clear Status */
  18285                 val = soc_pci_read(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc));
  18286                 soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val,
  18287                                   ENf, 0);
  18288                 soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val,
  18289                                   ST_DMA_ITER_DONE_CLRf, 0);
  18290                 soc_pci_write(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc), val);
  18291                 /* start DMA */
  18292                 soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val,
  18293                                   ENf, 1);
  18294                 soc_pci_write(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc), val);
  18295             } else
  18296 #endif
  18297 #endif
  18298             {
  18299                 /* Clear Status and start DMA */
  18300 #ifdef WRITE_CMIC_DMA_STATr
  18301                 WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_DONE_CLR);
  18302                 READ_CMIC_STAT_DMA_SETUPr(unit, &val);
  18303                 soc_reg_field_set(unit, CMIC_STAT_DMA_SETUPr, &val,
  18304                                   ENf, 1);
  18305                 WRITE_CMIC_STAT_DMA_SETUPr(unit, val);
  18306 #endif
  18307             }
  18308             /* Wait for ISR to wake semaphore */
  18309 #ifdef BCM_CMICM_SUPPORT
  18310             if(soc_feature(unit, soc_feature_cmicm)) {
  18311                 if (sal_sem_take(soc->counter_intr, cdma_timeout) >= 0) {
  18312                     soc_cm_sinval(unit,
  18313                                   (void *)soc->counter_buf32,
  18314                                   soc->counter_bufsize);
  18315 
  18316                     LOG_DEBUG(BSL_LS_SOC_COUNTER,
  18317                                 (BSL_META_U(unit,
  18318                                             "soc_counter_thread: "
  18319                                             "DMA iter done\n")));
  18320 
  18321 #ifdef COUNTER_BENCH
  18322                     LOG_DEBUG(BSL_LS_SOC_COMMON,
  18323                                 (BSL_META_U(unit,
  18324                                             "Time taken for dma: %d usec\n"),
  18325                                  SAL_USECS_SUB(sal_time_usecs(), start_time)));
  18326 #endif
  18327                 } else {
  18328                     LOG_ERROR(BSL_LS_SOC_COMMON,
  18329                               (BSL_META_U(unit,
  18330                                           "soc_counter_thread: "
  18331                                           "DMA did not finish buf32=%p\n"),
  18332                                (void *)soc->counter_buf32));
  18333                     err = 1;
  18334                 }
  18335 #if defined(BCM_ESW_SUPPORT)
  18336 
  18337                 if (soc_pci_read(unit, CMIC_CMCx_STAT_DMA_STAT_OFFSET(cmc)) & ST_CMCx_DMA_ERR) {
  18338                     LOG_ERROR(BSL_LS_SOC_COMMON,
  18339                               (BSL_META_U(unit,
  18340                                           "soc_counter_thread: unit = %d DMA Error\n"),
  18341                                unit));
  18342                     if (soc_ser_stat_error(unit, -1) != SOC_E_NONE) {
  18343                         _stat_err[unit]++;
  18344                         /* Error is reported atleast one more time after correction.
  18345                            So try few times and abort if correction really fails */
  18346                         if (_stat_err[unit] > 10) {
  18347                             err = 1;
  18348                         }
  18349                     } else {
  18350                         _stat_err[unit] = 0;
  18351                     }
  18352                 }
  18353 #endif
  18354             } else
  18355 #endif /* CMICm Support */
  18356             {
  18357                 if (sal_sem_take(soc->counter_intr, cdma_timeout) >= 0) {
  18358                     soc_cm_sinval(unit,
  18359                                   (void *)soc->counter_buf32,
  18360                                   soc->counter_bufsize);
  18361 
  18362                     LOG_DEBUG(BSL_LS_SOC_COUNTER,
  18363                                 (BSL_META_U(unit,
  18364                                             "soc_counter_thread: "
  18365                                             "DMA iter done\n")));
  18366 
  18367 #ifdef COUNTER_BENCH
  18368                     LOG_DEBUG(BSL_LS_SOC_COMMON,
  18369                                 (BSL_META_U(unit,
  18370                                             "Time taken for dma: %d usec\n"),
  18371                                  SAL_USECS_SUB(sal_time_usecs(), start_time)));
  18372 #endif
  18373                 } else {
  18374                     LOG_ERROR(BSL_LS_SOC_COMMON,
  18375                               (BSL_META_U(unit,
  18376                                           "soc_counter_thread: "
  18377                                           "DMA did not finish buf32=%p\n"),
  18378                                (void *)soc->counter_buf32));
  18379                     err = 1;
  18380                 }
  18381 #ifdef BCM_XGS3_SWITCH_SUPPORT
  18382                 if (SOC_IS_XGS3_SWITCH(unit)) {
  18383                     if (soc_pci_read(unit, CMIC_DMA_STAT) & DS_STAT_DMA_ERROR) {
  18384                         WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_DONE_CLR);
  18385                         if (soc_feature(unit, soc_feature_stat_dma_error_ack)) {
  18386                             WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_ERROR_CLR - 1);
  18387                         } else {
  18388                             WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_ERROR_CLR);
  18389                         }
  18390                         LOG_ERROR(BSL_LS_SOC_COMMON,
  18391                                   (BSL_META_U(unit,
  18392                                               "soc_counter_thread: unit = %d DMA Error\n"),
  18393                                    unit));
  18394                         if (soc_ser_stat_error(unit, -1) != SOC_E_NONE) {
  18395                             _stat_err[unit]++;
  18396                             /* Error is reported atleast one more time after correction.
  18397                                So try few times and abort if correction really fails */
  18398                             if (_stat_err[unit] > 10) {
  18399                                 err = 1;
  18400                                 _stat_err[unit] = 0;
  18401                             }
  18402                         } else {
  18403                             _stat_err[unit] = 0;
  18404                         }
  18405                     }
  18406                 }
  18407 #endif
  18408             }
  18409             if (soc->counter_interval == 0) {   /* Exit signaled */
  18410                 COUNTER_UNLOCK(unit);
  18411                 break;
  18412             }
  18413         }
  18414 
  18415         /*
  18416          * Add up changes to counter values.
  18417          */
  18418 
  18419 #ifdef BCM_SBUSDMA_SUPPORT
  18420         while (_soc_counter_pending[unit] && soc->counter_interval) {
  18421             COUNTER_UNLOCK(unit);
  18422             sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 100);
  18423             COUNTER_LOCK(unit);
  18424         }
  18425 #endif
  18426 
  18427         now = sal_time_usecs();
  18428         COUNTER_ATOMIC_BEGIN(s);
  18429         soc->counter_coll_prev = soc->counter_coll_cur;
  18430         soc->counter_coll_cur = now;
  18431         COUNTER_ATOMIC_END(s);
  18432 
  18433         if ( (!err) && (soc->counter_n32 > 0) && (soc->counter_interval) ) {
  18434             rv = soc_counter_collect32(unit, FALSE);
  18435             if (rv < 0) {
  18436                 LOG_ERROR(BSL_LS_SOC_COMMON,
  18437                           (BSL_META_U(unit,
  18438                                       "soc_counter_thread: collect32 failed: %s\n"),
  18439                            soc_errmsg(rv)));
  18440                 err = 1;
  18441             }
  18442         }
  18443 
  18444         if ((!err) && (soc->counter_n64 > 0) && (soc->counter_interval) ) {
  18445             if(SOC_IS_SAND(unit)) {
  18446                 if (SOC_IS_ARAD(unit)) {
  18447 #ifdef BCM_PETRA_SUPPORT
  18448                     rv = soc_counter_collect64(unit, FALSE, -1, INVALIDr);
  18449 #endif
  18450                 } else {
  18451                     rv = SOC_E_NONE;
  18452                 }
  18453             } else {
  18454 #ifdef BCM_XGS_SUPPORT
  18455                 rv = soc_counter_collect64(unit, FALSE, -1, INVALIDr);
  18456 #endif
  18457             }
  18458 
  18459             if (rv < 0) {
  18460                 LOG_ERROR(BSL_LS_SOC_COMMON,
  18461                           (BSL_META_U(unit,
  18462                                       "soc_counter_thread: collect64 failed: "
  18463                                       "%s\n"), soc_errmsg(rv)));
  18464                 err = 1;
  18465             }
  18466         }
  18467 
  18468         /* soc_counter_collect64 could trigger thread schedule */
  18469         if (!(soc->counter_interval)) {
  18470             COUNTER_UNLOCK(unit);
  18471             break;
  18472         }
  18473 
  18474         if ((soc->counter_interval)) {
  18475             soc_controlled_counters_collect64(unit, FALSE);
  18476             if (rv < 0) {
  18477                 LOG_ERROR(BSL_LS_SOC_COMMON,
  18478                           (BSL_META_U(unit,
  18479                                       "soc_counter_thread: soc_controlled_counters_collect64 failed: "
  18480                                       "%s\n"), soc_errmsg(rv)));
  18481                 err = 1;
  18482             }
  18483         }
  18484 
  18485         /* soc_controlled_counters_collect64 could trigger thread schedule */
  18486         if (!(soc->counter_interval)) {
  18487             COUNTER_UNLOCK(unit);
  18488             break;
  18489         }
  18490 
  18491         /*
  18492          * Check optional non CMIC counter DMA support entries
  18493          * These counters are included in "show counter" output
  18494          */
  18495         if ((soc->counter_interval)) {
  18496             if(soc_ctr_ctrl->collect_non_stat_dma) {
  18497                 soc_ctr_ctrl->collect_non_stat_dma(unit, -1, -1, -1, -1);
  18498             }
  18499         }
  18500 
  18501         COUNTER_UNLOCK(unit);
  18502 
  18503         /* soc_counter_collect_non_dma_entries could trigger thread schedule */
  18504         if (!(soc->counter_interval)) {
  18505             break;
  18506         }
  18507 
  18508         /*
  18509          * Callback for additional work
  18510          * These counters are not included in "show counter" output
  18511          */
  18512         for (i = 0; i < SOC_COUNTER_EXTRA_CB_MAX; i++) {
  18513             if (soc_counter_extra[unit][i] != NULL) {
  18514                 soc_counter_extra[unit][i](unit);
  18515             }
  18516 
  18517             /* soc_counter_extra could trigger thread schedule */
  18518             if (!(soc->counter_interval)) {
  18519                 if (err) {
  18520                     rv = SOC_E_INTERNAL;
  18521                 }
  18522                 goto done;
  18523             }
  18524         }
  18525 
  18526 #ifdef BCM_TRIDENT2_SUPPORT
  18527         if (age_sync) {
  18528             sal_sem_give(soc->l2x_age_sync);
  18529             age_sync = FALSE;
  18530         }
  18531 #endif
  18532 
  18533         /*
  18534          * Forgive spurious errors
  18535          */
  18536 
  18537         if (err) {
  18538                 LOG_ERROR(BSL_LS_SOC_COMMON,
  18539                           (BSL_META_U(unit,
  18540                                       "AbnormalThreadExit:"
  18541                                       "soc_counter_thread: Too many errors\n")));
  18542                 rv = SOC_E_INTERNAL;
  18543                 goto done;
  18544             }
  18545 
  18546 #ifdef COUNTER_BENCH
  18547         LOG_DEBUG(BSL_LS_SOC_COMMON,
  18548                     (BSL_META_U(unit,
  18549                                 "Iteration time: %d usec\n"),
  18550                      SAL_USECS_SUB(sal_time_usecs(), start_time)));
  18551 #endif
  18552 
  18553         if (sync_gnt) {
  18554             soc->counter_sync_req = 0;
  18555             sync_gnt = 0;
  18556         }
  18557     }
  18558 
  18559     rv = SOC_E_NONE;
  18560 
  18561  done:
  18562 #ifdef BCM_TRIDENT2_SUPPORT
  18563         if (age_sync) {
  18564             sal_sem_give(soc->l2x_age_sync);
  18565         }
  18566 #endif
  18567 
  18568     if (rv < 0) {
  18569         LOG_ERROR(BSL_LS_SOC_COMMON,
  18570                   (BSL_META_U(unit,
  18571                               "soc_counter_thread: Operation failed - exiting\n")));
  18572         soc_event_generate(unit, SOC_SWITCH_EVENT_THREAD_ERROR,
  18573                            SOC_SWITCH_EVENT_THREAD_COUNTER, __LINE__, rv);
  18574     }
  18575 
  18576     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  18577              (BSL_META_U(unit,
  18578                          "soc_counter_thread: exiting\n")));
  18579 
  18580     soc->counter_pid = SAL_THREAD_ERROR;
  18581     soc->counter_interval = 0;
  18582 
  18583     DNXC_MTA(dnxc_multithread_analyzer_declare_api_in_play(unit, __FUNCTION__, MTA_FLAG_THREAD_MAIN_FUNC, FALSE));
  18584 
  18585 #ifdef BCM_DNX_SUPPORT
  18586     if(SOC_IS_DNX(unit))
  18587     {
  18588         DNX_ERR_RECOVERY_UTILS_EXCLUDED_THREAD_REMOVE(unit);
  18589     }
  18590 #endif
  18591 
  18592     sal_thread_exit(0);
  18593 }
  18594 
  18595 /*
  18596  * Function:
  18597  *      soc_counter_start
  18598  * Purpose:
  18599  *      Start the counter collection, S/W accumulation process.
  18600  * Parameters:
  18601  *      unit - StrataSwitch unit #.
  18602  *      flags - SOC_COUNTER_F_xxx flags.
  18603  *      interval - collection period in micro-seconds.
  18604  *              Using 0 is the same as calling soc_counter_stop().
  18605  *      pbmp - bit map of ports to collact counters on.
  18606  * Returns:
  18607  *      SOC_E_XXX
  18608  */
  18609 int
  18610 soc_counter_start(int unit, uint32 flags, int interval, pbmp_t pbmp)
  18611 {
  18612     soc_control_t       *soc = SOC_CONTROL(unit);
  18613     char                pfmt[SOC_PBMP_FMT_LEN];
  18614     int         rv = SOC_E_NONE;
  18615     soc_port_t          p;
  18616     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  18617              (BSL_META_U(unit,
  18618                          "soc_counter_start: unit=%d flags=0x%x "
  18619                          "interval=%d pbmp=%s\n"),
  18620               unit, flags, interval, SOC_PBMP_FMT(pbmp, pfmt)));
  18621 
  18622     /* Stop if already running */
  18623 #ifdef ADAPTER_SERVER_MODE
  18624 #ifndef BCM_DNX_SUPPORT
  18625     return SOC_E_NONE;
  18626 #endif
  18627 #endif /* ADAPTER_SERVER_MODE */
  18628     if (soc->counter_interval != 0) {
  18629         SOC_IF_ERROR_RETURN(soc_counter_stop(unit));
  18630     }
  18631 
  18632     if (interval == 0) {
  18633         return SOC_E_NONE;
  18634     }
  18635 
  18636     /*
  18637      * Create fresh semaphores
  18638      * Semaphore already existing means other thread still holds it.
  18639      * Unexpected results could happen if we mandatorily destroy it here.
  18640      * So we need to retry soc_counter_stop(). If fail, then warn and return.
  18641      */
  18642 
  18643     if ((soc->counter_trigger != NULL || soc->counter_intr != NULL) &&
  18644         (rv = soc_counter_stop(unit)) != SOC_E_NONE) {
  18645         LOG_ERROR(BSL_LS_SOC_COMMON,
  18646                   (BSL_META_U(unit,
  18647                               "soc_counter_start: sem unexpectedly survives\n")));
  18648         return SOC_E_INTERNAL;
  18649     }
  18650 
  18651     soc->counter_trigger =
  18652         sal_sem_create("counter_trigger", sal_sem_BINARY, 0);
  18653 
  18654     soc->counter_intr =
  18655         sal_sem_create("counter_intr", sal_sem_BINARY, 0);
  18656 
  18657     if (soc->counter_trigger == NULL || soc->counter_intr == NULL) {
  18658         LOG_ERROR(BSL_LS_SOC_COMMON,
  18659                   (BSL_META_U(unit,
  18660                               "soc_counter_start: sem create failed\n")));
  18661         return SOC_E_INTERNAL;
  18662     }
  18663 
  18664     /* Create fresh lock */
  18665     if (soc->counter_lock != NULL) {
  18666         sal_spinlock_destroy(soc->counter_lock);
  18667         soc->counter_lock = NULL;
  18668     }
  18669 
  18670     soc->counter_lock = sal_spinlock_create("counter spinlock");
  18671 
  18672     if (soc->counter_lock == NULL) {
  18673         LOG_ERROR(BSL_LS_SOC_COMMON,
  18674                   (BSL_META_U(unit,
  18675                               "soc_counter_start: lock create failed\n")));
  18676         return SOC_E_INTERNAL;
  18677     }
  18678 
  18679     sal_snprintf(soc->counter_name,
  18680                  sizeof(soc->counter_name),
  18681                  "bcmCNTR.%d", unit);
  18682 
  18683     SOC_PBMP_ASSIGN(soc->counter_pbmp, pbmp);
  18684     PBMP_ITER(soc->counter_pbmp, p) {
  18685         if ((SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), p))) {
  18686             SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, p);
  18687         }
  18688         if (IS_LB_PORT(unit, p)) {
  18689             SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, p);
  18690         }
  18691     }
  18692     soc->counter_flags = flags;
  18693 
  18694     soc->counter_flags &= ~SOC_COUNTER_F_SWAP64; /* HW takes care of this */
  18695 
  18696     if (!soc_feature(unit, soc_feature_stat_dma) || SOC_IS_RCPU_ONLY(unit)) {
  18697         soc->counter_flags &= ~SOC_COUNTER_F_DMA;
  18698     }
  18699 
  18700     /*
  18701      * The HOLD register is not supported by DMA on HUMV/Bradley,
  18702      * but in order to allow certain test scripts to pass, we
  18703      * optionally collect this register manually.
  18704      */
  18705 
  18706 #ifdef BCM_BRADLEY_SUPPORT
  18707     soc->counter_flags &= ~SOC_COUNTER_F_HOLD;
  18708 
  18709     if (SOC_IS_HBX(unit)) {
  18710         if (soc_property_get(unit, spn_CDMA_PIO_HOLD_ENABLE, 1)) {
  18711             soc->counter_flags |= SOC_COUNTER_F_HOLD;
  18712         }
  18713     }
  18714 #endif /* BCM_BRADLEY_SUPPORT */
  18715 
  18716 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT)
  18717     if (soc_feature(unit, soc_feature_bigmac_rxcnt_bug)) {
  18718         /* Allocate buffer for DMA counter validation */
  18719         soc_counter_tbuf[unit] = sal_alloc(SOC_COUNTER_TBUF_SIZE(unit),
  18720                                            "counter_tbuf");
  18721         if (soc_counter_tbuf[unit] == NULL) {
  18722             LOG_ERROR(BSL_LS_SOC_COMMON,
  18723                       (BSL_META_U(unit,
  18724                                   "soc_counter_thread: unit %d: "
  18725                                   "failed to allocate temp counter buffer\n"),
  18726                        unit));
  18727         }
  18728     }
  18729 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */
  18730 
  18731     SOC_IF_ERROR_RETURN(soc_counter_autoz(unit, 0));
  18732 
  18733     /* Synchronize counter 'prev' values with current hardware counters */
  18734 
  18735     soc->counter_coll_prev = soc->counter_coll_cur = sal_time_usecs();
  18736 
  18737     if (soc->counter_n32 > 0) {
  18738         COUNTER_LOCK(unit);
  18739         rv = soc_counter_collect32(unit, TRUE);
  18740         COUNTER_UNLOCK(unit);
  18741         SOC_IF_ERROR_RETURN(rv);
  18742     }
  18743 
  18744     if (soc->counter_n64 > 0) {
  18745         COUNTER_LOCK(unit);
  18746         if(SOC_IS_SAND(unit)) {
  18747                 rv = SOC_E_NONE;
  18748         } else {
  18749 #if defined(BCM_XGS_SUPPORT)
  18750             rv = soc_counter_collect64(unit,FALSE, -1, INVALIDr);
  18751 #endif
  18752         }
  18753         COUNTER_UNLOCK(unit);
  18754         SOC_IF_ERROR_RETURN(rv);
  18755     }
  18756 
  18757 #if defined (BCM_DNX_SUPPORT) || defined (BCM_DNXF_SUPPORT)
  18758     /*
  18759      * Temporarily allow DBAL writes for current thread even if it's generally disabled.
  18760      */
  18761     if (SOC_IS_DNX(unit) || SOC_IS_DNXF(unit)) 
  18762     {
  18763         rv = dnxc_ha_tmp_allow_access_enable(unit, DNXC_HA_ALLOW_DBAL);
  18764         SOC_IF_ERROR_RETURN(rv);
  18765     }
  18766 #endif /*BCM_DNX_SUPPORT*/
  18767 
  18768     soc_controlled_counters_collect64(unit, TRUE);
  18769 
  18770 #if defined (BCM_DNX_SUPPORT) || defined (BCM_DNXF_SUPPORT)
  18771     /*
  18772      * revert dnxc_allow_hw_write_enable.
  18773      */
  18774     if (SOC_IS_DNX(unit) || SOC_IS_DNXF(unit)) 
  18775     {
  18776         rv = dnxc_ha_tmp_allow_access_disable(unit, DNXC_HA_ALLOW_DBAL);
  18777     }
  18778 #endif /*BCM_DNX_SUPPORT*/
  18779 
  18780     /* Start the thread */
  18781 
  18782     if (interval != 0) {
  18783         soc->counter_interval = interval;
  18784 
  18785         soc->counter_pid =
  18786             sal_thread_create(soc->counter_name,
  18787                               SAL_THREAD_STKSZ,
  18788                               soc_property_get(unit,
  18789                                                spn_COUNTER_THREAD_PRI,
  18790                                                _SOC_CTR_THREAD_PRI),
  18791                               soc_counter_thread, INT_TO_PTR(unit));
  18792 
  18793         if (soc->counter_pid == SAL_THREAD_ERROR) {
  18794             soc->counter_interval = 0;
  18795             LOG_ERROR(BSL_LS_SOC_COMMON,
  18796                       (BSL_META_U(unit,
  18797                                   "soc_counter_start: thread create failed\n")));
  18798             return (SOC_E_INTERNAL);
  18799         }
  18800 
  18801         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  18802                  (BSL_META_U(unit,
  18803                              "soc_counter_start: complete\n")));
  18804     }
  18805 #ifdef BCM_TOMAHAWK_SUPPORT
  18806     if ((soc_feature(unit, soc_feature_counter_eviction)) &&
  18807         (!SOC_WARM_BOOT(unit))) {
  18808         /* During WB, eviction will be enabled post WB init */
  18809         SOC_IF_ERROR_RETURN(soc_ctr_evict_start(unit, 0, interval));
  18810     }
  18811 #endif /* BCM_TOMAHAWK_SUPPORT */
  18812 
  18813 
  18814     return (SOC_E_NONE);
  18815 }
  18816 
  18817 
  18818 
  18819 /*
  18820  * Function:
  18821  *      soc_counter_port_collect_enable_set
  18822  * Purpose:
  18823  *      Enable/disable the gathering of MIB statistics on this port.
  18824  * Parameters:
  18825  *      unit - StrataSwitch unit #.
  18826  *      port - Port number #.
  18827  *      enable: enable/disable the port's mib gathering.
  18828  * Returns:
  18829  *      SOC_E_XXX
  18830  */
  18831 int
  18832 soc_counter_port_collect_enable_set(int unit, int port, int enable)
  18833 {
  18834     soc_control_t       *soc = SOC_CONTROL(unit);
  18835 
  18836     if (IS_LB_PORT(unit, port)) {
  18837         return SOC_E_NONE;
  18838     }
  18839 
  18840     if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) {
  18841         return SOC_E_NONE;
  18842     }
  18843 
  18844     COUNTER_LOCK(unit);
  18845 
  18846     if (enable) {
  18847         SOC_PBMP_PORT_ADD(soc->counter_pbmp,port);
  18848     } else {
  18849         SOC_PBMP_PORT_REMOVE(soc->counter_pbmp,port);
  18850     }
  18851 
  18852     COUNTER_UNLOCK(unit);
  18853 
  18854     return (SOC_E_NONE);
  18855 }
  18856 
  18857 /*
  18858  * Function:
  18859  *      soc_counter_status
  18860  * Purpose:
  18861  *      Get the status of counter collection, S/W accumulation process.
  18862  * Parameters:
  18863  *      unit - StrataSwitch unit #.
  18864  *      flags - SOC_COUNTER_F_xxx flags.
  18865  *      interval - collection period in micro-seconds.
  18866  *      pbmp - bit map of ports to collact counters on.
  18867  * Returns:
  18868  *      SOC_E_XXX
  18869  */
  18870 
  18871 int
  18872 soc_counter_status(int unit, uint32 *flags, int *interval, pbmp_t *pbmp)
  18873 {
  18874     soc_control_t       *soc = SOC_CONTROL(unit);
  18875 
  18876     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  18877              (BSL_META_U(unit,
  18878                          "soc_counter_status: unit=%d\n"), unit));
  18879 
  18880     *interval = soc->counter_interval;
  18881     *flags = soc->counter_flags;
  18882     SOC_PBMP_ASSIGN(*pbmp, soc->counter_pbmp);
  18883 
  18884     return (SOC_E_NONE);
  18885 }
  18886 
  18887 /*
  18888  * Function:
  18889  *      soc_counter_sync
  18890  * Purpose:
  18891  *      Force an immediate counter update
  18892  * Parameters:
  18893  *      unit - StrataSwitch unit #.
  18894  * Returns:
  18895  *      SOC_E_XXX
  18896  * Notes:
  18897  *      Ensures that ALL counter activity that occurred before the sync
  18898  *      is reflected in the results of any soc_counter_get()-type
  18899  *      routine that is called after the sync.
  18900  */
  18901 
  18902 int
  18903 soc_counter_sync(int unit)
  18904 {
  18905     soc_control_t       *soc = SOC_CONTROL(unit);
  18906     soc_timeout_t       to;
  18907     uint32              stat_sync_timeout;
  18908 
  18909     if (soc->counter_interval == 0) {
  18910         return SOC_E_DISABLED;
  18911     }
  18912 
  18913     /* Trigger a collection */
  18914 
  18915     soc->counter_sync_req = TRUE;
  18916 
  18917     sal_sem_give(soc->counter_trigger);
  18918     
  18919 #ifdef BCM_TOMAHAWK_SUPPORT
  18920     if (soc_feature(unit, soc_feature_counter_eviction)) {
  18921         SOC_IF_ERROR_RETURN(soc_counter_eviction_sync(unit));
  18922     }
  18923 #endif /* BCM_TOMAHAWK_SUPPORT */
  18924 
  18925     if (SAL_BOOT_QUICKTURN) {
  18926         stat_sync_timeout = STAT_SYNC_TIMEOUT_QT;
  18927     } else if (SAL_BOOT_BCMSIM) {
  18928         stat_sync_timeout = STAT_SYNC_TIMEOUT_BCMSIM;
  18929     } else if (SOC_IS_RCPU_ONLY(unit)) {
  18930         stat_sync_timeout = STAT_SYNC_TIMEOUT*4;
  18931     } else {
  18932         stat_sync_timeout = STAT_SYNC_TIMEOUT;
  18933     }
  18934     stat_sync_timeout = soc_property_get(unit,
  18935                                          spn_BCM_STAT_SYNC_TIMEOUT,
  18936                                          stat_sync_timeout);
  18937     soc_timeout_init(&to, stat_sync_timeout, 0);
  18938     while (soc->counter_sync_req) {
  18939         if (soc_timeout_check(&to)) {
  18940             if (soc->counter_sync_req) {
  18941                 LOG_ERROR(BSL_LS_SOC_COMMON,
  18942                           (BSL_META_U(unit,
  18943                                       "soc_counter_sync: counter thread not responding\n")));
  18944                 soc->counter_sync_req = FALSE;
  18945                 return SOC_E_TIMEOUT;
  18946             }
  18947         }
  18948 
  18949         sal_usleep(10000);
  18950     }
  18951 
  18952     return SOC_E_NONE;
  18953 }
  18954 
  18955 /*
  18956  * Function:
  18957  *      soc_counter_stop
  18958  * Purpose:
  18959  *      Terminate the counter collection, S/W accumulation process.
  18960  * Parameters:
  18961  *      unit - StrataSwitch unit #.
  18962  * Returns:
  18963  *      SOC_E_XXX
  18964  */
  18965 
  18966 int
  18967 soc_counter_stop(int unit)
  18968 {
  18969     soc_control_t       *soc = SOC_CONTROL(unit);
  18970     int                 rv = SOC_E_NONE;
  18971     soc_timeout_t       to;
  18972     sal_usecs_t         cdma_timeout;
  18973 #ifdef BCM_XGS_SUPPORT
  18974 #ifdef BCM_CMICM_SUPPORT
  18975     int cmc = SOC_PCI_CMC(unit);
  18976 #endif
  18977 #endif
  18978 
  18979     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  18980              (BSL_META_U(unit,
  18981                          "soc_counter_stop: unit=%d\n"), unit));
  18982 
  18983     if (SAL_BOOT_QUICKTURN) {
  18984         cdma_timeout = CDMA_TIMEOUT_QT;
  18985     } else if (SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM) {
  18986         cdma_timeout = CDMA_TIMEOUT_BCMSIM;
  18987     } else if (SOC_IS_RCPU_ONLY(unit)) {
  18988         cdma_timeout = CDMA_TIMEOUT*10;
  18989     } else {
  18990         cdma_timeout = CDMA_TIMEOUT*5;
  18991     }
  18992     cdma_timeout = soc_property_get(unit, spn_CDMA_TIMEOUT_USEC, cdma_timeout);
  18993 
  18994     /* Stop thread if present. */
  18995 
  18996     if (soc->counter_interval != 0) {
  18997         sal_thread_t    sample_pid;
  18998 
  18999         /*
  19000          * Signal by setting interval to 0, and wake up thread to speed
  19001          * its exit.  It may also be waiting for the hardware interrupt
  19002          * semaphore.  Wait a limited amount of time for it to exit.
  19003          */
  19004 
  19005         soc->counter_interval = 0;
  19006 
  19007         sal_sem_give(soc->counter_intr);
  19008         sal_sem_give(soc->counter_trigger);
  19009 
  19010         soc_timeout_init(&to, cdma_timeout, 0);
  19011 
  19012         while ((sample_pid = soc->counter_pid) != SAL_THREAD_ERROR) {
  19013             if (soc_timeout_check(&to)) {
  19014                 LOG_ERROR(BSL_LS_SOC_COMMON,
  19015                           (BSL_META_U(unit,
  19016                                       "soc_counter_stop: thread did not exit\n")));
  19017                 soc->counter_pid = SAL_THREAD_ERROR;
  19018                 rv = SOC_E_TIMEOUT;
  19019                 break;
  19020             }
  19021 
  19022             sal_usleep(10000);
  19023         }
  19024     }
  19025 
  19026 #ifdef BCM_XGS_SUPPORT
  19027     if ((soc->counter_flags & SOC_COUNTER_F_DMA) &&
  19028         !soc_feature(unit, soc_feature_sbusdma)) {
  19029         uint32          val;
  19030 
  19031         /*
  19032          * Disable hardware counter scanning.
  19033          * Turn off all ports to speed up final scan cycle.
  19034          *
  19035          * This cleanup is done here instead of at the end of the
  19036          * counter thread so counter DMA will turn off even if the
  19037          * thread is non responsive.
  19038          */
  19039 
  19040 #ifdef BCM_CMICM_SUPPORT
  19041         if(soc_feature(unit, soc_feature_cmicm)) {
  19042 
  19043             soc_cmicm_intr0_disable(unit, IRQ_CMCx_STAT_ITER_DONE);
  19044 
  19045             val = soc_pci_read(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc));
  19046             soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val, ENf, 0);
  19047             soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val, E_Tf, 0);
  19048             soc_pci_write(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc), val);
  19049             soc_pci_write(unit, CMIC_CMCx_STAT_DMA_PORTS_0_OFFSET(cmc), 0);
  19050             if (SOC_REG_IS_VALID(unit, CMIC_CMC0_STAT_DMA_PORTS_1r)) { 
  19051                 soc_pci_write(unit, CMIC_CMCx_STAT_DMA_PORTS_1_OFFSET(cmc), 0);
  19052             }
  19053             if (SOC_REG_IS_VALID(unit, CMIC_CMC0_STAT_DMA_PORTS_2r)) { 
  19054                 soc_pci_write(unit, CMIC_CMCx_STAT_DMA_PORTS_2_OFFSET(cmc), 0);
  19055             }
  19056         } else
  19057 #endif
  19058         {
  19059 
  19060             soc_intr_disable(unit, IRQ_STAT_ITER_DONE);
  19061 
  19062             READ_CMIC_STAT_DMA_SETUPr(unit, &val);
  19063             soc_reg_field_set(unit, CMIC_STAT_DMA_SETUPr, &val, ENf, 0);
  19064             soc_reg_field_set(unit, CMIC_STAT_DMA_SETUPr, &val, E_Tf, 0);
  19065             WRITE_CMIC_STAT_DMA_SETUPr(unit, val);
  19066             WRITE_CMIC_STAT_DMA_PORTSr(unit, 0);
  19067 #if defined(BCM_RAPTOR_SUPPORT)
  19068             if (soc_feature(unit, soc_feature_register_hi)) {
  19069                 WRITE_CMIC_STAT_DMA_PORTS_HIr(unit, 0);
  19070             }
  19071 #endif /* BCM_RAPTOR_SUPPORT */
  19072 #if defined(BCM_TRIUMPH_SUPPORT)
  19073             if (SOC_IS_TR_VL(unit)) {
  19074                 WRITE_CMIC_STAT_DMA_PORTS_HIr(unit, 0);
  19075             }
  19076 #endif /* BCM_TRIUMPH_SUPPORT */
  19077         }
  19078 
  19079         /*
  19080          * Wait for STAT_DMA_ACTIVE to go away, with a timeout in case
  19081          * it never does.
  19082          */
  19083 
  19084         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  19085                  (BSL_META_U(unit,
  19086                              "soc_counter_stop: waiting for idle\n")));
  19087 
  19088         soc_timeout_init(&to, cdma_timeout, 0);
  19089 #ifdef BCM_CMICM_SUPPORT
  19090         if(soc_feature(unit, soc_feature_cmicm)) {
  19091             while (soc_pci_read(unit, CMIC_CMCx_STAT_DMA_STAT_OFFSET(cmc)) & ST_CMCx_DMA_ACTIVE) {
  19092                 if (soc_timeout_check(&to)) {
  19093                     rv = SOC_E_INTERNAL;
  19094                     break;
  19095                 }
  19096             }
  19097         } else
  19098 #endif
  19099         {
  19100             while (soc_pci_read(unit, CMIC_DMA_STAT) & DS_STAT_DMA_ACTIVE) {
  19101                 if (soc_timeout_check(&to)) {
  19102                     rv = SOC_E_TIMEOUT;
  19103                     break;
  19104                 }
  19105             }
  19106         }
  19107     }
  19108 
  19109 #ifdef BCM_XGS3_SWITCH_SUPPORT
  19110 #ifdef BCM_SBUSDMA_SUPPORT
  19111     if ((soc->counter_flags & SOC_COUNTER_F_DMA) &&
  19112         soc_feature(unit, soc_feature_sbusdma)) {
  19113         int err;
  19114         if ((err = _soc_counter_sbudma_desc_free_all(unit)) != 0) {
  19115             LOG_ERROR(BSL_LS_SOC_COMMON,
  19116                       (BSL_META_U(unit,
  19117                                   "soc_counter_stop: [%d] Desc free error(s)\n"),
  19118                        err));
  19119         }
  19120     }
  19121 #endif
  19122 #endif
  19123 
  19124 #ifdef BCM_BRADLEY_SUPPORT
  19125     if (soc_counter_tbuf[unit]) {
  19126         sal_free(soc_counter_tbuf[unit]);
  19127         soc_counter_tbuf[unit] = NULL;
  19128     }
  19129 #endif /* BCM_BRADLEY_SUPPORT */
  19130 #endif /* BCM_XGS_SUPPORT */
  19131 
  19132     if (rv != SOC_E_TIMEOUT) {
  19133         if (NULL != soc->counter_intr) {
  19134             sal_sem_destroy(soc->counter_intr);
  19135             soc->counter_intr = NULL;
  19136         }
  19137         if (NULL != soc->counter_trigger) {
  19138             sal_sem_destroy(soc->counter_trigger);
  19139             soc->counter_trigger = NULL;
  19140         }
  19141     }
  19142 
  19143     if (soc->counter_lock != NULL) {
  19144         sal_spinlock_destroy(soc->counter_lock);
  19145         soc->counter_lock = NULL;
  19146     }
  19147 
  19148     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  19149              (BSL_META_U(unit,
  19150                          "soc_counter_stop: stopped\n")));
  19151 
  19152 #ifdef BCM_TOMAHAWK_SUPPORT
  19153     if (soc_feature(unit, soc_feature_counter_eviction)) {
  19154         SOC_IF_ERROR_RETURN(soc_ctr_evict_stop(unit));
  19155     }
  19156 #endif /* BCM_TOMAHAWK_SUPPORT */
  19157 
  19158     return (rv);
  19159 }
  19160 
  19161 /*
  19162  * Function:
  19163  *      soc_counter_extra_register
  19164  * Purpose:
  19165  *      Register callback for additional counter collection.
  19166  * Parameters:
  19167  *      unit - The SOC unit number
  19168  *      fn   - Callback function.
  19169  * Returns:
  19170  *      SOC_E_XXX
  19171  * Notes:
  19172  */
  19173 int
  19174 soc_counter_extra_register(int unit, soc_counter_extra_f fn)
  19175 {
  19176     int i;
  19177 
  19178     if (fn == NULL) {
  19179         return SOC_E_PARAM;
  19180     }
  19181 
  19182     for (i = 0; i < SOC_COUNTER_EXTRA_CB_MAX; i++) {
  19183         if (soc_counter_extra[unit][i] == fn) {
  19184             return SOC_E_NONE;
  19185         }
  19186     }
  19187 
  19188     for (i = 0; i < SOC_COUNTER_EXTRA_CB_MAX; i++) {
  19189         if (soc_counter_extra[unit][i] == NULL) {
  19190             soc_counter_extra[unit][i] = fn;
  19191             return SOC_E_NONE;
  19192         }
  19193     }
  19194 
  19195     return SOC_E_FULL;
  19196 }
  19197 
  19198 /*
  19199  * Function:
  19200  *      soc_counter_extra_unregister
  19201  * Purpose:
  19202  *      Unregister callback for additional counter collection.
  19203  * Parameters:
  19204  *      unit - The SOC unit number
  19205  *      fn   - Callback function.
  19206  * Returns:
  19207  *      SOC_E_XXX
  19208  * Notes:
  19209  */
  19210 int
  19211 soc_counter_extra_unregister(int unit, soc_counter_extra_f fn)
  19212 {
  19213     int i;
  19214 
  19215     if (fn == NULL) {
  19216         return SOC_E_PARAM;
  19217     }
  19218 
  19219     for (i = 0; i < SOC_COUNTER_EXTRA_CB_MAX; i++) {
  19220         if (soc_counter_extra[unit][i] == fn) {
  19221             soc_counter_extra[unit][i] = NULL;
  19222             return SOC_E_NONE;
  19223         }
  19224     }
  19225 
  19226     return SOC_E_NOT_FOUND;
  19227 }
  19228 
  19229 int
  19230 soc_counter_timestamp_get(int unit, soc_port_t port,
  19231                           uint32 *timestamp)
  19232 {
  19233     soc_control_t       *soc = SOC_CONTROL(unit);
  19234     int rv = SOC_E_NOT_FOUND;
  19235 
  19236     if (!soc_feature(unit, soc_feature_timestamp_counter)) {
  19237         return rv;
  19238     }
  19239 
  19240     if (soc->counter_timestamp_fifo[port] == NULL) {
  19241         return rv;
  19242     }
  19243 
  19244     COUNTER_LOCK(unit);
  19245     if (!SHR_FIFO_IS_EMPTY(soc->counter_timestamp_fifo[port])) {
  19246         SHR_FIFO_POP(soc->counter_timestamp_fifo[port], timestamp);
  19247         rv = SOC_E_NONE;
  19248     }
  19249     COUNTER_UNLOCK(unit);
  19250     return rv;
  19251 }
  19252 
  19253 /* Function to return associated dma for a given dma structure.
  19254  * Example, Associated DMA for ING_FLEX_PKT is ING_FLEX_BYTE and vice versa.
  19255  */
  19256 STATIC
  19257 void soc_counter_get_associated_dma(int unit, soc_reg_t id,
  19258                                     soc_counter_non_dma_t *non_dma,
  19259                                     soc_counter_non_dma_t **non_dma_temp)
  19260 {
  19261     if (non_dma_temp == NULL) {
  19262         return;
  19263     }
  19264 
  19265     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) {
  19266         /* If CLR_ON_READ is NOT set, Return NULL */
  19267         *non_dma_temp = NULL;
  19268         return;
  19269     }
  19270     switch (id) {
  19271         case SOC_COUNTER_NON_DMA_ING_FLEX_PKT:
  19272         case SOC_COUNTER_NON_DMA_EGR_FLEX_PKT:
  19273         case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT:
  19274         case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC:
  19275         case SOC_COUNTER_NON_DMA_EFP_PKT:
  19276             *non_dma_temp = non_dma + 1;
  19277             break;
  19278         case SOC_COUNTER_NON_DMA_ING_FLEX_BYTE:
  19279         case SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE:
  19280         case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE:
  19281         case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC:
  19282         case SOC_COUNTER_NON_DMA_EFP_BYTE:
  19283             *non_dma_temp = non_dma - 1;
  19284             break;
  19285         default:
  19286             *non_dma_temp = NULL;
  19287             break; /* all other cases not handled yet */
  19288     }
  19289 
  19290 }
  19291 
  19292 /*
  19293  * Function:
  19294  *      soc_counter_generic_collect_non_dma_entries
  19295  * Purpose:
  19296  *      This routine is similar to the soc_counter_collect_non_dma_entries
  19297  *      routine. The difference is that soc_counter_collect_non_dma_entries can
  19298  *      handle only SOC_CTR_INSTANCE_TYPE_PORT while this routine can handle the
  19299  *      types defined in soc_ctr_instance_type_e. 
  19300  * Parameters:
  19301  *      unit - StrataSwitch unit #.
  19302  *      ctrl_info - StrataSwitch port #.
  19303  *      base_idx - base index returned by generic_get_info. 
  19304  *      ar_idx -  index.
  19305  *      ctr_reg - if INVALIDr, collects and accumulates counter values for all 
  19306  *                else collects and accumulates for a specified port. 
  19307  *                Currently, this functionality is not being used.
  19308  * Returns:
  19309  *      NONE
  19310  * Notes:
  19311  */
  19312 
  19313 STATIC void
  19314 soc_counter_generic_collect_non_dma_entries(int unit, 
  19315                                             soc_ctr_control_info_t ctrl_info, 
  19316                                             int base_idx,
  19317                                             int ar_idx,
  19318                                             soc_reg_t ctr_reg)    
  19319 {
  19320     soc_control_t *soc;
  19321     soc_counter_non_dma_t *non_dma, *non_dma_temp;
  19322     int base_index = 0, width, i, j;
  19323     int id = 0;
  19324     int idx = 0;
  19325     int port=0;
  19326     uint32 fval[2];
  19327     uint64 ctr_new, ctr_prev, ctr_diff, wrap_amt;
  19328     int rv = 0, count, entry_words;
  19329     COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit);
  19330     int dma_base_index = 0;
  19331     int num_non_dma_entries = 0;
  19332     soc_mem_t dma_mem;
  19333     int non_dma_counter_end = SOC_COUNTER_NON_DMA_END - 
  19334                               SOC_COUNTER_NON_DMA_START;
  19335     static int ctr_dma_ct = 0;
  19336     int index_max = 0, pipe = 0, entries_per_pipe = 0, inst_pipe = -1;
  19337     int pipe_start = 0, pool_id;
  19338     uint32 subset_ct = 0; /* For Parent-Child Model */
  19339     uint32 fld_ct = 2;
  19340     soc_info_t *si = NULL;
  19341 
  19342     si = &SOC_INFO(unit);
  19343 
  19344     soc = SOC_CONTROL(unit);
  19345 
  19346     if (soc->counter_non_dma == NULL) {
  19347         return;
  19348     }
  19349 
  19350     /*
  19351      * if ctr_reg != -1, retrieve stats for a
  19352      * specific port and queue from the hardware
  19353      * update the sw copy of the same.
  19354      */
  19355     if (ctr_reg >= NUM_SOC_REG) {
  19356         id = ctr_reg - SOC_COUNTER_NON_DMA_START;
  19357         non_dma_counter_end = id + 1;
  19358         idx = (ar_idx < 0)? 0: ar_idx;
  19359     }
  19360 
  19361     for (; id < non_dma_counter_end; id++) {
  19362         non_dma = &soc->counter_non_dma[id];
  19363 
  19364         if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID) && ctr_reg == INVALIDr) {
  19365             continue;
  19366         }
  19367 
  19368         /* If signaled to exit then return  */
  19369         if (!soc->counter_interval) {
  19370             return;
  19371         }
  19372 
  19373         width = entry_words = 0;
  19374 
  19375         if (non_dma->mem != INVALIDm) {
  19376             count = 0;
  19377 
  19378             /* If there is subset of counters, use subset info for DMA */
  19379             if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
  19380                     (non_dma->extra_ctrs != NULL)) {
  19381                 /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */
  19382                 subset_ct = non_dma->extra_ctr_ct << 1;
  19383 #ifdef BCM_TOMAHAWK3_SUPPORT
  19384                 if(SOC_IS_TOMAHAWK3(unit) && (non_dma->extra_ctr_fld_ct != 0)) {
  19385                     subset_ct = non_dma->extra_ctr_ct;
  19386                     fld_ct = non_dma->extra_ctr_fld_ct;
  19387                 }
  19388 #endif
  19389                 non_dma = non_dma->extra_ctrs;
  19390             } else {
  19391                 subset_ct = 1;
  19392             }
  19393 
  19394             do {
  19395                 /* If signaled to exit then return  */
  19396                 if (!soc->counter_interval) {
  19397                     return;
  19398                 }
  19399                 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID) && ctr_reg == INVALIDr) {
  19400                     break;
  19401                 }
  19402 
  19403                 /* Check if this Counter is up for DMA.
  19404                  * During Slow-DMA, not all counters are up for DMA at the same
  19405                  * time/frequency.
  19406                  */
  19407                 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_CTR_EVICT) &&
  19408                     (!soc_counter_non_dma_ready(unit, non_dma, &ctr_dma_ct))) {
  19409                     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  19410                              (BSL_META_U(unit,
  19411                                          "id %d(%d): NOT pickd for DMA(pipes %d). Ct %d, mem:\n\t%d\n"),
  19412                               id, SOC_COUNTER_NON_DMA_START, count,
  19413                               NUM_PIPE(unit), non_dma->mem));
  19414                     for (i = 0; i < NUM_PIPE(unit); i++) {
  19415                         LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  19416                              (BSL_META_U(unit, "\t%d\n"), non_dma->dma_mem[i]));
  19417                     }
  19418                     count++;
  19419                     non_dma++;
  19420                     continue;
  19421                 }
  19422 
  19423                     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  19424                              (BSL_META_U(unit,
  19425                                      "id %d(%d): picked for DMA(Pipes %d). mem:\n\t%d\n"),
  19426                               id, SOC_COUNTER_NON_DMA_START, NUM_PIPE(unit),
  19427                           non_dma->mem));
  19428                 for (i = 0; i < NUM_PIPE(unit); i++) {
  19429                     LOG_VERBOSE(BSL_LS_SOC_COUNTER,
  19430                          (BSL_META_U(unit, "\t%d\n"), non_dma->dma_mem[i]));
  19431                 }
  19432                 entry_words = soc_mem_entry_words(unit, non_dma->mem);
  19433 
  19434                 /* Non-DMA can have either register based or memory based
  19435                  * counters. INVALIDr signifies memory based */
  19436                 if (ctr_reg == INVALIDr) {
  19437                     for (i = 0; i < NUM_PIPE(unit); i++) {
  19438                         /* Do only if the Pipe mem is VALID. */
  19439                         if (non_dma->dma_mem[i] == INVALIDm) {
  19440                             continue;
  19441                         }
  19442                         /* Skip if no enabled ports in pipe */
  19443                         if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, i))) {
  19444                             continue;
  19445                         }
  19446                         if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) {
  19447 
  19448                             if (non_dma->dma_buf[i] == NULL) {
  19449                                 continue;
  19450                             }
  19451 
  19452                             rv = soc_mem_read_range(unit, 
  19453                                                     non_dma->dma_mem[i],
  19454                                                     MEM_BLOCK_ANY,
  19455                                                     non_dma->dma_index_min[i],
  19456                                                     non_dma->dma_index_max[i],
  19457                                                     &non_dma->dma_buf[i]);
  19458 
  19459                             if (SOC_FAILURE(rv)) {
  19460                                 return;
  19461                             }
  19462                         }
  19463                     }
  19464 
  19465                     base_index = non_dma->base_index;
  19466                     index_max = non_dma->num_entries; 
  19467                     entries_per_pipe = non_dma->num_entries / NUM_PIPE(unit);
  19468                     num_non_dma_entries = index_max;
  19469 
  19470                 } else {
  19471                     subset_ct = 1; /* Only for given instance type */
  19472                     /* Collect counter values for a specific instance */
  19473 
  19474                     base_index = base_idx + ar_idx;
  19475                     num_non_dma_entries = 1;
  19476                     if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_XPE_PORT) {
  19477                         int xpe_inst = (ctrl_info.instance >> 10) & 0xf;
  19478                         int port = ctrl_info.instance >> 14;
  19479                         soc_counter_non_dma_t *parent_dma;
  19480 
  19481                         parent_dma = &soc->counter_non_dma[id];
  19482                         inst_pipe = si->port_pipe[port];
  19483 
  19484                         if ((xpe_inst >= 0) && (xpe_inst < NUM_XPE(unit)) &&
  19485                             (parent_dma->extra_ctrs)) {
  19486                             non_dma = &parent_dma->extra_ctrs[xpe_inst << 1];
  19487                             /* Each XPE has 2 pipe entries */
  19488                             if ( 1 == NUM_PIPE(unit)) {
  19489                                 entries_per_pipe = non_dma->num_entries;
  19490                             } else {
  19491                                 entries_per_pipe = non_dma->num_entries / 2;
  19492                             }
  19493                             dma_mem = non_dma->dma_mem[inst_pipe];
  19494                             if (dma_mem == INVALIDm) {
  19495                                 break;
  19496                             }
  19497 
  19498                             dma_base_index = (base_idx - non_dma->base_index) %
  19499                                              entries_per_pipe +
  19500                                              non_dma->dma_index_min[inst_pipe];
  19501                             rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY,
  19502                                               dma_base_index + idx,
  19503                                               non_dma->dma_buf[inst_pipe]);
  19504                             if (SOC_FAILURE(rv)) {
  19505                                 return;
  19506                             }
  19507                         }
  19508                     } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_ITM_PORT) {
  19509                         /* Decode ITM instance and port for TYPE_ITM_PORT */
  19510                         int itm_inst =
  19511                             (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_ITM) >>
  19512                             CTR_INSTANCE_BIT_SHIFT_ITM;
  19513                         int port =
  19514                             (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_PORT) >>
  19515                             CTR_INSTANCE_BIT_SHIFT_PORT;
  19516                         soc_counter_non_dma_t *parent_dma;
  19517 
  19518                         parent_dma = &soc->counter_non_dma[id];
  19519                         inst_pipe = si->port_pipe[port];
  19520 
  19521                         if ((itm_inst >= 0) && (itm_inst < NUM_ITM(unit)) &&
  19522                             (parent_dma->extra_ctrs)) {
  19523                             non_dma = &parent_dma->extra_ctrs[itm_inst];
  19524                             entries_per_pipe = non_dma->num_entries;
  19525                             dma_mem = non_dma->dma_mem[inst_pipe];
  19526 #ifdef BCM_TOMAHAWK3_SUPPORT
  19527                             /* In normal case, only dma_mem[0] is filled */
  19528                             if (SOC_IS_TOMAHAWK3(unit) &&
  19529                                 (SOC_CONTROL(unit)->em_halfchip == 0)) {
  19530                                 dma_mem = non_dma->dma_mem[0];
  19531                             }
  19532 #endif
  19533                             if (dma_mem == INVALIDm) {
  19534                                 break;
  19535                             }
  19536 
  19537                             /* Retrieve table index by substract the base_index */
  19538                             dma_base_index = (base_idx - non_dma->base_index);
  19539                             rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY,
  19540                                               dma_base_index + idx,
  19541                                               non_dma->dma_buf[inst_pipe]);
  19542                             if (SOC_FAILURE(rv)) {
  19543                                 return;
  19544                             }
  19545                         }
  19546                     } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PORT) {
  19547                         dma_mem = non_dma->dma_mem[0];
  19548                         dma_base_index = base_idx - non_dma->base_index +
  19549                                          non_dma->dma_index_min[0];
  19550                         inst_pipe = 0;
  19551 
  19552                         for (i = 1; i < NUM_PIPE(unit); i++) {
  19553                             if (non_dma->dma_buf[i] == NULL) {
  19554                                 continue;
  19555                             }
  19556 
  19557                             if (dma_base_index > non_dma->dma_index_max[i - 1]) {
  19558                                 inst_pipe = i;
  19559                                 dma_mem = non_dma->dma_mem[i];
  19560                                 dma_base_index -= non_dma->dma_index_max[i - 1] + 1;
  19561                                 dma_base_index += non_dma->dma_index_min[i];
  19562                             }
  19563                         }
  19564                         rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY,
  19565                                           dma_base_index + idx,
  19566                                           non_dma->dma_buf[inst_pipe]);
  19567                         if (SOC_FAILURE(rv)) {
  19568                             return;
  19569                         }
  19570                     } else if (ctrl_info.instance_type ==
  19571                                SOC_CTR_INSTANCE_TYPE_PIPE) {
  19572                         inst_pipe = ctrl_info.instance;
  19573                         entries_per_pipe = non_dma->num_entries / NUM_PIPE(unit);
  19574                         rv = soc_mem_read(unit,
  19575                                           non_dma->dma_mem[inst_pipe],
  19576                                           MEM_BLOCK_ANY, ar_idx,
  19577                                           non_dma->dma_buf[inst_pipe]);
  19578                         if (SOC_FAILURE(rv)) {
  19579                             return;
  19580                         }
  19581                     }
  19582                     else if ((ctrl_info.instance_type
  19583                                 == SOC_CTR_INSTANCE_TYPE_POOL) ||
  19584                              (ctrl_info.instance_type
  19585                                 == SOC_CTR_INSTANCE_TYPE_POOL_PIPE)) {
  19586                         /* Only POOL_PIPE is possible. Type POOL was translated to
  19587                            type POOL_PIPE in _soc_counter_generic_get */
  19588                         pipe_start = (ctrl_info.instance & 0xF);
  19589                         pool_id = (ctrl_info.instance >> 4) & 0x3F;
  19590 
  19591                         non_dma = &(non_dma[pool_id << 1]);
  19592 
  19593                         rv = soc_mem_read(unit, non_dma->dma_mem[pipe_start],
  19594                                               MEM_BLOCK_ANY, idx,
  19595                                               non_dma->dma_buf[pipe_start]);
  19596                         if (SOC_FAILURE(rv)) {
  19597                             return;
  19598                         }
  19599                         entries_per_pipe = non_dma->num_entries / NUM_PIPE(unit);
  19600                     }
  19601                     else if ((ctrl_info.instance_type
  19602                                 == SOC_CTR_INSTANCE_TYPE_FT_GROUP)) {
  19603 
  19604 /*                        non_dma = &(non_dma[pool_id << 1]);*/
  19605 
  19606                         rv = soc_mem_read(unit, non_dma->dma_mem[0],
  19607                                               MEM_BLOCK_ANY, idx,
  19608                                               non_dma->dma_buf[0]);
  19609                         if (SOC_FAILURE(rv)) {
  19610                             return;
  19611                         }
  19612                         entries_per_pipe = non_dma->num_entries / NUM_PIPE(unit);
  19613                     }
  19614 
  19615                 }
  19616 
  19617                 pipe = 0; 
  19618                 non_dma_temp = non_dma;
  19619                 for (j = 0; j < fld_ct; j++) { /* for packet and byte */
  19620                     for (i = 0; i < num_non_dma_entries; i++) {
  19621                         if (ctr_reg == INVALIDr) {
  19622                             pipe = i / entries_per_pipe;
  19623                             /* buffer is NULL. Can happen if memory has holes */
  19624                             if (!non_dma->dma_buf[pipe]) {
  19625                                 /* Skip the pipe indices if dma_buf for given pipe
  19626                                  * is NULL. 
  19627                                  * Also -1 because for-loop increases index by 1
  19628                                  * after continue (-1).
  19629                                  */
  19630                                 i += entries_per_pipe - 1;
  19631                                 continue;
  19632                             }
  19633                             soc_mem_field_get(unit, non_dma->mem,
  19634                                               &non_dma->dma_buf[pipe][entry_words *
  19635                                               (i % entries_per_pipe)],
  19636                                               non_dma_temp->field, fval);
  19637                         } else {
  19638                             /* Only for given instance type */
  19639                             if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) {
  19640                                 /* Recalculate the base_index when converting from
  19641                                    pkt to byte or byte to pkt */
  19642                                 if (j > 0) {
  19643                                     base_index += non_dma_temp->base_index -
  19644                                                   non_dma->base_index;
  19645                                 }
  19646                                 soc_mem_field_get(unit, non_dma->mem,
  19647                                                   &non_dma->dma_buf[inst_pipe]
  19648                                                   [entry_words *(i % entries_per_pipe)]
  19649                                                   , non_dma_temp->field, fval);
  19650                             } else if ((ctrl_info.instance_type ==
  19651                                        SOC_CTR_INSTANCE_TYPE_XPE_PORT) ||
  19652                                        (ctrl_info.instance_type ==
  19653                                         SOC_CTR_INSTANCE_TYPE_PORT)) {
  19654                                 /* Recalculate the base_index when converting from
  19655                                    pkt to byte or byte to pkt */
  19656                                 if (j > 0) {
  19657                                     base_index += non_dma_temp->base_index -
  19658                                                   non_dma->base_index;
  19659                                 }
  19660                                 if (inst_pipe != -1) {
  19661                                     soc_mem_field_get(unit,
  19662                                                       non_dma->dma_mem[inst_pipe],
  19663                                                       &non_dma->dma_buf[inst_pipe][0],
  19664                                                       non_dma_temp->field, fval);
  19665                                 } else {
  19666                                     break;
  19667                                 }
  19668                             }
  19669                             else if ((ctrl_info.instance_type ==
  19670                                       SOC_CTR_INSTANCE_TYPE_POOL) ||
  19671                                      (ctrl_info.instance_type ==
  19672                                       SOC_CTR_INSTANCE_TYPE_POOL_PIPE)) {
  19673                                  /* num_non_dma_entries is always 1 because only
  19674                                     POOL_PIPE is possible */
  19675                                  pipe = pipe_start;
  19676                                  i = pipe_start * entries_per_pipe;
  19677 
  19678                                  if (!non_dma->dma_buf[pipe]) {
  19679                                        continue;
  19680                                   }
  19681                                  soc_mem_field_get(unit, non_dma->mem,
  19682                                               non_dma->dma_buf[pipe],
  19683                                               non_dma_temp->field, fval);
  19684                                 /* recalculate base_index for pkt or byte */
  19685                                 base_index = (non_dma_temp->base_index) + idx;
  19686                             } else if ((ctrl_info.instance_type ==
  19687                                        SOC_CTR_INSTANCE_TYPE_ITM_PORT)) {
  19688                                 if (inst_pipe != -1) {
  19689                                     soc_mem_field_get(unit,
  19690                                                       non_dma->dma_mem[0],
  19691                                                       &non_dma->dma_buf[inst_pipe][0],
  19692                                                       non_dma_temp->field, fval);
  19693                                 } else {
  19694                                     break;
  19695                                 }
  19696                             }
  19697                             else if ((ctrl_info.instance_type ==
  19698                                       SOC_CTR_INSTANCE_TYPE_FT_GROUP)) {
  19699                                  /* num_non_dma_entries is always 1 because only
  19700                                     POOL_PIPE is possible */
  19701                                  if (!non_dma->dma_buf[0]) {
  19702                                        continue;
  19703                                   }
  19704                                  soc_mem_field_get(unit, non_dma->mem,
  19705                                               non_dma->dma_buf[0],
  19706                                               non_dma_temp->field, fval);
  19707                                 /* recalculate base_index for pkt or byte */
  19708                                 base_index = (non_dma_temp->base_index) + idx;
  19709                             }
  19710                         }
  19711                         if (non_dma_temp->field != INVALIDf) {
  19712                             width = soc_mem_field_length(unit, non_dma_temp->mem,
  19713                                 non_dma_temp->field);
  19714                         } else {
  19715                             width = 32;
  19716                         }
  19717                         if (width <= 32) {
  19718                             /*
  19719                              * COVERITY
  19720                              * faval is passed as output parameter to function
  19721                              * soc_mem_field_get to get initialized
  19722                              */
  19723                             /* coverity[uninit_use : FALSE] */
  19724                             COMPILER_64_SET(ctr_new, 0, fval[0]);
  19725                         } else {
  19726                             /* coverity[uninit_use : FALSE] */
  19727                             COMPILER_64_SET(ctr_new, fval[1], fval[0]);
  19728                         }
  19729                         if (non_dma->flags & _SOC_COUNTER_NON_DMA_EXTRA_COUNT) {
  19730                             COMPILER_64_SUB_32(ctr_new, 1);
  19731                         }
  19732                         COUNTER_ATOMIC_BEGIN(s);
  19733                         ctr_prev = soc->counter_hw_val[base_index + i];
  19734                         COUNTER_ATOMIC_END(s);
  19735 
  19736                         if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) {
  19737                             if (COMPILER_64_EQ(ctr_new, ctr_prev)) {
  19738                                 COUNTER_ATOMIC_BEGIN(s);
  19739                                 COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  19740                                 COUNTER_ATOMIC_END(s);
  19741                                 continue;
  19742                             }
  19743                         }
  19744 
  19745                         ctr_diff = ctr_new;
  19746 
  19747                         if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) {
  19748                             COUNTER_ATOMIC_BEGIN(s);
  19749                             if (COMPILER_64_GT(ctr_new, soc->counter_sw_val[base_index + i])) {
  19750                                 soc->counter_sw_val[base_index + i] = ctr_new;
  19751                             }
  19752                             soc->counter_hw_val[base_index + i] = ctr_new;
  19753                             COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  19754                             COUNTER_ATOMIC_END(s);
  19755                             continue;
  19756                         }
  19757 
  19758                         if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) {
  19759                             COUNTER_ATOMIC_BEGIN(s);
  19760                             soc->counter_sw_val[base_index + i] = ctr_new;
  19761                             soc->counter_hw_val[base_index + i] = ctr_new;
  19762                             COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  19763                             COUNTER_ATOMIC_END(s);
  19764                             continue;
  19765                         }
  19766 
  19767                         if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) {
  19768                             if (COMPILER_64_LT(ctr_diff, ctr_prev)) {
  19769                                 if (width < 32) {
  19770                                     COMPILER_64_ADD_32(ctr_diff, 1U << width);
  19771                                 } else if (width < 64) {
  19772                                     COMPILER_64_SET(wrap_amt, 1U << (width - 32), 0);
  19773                                     COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  19774                                 }
  19775                             }
  19776 
  19777                             COMPILER_64_SUB_64(ctr_diff, ctr_prev);
  19778                         }
  19779 
  19780                         COUNTER_ATOMIC_BEGIN(s);
  19781                         COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i],
  19782                                            ctr_diff);
  19783                         soc->counter_hw_val[base_index + i] = ctr_new;
  19784                         soc->counter_delta[base_index + i] = ctr_diff;
  19785                         COUNTER_ATOMIC_END(s);
  19786                     }
  19787                     /* Get the associated dma. Get the byte from the pkt, or pkt from the byte */
  19788                     non_dma_temp = NULL;
  19789                     /* do this check for CLEAR_ON_READ CASE ONLY *
  19790                      */
  19791                     if ((ctr_reg != INVALIDr)) {
  19792                         soc_counter_get_associated_dma(unit, ctr_reg, non_dma,
  19793                                                        &non_dma_temp);
  19794                     }
  19795                     if (non_dma_temp == NULL) {
  19796                         /* Don't loop for the second time if the associated dma is NULL
  19797                            or when doing a global sync */
  19798                         break;
  19799                     }
  19800                 }
  19801                 count++;
  19802                 non_dma++;
  19803             } while ((count < subset_ct) && non_dma);
  19804         } else if (non_dma->reg != INVALIDr) {
  19805             pbmp_t counter_pbmp;
  19806 
  19807             count = 0;
  19808             if (non_dma->field != INVALIDf) {
  19809                 width = soc_reg_field_length(unit, non_dma->reg, 
  19810                                              non_dma->field);
  19811             } else {
  19812                 width = 32;
  19813             }
  19814 
  19815             /*
  19816              * If stats retrieval is for a specific
  19817              * port, set the pbmp for counter collection.
  19818              */  
  19819             if (ctr_reg >= NUM_SOC_REG) {
  19820                 SOC_PBMP_CLEAR(counter_pbmp);
  19821                 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_ITM_PORT) {
  19822                     /* For ITM counter register, port is used as ITM instance */
  19823                     port =
  19824                         (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_ITM) >>
  19825                         CTR_INSTANCE_BIT_SHIFT_ITM;
  19826                 } else {
  19827                     port = ctrl_info.instance;
  19828                 }
  19829                 SOC_PBMP_PORT_ADD(counter_pbmp, port);
  19830             } else {
  19831                 SOC_PBMP_CLEAR(counter_pbmp);
  19832                 SOC_PBMP_ASSIGN(counter_pbmp, soc->counter_pbmp);
  19833             }
  19834 
  19835             PBMP_ITER(counter_pbmp, port) {
  19836                 /*
  19837                  * stats retrieval for a specific port.
  19838                  */  
  19839 
  19840                 if (ctr_reg >= NUM_SOC_REG) {
  19841                     if (!SOC_PBMP_MEMBER(counter_pbmp, port)) {
  19842                         continue;
  19843                     }
  19844 
  19845                     i = idx;
  19846                     count = i + 1;
  19847                     base_index = base_idx;
  19848                 } else {
  19849                     if (non_dma->entries_per_port == 0) {
  19850                         /*
  19851                          * OK to over-write port variable as loop 
  19852                          * breaks after 1 iter.  Check below for 
  19853                          * the same codition.
  19854                          */
  19855                         port = REG_PORT_ANY;
  19856                         count = non_dma->num_entries;
  19857                         base_index = non_dma->base_index;
  19858                     } else {
  19859                         if (!SOC_PBMP_MEMBER(non_dma->pbmp, port)) {
  19860                             continue;
  19861                         }
  19862 
  19863                         if (non_dma->flags & _SOC_COUNTER_NON_DMA_PERQ_REG) {
  19864                             count = num_cosq[unit][port];
  19865                             base_index = non_dma->base_index;
  19866                             for (i = 0; i < port; i++) {
  19867                                 base_index += num_cosq[unit][i];
  19868                             }
  19869                         } else {
  19870                             count = non_dma->entries_per_port;
  19871                             base_index = non_dma->base_index + port * count;
  19872                         }
  19873                     }
  19874                 }
  19875 
  19876                 for (i = 0; i < count; i++) {
  19877                     /* coverity[negative_returns : FALSE] */
  19878                     rv = soc_reg_get(unit, non_dma->reg, port, i, &ctr_new);
  19879                     if (SOC_FAILURE(rv)) {
  19880                         return;
  19881                     }
  19882                     COUNTER_ATOMIC_BEGIN(s);
  19883                     ctr_prev = soc->counter_hw_val[base_index + i];
  19884                     COUNTER_ATOMIC_END(s);
  19885 
  19886                     if (COMPILER_64_EQ(ctr_new, ctr_prev)) {
  19887                         COUNTER_ATOMIC_BEGIN(s);
  19888                         COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  19889                         COUNTER_ATOMIC_END(s);
  19890                         continue;
  19891                     }
  19892 
  19893                     ctr_diff = ctr_new;
  19894 
  19895                     if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) {
  19896                         COUNTER_ATOMIC_BEGIN(s);
  19897                         if (COMPILER_64_GT(ctr_new,
  19898                                            soc->counter_sw_val[base_index + i])) {
  19899                             soc->counter_sw_val[base_index + i] = ctr_new;
  19900                         }
  19901                         soc->counter_hw_val[base_index + i] = ctr_new;
  19902                         COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  19903                         COUNTER_ATOMIC_END(s);
  19904                         continue;
  19905                     }
  19906 
  19907                     if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) {
  19908                         COUNTER_ATOMIC_BEGIN(s);
  19909                         soc->counter_sw_val[base_index + i] = ctr_new;
  19910                         soc->counter_hw_val[base_index + i] = ctr_new;
  19911                         COMPILER_64_ZERO(soc->counter_delta[base_index + i]);
  19912                         COUNTER_ATOMIC_END(s);
  19913                         continue;
  19914                     }
  19915 
  19916                     if (COMPILER_64_LT(ctr_diff, ctr_prev)) {
  19917                         if (width < 32) {
  19918                             COMPILER_64_ADD_32(ctr_diff, 1U << width);
  19919                         } else if (width < 64) {
  19920                             COMPILER_64_SET(wrap_amt, 1U << (width - 32), 0);
  19921                             COMPILER_64_ADD_64(ctr_diff, wrap_amt);
  19922                         }
  19923                     }
  19924 
  19925                     COMPILER_64_SUB_64(ctr_diff, ctr_prev);
  19926 
  19927                     COUNTER_ATOMIC_BEGIN(s);
  19928                     COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i],
  19929                                        ctr_diff);
  19930                     soc->counter_hw_val[base_index + i] = ctr_new;
  19931                     soc->counter_delta[base_index + i] = ctr_diff;
  19932                     COUNTER_ATOMIC_END(s);
  19933                 }
  19934                 if (non_dma->entries_per_port == 0) {
  19935                     break;
  19936                 }
  19937             }
  19938         } else {
  19939             continue;
  19940         }
  19941     }
  19942     ctr_dma_ct++;
  19943 }
  19944 
  19945 /*
  19946  * Function:
  19947  *      _soc_counter_port_pbmp_add(int unit, int port)
  19948  * Purpose:
  19949  *      add port to counter_pbmp
  19950  *
  19951  * Parameters:
  19952  *      unit - StrataSwitch unit #.
  19953  *      port - Port number #.
  19954  *
  19955  * Returns:
  19956  *      SOC_E_XXX
  19957  */
  19958 STATIC int
  19959 _soc_counter_port_pbmp_add(int unit, int port)
  19960 {
  19961     soc_control_t *soc = SOC_CONTROL(unit);
  19962     int phy_port;
  19963     int blk;
  19964     int bindex;
  19965     int blktype;
  19966     int port_idx;
  19967     soc_ctr_type_t ctype;
  19968 
  19969     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  19970     if (phy_port < 0) {
  19971         return SOC_E_INTERNAL;
  19972     }
  19973 
  19974     blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0);
  19975     bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0);
  19976 #if defined(BCM_MONTEREY_SUPPORT)
  19977      if (!(IS_CPRI_PORT(unit, port)) && SOC_IS_MONTEREY(unit)) {
  19978          if ( ((phy_port > 0) && (phy_port < 13)) || 
  19979              ((phy_port > 48) && (phy_port < 65))) { 
  19980               blk = SOC_PORT_IDX_BLOCK(unit, phy_port,1);
  19981               bindex = SOC_PORT_IDX_BINDEX(unit, phy_port,1);
  19982          }   
  19983     }
  19984 #endif 
  19985     if (blk < 0 && bindex < 0) { /* End of regsfile port list */
  19986         return SOC_E_NONE;
  19987     }
  19988 
  19989     for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype;
  19990          port_idx++) {
  19991         blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx);
  19992         if (blk < 0) { /* End of block list of each port */
  19993             break;
  19994         }
  19995 
  19996         blktype = SOC_BLOCK_INFO(unit, blk).type;
  19997         switch (blktype) {
  19998         case SOC_BLK_CPORT:
  19999         case SOC_BLK_XLPORT:
  20000         case SOC_BLK_XLPORTB0:
  20001         case SOC_BLK_CLPORT:
  20002         case SOC_BLK_CLG2PORT:
  20003         case SOC_BLK_CDPORT:
  20004         case SOC_BLK_GXPORT:
  20005             ctype = SOC_CTR_TYPE_XE;
  20006 
  20007 #ifdef BCM_GREYHOUND_SUPPORT
  20008             if (SOC_IS_GREYHOUND(unit) && blktype == SOC_BLK_GXPORT){
  20009                 if (SOC_BLOCK_PORT(unit, blk) < 0){
  20010                     ctype = SOC_CTR_TYPE_XE;
  20011                 } else {
  20012                     /* Greyhound GE port with SOC_BLK_GXPORT case*/
  20013                     ctype = SOC_CTR_TYPE_GE;
  20014                 }
  20015             }
  20016 #endif /* BCM_GREYHOUND_SUPPORT */
  20017 #ifdef BCM_GREYHOUND2_SUPPORT
  20018             if (SOC_IS_GREYHOUND2(unit) && blktype == SOC_BLK_CLPORT) {
  20019                 ctype = SOC_CTR_TYPE_CE; 
  20020             } 
  20021 #endif /* BCM_GREYHOUND2_SUPPORT */
  20022 #ifdef BCM_HELIX5_SUPPORT
  20023             if (SOC_IS_HELIX5(unit)) {
  20024                 if (IS_QSGMII_PORT(unit, port)) {
  20025                     ctype = SOC_CTR_TYPE_GE;
  20026                 } else {
  20027                     ctype = SOC_CTR_TYPE_XE;
  20028                 }
  20029                 if (blktype == SOC_BLK_CLPORT) {
  20030                     ctype = SOC_CTR_TYPE_CE;
  20031                 }
  20032                 break;
  20033             }
  20034 #endif
  20035 #if defined(BCM_TRIDENT3_SUPPORT) || defined BCM_TOMAHAWKPLUS_SUPPORT || \
  20036     defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  20037             if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWKPLUS(unit) ||
  20038                 SOC_IS_TOMAHAWK2(unit) || SOC_IS_TOMAHAWK3(unit)) {
  20039                 if (blktype == SOC_BLK_CLPORT) {
  20040                     ctype = SOC_CTR_TYPE_CE;
  20041                     break;
  20042                 }
  20043                 if (blktype == SOC_BLK_CDPORT) {
  20044                     ctype = SOC_CTR_TYPE_CD;
  20045                     break;
  20046                 }
  20047                 if (blktype == SOC_BLK_XLPORT) {
  20048                     ctype = SOC_CTR_TYPE_XE;
  20049                     break;
  20050                 }
  20051                 LOG_WARN(BSL_LS_SOC_COMMON,
  20052                          (BSL_META_U(unit, " UNKNOWN TYPE \n")));
  20053             }
  20054 #endif /* BCM_TOMAHAWKPLUS_SUPPORT */
  20055             if (blktype == SOC_BLK_CLG2PORT) {
  20056                 ctype = SOC_CTR_TYPE_CE;
  20057             }
  20058             if (SOC_BLOCK_PORT(unit, blk) < 0) {
  20059                 ctype = -1;
  20060             }
  20061             break;
  20062 #if defined(BCM_MONTEREY_SUPPORT)
  20063         case SOC_BLK_CPRI:
  20064                 if(IS_CPRI_PORT(unit, port) && 
  20065                             SOC_IS_MONTEREY(unit) ) {
  20066                    ctype = SOC_CTR_TYPE_CPU; 
  20067                 } else 
  20068                 { 
  20069                 ctype = -1;
  20070                 }
  20071             break;  
  20072 #endif
  20073         default:
  20074             ctype = -1;
  20075             break;
  20076         }
  20077 
  20078         if (ctype != -1) {
  20079             SOC_IF_ERROR_RETURN(soc_port_cmap_set(unit, port, ctype));
  20080             SOC_PBMP_PORT_ADD(soc->counter_pbmp,port);
  20081             break;
  20082         }
  20083     } /* For each block in the given port */
  20084 
  20085     return SOC_E_NONE;
  20086 }
  20087 
  20088 int
  20089 soc_counter_port_pbmp_add(int unit, int port)
  20090 {
  20091     int rv;
  20092 
  20093     COUNTER_LOCK(unit);
  20094     rv = _soc_counter_port_pbmp_add(unit, port);
  20095     COUNTER_UNLOCK(unit);
  20096     return rv;
  20097 }
  20098 
  20099 int
  20100 soc_counter_port_pbmp_remove(int unit, int port)
  20101 {
  20102     soc_control_t *soc = SOC_CONTROL(unit);
  20103 
  20104     COUNTER_LOCK(unit);
  20105     soc->counter_map[port] = 0;
  20106     SOC_PBMP_PORT_REMOVE(soc->counter_pbmp,port);
  20107     COUNTER_UNLOCK(unit);
  20108     return SOC_E_NONE;
  20109 }
  20110 
  20111 
  20112 /*
  20113  * Function:
  20114  *      soc_ser_update_counter
  20115  *
  20116  * Purpose:
  20117  *      Update both sw and corresponding hw counter
  20118  *      (to keep SW and HW counters coherent)
  20119  *
  20120  * Parameters:
  20121  *      unit - SOC unit number
  20122  *
  20123  *      is_reg - nonZero => counter is declared as REG in regsfile
  20124  *             - Zero    => counter is declared as MEM in regsfile
  20125  *
  20126  *      restore_reg - register view that needs to be written
  20127  *                    (for REG based counters)
  20128  *
  20129  *      restore_mem - mem view (hw) that needs to be written
  20130  *                    (for MEM based counters)
  20131  *
  20132  *      index - index for MEM based counter tables
  20133  *            - element_number for REG based counter
  20134  *
  20135  *      copyno - copyno for use with soc_mem_write
  20136  *             - port for use with soc_reg_set
  20137  *
  20138  *      base_reg - base reg view (for REG based counters)
  20139  *
  20140  *      base_mem - base mem view (for MEM based counters)
  20141  *
  20142  *      inst_num - Instance number
  20143  *               - Pool number in case of flex counters
  20144  *               - XPE number in case of mmu counters
  20145  *               - obm queue number in case of obm counters
  20146  *               - 0 otherwise
  20147  *
  20148  *      pipe   - Will be invalid (-1) for MMU_CTR_COLOR_DROP_MEM_XPE0-3
  20149  *             - Will be >= 0 and < NUM_PIPE(unit) otherwise
  20150  *
  20151  *      restore_last - nonZero => write last sw recorded value to hw counter
  20152  *                   - Zero    => clear both sw and hw counter
  20153  *
  20154  * Returns:
  20155  *      SOC_E_???
  20156  *
  20157  * Notes:
  20158  */
  20159 int
  20160 soc_ser_update_counter(int unit, int is_reg, soc_reg_t restore_reg,
  20161                           soc_mem_t restore_mem, int index, int copyno,
  20162                           soc_reg_t base_reg, soc_mem_t base_mem,
  20163                           int inst_num, int pipe, int restore_last)
  20164 {
  20165     void *null_entry = NULL;
  20166 
  20167     LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit,
  20168         "restore_%s %s, index=%0d, copyno=%0d, "
  20169         "base_%s=%s, inst_num=%0d, pipe=%0d, restore_last=%0d \n"),
  20170         is_reg? "reg" : "mem",
  20171         is_reg? SOC_REG_NAME(unit, restore_reg)
  20172               : SOC_MEM_NAME(unit, restore_mem),
  20173         index, copyno,
  20174         is_reg? "reg" : "mem",
  20175         is_reg? SOC_REG_NAME(unit, base_reg)
  20176               : SOC_MEM_NAME(unit, base_mem),
  20177         inst_num, pipe, restore_last));
  20178 
  20179     if (is_reg &&
  20180         SOC_REG_IS_VALID(unit, restore_reg) &&
  20181         SOC_REG_IS_VALID(unit, base_reg)) {
  20182         int reg_set_port = copyno;
  20183 
  20184         /* clear hw reg */
  20185         if (SOC_REG_IS_64(unit, restore_reg)) {
  20186             uint64 tmp64;
  20187             COMPILER_64_ZERO(tmp64);
  20188             LOG_WARN(BSL_LS_SOC_SER,
  20189                 (BSL_META_U(unit,
  20190                             "Clearing restore_reg %s, 64b, pipe=%0d, numels=%0d\n"),
  20191                  SOC_REG_NAME(unit, restore_reg), pipe, index));
  20192             SOC_IF_ERROR_RETURN(
  20193                 soc_reg_set(unit, restore_reg, reg_set_port, index, tmp64));
  20194         } else {
  20195             LOG_WARN(BSL_LS_SOC_SER,
  20196                 (BSL_META_U(unit,
  20197                             "Clearing restore_reg %s, 32b, pipe=%0d, numels=%0d\n"),
  20198                  SOC_REG_NAME(unit, restore_reg), pipe, index));
  20199             SOC_IF_ERROR_RETURN(
  20200                 soc_reg32_set(unit, restore_reg, reg_set_port, index, 0));
  20201         }
  20202         return SOC_E_NONE;
  20203     } else if (!is_reg &&
  20204         SOC_MEM_IS_VALID(unit, restore_mem) &&
  20205         SOC_MEM_IS_VALID(unit, base_mem)) {
  20206 
  20207         /* clear hw mem */
  20208         null_entry = soc_mem_entry_null(unit, restore_mem);
  20209         return(soc_mem_write(unit, restore_mem, copyno, index, null_entry));
  20210     }
  20211 
  20212     return SOC_E_FAIL;
  20213 }
  20214 
  20215 #endif /* defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) */