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 (179876B)


      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  * TH counter module routines.
      8  */
      9 
     10 #include <shared/bsl.h>
     11 
     12 #include <sal/core/libc.h>
     13 
     14 #include <soc/debug.h>
     15 #include <soc/util.h>
     16 #include <soc/mem.h>
     17 #include <soc/tomahawk.h>
     18 #if defined(BCM_TOMAHAWK2_SUPPORT)
     19 #include <soc/tomahawk2.h>
     20 #endif
     21 #if defined(BCM_TOMAHAWK3_SUPPORT)
     22 #include <soc/tomahawk3.h>
     23 #endif
     24 
     25 #include <bcm_int/esw/flex_ctr.h>
     26 #include <bcm_int/esw/stat.h>
     27 
     28 #ifdef BCM_TOMAHAWK_SUPPORT
     29 
     30 STATIC int
     31 _soc_counter_th_get_child_dma_by_idx(int unit, soc_counter_non_dma_t *parent,
     32                                      int idx, soc_counter_non_dma_t **child)
     33 {
     34     int rv = SOC_E_NONE;
     35 
     36     if ((parent->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
     37         if (idx >= parent->extra_ctr_ct) {
     38             return SOC_E_PARAM;
     39         }
     40         *child = &parent->extra_ctrs[idx << 1];
     41     } else {
     42         *child = parent;
     43     }
     44     return rv;
     45 }
     46 
     47 int
     48 soc_counter_tomahawk_get_child_dma(int unit, soc_reg_t id,
     49                                    soc_ctr_control_info_t ctrl_info,
     50                                    soc_counter_non_dma_t **child_dma)
     51 {
     52     soc_control_t *soc = SOC_CONTROL(unit);
     53     soc_counter_non_dma_t *parent_dma = NULL;
     54     int c_offset = -1;
     55 
     56     if ((id < NUM_SOC_REG) || (id >= SOC_COUNTER_NON_DMA_END)) {
     57         return SOC_E_PARAM;
     58     }
     59     parent_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
     60 
     61     if ((!(parent_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) || 
     62         (ctrl_info.instance == -1)) {
     63         *child_dma = parent_dma;
     64         return SOC_E_NONE;
     65     }
     66 
     67     switch (ctrl_info.instance_type) {
     68         case SOC_CTR_INSTANCE_TYPE_POOL:
     69             c_offset = ctrl_info.instance;
     70             if ((c_offset < 0) || (c_offset >= parent_dma->extra_ctr_ct)) {
     71                 return SOC_E_PARAM;
     72             }
     73 
     74             switch (id) {
     75                 case SOC_COUNTER_NON_DMA_ING_FLEX_BYTE: 
     76                 case SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE:
     77                 case SOC_COUNTER_NON_DMA_ING_FLEX_PKT:
     78                 case SOC_COUNTER_NON_DMA_EGR_FLEX_PKT:
     79                     if ((parent_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
     80                         (parent_dma->extra_ctrs != NULL)) {
     81                         /* Refer extra_ctrs_init for PKT/BYTE control block placement.
     82                         */
     83                         *child_dma = &parent_dma->extra_ctrs[(c_offset << 1)];
     84                     }
     85                     break;
     86                 default:
     87                     return SOC_E_PARAM;
     88             }
     89             break;
     90         default:
     91             return SOC_E_PARAM;
     92     }
     93     return SOC_E_NONE;
     94 }
     95 
     96 int
     97 soc_counter_tomahawk_generic_get_info(int unit,soc_ctr_control_info_t ctrl_info,
     98                                       soc_reg_t id, int *base_index,
     99                                       int *num_entries)
    100 {
    101     soc_info_t *si = &SOC_INFO(unit);
    102     soc_control_t *soc = SOC_CONTROL(unit);
    103     soc_counter_non_dma_t *non_dma;
    104     soc_port_t port;
    105     soc_port_t phy_port = 0, mmu_port = 0;
    106     int pipe, xpe = 0, c_offset, pipe_offset = 0;
    107     int is_uc = 0;
    108 
    109     if ((id < NUM_SOC_REG) || (id >= SOC_COUNTER_NON_DMA_END)) {
    110         return SOC_E_PARAM;
    111     }
    112 
    113     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
    114 
    115     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID) &&
    116             !(non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
    117         /* For Parent-Child model, return E_UNAVAIL if child non_dma is INVALID.
    118          */
    119         return SOC_E_UNAVAIL;
    120     }
    121 
    122     *base_index = 0;
    123     switch (ctrl_info.instance_type) {
    124         case SOC_CTR_INSTANCE_TYPE_PORT: 
    125             port = ctrl_info.instance;
    126             if (si->port_l2p_mapping[port] == -1) {
    127                 *base_index = 0;
    128                 *num_entries = 0;
    129                 return SOC_E_PARAM;
    130             }
    131             pipe = si->port_pipe[port];
    132 
    133             switch (id) {
    134                 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC:
    135                 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC:
    136                     is_uc = 1;
    137                     /* fall-through */
    138                 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT:
    139                 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE:
    140                     *num_entries = (is_uc)? si->port_num_uc_cosq[port]: si->port_num_cosq[port];
    141                     if (IS_CPU_PORT(unit, port)) {
    142                         *base_index = 0;
    143                     } else {
    144 #if defined(BCM_TOMAHAWK3_SUPPORT)
    145                         if (SOC_IS_TOMAHAWK3(unit)) {
    146                             *base_index =
    147                                 pipe * 288 +
    148                                 SOC_TH3_NUM_CPU_QUEUES +
    149                                 (port % SOC_TH3_MAX_DEV_PORTS_PER_PIPE) *
    150                                  SOC_TH3_NUM_GP_QUEUES +
    151                                 si->port_num_uc_cosq[port] * (!is_uc);
    152                         } else
    153 #endif
    154                         {
    155                             *base_index = pipe * 728 + 48 + (port % 34) * 20 + (10 * !is_uc);
    156                         }
    157                     }
    158                     break;
    159                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO:
    160                 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO:
    161                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI:
    162                 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI:
    163                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0:
    164                 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0:
    165                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1:
    166                 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1:
    167                 case SOC_COUNTER_NON_DMA_PORT_OBM_FC_EVENTS:
    168                     if (IS_CPU_PORT(unit, port)) {
    169                         return SOC_E_PARAM;
    170                     }
    171                     return soc_counter_tomahawk_get_info(unit, port, id,
    172                                                          base_index,
    173                                                          num_entries);
    174                     break;
    175 #ifdef BCM_TOMAHAWK3_SUPPORT
    176                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING:
    177                 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING:
    178                     if (SOC_IS_TOMAHAWK3(unit)) {
    179                         *base_index = SOC_TH3_MMU_LOCAL_PORT(unit,port);
    180                         *base_index +=
    181                             pipe *(non_dma->num_entries / _TH3_PIPES_PER_DEV);
    182                         *num_entries = 1;
    183                     }
    184                     break;
    185 #endif /* BCM_TOMAHAWK3_SUPPORT */
    186                 default:
    187                     return SOC_E_PARAM;
    188             }
    189             break;
    190 
    191         case SOC_CTR_INSTANCE_TYPE_XPE_PORT:
    192 #ifdef BCM_TOMAHAWK3_SUPPORT
    193         case SOC_CTR_INSTANCE_TYPE_ITM_PORT:
    194             if (SOC_IS_TOMAHAWK3(unit)) {
    195                 c_offset =
    196                     (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_ITM) >>
    197                     CTR_INSTANCE_BIT_SHIFT_ITM;
    198                 port =
    199                     (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_PORT) >>
    200                     CTR_INSTANCE_BIT_SHIFT_PORT;
    201             } else
    202 #endif /* BCM_TOMAHAWK3_SUPPORT */
    203             {
    204                 c_offset = (ctrl_info.instance & 0x3C00) >> 10;
    205                 port =  (ctrl_info.instance & 0xFFC000) >> 14;
    206             }
    207 
    208             phy_port = si->port_l2p_mapping[port];
    209             mmu_port = si->port_p2m_mapping[phy_port];
    210             pipe = si->port_pipe[port];
    211 
    212             switch (id) {
    213                 case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC:
    214                 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC:
    215                 case SOC_COUNTER_NON_DMA_COSQ_DROP_WRED_PKT:
    216                 case SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK:
    217                 case SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT:
    218                     is_uc = 1;
    219                     /* fall-through */
    220                 case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE:
    221                 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT:
    222                 case SOC_COUNTER_NON_DMA_QUEUE_PEAK:
    223                 case SOC_COUNTER_NON_DMA_QUEUE_CURRENT:
    224                     if (is_uc) {
    225                         *base_index = si->port_uc_cosq_base[port];
    226                         *num_entries = si->port_num_uc_cosq[port];
    227                     } else {
    228                         *base_index = si->port_cosq_base[port];
    229                         *num_entries = si->port_num_cosq[port];
    230                     }
    231 
    232 #ifdef BCM_TOMAHAWK3_SUPPORT
    233                     if (SOC_IS_TOMAHAWK3(unit)) {
    234                         if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    235                                 (non_dma->extra_ctrs != NULL)) {
    236 
    237                             non_dma = non_dma->extra_ctrs + c_offset;
    238 
    239                             if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    240                                 return SOC_E_UNAVAIL;
    241                             }
    242                         }
    243                         pipe_offset = 0; /* pipe offset done in base_index above */
    244                     } else
    245 #endif /* BCM_TOMAHAWK3_SUPPORT */
    246                     {
    247                         if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    248                                 (non_dma->extra_ctrs != NULL)) {
    249                             /* Refer extra_ctrs_init for PKT/BYTE control block placement.
    250                              * c_offset for extra ctrs are in pairs of PKT/BYTE.
    251                              */
    252                             non_dma = &non_dma->extra_ctrs[(c_offset << 1)];
    253 
    254                             if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    255                                 return SOC_E_UNAVAIL;
    256                             }
    257                         }
    258                         /* UC and MC drop are Egress based. Each XPE has 2 pipes.
    259                          * XPE 0/2 - Pipe 0 + 1
    260                          * XPE 1/3 - Pipe 2 + 3
    261                          */
    262                         pipe_offset =
    263                             (non_dma->num_entries / non_dma->num_valid_pipe) * (pipe & 0x1);
    264                     }
    265                     *base_index += pipe_offset;
    266                     break;
    267 
    268                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW:
    269                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED:
    270                 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN:
    271                 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW:
    272                 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED:
    273                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW_UC:
    274                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED_UC:
    275                 case SOC_COUNTER_NON_DMA_PG0_MIN_CURRENT:
    276                 case SOC_COUNTER_NON_DMA_PG1_MIN_CURRENT:
    277                 case SOC_COUNTER_NON_DMA_PG2_MIN_CURRENT:
    278                 case SOC_COUNTER_NON_DMA_PG3_MIN_CURRENT:
    279                 case SOC_COUNTER_NON_DMA_PG4_MIN_CURRENT:
    280                 case SOC_COUNTER_NON_DMA_PG5_MIN_CURRENT:
    281                 case SOC_COUNTER_NON_DMA_PG6_MIN_CURRENT:
    282                 case SOC_COUNTER_NON_DMA_PG7_MIN_CURRENT:
    283                 case SOC_COUNTER_NON_DMA_PG0_SHARED_CURRENT:
    284                 case SOC_COUNTER_NON_DMA_PG1_SHARED_CURRENT:
    285                 case SOC_COUNTER_NON_DMA_PG2_SHARED_CURRENT:
    286                 case SOC_COUNTER_NON_DMA_PG3_SHARED_CURRENT:
    287                 case SOC_COUNTER_NON_DMA_PG4_SHARED_CURRENT:
    288                 case SOC_COUNTER_NON_DMA_PG5_SHARED_CURRENT:
    289                 case SOC_COUNTER_NON_DMA_PG6_SHARED_CURRENT:
    290                 case SOC_COUNTER_NON_DMA_PG7_SHARED_CURRENT:
    291                 case SOC_COUNTER_NON_DMA_PG0_HDRM_CURRENT:
    292                 case SOC_COUNTER_NON_DMA_PG1_HDRM_CURRENT:
    293                 case SOC_COUNTER_NON_DMA_PG2_HDRM_CURRENT:
    294                 case SOC_COUNTER_NON_DMA_PG3_HDRM_CURRENT:
    295                 case SOC_COUNTER_NON_DMA_PG4_HDRM_CURRENT:
    296                 case SOC_COUNTER_NON_DMA_PG5_HDRM_CURRENT:
    297                 case SOC_COUNTER_NON_DMA_PG6_HDRM_CURRENT:
    298                 case SOC_COUNTER_NON_DMA_PG7_HDRM_CURRENT:
    299                 case SOC_COUNTER_NON_DMA_SP0_CURRENT:
    300                 case SOC_COUNTER_NON_DMA_SP1_CURRENT:
    301                 case SOC_COUNTER_NON_DMA_SP2_CURRENT:
    302                 case SOC_COUNTER_NON_DMA_SP3_CURRENT:
    303 #ifdef BCM_TOMAHAWK3_SUPPORT
    304                     if (SOC_IS_TOMAHAWK3(unit)) {
    305                         *base_index = SOC_TH3_MMU_CHIP_PORT(unit,port);
    306                         *num_entries = 1;
    307                         if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    308                                 (non_dma->extra_ctrs != NULL)) {
    309 
    310                             non_dma = non_dma->extra_ctrs + c_offset;
    311 
    312                             if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    313                                 return SOC_E_UNAVAIL;
    314                             }
    315                         }
    316                         break;
    317                     }
    318 #endif /* BCM_TOMAHAWK3_SUPPORT */
    319                     if (IS_CPU_PORT(unit, port)) {
    320                         *base_index += 32;
    321                     } else if (IS_LB_PORT(unit, port)) {
    322                         if (SOC_IS_TOMAHAWK2(unit)) {
    323                             *base_index += 33;
    324                         } else {
    325                             *base_index += (pipe % 2) * 34 + 33;
    326                         }
    327                     } else {
    328                         if (SOC_IS_TOMAHAWK2(unit)) {
    329                             *base_index += mmu_port % SOC_TH_MMU_PORT_STRIDE;
    330                         } else {
    331                             *base_index += (pipe % 2) * 34 +
    332                                       (mmu_port % SOC_TH_MMU_PORT_STRIDE);
    333                         }
    334                     }
    335                     if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    336                         (non_dma->extra_ctrs != NULL)) {
    337                         /* Refer extra_ctrs_init for PKT/BYTE control block placement.
    338                          */
    339                         non_dma = &non_dma->extra_ctrs[(c_offset << 1)];
    340                     }
    341                     if (SOC_IS_TOMAHAWK2(unit)) {
    342                         /* WRED and Color drop are Egress based. Each XPE has 2 pipes.
    343                          * XPE 0/2 - Pipe 0 + 1
    344                          * XPE 1/3 - Pipe 2 + 3
    345                          */
    346                         pipe_offset = 
    347                             (non_dma->num_entries / non_dma->num_valid_pipe) * (pipe & 0x1);
    348                         *base_index += pipe_offset;
    349                     }
    350                     *num_entries = 1;
    351                     break;
    352 
    353                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING:
    354                 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING:
    355                     *base_index = mmu_port % SOC_TH_MMU_PORT_STRIDE;
    356                     if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    357                         (non_dma->extra_ctrs != NULL)) {
    358                         /* Refer extra_ctrs_init for PKT/BYTE control block placement.
    359                          * c_offset for extra ctrs are in pairs of PKT/BYTE.
    360                          */
    361                         non_dma = &non_dma->extra_ctrs[(c_offset << 1)];
    362 
    363                         if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    364                             return SOC_E_UNAVAIL;
    365                         }
    366                     }
    367                     /* ING drop are Ingress based. Each XPE has 2 pipes.
    368                      * XPE 0/1 - Pipe 0 + 3
    369                      * XPE 2/3 - Pipe 1 + 2
    370                      */
    371                     if (pipe & 2) {
    372                         /* Pipe 2 & 3 are located in the bottom half of the
    373                          * sw_val
    374                          */
    375                         pipe_offset = 
    376                             (non_dma->num_entries / non_dma->num_valid_pipe);
    377                     }
    378                     *num_entries = 1;
    379                     *base_index += pipe_offset;
    380                     break;
    381                 case SOC_COUNTER_NON_DMA_PG_MIN_PEAK:
    382                 case SOC_COUNTER_NON_DMA_PG_MIN_CURRENT:
    383                 case SOC_COUNTER_NON_DMA_PG_SHARED_PEAK:
    384                 case SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT:
    385                 case SOC_COUNTER_NON_DMA_PG_HDRM_PEAK:
    386                 case SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT:
    387                     if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    388                             (non_dma->extra_ctrs != NULL)) {
    389                         /* Refer extra_ctrs_init for PKT/BYTE control block placement.
    390                          * c_offset for extra ctrs are in pairs of PKT/BYTE. 
    391                          */
    392                         non_dma = &non_dma->extra_ctrs[(c_offset << 1)];
    393 
    394                         if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    395                             return SOC_E_UNAVAIL;
    396                         }
    397                     }
    398 
    399                     *num_entries = non_dma->entries_per_port;
    400                     pipe_offset = 
    401                         (non_dma->num_entries / non_dma->num_valid_pipe) / *num_entries;
    402 
    403                     if (IS_CPU_PORT(unit, port)) {
    404                         *base_index += mmu_port;
    405                     } else {
    406                         *base_index += (pipe / 2) * pipe_offset +
    407                             (mmu_port % SOC_TH_MMU_PORT_STRIDE);
    408                     }
    409                     *base_index *= _TH_MMU_NUM_PG;
    410                     break;
    411                 case SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT:
    412                 case SOC_COUNTER_NON_DMA_PRIQ_DROP_BYTE:
    413                 case SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT_YELLOW:
    414                 case SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT_RED:
    415                 case SOC_COUNTER_NON_DMA_HDRM_POOL_DROP_PKT:
    416                     if ((c_offset >=  NUM_ITM(unit)) || (c_offset < 0) ) {
    417                         return SOC_E_PARAM;
    418                     }
    419                     *num_entries = non_dma->num_entries / NUM_ITM(unit);
    420                     *base_index = *num_entries * c_offset;
    421                     break;
    422                 default:
    423                     return SOC_E_PARAM;
    424             }
    425             break;
    426         case SOC_CTR_INSTANCE_TYPE_XPE:
    427             xpe = ctrl_info.instance;
    428             if ((xpe >=  NUM_XPE(unit)) || (xpe < -1) ) {
    429                 return SOC_E_PARAM;
    430             }
    431             switch (id) {
    432                 case SOC_COUNTER_NON_DMA_DROP_RQ_PKT:
    433                 case SOC_COUNTER_NON_DMA_DROP_RQ_BYTE:
    434                 case SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW:
    435                 case SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED:
    436                 case SOC_COUNTER_NON_DMA_POOL_PEAK:
    437                 case SOC_COUNTER_NON_DMA_POOL_CURRENT:
    438                     *base_index = (non_dma->num_entries / NUM_XPE(unit)) * xpe;
    439                     *num_entries = non_dma->num_entries;
    440                     break;
    441                 default:
    442                     return SOC_E_PARAM;
    443             }
    444             break;
    445         case SOC_CTR_INSTANCE_TYPE_PIPE:
    446             pipe = ctrl_info.instance;
    447             if ((pipe >=  NUM_PIPE(unit)) || (pipe < -1) ) {
    448                 return SOC_E_PARAM;
    449             }
    450             switch (id) {
    451                 case SOC_COUNTER_NON_DMA_EFP_PKT:
    452                 case SOC_COUNTER_NON_DMA_EFP_BYTE:
    453                     *base_index = 0;
    454                     *num_entries = non_dma->num_entries / NUM_PIPE(unit);
    455                     if (pipe > 0) {
    456                         pipe_offset = pipe * (*num_entries);
    457                         *base_index += pipe_offset;
    458                     }
    459                     break;
    460                 default:
    461                     return SOC_E_INTERNAL;
    462             }
    463             break;
    464         case SOC_CTR_INSTANCE_TYPE_POOL:
    465             c_offset = ctrl_info.instance;
    466             if ((c_offset < 0) || (c_offset >= non_dma->extra_ctr_ct)) {
    467                 return SOC_E_PARAM;
    468             }
    469 
    470             switch (id) {
    471                 case SOC_COUNTER_NON_DMA_ING_FLEX_BYTE: 
    472                 case SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE:
    473                 case SOC_COUNTER_NON_DMA_ING_FLEX_PKT:
    474                 case SOC_COUNTER_NON_DMA_EGR_FLEX_PKT:
    475                     *base_index = 0;
    476 
    477                     if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    478                             (non_dma->extra_ctrs != NULL)) {
    479                         /* Refer extra_ctrs_init for PKT/BYTE control block placement.
    480                          */
    481                         non_dma = &non_dma->extra_ctrs[(c_offset << 1)];
    482                     }
    483                     *num_entries = non_dma->num_entries / NUM_PIPE(unit);
    484                     break;
    485                 default:
    486                     return SOC_E_PARAM;
    487             }
    488             break;
    489         case SOC_CTR_INSTANCE_TYPE_POOL_PIPE:
    490             c_offset = (ctrl_info.instance & 0x3F0) >> 4;
    491             pipe = ctrl_info.instance & 0xF;
    492             if ((c_offset < 0) || (c_offset >= non_dma->extra_ctr_ct) ||
    493                     (pipe >=  NUM_PIPE(unit)) || (pipe < 0)) {
    494                 return SOC_E_PARAM;
    495             }
    496             switch (id) {
    497                 case SOC_COUNTER_NON_DMA_ING_FLEX_BYTE: 
    498                 case SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE:
    499                 case SOC_COUNTER_NON_DMA_ING_FLEX_PKT:
    500                 case SOC_COUNTER_NON_DMA_EGR_FLEX_PKT:
    501 
    502                     if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    503                             (non_dma->extra_ctrs != NULL)) {
    504                         /* Refer extra_ctrs_init for PKT/BYTE control block placement.
    505                          */
    506                         non_dma = &non_dma->extra_ctrs[(c_offset << 1)];
    507                     }
    508                     *num_entries = non_dma->num_entries / NUM_PIPE(unit);
    509                     *base_index = (*num_entries)*pipe;
    510                     break;
    511                 default:
    512                     return SOC_E_PARAM;
    513             }
    514             break;
    515         case SOC_CTR_INSTANCE_TYPE_SFLOW:
    516            c_offset = ctrl_info.instance;
    517            if ((c_offset < 0) || (c_offset >= non_dma->extra_ctr_ct)) {
    518                return SOC_E_PARAM;
    519            }
    520 
    521            *base_index = 0;
    522            if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    523                     (non_dma->extra_ctrs != NULL)) {
    524                non_dma = &non_dma->extra_ctrs[(c_offset << 1)];
    525            }
    526            *num_entries = non_dma->num_entries;
    527            break;
    528         default:
    529             return SOC_E_PARAM;
    530     }
    531     *base_index += non_dma->base_index;
    532     return SOC_E_NONE;
    533 }
    534 
    535 int
    536 soc_counter_tomahawk_get_info(int unit, soc_port_t port, soc_reg_t id,
    537                                int *base_index, int *num_entries)
    538 {
    539     soc_info_t *si;
    540     soc_control_t *soc;
    541     soc_counter_non_dma_t *non_dma;
    542     soc_port_t phy_port, mmu_port;
    543     int pipe, pipe_offset, obm_id = 0, lane = 0;
    544     uint8 c_offset = 0; /* child offset in Parent-child model */
    545     int is_uc = 0;
    546 
    547     soc = SOC_CONTROL(unit);
    548 
    549     /* For TH non-dma, id is Encoded with offset.
    550      * Bit 31    - sign bit (used incase of -1)
    551      * Bit 30:24 - offset (7 bits)
    552      * Bit 23:0  - id
    553      */
    554     c_offset = (id >> 24) & 0x7f;
    555 
    556     if (c_offset) {
    557         id &= 0x80ffffff;
    558     }
    559 
    560     if (id >= NUM_SOC_REG) {
    561         if (id >= SOC_COUNTER_NON_DMA_END) {
    562             return SOC_E_PARAM;
    563         }
    564     }
    565 
    566     non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
    567 
    568     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID) &&
    569         !(non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
    570         /* For Parent-Child model, return E_UNAVAIL if child non_dma is INVALID.
    571          */
    572         return SOC_E_UNAVAIL;
    573     }
    574 
    575     si = &SOC_INFO(unit);
    576     if (si->port_l2p_mapping[port] == -1) {
    577         *base_index = 0;
    578         *num_entries = 0;
    579         return SOC_E_NONE;
    580     }
    581 
    582     phy_port = si->port_l2p_mapping[port];
    583     mmu_port = si->port_p2m_mapping[phy_port];
    584     pipe = si->port_pipe[port];
    585     switch (id) {
    586     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC:
    587     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC:
    588         is_uc = 1;
    589         /* fall-through */
    590     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT:
    591     case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE:
    592         *num_entries = (is_uc)? si->port_num_uc_cosq[port]: si->port_num_cosq[port];
    593         if (IS_CPU_PORT(unit, port)) {
    594             *base_index = 0;
    595         } else {
    596 #if defined(BCM_TOMAHAWK3_SUPPORT)
    597             if (SOC_IS_TOMAHAWK3(unit)) {
    598                 *base_index = pipe * 288 +
    599                               SOC_TH3_NUM_CPU_QUEUES +
    600                               SOC_TH3_MMU_LOCAL_PORT(unit, port) *
    601                                SOC_TH3_NUM_GP_QUEUES +
    602                               si->port_num_uc_cosq[port] * (!is_uc);
    603             } else
    604 #endif
    605             {
    606                 *base_index = pipe * 728 + 48 + (port % 34) * 20 + (10 * !is_uc);
    607             }
    608         }
    609         break;
    610     case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC:
    611     case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC:
    612     case SOC_COUNTER_NON_DMA_COSQ_DROP_WRED_PKT:
    613         is_uc = 1;
    614         /* fall-through */
    615     case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT:
    616     case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE:
    617     case SOC_COUNTER_NON_DMA_QUEUE_CURRENT:
    618     case SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT:
    619         if (is_uc) {
    620             *base_index = si->port_uc_cosq_base[port];
    621             *num_entries = si->port_num_uc_cosq[port];
    622         } else {
    623             *base_index = si->port_cosq_base[port];
    624             *num_entries = si->port_num_cosq[port];
    625         }
    626 #ifdef BCM_TOMAHAWK3_SUPPORT
    627         if (SOC_IS_TOMAHAWK3(unit)) {
    628             if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    629                     (non_dma->extra_ctrs != NULL)) {
    630 
    631                 non_dma = non_dma->extra_ctrs + c_offset;
    632 
    633                 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    634                     return SOC_E_UNAVAIL;
    635                 }
    636             }
    637             break;
    638         } else {
    639             /* following id's not supported in TH/TH2 */
    640             if(id == SOC_COUNTER_NON_DMA_QUEUE_CURRENT ||
    641                id == SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT) {
    642                 return SOC_E_UNAVAIL;
    643             }
    644         }
    645 #endif /* BCM_TOMAHAWK3_SUPPORT */
    646         if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    647             (non_dma->extra_ctrs != NULL)) {
    648             /* Refer extra_ctrs_init for PKT/BYTE control block placement.
    649              * c_offset for extra ctrs are in pairs of PKT/BYTE.
    650              */
    651             non_dma = &non_dma->extra_ctrs[(c_offset << 1)];
    652 
    653             if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    654                 return SOC_E_UNAVAIL;
    655             }
    656         }
    657         pipe_offset =  (non_dma->num_entries / non_dma->num_valid_pipe) * pipe;
    658         *base_index += pipe_offset;
    659         break;
    660     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING:
    661     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING:
    662 #ifdef BCM_TOMAHAWK3_SUPPORT
    663         if (SOC_IS_TOMAHAWK3(unit)) {
    664             *base_index = SOC_TH3_MMU_LOCAL_PORT(unit,port);
    665             *base_index += pipe * (non_dma->num_entries / _TH3_PIPES_PER_DEV);
    666             *num_entries = 1;
    667             break;
    668         }
    669 #endif /* BCM_TOMAHAWK3_SUPPORT */
    670         *base_index = mmu_port & 0x3f;
    671         if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    672             (non_dma->extra_ctrs != NULL)) {
    673             /* Refer extra_ctrs_init for PKT/BYTE control block placement.
    674              * c_offset for extra ctrs are in pairs of PKT/BYTE. 
    675              */
    676             non_dma = &non_dma->extra_ctrs[(c_offset << 1)];
    677 
    678             if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    679                 return SOC_E_UNAVAIL;
    680             }
    681         }
    682         pipe_offset =  (non_dma->num_entries / non_dma->num_valid_pipe) * pipe;
    683         *base_index += pipe_offset;
    684         *num_entries = 1;
    685         break;
    686 
    687     case SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT:
    688     case SOC_COUNTER_NON_DMA_PRIQ_DROP_BYTE:
    689     case SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT_YELLOW:
    690     case SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT_RED:
    691     case SOC_COUNTER_NON_DMA_HDRM_POOL_DROP_PKT:
    692         *base_index = non_dma->num_entries / NUM_ITM(unit);
    693         *num_entries = non_dma->num_entries;
    694         break;
    695     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW:
    696     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED:
    697     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN:
    698     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED:
    699     case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW:
    700     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW_UC:
    701     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED_UC:
    702     case SOC_COUNTER_NON_DMA_PG0_MIN_CURRENT:
    703     case SOC_COUNTER_NON_DMA_PG1_MIN_CURRENT:
    704     case SOC_COUNTER_NON_DMA_PG2_MIN_CURRENT:
    705     case SOC_COUNTER_NON_DMA_PG3_MIN_CURRENT:
    706     case SOC_COUNTER_NON_DMA_PG4_MIN_CURRENT:
    707     case SOC_COUNTER_NON_DMA_PG5_MIN_CURRENT:
    708     case SOC_COUNTER_NON_DMA_PG6_MIN_CURRENT:
    709     case SOC_COUNTER_NON_DMA_PG7_MIN_CURRENT:
    710     case SOC_COUNTER_NON_DMA_PG0_SHARED_CURRENT:
    711     case SOC_COUNTER_NON_DMA_PG1_SHARED_CURRENT:
    712     case SOC_COUNTER_NON_DMA_PG2_SHARED_CURRENT:
    713     case SOC_COUNTER_NON_DMA_PG3_SHARED_CURRENT:
    714     case SOC_COUNTER_NON_DMA_PG4_SHARED_CURRENT:
    715     case SOC_COUNTER_NON_DMA_PG5_SHARED_CURRENT:
    716     case SOC_COUNTER_NON_DMA_PG6_SHARED_CURRENT:
    717     case SOC_COUNTER_NON_DMA_PG7_SHARED_CURRENT:
    718     case SOC_COUNTER_NON_DMA_PG0_HDRM_CURRENT:
    719     case SOC_COUNTER_NON_DMA_PG1_HDRM_CURRENT:
    720     case SOC_COUNTER_NON_DMA_PG2_HDRM_CURRENT:
    721     case SOC_COUNTER_NON_DMA_PG3_HDRM_CURRENT:
    722     case SOC_COUNTER_NON_DMA_PG4_HDRM_CURRENT:
    723     case SOC_COUNTER_NON_DMA_PG5_HDRM_CURRENT:
    724     case SOC_COUNTER_NON_DMA_PG6_HDRM_CURRENT:
    725     case SOC_COUNTER_NON_DMA_PG7_HDRM_CURRENT:
    726     case SOC_COUNTER_NON_DMA_SP0_CURRENT:
    727     case SOC_COUNTER_NON_DMA_SP1_CURRENT:
    728     case SOC_COUNTER_NON_DMA_SP2_CURRENT:
    729     case SOC_COUNTER_NON_DMA_SP3_CURRENT:
    730 #ifdef BCM_TOMAHAWK3_SUPPORT
    731         if (SOC_IS_TOMAHAWK3(unit)) {
    732             *base_index = SOC_TH3_MMU_CHIP_PORT(unit,port);
    733             *num_entries = 1;
    734             if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    735                     (non_dma->extra_ctrs != NULL)) {
    736 
    737                 non_dma = non_dma->extra_ctrs + c_offset;
    738 
    739                 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
    740                     return SOC_E_UNAVAIL;
    741                 }
    742             }
    743             break;
    744         }
    745 #endif /* BCM_TOMAHAWK3_SUPPORT */
    746         if (IS_CPU_PORT(unit, port)) {
    747             *base_index = 32;
    748         } else if (IS_LB_PORT(unit, port)) {
    749             if (SOC_IS_TOMAHAWK2(unit)) {
    750                 *base_index = 33;
    751             } else {
    752                 *base_index = (pipe % 2) * 32 + 33;
    753             }
    754         } else {
    755             if (SOC_IS_TOMAHAWK2(unit)) {
    756                 *base_index = mmu_port % SOC_TH_MMU_PORT_STRIDE;
    757             } else {
    758                 *base_index = (pipe % 2) * 34 + (mmu_port % SOC_TH_MMU_PORT_STRIDE);
    759             }
    760         }
    761         if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    762             (non_dma->extra_ctrs != NULL)) {
    763             /* Refer extra_ctrs_init for PKT/BYTE control block placement.
    764              */
    765             non_dma = &non_dma->extra_ctrs[(c_offset << 1)];
    766         }
    767         if (SOC_IS_TOMAHAWK2(unit)) {
    768             pipe_offset =  (non_dma->num_entries / non_dma->num_valid_pipe) * pipe;
    769             *base_index += pipe_offset;
    770         }
    771             
    772         *num_entries = 1;
    773         break;
    774     case SOC_COUNTER_NON_DMA_ING_FLEX_BYTE: 
    775     case SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE:
    776     case SOC_COUNTER_NON_DMA_ING_FLEX_PKT:
    777     case SOC_COUNTER_NON_DMA_EGR_FLEX_PKT:
    778         *base_index = 0;
    779         
    780         if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
    781             (non_dma->extra_ctrs != NULL)) {
    782             /* refer extra_ctrs_init for pkt/byte control block placement.
    783              */
    784             non_dma = &non_dma->extra_ctrs[(c_offset << 1)];
    785         }
    786         *num_entries = non_dma->num_entries / NUM_PIPE(unit);
    787         break;
    788     case SOC_COUNTER_NON_DMA_EFP_PKT:
    789     case SOC_COUNTER_NON_DMA_EFP_BYTE:
    790         *base_index = 0;
    791         *num_entries = non_dma->num_entries / NUM_PIPE(unit);
    792         break;
    793     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO:
    794     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO:
    795     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI:
    796     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI:
    797     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0:
    798     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0:
    799     case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1:
    800     case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1:
    801     case SOC_COUNTER_NON_DMA_PORT_OBM_FC_EVENTS:    
    802         *base_index = 0;
    803         *num_entries = 1;
    804         /* find obm from the port number */
    805         SOC_IF_ERROR_RETURN
    806             (soc_tomahawk_port_obm_info_get(unit, port, &obm_id, &lane));
    807         pipe = si->port_pipe[port];
    808         SOC_IF_ERROR_RETURN(_soc_counter_th_get_child_dma_by_idx
    809                                 (unit, non_dma, obm_id, &non_dma));
    810         *base_index += (pipe * non_dma->entries_per_port) + lane;
    811         break;
    812     default:
    813         return SOC_E_INTERNAL;
    814     }
    815     *base_index += non_dma->base_index;
    816     return SOC_E_NONE;
    817 }
    818 
    819 int
    820 soc_counter_tomahawk_status_enable(int unit, int enable)
    821 {
    822     soc_reg_t reg;
    823     uint32 rval;
    824     int reg_id, count;
    825     static const soc_reg_t update_regs[] = {
    826         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_0r,  /* MEMORY_ID 1 */
    827         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_1r,  /* MEMORY_ID 2 */
    828         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_2r,  /* MEMORY_ID 3 */
    829         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_3r,  /* MEMORY_ID 4 */
    830         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_4r,  /* MEMORY_ID 5 */
    831         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_5r,  /* MEMORY_ID 6 */
    832         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_6r,  /* MEMORY_ID 7 */
    833         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_7r,  /* MEMORY_ID 8 */
    834         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_8r,  /* MEMORY_ID 9 */
    835         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_9r,  /* MEMORY_ID 10 */
    836         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_10r, /* MEMORY_ID 11 */
    837         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_11r, /* MEMORY_ID 12 */
    838         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_12r, /* MEMORY_ID 13 */
    839         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_13r, /* MEMORY_ID 14 */
    840         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_14r, /* MEMORY_ID 15 */
    841         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_15r, /* MEMORY_ID 16 */
    842         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_16r, /* MEMORY_ID 17 */
    843         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_17r, /* MEMORY_ID 18 */
    844         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_18r, /* MEMORY_ID 19 */
    845         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_19r, /* MEMORY_ID 20 */
    846         EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_0r,  /* MEMORY_ID 21 */
    847         EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_1r,  /* MEMORY_ID 22 */
    848         EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_2r,  /* MEMORY_ID 23 */
    849         EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_3r,  /* MEMORY_ID 24 */
    850         EGR_PERQ_CNTR_UPDATE_CONTROLr,           /* MEMORY_ID 25 */
    851         EGR_EFP_CNTR_UPDATE_CONTROLr             /* MEMORY_ID 26 */
    852     };
    853 
    854     count = sizeof(update_regs) / sizeof(update_regs[0]);
    855     rval = 0;
    856     soc_reg_field_set(unit, update_regs[0], &rval, COUNTER_POOL_ENABLEf,
    857                       enable?1:0);
    858     for (reg_id = 0; reg_id < count; reg_id++) {
    859 #if defined(INCLUDE_FLOWTRACKER)
    860          if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
    861               soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
    862               soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
    863             if ((reg_id < BCM_STAT_TH_FLEX_COUNTER_MAX_POOL) &&
    864                 _bcm_esw_stat_pool_reserved(unit, bcmStatFlexDirectionIngress, reg_id)) {
    865                 continue;
    866             }
    867         }
    868 #endif
    869         reg = update_regs[reg_id];
    870         SOC_IF_ERROR_RETURN
    871             (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
    872     }
    873     return SOC_E_NONE;
    874 }
    875 
    876 int
    877 soc_counter_tomahawk_eviction_init(int unit)
    878 {
    879     soc_control_t *soc;
    880     soc_counter_evict_t *evict;
    881     int pipe, mem_id, offset=0;
    882     int counter_id;
    883     static const struct {
    884         int pkt_counter_id;
    885         int byte_counter_id;
    886         soc_mem_t mem;
    887         int pool_id;
    888     } evict_info[] = {
    889         { /* MEMORY_ID 0 is reserved */
    890             -1,
    891             -1,
    892             INVALIDm,
    893             0
    894         },
    895         { /* MEMORY_ID 1 */
    896             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    897             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    898             ING_FLEX_CTR_COUNTER_TABLE_0m,
    899             0
    900         },
    901         { /* MEMORY_ID 2 */
    902             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    903             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    904             ING_FLEX_CTR_COUNTER_TABLE_1m,
    905             1
    906         },
    907         { /* MEMORY_ID 3 */
    908             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    909             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    910             ING_FLEX_CTR_COUNTER_TABLE_2m,
    911             2
    912         },
    913         { /* MEMORY_ID 4 */
    914             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    915             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    916             ING_FLEX_CTR_COUNTER_TABLE_3m,
    917             3
    918         },
    919         { /* MEMORY_ID 5 */
    920             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    921             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    922             ING_FLEX_CTR_COUNTER_TABLE_4m,
    923             4
    924         },
    925         { /* MEMORY_ID 6 */
    926             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    927             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    928             ING_FLEX_CTR_COUNTER_TABLE_5m,
    929             5
    930         },
    931         { /* MEMORY_ID 7 */
    932             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    933             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    934             ING_FLEX_CTR_COUNTER_TABLE_6m,
    935             6
    936         },
    937         { /* MEMORY_ID 8 */
    938             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    939             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    940             ING_FLEX_CTR_COUNTER_TABLE_7m,
    941             7
    942         },
    943         { /* MEMORY_ID 9 */
    944             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    945             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    946             ING_FLEX_CTR_COUNTER_TABLE_8m,
    947             8
    948         },
    949         { /* MEMORY_ID 10 */
    950             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    951             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    952             ING_FLEX_CTR_COUNTER_TABLE_9m,
    953             9
    954         },
    955         { /* MEMORY_ID 11 */
    956             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    957             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    958             ING_FLEX_CTR_COUNTER_TABLE_10m,
    959             10
    960         },
    961         { /* MEMORY_ID 12 */
    962             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    963             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    964             ING_FLEX_CTR_COUNTER_TABLE_11m,
    965             11
    966         },
    967         { /* MEMORY_ID 13 */
    968             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    969             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    970             ING_FLEX_CTR_COUNTER_TABLE_12m,
    971             12
    972         },
    973         { /* MEMORY_ID 14 */
    974             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    975             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    976             ING_FLEX_CTR_COUNTER_TABLE_13m,
    977             13
    978         },
    979         { /* MEMORY_ID 15 */
    980             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    981             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    982             ING_FLEX_CTR_COUNTER_TABLE_14m,
    983             14
    984         },
    985         { /* MEMORY_ID 16 */
    986             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    987             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    988             ING_FLEX_CTR_COUNTER_TABLE_15m,
    989             15
    990         },
    991         { /* MEMORY_ID 17 */
    992             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    993             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
    994             ING_FLEX_CTR_COUNTER_TABLE_16m,
    995             16
    996         },
    997         { /* MEMORY_ID 18 */
    998             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
    999             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
   1000             ING_FLEX_CTR_COUNTER_TABLE_17m,
   1001             17
   1002         },
   1003         { /* MEMORY_ID 19 */
   1004             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
   1005             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
   1006             ING_FLEX_CTR_COUNTER_TABLE_18m,
   1007             18
   1008         },
   1009         { /* MEMORY_ID 20 */
   1010             SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
   1011             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
   1012             ING_FLEX_CTR_COUNTER_TABLE_19m,
   1013             19
   1014         },
   1015         { /* MEMORY_ID 21 */
   1016             SOC_COUNTER_NON_DMA_EGR_FLEX_PKT,
   1017             SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE,
   1018             EGR_FLEX_CTR_COUNTER_TABLE_0m,
   1019             0
   1020         },
   1021         { /* MEMORY_ID 22 */
   1022             SOC_COUNTER_NON_DMA_EGR_FLEX_PKT,
   1023             SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE,
   1024             EGR_FLEX_CTR_COUNTER_TABLE_1m,
   1025             1
   1026         },
   1027         { /* MEMORY_ID 23 */
   1028             SOC_COUNTER_NON_DMA_EGR_FLEX_PKT,
   1029             SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE,
   1030             EGR_FLEX_CTR_COUNTER_TABLE_2m,
   1031             2
   1032         },
   1033         { /* MEMORY_ID 24 */
   1034             SOC_COUNTER_NON_DMA_EGR_FLEX_PKT,
   1035             SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE,
   1036             EGR_FLEX_CTR_COUNTER_TABLE_3m,
   1037             3
   1038         },
   1039         { /* MEMORY_ID 25 */
   1040             SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,
   1041             SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE,
   1042             EGR_PERQ_XMT_COUNTERSm,
   1043             0
   1044         },
   1045         { /* MEMORY_ID 26 */
   1046             SOC_COUNTER_NON_DMA_EFP_PKT,
   1047             SOC_COUNTER_NON_DMA_EFP_BYTE,
   1048             EFP_COUNTER_TABLEm,
   1049             0
   1050         }
   1051     };
   1052 
   1053     soc = SOC_CONTROL(unit);
   1054 
   1055     if (soc->counter_evict == NULL) {
   1056         /* memory_id 0 is reserved, allocate 1 extra entries */
   1057         soc->counter_evict = sal_alloc(sizeof(soc_counter_evict_t) * 27,
   1058                                        "Tomahawk counter_evict");
   1059         if (soc->counter_evict == NULL) {
   1060             return SOC_E_MEMORY;
   1061         }
   1062     }
   1063 
   1064     counter_id = -1;
   1065     soc->counter_evict_max_mem_id = 0;
   1066     for (mem_id = 1; mem_id < sizeof(evict_info) / sizeof(evict_info[0]);
   1067          mem_id++) {
   1068         evict = &soc->counter_evict[mem_id];
   1069         evict->pkt_counter_id = evict_info[mem_id].pkt_counter_id;
   1070         evict->byte_counter_id = evict_info[mem_id].byte_counter_id;
   1071         evict->pool_id = evict_info[mem_id].pool_id;
   1072         soc->counter_evict_max_mem_id = mem_id;
   1073         if (counter_id != evict->pkt_counter_id) {
   1074             offset = 0;
   1075             counter_id = evict->pkt_counter_id;
   1076         }
   1077         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1078             /* Skip if no enabled ports in pipe */
   1079             if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, pipe))) {
   1080                 continue;
   1081             }
   1082             evict->offset[pipe] = offset;
   1083             evict->mem[pipe] =
   1084                 SOC_MEM_UNIQUE_ACC(unit, evict_info[mem_id].mem)[pipe];
   1085             offset += soc_mem_index_count(unit, evict->mem[pipe]);
   1086         }
   1087     }
   1088 
   1089     return SOC_E_NONE;
   1090 }
   1091 
   1092 int
   1093 soc_counter_tomahawk_dma_flags_update(int unit, soc_counter_non_dma_t *ctr_dma,
   1094                                       uint32 flags, int val)
   1095 {
   1096     int rv = SOC_E_NONE;
   1097     int count = 0, subset_ct = 0;
   1098 
   1099     if ((ctr_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
   1100         (ctr_dma->extra_ctrs != NULL)) {
   1101         subset_ct = ctr_dma->extra_ctr_ct << 1;
   1102         ctr_dma = ctr_dma->extra_ctrs;
   1103     } else {
   1104         subset_ct = 1;
   1105     }
   1106 
   1107     do {
   1108         switch (flags) {
   1109             case _SOC_COUNTER_NON_DMA_CLEAR_ON_READ:
   1110                 /* Update only for CLR_ON_READ, until necessity calls for other
   1111                  * FLAGS */
   1112                 if (ctr_dma->flags & _SOC_COUNTER_NON_DMA_CTR_EVICT) {
   1113                     if (val) {
   1114                          ctr_dma->flags |= _SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   1115                     } else {
   1116                          ctr_dma->flags &= ~_SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   1117                     }
   1118                 }
   1119                 break;
   1120             case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_ALL:
   1121                 if (ctr_dma->flags & _SOC_COUNTER_NON_DMA_CTR_EVICT) {
   1122                     ctr_dma->dma_rate_profile = (val) ?
   1123                                        _SOC_COUNTER_DMA_RATE_PROFILE_ALL : 0;
   1124                 }
   1125                 break;
   1126             case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_AUTO:
   1127             case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_WFS:
   1128                 return SOC_E_UNAVAIL;
   1129             default:
   1130                 return SOC_E_PARAM;
   1131         }
   1132         count++;
   1133         ctr_dma++;
   1134     } while ((count < subset_ct) && ctr_dma);
   1135 
   1136     return rv;
   1137 }
   1138 
   1139 void
   1140 soc_counter_tomahawk_eviction_flags_update(int unit, uint32 flags, int enable)
   1141 {
   1142     soc_control_t *soc;
   1143     int idx = 0;
   1144     soc_counter_non_dma_t *non_dma = NULL;
   1145     soc = SOC_CONTROL(unit);
   1146 
   1147     if (soc->counter_non_dma == NULL) {
   1148         /* Counter_non_dma will be NULL after soc_counter_detach.
   1149          * Also soc_counter_detach is called during bcm_detach and soc_detach.
   1150          * Hence sanity check before accessing the pointer.
   1151          */
   1152         return;
   1153     }
   1154 
   1155 
   1156     for (idx = 0; idx < SOC_COUNTER_NON_DMA_END - SOC_COUNTER_NON_DMA_START;
   1157          idx++) {
   1158 #if defined(INCLUDE_TELEMETRY)
   1159         if (enable && SOC_CONTROL(unit)->uc_telemetry_enable) {
   1160             /* Disable CLEAR_ON_READ for telemetry feature */
   1161             int disable_idx = idx + SOC_COUNTER_NON_DMA_START;
   1162             if (disable_idx == SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT ||
   1163                 disable_idx == SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE ||
   1164                 disable_idx == SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC ||
   1165                 disable_idx == SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC) {
   1166                 continue;
   1167             }
   1168         }
   1169 #endif /* INCLUDE_TELEMETRY */
   1170 
   1171         non_dma = &soc->counter_non_dma[idx];
   1172         if (!non_dma || !(non_dma->flags & _SOC_COUNTER_NON_DMA_CTR_EVICT)) {
   1173             continue;
   1174         }
   1175         soc_counter_tomahawk_dma_flags_update(unit, non_dma, flags, enable);
   1176     }
   1177     return;
   1178 }
   1179 
   1180 int
   1181 soc_counter_tomahawk_eviction_enable(int unit, int enable)
   1182 {
   1183     soc_reg_t reg;
   1184     uint32 rval, flag = 0;
   1185     uint64 rval64;
   1186     int pipe, id, count;
   1187     soc_info_t *si;
   1188 
   1189     /* Counter Eviction cannot use Memory ID 0. */
   1190     static const soc_reg_t evict_regs[] = {
   1191         ING_FLEX_CTR_EVICTION_CONTROL_POOL_0r,  /* MEMORY_ID 1 */
   1192         ING_FLEX_CTR_EVICTION_CONTROL_POOL_1r,  /* MEMORY_ID 2 */
   1193         ING_FLEX_CTR_EVICTION_CONTROL_POOL_2r,  /* MEMORY_ID 3 */
   1194         ING_FLEX_CTR_EVICTION_CONTROL_POOL_3r,  /* MEMORY_ID 4 */
   1195         ING_FLEX_CTR_EVICTION_CONTROL_POOL_4r,  /* MEMORY_ID 5 */
   1196         ING_FLEX_CTR_EVICTION_CONTROL_POOL_5r,  /* MEMORY_ID 6 */
   1197         ING_FLEX_CTR_EVICTION_CONTROL_POOL_6r,  /* MEMORY_ID 7 */
   1198         ING_FLEX_CTR_EVICTION_CONTROL_POOL_7r,  /* MEMORY_ID 8 */
   1199         ING_FLEX_CTR_EVICTION_CONTROL_POOL_8r,  /* MEMORY_ID 9 */
   1200         ING_FLEX_CTR_EVICTION_CONTROL_POOL_9r,  /* MEMORY_ID 10 */
   1201         ING_FLEX_CTR_EVICTION_CONTROL_POOL_10r, /* MEMORY_ID 11 */
   1202         ING_FLEX_CTR_EVICTION_CONTROL_POOL_11r, /* MEMORY_ID 12 */
   1203         ING_FLEX_CTR_EVICTION_CONTROL_POOL_12r, /* MEMORY_ID 13 */
   1204         ING_FLEX_CTR_EVICTION_CONTROL_POOL_13r, /* MEMORY_ID 14 */
   1205         ING_FLEX_CTR_EVICTION_CONTROL_POOL_14r, /* MEMORY_ID 15 */
   1206         ING_FLEX_CTR_EVICTION_CONTROL_POOL_15r, /* MEMORY_ID 16 */
   1207         ING_FLEX_CTR_EVICTION_CONTROL_POOL_16r, /* MEMORY_ID 17 */
   1208         ING_FLEX_CTR_EVICTION_CONTROL_POOL_17r, /* MEMORY_ID 18 */
   1209         ING_FLEX_CTR_EVICTION_CONTROL_POOL_18r, /* MEMORY_ID 19 */
   1210         ING_FLEX_CTR_EVICTION_CONTROL_POOL_19r, /* MEMORY_ID 20 */
   1211         EGR_FLEX_CTR_EVICTION_CONTROL_POOL_0r,  /* MEMORY_ID 21 */
   1212         EGR_FLEX_CTR_EVICTION_CONTROL_POOL_1r,  /* MEMORY_ID 22 */
   1213         EGR_FLEX_CTR_EVICTION_CONTROL_POOL_2r,  /* MEMORY_ID 23 */
   1214         EGR_FLEX_CTR_EVICTION_CONTROL_POOL_3r,  /* MEMORY_ID 24 */
   1215         EGR_PERQ_EVICTION_CONTROLr,             /* MEMORY_ID 25 */
   1216         EGR_EFP_EVICTION_CONTROLr               /* MEMORY_ID 26 */
   1217     };
   1218     static const soc_reg_t seed_regs[] = {
   1219         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_0r,  /* MEMORY_ID 1 */
   1220         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_1r,  /* MEMORY_ID 2 */
   1221         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_2r,  /* MEMORY_ID 3 */
   1222         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_3r,  /* MEMORY_ID 4 */
   1223         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_4r,  /* MEMORY_ID 5 */
   1224         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_5r,  /* MEMORY_ID 6 */
   1225         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_6r,  /* MEMORY_ID 7 */
   1226         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_7r,  /* MEMORY_ID 8 */
   1227         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_8r,  /* MEMORY_ID 9 */
   1228         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_9r,  /* MEMORY_ID 10 */
   1229         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_10r, /* MEMORY_ID 11 */
   1230         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_11r, /* MEMORY_ID 12 */
   1231         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_12r, /* MEMORY_ID 13 */
   1232         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_13r, /* MEMORY_ID 14 */
   1233         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_14r, /* MEMORY_ID 15 */
   1234         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_15r, /* MEMORY_ID 16 */
   1235         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_16r, /* MEMORY_ID 17 */
   1236         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_17r, /* MEMORY_ID 18 */
   1237         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_18r, /* MEMORY_ID 19 */
   1238         ING_FLEX_CTR_EVICTION_LFSR_SEED_POOL_19r, /* MEMORY_ID 20 */
   1239         EGR_FLEX_CTR_EVICTION_LFSR_SEED_POOL_0r,  /* MEMORY_ID 21 */
   1240         EGR_FLEX_CTR_EVICTION_LFSR_SEED_POOL_1r,  /* MEMORY_ID 22 */
   1241         EGR_FLEX_CTR_EVICTION_LFSR_SEED_POOL_2r,  /* MEMORY_ID 23 */
   1242         EGR_FLEX_CTR_EVICTION_LFSR_SEED_POOL_3r,  /* MEMORY_ID 24 */
   1243         EGR_PERQ_EVICTION_SEEDr,                  /* MEMORY_ID 25 */
   1244         EGR_EFP_EVICTION_SEEDr                    /* MEMORY_ID 26 */
   1245 
   1246     };
   1247     static const soc_reg_t update_regs[] = {
   1248         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_0r,  /* MEMORY_ID 1 */
   1249         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_1r,  /* MEMORY_ID 2 */
   1250         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_2r,  /* MEMORY_ID 3 */
   1251         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_3r,  /* MEMORY_ID 4 */
   1252         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_4r,  /* MEMORY_ID 5 */
   1253         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_5r,  /* MEMORY_ID 6 */
   1254         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_6r,  /* MEMORY_ID 7 */
   1255         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_7r,  /* MEMORY_ID 8 */
   1256         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_8r,  /* MEMORY_ID 9 */
   1257         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_9r,  /* MEMORY_ID 10 */
   1258         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_10r, /* MEMORY_ID 11 */
   1259         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_11r, /* MEMORY_ID 12 */
   1260         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_12r, /* MEMORY_ID 13 */
   1261         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_13r, /* MEMORY_ID 14 */
   1262         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_14r, /* MEMORY_ID 15 */
   1263         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_15r, /* MEMORY_ID 16 */
   1264         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_16r, /* MEMORY_ID 17 */
   1265         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_17r, /* MEMORY_ID 18 */
   1266         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_18r, /* MEMORY_ID 19 */
   1267         ING_FLEX_CTR_COUNTER_UPDATE_CONTROL_19r, /* MEMORY_ID 20 */
   1268         EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_0r,  /* MEMORY_ID 21 */
   1269         EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_1r,  /* MEMORY_ID 22 */
   1270         EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_2r,  /* MEMORY_ID 23 */
   1271         EGR_FLEX_CTR_COUNTER_UPDATE_CONTROL_3r,  /* MEMORY_ID 24 */
   1272         EGR_PERQ_CNTR_UPDATE_CONTROLr,           /* MEMORY_ID 25 */
   1273         EGR_EFP_CNTR_UPDATE_CONTROLr             /* MEMORY_ID 26 */
   1274     };
   1275     static const soc_reg_t threshold_regs[] = {
   1276         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_0r,  /* MEMORY_ID 1 */
   1277         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_1r,  /* MEMORY_ID 2 */
   1278         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_2r,  /* MEMORY_ID 3 */
   1279         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_3r,  /* MEMORY_ID 4 */
   1280         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_4r,  /* MEMORY_ID 5 */
   1281         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_5r,  /* MEMORY_ID 6 */
   1282         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_6r,  /* MEMORY_ID 7 */
   1283         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_7r,  /* MEMORY_ID 8 */
   1284         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_8r,  /* MEMORY_ID 9 */
   1285         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_9r,  /* MEMORY_ID 10 */
   1286         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_10r, /* MEMORY_ID 11 */
   1287         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_11r, /* MEMORY_ID 12 */
   1288         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_12r, /* MEMORY_ID 13 */
   1289         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_13r, /* MEMORY_ID 14 */
   1290         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_14r, /* MEMORY_ID 15 */
   1291         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_15r, /* MEMORY_ID 16 */
   1292         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_16r, /* MEMORY_ID 17 */
   1293         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_17r, /* MEMORY_ID 18 */
   1294         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_18r, /* MEMORY_ID 19 */
   1295         ING_FLEX_CTR_EVICTION_THRESHOLD_POOL_19r, /* MEMORY_ID 20 */
   1296         EGR_FLEX_CTR_EVICTION_THRESHOLD_POOL_0r,  /* MEMORY_ID 21 */
   1297         EGR_FLEX_CTR_EVICTION_THRESHOLD_POOL_1r,  /* MEMORY_ID 22 */
   1298         EGR_FLEX_CTR_EVICTION_THRESHOLD_POOL_2r,  /* MEMORY_ID 23 */
   1299         EGR_FLEX_CTR_EVICTION_THRESHOLD_POOL_3r,  /* MEMORY_ID 24 */
   1300         EGR_PERQ_EVICTION_THRESHOLDr,             /* MEMORY_ID 25 */
   1301         EGR_EFP_EVICTION_THRESHOLDr               /* MEMORY_ID 26 */
   1302     };
   1303     int field_len = 0, i;
   1304     uint8 thd_percentage = 0;
   1305     soc_field_t threshold_field[] = {THRESHOLD_PKTSf,
   1306                                      THRESHOLD_BYTESf};
   1307     uint64 threshold64, temp64;
   1308 
   1309     si = &SOC_INFO(unit);
   1310 
   1311     if (!(SOC_CONTROL(unit)->soc_flags & SOC_F_INITED)) {
   1312         /* Soc is Not yet initialized. Do Nothing.
   1313          */
   1314         return SOC_E_NONE;
   1315     }
   1316 
   1317     COMPILER_64_SET(temp64, 0, 100); /* For percentage calculation */
   1318     count = COUNTOF(evict_regs);
   1319     if (enable) {
   1320         rval = 0;
   1321         reg = CENTRAL_CTR_EVICTION_CONTROLr;
   1322         soc_reg_field_set(unit, reg, &rval, NUM_CE_PER_PIPEf, count);
   1323         soc_reg_field_set(unit, reg, &rval, FIFO_ENABLEf, 1);
   1324         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1325 
   1326         rval = 0;
   1327         if (soc_feature(unit, soc_feature_th_a0_sw_war)) {
   1328             /* Set Evict Mode as Threshold Mode */
   1329             soc_reg_field_set(unit, evict_regs[0], &rval, MODEf, 2);
   1330             /* Set Threshold at 50% limit for both PKT and BYTE. */
   1331             thd_percentage = 50;
   1332         } else {
   1333             /* Set Evict Mode as Random Mode */
   1334             soc_reg_field_set(unit, evict_regs[0], &rval, MODEf, 1);
   1335             /* Set Threshold at 90% limit for both PKT and BYTE. */
   1336             thd_percentage = 90;
   1337         }
   1338         for (id = 0; id < count; id++) {
   1339 #if defined(INCLUDE_FLOWTRACKER)
   1340          if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
   1341               soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
   1342               soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
   1343             if ((id  < BCM_STAT_TH_FLEX_COUNTER_MAX_POOL) &&
   1344                 _bcm_esw_stat_pool_reserved(unit, bcmStatFlexDirectionIngress, id)) {
   1345                 /* Set Evict Mode as disable Mode */
   1346                 soc_reg_field_set(unit, evict_regs[0], &rval, MODEf, 0);
   1347             } else {
   1348                 if (soc_feature(unit, soc_feature_th_a0_sw_war)) {
   1349                     /* Set Evict Mode as Threshold Mode */
   1350                     soc_reg_field_set(unit, evict_regs[0], &rval, MODEf, 2);
   1351                 } else {
   1352                     /* Set Evict Mode as Random Mode */
   1353                     soc_reg_field_set(unit, evict_regs[0], &rval, MODEf, 1);
   1354                 }
   1355             }
   1356        }
   1357 #endif
   1358             soc_reg_field_set(unit, evict_regs[id], &rval, MEMORY_IDf, id + 1);
   1359             for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1360                  if (SOC_PBMP_IS_NULL(si->pipe_pbm[pipe])) {
   1361                     continue;
   1362                 }
   1363                 reg = SOC_REG_UNIQUE_ACC(unit, evict_regs[id])[pipe];
   1364                 soc_reg_field_set(unit, reg, &rval, PIPE_IDf, pipe);
   1365                 SOC_IF_ERROR_RETURN
   1366                     (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1367             }
   1368         }
   1369 
   1370 #if defined(INCLUDE_TELEMETRY)
   1371         if (SOC_CONTROL(unit)->uc_telemetry_enable) {
   1372             for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1373                 reg = SOC_REG_UNIQUE_ACC(unit, EGR_PERQ_EVICTION_CONTROLr)[pipe];
   1374                 SOC_IF_ERROR_RETURN
   1375                     (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1376                 soc_reg_field_set(unit, reg, &rval, MODEf, 0);
   1377                 SOC_IF_ERROR_RETURN
   1378                     (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1379             }
   1380         }
   1381 #endif /* INCLUDE_TELEMETRY */
   1382 
   1383         field_len = 0;
   1384         COMPILER_64_ZERO(rval64);
   1385         for (i = 0; i < COUNTOF(threshold_field); i++) {
   1386             field_len = soc_reg_field_length(unit, threshold_regs[0],
   1387                                              threshold_field[i]);
   1388             COMPILER_64_ZERO(threshold64);
   1389 
   1390             if (field_len >= 32) {
   1391                 COMPILER_64_SET(threshold64, (1 << (field_len - 32)), 0);
   1392 
   1393             } else {
   1394                 COMPILER_64_SET(threshold64, 0, (1 << field_len));
   1395             }
   1396             COMPILER_64_UMUL_32(threshold64, thd_percentage);
   1397             COMPILER_64_UDIV_64(threshold64, temp64);
   1398             soc_reg64_field_set(unit, threshold_regs[0], &rval64,
   1399                                 threshold_field[i], threshold64);
   1400         }
   1401         for (id = 0; id < count; id++) {
   1402             SOC_IF_ERROR_RETURN
   1403                 (soc_reg_set(unit, threshold_regs[id], REG_PORT_ANY, 0, rval64));
   1404         }
   1405 
   1406         COMPILER_64_ZERO(rval64);
   1407         for (id = 0; id < count; id++) {
   1408             for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1409                 int seed_val = 0;
   1410                 /* Skip if no enabled ports in pipe */
   1411                 if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, pipe))) {
   1412                     continue;
   1413                 }
   1414                 reg = SOC_REG_UNIQUE_ACC(unit, seed_regs[id])[pipe];
   1415                 /* Arbitrarily pick a different seed for each table */
   1416                 seed_val = ((id + 1) << 16) + pipe;
   1417                 soc_reg64_field32_set(unit, reg, &rval64, SEEDf, seed_val);
   1418                 SOC_IF_ERROR_RETURN
   1419                     (soc_reg64_set(unit, reg, REG_PORT_ANY, 0, rval64));
   1420             }
   1421         }
   1422 
   1423         rval = 0;
   1424         soc_reg_field_set(unit, update_regs[0], &rval, COUNTER_POOL_ENABLEf,
   1425                           1);
   1426         soc_reg_field_set(unit, update_regs[0], &rval, CLR_ON_READf, 1);
   1427         for (id = 0; id < count; id++) {
   1428 #if defined(INCLUDE_FLOWTRACKER)
   1429          if ((soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
   1430               soc_feature(unit, soc_feature_uc_flowtracker_export)) ||
   1431               soc_feature(unit, soc_feature_mv2_style_flowtracker)) {
   1432             if ((id  < BCM_STAT_TH_FLEX_COUNTER_MAX_POOL) &&
   1433                 _bcm_esw_stat_pool_reserved(unit, bcmStatFlexDirectionIngress, id)) {
   1434                 continue;
   1435             }
   1436         }
   1437 #endif
   1438             reg = update_regs[id];
   1439             SOC_IF_ERROR_RETURN
   1440                 (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1441         }
   1442         if (soc_feature(unit, soc_feature_th_a0_sw_war)) {
   1443             reg = EGR_EFP_CNTR_UPDATE_CONTROLr;
   1444             soc_reg_field_set(unit, reg, &rval, CLR_ON_READf, 0);
   1445             SOC_IF_ERROR_RETURN (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1446         }
   1447 
   1448 #if defined(INCLUDE_TELEMETRY)
   1449         if (SOC_CONTROL(unit)->uc_telemetry_enable) {
   1450             reg = EGR_PERQ_CNTR_UPDATE_CONTROLr;
   1451             soc_reg_field_set(unit, reg, &rval, CLR_ON_READf, 0);
   1452             SOC_IF_ERROR_RETURN (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1453         }
   1454 #endif /* INCLUDE_TELEMETRY */
   1455     } else {
   1456         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1457             if (SOC_PBMP_IS_NULL(si->pipe_pbm[pipe])) {
   1458                 continue;
   1459             }
   1460             for (id = 0; id < count; id++) {
   1461                 reg = SOC_REG_UNIQUE_ACC(unit, evict_regs[id])[pipe];
   1462                 SOC_IF_ERROR_RETURN
   1463                     (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0));
   1464             }
   1465         }
   1466 
   1467         /* Leave the seed regs as is */
   1468 
   1469         for (id = 0; id < count; id++) {
   1470             rval = 0;
   1471 
   1472             if (soc_feature(unit, soc_feature_th_a0_sw_war)) {
   1473                 COMPILER_64_ZERO(rval64);
   1474                 SOC_IF_ERROR_RETURN
   1475                     (soc_reg_set(unit, threshold_regs[id], REG_PORT_ANY, 0, rval64));
   1476             }
   1477 #if defined(INCLUDE_FLOWTRACKER)
   1478             if (soc_feature(unit, soc_feature_uc_flowtracker_learn) &&
   1479                 soc_feature(unit, soc_feature_uc_flowtracker_export)) {
   1480                 if ((id < BCM_STAT_TH_FLEX_COUNTER_MAX_POOL) &&
   1481                     _bcm_esw_stat_pool_reserved(unit, bcmStatFlexDirectionIngress, id)) {
   1482                     continue;
   1483                 }
   1484             }
   1485 #endif
   1486             /* Always have Counter enabled */
   1487             soc_reg_field_set(unit, update_regs[0], &rval, COUNTER_POOL_ENABLEf,
   1488                               1);
   1489             reg = update_regs[id];
   1490             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1491         }
   1492 
   1493         reg = CENTRAL_CTR_EVICTION_CONTROLr;
   1494         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0));
   1495     }
   1496 
   1497     flag = _SOC_COUNTER_NON_DMA_CLEAR_ON_READ;
   1498     soc_counter_tomahawk_eviction_flags_update(unit, flag, enable);
   1499     return SOC_E_NONE;
   1500 }
   1501 
   1502 int
   1503 soc_counter_th_extra_ctrs_init(int unit, soc_reg_t id,
   1504                                soc_counter_non_dma_t *non_dma_parent,
   1505                                soc_counter_non_dma_t *non_dma_extra,
   1506                                uint32 extra_ctr_ct,
   1507                                int *total_entries)
   1508 {
   1509     int i, pipe, count = 0;
   1510     soc_mem_t *base_mem_array = NULL, base_mem = INVALIDm;
   1511     int base_mem_ct = 0;
   1512     int parent_base_index = 0;
   1513     uint8 mmu_mem = FALSE;
   1514     int xpe;
   1515 
   1516     soc_mem_t ing_flex_mems[] = {
   1517         ING_FLEX_CTR_COUNTER_TABLE_0m,   /* MEMORYID 1 */
   1518         ING_FLEX_CTR_COUNTER_TABLE_1m,   /* MEMORYID 2 */
   1519         ING_FLEX_CTR_COUNTER_TABLE_2m,   /* MEMORYID 3 */
   1520         ING_FLEX_CTR_COUNTER_TABLE_3m,   /* MEMORYID 4 */
   1521         ING_FLEX_CTR_COUNTER_TABLE_4m,   /* MEMORYID 5 */
   1522         ING_FLEX_CTR_COUNTER_TABLE_5m,   /* MEMORYID 6 */
   1523         ING_FLEX_CTR_COUNTER_TABLE_6m,   /* MEMORYID 7 */
   1524         ING_FLEX_CTR_COUNTER_TABLE_7m,   /* MEMORYID 8 */
   1525         ING_FLEX_CTR_COUNTER_TABLE_8m,   /* MEMORYID 9 */
   1526         ING_FLEX_CTR_COUNTER_TABLE_9m,   /* MEMORYID 10 */
   1527         ING_FLEX_CTR_COUNTER_TABLE_10m,  /* MEMORYID 11 */
   1528         ING_FLEX_CTR_COUNTER_TABLE_11m,  /* MEMORYID 12 */
   1529         ING_FLEX_CTR_COUNTER_TABLE_12m,  /* MEMORYID 13 */
   1530         ING_FLEX_CTR_COUNTER_TABLE_13m,  /* MEMORYID 14 */
   1531         ING_FLEX_CTR_COUNTER_TABLE_14m,  /* MEMORYID 15 */
   1532         ING_FLEX_CTR_COUNTER_TABLE_15m,  /* MEMORYID 16 */
   1533         ING_FLEX_CTR_COUNTER_TABLE_16m,  /* MEMORYID 17 */
   1534         ING_FLEX_CTR_COUNTER_TABLE_17m,  /* MEMORYID 18 */
   1535         ING_FLEX_CTR_COUNTER_TABLE_18m,  /* MEMORYID 19 */
   1536         ING_FLEX_CTR_COUNTER_TABLE_19m   /* MEMORYID 20 */
   1537     };
   1538 
   1539     soc_mem_t egr_flex_mems[] = {
   1540         EGR_FLEX_CTR_COUNTER_TABLE_0m,   /* MEMORYID 21 */
   1541         EGR_FLEX_CTR_COUNTER_TABLE_1m,   /* MEMORYID 22 */
   1542         EGR_FLEX_CTR_COUNTER_TABLE_2m,   /* MEMORYID 23 */
   1543         EGR_FLEX_CTR_COUNTER_TABLE_3m   /* MEMORYID 24 */
   1544     };
   1545 
   1546     /* DO SANITY CHECK FOR INPUT PARAMs */
   1547     if (!(non_dma_parent->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
   1548         /* Only for Extra counters */
   1549         return SOC_E_PARAM;
   1550     }
   1551 
   1552     parent_base_index = non_dma_parent->base_index;
   1553     *total_entries = 0;
   1554 
   1555     switch (id) {
   1556         case SOC_COUNTER_NON_DMA_ING_FLEX_PKT:
   1557         case SOC_COUNTER_NON_DMA_ING_FLEX_BYTE:
   1558             base_mem_array = ing_flex_mems;
   1559             count = sizeof(ing_flex_mems) / sizeof(ing_flex_mems[0]);
   1560             break;
   1561         case SOC_COUNTER_NON_DMA_EGR_FLEX_PKT:
   1562         case SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE:
   1563             base_mem_array = egr_flex_mems;
   1564             count = sizeof(egr_flex_mems) / sizeof(egr_flex_mems[0]);
   1565             break;
   1566         case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT:
   1567         case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE:
   1568         case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC:
   1569         case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC:
   1570         case SOC_COUNTER_NON_DMA_QUEUE_PEAK:
   1571         case SOC_COUNTER_NON_DMA_QUEUE_CURRENT:
   1572         case SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK:
   1573         case SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT:
   1574         case SOC_COUNTER_NON_DMA_PG_MIN_PEAK:
   1575         case SOC_COUNTER_NON_DMA_PG_MIN_CURRENT:
   1576         case SOC_COUNTER_NON_DMA_PG_SHARED_PEAK:
   1577         case SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT:
   1578         case SOC_COUNTER_NON_DMA_PG_HDRM_PEAK:
   1579         case SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT:
   1580         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING:
   1581         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING:
   1582         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW:
   1583         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED:
   1584         case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN:
   1585         case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW:
   1586         case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED:
   1587         case SOC_COUNTER_NON_DMA_COSQ_DROP_WRED_PKT:
   1588             mmu_mem = TRUE;
   1589             count = NUM_XPE(unit);
   1590 
   1591             /* Get the mem attributes(Max idx) from the first child,
   1592              * which could be used for other instances.
   1593              * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   1594              */
   1595             base_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, non_dma_parent->mem,
   1596                                                    0, 0);
   1597             if (base_mem != INVALIDm) {
   1598                 /* XPE 0/PIPE 0 combination is true for both IP/EP */
   1599                 base_mem_ct = soc_mem_index_max(unit, base_mem) + 1;
   1600             }
   1601             break;
   1602         default:
   1603             return SOC_E_INTERNAL;
   1604     }
   1605 
   1606     if (extra_ctr_ct > count) {
   1607         return SOC_E_INTERNAL;
   1608     }
   1609 
   1610     for (i = 0; i < count; i++) {
   1611         if (mmu_mem == FALSE) {
   1612             int entries_per_pipe = 0;
   1613             non_dma_extra->mem = base_mem_array[i];
   1614             base_mem_ct = soc_mem_index_count(unit, non_dma_extra->mem);
   1615 
   1616             /* Set Child attributes */
   1617             non_dma_extra->base_index = parent_base_index + *total_entries;
   1618             non_dma_extra->num_entries = NUM_PIPE(unit) * base_mem_ct;
   1619 
   1620             /* Inherit few info from the Parent */
   1621             non_dma_extra->flags = (non_dma_parent->flags &
   1622                                     ~_SOC_COUNTER_NON_DMA_SUBSET_PARENT) |
   1623                                     _SOC_COUNTER_NON_DMA_SUBSET_CHILD;
   1624 
   1625             non_dma_extra->cname = sal_alloc(sal_strlen(non_dma_parent->cname) + 9,
   1626                                              "Extra ctrs cname");
   1627 
   1628             if (non_dma_extra->cname == NULL) {
   1629                 return SOC_E_MEMORY;
   1630             }
   1631             sal_sprintf(non_dma_extra->cname, "*%s_PL%d",
   1632                         non_dma_parent->cname, i);
   1633             
   1634             non_dma_extra->field = non_dma_parent->field;
   1635             non_dma_extra->reg = non_dma_parent->reg;
   1636 
   1637             for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1638                 non_dma_extra->dma_mem[pipe] = 
   1639                     SOC_MEM_UNIQUE_ACC(unit, non_dma_extra->mem)[pipe];
   1640 
   1641                 non_dma_extra->dma_index_max[pipe] = 
   1642                     soc_mem_index_max(unit, non_dma_extra->dma_mem[pipe]);
   1643                 non_dma_extra->dma_index_min[pipe] = 0;
   1644                 non_dma_extra->dma_buf[pipe] = non_dma_parent->dma_buf[pipe];
   1645                 entries_per_pipe = (non_dma_extra->dma_index_max[pipe] -
   1646                                    non_dma_extra->dma_index_min[pipe] + 1);
   1647                 non_dma_extra->dma_num_entries[pipe] = entries_per_pipe;
   1648                 *total_entries += entries_per_pipe;
   1649             }
   1650             /* Allocation of Child Control blocks.
   1651              * [0],..<even indices> - PKT_CTR non_dma ctrl block
   1652              * [1],..<odd indices> - BYTE_CTR non_dma ctrl block
   1653              * Hence in below code, jump by 2, so all similar control blocks are
   1654              * initilized at the same time.
   1655              */
   1656             non_dma_extra += 2;
   1657             /* coverity[check_after_deref] */
   1658             if (!non_dma_extra) {
   1659                 /* ERR: Cannot be NULL, until 'i reaches 'count' */
   1660                 /* This condition may not hit but intentional for defensive check */
   1661                 /* coverity[dead_error_line] */
   1662                 return SOC_E_INTERNAL;
   1663             }
   1664         } else { /* (mmu_mem == TRUE) */
   1665             int entries_per_xpe = 0;
   1666             int entries_per_pipe = 0;
   1667             xpe = i;
   1668             /* Inherit few info from the Parent */
   1669             non_dma_extra->flags = (non_dma_parent->flags &
   1670                                     ~_SOC_COUNTER_NON_DMA_SUBSET_PARENT) |
   1671                                     _SOC_COUNTER_NON_DMA_SUBSET_CHILD;
   1672 
   1673             non_dma_extra->cname = non_dma_parent->cname;
   1674             non_dma_extra->field = non_dma_parent->field;
   1675             non_dma_extra->reg = non_dma_parent->reg;
   1676             non_dma_extra->entries_per_port = non_dma_parent->entries_per_port;
   1677             non_dma_extra->id = non_dma_parent->id;
   1678             non_dma_extra->num_valid_pipe = 0;
   1679 
   1680             /* Set Child attributes */
   1681             non_dma_extra->base_index = parent_base_index + *total_entries;
   1682             if (non_dma_parent->mem != MMU_CTR_COLOR_DROP_MEMm ||
   1683                 (non_dma_parent->mem == MMU_CTR_COLOR_DROP_MEMm &&
   1684                 SOC_IS_TOMAHAWK2(unit))) {
   1685                 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1686                     non_dma_extra->dma_mem[pipe] =
   1687                         SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, non_dma_parent->mem,
   1688                                                     xpe, pipe);
   1689                     non_dma_extra->dma_index_min[pipe] = 0;
   1690 
   1691                     if (non_dma_extra->dma_mem[pipe] != INVALIDm) {
   1692                         if (non_dma_parent->mem == MMU_CTR_COLOR_DROP_MEMm) {
   1693                             switch(non_dma_extra->id) {
   1694                                 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED:
   1695                                     non_dma_extra->dma_index_min[pipe] = 0;
   1696                                     non_dma_extra->dma_index_max[pipe] = 33;
   1697                                     break;
   1698                                 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW:
   1699                                     non_dma_extra->dma_index_min[pipe] = 34;
   1700                                     non_dma_extra->dma_index_max[pipe] = 67;
   1701                                     break;              
   1702                                 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN:
   1703                                     non_dma_extra->dma_index_min[pipe] = 68;
   1704                                     non_dma_extra->dma_index_max[pipe] = 101;
   1705                                     break;
   1706                                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED:
   1707                                     non_dma_extra->dma_index_min[pipe] = 102;
   1708                                     non_dma_extra->dma_index_max[pipe] = 135;
   1709                                     break;
   1710                                 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW:
   1711                                     non_dma_extra->dma_index_min[pipe] = 136;
   1712                                     non_dma_extra->dma_index_max[pipe] = 169;
   1713                                     break;
   1714                                 default:
   1715                                     return SOC_E_PARAM;
   1716                             }
   1717                         } else {
   1718                             non_dma_extra->dma_index_max[pipe] = base_mem_ct - 1;
   1719                         }
   1720                         non_dma_extra->dma_buf[pipe] = non_dma_parent->dma_buf[pipe];
   1721                     } else {
   1722                         non_dma_extra->dma_index_max[pipe] = -1;
   1723                     }
   1724 
   1725                     entries_per_pipe = (non_dma_extra->dma_index_max[pipe] -
   1726                                        non_dma_extra->dma_index_min[pipe] + 1);
   1727                     if (entries_per_pipe > 0) {
   1728                         non_dma_extra->num_valid_pipe ++;
   1729                     }
   1730                     non_dma_extra->dma_num_entries[pipe] = entries_per_pipe;
   1731                     entries_per_xpe += entries_per_pipe;
   1732                     *total_entries += entries_per_pipe;
   1733                 }
   1734                 non_dma_extra->num_entries = entries_per_xpe;
   1735                 non_dma_extra->mem = non_dma_parent->mem;
   1736             } else {
   1737                 non_dma_extra->dma_mem[0] = 
   1738                     SOC_MEM_UNIQUE_ACC(unit, non_dma_parent->mem)[xpe];
   1739                 if(non_dma_extra->dma_mem[0] == INVALIDm) {
   1740                     return SOC_E_INTERNAL;
   1741                 }
   1742                 for (pipe = 1; pipe < NUM_PIPE(unit); pipe++) {
   1743                     non_dma_extra->dma_mem[pipe] = INVALIDm;
   1744                 }
   1745                 non_dma_extra->dma_num_entries[0] =
   1746                     soc_mem_index_count(unit, non_dma_extra->dma_mem[0]);
   1747                 if (non_dma_extra->dma_mem[0] != INVALIDm) {
   1748                     non_dma_extra->dma_buf[0] = non_dma_parent->dma_buf[0];
   1749                     switch(non_dma_extra->id) {
   1750                         case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED:
   1751                             non_dma_extra->dma_index_min[0] = 0;
   1752                             non_dma_extra->dma_index_max[0] = 67;
   1753                             break;
   1754                         case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW:
   1755                             non_dma_extra->dma_index_min[0] = 68;
   1756                             non_dma_extra->dma_index_max[0]= 135;
   1757                             break;              
   1758                         case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN:
   1759                             non_dma_extra->dma_index_min[0] = 136;
   1760                             non_dma_extra->dma_index_max[0] = 203;
   1761                             break;
   1762                         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED:
   1763                             non_dma_extra->dma_index_min[0] = 204;
   1764                             non_dma_extra->dma_index_max[0] = 271;
   1765                             break;
   1766                         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW:
   1767                             non_dma_extra->dma_index_min[0] = 272;
   1768                             non_dma_extra->dma_index_max[0] = 339;
   1769                             break;
   1770                         default:
   1771                             return SOC_E_PARAM;
   1772                     }
   1773                     entries_per_xpe = 68;
   1774                     *total_entries += entries_per_xpe;
   1775                     non_dma_extra->mem = non_dma_parent->mem;
   1776                     non_dma_extra->num_entries += entries_per_xpe;
   1777                 } else {
   1778                         non_dma_extra->dma_index_min[0] = 0;
   1779                         non_dma_extra->dma_index_max[0] = -1;
   1780                 }
   1781             }
   1782 
   1783 
   1784             /* Allocation of Child Control blocks.
   1785              * [0],..<even indices> - PKT_CTR non_dma ctrl block
   1786              * [1],..<odd indices> - BYTE_CTR non_dma ctrl block
   1787              * Hence in below code, jump by 2, so all similar control blocks are
   1788              * initilized at the same time.
   1789              */
   1790             non_dma_extra += 2;
   1791             /* coverity[check_after_deref] */
   1792             if (!non_dma_extra) {
   1793                 /* ERR: Cannot be NULL, until 'i reaches 'count' */
   1794                 /* coverity[dead_error_line] */
   1795                 return SOC_E_INTERNAL;
   1796             }
   1797         }
   1798 
   1799     }
   1800 
   1801     return SOC_E_NONE;
   1802 }
   1803 
   1804 /* Function to initialize sFlow extra counters */
   1805 int
   1806 soc_counter_th_extra_sflow_ctrs_init(int unit,
   1807                                soc_counter_non_dma_t *non_dma_parent,
   1808                                soc_counter_non_dma_t *non_dma_extra,
   1809                                uint32 extra_ctr_ct,
   1810                                int *total_entries)
   1811 {
   1812     int i, parent_base_index = 0;
   1813     int base_mem_ct = 0;
   1814     int do_dma = 1;
   1815     int pipe;
   1816 
   1817     soc_field_t sflow_counter_fields[] = {
   1818         SAMPLE_POOLf,
   1819         SAMPLE_POOL_SNAPSHOTf,
   1820         SAMPLE_COUNTf
   1821     };
   1822 
   1823     /* Do sanity check for input params */
   1824     if (!(non_dma_parent->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
   1825         /* Only for Extra counters */
   1826         return SOC_E_PARAM;
   1827     }
   1828 
   1829     parent_base_index = non_dma_parent->base_index;
   1830     *total_entries = 0;
   1831 
   1832     for (i = 0; i < extra_ctr_ct; i++) {
   1833         /* Set Child attributes. Inherit few info from the Parent */
   1834         non_dma_extra->mem = non_dma_parent->mem;
   1835         non_dma_extra->base_index = parent_base_index + *total_entries;
   1836         base_mem_ct = soc_mem_index_count(unit, non_dma_extra->mem);
   1837         non_dma_extra->num_entries = base_mem_ct;
   1838 
   1839         non_dma_extra->flags = (non_dma_parent->flags &
   1840                                 ~_SOC_COUNTER_NON_DMA_SUBSET_PARENT) |
   1841                                 _SOC_COUNTER_NON_DMA_SUBSET_CHILD;
   1842 
   1843         /* DMA should be done only once to get sFlow data table */
   1844         if (do_dma != 1) {
   1845             non_dma_extra->flags = (non_dma_extra->flags &
   1846                                     ~_SOC_COUNTER_NON_DMA_DO_DMA);
   1847         }
   1848 
   1849         non_dma_extra->cname = sal_alloc(sal_strlen(non_dma_parent->cname) + 9,
   1850                                          "Extra ctrs cname");
   1851 
   1852         if (non_dma_extra->cname == NULL) {
   1853             return SOC_E_MEMORY;
   1854         }
   1855 
   1856         sal_sprintf(non_dma_extra->cname, "*%s_CNTR%d",
   1857                     non_dma_parent->cname, i);
   1858 
   1859         non_dma_extra->field = sflow_counter_fields[i];
   1860         non_dma_extra->reg = non_dma_parent->reg;
   1861         non_dma_extra->dma_mem[0] = non_dma_parent->mem;
   1862 
   1863         /* No per-pipe instance for sFlow counters memory, hence pipe 1/2/3
   1864          * are assigned to INVALIDm
   1865          */
   1866         for (pipe = 1; pipe < NUM_PIPE(unit); pipe++) {
   1867             non_dma_extra->dma_mem[pipe] = INVALIDm;
   1868         }
   1869         non_dma_extra->dma_index_max[0] = soc_mem_index_max(unit,
   1870                                                         non_dma_parent->mem);
   1871         for (pipe = 1; pipe < NUM_PIPE(unit); pipe++) {
   1872             non_dma_extra->dma_index_max[pipe] = -1;
   1873         }
   1874         non_dma_extra->dma_index_min[0] = 0;
   1875         for (pipe = 1; pipe < NUM_PIPE(unit); pipe++) {
   1876             non_dma_extra->dma_index_min[pipe] = -1;
   1877         }
   1878         non_dma_extra->dma_buf[0] = non_dma_parent->dma_buf[0];
   1879 
   1880         *total_entries += (non_dma_extra->dma_index_max[0] -
   1881                            non_dma_extra->dma_index_min[0] + 1);
   1882 
   1883         /* Allocation of Child Control blocks.
   1884          * [0],..<even indices> - PKT_CTR non_dma ctrl block
   1885          * [1],..<odd indices> - BYTE_CTR non_dma ctrl block
   1886          * Hence in below code, jump by 2, so all similar control blocks are
   1887          * initilized at the same time.
   1888          */
   1889         non_dma_extra += 2;
   1890 
   1891         do_dma = 0;
   1892 
   1893         /* coverity[check_after_deref] */
   1894         if (!non_dma_extra) {
   1895             /* ERR: Cannot be NULL, until 'i reaches 'extra_ctr_ct' */
   1896             /* This condition may not hit but intentional for defensive check */
   1897             /* coverity[dead_error_line] */
   1898             return SOC_E_INTERNAL;
   1899         }
   1900     }
   1901 
   1902     return SOC_E_NONE;
   1903 }
   1904 
   1905 /* Function to initialize OBM extra counters */
   1906 int
   1907 soc_counter_th_extra_obm_ctrs_init(int unit,
   1908                                    soc_counter_non_dma_t *non_dma_parent,
   1909                                    soc_counter_non_dma_t *non_dma_extra,
   1910                                    uint32 extra_ctr_ct,
   1911                                    int *total_entries)
   1912 {
   1913 #define LOSSY_LO 0
   1914 #define LOSSY_HI 1
   1915 #define LOSSLESS0 2
   1916 #define LOSSLESS1 3
   1917     char obm_type_str[][12] = {"LOSSY_LO", "LOSSY_HI",
   1918                                "LOSSLESS0", "LOSSLESS1"}; /* For CNAME */
   1919     int i, byte_flag = 0, obm_type = 0, fc = 0, parent_base_index = 0;
   1920 
   1921     soc_reg_t obm_drop_pkt_regs[][4] = {
   1922         {IDB_OBM0_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM0_LOSSY_HI_PKT_DROP_COUNTr,
   1923          IDB_OBM0_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM0_LOSSLESS1_PKT_DROP_COUNTr
   1924         },
   1925         {IDB_OBM1_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM1_LOSSY_HI_PKT_DROP_COUNTr,
   1926          IDB_OBM1_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM1_LOSSLESS1_PKT_DROP_COUNTr
   1927         },
   1928         {IDB_OBM2_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM2_LOSSY_HI_PKT_DROP_COUNTr,
   1929          IDB_OBM2_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM2_LOSSLESS1_PKT_DROP_COUNTr
   1930         },
   1931         {IDB_OBM3_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM3_LOSSY_HI_PKT_DROP_COUNTr,
   1932          IDB_OBM3_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM3_LOSSLESS1_PKT_DROP_COUNTr
   1933         },
   1934         {IDB_OBM4_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM4_LOSSY_HI_PKT_DROP_COUNTr,
   1935          IDB_OBM4_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM4_LOSSLESS1_PKT_DROP_COUNTr
   1936         },
   1937         {IDB_OBM5_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM5_LOSSY_HI_PKT_DROP_COUNTr,
   1938          IDB_OBM5_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM5_LOSSLESS1_PKT_DROP_COUNTr
   1939         },
   1940         {IDB_OBM6_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM6_LOSSY_HI_PKT_DROP_COUNTr,
   1941          IDB_OBM6_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM6_LOSSLESS1_PKT_DROP_COUNTr
   1942         },
   1943         {IDB_OBM7_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM7_LOSSY_HI_PKT_DROP_COUNTr,
   1944          IDB_OBM7_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM7_LOSSLESS1_PKT_DROP_COUNTr
   1945         },
   1946 #ifdef BCM_TOMAHAWK2_SUPPORT
   1947         {IDB_OBM8_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM8_LOSSY_HI_PKT_DROP_COUNTr,
   1948          IDB_OBM8_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM8_LOSSLESS1_PKT_DROP_COUNTr
   1949         },
   1950         {IDB_OBM9_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM9_LOSSY_HI_PKT_DROP_COUNTr,
   1951          IDB_OBM9_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM9_LOSSLESS1_PKT_DROP_COUNTr
   1952         },
   1953         {IDB_OBM10_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM10_LOSSY_HI_PKT_DROP_COUNTr,
   1954          IDB_OBM10_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM10_LOSSLESS1_PKT_DROP_COUNTr
   1955         },
   1956         {IDB_OBM11_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM11_LOSSY_HI_PKT_DROP_COUNTr,
   1957          IDB_OBM11_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM11_LOSSLESS1_PKT_DROP_COUNTr
   1958         },
   1959         {IDB_OBM12_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM12_LOSSY_HI_PKT_DROP_COUNTr,
   1960          IDB_OBM12_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM12_LOSSLESS1_PKT_DROP_COUNTr
   1961         },
   1962         {IDB_OBM13_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM13_LOSSY_HI_PKT_DROP_COUNTr,
   1963          IDB_OBM13_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM13_LOSSLESS1_PKT_DROP_COUNTr
   1964         },
   1965         {IDB_OBM14_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM14_LOSSY_HI_PKT_DROP_COUNTr,
   1966          IDB_OBM14_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM14_LOSSLESS1_PKT_DROP_COUNTr
   1967         },
   1968         {IDB_OBM15_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM15_LOSSY_HI_PKT_DROP_COUNTr,
   1969          IDB_OBM15_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM15_LOSSLESS1_PKT_DROP_COUNTr
   1970         },
   1971 #endif
   1972     };
   1973     soc_reg_t obm_drop_byte_regs[][4] = {
   1974         {IDB_OBM0_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM0_LOSSY_HI_BYTE_DROP_COUNTr,
   1975          IDB_OBM0_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM0_LOSSLESS1_BYTE_DROP_COUNTr
   1976         },
   1977         {IDB_OBM1_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM1_LOSSY_HI_BYTE_DROP_COUNTr,
   1978          IDB_OBM1_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM1_LOSSLESS1_BYTE_DROP_COUNTr
   1979         },
   1980         {IDB_OBM2_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM2_LOSSY_HI_BYTE_DROP_COUNTr,
   1981          IDB_OBM2_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM2_LOSSLESS1_BYTE_DROP_COUNTr
   1982         },
   1983         {IDB_OBM3_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM3_LOSSY_HI_BYTE_DROP_COUNTr,
   1984          IDB_OBM3_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM3_LOSSLESS1_BYTE_DROP_COUNTr
   1985         },
   1986         {IDB_OBM4_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM4_LOSSY_HI_BYTE_DROP_COUNTr,
   1987          IDB_OBM4_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM4_LOSSLESS1_BYTE_DROP_COUNTr
   1988         },
   1989         {IDB_OBM5_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM5_LOSSY_HI_BYTE_DROP_COUNTr,
   1990          IDB_OBM5_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM5_LOSSLESS1_BYTE_DROP_COUNTr
   1991         },
   1992         {IDB_OBM6_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM6_LOSSY_HI_BYTE_DROP_COUNTr,
   1993          IDB_OBM6_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM6_LOSSLESS1_BYTE_DROP_COUNTr
   1994         },
   1995         {IDB_OBM7_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM7_LOSSY_HI_BYTE_DROP_COUNTr,
   1996          IDB_OBM7_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM7_LOSSLESS1_BYTE_DROP_COUNTr
   1997         },
   1998 #ifdef BCM_TOMAHAWK2_SUPPORT
   1999         {IDB_OBM8_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM8_LOSSY_HI_BYTE_DROP_COUNTr,
   2000          IDB_OBM8_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM8_LOSSLESS1_BYTE_DROP_COUNTr
   2001         },
   2002         {IDB_OBM9_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM9_LOSSY_HI_BYTE_DROP_COUNTr,
   2003          IDB_OBM9_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM9_LOSSLESS1_BYTE_DROP_COUNTr
   2004         },
   2005         {IDB_OBM10_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM10_LOSSY_HI_BYTE_DROP_COUNTr,
   2006          IDB_OBM10_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM10_LOSSLESS1_BYTE_DROP_COUNTr
   2007         },
   2008         {IDB_OBM11_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM11_LOSSY_HI_BYTE_DROP_COUNTr,
   2009          IDB_OBM11_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM11_LOSSLESS1_BYTE_DROP_COUNTr
   2010         },
   2011         {IDB_OBM12_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM12_LOSSY_HI_BYTE_DROP_COUNTr,
   2012          IDB_OBM12_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM12_LOSSLESS1_BYTE_DROP_COUNTr
   2013         },
   2014         {IDB_OBM13_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM13_LOSSY_HI_BYTE_DROP_COUNTr,
   2015          IDB_OBM13_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM13_LOSSLESS1_BYTE_DROP_COUNTr
   2016         },
   2017         {IDB_OBM14_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM14_LOSSY_HI_BYTE_DROP_COUNTr,
   2018          IDB_OBM14_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM14_LOSSLESS1_BYTE_DROP_COUNTr
   2019         },
   2020         {IDB_OBM15_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM15_LOSSY_HI_BYTE_DROP_COUNTr,
   2021          IDB_OBM15_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM15_LOSSLESS1_BYTE_DROP_COUNTr
   2022         },
   2023 #endif
   2024     };
   2025     soc_reg_t obm_fc_event_regs[] = {
   2026         IDB_OBM0_FLOW_CONTROL_EVENT_COUNTr,
   2027         IDB_OBM1_FLOW_CONTROL_EVENT_COUNTr,
   2028         IDB_OBM2_FLOW_CONTROL_EVENT_COUNTr,
   2029         IDB_OBM3_FLOW_CONTROL_EVENT_COUNTr,
   2030         IDB_OBM4_FLOW_CONTROL_EVENT_COUNTr,
   2031         IDB_OBM5_FLOW_CONTROL_EVENT_COUNTr,
   2032         IDB_OBM6_FLOW_CONTROL_EVENT_COUNTr,
   2033         IDB_OBM7_FLOW_CONTROL_EVENT_COUNTr,
   2034 #ifdef BCM_TOMAHAWK2_SUPPORT
   2035         IDB_OBM8_FLOW_CONTROL_EVENT_COUNTr,
   2036         IDB_OBM9_FLOW_CONTROL_EVENT_COUNTr,
   2037         IDB_OBM10_FLOW_CONTROL_EVENT_COUNTr,
   2038         IDB_OBM11_FLOW_CONTROL_EVENT_COUNTr,
   2039         IDB_OBM12_FLOW_CONTROL_EVENT_COUNTr,
   2040         IDB_OBM13_FLOW_CONTROL_EVENT_COUNTr,
   2041         IDB_OBM14_FLOW_CONTROL_EVENT_COUNTr,
   2042         IDB_OBM15_FLOW_CONTROL_EVENT_COUNTr,
   2043 #endif
   2044     };
   2045 
   2046     /* Do sanity check for input params */
   2047     if (!(non_dma_parent->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) {
   2048         /* Only for Extra counters */
   2049         return SOC_E_PARAM;
   2050     }
   2051     switch (non_dma_parent->id) {
   2052         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO:
   2053         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI:
   2054         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0:
   2055         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1:
   2056             byte_flag = 0;
   2057             break;
   2058         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO:
   2059         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI:
   2060         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0:
   2061         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1:
   2062             byte_flag = 1;
   2063             break;
   2064         case SOC_COUNTER_NON_DMA_PORT_OBM_FC_EVENTS:
   2065             fc = 1;
   2066             break;
   2067         default:
   2068             return SOC_E_PARAM;
   2069     }
   2070 
   2071     switch (non_dma_parent->id) {
   2072         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO:
   2073         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO:
   2074             obm_type = LOSSY_LO;
   2075             break;
   2076         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI:
   2077         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI:
   2078             obm_type = LOSSY_HI;
   2079             break;
   2080         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0:
   2081         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0:
   2082             obm_type = LOSSLESS0;
   2083             break;
   2084         case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1:
   2085         case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1:
   2086             obm_type = LOSSLESS1;
   2087             break;
   2088     }
   2089 
   2090     parent_base_index = non_dma_parent->base_index;
   2091     *total_entries = 0;
   2092 
   2093     for (i = 0; i < extra_ctr_ct; i++) {
   2094         *non_dma_extra = *non_dma_parent;
   2095         if (fc) {
   2096             non_dma_extra->reg = obm_fc_event_regs[i];
   2097         } else if (byte_flag == 0) {
   2098             non_dma_extra->reg = obm_drop_pkt_regs[i][obm_type];
   2099         } else {
   2100             non_dma_extra->reg = obm_drop_byte_regs[i][obm_type];
   2101         }
   2102         non_dma_extra->extra_ctrs = NULL;
   2103         non_dma_extra->extra_ctr_ct = 0;
   2104         non_dma_extra->base_index = parent_base_index + *total_entries;
   2105         non_dma_extra->flags = (non_dma_parent->flags &
   2106                                 ~_SOC_COUNTER_NON_DMA_SUBSET_PARENT) |
   2107                                 _SOC_COUNTER_NON_DMA_SUBSET_CHILD;
   2108 
   2109         non_dma_extra->cname = sal_alloc(sal_strlen(non_dma_parent->cname) + 9,
   2110                                          "Extra ctrs cname");
   2111 
   2112         if (non_dma_extra->cname == NULL) {
   2113             return SOC_E_MEMORY;
   2114         }
   2115 
   2116         if (fc) {
   2117             sal_sprintf(non_dma_extra->cname, "*OBM%d_FC_EVENTS", i);
   2118         } else {
   2119             sal_sprintf(non_dma_extra->cname, "*OBM%d_%s_DRP_%s",
   2120                         i, obm_type_str[obm_type], byte_flag ? "BYTE":"PKT");
   2121         }
   2122 
   2123         non_dma_extra->num_entries = non_dma_extra->entries_per_port *
   2124                                      NUM_PIPE(unit);
   2125         *total_entries += non_dma_extra->num_entries;
   2126 
   2127         /* Allocation of Child Control blocks.
   2128          * [0],..<even indices> - PKT_CTR non_dma ctrl block
   2129          * [1],..<odd indices> - BYTE_CTR non_dma ctrl block
   2130          * Hence in below code, jump by 2, so all similar control blocks are
   2131          * initilized at the same time.
   2132          */
   2133         non_dma_extra += 2;
   2134         /* coverity[check_after_deref] */
   2135         if (!non_dma_extra) {
   2136             /* ERR: Cannot be NULL, until 'i reaches 'extra_ctr_ct' */
   2137             /* This condition may not hit but intentional for defensive check */
   2138             /* coverity[dead_error_line] */
   2139             return SOC_E_INTERNAL;
   2140         }
   2141     }
   2142     return SOC_E_NONE;
   2143 }
   2144 
   2145 /* Function to update VALID flag for a given Counter id */
   2146 STATIC int
   2147 soc_counter_tomahawk_ctr_dma_valid_update(int unit, soc_reg_t id, uint8 enable)
   2148 {
   2149     soc_control_t *soc = SOC_CONTROL(unit);
   2150     soc_counter_non_dma_t *ctr_dma = NULL;
   2151     soc_counter_non_dma_t *parent_dma = NULL;
   2152     uint32 count = 0, subset_ct = 0; /* For Parent-Child Model */
   2153 
   2154     if ((id < SOC_COUNTER_NON_DMA_START) ||
   2155         (id >= SOC_COUNTER_NON_DMA_END)) {
   2156         /* Not supported */
   2157         return SOC_E_NONE;
   2158     }
   2159     parent_dma = ctr_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
   2160 
   2161     if (parent_dma == NULL) {
   2162         /* This condition may not hit but intentional for defensive check */
   2163         /* coverity[dead_error_line] */
   2164         return SOC_E_NONE;
   2165     }
   2166 
   2167     /* If there is subset of counters, use subset info for DMA */
   2168     if ((ctr_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) &&
   2169         (ctr_dma->extra_ctrs != NULL)) {
   2170         subset_ct = parent_dma->extra_ctr_ct;
   2171 
   2172         for (count = 0; count < subset_ct; count++) {
   2173             SOC_IF_ERROR_RETURN
   2174                 (_soc_counter_th_get_child_dma_by_idx(unit, parent_dma,
   2175                                                       count, &ctr_dma));
   2176             if (enable) {
   2177                 ctr_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
   2178             } else {
   2179                 ctr_dma->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   2180             }
   2181         }
   2182     }
   2183     if (enable) {
   2184         parent_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
   2185     } else {
   2186         parent_dma->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   2187     }
   2188     return SOC_E_NONE;
   2189 }
   2190 
   2191 
   2192 /* Function to disable few non_dma counters enabled during init.
   2193  */
   2194 int
   2195 soc_counter_tomahawk_ctr_dma_post_init(int unit)
   2196 {
   2197     int id = 0, i, idx_max = 0;
   2198     int disable_ids[] = {
   2199         SOC_COUNTER_NON_DMA_EFP_BYTE,
   2200         SOC_COUNTER_NON_DMA_EFP_PKT,
   2201         SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE,
   2202         SOC_COUNTER_NON_DMA_EGR_FLEX_PKT,
   2203         SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
   2204         SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
   2205         SOC_COUNTER_NON_DMA_SFLOW_ING_PKT,
   2206         SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT
   2207     };
   2208 
   2209     idx_max = sizeof(disable_ids)/sizeof(int);
   2210 
   2211     for (i = 0; i < idx_max; i++) {
   2212         id = disable_ids[i];
   2213         soc_counter_tomahawk_ctr_dma_valid_update(unit, id, 0);
   2214     }
   2215 
   2216     return SOC_E_NONE;
   2217 }
   2218 
   2219 /* Tomahawk: Counters are made of 2 types: 
   2220  * 1. Traditional Non-StatDma
   2221  * 2. Counter Eviction elligible counters. 
   2222  *
   2223  * When Counter Eviction is enabled, HW performs Clear on Read on the eviction
   2224  * enabled counters when a Read is performed.
   2225  *
   2226  * When Counter Eviction is disabled, all counters will work as in TD2.
   2227  */
   2228 int
   2229 soc_counter_tomahawk_non_dma_init(int unit, int nports,
   2230                                   int non_dma_start_index,
   2231                                   int *non_dma_entries)
   2232 {
   2233     soc_control_t *soc;
   2234     soc_counter_non_dma_t *non_dma0, *non_dma1, *non_dma2, *temp;
   2235     int rv = SOC_E_NONE, pipe;
   2236     int num_entries, alloc_size, entry_words, num_extra_ctr_entries;
   2237     int pool_count = 0;
   2238     soc_mem_t child_mem = INVALIDm;
   2239     uint32 *buf;
   2240     soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit);
   2241 
   2242     if (soc_ctr_ctrl == NULL) {
   2243         return SOC_E_INIT;
   2244     }
   2245 
   2246     soc = SOC_CONTROL(unit);
   2247     *non_dma_entries = 0;
   2248 
   2249     /* Registration of Chip specific functions to the Global Counter 
   2250      * control structure.
   2251      */
   2252     soc_ctr_ctrl->get_child_dma = soc_counter_tomahawk_get_child_dma;
   2253     soc_ctr_ctrl->dma_config_update = soc_counter_tomahawk_dma_flags_update;
   2254     soc_ctr_ctrl->port_obm_info_get = soc_tomahawk_port_obm_info_get;
   2255 
   2256     /* ING_FLEX_CTR_COUNTER_TABLE_0 is the largest table to be DMA'ed */
   2257     num_entries = soc_mem_index_count(unit, ING_FLEX_CTR_COUNTER_TABLE_0m);
   2258     entry_words = soc_mem_entry_words(unit, ING_FLEX_CTR_COUNTER_TABLE_0m);
   2259     alloc_size = NUM_PIPE(unit) * num_entries * sizeof(uint32) * entry_words;
   2260 
   2261     buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter");
   2262     if (buf == NULL) {
   2263         return SOC_E_MEMORY;
   2264     }
   2265     sal_memset(buf, 0, alloc_size);
   2266  
   2267     /* Ctrl block for EGR_PERQ */
   2268     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   2269                                      SOC_COUNTER_NON_DMA_START];
   2270     non_dma0->id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT;
   2271     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2272                       _SOC_COUNTER_NON_DMA_DO_DMA |
   2273                       _SOC_COUNTER_NON_DMA_ALLOC |
   2274                       _SOC_COUNTER_NON_DMA_CTR_EVICT;
   2275 
   2276     /* Clear on Read Flag set if eviction is enabled */
   2277     non_dma0->flags |= _SOC_COUNTER_NON_DMA_CTR_EVICT;
   2278     non_dma0->dma_rate_profile |= _SOC_COUNTER_DMA_RATE_PROFILE_ALL;
   2279 
   2280     non_dma0->pbmp = PBMP_ALL(unit);
   2281     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2282     non_dma0->entries_per_port = 48; /* cpu port has max number of queues */
   2283     non_dma0->num_entries =
   2284         NUM_PIPE(unit) * soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm);
   2285     non_dma0->mem = EGR_PERQ_XMT_COUNTERSm;
   2286     non_dma0->reg = INVALIDr;
   2287     non_dma0->field = PACKET_COUNTERf;
   2288     non_dma0->cname = "PERQ_PKT";
   2289     num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm);
   2290     entry_words = soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm);
   2291 
   2292     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2293         non_dma0->dma_mem[pipe] = 
   2294             SOC_MEM_UNIQUE_ACC(unit, non_dma0->mem)[pipe];
   2295         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   2296         non_dma0->dma_index_max[pipe] =
   2297             soc_mem_index_max(unit, non_dma0->dma_mem[pipe]);
   2298     }
   2299 
   2300     *non_dma_entries += non_dma0->num_entries;
   2301 
   2302     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   2303                                      SOC_COUNTER_NON_DMA_START];
   2304     *non_dma1 = *non_dma0;
   2305     non_dma1->id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE;
   2306     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   2307     /* Clear on Read Flag set if eviction is enabled */
   2308     non_dma1->flags |= _SOC_COUNTER_NON_DMA_CTR_EVICT;
   2309     non_dma0->dma_rate_profile |= _SOC_COUNTER_DMA_RATE_PROFILE0;
   2310 
   2311     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2312     non_dma1->field = BYTE_COUNTERf;
   2313     non_dma1->cname = "PERQ_BYTE";
   2314     *non_dma_entries += non_dma1->num_entries;
   2315 
   2316 
   2317     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC -
   2318                                      SOC_COUNTER_NON_DMA_START];
   2319     *non_dma2 = *non_dma0;
   2320     non_dma2->id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC;
   2321     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID;
   2322     /* Clear on Read Flag set if eviction is enabled */
   2323     non_dma2->flags |= _SOC_COUNTER_NON_DMA_CTR_EVICT;
   2324     non_dma2->dma_rate_profile |= _SOC_COUNTER_DMA_RATE_PROFILE0;
   2325 
   2326     non_dma2->pbmp = PBMP_PORT_ALL(unit);
   2327     non_dma2->entries_per_port = 10; /* 10 UC Qs Per port */
   2328     non_dma2->num_entries = 0;
   2329     non_dma2->cname = "UC_PERQ_PKT";
   2330 
   2331     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC -
   2332                                      SOC_COUNTER_NON_DMA_START];
   2333     *non_dma2 = *non_dma1;
   2334     non_dma2->id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC;
   2335     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID;
   2336     /* Clear on Read Flag set if eviction is enabled */
   2337     non_dma2->flags |= _SOC_COUNTER_NON_DMA_CTR_EVICT;
   2338     non_dma2->dma_rate_profile |= _SOC_COUNTER_DMA_RATE_PROFILE0;
   2339 
   2340     non_dma2->pbmp = PBMP_PORT_ALL(unit);
   2341     non_dma2->entries_per_port = 10; /* 10 UC Qs Per port */
   2342     non_dma2->num_entries = 0;
   2343     non_dma2->cname = "UC_PERQ_BYTE";
   2344 
   2345     if (!SOC_IS_TOMAHAWK3(unit)) {
   2346     /* Ctrl block for DROP_PKT_MC */
   2347     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   2348                                      SOC_COUNTER_NON_DMA_START];
   2349     non_dma0->id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT;
   2350     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2351                       _SOC_COUNTER_NON_DMA_DO_DMA |
   2352                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   2353     non_dma0->pbmp = PBMP_ALL(unit);
   2354     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2355     non_dma0->entries_per_port = 48; /* 48 for cpu port */
   2356     non_dma0->mem = MMU_CTR_MC_DROP_MEMm;
   2357 
   2358     /* Get the mem attributes(Max idx) from the first child,
   2359      * which could be used for other instances.
   2360      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   2361      */
   2362     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, non_dma0->mem, 0, 0);
   2363     num_entries = soc_mem_index_max(unit, child_mem) + 1;
   2364     entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   2365     non_dma0->num_entries = NUM_PIPE(unit) * num_entries;
   2366 
   2367     non_dma0->reg = INVALIDr;
   2368     non_dma0->field = PKTCNTf;
   2369     non_dma0->cname = "PERQ_DROP_PKT";
   2370 
   2371     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2372         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   2373     }
   2374 
   2375     non_dma0->extra_ctr_ct = NUM_XPE(unit);
   2376     /* Incl. buffer for BYTE_CTR. 2x alloc size*/
   2377     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   2378     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_perq_drop_mc");
   2379 
   2380 
   2381     /*
   2382      * Below represents how Extra cntrs are arranged
   2383      * for Per Queue(UC|MC) Drop Counters.
   2384      * n = NUM_XPE
   2385      *
   2386      *   [0]     [2]        [2n-2]
   2387      *  ------  ------     ------ 
   2388      * |      ||      |...|      |
   2389      * | PKT  || PKT  |...| PKT  |
   2390      * | [0]  || [1]  |...| [n-1]|
   2391      *  ------  ------ ... ------ 
   2392      * |      ||      |...|      |
   2393      * | BYTE || BYTE |...| BYTE |
   2394      * | [0]  || [1]  |...| [n-1]|
   2395      *  ------  ------     ------
   2396      *   [1]     [3]        [2n-1]
   2397      */
   2398     if (non_dma0->extra_ctrs == NULL) {
   2399         non_dma0->extra_ctr_ct = 0;
   2400         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   2401         return SOC_E_MEMORY;
   2402     } else {
   2403         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   2404         rv = soc_counter_th_extra_ctrs_init(unit,
   2405                                             SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,
   2406                                             non_dma0,
   2407                                             non_dma0->extra_ctrs,
   2408                                             non_dma0->extra_ctr_ct,
   2409                                             &num_extra_ctr_entries);
   2410         if (rv != SOC_E_NONE) {
   2411             LOG_CLI((BSL_META_U(unit,
   2412                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2413                      SOC_COUNTER_NON_DMA_COSQ_DROP_PKT -
   2414                      SOC_COUNTER_NON_DMA_START));
   2415         }
   2416         non_dma0->num_entries = num_extra_ctr_entries;
   2417     }
   2418     *non_dma_entries += non_dma0->num_entries;
   2419 
   2420  
   2421     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE -
   2422                                      SOC_COUNTER_NON_DMA_START];
   2423     *non_dma1 = *non_dma0;
   2424     non_dma1->id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE;
   2425 
   2426     /* FLAGS - Notes
   2427      * 1. Flag DO_DMA removed as BYTE descriptor need NOT do DMA.
   2428      * DMA already performed in PACKET descriptor.
   2429      *
   2430      * 2. In Parent-child model based counters, BYTE counter Parent need
   2431      * to contain DMA_VALID flag, long enough to setup the Children during
   2432      * extra_ctrs_init. 
   2433      * Post children INIT, byte counter parent's DMA_VALID flag NEED to be
   2434      * set to FALSE, so during Counter thread it is ignored.
   2435      */
   2436     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   2437                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   2438     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2439     non_dma1->field = BYTECNTf;
   2440     non_dma1->cname = "PERQ_DROP_BYTE";
   2441     non_dma1->extra_ctr_ct = NUM_XPE(unit);
   2442 
   2443     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   2444     non_dma1->extra_ctrs = non_dma0->extra_ctrs + 1;
   2445 
   2446     if (non_dma0->extra_ctrs) {
   2447         rv = soc_counter_th_extra_ctrs_init(unit,
   2448                                             SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE,
   2449                                             non_dma1,
   2450                                             non_dma1->extra_ctrs,
   2451                                             non_dma1->extra_ctr_ct,
   2452                                             &num_extra_ctr_entries);
   2453         if (rv != SOC_E_NONE) {
   2454             LOG_CLI((BSL_META_U(unit,
   2455                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2456                      SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE -
   2457                      SOC_COUNTER_NON_DMA_START));
   2458         }
   2459     }
   2460     non_dma1->flags = _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   2461     *non_dma_entries += non_dma1->num_entries;
   2462     /* End Ctrl block for DROP_PKT_MC */
   2463 
   2464 
   2465     /* Ctrl block for DROP_PKT_UC */
   2466     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC -
   2467                                      SOC_COUNTER_NON_DMA_START];
   2468     non_dma0->id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC;
   2469     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2470                       _SOC_COUNTER_NON_DMA_DO_DMA |
   2471                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   2472     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   2473     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2474     non_dma0->entries_per_port = 10; /* 10 UC queues per port */
   2475     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm);
   2476     non_dma0->mem = MMU_CTR_UC_DROP_MEMm;
   2477 
   2478     /* Get the mem attributes(Max idx) from the first child,
   2479      * which could be used for other instances.
   2480      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   2481      */
   2482     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, non_dma0->mem, 0, 0);
   2483     num_entries = soc_mem_index_max(unit, child_mem) + 1;
   2484     entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   2485     non_dma0->num_entries = NUM_PIPE(unit) * num_entries;
   2486 
   2487     non_dma0->reg = INVALIDr;
   2488     non_dma0->field = PKTCNTf;
   2489     non_dma0->cname = "PERQ_DROP_PKT_UC";
   2490 
   2491     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2492         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   2493     }
   2494 
   2495     non_dma0->extra_ctr_ct = NUM_XPE(unit);
   2496     /* Incl. buffer for BYTE_CTR. 2x alloc size*/
   2497     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   2498     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_perq_drop_uc");
   2499 
   2500     if (non_dma0->extra_ctrs == NULL) {
   2501         non_dma0->extra_ctr_ct = 0;
   2502         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   2503         return SOC_E_MEMORY;
   2504     } else {
   2505         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   2506         rv = soc_counter_th_extra_ctrs_init(unit,
   2507                                             SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC,
   2508                                             non_dma0,
   2509                                             non_dma0->extra_ctrs,
   2510                                             non_dma0->extra_ctr_ct,
   2511                                             &num_extra_ctr_entries);
   2512         if (rv != SOC_E_NONE) {
   2513             LOG_CLI((BSL_META_U(unit,
   2514                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2515                      SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC -
   2516                      SOC_COUNTER_NON_DMA_START));
   2517         }
   2518         non_dma0->num_entries = num_extra_ctr_entries;
   2519     }
   2520     *non_dma_entries += non_dma0->num_entries;
   2521 
   2522     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC -
   2523                                      SOC_COUNTER_NON_DMA_START];
   2524     *non_dma1 = *non_dma0;
   2525     non_dma1->id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC;
   2526 
   2527     /* FLAGS - Notes
   2528      * Refer notes init of ID - SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE
   2529      */
   2530     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   2531                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   2532     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2533     non_dma1->field = BYTECNTf;
   2534     non_dma1->cname = "PERQ_DROP_BYTE_UC";
   2535 
   2536     non_dma1->extra_ctr_ct = NUM_XPE(unit);
   2537 
   2538     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   2539     non_dma1->extra_ctrs = non_dma0->extra_ctrs + 1;
   2540 
   2541     if (non_dma0->extra_ctrs)
   2542     {
   2543         rv = soc_counter_th_extra_ctrs_init(unit,
   2544                                             SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC,
   2545                                             non_dma1,
   2546                                             non_dma1->extra_ctrs,
   2547                                             non_dma1->extra_ctr_ct,
   2548                                             &num_extra_ctr_entries);
   2549         if (rv != SOC_E_NONE) {
   2550             LOG_CLI((BSL_META_U(unit,
   2551                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2552                      SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC -
   2553                      SOC_COUNTER_NON_DMA_START));
   2554         }
   2555     }
   2556     non_dma1->flags = _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   2557     *non_dma_entries += non_dma1->num_entries;
   2558 
   2559 
   2560     /* Ctrl block for DROP_PKT_MC */
   2561     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING -
   2562                                      SOC_COUNTER_NON_DMA_START];
   2563     non_dma0->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING;
   2564     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2565                       _SOC_COUNTER_NON_DMA_DO_DMA |
   2566                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   2567     non_dma0->pbmp = PBMP_ALL(unit);
   2568     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2569     non_dma0->entries_per_port = 1;
   2570     non_dma0->mem = MMU_CTR_ING_DROP_MEMm;
   2571 
   2572     /* Get the mem attributes(Max idx) from the first child,
   2573      * which could be used for other instances.
   2574      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   2575      */
   2576     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, non_dma0->mem, 0, 0);
   2577     num_entries = soc_mem_index_max(unit, child_mem) + 1;
   2578     entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   2579     non_dma0->num_entries = NUM_PIPE(unit) * num_entries;
   2580 
   2581     non_dma0->reg = INVALIDr;
   2582     non_dma0->field = PKTCNTf;
   2583     non_dma0->cname = "DROP_PKT_ING";
   2584 
   2585     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2586         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   2587     }
   2588 
   2589     non_dma0->extra_ctr_ct = NUM_XPE(unit);
   2590     /* Incl. buffer for BYTE_CTR. 2x alloc size*/
   2591     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   2592     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_ing_drop");
   2593 
   2594 
   2595     /*
   2596      * Below represents how Extra cntrs are arranged
   2597      * for Per Queue(UC|MC) Drop Counters.
   2598      * n = NUM_XPE
   2599      *
   2600      *   [0]     [2]        [2n-2]
   2601      *  ------  ------     ------ 
   2602      * |      ||      |...|      |
   2603      * | PKT  || PKT  |...| PKT  |
   2604      * | [0]  || [1]  |...| [n-1]|
   2605      *  ------  ------ ... ------ 
   2606      * |      ||      |...|      |
   2607      * | BYTE || BYTE |...| BYTE |
   2608      * | [0]  || [1]  |...| [n-1]|
   2609      *  ------  ------     ------
   2610      *   [1]     [3]        [2n-1]
   2611      */
   2612     if (non_dma0->extra_ctrs == NULL) {
   2613         non_dma0->extra_ctr_ct = 0;
   2614         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   2615         return SOC_E_MEMORY;
   2616     } else {
   2617         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   2618         rv = soc_counter_th_extra_ctrs_init(unit,
   2619                                             SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING,
   2620                                             non_dma0,
   2621                                             non_dma0->extra_ctrs,
   2622                                             non_dma0->extra_ctr_ct,
   2623                                             &num_extra_ctr_entries);
   2624         if (rv != SOC_E_NONE) {
   2625             LOG_CLI((BSL_META_U(unit,
   2626                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2627                      SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING -
   2628                      SOC_COUNTER_NON_DMA_START));
   2629         }
   2630         non_dma0->num_entries = num_extra_ctr_entries;
   2631     }
   2632     *non_dma_entries += non_dma0->num_entries;
   2633 
   2634  
   2635     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING -
   2636                                      SOC_COUNTER_NON_DMA_START];
   2637     *non_dma1 = *non_dma0;
   2638     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING;
   2639 
   2640     /* FLAGS - Notes
   2641      * Refer notes init of ID - SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE
   2642      */
   2643     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   2644                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   2645     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2646     non_dma1->field = BYTECNTf;
   2647     non_dma1->cname = "DROP_BYTE_ING";
   2648     non_dma1->extra_ctr_ct = NUM_XPE(unit);
   2649 
   2650     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   2651     non_dma1->extra_ctrs = non_dma0->extra_ctrs + 1;
   2652 
   2653     if (non_dma0->extra_ctrs) {
   2654         rv = soc_counter_th_extra_ctrs_init(unit,
   2655                                             SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING,
   2656                                             non_dma1,
   2657                                             non_dma1->extra_ctrs,
   2658                                             non_dma1->extra_ctr_ct,
   2659                                             &num_extra_ctr_entries);
   2660         if (rv != SOC_E_NONE) {
   2661             LOG_CLI((BSL_META_U(unit,
   2662                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2663                      SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING -
   2664                      SOC_COUNTER_NON_DMA_START));
   2665         }
   2666     }
   2667     non_dma1->flags = _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   2668     *non_dma_entries += non_dma1->num_entries;
   2669     /* End Ctrl block for DROP_PKT_MC */
   2670 
   2671     /* Ctrl block for wred red counter */
   2672 
   2673     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED -
   2674                                      SOC_COUNTER_NON_DMA_START];
   2675     non_dma0->id = SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED;
   2676     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 
   2677                       _SOC_COUNTER_NON_DMA_DO_DMA |
   2678                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   2679     non_dma0->pbmp = PBMP_ALL(unit);
   2680     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2681     non_dma0->entries_per_port = 1;
   2682     non_dma0->mem = MMU_CTR_COLOR_DROP_MEMm;
   2683     non_dma0->reg = INVALIDr;
   2684     non_dma0->cname = "WRED_PKT_RED";
   2685     non_dma0->field = PKTCNTf;
   2686 
   2687     if (SOC_IS_TOMAHAWK2(unit)) {
   2688         child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, non_dma0->mem, 0, 0);
   2689         num_entries = soc_mem_index_max(unit, child_mem) + 1;
   2690         entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   2691         non_dma0->num_entries = NUM_PIPE(unit) * num_entries;
   2692         
   2693         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2694             non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   2695         }
   2696     } else {
   2697         child_mem = SOC_MEM_UNIQUE_ACC(unit, non_dma0->mem)[0];
   2698         num_entries = soc_mem_index_max(unit,child_mem) + 1;
   2699         non_dma0->num_entries = num_entries * NUM_XPE(unit);
   2700         
   2701         non_dma0->dma_buf[0] = &buf[0];
   2702     }
   2703     non_dma0->extra_ctr_ct = NUM_XPE(unit);
   2704     /* Buffer allocated for 2x alloc size. Though 2nd half is NOT used. */
   2705     
   2706     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   2707     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_wred_pkt_red");
   2708     
   2709     /*
   2710      * Below represents how Extra cntrs are arranged for wred red pkt, wred
   2711      * yellow pkt, wred green pkt, drop pkt red, drop pkt yellow counters.
   2712      *
   2713      *  n = NUM_XPE
   2714      *
   2715      *   [0]     [2]        [2n-2]
   2716      *  ------  ------     ------ 
   2717      * |      ||      |...|      |
   2718      * | PKT  || PKT  |...| PKT  |
   2719      * | [0]  || [1]  |...| [n-1]|
   2720      *  ------  ------ ... ------ 
   2721      * |      ||      |...|      |
   2722      * | N/A  || N/A  |...| N/A  |
   2723      * | [0]  || [1]  |...| [n-1]|
   2724      *  ------  ------     ------
   2725      *   [1]     [3]        [2n-1]
   2726      */
   2727 
   2728     if (non_dma0->extra_ctrs == NULL) {
   2729         non_dma0->extra_ctr_ct = 0;
   2730         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   2731         return SOC_E_MEMORY;
   2732     } else {
   2733         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   2734         rv = soc_counter_th_extra_ctrs_init(unit,
   2735                                             SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED,
   2736                                             non_dma0,
   2737                                             non_dma0->extra_ctrs,
   2738                                             non_dma0->extra_ctr_ct,
   2739                                             &num_extra_ctr_entries);
   2740         if (rv != SOC_E_NONE) {
   2741             LOG_CLI((BSL_META_U(unit,
   2742                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2743                      SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED -
   2744                      SOC_COUNTER_NON_DMA_START));
   2745         }
   2746         non_dma0->num_entries = num_extra_ctr_entries;
   2747     }
   2748     *non_dma_entries += non_dma0->num_entries;
   2749 
   2750     /* Ctrl block for wred yellow counter */
   2751 
   2752     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW -
   2753                                      SOC_COUNTER_NON_DMA_START];
   2754     *non_dma1 = *non_dma0;
   2755     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW;
   2756     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2757     non_dma1->cname = "WRED_PKT_YEL";
   2758     
   2759     if (SOC_IS_TOMAHAWK2(unit)) {
   2760         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2761             non_dma1->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   2762         }
   2763     } else {
   2764         non_dma1->dma_buf[0] = &buf[0];
   2765     }
   2766     /* Buffer allocated for 2x alloc size. Though 2nd half is NOT used. */
   2767     non_dma1->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_wred_pkt_yel");
   2768 
   2769     if (non_dma1->extra_ctrs == NULL) {
   2770         non_dma1->extra_ctr_ct = 0;
   2771         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   2772         return SOC_E_MEMORY;
   2773     } else {
   2774         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   2775         rv = soc_counter_th_extra_ctrs_init(unit,
   2776                                             SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW,
   2777                                             non_dma1,
   2778                                             non_dma1->extra_ctrs,
   2779                                             non_dma1->extra_ctr_ct,
   2780                                             &num_extra_ctr_entries);
   2781         if (rv != SOC_E_NONE) {
   2782             LOG_CLI((BSL_META_U(unit,
   2783                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2784                      SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW -
   2785                      SOC_COUNTER_NON_DMA_START));
   2786         }
   2787         non_dma1->num_entries = num_extra_ctr_entries;
   2788     }
   2789     *non_dma_entries += non_dma1->num_entries;
   2790 
   2791     /* Ctrl block for wred green counter */
   2792 
   2793     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN -
   2794                                      SOC_COUNTER_NON_DMA_START];
   2795     *non_dma1 = *non_dma0;
   2796     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN;
   2797     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2798     non_dma1->cname = "WRED_PKT_GRE";
   2799     if (SOC_IS_TOMAHAWK2(unit)) {
   2800         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2801             non_dma1->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   2802         }
   2803     } else {
   2804         non_dma1->dma_buf[0] = &buf[0];
   2805     }
   2806 
   2807     /* Buffer allocated for 2x alloc size. Though 2nd half is NOT used. */
   2808     
   2809     non_dma1->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_wred_pkt_gre");
   2810 
   2811     if (non_dma1->extra_ctrs == NULL) {
   2812         non_dma1->extra_ctr_ct = 0;
   2813         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   2814         return SOC_E_MEMORY;
   2815     } else {
   2816         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   2817         rv = soc_counter_th_extra_ctrs_init(unit,
   2818                                             SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN,
   2819                                             non_dma1,
   2820                                             non_dma1->extra_ctrs,
   2821                                             non_dma1->extra_ctr_ct,
   2822                                             &num_extra_ctr_entries);
   2823         if (rv != SOC_E_NONE) {
   2824             LOG_CLI((BSL_META_U(unit,
   2825                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2826                      SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN -
   2827                      SOC_COUNTER_NON_DMA_START));
   2828         }
   2829         non_dma1->num_entries = num_extra_ctr_entries;
   2830     }
   2831     *non_dma_entries += non_dma1->num_entries;
   2832 
   2833     /* Ctrl block for Red Drop counter */
   2834 
   2835     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   2836                                      SOC_COUNTER_NON_DMA_START];
   2837     *non_dma1 = *non_dma0;
   2838     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED;
   2839     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2840     non_dma1->cname = "DROP_PKT_RED";
   2841     if (SOC_IS_TOMAHAWK2(unit)) {
   2842         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2843             non_dma1->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   2844         }
   2845     } else {
   2846         non_dma1->dma_buf[0] = &buf[0];
   2847     }
   2848 
   2849     /* Buffer allocated for 2x alloc size. Though 2nd half is NOT used. */
   2850     
   2851     non_dma1->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_drop_pkt_red");
   2852     
   2853     if (non_dma1->extra_ctrs == NULL) {
   2854         non_dma1->extra_ctr_ct = 0;
   2855         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   2856         return SOC_E_MEMORY;
   2857     } else {
   2858         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   2859         rv = soc_counter_th_extra_ctrs_init(unit,
   2860                                             SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED,
   2861                                             non_dma1,
   2862                                             non_dma1->extra_ctrs,
   2863                                             non_dma1->extra_ctr_ct,
   2864                                             &num_extra_ctr_entries);
   2865         if (rv != SOC_E_NONE) {
   2866             LOG_CLI((BSL_META_U(unit,
   2867                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2868                      SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED -
   2869                      SOC_COUNTER_NON_DMA_START));
   2870         }
   2871         non_dma1->num_entries = num_extra_ctr_entries;
   2872     }
   2873     *non_dma_entries += non_dma1->num_entries;
   2874 
   2875     /* Ctrl block for Yellow Drop counter */
   2876 
   2877     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   2878                                      SOC_COUNTER_NON_DMA_START];
   2879     *non_dma1 = *non_dma0;
   2880     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW;
   2881     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   2882     non_dma1->cname = "DROP_PKT_YEL";
   2883     if (SOC_IS_TOMAHAWK2(unit)) {
   2884         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2885             non_dma1->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   2886         }
   2887     } else {
   2888         non_dma1->dma_buf[0] = &buf[0];
   2889     }
   2890 
   2891     /* Buffer allocated for 2x alloc size. Though 2nd half is NOT used. */
   2892     
   2893     non_dma1->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_drop_pkt_yel");
   2894     
   2895     if (non_dma1->extra_ctrs == NULL) {
   2896         non_dma1->extra_ctr_ct = 0;
   2897         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   2898         return SOC_E_MEMORY;
   2899     } else {
   2900         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   2901         rv = soc_counter_th_extra_ctrs_init(unit,
   2902                                             SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW,
   2903                                             non_dma1,
   2904                                             non_dma1->extra_ctrs,
   2905                                             non_dma1->extra_ctr_ct,
   2906                                             &num_extra_ctr_entries);
   2907         if (rv != SOC_E_NONE) {
   2908             LOG_CLI((BSL_META_U(unit,
   2909                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2910                      SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW -
   2911                      SOC_COUNTER_NON_DMA_START));
   2912         }
   2913         non_dma1->num_entries = num_extra_ctr_entries;
   2914     }
   2915     *non_dma_entries += non_dma1->num_entries;
   2916 
   2917     /* Ctrl block for MC Queue Count */
   2918     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_PEAK -
   2919                                      SOC_COUNTER_NON_DMA_START];
   2920     non_dma0->id = SOC_COUNTER_NON_DMA_QUEUE_PEAK;
   2921 
   2922     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   2923                       _SOC_COUNTER_NON_DMA_DO_DMA |
   2924                       _SOC_COUNTER_NON_DMA_PEAK |
   2925                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   2926     non_dma0->pbmp = PBMP_ALL(unit);
   2927     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   2928     non_dma0->entries_per_port = 48; /* 48 for cpu port */
   2929     non_dma0->mem = MMU_THDM_DB_QUEUE_COUNTm;
   2930 
   2931     /* Get the mem attributes(Max idx) from the first child,
   2932      * which could be used for other instances.
   2933      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   2934      */
   2935     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, non_dma0->mem, 0, 0);
   2936     num_entries = soc_mem_index_max(unit, child_mem) + 1;
   2937     entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   2938     non_dma0->num_entries = NUM_PIPE(unit) * num_entries;
   2939 
   2940     non_dma0->reg = INVALIDr;
   2941     non_dma0->field = SHARED_COUNTf;
   2942     non_dma0->cname = "QUEUE_PEAK";
   2943 
   2944     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2945         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   2946     }
   2947 
   2948     non_dma0->extra_ctr_ct = NUM_XPE(unit);
   2949     /* Buffer allocated for 2x alloc size. Though 2nd half is NOT used.
   2950      * This memory supports Min Count, but not implemented yet. So space
   2951      * reserved.
   2952      */
   2953     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   2954     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_mc_q_ct");
   2955 
   2956     /*
   2957      * Below represents how Extra cntrs are arranged 
   2958      * for Q(MC) SHD counters.
   2959      * n = NUM_XPE
   2960      *
   2961      *   [0]     [2]        [2n-2]
   2962      *  ------  ------     ------ 
   2963      * |      ||      |...|      |
   2964      * | SHD  || SHD  |...| SHD  |
   2965      * | [0]  || [1]  |...| [n-1]|
   2966      *  ------  ------ ... ------ 
   2967      * |      ||      |...|      |
   2968      * | N/A  || N/A  |...| N/A  |
   2969      * | [0]  || [1]  |...| [n-1]|
   2970      *  ------  ------     ------
   2971      *   [1]     [3]        [2n-1]
   2972      */
   2973 
   2974     if (non_dma0->extra_ctrs == NULL) {
   2975         non_dma0->extra_ctr_ct = 0;
   2976         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   2977         return SOC_E_MEMORY;
   2978     } else {
   2979         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   2980         rv = soc_counter_th_extra_ctrs_init(unit,
   2981                                             SOC_COUNTER_NON_DMA_QUEUE_PEAK,
   2982                                             non_dma0,
   2983                                             non_dma0->extra_ctrs,
   2984                                             non_dma0->extra_ctr_ct,
   2985                                             &num_extra_ctr_entries);
   2986         if (rv != SOC_E_NONE) {
   2987             LOG_CLI((BSL_META_U(unit,
   2988                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   2989                      SOC_COUNTER_NON_DMA_QUEUE_PEAK -
   2990                      SOC_COUNTER_NON_DMA_START));
   2991         }
   2992         non_dma0->num_entries = num_extra_ctr_entries;
   2993     }
   2994     *non_dma_entries += non_dma0->num_entries;
   2995 
   2996  
   2997     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_CURRENT -
   2998                                      SOC_COUNTER_NON_DMA_START];
   2999     *non_dma2 = *non_dma0;
   3000     non_dma2->id = SOC_COUNTER_NON_DMA_QUEUE_CURRENT;
   3001     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   3002                       _SOC_COUNTER_NON_DMA_CURRENT |
   3003                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3004     non_dma2->cname = "QUEUE_CUR";
   3005     /* End Ctrl block for MC Queue Count */
   3006  
   3007     /* Ctrl block for UC Queue Count */
   3008     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK -
   3009                                      SOC_COUNTER_NON_DMA_START];
   3010     non_dma0->id = SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK;
   3011 
   3012     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3013                       _SOC_COUNTER_NON_DMA_DO_DMA |
   3014                       _SOC_COUNTER_NON_DMA_PEAK |
   3015                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3016     non_dma0->pbmp = PBMP_PORT_ALL(unit); /* No UC queue for CPU/LB ports */
   3017     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3018     non_dma0->entries_per_port = 10;
   3019     non_dma0->mem = MMU_THDU_COUNTER_QUEUEm;
   3020 
   3021     /* Get the mem attributes(Max idx) from the first child,
   3022      * which could be used for other instances.
   3023      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   3024      */
   3025     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, non_dma0->mem, 0, 0);
   3026     num_entries = soc_mem_index_max(unit, child_mem) + 1;
   3027     entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   3028     non_dma0->num_entries = NUM_PIPE(unit) * num_entries;
   3029 
   3030     non_dma0->reg = INVALIDr;
   3031     non_dma0->field = SHARED_COUNTf;
   3032     non_dma0->cname = "UC_QUEUE_PEAK";
   3033 
   3034     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   3035         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   3036     }
   3037 
   3038     non_dma0->extra_ctr_ct = NUM_XPE(unit);
   3039 
   3040     /* Buffer allocated for 2x alloc size. Though 2nd half is NOT used.
   3041      * This memory supports Min Count, but not implemented yet. So space
   3042      * reserved.
   3043      */
   3044     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   3045     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_uc_q_ct");
   3046 
   3047     /*
   3048      * Below represents how Extra cntrs are arranged 
   3049      * for Q(UC) SHD counters.
   3050      * n = NUM_XPE
   3051      *
   3052      *   [0]     [2]        [2n]
   3053      *  ------  ------     ------ 
   3054      * |      ||      |...|      |
   3055      * | SHD  || SHD  |...| SHD  |
   3056      * | [0]  || [1]  |...| [n]  |
   3057      *  ------  ------ ... ------ 
   3058      * |      ||      |...|      |
   3059      * | N/A  || N/A  |...| N/A  |
   3060      * | [0]  || [1]  |...| [n]  |
   3061      *  ------  ------     ------
   3062      *   [1]     [3]        [2n+1]
   3063      */
   3064  
   3065     if (non_dma0->extra_ctrs == NULL) {
   3066         non_dma0->extra_ctr_ct = 0;
   3067         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   3068         return SOC_E_MEMORY;
   3069     } else {
   3070         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   3071         rv = soc_counter_th_extra_ctrs_init(unit,
   3072                                             SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK,
   3073                                             non_dma0,
   3074                                             non_dma0->extra_ctrs,
   3075                                             non_dma0->extra_ctr_ct,
   3076                                             &num_extra_ctr_entries);
   3077         if (rv != SOC_E_NONE) {
   3078             LOG_CLI((BSL_META_U(unit,
   3079                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3080                      SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK -
   3081                      SOC_COUNTER_NON_DMA_START));
   3082         }
   3083         non_dma0->num_entries = num_extra_ctr_entries;
   3084     }
   3085     *non_dma_entries += non_dma0->num_entries;
   3086 
   3087  
   3088     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT -
   3089                                      SOC_COUNTER_NON_DMA_START];
   3090     *non_dma2 = *non_dma0;
   3091     non_dma2->id = SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT;
   3092     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   3093                       _SOC_COUNTER_NON_DMA_CURRENT |
   3094                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3095     non_dma2->cname = "UC_QUEUE_CUR";
   3096     /* End Ctrl block for MC Queue Count */
   3097 
   3098     /* Ctrl block for RQ Drop */
   3099     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT -
   3100                                      SOC_COUNTER_NON_DMA_START];
   3101     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3102                       _SOC_COUNTER_NON_DMA_DO_DMA;
   3103     non_dma0->id = SOC_COUNTER_NON_DMA_DROP_RQ_PKT;
   3104     SOC_PBMP_CLEAR(non_dma0->pbmp);
   3105     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3106     non_dma0->entries_per_port = 0;
   3107     non_dma0->num_entries = 11 * NUM_XPE(unit);
   3108     non_dma0->mem = INVALIDm;
   3109     non_dma0->reg = DROP_PKT_CNT_RQE_PKT_64r;
   3110     non_dma0->field = PKTCNTf;
   3111     non_dma0->cname = "RQ_DROP_PKT";
   3112     non_dma0->dma_buf[0] = buf;
   3113     *non_dma_entries += non_dma0->num_entries;
   3114 
   3115     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_BYTE -
   3116                                      SOC_COUNTER_NON_DMA_START];
   3117     *non_dma1 = *non_dma0;
   3118     non_dma1->id = SOC_COUNTER_NON_DMA_DROP_RQ_BYTE;
   3119     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3120     non_dma1->reg = DROP_PKT_CNT_RQE_BYTE_64r;
   3121     non_dma1->field = BYTECNTf;
   3122     non_dma1->cname = "RQ_DROP_BYTE";
   3123     *non_dma_entries += non_dma1->num_entries;
   3124 
   3125     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW -
   3126                                      SOC_COUNTER_NON_DMA_START];
   3127     *non_dma1 = *non_dma0;
   3128     non_dma1->id = SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW;
   3129     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3130     non_dma1->reg = DROP_PKT_CNT_RQE_YEL_64r;
   3131     non_dma1->field = PKTCNTf;
   3132     non_dma1->cname = "RQ_DROP_PKT_YEL";
   3133     *non_dma_entries += non_dma1->num_entries;
   3134 
   3135     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED -
   3136                                      SOC_COUNTER_NON_DMA_START];
   3137     *non_dma1 = *non_dma0;
   3138     non_dma1->id = SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED;
   3139     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3140     non_dma1->reg = DROP_PKT_CNT_RQE_RED_64r;
   3141     non_dma1->field = PKTCNTf;
   3142     non_dma1->cname = "RQ_DROP_PKT_RED";
   3143     *non_dma_entries += non_dma1->num_entries;
   3144     /* End Ctrl block for RQ Drop */
   3145 
   3146     /* Ctrl block for Pool Peak */
   3147     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_PEAK -
   3148                                      SOC_COUNTER_NON_DMA_START];
   3149     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3150                       _SOC_COUNTER_NON_DMA_PEAK;
   3151     non_dma0->id = SOC_COUNTER_NON_DMA_POOL_PEAK;
   3152     SOC_PBMP_CLEAR(non_dma0->pbmp);
   3153     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3154     non_dma0->entries_per_port = 0;
   3155     non_dma0->num_entries = 4  * NUM_XPE(unit);
   3156     non_dma0->mem = INVALIDm;
   3157     non_dma0->reg = THDI_POOL_SHARED_COUNT_SPr;
   3158     non_dma0->field = TOTAL_BUFFER_COUNTf;
   3159     non_dma0->cname = "POOL_PEAK";
   3160     non_dma0->dma_buf[0] = buf;
   3161     *non_dma_entries += non_dma0->num_entries;
   3162 
   3163     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_CURRENT -
   3164                                      SOC_COUNTER_NON_DMA_START];
   3165     *non_dma2 = *non_dma0;
   3166     non_dma2->id = SOC_COUNTER_NON_DMA_POOL_CURRENT;
   3167     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   3168                       _SOC_COUNTER_NON_DMA_CURRENT;
   3169     non_dma2->cname = "POOL_CUR";
   3170     /* End Ctrl block for Pool Peak */
   3171 
   3172     /* Ctrl block for PG Counters */
   3173     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_PEAK -
   3174                                      SOC_COUNTER_NON_DMA_START];
   3175     non_dma0->id = SOC_COUNTER_NON_DMA_PG_MIN_PEAK;
   3176 
   3177     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3178                       _SOC_COUNTER_NON_DMA_DO_DMA |
   3179                       _SOC_COUNTER_NON_DMA_PEAK |
   3180                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3181     non_dma0->pbmp = PBMP_ALL(unit);
   3182     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3183     non_dma0->entries_per_port = 8;
   3184     non_dma0->mem = THDI_PORT_PG_CNTRS_RT1m;
   3185 
   3186     /* Get the mem attributes(Max idx) from the first child,
   3187      * which could be used for other instances.
   3188      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   3189      */
   3190     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, non_dma0->mem, 0, 0);
   3191     num_entries = soc_mem_index_max(unit, child_mem) + 1;
   3192     entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   3193     non_dma0->num_entries = NUM_PIPE(unit) * num_entries;
   3194 
   3195     non_dma0->reg = INVALIDr;
   3196     non_dma0->field = PG_MIN_COUNTf;
   3197     non_dma0->cname = "PG_MIN_PEAK";
   3198 
   3199     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   3200         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   3201     }
   3202 
   3203     non_dma0->extra_ctr_ct = NUM_XPE(unit);
   3204     /* Incl. buffer for SHD_CNTR. 2x alloc size
   3205      * (Note: SDH_CNTR instead of BYTE CNTR present) */
   3206     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   3207     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_pg_ctrs");
   3208 
   3209     /*
   3210      * Below represents how Extra cntrs are arranged 
   3211      * for PG MIN and Shared(SHD) counters.
   3212      * n = NUM_XPE
   3213      *
   3214      *   [0]     [2]        [2n]
   3215      *  ------  ------     ------ 
   3216      * |      ||      |...|      |
   3217      * | MIN  || MIN  |...| MIN  |
   3218      * | [0]  || [1]  |...| [n]  |
   3219      *  ------  ------ ... ------ 
   3220      * |      ||      |...|      |
   3221      * | SHD  || SHD  |...| SHD  |
   3222      * | [0]  || [1]  |...| [n]  |
   3223      *  ------  ------     ------
   3224      *   [1]     [3]        [2n+1]
   3225      */
   3226 
   3227     if (non_dma0->extra_ctrs == NULL) {
   3228         non_dma0->extra_ctr_ct = 0;
   3229         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   3230         return SOC_E_MEMORY;
   3231     } else {
   3232         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   3233         rv = soc_counter_th_extra_ctrs_init(unit,
   3234                                             SOC_COUNTER_NON_DMA_PG_MIN_PEAK,
   3235                                             non_dma0,
   3236                                             non_dma0->extra_ctrs,
   3237                                             non_dma0->extra_ctr_ct,
   3238                                             &num_extra_ctr_entries);
   3239         if (rv != SOC_E_NONE) {
   3240             LOG_CLI((BSL_META_U(unit,
   3241                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3242                      SOC_COUNTER_NON_DMA_PG_MIN_PEAK -
   3243                      SOC_COUNTER_NON_DMA_START));
   3244         }
   3245         non_dma0->num_entries = num_extra_ctr_entries;
   3246     }
   3247     *non_dma_entries += non_dma0->num_entries;
   3248 
   3249  
   3250     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_CURRENT -
   3251                                      SOC_COUNTER_NON_DMA_START];
   3252     *non_dma2 = *non_dma0;
   3253     non_dma2->id = SOC_COUNTER_NON_DMA_PG_MIN_CURRENT;
   3254     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   3255                       _SOC_COUNTER_NON_DMA_CURRENT |
   3256                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3257     non_dma2->cname = "PG_MIN_CUR";
   3258 
   3259     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_PEAK -
   3260                                      SOC_COUNTER_NON_DMA_START];
   3261     *non_dma1 = *non_dma0;
   3262     non_dma1->id = SOC_COUNTER_NON_DMA_PG_SHARED_PEAK;
   3263     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   3264                       _SOC_COUNTER_NON_DMA_PEAK |
   3265                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3266     non_dma1->cname = "PG_SHARED_PEAK";
   3267     non_dma1->field = PG_SHARED_COUNTf;
   3268     non_dma1->extra_ctr_ct = NUM_XPE(unit);
   3269     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3270 
   3271     /* Memory for extra ctrs for SHD_CNTRS are done along with MIN_CTRS */
   3272     non_dma1->extra_ctrs = non_dma0->extra_ctrs + 1;
   3273 
   3274     if (non_dma0->extra_ctrs)
   3275     {
   3276         rv = soc_counter_th_extra_ctrs_init(unit,
   3277                                             SOC_COUNTER_NON_DMA_PG_SHARED_PEAK,
   3278                                             non_dma1,
   3279                                             non_dma1->extra_ctrs,
   3280                                             non_dma1->extra_ctr_ct,
   3281                                             &num_extra_ctr_entries);
   3282         if (rv != SOC_E_NONE) {
   3283             LOG_CLI((BSL_META_U(unit,
   3284                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3285                      SOC_COUNTER_NON_DMA_PG_SHARED_PEAK -
   3286                      SOC_COUNTER_NON_DMA_START));
   3287         }
   3288     }
   3289     non_dma1->flags = _SOC_COUNTER_NON_DMA_SUBSET_PARENT |
   3290                       _SOC_COUNTER_NON_DMA_PEAK;
   3291     *non_dma_entries += non_dma1->num_entries;
   3292  
   3293     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT -
   3294                                      SOC_COUNTER_NON_DMA_START];
   3295     *non_dma2 = *non_dma1;
   3296     non_dma2->id = SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT;
   3297     non_dma2->flags = _SOC_COUNTER_NON_DMA_CURRENT |
   3298                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3299     non_dma2->cname = "PG_SHARED_CUR";
   3300  
   3301  
   3302 
   3303     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_PEAK -
   3304                                      SOC_COUNTER_NON_DMA_START];
   3305     non_dma0->id = SOC_COUNTER_NON_DMA_PG_HDRM_PEAK;
   3306     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3307                       _SOC_COUNTER_NON_DMA_DO_DMA |
   3308                       _SOC_COUNTER_NON_DMA_PEAK |
   3309                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3310     non_dma0->pbmp = PBMP_ALL(unit);
   3311     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3312     non_dma0->entries_per_port = 8;
   3313     non_dma0->mem = THDI_PORT_PG_CNTRS_RT2m;
   3314 
   3315     /* Get the mem attributes(Max idx) from the first child,
   3316      * which could be used for other instances.
   3317      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   3318      */
   3319     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, non_dma0->mem, 0, 0);
   3320     num_entries = soc_mem_index_max(unit, child_mem) + 1;
   3321     entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   3322     non_dma0->num_entries = NUM_PIPE(unit) * num_entries;
   3323 
   3324     non_dma0->reg = INVALIDr;
   3325     non_dma0->field = PG_HDRM_COUNTf;
   3326     non_dma0->cname = "PG_HDRM_PEAK";
   3327 
   3328     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   3329         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   3330     }
   3331 
   3332     non_dma0->extra_ctr_ct = NUM_XPE(unit);
   3333 
   3334     /* Buffer allocated for 2x alloc size. Though 2nd half is NOT used.
   3335      * This memory supports Min Count, but not implemented yet. So space
   3336      * reserved.
   3337      */
   3338     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   3339     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_hdrm_ctrs");
   3340 
   3341     /*
   3342      * Below represents how Extra cntrs are arranged 
   3343      * for PG HDRM counters.
   3344      * n = NUM_XPE
   3345      *
   3346      *   [0]     [2]        [2n]
   3347      *  ------  ------     ------ 
   3348      * |      ||      |...|      |
   3349      * | HDRM || HDRM |...| HDRM |
   3350      * | [0]  || [1]  |...| [n]  |
   3351      *  ------  ------ ... ------ 
   3352      * |      ||      |...|      |
   3353      * | N/A  || N/A  |...| N/A  |
   3354      * | [0]  || [1]  |...| [n]  |
   3355      *  ------  ------     ------
   3356      *   [1]     [3]        [2n+1]
   3357      */
   3358  
   3359     if (non_dma0->extra_ctrs == NULL) {
   3360         non_dma0->extra_ctr_ct = 0;
   3361         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   3362         return SOC_E_MEMORY;
   3363     } else {
   3364         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   3365         rv = soc_counter_th_extra_ctrs_init(unit,
   3366                                             SOC_COUNTER_NON_DMA_PG_HDRM_PEAK,
   3367                                             non_dma0,
   3368                                             non_dma0->extra_ctrs,
   3369                                             non_dma0->extra_ctr_ct,
   3370                                             &num_extra_ctr_entries);
   3371         if (rv != SOC_E_NONE) {
   3372             LOG_CLI((BSL_META_U(unit,
   3373                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3374                      SOC_COUNTER_NON_DMA_PG_HDRM_PEAK -
   3375                      SOC_COUNTER_NON_DMA_START));
   3376         }
   3377         non_dma0->num_entries = num_extra_ctr_entries;
   3378     }
   3379     *non_dma_entries += non_dma0->num_entries;
   3380 
   3381  
   3382     non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT -
   3383                                      SOC_COUNTER_NON_DMA_START];
   3384     *non_dma2 = *non_dma0;
   3385     non_dma2->id = SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT;
   3386     non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID |
   3387                       _SOC_COUNTER_NON_DMA_CURRENT |
   3388                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3389     non_dma2->cname = "PG_HDRM_CUR";
   3390     /* End Ctrl block for PG Counters */
   3391     }
   3392 
   3393     /* Ctrl block for ING_FLEX */
   3394     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_ING_FLEX_PKT -
   3395                                      SOC_COUNTER_NON_DMA_START];
   3396     non_dma0->id = SOC_COUNTER_NON_DMA_ING_FLEX_PKT;
   3397     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3398                       _SOC_COUNTER_NON_DMA_DO_DMA |
   3399                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3400 
   3401     /* Clear on Read Flag set if eviction is enabled */
   3402     non_dma0->flags |= _SOC_COUNTER_NON_DMA_CTR_EVICT;
   3403     non_dma0->flags |= _SOC_COUNTER_NON_DMA_NO_SHOW_C;
   3404     SOC_PBMP_CLEAR(non_dma0->pbmp);
   3405     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3406     non_dma0->entries_per_port = 0;
   3407     pool_count = 20;
   3408     non_dma0->num_entries =
   3409         pool_count * NUM_PIPE(unit) * 
   3410                         soc_mem_index_count(unit, ING_FLEX_CTR_COUNTER_TABLE_0m);
   3411     non_dma0->mem = ING_FLEX_CTR_COUNTER_TABLE_0m;
   3412     non_dma0->reg = INVALIDr;
   3413     non_dma0->field = PACKET_COUNTERf;
   3414     non_dma0->cname = "ING_FLEX_PKT";
   3415 
   3416     num_entries = soc_mem_index_count(unit, ING_FLEX_CTR_COUNTER_TABLE_0m);
   3417     entry_words = soc_mem_entry_words(unit, ING_FLEX_CTR_COUNTER_TABLE_0m);
   3418     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   3419         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   3420     }
   3421 
   3422     non_dma0->extra_ctr_ct = pool_count; 
   3423     /* Incl. buffer for BYTE_CTR. 2x alloc size*/
   3424     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   3425     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_ing_flex");
   3426 
   3427     if (non_dma0->extra_ctrs == NULL) {
   3428         non_dma0->extra_ctr_ct = 0;
   3429         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   3430         return SOC_E_MEMORY;
   3431     } else {
   3432         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   3433         rv = soc_counter_th_extra_ctrs_init(unit, SOC_COUNTER_NON_DMA_ING_FLEX_PKT,
   3434                                             non_dma0,
   3435                                             non_dma0->extra_ctrs,
   3436                                             non_dma0->extra_ctr_ct,
   3437                                             &num_extra_ctr_entries);
   3438         if (rv != SOC_E_NONE) {
   3439             LOG_CLI((BSL_META_U(unit,
   3440                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3441                      SOC_COUNTER_NON_DMA_ING_FLEX_PKT -
   3442                      SOC_COUNTER_NON_DMA_START));
   3443         }
   3444         non_dma0->num_entries = num_extra_ctr_entries;
   3445     }
   3446     *non_dma_entries += non_dma0->num_entries;
   3447 
   3448     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_ING_FLEX_BYTE -
   3449                                      SOC_COUNTER_NON_DMA_START];
   3450     *non_dma1 = *non_dma0;
   3451     non_dma1->id = SOC_COUNTER_NON_DMA_ING_FLEX_BYTE;
   3452 
   3453     /* FLAGS - Notes
   3454      * Refer notes init of ID - SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE
   3455      */
   3456     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   3457                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3458 
   3459     /* Clear on Read Flag set if eviction is enabled */
   3460     non_dma1->flags |= _SOC_COUNTER_NON_DMA_CTR_EVICT;
   3461     non_dma1->flags |= _SOC_COUNTER_NON_DMA_NO_SHOW_C;
   3462     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3463     non_dma1->field = BYTE_COUNTERf;
   3464     non_dma1->cname = "ING_FLEX_BYTE";
   3465     non_dma1->extra_ctr_ct = pool_count; /* Taken care by PKT_CTR */
   3466 
   3467     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   3468     non_dma1->extra_ctrs = non_dma0->extra_ctrs + 1;
   3469 
   3470     if (non_dma0->extra_ctrs)
   3471     {
   3472         rv = soc_counter_th_extra_ctrs_init(unit,
   3473                                             SOC_COUNTER_NON_DMA_ING_FLEX_BYTE,
   3474                                             non_dma1,
   3475                                             non_dma1->extra_ctrs,
   3476                                             non_dma1->extra_ctr_ct,
   3477                                             &num_extra_ctr_entries);
   3478         if (rv != SOC_E_NONE) {
   3479             LOG_CLI((BSL_META_U(unit,
   3480                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3481                      SOC_COUNTER_NON_DMA_ING_FLEX_BYTE -
   3482                      SOC_COUNTER_NON_DMA_START));
   3483         }
   3484     }
   3485 
   3486     non_dma1->flags = _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3487     non_dma1->flags |= _SOC_COUNTER_NON_DMA_NO_SHOW_C;
   3488     *non_dma_entries += non_dma1->num_entries;
   3489 
   3490 
   3491     /* Ctrl block for EGR_FLEX */
   3492     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_FLEX_PKT -
   3493                                      SOC_COUNTER_NON_DMA_START];
   3494     non_dma0->id = SOC_COUNTER_NON_DMA_EGR_FLEX_PKT;
   3495     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3496                       _SOC_COUNTER_NON_DMA_DO_DMA |
   3497                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3498 
   3499     /* Clear on Read Flag set if eviction is enabled */
   3500     non_dma0->flags |= _SOC_COUNTER_NON_DMA_CTR_EVICT;
   3501     non_dma0->flags |= _SOC_COUNTER_NON_DMA_NO_SHOW_C;
   3502     SOC_PBMP_CLEAR(non_dma0->pbmp);
   3503     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3504     pool_count = 4;
   3505     non_dma0->entries_per_port = 0;
   3506     non_dma0->num_entries =
   3507         pool_count * NUM_PIPE(unit) *
   3508             soc_mem_index_count(unit, EGR_FLEX_CTR_COUNTER_TABLE_0m);
   3509     non_dma0->mem = EGR_FLEX_CTR_COUNTER_TABLE_0m;
   3510     non_dma0->reg = INVALIDr;
   3511     non_dma0->field = PACKET_COUNTERf;
   3512     non_dma0->cname = "EGR_FLEX_PKT";
   3513 
   3514     num_entries = soc_mem_index_count(unit, EGR_FLEX_CTR_COUNTER_TABLE_0m);
   3515     entry_words = soc_mem_entry_words(unit, EGR_FLEX_CTR_COUNTER_TABLE_0m);
   3516     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   3517         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   3518     }
   3519 
   3520     non_dma0->extra_ctr_ct = pool_count; 
   3521 
   3522     /* Incl. buffer for BYTE_CTR. 2x alloc size*/
   3523     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   3524     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_ing_flex");
   3525 
   3526     if (non_dma0->extra_ctrs == NULL) {
   3527         non_dma0->extra_ctr_ct = 0;
   3528         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   3529         return SOC_E_MEMORY;
   3530     } else {
   3531         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   3532         rv = soc_counter_th_extra_ctrs_init(unit, SOC_COUNTER_NON_DMA_EGR_FLEX_PKT,
   3533                                             non_dma0,
   3534                                             non_dma0->extra_ctrs,
   3535                                             non_dma0->extra_ctr_ct,
   3536                                             &num_extra_ctr_entries);
   3537         if (rv != SOC_E_NONE) {
   3538             LOG_CLI((BSL_META_U(unit,
   3539                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3540                      SOC_COUNTER_NON_DMA_EGR_FLEX_PKT -
   3541                      SOC_COUNTER_NON_DMA_START));
   3542         }
   3543         non_dma0->num_entries = num_extra_ctr_entries;
   3544     }
   3545  
   3546     *non_dma_entries += non_dma0->num_entries;
   3547 
   3548 
   3549     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE -
   3550                                      SOC_COUNTER_NON_DMA_START];
   3551     *non_dma1 = *non_dma0;
   3552     non_dma1->id = SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE;
   3553 
   3554     /* FLAGS - Notes
   3555      * Refer notes init of ID - SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE
   3556      */
   3557     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID |
   3558                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3559     /* Clear on Read Flag set if eviction is enabled */
   3560     non_dma1->flags |= _SOC_COUNTER_NON_DMA_CTR_EVICT;
   3561     non_dma1->flags |= _SOC_COUNTER_NON_DMA_NO_SHOW_C;
   3562     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3563     non_dma1->field = BYTE_COUNTERf;
   3564     non_dma1->cname = "EGR_FLEX_BYTE";
   3565     non_dma1->extra_ctr_ct = pool_count; /* Taken care by PKT_CTR */
   3566 
   3567     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   3568     non_dma1->extra_ctrs = non_dma0->extra_ctrs + 1;
   3569 
   3570     if (non_dma0->extra_ctrs)
   3571     {
   3572         rv = soc_counter_th_extra_ctrs_init(unit,
   3573                                             SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE,
   3574                                             non_dma1,
   3575                                             non_dma1->extra_ctrs,
   3576                                             non_dma1->extra_ctr_ct,
   3577                                             &num_extra_ctr_entries);
   3578         if (rv != SOC_E_NONE) {
   3579             LOG_CLI((BSL_META_U(unit,
   3580                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3581                      SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE -
   3582                      SOC_COUNTER_NON_DMA_START));
   3583         }
   3584     }
   3585     non_dma1->flags = _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3586     non_dma1->flags |= _SOC_COUNTER_NON_DMA_NO_SHOW_C;
   3587  
   3588     *non_dma_entries += non_dma1->num_entries;
   3589 
   3590 
   3591     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EFP_PKT -
   3592                                      SOC_COUNTER_NON_DMA_START];
   3593     non_dma0->id = SOC_COUNTER_NON_DMA_EFP_PKT;
   3594     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3595                       _SOC_COUNTER_NON_DMA_DO_DMA;
   3596     non_dma0->flags |= _SOC_COUNTER_NON_DMA_CTR_EVICT;
   3597     non_dma0->flags |= _SOC_COUNTER_NON_DMA_NO_SHOW_C;
   3598 
   3599     SOC_PBMP_CLEAR(non_dma0->pbmp);
   3600     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3601     non_dma0->entries_per_port = 0;
   3602     non_dma0->num_entries =
   3603         NUM_PIPE(unit) * soc_mem_index_count(unit, EFP_COUNTER_TABLEm);
   3604     non_dma0->mem = EFP_COUNTER_TABLEm;
   3605     non_dma0->reg = INVALIDr;
   3606     non_dma0->field = PACKET_COUNTERf;
   3607     non_dma0->cname = "EFP_PKT";
   3608  
   3609     num_entries = soc_mem_index_count(unit, EFP_COUNTER_TABLEm);
   3610     entry_words = soc_mem_entry_words(unit, EFP_COUNTER_TABLEm);
   3611 
   3612     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   3613         non_dma0->dma_mem[pipe] = 
   3614             SOC_MEM_UNIQUE_ACC(unit, non_dma0->mem)[pipe];
   3615         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   3616         non_dma0->dma_index_max[pipe] =
   3617             soc_mem_index_max(unit, non_dma0->dma_mem[pipe]);
   3618     }
   3619 
   3620     *non_dma_entries += non_dma0->num_entries;
   3621 
   3622 
   3623     non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EFP_BYTE -
   3624                                      SOC_COUNTER_NON_DMA_START];
   3625     *non_dma1 = *non_dma0;
   3626     non_dma1->id = SOC_COUNTER_NON_DMA_EFP_BYTE;
   3627     non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID;
   3628     non_dma1->flags |= _SOC_COUNTER_NON_DMA_CTR_EVICT;
   3629     non_dma1->flags |= _SOC_COUNTER_NON_DMA_NO_SHOW_C;
   3630 
   3631     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3632     non_dma1->field = BYTE_COUNTERf;
   3633     non_dma1->cname = "EFP_BYTE";
   3634     *non_dma_entries += non_dma1->num_entries;
   3635 
   3636     /* Control block for Ingress sFlow counters */
   3637     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_SFLOW_ING_PKT -
   3638                                      SOC_COUNTER_NON_DMA_START];
   3639     non_dma0->id = SOC_COUNTER_NON_DMA_SFLOW_ING_PKT;
   3640     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA
   3641                       | _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3642     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   3643     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3644     non_dma0->entries_per_port = 1;
   3645     non_dma0->mem = SFLOW_ING_DATA_SOURCEm;
   3646 
   3647     num_entries = soc_mem_index_count(unit, SFLOW_ING_DATA_SOURCEm);
   3648     entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   3649     non_dma0->num_entries = SOC_SFLOW_CTR_TYPE_COUNT * num_entries;
   3650     non_dma0->reg = INVALIDr;
   3651     non_dma0->cname = "SFLOW_ING_PKT";
   3652     non_dma0->field = SAMPLE_POOLf;
   3653     non_dma0->dma_buf[0] = &buf[0];
   3654 
   3655     non_dma0->extra_ctr_ct = SOC_SFLOW_CTR_TYPE_COUNT;
   3656 
   3657     /* Buffer allocated for 2x alloc size. Though 2nd half is NOT used.
   3658      * This memory supports BYTE Count, but not implemented yet. So space
   3659      * reserved.
   3660      */
   3661     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   3662     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_sflow_ing");
   3663 
   3664     /*
   3665      * Below represents how Extra cntrs are arranged
   3666      * for sFlow counters.
   3667      *
   3668      *       --------------------------
   3669      * [0]  |      SAMPLE_POOL [0]     |
   3670      *       --------------------------
   3671      * [1]  |           N/A [0]        |
   3672      *       --------------------------
   3673      * [2]  | SAMPLE_POOL_SNAPSHOT [0] |
   3674      *       --------------------------
   3675      * [3]  |           N/A [0]        |
   3676      *       --------------------------
   3677      * [4]  |      SAMPLE_COUNT [0]    |
   3678      *       --------------------------
   3679      * [5]  |           N/A [0]        |
   3680      *       --------------------------
   3681  */
   3682 
   3683     if (non_dma0->extra_ctrs == NULL) {
   3684         non_dma0->extra_ctr_ct = 0;
   3685         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   3686         return SOC_E_MEMORY;
   3687     } else {
   3688         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   3689         rv = soc_counter_th_extra_sflow_ctrs_init(unit,
   3690                                             non_dma0,
   3691                                             non_dma0->extra_ctrs,
   3692                                             non_dma0->extra_ctr_ct,
   3693                                             &num_extra_ctr_entries);
   3694         if (rv != SOC_E_NONE) {
   3695             LOG_CLI((BSL_META_U(unit,
   3696                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3697                         SOC_COUNTER_NON_DMA_SFLOW_ING_PKT -
   3698                         SOC_COUNTER_NON_DMA_START));
   3699         }
   3700         non_dma0->num_entries = num_extra_ctr_entries;
   3701     }
   3702     *non_dma_entries += non_dma0->num_entries;
   3703 
   3704     /* Control block for Flex sFlow counters */
   3705     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT -
   3706                                      SOC_COUNTER_NON_DMA_START];
   3707     non_dma0->id = SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT;
   3708     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA
   3709                       | _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3710     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   3711     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3712     non_dma0->entries_per_port = 1;
   3713     non_dma0->mem = SFLOW_ING_FLEX_DATA_SOURCEm;
   3714 
   3715     num_entries = soc_mem_index_count(unit, SFLOW_ING_FLEX_DATA_SOURCEm);
   3716     entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   3717     non_dma0->num_entries = SOC_SFLOW_CTR_TYPE_COUNT * num_entries;
   3718     non_dma0->reg = INVALIDr;
   3719     non_dma0->cname = "SFLOW_FLEX_PKT";
   3720     non_dma0->field = SAMPLE_POOLf;
   3721     non_dma0->dma_buf[0] = &buf[0];
   3722 
   3723     non_dma0->extra_ctr_ct = SOC_SFLOW_CTR_TYPE_COUNT;
   3724 
   3725     /* Buffer allocated for 2x alloc size. Though 2nd half is NOT used.
   3726      * This memory supports BYTE Count, but not implemented yet. So space
   3727      * reserved.
   3728      */
   3729     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   3730     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_sflow_flex");
   3731 
   3732     if (non_dma0->extra_ctrs == NULL) {
   3733         non_dma0->extra_ctr_ct = 0;
   3734         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   3735         return SOC_E_MEMORY;
   3736     } else {
   3737         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   3738         rv = soc_counter_th_extra_sflow_ctrs_init(unit,
   3739                                             non_dma0,
   3740                                             non_dma0->extra_ctrs,
   3741                                             non_dma0->extra_ctr_ct,
   3742                                             &num_extra_ctr_entries);
   3743         if (rv != SOC_E_NONE) {
   3744             LOG_CLI((BSL_META_U(unit,
   3745                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3746                         SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT -
   3747                         SOC_COUNTER_NON_DMA_START));
   3748         }
   3749         non_dma0->num_entries = num_extra_ctr_entries;
   3750     }
   3751     *non_dma_entries += non_dma0->num_entries;
   3752 
   3753     /* Control block for IDB OBM counters */
   3754     /* Lossy LO drop counters - Pkt Counters */
   3755     non_dma0 =
   3756         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO -
   3757                               SOC_COUNTER_NON_DMA_START];
   3758     non_dma0->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO;
   3759     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   3760     non_dma0->reg = IDB_OBM0_LOSSY_LO_PKT_DROP_COUNTr;
   3761     non_dma0->cname = "OBM_LOSSY_LO_DRP_PKT";
   3762 
   3763     /* Common across all OBM structures */
   3764     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   3765                       _SOC_COUNTER_NON_DMA_OBM;
   3766     /* Use Parent-Child model to cover all 8 OBMs */
   3767     non_dma0->flags |= _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   3768     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   3769     non_dma0->entries_per_port = _TH_PORTS_PER_PBLK;
   3770     non_dma0->num_entries = _TH_PORTS_PER_PBLK * NUM_PIPE(unit);
   3771     non_dma0->mem = INVALIDm;
   3772     non_dma0->field = COUNTERf;
   3773     non_dma0->dma_buf[0] = buf;
   3774 
   3775     /*
   3776      * Below represents how Extra cntrs are arranged
   3777      * for OBM 0-7 Drop Counters.
   3778      * n = NUM_OBMs (8)
   3779      *
   3780      *   [0]     [2]        [2n-2]
   3781      *  ------  ------     ------
   3782      * |      ||      |...|      |
   3783      * | PKT  || PKT  |...| PKT  |
   3784      * | [0]  || [1]  |...| [n-1]|
   3785      *  ------  ------ ... ------
   3786      * |      ||      |...|      |
   3787      * | BYTE || BYTE |...| BYTE |
   3788      * | [0]  || [1]  |...| [n-1]|
   3789      *  ------  ------     ------
   3790      *   [1]     [3]        [2n-1]
   3791      */
   3792 #if defined(BCM_TOMAHAWK2_SUPPORT)
   3793     if (SOC_IS_TOMAHAWK2(unit)) {
   3794         non_dma0->extra_ctr_ct = _TH2_PBLKS_PER_PIPE; /* 16 OBMs per Pipe */
   3795     } else
   3796 #endif
   3797     {
   3798         non_dma0->extra_ctr_ct = _TH_PBLKS_PER_PIPE; /* 8 OBMs per Pipe */
   3799     }
   3800     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   3801     temp = non_dma0->extra_ctrs = sal_alloc(alloc_size,
   3802                                             "non_dma_ctrs_obm_lossy_lo");
   3803 
   3804     if (non_dma0->extra_ctrs == NULL) {
   3805         non_dma0->extra_ctr_ct = 0;
   3806         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   3807         return SOC_E_MEMORY;
   3808     } else {
   3809         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   3810         rv = soc_counter_th_extra_obm_ctrs_init(unit,
   3811                                                 non_dma0,
   3812                                                 non_dma0->extra_ctrs,
   3813                                                 non_dma0->extra_ctr_ct,
   3814                                                 &num_extra_ctr_entries);
   3815         if (rv != SOC_E_NONE) {
   3816             LOG_CLI((BSL_META_U(unit,
   3817                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3818                         non_dma0->id - SOC_COUNTER_NON_DMA_START));
   3819         }
   3820         non_dma0->num_entries = num_extra_ctr_entries;
   3821     }
   3822     *non_dma_entries += non_dma0->num_entries;
   3823 
   3824     /* Lossy LO drop counters - Byte Counters */
   3825     non_dma1 =
   3826         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO -
   3827                               SOC_COUNTER_NON_DMA_START];
   3828     *non_dma1 = *non_dma0;
   3829     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO;
   3830     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3831     non_dma1->reg = IDB_OBM0_LOSSY_LO_BYTE_DROP_COUNTr;
   3832     non_dma1->field = COUNTERf;
   3833     non_dma1->cname = "OBM_LOSSY_LO_DRP_BYTE";
   3834 
   3835     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   3836     non_dma1->extra_ctrs = temp + 1;
   3837     if (non_dma1->extra_ctrs) {
   3838         rv = soc_counter_th_extra_obm_ctrs_init(unit,
   3839                                                 non_dma1,
   3840                                                 non_dma1->extra_ctrs,
   3841                                                 non_dma1->extra_ctr_ct,
   3842                                                 &num_extra_ctr_entries);
   3843         if (rv != SOC_E_NONE) {
   3844             LOG_CLI((BSL_META_U(unit,
   3845                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3846                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   3847         }
   3848     }
   3849     *non_dma_entries += non_dma1->num_entries;
   3850 
   3851     /* Lossy HI drop counters - Packet Counters */
   3852     non_dma1 =
   3853         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI -
   3854                               SOC_COUNTER_NON_DMA_START];
   3855     *non_dma1 = *non_dma0;
   3856     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI;
   3857     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3858     non_dma1->reg = IDB_OBM0_LOSSY_HI_PKT_DROP_COUNTr;
   3859     non_dma1->cname = "OBM_LOSSY_HI_DRP_PKT";
   3860 
   3861     temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   3862                                             "non_dma_ctrs_obm_lossy_hi");
   3863 
   3864     if (non_dma1->extra_ctrs == NULL) {
   3865         non_dma1->extra_ctr_ct = 0;
   3866         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   3867         return SOC_E_MEMORY;
   3868     } else {
   3869         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   3870         rv = soc_counter_th_extra_obm_ctrs_init(unit,
   3871                                                 non_dma1,
   3872                                                 non_dma1->extra_ctrs,
   3873                                                 non_dma1->extra_ctr_ct,
   3874                                                 &num_extra_ctr_entries);
   3875         if (rv != SOC_E_NONE) {
   3876             LOG_CLI((BSL_META_U(unit,
   3877                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3878                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   3879         }
   3880         non_dma1->num_entries = num_extra_ctr_entries;
   3881     }
   3882     *non_dma_entries += non_dma1->num_entries;
   3883 
   3884 
   3885     /* Lossy HI drop counters - Byte Counters */
   3886     non_dma1 =
   3887         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI -
   3888                               SOC_COUNTER_NON_DMA_START];
   3889     *non_dma1 = *non_dma0;
   3890     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI;
   3891     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3892     non_dma1->reg = IDB_OBM0_LOSSY_HI_BYTE_DROP_COUNTr;
   3893     non_dma1->field = COUNTERf;
   3894     non_dma1->cname = "OBM_LOSSY_HI_DRP_BYTE";
   3895 
   3896     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   3897     non_dma1->extra_ctrs = temp + 1;
   3898     if (non_dma1->extra_ctrs) {
   3899         rv = soc_counter_th_extra_obm_ctrs_init(unit,
   3900                                                 non_dma1,
   3901                                                 non_dma1->extra_ctrs,
   3902                                                 non_dma1->extra_ctr_ct,
   3903                                             &num_extra_ctr_entries);
   3904         if (rv != SOC_E_NONE) {
   3905             LOG_CLI((BSL_META_U(unit,
   3906                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3907                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   3908         }
   3909     }
   3910     *non_dma_entries += non_dma1->num_entries;
   3911 
   3912 
   3913     /* Lossless0 drop counters - Packet Counters */
   3914     non_dma1 =
   3915         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0 -
   3916                               SOC_COUNTER_NON_DMA_START];
   3917     *non_dma1 = *non_dma0;
   3918     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0;
   3919     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3920     non_dma1->reg = IDB_OBM0_LOSSLESS0_PKT_DROP_COUNTr;
   3921     non_dma1->cname = "OBM_LOSSLESS0_DRP_PKT";
   3922 
   3923     temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   3924                                             "non_dma_ctrs_obm_lossless0");
   3925 
   3926     if (non_dma1->extra_ctrs == NULL) {
   3927         non_dma1->extra_ctr_ct = 0;
   3928         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   3929         return SOC_E_MEMORY;
   3930     } else {
   3931         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   3932         rv = soc_counter_th_extra_obm_ctrs_init(unit,
   3933                                                 non_dma1,
   3934                                                 non_dma1->extra_ctrs,
   3935                                                 non_dma1->extra_ctr_ct,
   3936                                                 &num_extra_ctr_entries);
   3937         if (rv != SOC_E_NONE) {
   3938             LOG_CLI((BSL_META_U(unit,
   3939                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3940                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   3941         }
   3942         non_dma1->num_entries = num_extra_ctr_entries;
   3943     }
   3944     *non_dma_entries += non_dma1->num_entries;
   3945 
   3946     /* Lossless0 drop counters - Byte Counters */
   3947     non_dma1 =
   3948         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0 -
   3949                               SOC_COUNTER_NON_DMA_START];
   3950     *non_dma1 = *non_dma0;
   3951     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0;
   3952     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3953     non_dma1->reg = IDB_OBM0_LOSSLESS0_BYTE_DROP_COUNTr;
   3954     non_dma1->field = COUNTERf;
   3955     non_dma1->cname = "OBM_LOSSLESS0_DRP_BYTE";
   3956 
   3957     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   3958     non_dma1->extra_ctrs = temp + 1;
   3959     if (non_dma1->extra_ctrs) {
   3960         rv = soc_counter_th_extra_obm_ctrs_init(unit,
   3961                                                 non_dma1,
   3962                                                 non_dma1->extra_ctrs,
   3963                                                 non_dma1->extra_ctr_ct,
   3964                                                 &num_extra_ctr_entries);
   3965         if (rv != SOC_E_NONE) {
   3966             LOG_CLI((BSL_META_U(unit,
   3967                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   3968                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   3969         }
   3970     }
   3971     *non_dma_entries += non_dma1->num_entries;
   3972 
   3973     /* Lossless1 drop counters - Packet counters */
   3974     non_dma1 =
   3975         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1 -
   3976                               SOC_COUNTER_NON_DMA_START];
   3977     *non_dma1 = *non_dma0;
   3978     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1;
   3979     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   3980     non_dma1->reg = IDB_OBM0_LOSSLESS1_PKT_DROP_COUNTr;
   3981     non_dma1->cname = "OBM_LOSSLESS1_DRP_PKT";
   3982 
   3983     temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   3984                                             "non_dma_ctrs_obm_lossless1");
   3985 
   3986     if (non_dma1->extra_ctrs == NULL) {
   3987         non_dma1->extra_ctr_ct = 0;
   3988         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   3989         return SOC_E_MEMORY;
   3990     } else {
   3991         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   3992         rv = soc_counter_th_extra_obm_ctrs_init(unit,
   3993                                                 non_dma1,
   3994                                                 non_dma1->extra_ctrs,
   3995                                                 non_dma1->extra_ctr_ct,
   3996                                                 &num_extra_ctr_entries);
   3997         if (rv != SOC_E_NONE) {
   3998             LOG_CLI((BSL_META_U(unit,
   3999                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4000                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4001         }
   4002         non_dma1->num_entries = num_extra_ctr_entries;
   4003     }
   4004     *non_dma_entries += non_dma1->num_entries;
   4005 
   4006     /* Lossless1 drop counters - Byte Counters */
   4007     non_dma1 =
   4008         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1 -
   4009                               SOC_COUNTER_NON_DMA_START];
   4010     *non_dma1 = *non_dma0;
   4011     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1;
   4012     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4013     non_dma1->reg = IDB_OBM0_LOSSLESS1_BYTE_DROP_COUNTr;
   4014     non_dma1->field = COUNTERf;
   4015     non_dma1->cname = "OBM_LOSSLESS1_DRP_BYTE";
   4016 
   4017     /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */
   4018     non_dma1->extra_ctrs = temp + 1;
   4019     if (non_dma1->extra_ctrs) {
   4020         rv = soc_counter_th_extra_obm_ctrs_init(unit,
   4021                                                 non_dma1,
   4022                                                 non_dma1->extra_ctrs,
   4023                                                 non_dma1->extra_ctr_ct,
   4024                                                 &num_extra_ctr_entries);
   4025         if (rv != SOC_E_NONE) {
   4026             LOG_CLI((BSL_META_U(unit,
   4027                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4028                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4029         }
   4030     }
   4031     *non_dma_entries += non_dma1->num_entries;
   4032 
   4033     /* FC event counters */
   4034     non_dma1 =
   4035         &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_OBM_FC_EVENTS -
   4036                               SOC_COUNTER_NON_DMA_START];
   4037     *non_dma1 = *non_dma0;
   4038     non_dma1->id = SOC_COUNTER_NON_DMA_PORT_OBM_FC_EVENTS;
   4039     non_dma1->base_index = non_dma_start_index + *non_dma_entries;
   4040     non_dma1->reg = IDB_OBM0_FLOW_CONTROL_EVENT_COUNTr;
   4041     non_dma1->field = COUNTERf;
   4042     non_dma1->cname = "OBM_FC_EVENTS";
   4043 
   4044     temp = non_dma1->extra_ctrs = sal_alloc(alloc_size,
   4045                                             "non_dma_ctrs_obm_fc");
   4046 
   4047     if (non_dma1->extra_ctrs == NULL) {
   4048         non_dma1->extra_ctr_ct = 0;
   4049         non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4050         return SOC_E_MEMORY;
   4051     } else {
   4052         sal_memset(non_dma1->extra_ctrs, 0, alloc_size);
   4053         rv = soc_counter_th_extra_obm_ctrs_init(unit,
   4054                                                 non_dma1,
   4055                                                 non_dma1->extra_ctrs,
   4056                                                 non_dma1->extra_ctr_ct,
   4057                                                 &num_extra_ctr_entries);
   4058         if (rv != SOC_E_NONE) {
   4059             LOG_CLI((BSL_META_U(unit,
   4060                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4061                      non_dma1->id - SOC_COUNTER_NON_DMA_START));
   4062         }
   4063         non_dma1->num_entries = num_extra_ctr_entries;
   4064     }
   4065     *non_dma_entries += non_dma1->num_entries;
   4066     /* End of Control block for IDB OBM counters */
   4067 
   4068     /* Ctrl block for PERQ_WRED_DROP_PKT_UC */
   4069     non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_WRED_PKT -
   4070                                      SOC_COUNTER_NON_DMA_START];
   4071     non_dma0->id = SOC_COUNTER_NON_DMA_COSQ_DROP_WRED_PKT;
   4072     non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID |
   4073                       _SOC_COUNTER_NON_DMA_DO_DMA |
   4074                       _SOC_COUNTER_NON_DMA_SUBSET_PARENT;
   4075     non_dma0->pbmp = PBMP_PORT_ALL(unit);
   4076     non_dma0->base_index = non_dma_start_index + *non_dma_entries;
   4077     non_dma0->entries_per_port = 10; /* 10 UC queues per port */
   4078     non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_WRED_DROP_MEMm);
   4079     non_dma0->mem = MMU_CTR_WRED_DROP_MEMm;
   4080 
   4081     /* Get the mem attributes(Max idx) from the first child,
   4082      * which could be used for other instances.
   4083      * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr).
   4084      */
   4085     child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, non_dma0->mem, 0, 0);
   4086     num_entries = soc_mem_index_max(unit, child_mem) + 1;
   4087     entry_words = soc_mem_entry_words(unit, non_dma0->mem);
   4088     non_dma0->num_entries = NUM_PIPE(unit) * num_entries;
   4089 
   4090     non_dma0->reg = INVALIDr;
   4091     non_dma0->field = PKTCNTf;
   4092     non_dma0->cname = "PERQ_WRED_DROP_PKT_UC";
   4093 
   4094     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   4095         non_dma0->dma_buf[pipe] = &buf[num_entries * entry_words * pipe];
   4096     }
   4097 
   4098     non_dma0->extra_ctr_ct = NUM_XPE(unit);
   4099     /* Incl. buffer to 2x alloc size due to structure of soc_counter_th_extra_ctrs_init, even
   4100       * without BYTE counters.
   4101       */
   4102     alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t);
   4103     non_dma0->extra_ctrs = sal_alloc(alloc_size, "non_dma_ctrs_perq_wred_drop_uc");
   4104 
   4105     if (non_dma0->extra_ctrs == NULL) {
   4106         non_dma0->extra_ctr_ct = 0;
   4107         non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID;
   4108         return SOC_E_MEMORY;
   4109     } else {
   4110         sal_memset(non_dma0->extra_ctrs, 0, alloc_size);
   4111         rv = soc_counter_th_extra_ctrs_init(unit,
   4112                                             SOC_COUNTER_NON_DMA_COSQ_DROP_WRED_PKT,
   4113                                             non_dma0,
   4114                                             non_dma0->extra_ctrs,
   4115                                             non_dma0->extra_ctr_ct,
   4116                                             &num_extra_ctr_entries);
   4117         if (rv != SOC_E_NONE) {
   4118             LOG_CLI((BSL_META_U(unit,
   4119                                 "ERR: Extra ctrs Init FAILED for id %d\n"),
   4120                      SOC_COUNTER_NON_DMA_COSQ_DROP_WRED_PKT -
   4121                      SOC_COUNTER_NON_DMA_START));
   4122         }
   4123         non_dma0->num_entries = num_extra_ctr_entries;
   4124     }
   4125     *non_dma_entries += non_dma0->num_entries;
   4126 
   4127 
   4128     /* eviction table init */
   4129     SOC_IF_ERROR_RETURN(soc_counter_tomahawk_eviction_init(unit));
   4130 
   4131     soc_counter_tomahawk_ctr_dma_post_init(unit);
   4132     return SOC_E_NONE;
   4133 }
   4134 
   4135 #if defined(INCLUDE_TELEMETRY)
   4136 /*
   4137  * Function:
   4138  *      soc_counter_tomahawk_telemetry_init
   4139  * Purpose:
   4140  *      Disable counter eviction and clear on read for counters
   4141  *      used by the Telemetry EApp
   4142  * Parameters:
   4143  *      unit         - (IN) BCM device number
   4144  * Returns:
   4145  *      BCM_E_XXX   - BCM error code.
   4146  */
   4147 int soc_counter_tomahawk_telemetry_init(int unit)
   4148 {
   4149     soc_control_t *soc;
   4150     soc_counter_non_dma_t *non_dma = NULL;
   4151     soc_reg_t reg;
   4152     uint32 rval;
   4153     int pipe;
   4154 
   4155     soc = SOC_CONTROL(unit);
   4156 
   4157     if (soc->counter_non_dma == NULL) {
   4158         /* Counter_non_dma will be NULL after soc_counter_detach.
   4159          * Also soc_counter_detach is called during bcm_detach and soc_detach.
   4160          * Hence sanity check before accessing the pointer.
   4161          */
   4162         return SOC_E_INTERNAL;
   4163     }
   4164 
   4165     non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   4166                                     SOC_COUNTER_NON_DMA_START];
   4167     soc_counter_tomahawk_dma_flags_update(unit, non_dma,
   4168                                         _SOC_COUNTER_NON_DMA_CLEAR_ON_READ, 0);
   4169 
   4170     non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   4171                                     SOC_COUNTER_NON_DMA_START];
   4172     soc_counter_tomahawk_dma_flags_update(unit, non_dma,
   4173                                         _SOC_COUNTER_NON_DMA_CLEAR_ON_READ, 0);
   4174 
   4175     non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC -
   4176                                     SOC_COUNTER_NON_DMA_START];
   4177     soc_counter_tomahawk_dma_flags_update(unit, non_dma,
   4178                                         _SOC_COUNTER_NON_DMA_CLEAR_ON_READ, 0);
   4179 
   4180     non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC -
   4181                                     SOC_COUNTER_NON_DMA_START];
   4182     soc_counter_tomahawk_dma_flags_update(unit, non_dma,
   4183                                         _SOC_COUNTER_NON_DMA_CLEAR_ON_READ, 0);
   4184 
   4185     if (!SOC_WARM_BOOT(unit)) {
   4186         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   4187             reg = SOC_REG_UNIQUE_ACC(unit, EGR_PERQ_EVICTION_CONTROLr)[pipe];
   4188             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   4189             soc_reg_field_set(unit, reg, &rval, MODEf, 0);
   4190             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   4191         }
   4192 
   4193         reg = EGR_PERQ_CNTR_UPDATE_CONTROLr;
   4194         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   4195         soc_reg_field_set(unit, reg, &rval, CLR_ON_READf, 0);
   4196         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   4197     }
   4198     return SOC_E_NONE;
   4199 }
   4200 
   4201 /*
   4202  * Function:
   4203  *      soc_counter_tomahawk_telemetry_detach
   4204  * Purpose:
   4205  *      Reset the telemetry speicifc settings to default
   4206  *
   4207  * Parameters:
   4208  *      unit         - (IN) BCM device number
   4209  * Returns:
   4210  *      BCM_E_XXX   - BCM error code.
   4211  */
   4212 int soc_counter_tomahawk_telemetry_detach(int unit)
   4213 {
   4214     soc_control_t *soc;
   4215     soc_counter_non_dma_t *non_dma = NULL;
   4216     soc_reg_t reg;
   4217     uint32 rval;
   4218     int pipe;
   4219 
   4220     soc = SOC_CONTROL(unit);
   4221     if (soc->counter_non_dma != NULL) {
   4222         /* Counter_non_dma will be NULL after soc_counter_detach.
   4223          * Also soc_counter_detach is called during bcm_detach and soc_detach.
   4224          * Hence sanity check before accessing the pointer.
   4225          */
   4226 
   4227         non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT -
   4228                                         SOC_COUNTER_NON_DMA_START];
   4229         soc_counter_tomahawk_dma_flags_update(unit, non_dma,
   4230                                               _SOC_COUNTER_NON_DMA_CLEAR_ON_READ, 1);
   4231 
   4232         non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE -
   4233                                         SOC_COUNTER_NON_DMA_START];
   4234         soc_counter_tomahawk_dma_flags_update(unit, non_dma,
   4235                                               _SOC_COUNTER_NON_DMA_CLEAR_ON_READ, 1);
   4236 
   4237         non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC -
   4238                                         SOC_COUNTER_NON_DMA_START];
   4239         soc_counter_tomahawk_dma_flags_update(unit, non_dma,
   4240                                               _SOC_COUNTER_NON_DMA_CLEAR_ON_READ, 1);
   4241 
   4242         non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC -
   4243                                         SOC_COUNTER_NON_DMA_START];
   4244         soc_counter_tomahawk_dma_flags_update(unit, non_dma,
   4245                                               _SOC_COUNTER_NON_DMA_CLEAR_ON_READ, 1);
   4246     }
   4247     if (!SOC_WARM_BOOT(unit)) {
   4248         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   4249             reg = SOC_REG_UNIQUE_ACC(unit, EGR_PERQ_EVICTION_CONTROLr)[pipe];
   4250             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   4251 
   4252             if (soc_feature(unit, soc_feature_th_a0_sw_war)) {
   4253                 /* Set Evict Mode as Threshold Mode */
   4254                 soc_reg_field_set(unit, reg, &rval, MODEf, 2);
   4255             } else {
   4256                 /* Set Evict Mode as Random Mode */
   4257                 soc_reg_field_set(unit, reg, &rval, MODEf, 1);
   4258             }
   4259             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   4260         }
   4261 
   4262         reg = EGR_PERQ_CNTR_UPDATE_CONTROLr;
   4263         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   4264         soc_reg_field_set(unit, reg, &rval, CLR_ON_READf, 1);
   4265         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   4266     }
   4267     return SOC_E_NONE;
   4268 }
   4269 #endif /* INCLUDE_TELEMETRY */
   4270 #endif /* BCM_TOMAHAWK_SUPPORT */
   4271 
   4272