openbcm

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

common.c (74765B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        soc_common.c
      8  * Purpose:     Common functions for soc drivers
      9  * Requires:
     10  */
     11 
     12 #include <soc/defs.h>
     13 #include <assert.h>
     14 #include <sal/core/libc.h>
     15 
     16 #include <soc/drv.h>
     17 #include <soc/error.h>
     18 #include <soc/cm.h>
     19 #include <soc/debug.h>
     20 #include <soc/mem.h>
     21 #include <soc/cmic.h>
     22 #ifdef BCM_CMICM_SUPPORT
     23 #include <soc/cmicm.h>
     24 #endif
     25 
     26 #ifdef BCM_IPROC_SUPPORT
     27 #include <soc/iproc.h>
     28 #endif
     29 
     30 #if defined(BCM_DFE_SUPPORT)
     31 #include <soc/dfe/cmn/dfe_drv.h>
     32 #endif
     33 #ifdef BCM_DNX_SUPPORT
     34 #include <bcm/types.h>
     35 #include <bcm_int/dnx/algo/port/algo_port_mgmt.h>
     36 #include <bcm_int/dnx/algo/port/algo_port_utils.h>
     37 #include <soc/dnx/drv.h>
     38 #endif
     39 #if defined(BCM_PETRA_SUPPORT)
     40 #include <soc/dpp/drv.h>
     41 #endif
     42 
     43 #if defined(BCM_KATANA2_SUPPORT)
     44 #include <soc/katana2.h>
     45 #endif
     46 
     47 #if defined(BCM_GREYHOUND_SUPPORT)
     48 #include <soc/greyhound.h>
     49 #endif
     50 
     51 #if defined(BCM_SABER2_SUPPORT)
     52 #include <soc/saber2.h>
     53 #endif
     54 
     55 #if defined(BCM_METROLITE_SUPPORT)
     56 #include <soc/metrolite.h>
     57 #endif
     58 
     59 #ifdef BCM_TOMAHAWK3_SUPPORT
     60 #define CDMAC_OFFSET_CNT    0x10000
     61 #define CDMAC0_STAGE_ID     1
     62 #define CDMAC1_STAGE_ID     2
     63 #endif
     64 
     65 /* Initialize composite block types */
     66 uint32 _soc_block_ports_t[] = {
     67     SOC_BLK_PORT_INITIALIZER
     68 };
     69 
     70 uint32 _soc_block_cpu_t[] = {
     71     SOC_BLK_CPU_INITIALIZER
     72 };
     73 
     74 uint32 _soc_block_ether_t[] = {
     75     SOC_BLK_ETHER_INITIALIZER
     76 };
     77 
     78 uint32 _soc_block_higig_t[] = {
     79     SOC_BLK_HIGIG_INITIALIZER
     80 };
     81 
     82 uint32 _soc_block_fabric_t[] = {
     83     SOC_BLK_FABRIC_INITIALIZER
     84 };
     85 
     86 uint32 _soc_block_net_t[] = {
     87     SOC_BLK_NET_INITIALIZER
     88 };
     89 
     90 uint32 _soc_block_hgport_t[] = {
     91     SOC_BLK_HGPORT_INITIALIZER
     92 };
     93 
     94 
     95 /* The granularity of register addresses, indexed by soc_regtype_t */
     96 int soc_regtype_gran[] = {
     97     1, /* soc_schan_reg,    */
     98     1, /* soc_genreg,       */
     99     1, /* soc_portreg,      */
    100     1, /* soc_ppportreg,    */
    101     1, /* soc_cosreg,       */
    102     1, /* soc_pipereg,      */
    103     1, /* soc_xpereg,       */
    104     1, /* soc_slicereg      */
    105     1, /* soc_layerreg      */
    106     1, /* soc_itmreg      */
    107     1, /* soc_ebreg      */
    108     4, /* soc_cpureg,       */
    109     4, /* soc_pci_cfg_reg,  */
    110     1, /* soc_phy_reg,      */
    111     1, /* soc_spi_reg,      */
    112     4, /* soc_mcsreg,       */
    113     4, /* soc_iprocreg,     */
    114     4, /* soc_hostmem_w,    */
    115     2, /* soc_hostmem_h,    */
    116     1, /* soc_hostmem_b,    */
    117     1, /* soc_customreg,    */
    118     0, /* soc_invalidreg    */
    119 };
    120 
    121 /* Names of register types, indexed by soc_regtype_t */
    122 char *soc_regtypenames[] = {
    123     "schan",          /* soc_schan_reg,    */
    124     "general",        /* soc_genreg,       */
    125     "port",           /* soc_portreg,      */
    126     "ppport",         /* soc_ppportreg,    */
    127     "cos",            /* soc_cosreg,       */
    128     "pipe",           /* soc_pipereg,      */
    129     "xpe",            /* soc_xpereg,       */
    130     "slice",          /* soc_slicereg,     */
    131     "layer",          /* soc_layerreg,     */
    132     "itm",            /* soc_itmreg        */
    133     "eb",             /* soc_ebreg         */
    134     "cpu",            /* soc_cpureg,       */
    135     "pci_cfg",        /* soc_pci_cfg_reg,  */
    136     "phy",            /* soc_phy_reg,      */
    137     "spi",            /* soc_spi_reg,      */
    138     "mcs",            /* soc_mcsreg,       */
    139     "iproc",          /* soc_iprocreg,     */
    140     "mem_word",       /* soc_hostmem_w,    */
    141     "mem_hword",      /* soc_hostmem_h,    */
    142     "mem_byte",       /* soc_hostmem_b,    */
    143     "custom",          /* soc_customreg,       */
    144     "invalid"         /* soc_invalidreg    */
    145 };
    146 
    147 /****************************************************************
    148  *
    149  * This array maps from specific chip enum value to the group
    150  * to which the chip belongs.
    151  *
    152  * NB: Order of this array must match soc_chip_types_e from soc/defs.h
    153  */
    154 soc_chip_groups_t soc_chip_type_map[SOC_CHIP_TYPES_COUNT] = {
    155     SOC_CHIP_TYPE_MAP_INIT
    156 };
    157 
    158 
    159 /****************************************************************
    160  *
    161  * This array maps type indices to names.
    162  *
    163  * Indexed by soc_chip_types
    164  */
    165 char *soc_chip_type_names[SOC_CHIP_TYPES_COUNT] = {
    166     SOC_CHIP_TYPE_NAMES_INIT
    167 };
    168 
    169 /****************************************************************
    170  *
    171  * This array maps group indices to names.
    172  *
    173  * Indexed by soc_chip_groups_t
    174  */
    175 char* soc_chip_group_names[SOC_CHIP_GROUPS_COUNT] = {
    176     SOC_CHIP_GROUP_NAMES_INIT
    177 };
    178 
    179 /*
    180  * The following routines can be called for CMIC (PCI memory space)
    181  * registers or for SOC registers.  The register type is indicated
    182  * in rt.
    183  */
    184 
    185 /* Match block against a list */
    186 /* Internally retreives block type from index */
    187 int
    188 SOC_BLOCK_IS_TYPE(int unit, int blk_idx, int *list)
    189 {
    190     int _bidx = 0;
    191     while(list[_bidx] != SOC_BLOCK_TYPE_INVALID) {
    192         if (SOC_BLOCK_TYPE(unit, blk_idx) == list[_bidx]) {
    193             return TRUE;
    194         }
    195         _bidx++;
    196     }
    197     return FALSE;
    198 }
    199 
    200 /* Checks if a blk type is part of a composite type */
    201 /* Internally retreives block type from index */
    202 int
    203 SOC_BLOCK_IS_COMPOSITE(int unit, int blk_idx, int type)
    204 {
    205     uint32 *blks = NULL;
    206     uint8  _tidx = 0;
    207 
    208     switch(type) {
    209     case SOC_BLK_PORT:
    210          blks = _soc_block_ports_t;
    211          break;
    212     case SOC_BLK_CPU:
    213          blks = _soc_block_cpu_t;
    214          break;
    215     case SOC_BLK_ETHER:
    216          blks = _soc_block_ether_t;
    217          break;
    218     case SOC_BLK_HIGIG:
    219          blks = _soc_block_higig_t;
    220          break;
    221     case SOC_BLK_FABRIC:
    222          blks = _soc_block_fabric_t;
    223          break;
    224     case SOC_BLK_NET:
    225          blks = _soc_block_net_t;
    226          break;
    227     case SOC_BLK_HGPORT:
    228          blks = _soc_block_hgport_t;
    229          break;
    230     default: return FALSE;
    231     }
    232     while(blks[_tidx] != SOC_BLOCK_TYPE_INVALID) {
    233         if (SOC_BLOCK_TYPE(unit, blk_idx) == blks[_tidx]) {
    234             return TRUE;
    235         }
    236         _tidx++;
    237     }
    238     return FALSE;
    239 }
    240 
    241 /* Match a block type against a block list.
    242  * Type could be specific or composite like PORT.
    243  * As an optimization one could use SOC_BLOCK_IS if type is
    244  * known to not be composite.
    245  */
    246 int
    247 SOC_BLOCK_IN_LIST(int *blk, int type)
    248 {
    249     int _bidx = 0;
    250     uint32 *blks = NULL;
    251     while(blk[_bidx] != SOC_BLOCK_TYPE_INVALID) {
    252         int _tidx = 0;
    253         uint8 composite = TRUE;
    254         switch(type) {
    255         case SOC_BLK_PORT:
    256              blks = _soc_block_ports_t;
    257              break;
    258         case SOC_BLK_CPU:
    259              blks = _soc_block_cpu_t;
    260              break;
    261         case SOC_BLK_ETHER:
    262              blks = _soc_block_ether_t;
    263              break;
    264         case SOC_BLK_HIGIG:
    265              blks = _soc_block_higig_t;
    266              break;
    267         case SOC_BLK_FABRIC:
    268              blks = _soc_block_fabric_t;
    269              break;
    270         case SOC_BLK_NET:
    271              blks = _soc_block_net_t;
    272              break;
    273         case SOC_BLK_HGPORT:
    274              blks = _soc_block_hgport_t;
    275              break;
    276         default: composite = FALSE;
    277         }
    278        /* when composite is non-null, you are coming from non-default
    279           case above and no need to check blks for NULL */
    280         if (composite) {
    281            /* coverity[dead_error_condition] */
    282             if (blks == NULL) {
    283                /*
    284                 * Coverity
    285                 * Defencive check.
    286 		* coverity[dead_error_line]
    287 		*/
    288                 return FALSE;
    289             }
    290             while(blks[_tidx] != SOC_BLOCK_TYPE_INVALID) {
    291                 if (blk[_bidx] == blks[_tidx]) {
    292                     return TRUE;
    293                 }
    294                 _tidx++;
    295             }
    296             return FALSE;
    297         } else if (blk[_bidx] == type) {
    298             return TRUE;
    299         }
    300         _bidx++;
    301     }
    302     return FALSE;
    303 }
    304 #ifdef BCM_CMICM_SUPPORT
    305 /*
    306  * There is some PCI addresses that are not mapped to any register.
    307  * Accessing some of them lead to BUS error. So it is unreasonable to access
    308  * the invalid addresses.
    309  */
    310 static int
    311 soc_cpureg_address_is_invalid(int unit, soc_regaddrinfo_t *ainfo) {
    312     int off;
    313 
    314     off = SOC_REG_BASE(unit, ainfo->reg);
    315     if (soc_feature(unit, soc_feature_time_v3_no_bs)){
    316         if (off >= CMIC_BS0_CONFIG_OFFSET &&
    317             off <= CMIC_BS1_INITIAL_CRC_OFFSET){
    318             return TRUE;
    319         }
    320     }
    321     if (off >= CMIC_MMU_COSLC_COUNT_ADDR_OFFSET &&
    322             off < CMIC_TIM0_TIMER1LOAD_OFFSET) {
    323             return TRUE;
    324     }
    325 
    326     /*
    327      * These registers do not ack the CPU until the FSCHAN read cycle is completed.
    328      * Meaning you must activate a proper FSCHAN read command in order to read these registers.
    329      */
    330     switch (ainfo->reg) {
    331         case CMIC_CMC0_FSCHAN_DATA32r            :
    332         case CMIC_CMC0_FSCHAN_DATA64_LOr         :
    333         case CMIC_FSCHAN_DATA32r                 :
    334         case CMIC_FSCHAN_DATA64_LOr              :
    335         case CMIC_CMC1_FSCHAN_DATA32r            :
    336         case CMIC_CMC1_FSCHAN_DATA64_LOr         :
    337         case CMIC_CMC2_FSCHAN_DATA32r            :
    338         case CMIC_CMC2_FSCHAN_DATA64_LOr         :
    339             return TRUE;
    340         default:
    341             /* Do Nothing */
    342             break;
    343     }
    344     return FALSE;
    345 }
    346 #endif
    347 
    348 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) || defined(PORTMOD_SUPPORT)
    349 int
    350 soc_anyreg_read(int unit, soc_regaddrinfo_t *ainfo, uint64 *data)
    351 {
    352     uint32          tmpdata;
    353     int             rv = SOC_E_NONE;
    354     soc_regtype_t   type;
    355     int             port = ainfo->port;
    356 
    357     if (ainfo->reg < 0) {
    358         type = soc_genreg;
    359     } else {
    360         type = SOC_REG_INFO(unit, ainfo->reg).regtype;
    361     }
    362 
    363 #if defined(BCM_SAND_SUPPORT)
    364     if (SOC_IS_SAND(unit)) {
    365         if ((ainfo->port >=0) || (ainfo->port & SOC_REG_ADDR_INSTANCE_MASK)) {
    366             port = ainfo->port;
    367         }  else {
    368             port = REG_PORT_ANY;
    369         }
    370     }
    371 #endif
    372 
    373     switch (type) {
    374     case soc_cpureg:
    375 #ifdef BCM_CMICM_SUPPORT
    376         if (soc_feature(unit, soc_feature_cmicm)) {
    377             if (soc_feature(unit, soc_feature_cpureg_dump)){
    378                 if (soc_cpureg_address_is_invalid(unit, ainfo)) {
    379                     rv = SOC_E_INTERNAL;
    380                     break;
    381                 }
    382             }
    383         }
    384 #endif
    385         tmpdata = soc_pci_read(unit, ainfo->addr);
    386         COMPILER_64_SET(*data, 0, tmpdata);
    387         break;
    388 #ifdef BCM_CMICM_SUPPORT
    389     case soc_mcsreg:
    390         tmpdata = soc_pci_mcs_read(unit, ainfo->addr);
    391         COMPILER_64_SET(*data, 0, tmpdata);
    392         break;
    393 #endif
    394 #ifdef BCM_IPROC_SUPPORT
    395     case soc_iprocreg:
    396         tmpdata = soc_cm_iproc_read(unit, ainfo->addr);
    397         COMPILER_64_SET(*data, 0, tmpdata);
    398         break;
    399 #endif
    400     case soc_customreg:
    401     case soc_genreg:
    402     case soc_portreg:
    403     case soc_ppportreg:
    404 #if defined(BCM_TRIDENT2_SUPPORT)
    405         if (soc_feature(unit, soc_feature_pgw_mac_rsv_mask_remap) &&
    406             ainfo->reg == PGW_MAC_RSV_MASKr) {
    407             int block;
    408             uint8 acc_type;
    409 
    410             ainfo->addr = soc_reg_addr_get(unit, PGW_MAC_RSV_MASKr,
    411                                            ainfo->port, 0,
    412                                            SOC_REG_ADDR_OPTION_NONE,
    413                                            &block, &acc_type);
    414             ainfo->addr &= 0xffffff00;
    415             ainfo->addr |=
    416                 (SOC_INFO(unit).port_l2p_mapping[ainfo->port] - 1) & 0xf;
    417             rv = _soc_reg32_get(unit, block, acc_type, ainfo->addr, &tmpdata);
    418             if (SOC_SUCCESS(rv)) {
    419                 COMPILER_64_SET(*data, 0, tmpdata);
    420             }
    421             break;
    422         } else
    423 #endif /* BCM_TRIDENT2_SUPPORT */
    424         if (ainfo->valid && (int)ainfo->reg >= 0 &&
    425             SOC_REG_IS_VALID(unit, ainfo->reg) &&
    426             SOC_REG_IS_64(unit, ainfo->reg)) {
    427             if (soc_feature(unit, soc_feature_new_sbus_format)) {
    428                 rv = soc_reg_get(unit, ainfo->reg, port, ainfo->idx, data);
    429             } else {
    430                 rv = soc_reg_read(unit, ainfo->reg, ainfo->addr, data);
    431             }
    432         } else {
    433             if (soc_feature(unit, soc_feature_new_sbus_format)) {
    434                 rv = soc_reg32_get(unit, ainfo->reg, port, ainfo->idx,
    435                                    &tmpdata);
    436             } else {
    437                 rv = soc_reg32_read(unit, ainfo->addr, &tmpdata);
    438             }
    439             COMPILER_64_SET(*data, 0, tmpdata);
    440         }
    441         break;
    442 
    443     case soc_pipereg:
    444     case soc_xpereg:
    445     case soc_itmreg:
    446     case soc_ebreg:
    447     case soc_slicereg:
    448     case soc_layerreg:
    449         if (soc_feature(unit, soc_feature_new_sbus_format)) {
    450             if (ainfo->valid && (int)ainfo->reg >= 0 &&
    451                 SOC_REG_IS_VALID(unit, ainfo->reg) &&
    452                 SOC_REG_IS_64(unit, ainfo->reg)) {
    453                 rv = soc_reg_get(unit, ainfo->reg, ainfo->port, ainfo->idx, data);
    454             } else {
    455                 rv = soc_reg32_get(unit, ainfo->reg, ainfo->port, ainfo->idx, &tmpdata);
    456                  COMPILER_64_SET(*data, 0, tmpdata);
    457             }
    458             break;
    459         }
    460     case soc_cosreg:
    461         if (ainfo->valid && (int)ainfo->reg >= 0 &&
    462             SOC_REG_IS_VALID(unit, ainfo->reg) &&
    463             SOC_REG_IS_64(unit, ainfo->reg)) {
    464             if (soc_feature(unit, soc_feature_new_sbus_format)) {
    465                 rv = soc_reg_get(unit, ainfo->reg, ainfo->cos, ainfo->idx, data);
    466             } else {
    467                 rv = soc_reg_read(unit, ainfo->reg, ainfo->addr, data);
    468             }
    469         } else {
    470             if (soc_feature(unit, soc_feature_new_sbus_format)) {
    471                 rv = soc_reg32_get(unit, ainfo->reg, ainfo->cos, ainfo->idx, &tmpdata);
    472             } else {
    473                 rv = soc_reg32_read(unit, ainfo->addr, &tmpdata);
    474             }
    475             COMPILER_64_SET(*data, 0, tmpdata);
    476         }
    477         break;
    478     default:
    479         assert(0);
    480         rv = SOC_E_INTERNAL;
    481         break;
    482     }
    483 
    484     return rv;
    485 }
    486 
    487 
    488 /*
    489  * Function:
    490  *      soc_anyreg_write
    491  * Purpose:
    492  *      Write a soc register according to type
    493  * Parameters:
    494  *      unit - soc unit number
    495  *      ainfo - address information structure
    496  *      data - 64 bit data.  Will type correctly for register.
    497  * Returns:
    498  *      BCM_E_XXX
    499  * Notes:
    500  *      This routine requires ainfo->addr to be
    501  *      properly set.
    502  *      If it is a 64-bit register, then additionally, ainfo->valid
    503  *      must be set and ainfo->reg must be set properly.
    504  */
    505 
    506 int
    507 soc_anyreg_write(int unit, soc_regaddrinfo_t *ainfo, uint64 data)
    508 {
    509     uint32          tmpdata = 0;
    510     int             rv = SOC_E_NONE;
    511     soc_regtype_t   type;
    512     int             port = ainfo->port;
    513 
    514     if (ainfo->reg < 0) {
    515         type = soc_genreg;
    516     } else {
    517         if (!SOC_REG_IS_VALID(unit, ainfo->reg)) {
    518             return SOC_E_PARAM;
    519         }
    520         type = SOC_REG_INFO(unit, ainfo->reg).regtype;
    521     }
    522 
    523 #if defined(BCM_SAND_SUPPORT)
    524     if (SOC_IS_SAND(unit)) {
    525         if ((ainfo->port >=0) || (ainfo->port & SOC_REG_ADDR_INSTANCE_MASK)) {
    526             port = ainfo->port;
    527         }  else {
    528             port = REG_PORT_ANY;
    529         }
    530     }
    531 #endif
    532 
    533     switch (type) {
    534     case soc_cpureg:
    535 #ifdef BCM_CMICM_SUPPORT
    536         if (soc_feature(unit, soc_feature_cmicm)) {
    537             if (soc_feature(unit, soc_feature_cpureg_dump)){
    538                 if (soc_cpureg_address_is_invalid(unit, ainfo)) {
    539                     rv = SOC_E_INTERNAL;
    540                     break;
    541                 }
    542             }
    543         }
    544 #endif
    545         COMPILER_64_TO_32_LO(tmpdata, data);
    546         soc_pci_write(unit, ainfo->addr, tmpdata);
    547         break;
    548 #ifdef BCM_CMICM_SUPPORT
    549     case soc_mcsreg:
    550         COMPILER_64_TO_32_LO(tmpdata, data);
    551         soc_pci_mcs_write(unit, ainfo->addr, tmpdata);
    552         break;
    553 #endif
    554 #ifdef BCM_IPROC_SUPPORT
    555     case soc_iprocreg:
    556         COMPILER_64_TO_32_LO(tmpdata, data);
    557         soc_cm_iproc_write(unit, ainfo->addr, tmpdata);
    558         break;
    559 #endif
    560     case soc_customreg:
    561     case soc_genreg:
    562     case soc_portreg:
    563     case soc_ppportreg:
    564     case soc_pipereg:
    565     case soc_xpereg:
    566     case soc_itmreg:
    567     case soc_ebreg:
    568     case soc_slicereg:
    569     case soc_layerreg:
    570     case soc_cosreg:
    571         if (type == soc_cosreg) {
    572             port = ainfo->cos;
    573         }
    574 #if defined(BCM_TRIDENT2_SUPPORT)
    575         if (soc_feature(unit, soc_feature_pgw_mac_rsv_mask_remap) &&
    576             ainfo->reg == PGW_MAC_RSV_MASKr) {
    577             int block;
    578             uint8 acc_type;
    579 
    580             ainfo->addr = soc_reg_addr_get(unit, PGW_MAC_RSV_MASKr,
    581                                            ainfo->port, 0,
    582                                            SOC_REG_ADDR_OPTION_WRITE,
    583                                            &block, &acc_type);
    584             ainfo->addr &= 0xffffff00;
    585             ainfo->addr |=
    586                 (SOC_INFO(unit).port_l2p_mapping[ainfo->port] - 1) & 0xf;
    587             tmpdata = COMPILER_64_LO(data);
    588             rv = _soc_reg32_set(unit, block, acc_type, ainfo->addr, tmpdata);
    589         } else
    590 #endif /* BCM_TRIDENT2_SUPPORT */
    591         if (ainfo->valid && (int)ainfo->reg >= 0) {
    592             if (SOC_REG_IS_64(unit, ainfo->reg)) {
    593                 if (soc_feature(unit, soc_feature_new_sbus_format)) {
    594                     rv = soc_reg64_set(unit, ainfo->reg, port, ainfo->idx, data);
    595                 } else {
    596                     rv = soc_reg64_write(unit, ainfo->addr, data);
    597                 }
    598             } else {
    599                 COMPILER_64_TO_32_LO(tmpdata, data);
    600                 if (soc_feature(unit, soc_feature_new_sbus_format)) {
    601                     rv = soc_reg32_set(unit, ainfo->reg, port, ainfo->idx, tmpdata);
    602                 } else {
    603                     rv = soc_reg32_write(unit, ainfo->addr, tmpdata);
    604                 }
    605             }
    606 #if defined(BCM_XGS_SUPPORT)
    607             if (soc_feature(unit, soc_feature_regs_as_mem)) {
    608                 if (SOC_REG_IS_64(unit, ainfo->reg)) {
    609                     (void)soc_ser_reg_cache_set(unit, ainfo->reg, port < 0 ? 0 : port,
    610                                                 ainfo->idx, data);
    611                 } else {
    612                     (void)soc_ser_reg32_cache_set(unit, ainfo->reg, port < 0 ? 0 : port,
    613                                                   ainfo->idx < 0 ? 0 : ainfo->idx, tmpdata);
    614                 }
    615             }
    616 #endif /* BCM_XGS_SUPPORT */
    617         } else { /* Left around for some legacy support */
    618             rv = soc_reg32_write(unit, ainfo->addr, tmpdata);
    619         }
    620         break;
    621     default:
    622         assert(0);
    623         rv = SOC_E_INTERNAL;
    624         break;
    625     }
    626     return rv;
    627 }
    628 
    629 #define UPDATE_BP(bp) while (*(bp)) (bp)++;
    630 
    631 /* This is inefficient, because it does a lookup for each field. */
    632 void
    633 soc_reg_sprint_data(int unit, char *bp, char *infix, soc_reg_t reg,
    634                     uint32 value)
    635 {
    636     int             i, n;
    637     soc_field_t     field;
    638     int             len;
    639     char            buf[24];
    640 
    641     if (!SOC_REG_IS_VALID(unit, reg)) {
    642         return;
    643     }
    644     n = SOC_REG_INFO(unit, reg).nFields;
    645     for (i = 0; i < n; i++) {
    646         field = SOC_REG_INFO(unit, reg).fields[i].field;
    647         len = SOC_REG_INFO(unit, reg).fields[i].len;
    648         if (i == n - 1) {
    649             infix = "";
    650         }
    651 #if defined(SOC_NO_NAMES)
    652         sal_sprintf(buf, "#%%d = 0x%%0%dx%%s", (len + 3) >> 2);
    653         sal_sprintf(bp, buf, field,
    654                     soc_reg_field_get(unit, reg, value, field), infix);
    655 #else
    656         sal_sprintf(buf, "%%s = 0x%%0%dx%%s", (len + 3) >> 2);
    657         sal_sprintf(bp, buf, soc_fieldnames[field],
    658                     soc_reg_field_get(unit, reg, value, field), infix);
    659 #endif
    660         UPDATE_BP(bp);
    661     }
    662 }
    663 
    664 void
    665 soc_reg_sprint_addr(int unit, char *bp, soc_regaddrinfo_t *ainfo)
    666 {
    667     soc_field_info_t *finfop = 0;
    668     int             msb, lsb;
    669     soc_reg_info_t *reginfo;
    670     int len = 0;
    671 
    672     if (!ainfo->valid) {
    673         len = sal_strlen("Invalid Address");
    674         sal_strncpy(bp, "Invalid Address", len);
    675         bp[len] = '\0';
    676         return;
    677     }
    678     if (ainfo->reg != INVALIDr && SOC_REG_IS_VALID(unit, ainfo->reg)) {
    679         reginfo = &SOC_REG_INFO(unit, ainfo->reg);
    680         if (ainfo->field != INVALIDf) {
    681             SOC_FIND_FIELD(ainfo->field,
    682                            reginfo->fields,
    683                            reginfo->nFields,
    684                            finfop);
    685             assert(finfop);
    686             if (finfop->flags & SOCF_LE) {
    687                 msb = finfop->bp + finfop->len - 1;
    688                 lsb = finfop->bp;
    689             } else {
    690                 msb = finfop->bp;
    691                 lsb = finfop->bp + finfop->len - 1;
    692             }
    693             sal_sprintf(bp, "[%d:%d] ", msb, lsb);
    694             UPDATE_BP(bp);
    695         }
    696     } else {
    697         len = sal_strlen("Reserved");
    698         sal_strncpy(bp, "Reserved", len);
    699         bp[len] = '\0';
    700         return;
    701     }
    702 
    703 #ifdef SOC_NO_NAMES
    704     sal_sprintf(bp, "#%d", ainfo->reg);
    705 #else
    706     sal_sprintf(bp, "%s", SOC_REG_NAME(unit, ainfo->reg));
    707 #endif /* SOC_NO_NAMES */
    708     UPDATE_BP(bp);
    709 
    710     if (SOC_REG_ARRAY(unit, ainfo->reg)) {
    711         sal_sprintf(bp, "(%d)", ainfo->idx);
    712         UPDATE_BP(bp);
    713     }
    714     if (ainfo->cos != -1) {
    715         sal_sprintf(bp, ".%d", ainfo->cos);
    716         UPDATE_BP(bp);
    717     }
    718     if ((reginfo->regtype != soc_portreg) &&
    719         (reginfo->regtype != soc_ppportreg) &&
    720         (reginfo->regtype != soc_customreg)) {
    721         *bp++ = '.';
    722         len = sal_strlen(SOC_BLOCK_NAME(unit, ainfo->block));
    723         sal_strncpy(bp, SOC_BLOCK_NAME(unit, ainfo->block), len);
    724         if (len)
    725             bp[len] = '\0';
    726         UPDATE_BP(bp);
    727     }
    728     if (reginfo->regtype == soc_ppportreg) {
    729         *bp++ = '.';
    730         sal_sprintf(bp, "pp%d", ainfo->port);
    731         UPDATE_BP(bp);
    732     }
    733     if (reginfo->regtype == soc_portreg || reginfo->regtype == soc_customreg) {
    734         *bp++ = '.';
    735         len = sal_strlen(SOC_PORT_NAME(unit, ainfo->port));
    736         sal_strncpy(bp, SOC_PORT_NAME(unit, ainfo->port), len);
    737         bp[len] = '\0';
    738         UPDATE_BP(bp);
    739     }
    740     if (finfop) {
    741 #ifdef SOC_NO_NAMES
    742         sal_sprintf(bp, ".#%d", ainfo->field);
    743 #else
    744         sal_sprintf(bp, ".%s", soc_fieldnames[ainfo->field]);
    745 #endif /* SOC_NO_NAMES */
    746         UPDATE_BP(bp);
    747     }
    748 }
    749 #undef  UPDATE_BP
    750 
    751 #define SOC_E_IGNORE -6000
    752 
    753 /*
    754  * This handles the iteration for a particular register addr info
    755  * It does it across all array entries if the register is an array reg.
    756  */
    757 static int
    758 _do_reg_iter(int unit, soc_reg_iter_f do_it,
    759              soc_regaddrinfo_t *ainfo, void *data, int *done)
    760 {
    761     int             first_array_idx, idx;
    762     int             num_els, gran;
    763     int             rv = SOC_E_NONE;
    764     uint32          base_addr;
    765     soc_reg_t       reg;
    766 
    767     /* The granularity of register addresses, indexed by soc_regtype_t */
    768     /* new bus format */
    769     int soc_regtype_gran_new_bus[] = {
    770         1,      /* soc_schan_reg,    */
    771         1 << 8, /* soc_genreg,       */
    772         1,      /* soc_portreg,      */
    773         1,      /* soc_ppportreg,    */
    774         1,      /* soc_cosreg,       */
    775         1 << 8, /* soc_pipereg,      */
    776         1 << 8, /* soc_xpereg,       */
    777         1 << 8, /* soc_slicereg      */
    778         1 << 8, /* soc_layerreg      */
    779         4,      /* soc_cpureg,       */
    780         4,      /* soc_pci_cfg_reg,  */
    781         1,      /* soc_phy_reg,      */
    782         1,      /* soc_spi_reg,      */
    783         4,      /* soc_mcsreg,       */
    784         4,      /* soc_iprocreg,     */
    785         4,      /* soc_hostmem_w,    */
    786         2,      /* soc_hostmem_h,    */
    787         1,      /* soc_hostmem_b,    */
    788         1 << 8, /* soc_customreg,    */
    789         0,      /* soc_invalidreg    */
    790     };
    791     int reg_type_no = 0;
    792 
    793     reg = ainfo->reg;
    794     reg_type_no = SOC_REG_INFO(unit, reg).regtype;
    795     if (ainfo->reg == INVALIDr || !SOC_REG_IS_VALID(unit, ainfo->reg) ||
    796         reg_type_no >= COUNTOF(soc_regtype_gran_new_bus)) {
    797         return SOC_E_PARAM;
    798     }
    799 
    800     base_addr = ainfo->addr;
    801     gran = (soc_feature(unit, soc_feature_new_sbus_format))?
    802            soc_regtype_gran_new_bus[reg_type_no]:
    803            SOC_REG_GRAN(unit, reg);
    804 
    805     if (SOC_IS_GREYHOUND2(unit) &&
    806         (SOC_REG_INFO(unit, reg).regtype == soc_genreg) &&
    807         (SOC_REG_FIRST_BLK_TYPE(SOC_REG_INFO(unit, reg).block) == SOC_BLK_TAF)) {
    808         gran = 1;
    809     }
    810 
    811     if (SOC_REG_ARRAY(unit, reg) || SOC_REG_IS_ARRAY(unit, reg)) {
    812         num_els = SOC_REG_NUMELS(unit, reg);
    813         first_array_idx = SOC_REG_INFO(unit, reg).first_array_index;
    814     } else {
    815         num_els = 1;
    816         first_array_idx = 0;
    817     }
    818 
    819     for (idx = first_array_idx; (idx < first_array_idx + num_els) && !*done; idx++) {
    820         if (SOC_REG_IS_ARRAY(unit, reg)) {
    821             ainfo->addr = base_addr + (idx - first_array_idx) * SOC_REG_ELEM_SKIP(unit, reg);
    822         } else if (SOC_REG_ARRAY(unit, reg)) {
    823             ainfo->addr = base_addr + (idx * gran);
    824             if (SOC_REG_ARRAY2(unit, reg)) {
    825                 ainfo->addr = base_addr + (idx * gran * 2);
    826             } else if (SOC_REG_ARRAY4(unit, reg)) {
    827                 ainfo->addr = base_addr + (idx * gran * 4);
    828             }
    829         } else {
    830             ainfo->addr = base_addr + (idx * gran); /* idx == 0 */
    831         }
    832         ainfo->idx = idx;
    833         if ((SOC_REG_INFO(unit, reg).flags & SOC_REG_FLAG_NO_DGNL) &&
    834             (idx == ainfo->port)) {
    835             continue;
    836         }
    837         rv = (*do_it)(unit, ainfo, data);
    838         switch (rv) {
    839         case SOC_E_NONE:
    840             break;
    841         case SOC_E_IGNORE:
    842             rv = SOC_E_NONE;
    843             *done = 1;
    844             break;
    845         default:
    846             *done = 1;
    847             break;
    848         }
    849     }
    850 
    851     ainfo->addr = base_addr;
    852     return rv;
    853 }
    854 
    855 #ifdef BCM_KATANA2_SUPPORT
    856 /* EMC registers common to KT2 and SB2*/
    857 static soc_reg_t emc_regs[] =
    858 {
    859     CI0_TO_EMC_CELL_DATA_RETURN_COUNT_DEBUGr,
    860     CI0_TO_EMC_WTAG_RETURN_COUNT_DEBUGr,
    861     CI1_TO_EMC_CELL_DATA_RETURN_COUNT_DEBUGr,
    862     CI1_TO_EMC_WTAG_RETURN_COUNT_DEBUGr,
    863     EMC_BUFFER_EMPTY_FULL_STATUS_DEBUGr,
    864     EMC_CFGr,
    865     EMC_CI_FULL_STATUS_DEBUGr,
    866     EMC_CSDB_0_BUFFER_PAR_STATUS_DEBUGr,
    867     EMC_CSDB_1_BUFFER_PAR_STATUS_DEBUGr,
    868     EMC_CSDB_MEM_DEBUGr,
    869     EMC_ECC_DEBUG_0r,
    870     EMC_ECC_DEBUG_1r,
    871     EMC_ERRORr,
    872     EMC_ERROR_0r,
    873     EMC_ERROR_1r,
    874     EMC_ERROR_2r,
    875     EMC_ERROR_3r,
    876     EMC_ERROR_MASK_0r,
    877     EMC_ERROR_MASK_1r,
    878     EMC_ERROR_MASK_2r,
    879     EMC_ERROR_MASK_3r,
    880     EMC_FREE_POOL_SIZESr,
    881     EMC_GLOBAL_1B_ECC_ERROR_COUNT_DEBUGr,
    882     EMC_GLOBAL_2B_ECC_ERROR_COUNT_DEBUGr,
    883     EMC_IRRB_BUFFER_ECC_STATUS_DEBUGr,
    884     EMC_IRRB_BUFFER_FILL_LEVEL_DEBUGr,
    885     EMC_IRRB_BUFFER_WATERMARK_DEBUGr,
    886     EMC_IRRB_THRESHOLDSr,
    887     EMC_RFCQ_BUFFER_ECC_STATUS_DEBUGr,
    888     EMC_RFCQ_BUFFER_FILL_LEVEL_DEBUGr,
    889     EMC_RFCQ_BUFFER_WATERMARK_DEBUGr,
    890     EMC_RFCQ_MEM_DEBUGr,
    891     EMC_RSFP_BUFFER_ECC_STATUS_DEBUGr,
    892     EMC_RSFP_BUFFER_FILL_LEVEL_DEBUGr,
    893     EMC_RSFP_MEM_DEBUGr,
    894     EMC_SWAT_BUFFER_ECC_STATUS_DEBUGr,
    895     EMC_SWAT_MEM_DEBUGr,
    896     EMC_TO_CI0_RD_REQ_COUNT_DEBUGr,
    897     EMC_TO_CI0_WR_REQ_COUNT_DEBUGr,
    898     EMC_TO_CI1_RD_REQ_COUNT_DEBUGr,
    899     EMC_TO_CI1_WR_REQ_COUNT_DEBUGr,
    900     EMC_WLCT_MEM_DEBUGr,
    901     EMC_WLCT_MERGED_RETURN_WTAG_FIFO_MEM_DEBUGr,
    902     EMC_WLCT_MERGED_RETURN_WTAG_FIFO_NFULL_THRESHOLDr,
    903     EMC_WTFP_BUFFER_ECC_STATUS_DEBUGr,
    904     EMC_WTFP_BUFFER_FILL_LEVEL_DEBUGr,
    905     EMC_WTFP_MEM_DEBUGr,
    906     EMC_WTOQ_BUFFER_ECC_STATUS_DEBUGr,
    907     EMC_WTOQ_BUFFER_FILL_LEVEL_DEBUGr,
    908     EMC_WTOQ_MEM_DEBUGr,
    909     ITE_TO_EMC_WR_REQ_SOP_COUNT_DEBUGr,
    910     MMU_ITE_EMC_BACKPRESSURE_DEBUG_CONFIGr,
    911     MMU_ITE_EMC_BACKPRESSURE_DEBUG_STATUSr
    912 };
    913 
    914 /* EMC registers of KT2 */
    915 static soc_reg_t kt2_emc_regs[] =
    916 {
    917     CI2_TO_EMC_CELL_DATA_RETURN_COUNT_DEBUGr,
    918     CI2_TO_EMC_WTAG_RETURN_COUNT_DEBUGr,
    919     CI3_TO_EMC_CELL_DATA_RETURN_COUNT_DEBUGr,
    920     CI3_TO_EMC_WTAG_RETURN_COUNT_DEBUGr,
    921     CI4_TO_EMC_CELL_DATA_RETURN_COUNT_DEBUGr,
    922     CI4_TO_EMC_WTAG_RETURN_COUNT_DEBUGr,
    923     CI5_TO_EMC_CELL_DATA_RETURN_COUNT_DEBUGr,
    924     CI5_TO_EMC_WTAG_RETURN_COUNT_DEBUGr,
    925     EMC_CSDB_2_BUFFER_PAR_STATUS_DEBUGr,
    926     EMC_CSDB_3_BUFFER_PAR_STATUS_DEBUGr,
    927     EMC_CSDB_4_BUFFER_PAR_STATUS_DEBUGr,
    928     EMC_CSDB_5_BUFFER_PAR_STATUS_DEBUGr,
    929     EMC_ERRB_0_BUFFER_ECC_STATUS_DEBUGr,
    930     EMC_ERRB_0_BUFFER_FILL_LEVEL_DEBUGr,
    931     EMC_ERRB_0_BUFFER_WATERMARK_DEBUGr,
    932     EMC_ERRB_0_MEM_DEBUGr,
    933     EMC_ERRB_1_BUFFER_ECC_STATUS_DEBUGr,
    934     EMC_ERRB_1_BUFFER_FILL_LEVEL_DEBUGr,
    935     EMC_ERRB_1_BUFFER_WATERMARK_DEBUGr,
    936     EMC_ERRB_1_MEM_DEBUGr,
    937     EMC_ERRB_FIFO_NFULL_THRESHOLDr,
    938     EMC_EWRB_0_BUFFER_0_ECC_STATUS_DEBUGr,
    939     EMC_EWRB_0_BUFFER_1_ECC_STATUS_DEBUGr,
    940     EMC_EWRB_0_BUFFER_FILL_LEVEL_DEBUGr,
    941     EMC_EWRB_0_BUFFER_WATERMARK_DEBUGr,
    942     EMC_EWRB_0_MEM_DEBUGr,
    943     EMC_EWRB_1_BUFFER_0_ECC_STATUS_DEBUGr,
    944     EMC_EWRB_1_BUFFER_1_ECC_STATUS_DEBUGr,
    945     EMC_EWRB_1_BUFFER_FILL_LEVEL_DEBUGr,
    946     EMC_EWRB_1_BUFFER_WATERMARK_DEBUGr,
    947     EMC_EWRB_1_MEM_DEBUGr,
    948     EMC_EWRB_FIFO_NFULL_THRESHOLDr,
    949     EMC_IWRB_BUFFER_ECC_STATUS_DEBUGr,
    950     EMC_IWRB_BUFFER_FILL_LEVEL_DEBUGr,
    951     EMC_IWRB_BUFFER_WATERMARK_DEBUGr,
    952     EMC_IWRB_MEM_DEBUGr,
    953     EMC_IWRB_SIZEr,
    954     EMC_TO_CI2_RD_REQ_COUNT_DEBUGr,
    955     EMC_TO_CI2_WR_REQ_COUNT_DEBUGr,
    956     EMC_TO_CI3_RD_REQ_COUNT_DEBUGr,
    957     EMC_TO_CI3_WR_REQ_COUNT_DEBUGr,
    958     EMC_TO_CI4_RD_REQ_COUNT_DEBUGr,
    959     EMC_TO_CI4_WR_REQ_COUNT_DEBUGr,
    960     EMC_TO_CI5_RD_REQ_COUNT_DEBUGr,
    961     EMC_TO_CI5_WR_REQ_COUNT_DEBUGr,
    962     EMC_WCMT_BUFFER_ECC_STATUS_DEBUGr,
    963     EMC_WCMT_MEM_DEBUGr,
    964     EMC_WLCT0_LOWER_A_BUFFER_ECC_STATUS_DEBUGr,
    965     EMC_WLCT1_MERGED_RETURN_WTAG_FIFO_ECC_STATUS_DEBUGr,
    966     EMC_WLCT0_LOWER_B_BUFFER_ECC_STATUS_DEBUGr,
    967     EMC_WLCT0_MERGED_RETURN_WTAG_FIFO_ECC_STATUS_DEBUGr,
    968     EMC_WLCT0_UPPER_A_BUFFER_ECC_STATUS_DEBUGr,
    969     EMC_WLCT0_UPPER_B_BUFFER_ECC_STATUS_DEBUGr,
    970     EMC_WLCT1_LOWER_A_BUFFER_ECC_STATUS_DEBUGr,
    971     EMC_WLCT1_LOWER_B_BUFFER_ECC_STATUS_DEBUGr,
    972     EMC_WLCT1_UPPER_A_BUFFER_ECC_STATUS_DEBUGr,
    973     EMC_WLCT1_UPPER_B_BUFFER_ECC_STATUS_DEBUGr,
    974     EXT_BUFFER_POOL_CONG_STATEr,
    975     EMC_WLCT2_LOWER_A_BUFFER_ECC_STATUS_DEBUGr,
    976     EMC_WLCT2_LOWER_B_BUFFER_ECC_STATUS_DEBUGr,
    977     EMC_WLCT2_MERGED_RETURN_WTAG_FIFO_ECC_STATUS_DEBUGr,
    978     EMC_WLCT2_UPPER_A_BUFFER_ECC_STATUS_DEBUGr,
    979     EMC_WLCT2_UPPER_B_BUFFER_ECC_STATUS_DEBUGr
    980 };
    981 
    982 static soc_reg_t sb2_emc_regs[] =
    983 {
    984     EMC_FIXED_PATTERN_DEBUGr,
    985     EMC_IRRB_MEM_DEBUGr,
    986     EMC_TO_ITE_WR_REQ_PKT_COMPLETE_COUNT_DEBUGr,
    987     EMC_WLCT_BUFFER_ECC_STATUS_DEBUGr,
    988     EMC_WLCT_MERGED_RETURN_WTAG_FIFO_ECC_STATUS_DEBUGr,
    989     EMC_WLCT_MERGED_RETURN_WTAG_FIFO_FILL_LEVEL_DEBUGr,
    990     EMC_WLCT_MERGED_RETURN_WTAG_FIFO_WATERMARK_DEBUGr,
    991     ITE_TO_EMC_WR_REQ_EOP_COUNT_DEBUGr
    992 };
    993 
    994 static int
    995 _is_emc_reg(int unit, soc_reg_t reg)
    996 {
    997     int i;
    998 
    999     /* EMC registers common to KT2 and SB2*/
   1000     for (i = 0; i < (sizeof(emc_regs)/sizeof(soc_reg_t)); i++) {
   1001         if (emc_regs[i] == reg) {
   1002             return 1;
   1003         }
   1004     }
   1005 
   1006     /* EMC registers of KT2 */
   1007     if (SOC_IS_KATANA2(unit) && !(SOC_IS_SABER2(unit))){
   1008         for (i = 0; i < (sizeof(kt2_emc_regs)/sizeof(soc_reg_t)); i++) {
   1009             if (kt2_emc_regs[i] == reg) {
   1010                 return 1;
   1011             }
   1012         }
   1013     }
   1014 
   1015     /* EMC registers of SB2 */
   1016     if (SOC_IS_SABER2(unit)) {
   1017         for (i = 0; i < (sizeof(sb2_emc_regs)/sizeof(soc_reg_t)); i++) {
   1018             if (sb2_emc_regs[i] == reg) {
   1019                 return 1;
   1020             }
   1021         }
   1022     }
   1023 
   1024     return 0;
   1025 }
   1026 #endif
   1027 
   1028 int
   1029 soc_reg_iterate(int unit, soc_reg_iter_f do_it, void *data)
   1030 {
   1031     soc_reg_t       reg;
   1032     soc_port_t      port;
   1033     soc_cos_t       cos;
   1034     int             blk;
   1035     soc_block_types_t regblktype;
   1036     soc_regaddrinfo_t ainfo;
   1037     int             done;
   1038 #ifdef BCM_TRIUMPH2_SUPPORT
   1039     int             skip_cpu;
   1040 #endif
   1041     int             phy_port;
   1042     int             port_num_blktype;
   1043     int             i;
   1044     int             idx_min, idx_max, idx;
   1045 
   1046     ainfo.valid = 1;
   1047     ainfo.field = INVALIDf;
   1048 
   1049 #ifdef BCM_TRIUMPH2_SUPPORT
   1050     skip_cpu = soc_property_get(unit, "cmic_regtest_skip", 1);
   1051 #endif
   1052 
   1053     for (reg = 0; reg < NUM_SOC_REG; reg++) {
   1054         if (!SOC_REG_IS_VALID(unit, reg)) {
   1055             continue;
   1056         }
   1057         if (!SOC_REG_IS_ENABLED(unit, reg)) {
   1058             continue;
   1059         }
   1060         done = 0;
   1061         ainfo.reg = reg;
   1062         regblktype = SOC_REG_INFO(unit, reg).block;
   1063         if (SAL_BOOT_QUICKTURN && (SOC_BLOCK_IS(regblktype, SOC_BLK_BSAFE))) {
   1064             continue;
   1065         }
   1066         switch (SOC_REG_INFO(unit, reg).regtype) {
   1067         case soc_ppportreg:
   1068             PBMP_PP_ALL_ITER(unit, port) {
   1069                 ainfo.port = port;
   1070                 ainfo.addr = soc_reg_addr_get(unit, reg, ainfo.port, 0,
   1071                                               SOC_REG_ADDR_OPTION_NONE,
   1072                                               &ainfo.block, &ainfo.acc_type);
   1073                 ainfo.cos = -1;
   1074                 _do_reg_iter(unit, do_it, &ainfo, data, &done);
   1075                 if (done) {
   1076                     break;
   1077                 }
   1078             }
   1079             break;
   1080         case soc_customreg:
   1081         case soc_portreg:
   1082             PBMP_ALL_ITER(unit, port) {
   1083                 if (SOC_BLOCK_IN_LIST(regblktype, SOC_BLK_PORT)) {
   1084                     if (SOC_BLOCK_IS(regblktype, SOC_BLK_PGW_CL)) {
   1085                         port_num_blktype = SOC_DRIVER(unit)->port_num_blktype;
   1086                         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   1087                         blk = -1;
   1088                         for (i = 0; i < port_num_blktype; i++) {
   1089                             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   1090                             if (blk < 0) {
   1091                                 break;
   1092                             }
   1093                             if (SOC_REG_BLOCK_IN_LIST(unit, reg,
   1094                                              SOC_BLOCK_TYPE(unit, blk))) {
   1095                                 break;
   1096                             }
   1097                         }
   1098                         if (blk < 0) {
   1099                             continue;
   1100                         }
   1101                     } else if (!SOC_REG_BLOCK_IN_LIST(unit, reg,
   1102                                              SOC_PORT_TYPE(unit, port))) {
   1103                         continue;
   1104                     }
   1105                 }
   1106 #ifdef BCM_FIREBOLT_SUPPORT
   1107                 if (SOC_IS_FBX(unit)) {
   1108                     if (SOC_BLOCK_IS(regblktype, SOC_BLK_IPIPE_HI) &&
   1109                         ((!PBMP_MEMBER(SOC_BLOCK_BITMAP(unit,
   1110                                         IPIPE_HI_BLOCK(unit)), port)))) {
   1111                         continue;
   1112                     }
   1113                     if (SOC_BLOCK_IS(regblktype, SOC_BLK_EPIPE_HI) &&
   1114                         ((!PBMP_MEMBER(SOC_BLOCK_BITMAP(unit,
   1115                                         EPIPE_HI_BLOCK(unit)), port)))) {
   1116                         continue;
   1117                     }
   1118                 }
   1119 #endif
   1120 #ifdef BCM_GREYHOUND_SUPPORT
   1121                 if(SOC_IS_GREYHOUND(unit) && (SOC_BLOCK_IS(regblktype, SOC_BLK_XLPORT)||
   1122                     SOC_BLOCK_IS(regblktype, SOC_BLK_GXPORT))){
   1123                     port_num_blktype = SOC_DRIVER(unit)->port_num_blktype;
   1124                     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   1125                     blk = -1;
   1126                     for (i = 0; i < port_num_blktype; i++) {
   1127                         if (regblktype[0] == SOC_BLK_XLPORT){
   1128                             if (soc_greyhound_pgw_reg_blk_index_get(unit, reg, port,
   1129                                 NULL, &blk, NULL, 0) > 0){
   1130                                 /* get the correct blk */
   1131                                 break;
   1132                             }
   1133                         }
   1134                         blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   1135                         if (blk < 0) {
   1136                             break;
   1137                         }
   1138                         if (SOC_BLOCK_IS(regblktype,
   1139                                          SOC_BLOCK_TYPE(unit, blk))) {
   1140                             break;
   1141                         }
   1142                     }
   1143                     if (blk <= 0) {
   1144                         continue;
   1145                     }
   1146                     if (soc_greyhound_pgw_reg_blk_index_get(unit, reg, port,
   1147                                                 NULL, NULL, NULL, 0) == SOC_E_NOT_FOUND){
   1148                         /* port register not belong to pgw_gx and pgw_xl */
   1149                         if (!PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), port)){
   1150                             /* check the valid blk bitmap*/
   1151                             continue;
   1152                         }
   1153                     } else if (regblktype[0] == SOC_BLK_XLPORT){
   1154                         if (soc_greyhound_pgw_reg_blk_index_get(unit, reg, port,
   1155                             NULL, &blk, NULL, 1) > 0){
   1156                             /* check the valid blk */
   1157                             continue;
   1158                         }
   1159                     }
   1160                 }
   1161 #endif
   1162 
   1163 #ifdef BCM_TOMAHAWK3_SUPPORT
   1164                 if (SOC_IS_TOMAHAWK3(unit)) {
   1165                     if ((regblktype[0] == SOC_BLK_CDMAC) &&
   1166                                     IS_CPU_PORT(unit,port)) {
   1167                         continue;
   1168                     }
   1169                 }
   1170 #endif
   1171                 ainfo.port = port;
   1172                 ainfo.addr = soc_reg_addr_get(unit, reg, ainfo.port, 0,
   1173                                               SOC_REG_ADDR_OPTION_NONE,
   1174                                               &ainfo.block, &ainfo.acc_type);
   1175                 ainfo.block = -1;
   1176                 ainfo.cos = -1;
   1177                 _do_reg_iter(unit, do_it, &ainfo, data, &done);
   1178                 if (done) {
   1179                     break;
   1180                 }
   1181             }
   1182             break;
   1183         case soc_cosreg:
   1184             for (cos = 0; cos < NUM_COS(unit) && !done; cos++) {
   1185                 SOC_BLOCKS_ITER(unit, blk, regblktype) {
   1186                     ainfo.port = SOC_BLOCK_PORT(unit, blk);
   1187                     ainfo.addr = soc_reg_addr_get(unit, reg, ainfo.port, cos,
   1188                                                   SOC_REG_ADDR_OPTION_NONE,
   1189                                                   &ainfo.block, &ainfo.acc_type);
   1190                     ainfo.block = blk;
   1191                     ainfo.cos = cos;
   1192                     _do_reg_iter(unit, do_it, &ainfo, data, &done);
   1193                     if (done) {
   1194                         break;
   1195                     }
   1196                 }
   1197             }
   1198             break;
   1199         case soc_genreg:
   1200             if (SOC_BLOCK_IS(regblktype, SOC_BLK_ESM) &&
   1201                 (!soc_feature(unit, soc_feature_esm_support) || (SOC_CONTROL(unit)->tcam_info == NULL))) {
   1202                 break;
   1203             }
   1204 #ifdef BCM_KATANA2_SUPPORT
   1205             if (SOC_IS_KATANA2(unit)) {
   1206                 if (_is_emc_reg(unit, reg) || SOC_BLOCK_IS(regblktype, SOC_BLK_CI)) {
   1207                     if (soc_feature(unit, soc_feature_ddr3)) {
   1208                         /* Don't read external RAM related registers if same
   1209                          * is not present or not configured */
   1210                         if (!(soc_property_get(unit, spn_EXT_RAM_PRESENT, 0) &&
   1211                                soc_property_get(unit, spn_PBMP_EXT_MEM, 0))) {
   1212                             break;
   1213                         }
   1214                     } else {
   1215                         /* Don't read external RAM related regs if
   1216                          * feature not supported */
   1217                         break;
   1218                     }
   1219                 }
   1220             }
   1221 #endif
   1222             SOC_BLOCKS_ITER(unit, blk, regblktype) {
   1223                 switch (regblktype[0]) {
   1224                 case SOC_BLK_PMQPORT:
   1225                 case SOC_BLK_PMQ:
   1226                 case SOC_BLK_PGW_CL:
   1227                     ainfo.port = SOC_REG_ADDR_INSTANCE_MASK |
   1228                         SOC_BLOCK_NUMBER(unit, blk);
   1229                     break;
   1230 
   1231 #ifdef BCM_MONTEREY_SUPPORT
   1232                 case SOC_BLK_CPRI: 
   1233                         ainfo.port = SOC_BLOCK_PORT(unit, blk);
   1234                         break; 
   1235 #endif                        
   1236                 default:
   1237                     ainfo.port = SOC_BLOCK_PORT(unit, blk);
   1238                     break;
   1239                 }
   1240 #ifdef BCM_DNX_SUPPORT
   1241                 if (SOC_IS_DNX(unit) && ((regblktype[0] == SOC_BLK_CDPORT) ||
   1242                     (regblktype[0] == SOC_BLK_CDMAC))) {
   1243                     dnx_startup_test_function_f test_function = dnx_startup_test_functions[unit];
   1244                     if(test_function == NULL) {
   1245                         bcm_pbmp_t valid_ports;
   1246                         bcm_port_t valid_port;
   1247                         int phy_port = 0;
   1248                         int cd_block = 0;
   1249                         if (dnx_algo_port_logicals_get(unit, BCM_CORE_ALL, DNX_ALGO_PORT_LOGICALS_TYPE_NIF, 0, &valid_ports) < 0)   /* Get NIF logical port bitmap */
   1250                         {
   1251                             break;
   1252                         }
   1253                         BCM_PBMP_ITER(valid_ports, valid_port)
   1254                         {
   1255                             phy_port = SOC_INFO(unit).port_l2p_mapping[valid_port]; /* Get NIF port first phy */
   1256                             cd_block = SOC_PORT_BLOCK(unit, phy_port);
   1257                             if (blk == cd_block)
   1258                             {
   1259                                 break;
   1260                             }
   1261                         }
   1262                         if (blk != cd_block)
   1263                         {
   1264                             continue;
   1265                         }
   1266                     }
   1267                 }
   1268 #endif
   1269 #ifdef BCM_GREYHOUND_SUPPORT
   1270                 if (SOC_IS_GREYHOUND(unit) && ((regblktype[0] == SOC_BLK_XLPORT) ||
   1271                     (regblktype[0] == SOC_BLK_GXPORT))) {
   1272                     if (soc_greyhound_pgw_reg_blk_index_get(unit, reg, ainfo.port,
   1273                                                 NULL, NULL, NULL, 0) == SOC_E_NOT_FOUND){
   1274                         /* port register not belong to pgw_gx and pgw_xl */
   1275                         if (!PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), ainfo.port)){
   1276                             /* check the valid blk bitmap*/
   1277                             continue;
   1278                         }
   1279                     } else if (regblktype[0] == SOC_BLK_XLPORT){
   1280                         if (soc_greyhound_pgw_reg_blk_index_get(unit, reg, ainfo.port,
   1281                             NULL, &blk, NULL, 1) > 0){
   1282                             /* check the valid blk */
   1283                             continue;
   1284                         }
   1285                     }
   1286                 }
   1287 #endif
   1288 
   1289 #ifdef BCM_PETRA_SUPPORT
   1290                 if ((SOC_IS_ARAD(unit)) && (regblktype[0] == SOC_BLK_GPORT)) {
   1291                     break;
   1292                 }
   1293 #endif /*BCM_PETRA_SUPPORT*/
   1294 
   1295 #ifdef BCM_HURRICANE3_SUPPORT
   1296                 if ((SOC_IS_HURRICANE3(unit)) &&
   1297                     (regblktype[0] == SOC_BLK_PGW_GE)) {
   1298                     
   1299                     ainfo.port = SOC_REG_ADDR_INSTANCE_MASK |
   1300                         SOC_BLOCK_NUMBER(unit, blk);
   1301                 }
   1302 #endif
   1303                  
   1304 #ifdef BCM_MONTEREY_SUPPORT
   1305                 if (regblktype[0] == SOC_BLK_CPRI && !IS_CPRI_PORT(unit, ainfo.port )) { 
   1306 		    continue;  	
   1307                 }  
   1308 #endif
   1309                 ainfo.addr = soc_reg_addr_get(unit, reg, ainfo.port,
   1310                                               (SOC_REG_ARRAY(unit, reg) || SOC_REG_IS_ARRAY(unit, reg)) ? SOC_REG_INFO(unit, reg).first_array_index : 0,
   1311                                               SOC_REG_ADDR_OPTION_NONE,
   1312                                               &ainfo.block, &ainfo.acc_type);
   1313 
   1314                 ainfo.block = blk;
   1315                 ainfo.cos = -1;
   1316                 if (!soc_feature(unit, soc_feature_esm_support) &&
   1317                    soc_feature(unit, soc_feature_new_sbus_format) &&
   1318                    SOC_BLOCK_IS(regblktype, SOC_BLK_IPIPE)) { /* Needs update per chip */
   1319                     if (SOC_IS_TRIUMPH3(unit) &&
   1320                         SOC_REG_ADDR_STAGE(ainfo.addr) == 0x9) { /* IESMIF */
   1321                         continue;
   1322                     }
   1323                 }
   1324                 _do_reg_iter(unit, do_it, &ainfo, data, &done);
   1325                 if (done) {
   1326                     break;
   1327                 }
   1328             }
   1329             break;
   1330         case soc_cpureg:
   1331             /* Skip CPU registers in soc iteration. */
   1332 #ifdef BCM_TRIUMPH2_SUPPORT
   1333             if (SOC_IS_TRIUMPH2(unit) && !skip_cpu) {
   1334                 SOC_BLOCKS_ITER(unit, blk, regblktype) {
   1335                     ainfo.port = SOC_BLOCK_PORT(unit, blk);
   1336                     ainfo.addr = soc_reg_addr(unit, reg, ainfo.port, 0);
   1337                     ainfo.block = blk;
   1338                     ainfo.cos = -1;
   1339                     _do_reg_iter(unit, do_it, &ainfo, data, &done);
   1340                     if (done) {
   1341                         break;
   1342                     }
   1343                 }
   1344             }
   1345 #endif
   1346             break;
   1347         case soc_mcsreg:
   1348         case soc_iprocreg:
   1349             /* Skip MCS registers in soc iteration. */
   1350             break;
   1351         case soc_pipereg:
   1352         case soc_xpereg:
   1353         case soc_itmreg:
   1354         case soc_ebreg:
   1355         case soc_slicereg:
   1356         case soc_layerreg:
   1357             idx_min = 0;
   1358             switch (SOC_REG_INFO(unit, reg).regtype) {
   1359             case soc_pipereg:
   1360                 idx_max = NUM_PIPE(unit) - 1;
   1361                 break;
   1362             case soc_xpereg:
   1363                 idx_max = NUM_XPE(unit) - 1;
   1364                 break;
   1365             case soc_itmreg:
   1366                 idx_max = NUM_ITM(unit) - 1;
   1367                 break;
   1368             case soc_ebreg:
   1369                 idx_max = NUM_EB(unit) - 1;
   1370                 break;
   1371             case soc_slicereg:
   1372                 idx_max = NUM_SLICE(unit) - 1;
   1373                 break;
   1374             case soc_layerreg:
   1375                 idx_max = NUM_LAYER(unit) - 1;
   1376                 break;
   1377             default:
   1378                 assert(0);
   1379                 return 0;
   1380             }
   1381 
   1382             for (idx = idx_min; idx <= idx_max && !done; idx++) {
   1383                 SOC_BLOCKS_ITER(unit, blk, regblktype) {
   1384                     ainfo.port = SOC_REG_ADDR_INSTANCE_MASK | idx;
   1385                     ainfo.addr = soc_reg_addr_get(unit, reg, ainfo.port, 0,
   1386                                                   SOC_REG_ADDR_OPTION_NONE,
   1387                                                   &ainfo.block,
   1388                                                   &ainfo.acc_type);
   1389                     ainfo.block = blk;
   1390                     ainfo.cos = -1;
   1391                     _do_reg_iter(unit, do_it, &ainfo, data, &done);
   1392                     if (done) {
   1393                         break;
   1394                     }
   1395                 }
   1396             }
   1397             break;
   1398         default:
   1399             assert(0);
   1400             break;
   1401         }
   1402     }
   1403 
   1404     return 0;
   1405 }
   1406 
   1407 /*
   1408  * Given an address, fill in an regaddrinfo structure
   1409  * This can only be called for SOC registers, not for CPU registers
   1410  */
   1411 void
   1412 soc_regaddrinfo_get(int unit, soc_regaddrinfo_t *ainfo, uint32 addr)
   1413 {
   1414     int                 i, idx;
   1415     int                 blk = 0, bindex, port, phy_port;
   1416     uint32              minadr, maxadr;
   1417     soc_regtype_t       regtype;
   1418     int                 reg;
   1419     uint32              offset;         /* base address */
   1420     int                 block = -1;     /* block number */
   1421     int                 pindex;         /* port/cos index field */
   1422     int                 aindex = 0;     /* array index field */
   1423     soc_block_t         portblktype;
   1424 #ifdef BCM_TOMAHAWK3_SUPPORT
   1425     soc_reg_t reg_excep_list[]={MMU_CRB_DEVICE_PORT_TO_MMU_PORT_MAPPINGr,
   1426                                 MMU_RQE_REPL_PORT_AGG_MAPr};
   1427     int reg_index, num_regs, add_exception = 0;
   1428 #endif
   1429 
   1430 
   1431     ainfo->addr = addr;
   1432     ainfo->valid = 1;
   1433     ainfo->reg = INVALIDr;
   1434 
   1435     {
   1436         portblktype = SOC_BLK_PORT;
   1437     }
   1438     if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1439         block = ((addr >> SOC_BLOCK_BP) & 0xf) |
   1440                 (((addr >> SOC_BLOCK_MSB_BP) & 0x3) << 4);
   1441         /* extract fields from addr */
   1442         if (SOC_IS_HERCULES(unit)) {
   1443             offset = addr & 0xfffff;
   1444             pindex = 0;
   1445             aindex = 0;
   1446 #if defined(BCM_TRIDENT_SUPPORT)
   1447         } else if (SOC_IS_TD_TT(unit)) {
   1448             offset = addr & 0x3f080fff;
   1449             pindex = (addr >> SOC_REGIDX_BP) & 0x7f;
   1450             aindex = addr & 0xfff;
   1451 #endif /* BCM_TRIDENT_SUPPORT */
   1452 #if defined(BCM_FIREBOLT_SUPPORT)
   1453         } else if (SOC_IS_FBX(unit)) {
   1454             offset = addr & 0x3f0c0fff;
   1455             pindex = (addr >> SOC_REGIDX_BP) & 0x3f;
   1456             if (addr & 0x80000000) {
   1457                 pindex += 64;
   1458             }
   1459             aindex = addr & 0xfff;
   1460 #endif
   1461         } else {
   1462             offset = addr & 0xc0fff;
   1463             pindex = (addr >> SOC_REGIDX_BP) & 0x3f;
   1464             aindex = addr & 0xfff;
   1465         }
   1466     } else {
   1467         pindex = addr & 0xff;
   1468         if (addr & 0x02000000) {
   1469             offset = addr;
   1470         } else {
   1471             offset = addr & 0xffffff00;
   1472         }
   1473     }
   1474 
   1475     /* find the matching block */
   1476     /* we find the last matching block to make things work with cmic/cpic */
   1477     if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1478         blk = -1;
   1479         for (i = 0; SOC_BLOCK_INFO(unit, i).type >= 0; i++) {
   1480             if (SOC_BLOCK_INFO(unit, i).cmic == block) {
   1481                 blk = i;
   1482                 /* break; */
   1483             }
   1484         }
   1485     }
   1486     assert(blk >= 0);
   1487     for (reg = 0; reg < NUM_SOC_REG; reg++) {
   1488         if (!SOC_REG_IS_VALID(unit, reg)) {
   1489             continue;
   1490         }
   1491         minadr = SOC_REG_INFO(unit, reg).offset;
   1492         if (offset < minadr) {
   1493             continue;
   1494         }
   1495         if (SOC_REG_IS_ARRAY(unit, reg)) {
   1496             maxadr = minadr + (SOC_REG_NUMELS(unit, reg) - 1)*SOC_REG_ELEM_SKIP(unit, reg);
   1497         } else if (SOC_REG_ARRAY(unit, reg)) {
   1498             if (SOC_REG_ARRAY2(unit, reg)) {
   1499                 maxadr = minadr +
   1500                     2 * (SOC_REG_GRAN(unit, reg) * (SOC_REG_NUMELS(unit, reg) - 1));
   1501             } else if (SOC_REG_ARRAY4(unit, reg)) {
   1502                 maxadr = minadr +
   1503                     4 * (SOC_REG_GRAN(unit, reg) * (SOC_REG_NUMELS(unit, reg) - 1));
   1504             } else {
   1505                 maxadr = minadr +
   1506                     (SOC_REG_GRAN(unit, reg) * (SOC_REG_NUMELS(unit, reg) - 1));
   1507             }
   1508         } else {
   1509             maxadr = minadr;
   1510         }
   1511         if (offset > maxadr) {
   1512             continue;
   1513         }
   1514 
   1515         if (SOC_REG_ARRAY2(unit, reg)) {
   1516             if ( (offset & 0x1) != (minadr & 0x1) ) {
   1517                 /* make sure last bit are same as the base addr when array stride is 2 */
   1518                 continue;
   1519             }
   1520         }
   1521         if (SOC_REG_ARRAY4(unit, reg)) {
   1522             if ( (offset & 0x11) != (minadr & 0x11) ) {
   1523                 /* make sure last two bit are same as the base addr when array stride is 4 */
   1524                 continue;
   1525             }
   1526         }
   1527         regtype = SOC_REG_INFO(unit, reg).regtype;
   1528         if ((regtype == soc_cpureg) || (regtype == soc_mcsreg) || (regtype == soc_iprocreg))  {
   1529             continue;
   1530         }
   1531         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1532             if (!SOC_BLOCK_IS_TYPE(unit, blk, SOC_REG_INFO(unit, reg).block)) {
   1533                 continue;
   1534             }
   1535         }
   1536 
   1537         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1538             ainfo->block = blk;
   1539         }
   1540 
   1541         if (SOC_REG_IS_ARRAY(unit, reg)) {
   1542             for(idx=0 ; idx<SOC_REG_NUMELS(unit, reg) ; idx++) {
   1543                 if(minadr+idx*SOC_REG_ELEM_SKIP(unit, reg) == offset) {
   1544                     ainfo->reg = reg;
   1545                     ainfo->field = INVALIDf;
   1546                     ainfo->cos = -1;
   1547                     ainfo->port = -1;
   1548                     ainfo->idx = idx;
   1549                     return;
   1550                 }
   1551             }
   1552             continue;
   1553         }
   1554 
   1555         if (SOC_REG_ARRAY(unit, reg)) {
   1556             if (soc_feature(unit, soc_feature_new_sbus_format)) {
   1557                 aindex = (offset - SOC_REG_BASE(unit, reg)) >> 8;
   1558             } else {
   1559                 aindex = (offset - SOC_REG_BASE(unit, reg));
   1560             }
   1561             if (SOC_REG_ARRAY2(unit, reg)) {
   1562                 ainfo->idx = aindex / (2 * SOC_REG_GRAN(unit, reg));
   1563             } else if (SOC_REG_ARRAY4(unit, reg)) {
   1564                 ainfo->idx = aindex / (4 * SOC_REG_GRAN(unit, reg));
   1565             } else {
   1566                 ainfo->idx = aindex / SOC_REG_GRAN(unit, reg);
   1567             }
   1568         } else {
   1569             ainfo->idx = -1;
   1570         }
   1571 
   1572         ainfo->reg = reg;
   1573         ainfo->field = INVALIDf;
   1574         ainfo->cos = -1;
   1575         ainfo->port = -1;
   1576         switch (regtype) {
   1577         case soc_customreg:
   1578         case soc_ppportreg:
   1579         case soc_portreg:
   1580             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, reg).block, portblktype)) {
   1581                 for (phy_port = 0; ; phy_port++) {
   1582                     if (soc_feature(unit, soc_feature_logical_port_num)) {
   1583                         port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   1584                         if (port < 0) {
   1585                             continue;
   1586                         }
   1587                     } else {
   1588                         port = phy_port;
   1589                     }
   1590                     blk = SOC_PORT_BLOCK(unit, phy_port);
   1591                     bindex = SOC_PORT_BINDEX(unit, phy_port);
   1592                     if (blk < 0 && bindex < 0) {        /* end of list */
   1593                         break;
   1594                     }
   1595                     if (blk < 0) {                      /* empty slot */
   1596                         continue;
   1597                     }
   1598                     
   1599                     if ((uint32)blk == ainfo->block && bindex == pindex) {
   1600                         ainfo->port = port;
   1601                         break;
   1602                     }
   1603                 }
   1604                 if (ainfo->port == -1) {
   1605                     ainfo->reg = INVALIDr;
   1606                 }
   1607             } else {
   1608                 if (soc_feature(unit, soc_feature_logical_port_num) &&
   1609                     SOC_REG_INFO(unit, reg).block[0] == SOC_BLK_MMU) {
   1610 #ifdef BCM_TOMAHAWK3_SUPPORT
   1611                     /*MMU register with device port indexing*/
   1612                     num_regs = sizeof(reg_excep_list) / sizeof(soc_reg_t);
   1613                     for (reg_index = 0;reg_index < num_regs; reg_index++) {
   1614                         if (reg_excep_list[reg_index] == reg) {
   1615                             add_exception = 1;
   1616                             break;
   1617                         }
   1618                     }
   1619                     if (add_exception) {
   1620                         ainfo->port = pindex;
   1621                     } else
   1622 
   1623 #endif
   1624                     {
   1625                     phy_port = SOC_INFO(unit).port_m2p_mapping[pindex];
   1626                     ainfo->port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   1627                     }
   1628                 } else {
   1629                     ainfo->port = pindex;
   1630                 }
   1631             }
   1632             break;
   1633         case soc_cosreg:
   1634             if (pindex >= 0 && pindex <= NUM_COS(unit)) {
   1635                 ainfo->cos = pindex;
   1636             } else {
   1637                 ainfo->reg = INVALIDr;
   1638             }
   1639             break;
   1640         case soc_genreg:
   1641             if (pindex != 0) {
   1642                 ainfo->reg = INVALIDr;
   1643             }
   1644             break;
   1645         default:
   1646             assert(0);
   1647         }
   1648         break;
   1649     }
   1650 }
   1651 
   1652 /*
   1653  * Given an address, fill in an regaddrinfo structure
   1654  * This can only be called for SOC registers, not for CPU registers
   1655  */
   1656 void
   1657 soc_regaddrinfo_extended_get(int unit, soc_regaddrinfo_t *ainfo,
   1658                              soc_block_t block, int acc_type, uint32 addr)
   1659 {
   1660     int                 i;
   1661     int                 blk, bindex, port, phy_port = 0, cmic;
   1662     int                 actual_blk; /* For broadcast blocks this will be a broadcast member block, otherwise it will be the block itself */
   1663     uint32              minadr, maxadr;
   1664     soc_regtype_t       regtype;
   1665     int                 reg;
   1666     uint32              offset;         /* base address */
   1667     int                 pindex;         /* port/cos index field */
   1668     int                 aindex;         /* array index field */
   1669     soc_block_t         portblktype;
   1670     soc_block_types_t   regblktype;
   1671     int                 port_num_blktype;
   1672 #ifdef BCM_SAND_SUPPORT
   1673     int                 use_orig_address = 0;
   1674 #endif
   1675 #ifdef BCM_TOMAHAWK3_SUPPORT
   1676     soc_reg_t reg_excep_list[]={MMU_CRB_DEVICE_PORT_TO_MMU_PORT_MAPPINGr,
   1677                                 MMU_RQE_REPL_PORT_AGG_MAPr};
   1678     int reg_index, num_regs, add_exception = 0;
   1679     int               stage_id;
   1680 #endif
   1681 
   1682 
   1683     if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1684         soc_regaddrinfo_get(unit, ainfo, addr);
   1685         return;
   1686     }
   1687     ainfo->addr = addr;
   1688     ainfo->valid = 1;
   1689     ainfo->reg = INVALIDr;
   1690     portblktype = SOC_BLK_PORT;
   1691     port_num_blktype = SOC_DRIVER(unit)->port_num_blktype > 1 ?
   1692         SOC_DRIVER(unit)->port_num_blktype : 1;
   1693     pindex = addr & 0xff;
   1694 
   1695     /* find the matching block */
   1696     /* we find the last matching block to make things work with cmic/cpic */
   1697     blk = -1;
   1698     for (i = 0; SOC_BLOCK_INFO(unit, i).type >= 0; i++) {
   1699         cmic = SOC_BLOCK_INFO(unit, i).cmic;
   1700         if (cmic == block) {
   1701             blk = i;
   1702             /* break; */
   1703         }
   1704     }
   1705 
   1706     if (SOC_BLOCK_INFO(unit, blk).type != SOC_BLK_MMU_GLB &&
   1707         SOC_BLOCK_INFO(unit, blk).type != SOC_BLK_MMU_SC &&
   1708         SOC_BLOCK_INFO(unit, blk).type != SOC_BLK_MMU_SED &&
   1709         SOC_BLOCK_INFO(unit, blk).type != SOC_BLK_MMU_XPE &&
   1710         SOC_BLOCK_INFO(unit, blk).type != SOC_BLK_MMU_ITM &&
   1711         SOC_BLOCK_INFO(unit, blk).type != SOC_BLK_MMU_EB &&
   1712         addr & 0x02000000) {
   1713         offset = addr;
   1714     } else {
   1715         offset = addr & 0xffffff00;
   1716     }
   1717 
   1718 #if defined(BCM_SAND_SUPPORT)
   1719     if (SOC_IS_SAND(unit)) {
   1720         use_orig_address = 1; /* The register address of a soc_genreg does not end with 0x00 in DPP */
   1721     }
   1722 #endif
   1723 
   1724     actual_blk = blk;
   1725 #ifdef BCM_JERICHO_SUPPORT
   1726     /* handle broadcast blocks */
   1727     if (SOC_IS_JERICHO(unit) && SOC_BLOCK_IS_BROADCAST(unit, blk)) {
   1728         actual_blk = SOC_BLOCK_BROADCAST_MEMBER(unit, blk, 0);
   1729     }
   1730 #endif /* BCM_JERICHO_SUPPORT */
   1731 
   1732     assert(actual_blk >= 0);
   1733     for (reg = 0; reg < NUM_SOC_REG; reg++) {
   1734         uint32 reg_offset; /* base address according to the checked register candidate */
   1735         if (!SOC_REG_IS_VALID(unit, reg)) {
   1736             continue;
   1737         }
   1738         regtype = SOC_REG_INFO(unit, reg).regtype;
   1739         regblktype = SOC_REG_INFO(unit, reg).block;
   1740 #ifdef BCM_TOMAHAWK3_SUPPORT
   1741         if (SOC_IS_TOMAHAWK3(unit)) {
   1742            /* Since TH3 has the dummy blocks CDMAC defined in the regsfile, we need
   1743               to assign them to the CDPORT block */
   1744             if (regblktype[0] == SOC_BLK_CDMAC) {
   1745                 regblktype[0] = SOC_BLK_CDPORT;
   1746             }
   1747         }
   1748 #endif
   1749         /* Base address decision of GH2 TAF block */
   1750         if (SOC_IS_GREYHOUND2(unit) &&
   1751             (SOC_REG_INFO(unit, reg).regtype == soc_genreg) &&
   1752             (SOC_REG_FIRST_BLK_TYPE(regblktype) == SOC_BLK_TAF)) {
   1753             offset |= (1 << SOC_RT_BP);
   1754             pindex = 0;
   1755         }
   1756         
   1757 #ifdef BCM_SAND_SUPPORT
   1758         reg_offset = (use_orig_address && regtype == soc_genreg) ? addr : offset;
   1759         if (SOC_IS_DNX(unit) && (SOC_BLOCK_TYPE(unit, actual_blk) == SOC_BLK_CDMAC || SOC_BLOCK_TYPE(unit, actual_blk) == SOC_BLK_CDPORT)) {
   1760             reg_offset &= 0xf3ffff00;
   1761         }
   1762 #else
   1763         reg_offset = offset;
   1764 #endif
   1765 #ifdef BCM_TOMAHAWK3_SUPPORT
   1766         /* Since there are two CDMAC0 and CDMAC1, we need to determine which
   1767            stage does this port belong to for the per port registers.
   1768            For CDPORT registers, the stage is 0 and CDMAC_0 registers, it is 1
   1769            while for CDMAC_1 it is 2 */
   1770         if (SOC_IS_TOMAHAWK3(unit)) {
   1771             if (SOC_BLOCK_IS(regblktype, SOC_BLK_CDPORT)) {
   1772                 if ((reg_offset & 0x000F0000) == 0x10000) { /* CDMAC_OFFSET_CNT */
   1773                     reg_offset &= ~(0x04000000 | 0x08000000);
   1774                 }
   1775             }
   1776         }
   1777 #endif
   1778         if ((regtype == soc_cpureg) || (regtype == soc_mcsreg) || (regtype == soc_iprocreg))  {
   1779             continue;
   1780         }
   1781         /* coverity[negative_returns:FALSE] */
   1782         if (!SOC_BLOCK_IS_TYPE(unit, actual_blk, regblktype)) {
   1783 #ifdef BCM_DNX_SUPPORT
   1784             if (SOC_IS_DNX(unit) &&
   1785               ((SOC_BLOCK_TYPE(unit, actual_blk) == SOC_BLK_CDPORT && *SOC_REG_INFO(unit, reg).block == SOC_BLK_CDMAC) ||
   1786                (SOC_BLOCK_TYPE(unit, actual_blk) == SOC_BLK_CDMAC && *SOC_REG_INFO(unit, reg).block == SOC_BLK_CDPORT))) {
   1787                 /* In Jer2 CDPORT and CDMAC are the same sbus blocks */
   1788             } else
   1789 #endif
   1790             continue;
   1791         }
   1792 
   1793         if ((acc_type != SOC_REG_ACC_TYPE(unit, reg)) && (acc_type >= 0)
   1794                 /* skip acc_type check when acc_type is -ve */
   1795 #ifdef BCM_SAND_SUPPORT
   1796                 && (!use_orig_address)
   1797 #endif
   1798             ) {
   1799             continue;
   1800         }
   1801 
   1802         minadr = SOC_REG_INFO(unit, reg).offset;
   1803         if (reg_offset < minadr) {
   1804             continue;
   1805         }
   1806 
   1807         if (SOC_REG_IS_ARRAY(unit, reg)) {
   1808             maxadr = minadr + (SOC_REG_NUMELS(unit, reg) - 1) * SOC_REG_ELEM_SKIP(unit, reg);
   1809             if ( reg_offset > maxadr || ((reg_offset-minadr) % SOC_REG_ELEM_SKIP(unit, reg))) {
   1810                 continue; /* exit if address out of array range, or is not an exact multiple of element skip */
   1811             }
   1812             ainfo->idx = (reg_offset-minadr) / SOC_REG_ELEM_SKIP(unit, reg);
   1813         } else {
   1814             /* handle other possible array types */
   1815             if (SOC_REG_ARRAY(unit, reg)) {
   1816                 aindex = (reg_offset - SOC_REG_BASE(unit, reg)) >> 8;
   1817                 if (SOC_REG_ARRAY2(unit, reg)) {
   1818                     ainfo->idx = aindex / (2 * SOC_REG_GRAN(unit, reg));
   1819                     maxadr = minadr +
   1820                         ((2 * (SOC_REG_GRAN(unit, reg) *
   1821                          (SOC_REG_NUMELS(unit, reg) - 1))) << 8);
   1822                 } else if (SOC_REG_ARRAY4(unit, reg)) {
   1823                     ainfo->idx = aindex / (4 * SOC_REG_GRAN(unit, reg));
   1824                     maxadr = minadr +
   1825                         ((4 * (SOC_REG_GRAN(unit, reg) * 
   1826                          (SOC_REG_NUMELS(unit, reg) - 1))) << 8);
   1827                 } else {
   1828                     ainfo->idx = aindex / SOC_REG_GRAN(unit, reg);
   1829                     maxadr = minadr +
   1830                         (((SOC_REG_GRAN(unit, reg) *
   1831                          (SOC_REG_NUMELS(unit, reg) - 1))) << 8);
   1832                 }
   1833             } else {
   1834                 ainfo->idx = -1;
   1835                 maxadr = minadr;
   1836             }
   1837             if (reg_offset > maxadr) {
   1838                 continue;
   1839             }
   1840             if (SOC_REG_ARRAY2(unit, reg)) {
   1841                 if ( (reg_offset & 0x100) != (minadr & 0x100) ) {
   1842                     /* make sure last bit are same as the base addr when array stride is 2 */
   1843                     continue;
   1844                 }
   1845             }
   1846         }
   1847 
   1848         ainfo->block = blk;
   1849         ainfo->acc_type = acc_type;
   1850         ainfo->reg = reg;
   1851         ainfo->field = INVALIDf;
   1852         ainfo->cos = -1;
   1853         ainfo->port = REG_PORT_ANY;
   1854         switch (regtype) {
   1855         case soc_customreg:
   1856         case soc_portreg:
   1857         case soc_ppportreg:
   1858             if (SOC_BLOCK_IN_LIST(regblktype, portblktype) &&
   1859                     !(SOC_BLOCK_IS(regblktype, SOC_BLK_CDPORT))) {
   1860                 for (phy_port = 0; ; phy_port++) {
   1861                     if (soc_feature(unit, soc_feature_logical_port_num)) {
   1862                         port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   1863                         if (port < 0) {
   1864                             continue;
   1865                         }
   1866                     } else {
   1867                         port = phy_port;
   1868                     }
   1869 #ifdef BCM_KATANA2_SUPPORT
   1870                     /* Override port blocks with Linkphy Blocks.. */
   1871                     if(SOC_IS_KATANA2(unit) &&
   1872                         (regblktype[0] == SOC_BLK_TXLP) ) {
   1873                         if (soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   1874                             SOC_BLK_TXLP, &blk, &bindex) != SOC_E_NONE) {
   1875                             continue;
   1876                         }
   1877                     } else if(SOC_IS_KATANA2(unit) &&
   1878                     (regblktype[0] == SOC_BLK_RXLP) ) {
   1879                         if (soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   1880                             SOC_BLK_RXLP, &blk, &bindex) != SOC_E_NONE) {
   1881                             continue;
   1882                         }
   1883 
   1884                     } else
   1885 #endif
   1886 #ifdef BCM_METROLITE_SUPPORT
   1887                     /* Override port blocks with Linkphy Blocks.. */
   1888                     if (SOC_IS_METROLITE(unit) &&
   1889                         (regblktype[0] == SOC_BLK_IECELL)) {
   1890                         if (soc_ml_iecell_port_reg_blk_idx_get(unit, port,
   1891                             SOC_BLK_IECELL, &blk, &bindex) != SOC_E_NONE) {
   1892                             continue;
   1893                         }
   1894                     } else
   1895 #endif
   1896 #if defined (BCM_SABER2_SUPPORT)
   1897                     /* Override port blocks with Linkphy Blocks.. */
   1898                     if (SOC_IS_SABER2(unit) &&
   1899                         (regblktype[0] == SOC_BLK_IECELL)) {
   1900                         if (soc_sb2_iecell_port_reg_blk_idx_get(unit, port,
   1901                             SOC_BLK_IECELL, &blk, &bindex) != SOC_E_NONE) {
   1902                             continue;
   1903                         }
   1904                     } else
   1905 #endif
   1906                     {
   1907                         blk = SOC_PORT_BLOCK(unit, phy_port);
   1908                         bindex = SOC_PORT_BINDEX(unit, phy_port);
   1909                     }
   1910                     if (blk < 0 && bindex < 0) {        /* end of list */
   1911                         break;
   1912                     }
   1913                     if (blk < 0) {                      /* empty slot */
   1914                         continue;
   1915                     }
   1916                     
   1917                     for (i = 0; i < port_num_blktype ; i++) {
   1918 #ifdef BCM_KATANA2_SUPPORT
   1919                         /* Override port blocks with Linkphy Blocks.. */
   1920                         if(SOC_IS_KATANA2(unit) &&
   1921                             (regblktype[0] == SOC_BLK_TXLP)){
   1922                             if (soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   1923                                 SOC_BLK_TXLP, &blk, &bindex) != SOC_E_NONE) {
   1924                                 continue;
   1925                             }
   1926                         } else if(SOC_IS_KATANA2(unit) &&
   1927                         (regblktype[0] == SOC_BLK_RXLP) ) {
   1928                             if (soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   1929                                 SOC_BLK_RXLP, &blk, &bindex) != SOC_E_NONE) {
   1930                                 continue;
   1931                             }
   1932                         } else
   1933 #endif
   1934 #ifdef BCM_METROLITE_SUPPORT
   1935                         if ((SOC_IS_METROLITE(unit)) &&
   1936                             (regblktype[0] == SOC_BLK_IECELL) ) {
   1937                             if (soc_ml_iecell_port_reg_blk_idx_get(unit, port,
   1938                                 SOC_BLK_IECELL, &blk, &bindex) != SOC_E_NONE) {
   1939                                 continue;
   1940                             }
   1941                         } else
   1942 #endif
   1943 #if defined (BCM_SABER2_SUPPORT)
   1944                         if ((SOC_IS_SABER2(unit)) &&
   1945                             (regblktype[0] == SOC_BLK_IECELL) ) {
   1946                             if (soc_sb2_iecell_port_reg_blk_idx_get(unit, port,
   1947                                 SOC_BLK_IECELL, &blk, &bindex) != SOC_E_NONE) {
   1948                                 continue;
   1949                             }
   1950                         } else
   1951 #endif
   1952 #if defined (BCM_TRIDENT3_SUPPORT)
   1953                         if ((SOC_IS_TRIDENT3X(unit)) &&
   1954                             ((SOC_REG_INFO(unit, reg).block[0] == SOC_BLK_XLPORT) &&
   1955                             (pindex == 2) && (phy_port == 128))) {
   1956                             blk = SOC_PORT_IDX_BLOCK(unit, 129, i);
   1957                             bindex = 2;
   1958                         } else
   1959 #endif
   1960                         {
   1961                             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   1962                             bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
   1963                         }
   1964                         if ((uint32)blk != ainfo->block) {
   1965                             continue;
   1966                         }
   1967                         if (soc_feature(unit,
   1968                                         soc_feature_pgw_mac_rsv_mask_remap) &&
   1969                             reg == PGW_MAC_RSV_MASKr) {
   1970                             bindex = (phy_port - 1) & 0xf;
   1971                         }
   1972                         if (bindex == pindex) {
   1973                             ainfo->port = port;
   1974                             break;
   1975                         }
   1976                     }
   1977                     if (i == port_num_blktype) {
   1978                         continue;
   1979                     }
   1980                     if (blk >= 0) {
   1981                         break;
   1982                     }
   1983                 }
   1984                 if (ainfo->port == REG_PORT_ANY) {
   1985                     ainfo->reg = INVALIDr;
   1986                 }
   1987             } else {
   1988                 if (soc_feature(unit, soc_feature_logical_port_num) &&
   1989                     (regblktype[0] == SOC_BLK_MMU ||
   1990                      regblktype[0] == SOC_BLK_MMU_GLB ||
   1991                      regblktype[0] == SOC_BLK_MMU_XPE ||
   1992                      regblktype[0] == SOC_BLK_MMU_SED ||
   1993                      regblktype[0] == SOC_BLK_MMU_ITM ||
   1994                      regblktype[0] == SOC_BLK_MMU_EB ||
   1995                      regblktype[0] == SOC_BLK_MMU_SC)) {
   1996 #ifdef BCM_TOMAHAWK3_SUPPORT
   1997                     /*MMU register with device port indexing*/
   1998                     num_regs = sizeof(reg_excep_list) / sizeof(soc_reg_t);
   1999                     for (reg_index = 0;reg_index < num_regs; reg_index++) {
   2000                         if (reg_excep_list[reg_index] == reg) {
   2001                             add_exception = 1;
   2002                             break;
   2003                         }
   2004                     }
   2005                     if (add_exception) {
   2006                         ainfo->port = pindex;
   2007                     } else
   2008 
   2009 #endif
   2010                     {
   2011                     phy_port = SOC_INFO(unit).port_m2p_mapping[pindex];
   2012                     ainfo->port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   2013                     }
   2014                 } else {
   2015                     ainfo->port = pindex;
   2016                 }
   2017 #ifdef BCM_TOMAHAWK3_SUPPORT
   2018                 /* Since there are two CDMAC0 and CDMAC1, we need to determine which
   2019                 * CDMAC/stage id does this register belong to.
   2020                 * For CDMAC_0 registers, it is 1, while for CDMAC_1 it is 2 */
   2021                 if (SOC_IS_TOMAHAWK3(unit)) {
   2022                    phy_port = SOC_INFO(unit).port_m2p_mapping[pindex];
   2023                    if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CDPORT)) {
   2024                        if ((SOC_REG_INFO(unit, reg).offset & 0x000F0000) ==
   2025                                        CDMAC_OFFSET_CNT) {
   2026                            stage_id = ((((phy_port - 1) >> 2) & 1) == 0) ?
   2027                                              CDMAC0_STAGE_ID : CDMAC1_STAGE_ID;
   2028                            if (stage_id == CDMAC0_STAGE_ID) {
   2029                                pindex = pindex | 0x04000000;
   2030                                break;
   2031                            } else {
   2032                                pindex = pindex | 0x08000000;
   2033                                break;
   2034                            }
   2035                        }
   2036                    }
   2037                    ainfo->port = pindex;
   2038                 }
   2039 #endif
   2040             }
   2041             break;
   2042         case soc_cosreg:
   2043             if (pindex >= 0 && pindex <= NUM_COS(unit)) {
   2044                 ainfo->cos = pindex;
   2045             } else {
   2046                 ainfo->reg = INVALIDr;
   2047             }
   2048             break;
   2049         case soc_pipereg:
   2050             if (pindex >= 0 && pindex < NUM_PIPE(unit)) {
   2051                 ainfo->port = SOC_REG_ADDR_INSTANCE_MASK | pindex;
   2052             } else {
   2053                 ainfo->reg = INVALIDr;
   2054             }
   2055             break;
   2056         case soc_xpereg:
   2057             if (pindex >= 0 && pindex < NUM_XPE(unit)) {
   2058                 ainfo->port = SOC_REG_ADDR_INSTANCE_MASK | pindex;
   2059             } else {
   2060                 ainfo->reg = INVALIDr;
   2061             }
   2062             break;
   2063         case soc_itmreg:
   2064             if (pindex >= 0 && pindex < NUM_ITM(unit)) {
   2065                 ainfo->port = SOC_REG_ADDR_INSTANCE_MASK | pindex;
   2066             } else {
   2067                 ainfo->reg = INVALIDr;
   2068             }
   2069             break;
   2070         case soc_ebreg:
   2071             if (pindex >= 0 && pindex < NUM_EB(unit)) {
   2072                 ainfo->port = SOC_REG_ADDR_INSTANCE_MASK | pindex;
   2073             } else {
   2074                 ainfo->reg = INVALIDr;
   2075             }
   2076             break;
   2077         case soc_slicereg:
   2078             if (pindex >= 0 && pindex < NUM_SLICE(unit)) {
   2079                 ainfo->port = SOC_REG_ADDR_INSTANCE_MASK | pindex;
   2080             } else {
   2081                 ainfo->reg = INVALIDr;
   2082             }
   2083             break;
   2084         case soc_layerreg:
   2085             if (pindex >= 0 && pindex < NUM_LAYER(unit)) {
   2086                 ainfo->port = SOC_REG_ADDR_INSTANCE_MASK | pindex;
   2087             } else {
   2088                 ainfo->reg = INVALIDr;
   2089             }
   2090             break;
   2091         case soc_genreg:
   2092             if (pindex != 0) {
   2093 #ifdef BCM_SAND_SUPPORT
   2094                 if (!use_orig_address)
   2095 #endif
   2096                     ainfo->reg = INVALIDr;
   2097             }
   2098             break;
   2099         default:
   2100             assert(0);
   2101         }
   2102         if (ainfo->idx != -1) {
   2103             continue;
   2104         }
   2105         break;
   2106     }
   2107 }
   2108 
   2109 /* port_types supported: -1(all), ETH_PORT, STK_PORT, INTLB_PORT */
   2110 int
   2111 soc_pipe_port_get(int unit, uint32 port_type, int pipe, soc_pbmp_t *pbmp)
   2112 {
   2113     if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
   2114         return SOC_E_UNAVAIL;
   2115     }
   2116     if (pipe > NUM_PIPE(unit)) {
   2117         return SOC_E_PARAM;
   2118     }
   2119     SOC_PBMP_ASSIGN(*pbmp, PBMP_PIPE(unit, pipe));
   2120     SOC_PBMP_REMOVE(*pbmp, SOC_PORT_DISABLED_BITMAP(unit, all));
   2121     if (0xffffffff == port_type) {
   2122         return SOC_E_NONE;
   2123     } else {
   2124         if (!(port_type & ETH_PORT)) {
   2125             SOC_PBMP_REMOVE(*pbmp,  PBMP_E_ALL(unit));
   2126         }
   2127         if (!(port_type & STK_PORT)) {
   2128             SOC_PBMP_REMOVE(*pbmp,  PBMP_ST_ALL(unit));
   2129         }
   2130         if (!(port_type & INTLB_PORT)) {
   2131             SOC_PBMP_REMOVE(*pbmp,  PBMP_LB_ALL(unit));
   2132         }
   2133     }
   2134     return SOC_E_NONE;
   2135 }
   2136 
   2137 int
   2138 soc_port_pipe_get(int unit, int port, int *pipe)
   2139 {
   2140     if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
   2141         return SOC_E_UNAVAIL;
   2142     }
   2143     if (port > MAX_PORT(unit)) {
   2144         return SOC_E_PARAM;
   2145     }
   2146     *pipe = SOC_INFO(unit).port_pipe[port];
   2147     return SOC_E_NONE;
   2148 }
   2149 
   2150 #endif /* defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) || defined(PORTMOD_SUPPORT)*/