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

reg.c (218062B)


      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  * Register address and value manipulations.
      8  */
      9 
     10 
     11 #include <shared/bsl.h>
     12 
     13 #include <sal/core/libc.h>
     14 #include <sal/core/boot.h>
     15 
     16 #include <soc/debug.h>
     17 #include <soc/cm.h>
     18 #include <soc/drv.h>
     19 #include <soc/error.h>
     20 #include <soc/cmic.h>
     21 #include <soc/register.h>
     22 
     23 #if defined(BCM_PETRA_SUPPORT)
     24 #include <soc/dpp/drv.h>
     25 #include <soc/dpp/mbcm.h>
     26 #endif /* BCM_PETRA_SUPPORT */
     27 #if defined(BCM_DFE_SUPPORT)
     28 #include <soc/dfe/cmn/dfe_drv.h>
     29 #endif /* BCM_DFE_SUPPORT */
     30 #if defined(BCM_DNX_SUPPORT)
     31 #include <soc/dnx/drv.h>
     32 #include <soc/dnx/dnx_data/auto_generated/dnx_data_device.h>
     33 #endif
     34 #if defined(BCM_DNXF_SUPPORT)
     35 #include <soc/dnxf/cmn/dnxf_drv.h>
     36 #endif /* BCM_DNXF_SUPPORT */
     37 #ifdef DNX_TEST_CHIPS_SUPPORT
     38 #include <soc/dpp/dnxtestchip.h>
     39 #endif
     40 #ifdef BCM_CMICM_SUPPORT
     41 #include <soc/cmicm.h>
     42 #endif
     43 #ifdef BCM_IPROC_SUPPORT
     44 #include <soc/iproc.h>
     45 #endif
     46 #if defined(BCM_KATANA2_SUPPORT)
     47 #include <soc/katana2.h>
     48 #endif
     49 #if defined(BCM_GREYHOUND_SUPPORT)
     50 #include <soc/greyhound.h>
     51 #endif
     52 
     53 #ifdef CRASH_RECOVERY_SUPPORT
     54 #include <soc/hwstate/hw_log.h>
     55 #endif /* CRASH_RECOVERY_SUPPORT */
     56 
     57 #if defined(BCM_SABER2_SUPPORT)
     58 #include <soc/saber2.h>
     59 #endif
     60 #if defined(BCM_METROLITE_SUPPORT)
     61 #include <soc/metrolite.h>
     62 #endif
     63 
     64 #ifdef CANCUN_SUPPORT
     65 #include <soc/esw/cancun.h>
     66 #endif
     67 
     68 #if defined(BCM_APACHE_SUPPORT)
     69 #include <soc/apache.h>
     70 #endif
     71 #if defined(BCM_MONTEREY_SUPPORT)
     72 #include <soc/monterey.h>
     73 #endif
     74 
     75 #ifdef BCM_SAND_SUPPORT
     76 #include <soc/sand/sand_aux_access.h>
     77 #endif
     78 
     79 #include <soc/dnxc/multithread_analyzer.h>
     80 
     81 #ifdef BCM_DNX_SUPPORT
     82 #define CDMAC_OFFSET_CNT    0x10000
     83 #endif
     84 
     85 #ifdef BCM_TOMAHAWK3_SUPPORT
     86 #define CDMAC_OFFSET_CNT    0x10000
     87 #define CDMAC0_STAGE_ID     1
     88 #define CDMAC1_STAGE_ID     2
     89 #endif
     90 
     91 /*
     92  * Function:   soc_reg_datamask
     93  * Purpose:    Generate data mask for the fields in a register
     94  *             whose flags match the flags parameter
     95  * Returns:    The data mask
     96  *
     97  * Notes:  flags can be SOCF_RO, SOCF_WO, or zero (read/write)
     98  */
     99 uint32
    100 soc_reg_datamask(int unit, soc_reg_t reg, int flags)
    101 {
    102     int              i, start, end;
    103     soc_field_info_t *fieldp;
    104     soc_reg_info_t   *regp;
    105     uint32           result, mask;
    106 
    107     if (!SOC_REG_IS_VALID(unit, reg)) {
    108 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT)
    109 #if !defined(SOC_NO_NAMES)
    110         LOG_CLI((BSL_META_U(unit,
    111                             "reg %s is invalid\n"), soc_reg_name[reg]));
    112 #endif
    113 #endif
    114         assert(SOC_REG_IS_VALID(unit, reg));
    115     }
    116 
    117     regp = &(SOC_REG_INFO(unit, reg));
    118 
    119     result = 0;
    120     for (i = 0; i < (int)(regp->nFields); i++) {
    121         fieldp = &(regp->fields[i]);
    122 
    123         if ((fieldp->flags & flags) == flags) {
    124             start = fieldp->bp;
    125             if (start > 31) {
    126                 continue;
    127             }
    128             end = fieldp->bp + fieldp->len;
    129             if (end < 32) {
    130                 mask = (1 << end) - 1;
    131             } else {
    132                 mask = -1;
    133             }
    134             result |= ((uint32)-1 << start) & mask;
    135         }
    136     }
    137 
    138     return result;
    139 }
    140 
    141 /*
    142  * Function:   soc_reg64_datamask
    143  * Purpose:    Generate data mask for the fields in a 64-bit register
    144  *             whose flags match the flags parameter
    145  * Returns:    The data mask
    146  *
    147  * Notes:  flags can be SOCF_RO, SOCF_WO, or zero (read/write)
    148  */
    149 uint64
    150 soc_reg64_datamask(int unit, soc_reg_t reg, int flags)
    151 {
    152     int              i, start, end;
    153     soc_field_info_t *fieldp;
    154     soc_reg_info_t   *regp;
    155     uint64           mask, tmp, result;
    156 
    157     if (!SOC_REG_IS_VALID(unit, reg)) {
    158 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT)
    159 #if !defined(SOC_NO_NAMES)
    160         LOG_CLI((BSL_META_U(unit,
    161                             "reg %s is invalid\n"), soc_reg_name[reg]));
    162 #endif
    163 #endif
    164         assert(SOC_REG_IS_VALID(unit, reg));
    165     }
    166 
    167     regp = &(SOC_REG_INFO(unit, reg));
    168 
    169     COMPILER_64_ZERO(result);
    170 
    171     for (i = 0; i < (int)(regp->nFields); i++) {
    172         fieldp = &(regp->fields[i]);
    173 
    174         if ((fieldp->flags & flags) == flags) {
    175             start = fieldp->bp;
    176             end = fieldp->bp + fieldp->len;
    177             COMPILER_64_SET(mask, 0, 1);
    178             COMPILER_64_SHL(mask, end);
    179             COMPILER_64_SUB_32(mask, 1);
    180             COMPILER_64_ZERO(tmp);
    181     /*    coverity[overflow_assign]    */
    182             COMPILER_64_SUB_32(tmp, 1);
    183             COMPILER_64_SHL(tmp, start);
    184             COMPILER_64_AND(tmp, mask);
    185             COMPILER_64_OR(result, tmp);
    186         }
    187     }
    188 
    189     return result;
    190 }
    191 
    192 /*
    193  * Function:   soc_reg_above_64_datamask
    194  * Purpose:    Generate data mask for the fields in above 64-bit register
    195  *             whose flags match the flags parameter
    196  *
    197  * Notes:  flags can be SOCF_RO, SOCF_WO, or zero (read/write)
    198  */
    199 void
    200 soc_reg_above_64_datamask(int unit, soc_reg_t reg, int flags, soc_reg_above_64_val_t datamask)
    201 {
    202     int              i;
    203     soc_field_info_t *fieldp;
    204     soc_reg_info_t   *regp;
    205 
    206     if (!SOC_REG_IS_VALID(unit, reg)) {
    207 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT)
    208 #if !defined(SOC_NO_NAMES)
    209         LOG_CLI((BSL_META_U(unit,
    210                             "reg %s is invalid\n"), soc_reg_name[reg]));
    211 #endif
    212 #endif
    213         assert(SOC_REG_IS_VALID(unit, reg));
    214     }
    215 
    216     regp = &(SOC_REG_INFO(unit, reg));
    217 
    218     SOC_REG_ABOVE_64_CLEAR(datamask);
    219 
    220     for (i = 0; i < (int)(regp->nFields); i++) {
    221         fieldp = &(regp->fields[i]);
    222 
    223         if ((fieldp->flags & flags) == flags) {
    224             SOC_REG_ABOVE_64_CREATE_MASK(datamask, fieldp->len, fieldp->bp);
    225         }
    226     }
    227 }
    228 
    229 /************************************************************************/
    230 /* Routines for reading/writing SOC internal registers                        */
    231 /************************************************************************/
    232 
    233 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) || defined(PORTMOD_SUPPORT)
    234 
    235 STATIC 
    236 void _soc_snoop_reg(int unit, soc_block_t block, int acc, uint32 addr, 
    237                     uint32 flag, uint32 data_hi, uint32 data_lo) {
    238     soc_reg_info_t    *reg_info_p;
    239     soc_regaddrinfo_t ainfo;
    240     soc_reg_t         reg;
    241 
    242     if (bsl_check(bslLayerSoc, bslSourceTests, bslSeverityNormal, unit) == 0) {
    243         return;
    244     }
    245     soc_regaddrinfo_extended_get(unit, &ainfo, block, acc, addr);
    246     reg = (int)ainfo.reg;
    247     if (SOC_REG_IS_VALID(unit, reg)) {
    248         reg_info_p = &SOC_REG_INFO(unit, reg);
    249         /* (SOC_REG_SNOOP_READ & reg_info_p->snoop_flags))  */
    250         if (NULL != reg_info_p->snoop_cb) {
    251              if (reg_info_p->snoop_flags & flag) {
    252                  reg_info_p->snoop_cb(unit, reg,&ainfo, flag, data_hi,data_lo,
    253                                       reg_info_p->snoop_user_data);
    254              }
    255         }
    256     }
    257     return ;
    258 }
    259 #ifdef BROADCOM_DEBUG
    260 
    261 void
    262 _soc_reg_debug(int unit, int access_width, char *op_str,
    263                uint32 addr, uint32 data_hi, uint32 data_lo)
    264 {
    265     soc_regaddrinfo_t ainfo;
    266     char              buf[80];
    267 
    268     ainfo.block = SOC_BLK_NONE;
    269     soc_regaddrinfo_get(unit, &ainfo, addr);
    270 
    271     if (!ainfo.valid || (int)ainfo.reg < 0) {
    272         sal_strncpy(buf, "??", sizeof(buf));
    273     } else {
    274         soc_reg_sprint_addr(unit, buf, &ainfo);
    275     }
    276 
    277     if (data_hi != 0) {
    278         LOG_VERBOSE(BSL_LS_SOC_REG,
    279                  (BSL_META_U(unit,
    280                              "soc_reg%d_%s unit %d: "
    281                              "%s[0x%x] data=0x%08x_%08x\n"),
    282                   access_width, op_str, unit,
    283                   buf, addr, data_hi, data_lo));
    284     } else {
    285         LOG_VERBOSE(BSL_LS_SOC_REG,
    286                  (BSL_META_U(unit,
    287                              "soc_reg%d_%s unit %d: "
    288                              "%s[0x%x] data=0x%08x\n"),
    289                   access_width, op_str, unit,
    290                   buf, addr, data_lo));
    291     }
    292 }
    293 
    294 STATIC void
    295 _soc_reg_extended_debug(int unit, int access_width, char *op_str,
    296                         soc_block_t block, int acc, uint32 addr, 
    297                         uint32 data_hi, uint32 data_lo)
    298 {
    299     soc_regaddrinfo_t ainfo;
    300     char              buf[80];
    301 
    302     soc_regaddrinfo_extended_get(unit, &ainfo, block, acc, addr);
    303 
    304     if (!ainfo.valid || (int)ainfo.reg < 0) {
    305         sal_strncpy(buf, "??", sizeof(buf));
    306     } else {
    307         soc_reg_sprint_addr(unit, buf, &ainfo);
    308     }
    309 
    310     if (data_hi != 0) {
    311         LOG_VERBOSE(BSL_LS_SOC_REG,
    312                  (BSL_META_U(unit,
    313                              "soc_reg%d_%s unit %d: "
    314                              "%s[%d][0x%x] data=0x%08x_%08x\n"),
    315                   access_width, op_str, unit,
    316                   buf, block, addr, data_hi, data_lo));
    317     } else {
    318         LOG_VERBOSE(BSL_LS_SOC_REG,
    319                  (BSL_META_U(unit,
    320                              "soc_reg%d_%s unit %d: "
    321                              "%s[%d][0x%x] data=0x%08x\n"),
    322                   access_width, op_str, unit,
    323                   buf, block, addr, data_lo));
    324     }
    325 }
    326 
    327 void
    328 _soc_reg_above_64_debug(int unit, char *op_str, soc_block_t block, 
    329                uint32 addr, soc_reg_above_64_val_t data)
    330 {
    331     soc_regaddrinfo_t ainfo;
    332     char              buf[80];
    333     int i, first_non_zero;
    334 
    335     soc_regaddrinfo_extended_get(unit, &ainfo, block, 0, addr);
    336 
    337     if (!ainfo.valid || (int)ainfo.reg < 0) {
    338         sal_strncpy(buf, "??", sizeof(buf));
    339     } else {
    340         soc_reg_sprint_addr(unit, buf, &ainfo);
    341     }
    342 
    343     LOG_VERBOSE(BSL_LS_SOC_REG,
    344              (BSL_META_U(unit,
    345                          "soc_reg_above_64_%s unit %d: "
    346                          "%s[0x%x] data="),
    347               op_str, unit, 
    348               buf, addr));
    349 
    350     first_non_zero = 0;
    351     for(i=SOC_REG_ABOVE_64_MAX_SIZE_U32-1 ; i>=0 ; i--) {
    352         if(0 == i) {
    353             LOG_VERBOSE(BSL_LS_SOC_REG,
    354                      (BSL_META_U(unit,
    355                                  "0x%08x\n"),data[i]));
    356         } else {
    357             if(data[i] != 0) {
    358                 first_non_zero = 1;
    359             }
    360 
    361             if(1 == first_non_zero) {
    362                 LOG_VERBOSE(BSL_LS_SOC_REG,
    363                          (BSL_META_U(unit,
    364                                      "0x%08x_"),data[i]));
    365             }
    366         }
    367     }
    368    
    369 }
    370 
    371 #endif /* BROADCOM_DEBUG */
    372 
    373 
    374 #ifdef BCM_BIGMAC_SUPPORT
    375 
    376 /* List of registers that need iterative read/write operations */
    377 STATIC int
    378 iterative_op_required(soc_reg_t reg)
    379 {
    380     switch (reg) {
    381         case MAC_RXCTRLr:
    382         case MAC_RXMACSAr:
    383         case MAC_RXMAXSZr:
    384         case MAC_RXLSSCTRLr:
    385         case MAC_RXLSSSTATr:
    386         case MAC_RXSPARE0r:
    387         case IR64r:
    388         case IR127r:
    389         case IR255r:
    390         case IR511r:
    391         case IR1023r:
    392         case IR1518r:
    393         case IR2047r:
    394         case IR4095r:
    395         case IR9216r:
    396         case IR16383r:
    397         case IRMAXr:
    398         case IRPKTr:
    399         case IRFCSr:
    400         case IRUCr:
    401         case IRMCAr:
    402         case IRBCAr:
    403         case IRXPFr:
    404         case IRXPPr:
    405         case IRXUOr:
    406         case IRJBRr:
    407         case IROVRr:
    408         case IRXCFr:
    409         case IRFLRr:
    410         case IRPOKr:
    411         case IRMEGr:
    412         case IRMEBr:
    413         case IRBYTr:
    414         case IRUNDr:
    415         case IRFRGr:
    416         case IRERBYTr:
    417         case IRERPKTr:
    418         case IRJUNKr:
    419         case MAC_RXLLFCMSGCNTr:
    420         case MAC_RXLLFCMSGFLDSr:
    421             return TRUE;
    422             break;
    423         default:
    424             return FALSE;
    425             break;
    426     }
    427 }
    428 
    429 /*
    430  * Iterative read procedure for MAC registers on Hyperlite ports.
    431  */
    432 STATIC int
    433 soc_reg64_read_iterative(int unit, uint32 addr, soc_port_t port,
    434                          uint64 *data)
    435 {
    436     int rv, i, diff;
    437     uint64 xgxs_stat;
    438     uint32 locked;
    439     sal_usecs_t t1 = 0, t2;
    440     soc_timeout_t to;
    441     for (i = 0; i < 100; i++) {
    442        /* Read PLL lock status */
    443        soc_timeout_init(&to, 25 * MILLISECOND_USEC, 0);
    444        do {
    445            t1 = sal_time_usecs();
    446            rv = READ_MAC_XGXS_STATr(unit, port, &xgxs_stat);
    447            locked = soc_reg64_field32_get(unit, MAC_XGXS_STATr, xgxs_stat, 
    448                                           TXPLL_LOCKf);
    449            if (locked || SOC_FAILURE(rv)) {
    450                break;
    451            }
    452        } while (!soc_timeout_check(&to));
    453        if (SOC_FAILURE(rv)) {
    454            return rv;
    455        }
    456        if (!locked) {
    457            continue;
    458        }
    459        /* Read register value */
    460        SOC_IF_ERROR_RETURN(soc_reg64_read(unit, addr, data));
    461        /* Read PLL lock status */
    462        SOC_IF_ERROR_RETURN(READ_MAC_XGXS_STATr(unit, port, &xgxs_stat));
    463        locked = soc_reg64_field32_get(unit, MAC_XGXS_STATr, xgxs_stat, 
    464                                       TXPLL_LOCKf);
    465        t2 = sal_time_usecs();
    466        diff = SAL_USECS_SUB(t2, t1);
    467        if (locked && (diff < 20 * MILLISECOND_USEC)) {
    468            return SOC_E_NONE;
    469        }
    470        LOG_VERBOSE(BSL_LS_SOC_COMMON,
    471                    (BSL_META_U(unit,
    472                                "soc_reg64_read_iterative: WARNING: "
    473                                "iteration %d PLL went out of lock"),
    474                     i));
    475     }
    476     LOG_ERROR(BSL_LS_SOC_COMMON,
    477               (BSL_META_U(unit,
    478                           "soc_reg64_read_iterative: "
    479                           "operation failed:\n"))); 
    480     return SOC_E_FAIL;    
    481 }
    482 #endif /* BCM_BIGMAC_SUPPORT */
    483 
    484 /*
    485  * Read an internal 64-bit SOC register through S-Channel messaging buffer.
    486  */
    487 int
    488 _soc_reg64_get(int unit, soc_block_t block, int acc, uint32 addr, uint64 *reg)
    489 {
    490     schan_msg_t schan_msg;
    491     int rv, allow_intr = 0;
    492     int data_byte_len;
    493     int opcode, err;
    494 
    495     /*
    496      * Write message to S-Channel.
    497      */
    498     schan_msg_clear(&schan_msg);
    499 
    500     data_byte_len = 8;
    501     soc_schan_header_cmd_set(unit, &schan_msg.header, READ_REGISTER_CMD_MSG,
    502                              block, 0, acc, data_byte_len, 0, 0);
    503 
    504     schan_msg.readcmd.address = addr;
    505 
    506     if(SOC_IS_SAND(unit)) {
    507         allow_intr = 1;
    508     }
    509     /* Write header word + address DWORD, read header word + data DWORD */
    510     rv = soc_schan_op(unit, &schan_msg, 2, 3, allow_intr);
    511     if (SOC_FAILURE(rv)) {
    512 #if defined(BCM_XGS_SUPPORT)
    513         int rv1, port = 0, index;
    514 #endif /* BCM_XGS_SUPPORT */
    515         soc_regaddrinfo_t ainfo;
    516         
    517         if (!soc_feature(unit, soc_feature_ser_parity)) {
    518             return rv;
    519         }    
    520         soc_regaddrinfo_extended_get(unit, &ainfo, block, acc, addr);
    521         if (ainfo.reg != INVALIDr) {
    522             if (SOC_REG_IS_COUNTER(unit, ainfo.reg)) {
    523                 COMPILER_64_SET(*reg, 0, 0);
    524                 /* Force correct */
    525                 if (!SOC_REG_RETURN_SER_ERROR(unit)) {
    526                     rv = SOC_E_NONE;
    527                 }
    528             } 
    529 #if defined(BCM_XGS_SUPPORT)
    530             else if (soc_feature(unit, soc_feature_regs_as_mem)) {
    531                 if (SOC_REG_INFO(unit, ainfo.reg).regtype == soc_portreg) {
    532                     port = ainfo.port;
    533                 } else if (SOC_REG_INFO(unit, ainfo.reg).regtype == soc_cosreg) {
    534                     port = ainfo.cos;
    535                 }
    536                 index = ainfo.idx != -1 ? ainfo.idx : 0;
    537                 rv1 = soc_ser_reg_cache_get(unit, ainfo.reg, port, index, reg);
    538                 if (rv1 != SOC_E_NONE) {
    539                     if (SOC_REG_IS_DYNAMIC(unit, ainfo.reg)) {
    540                         COMPILER_64_SET(*reg, 0, 0);
    541                     } else {
    542                         return rv;
    543                     }
    544                 }
    545                 /* Force correct */
    546                 if (!SOC_REG_RETURN_SER_ERROR(unit)) {
    547                     rv = SOC_E_NONE;
    548                 }
    549             }
    550 #endif /* BCM_XGS_SUPPORT */
    551         } else {
    552             return rv;
    553         }
    554     }
    555     /* Check result */
    556     soc_schan_header_status_get(unit, &schan_msg.header, &opcode, NULL, NULL,
    557                                 &err, NULL, NULL);;
    558     if (opcode != READ_REGISTER_ACK_MSG || err != 0) {
    559         {
    560             LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "_soc_reg64_get: "
    561                       "invalid S-Channel reply, expected READ_REG_ACK: got %d "
    562                       "block:%d address:0x%x\n"), opcode, block, addr));
    563             soc_schan_dump(unit, &schan_msg, 2);
    564             return SOC_E_INTERNAL;
    565         }
    566     }
    567 
    568 #ifdef BROADCOM_DEBUG
    569     if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
    570         _soc_reg_extended_debug(unit, 64, "read", block, acc, addr,
    571                                 schan_msg.readresp.data[1],
    572                                 schan_msg.readresp.data[0]);
    573     }
    574 #endif /* BROADCOM_DEBUG */
    575     _soc_snoop_reg(unit, block, acc, addr,SOC_REG_SNOOP_READ, 
    576                    schan_msg.readresp.data[1],schan_msg.readresp.data[0]);
    577 
    578     COMPILER_64_SET(*reg,
    579                     schan_msg.readresp.data[1],
    580                     schan_msg.readresp.data[0]);
    581 
    582     return SOC_E_NONE;
    583 }
    584 
    585 #ifdef BCM_BIGMAC_SUPPORT
    586 
    587 /*
    588  * Iterative read procedure for MAC registers on Hyperlite ports.
    589  */
    590 STATIC int
    591 soc_reg64_get_iterative(int unit, soc_block_t block, int acc, uint32 addr,
    592                         soc_port_t port, uint64 *data)
    593 {
    594     int rv, i, diff;
    595     uint64 xgxs_stat;
    596     uint32 locked;
    597     sal_usecs_t t1 = 0, t2;
    598     soc_timeout_t to;
    599     for (i = 0; i < 100; i++) {
    600        /* Read PLL lock status */
    601        soc_timeout_init(&to, 25 * MILLISECOND_USEC, 0);
    602        do {
    603            t1 = sal_time_usecs();
    604            rv = READ_MAC_XGXS_STATr(unit, port, &xgxs_stat);
    605            locked = soc_reg64_field32_get(unit, MAC_XGXS_STATr, xgxs_stat, 
    606                                           TXPLL_LOCKf);
    607            if (locked || SOC_FAILURE(rv)) {
    608                break;
    609            }
    610        } while (!soc_timeout_check(&to));
    611        if (SOC_FAILURE(rv)) {
    612            return rv;
    613        }
    614        if (!locked) {
    615            continue;
    616        }
    617        /* Read register value */
    618        SOC_IF_ERROR_RETURN(_soc_reg64_get(unit, block, acc, addr, data));
    619        /* Read PLL lock status */
    620        SOC_IF_ERROR_RETURN(READ_MAC_XGXS_STATr(unit, port, &xgxs_stat));
    621        locked = soc_reg64_field32_get(unit, MAC_XGXS_STATr, xgxs_stat, 
    622                                       TXPLL_LOCKf);
    623        t2 = sal_time_usecs();
    624        diff = SAL_USECS_SUB(t2, t1);
    625        if (locked && (diff < 20 * MILLISECOND_USEC)) {
    626            return SOC_E_NONE;
    627        }
    628        LOG_VERBOSE(BSL_LS_SOC_COMMON,
    629                    (BSL_META_U(unit,
    630                                "soc_reg64_get_iterative: WARNING: "
    631                                "iteration %d PLL went out of lock"),
    632                     i));
    633     }
    634     LOG_ERROR(BSL_LS_SOC_COMMON,
    635               (BSL_META_U(unit,
    636                           "soc_reg64_get_iterative: "
    637                           "operation failed:\n"))); 
    638     return SOC_E_FAIL;    
    639 }
    640 
    641 #endif /* BCM_BIGMAC_SUPPORT */
    642 
    643 /*
    644  * Read an internal SOC register through S-Channel messaging buffer.
    645  * Checks if the register is 32 or 64 bits.
    646  */
    647 
    648 int
    649 soc_reg_read(int unit, soc_reg_t reg, uint32 addr, uint64 *data)
    650 {
    651     if (!SOC_REG_IS_VALID(unit, reg)) {
    652         return SOC_E_PARAM;
    653     }
    654 
    655     DNXC_MTA(dnxc_multithread_analyzer_log_resource_use(unit, MTA_RESOURCE_REG, reg, FALSE));
    656 
    657 #ifdef DNX_TEST_CHIPS_SUPPORT
    658     if (SOC_IS_DNX_TEST_DEVICE(unit)
    659 #if defined(PLISIM)
    660         && !SAL_BOOT_PLISIM
    661 #endif
    662         ) {
    663         return soc_dnxtestchip_reg_read(unit, reg, addr, data);
    664     }
    665 #endif /* DNX_TEST_CHIPS_SUPPORT */
    666 
    667     if (SOC_REG_IS_ABOVE_64(unit, reg)) {
    668         LOG_ERROR(BSL_LS_SOC_COMMON,
    669                   (BSL_META_U(unit,
    670                               "soc_reg_read: "
    671                               "Use soc_reg_above_64_get \n")));
    672         
    673         return SOC_E_FAIL;
    674     }
    675     
    676     if (SOC_REG_IS_64(unit, reg)) {
    677         soc_port_t port;
    678         soc_block_types_t regblktype = SOC_REG_INFO(unit, reg).block;
    679         int blk, pindex, bindex, block;
    680         pindex = (addr >> SOC_REGIDX_BP) & 0x3f;
    681         block = ((addr >> SOC_BLOCK_BP) & 0xf) |
    682                 (((addr >> SOC_BLOCK_MSB_BP) & 0x3) << 4);
    683         if (SOC_BLOCK_IN_LIST(regblktype, SOC_BLK_PORT) 
    684 #ifdef BCM_SAND_SUPPORT
    685            && !SOC_IS_SAND(unit)
    686 #endif /* BCM_SAND_SUPPORT */
    687 #ifdef BCM_BIGMAC_SUPPORT
    688            && iterative_op_required(reg)
    689 #endif /* BCM_BIGMAC_SUPPORT */
    690             ) {
    691             PBMP_HYPLITE_ITER(unit, port) {
    692                 blk = SOC_PORT_BLOCK(unit, port);
    693                 bindex = SOC_PORT_BINDEX(unit, port);
    694                 if ((SOC_BLOCK2SCH(unit, blk) == block) && (bindex == pindex)) {
    695                     break;
    696                 }
    697             }         
    698             if (!IS_HYPLITE_PORT(unit, port)) {
    699                 return soc_reg64_read(unit, addr, data);
    700             } 
    701 #ifdef BCM_BIGMAC_SUPPORT
    702             else {   
    703                 return soc_reg64_read_iterative(unit, addr, port, data);
    704             }
    705 #endif /* BCM_BIGMAC_SUPPORT */           
    706         } else {
    707             return soc_reg64_read(unit, addr, data);
    708         }
    709     } else {
    710         uint32 data32;
    711 
    712         SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &data32));
    713         COMPILER_64_SET(*data, 0, data32);
    714     }
    715 
    716     return SOC_E_NONE;
    717 }
    718 
    719 /*
    720  * Read an internal SOC register through S-Channel messaging buffer. 
    721  *  
    722  * block is cmic block id 
    723  */
    724 
    725 int
    726 soc_direct_memreg_get(int unit, int cmic_block, uint32 addr, uint32 dwc_read, int is_mem, uint32 *data)
    727 {
    728     schan_msg_t schan_msg;
    729     uint32 i;
    730     int allow_intr = 0;
    731     int data_byte_len;
    732     int opcode, err;
    733 
    734     /*
    735      * Write message to S-Channel.
    736      */
    737     schan_msg_clear(&schan_msg);
    738 
    739     soc_schan_header_cmd_set(unit, &schan_msg.header, (is_mem? READ_MEMORY_CMD_MSG : READ_REGISTER_CMD_MSG),
    740                              cmic_block, SOC_BLOCK2SCH(unit, CMIC_BLOCK(unit)),
    741                              0, dwc_read * 4, 0, 0);
    742 
    743 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    744     if(soc_feature(unit, soc_feature_cmicm) || soc_feature(unit, soc_feature_cmicx)) {
    745         schan_msg.readcmd.address = addr;
    746     } else
    747 #endif
    748     {
    749         uint32 cmice_addr = addr;
    750         if (cmic_block >= 0) {
    751             cmice_addr |= ((cmic_block & 0xf) << SOC_BLOCK_BP) | 
    752                             (((cmic_block >> 4) & 0x3) << SOC_BLOCK_MSB_BP);
    753         }
    754         
    755         schan_msg.readcmd.address = cmice_addr;
    756     }
    757 
    758     if (SOC_IS_SAND(unit)) {
    759         allow_intr = 1;
    760     }
    761     
    762     /* Write header word + address DWORD, read header word + data DWORD */
    763     SOC_IF_ERROR_RETURN(soc_schan_op(unit, &schan_msg, 2, dwc_read+1, allow_intr));
    764 
    765     /* Check result */
    766     soc_schan_header_status_get(unit, &schan_msg.header, &opcode, NULL,
    767                                 &data_byte_len, &err, NULL, NULL);
    768     if (opcode != (is_mem ? READ_MEMORY_ACK_MSG : READ_REGISTER_ACK_MSG) || err != 0) {
    769         {
    770             LOG_ERROR(BSL_LS_SOC_COMMON,
    771                 (BSL_META_U(unit,
    772                       "soc_direct_memreg_get(): block:%d address:%u "
    773                       "invalid S-Channel reply, expected %s and found %d err=%d\n"),
    774                       cmic_block, (unsigned)addr, (is_mem ? "READ_MEM_ACK" : "READ_REG_ACK"), opcode, err));
    775             soc_schan_dump(unit, &schan_msg, 2);
    776             return SOC_E_INTERNAL;
    777         }
    778     }
    779 
    780     for(i = 0; i < data_byte_len / 4; i++) {
    781         data[i] = schan_msg.readresp.data[i];
    782     }
    783 
    784     return SOC_E_NONE;
    785 }
    786 
    787 int
    788 soc_direct_reg_get(int unit, int cmic_block, uint32 addr, uint32 dwc_read, uint32 *data)
    789 {
    790     return soc_direct_memreg_get(unit, cmic_block, addr, dwc_read, 0, data);
    791 }
    792 
    793 
    794 void soc_direct_mem_set_cache_update(int unit, int cmic_block, uint32 addr, uint32 *entry_data)
    795 {
    796     int rc;
    797     soc_mem_t mem;
    798     int blk;
    799     int index;
    800     unsigned array_index;
    801 
    802     /* find the matching block by cmic_block */
    803     for (blk = 0; ; ++blk)
    804     {
    805         if (SOC_BLOCK_TYPE(unit, blk) < 0)
    806         {
    807             return;
    808         }
    809         else if (SOC_BLOCK_INFO(unit, blk).cmic == cmic_block)
    810         {
    811             break;
    812         }
    813     }
    814 
    815     mem = soc_addr_to_mem_extended(unit, cmic_block, 0xff, addr);
    816     if(mem == INVALIDm)
    817     {
    818         return;
    819     }
    820     SOC_MEM_ALIAS_TO_ORIG(unit,mem);
    821     rc = soc_mem_addr_to_array_element_and_index(unit, mem, addr, &array_index, &index);
    822     if (rc != SOC_E_NONE)
    823     {
    824         return;
    825     }
    826 
    827     _soc_mem_write_cache_update(unit, mem, blk, 0, index, (int)array_index, entry_data, NULL, NULL, NULL);
    828 
    829     return;
    830 }
    831 
    832 int
    833 soc_direct_memreg_set(int unit, int cmic_block, uint32 addr, uint32 dwc_write, int is_mem, uint32 *data)
    834 {
    835     schan_msg_t schan_msg;
    836     int i, allow_intr = 0;
    837 
    838     if (is_mem)
    839     {
    840         soc_direct_mem_set_cache_update(unit, cmic_block, addr, data);
    841     }
    842     /*
    843      * Setup S-Channel command packet
    844      *
    845      * NOTE: the datalen field matters only for the Write Memory and
    846      * Write Register commands, where it is used only by the CMIC to
    847      * determine how much data to send, and is in units of bytes.
    848      */
    849 
    850     schan_msg_clear(&schan_msg);
    851 
    852     soc_schan_header_cmd_set(unit, &schan_msg.header, (is_mem ? WRITE_MEMORY_CMD_MSG : WRITE_REGISTER_CMD_MSG),
    853                              cmic_block, SOC_BLOCK2SCH(unit, CMIC_BLOCK(unit)),
    854                              0, dwc_write * 4, 0, 0);
    855 
    856 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
    857     if(soc_feature(unit, soc_feature_cmicm) || soc_feature(unit, soc_feature_cmicx)) {
    858         schan_msg.writecmd.address = addr;
    859     } else
    860 #endif
    861     {
    862         uint32 cmice_addr = addr;
    863         if (cmic_block >= 0) {
    864             cmice_addr |= ((cmic_block & 0xf) << SOC_BLOCK_BP) |
    865                          (((cmic_block >> 4) & 0x3) << SOC_BLOCK_MSB_BP);
    866         }
    867         
    868         schan_msg.readcmd.address = cmice_addr;
    869     }
    870     
    871     for(i=0 ; i<dwc_write ; i++)
    872       schan_msg.writecmd.data[i] = data[i];
    873 
    874 
    875     if(SOC_IS_SAND(unit)) {
    876         allow_intr = 1;
    877     }
    878 
    879     /* Write header word + address + data DWORD */
    880     /* Note: The hardware does not send WRITE_REGISTER_ACK_MSG. */
    881     
    882     
    883 
    884     return soc_schan_op(unit, &schan_msg, dwc_write+2, 0, allow_intr);
    885 }
    886 
    887 int
    888 soc_direct_reg_set(int unit, int cmic_block, uint32 addr, uint32 dwc_write, uint32 *data)
    889 {
    890 #ifdef CRASH_RECOVERY_SUPPORT
    891     /*     Use crash recovery defined callback for access*/
    892     if (SOC_IS_DONE_INIT(unit))
    893     {
    894         if (BCM_UNIT_DO_HW_READ_WRITE(unit))
    895         {
    896             if(Hw_Log_List[unit].Access_cb.direct_reg_set)
    897             {
    898                 return Hw_Log_List[unit].Access_cb.direct_reg_set(unit, cmic_block, addr, dwc_write, data);
    899             }
    900         }
    901     }
    902 
    903 #endif /* CRASH_RECOVERY_SUPPORT */
    904     return soc_direct_memreg_set(unit, cmic_block, addr, dwc_write, 0, data);
    905 }
    906 
    907 /*
    908  * Read an internal SOC register through S-Channel messaging buffer.
    909  * Use soc_reg32_get() if you know the port number, index
    910  */
    911 
    912 int
    913 _soc_reg32_get(int unit, soc_block_t block, int acc, uint32 addr, uint32 *data)
    914 {
    915     schan_msg_t schan_msg;
    916     int rv, allow_intr = 0;
    917     int data_byte_len;
    918     int opcode, err;
    919 #ifdef BCM_HELIX5_SUPPORT
    920     soc_info_t *si = &SOC_INFO(unit);
    921 #endif
    922 
    923     /*
    924      * Write message to S-Channel.
    925      */
    926     schan_msg_clear(&schan_msg);
    927 
    928     data_byte_len = 4;
    929     soc_schan_header_cmd_set(unit, &schan_msg.header, READ_REGISTER_CMD_MSG,
    930                              block, 0, acc, data_byte_len, 0, 0);
    931 
    932     schan_msg.readcmd.address = addr;
    933 
    934     if(SOC_IS_SAND(unit)) {
    935         allow_intr = 1;
    936     }
    937 
    938     /* Write header word + address DWORD, read header word + data DWORD */
    939     rv = soc_schan_op(unit, &schan_msg, 2, 2, allow_intr);
    940     if (SOC_FAILURE(rv)) {
    941 #if defined(BCM_XGS_SUPPORT)
    942         int rv1, port = 0, index;
    943 #endif /* BCM_XGS_SUPPORT */
    944         soc_regaddrinfo_t ainfo;
    945         
    946         if (!soc_feature(unit, soc_feature_ser_parity)) {
    947             return rv;
    948         }
    949         soc_regaddrinfo_extended_get(unit, &ainfo, block, acc, addr);
    950         if (ainfo.reg != INVALIDr) {
    951             if (SOC_REG_IS_COUNTER(unit, ainfo.reg)) {
    952                 *data = 0;
    953                 /* Force correct */
    954                 if (!SOC_REG_RETURN_SER_ERROR(unit)) {
    955                     rv = SOC_E_NONE;
    956                 }
    957             } 
    958 #if defined(BCM_XGS_SUPPORT)
    959             else if (soc_feature(unit, soc_feature_regs_as_mem)) {
    960                 if (SOC_REG_INFO(unit, ainfo.reg).regtype == soc_portreg) {
    961                     port = ainfo.port;
    962                 } else if (SOC_REG_INFO(unit, ainfo.reg).regtype == soc_cosreg) {
    963                     port = ainfo.cos;
    964                 }
    965                 index = ainfo.idx != -1 ? ainfo.idx : 0;
    966                 rv1 = soc_ser_reg32_cache_get(unit, ainfo.reg, port, index, data);
    967                 if (rv1 != SOC_E_NONE) {
    968                     if (SOC_REG_IS_DYNAMIC(unit, ainfo.reg)) {
    969                         *data = 0;
    970                     } else {
    971                         return rv;
    972                     }
    973                 }
    974                 /* Force correct */
    975                 if (!SOC_REG_RETURN_SER_ERROR(unit)) {
    976                     rv = SOC_E_NONE;
    977                 }
    978             }
    979 #endif /* BCM_XGS_SUPPORT */
    980         } else {
    981             return rv;
    982         }
    983     }
    984 
    985     /* Check result */
    986     soc_schan_header_status_get(unit, &schan_msg.header, &opcode, NULL, NULL,
    987                                 &err, NULL, NULL);
    988     if (opcode != READ_REGISTER_ACK_MSG || err != 0) {
    989         {
    990             LOG_ERROR(BSL_LS_SOC_COMMON,
    991                   (BSL_META_U(unit,
    992                               "_soc_reg32_get: "
    993                               "invalid S-Channel reply, expected READ_REG_ACK(%d) and found %d err=%d\n"),
    994                               READ_REGISTER_ACK_MSG, opcode, err));
    995             soc_schan_dump(unit, &schan_msg, 2);
    996             return SOC_E_INTERNAL;
    997         }
    998     }
    999 
   1000     *data = schan_msg.readresp.data[0];
   1001 
   1002 #ifdef BCM_HELIX5_SUPPORT
   1003     /* For HX5 A WAR is needed when reading 'CHIP_CONFIGr', since the fields
   1004        PMD_PLL_CTRL_REFLK_DIV2f/PMD_PLL_CTRL_REFLK_DIV4f are swapped (Write
   1005        into the register is fine) */
   1006     if (si->hx5_chip_config_war_enable) {
   1007         uint32 pll_ctrl_ref_clk_div2 = 0, pll_ctrl_ref_clk_div4 = 0;
   1008         if (addr == si->hx5_chip_config_address) {
   1009             pll_ctrl_ref_clk_div2 = soc_reg_field_get(unit, CHIP_CONFIGr,
   1010                                     *data, PMD_PLL_CTRL_REFCLK_DIV2f);
   1011             pll_ctrl_ref_clk_div4 = soc_reg_field_get(unit, CHIP_CONFIGr,
   1012                                     *data, PMD_PLL_CTRL_REFCLK_DIV4f);
   1013             soc_reg_field_set(unit, CHIP_CONFIGr, data, PMD_PLL_CTRL_REFCLK_DIV2f,
   1014                                     pll_ctrl_ref_clk_div4);
   1015             soc_reg_field_set(unit, CHIP_CONFIGr, data, PMD_PLL_CTRL_REFCLK_DIV4f,
   1016                                     pll_ctrl_ref_clk_div2);
   1017         }
   1018     }
   1019 #endif /* BCM_HELIX5_SUPPORT */
   1020 
   1021 #ifdef BROADCOM_DEBUG
   1022     if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   1023         _soc_reg_extended_debug(unit, 32, "read", block, acc, addr, 0, *data);
   1024     }
   1025 #endif /* BROADCOM_DEBUG */
   1026     _soc_snoop_reg(unit, block, acc, addr,SOC_REG_SNOOP_READ, 0,*data);
   1027 
   1028     return SOC_E_NONE;
   1029 }
   1030 
   1031 /*
   1032  * Read an internal SOC register through S-Channel messaging buffer.
   1033  * Checks if the register is 32 or 64 bits.
   1034  */
   1035 
   1036 int
   1037 soc_reg_get(int unit, soc_reg_t reg, int port, int index, uint64 *data)
   1038 {
   1039     uint32 addr;
   1040     int block;
   1041     int pindex = port; 
   1042     int rv = SOC_E_NONE;
   1043     uint8 acc_type = 0;
   1044 
   1045     if (!SOC_REG_IS_VALID(unit, reg)) {
   1046         return SOC_E_PARAM;
   1047     }
   1048 
   1049     DNXC_MTA(dnxc_multithread_analyzer_log_resource_use(unit, MTA_RESOURCE_REG, reg, FALSE));
   1050 
   1051 #ifdef CRASH_RECOVERY_SUPPORT
   1052     /*     Use crash recovery defined callback for access*/
   1053     if (SOC_IS_DONE_INIT(unit) && BCM_UNIT_DO_HW_READ_WRITE(unit) && Hw_Log_List[unit].Access_cb.soc_reg_get) {
   1054         rv = Hw_Log_List[unit].Access_cb.soc_reg_get(unit, reg, port, index, data);
   1055     } else
   1056 #endif /* CRASH_RECOVERY_SUPPORT */
   1057    /* Use user defined callback for access */
   1058     if (SOC_INFO(unit).reg_access.reg64_get) {
   1059         rv = SOC_INFO(unit).reg_access.reg64_get(unit, reg, port, index, data);
   1060     } else
   1061 
   1062     if (SOC_REG_IS_ABOVE_64(unit, reg)) {
   1063         LOG_ERROR(BSL_LS_SOC_COMMON,
   1064                   (BSL_META_U(unit,
   1065                               "soc_reg_get: "
   1066                               "Use soc_reg_above_64_get \n")));
   1067         
   1068         return SOC_E_FAIL;
   1069     } else
   1070 
   1071 #ifdef CANCUN_SUPPORT
   1072     if (SOC_REG_IS_CCH(unit, reg) && !(soc_property_get(unit,
   1073                               "skip_cancun_cch_reg_check", 0) ? TRUE : FALSE) &&
   1074         SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CCH)) {
   1075              rv = soc_cancun_pseudo_reg_get(unit, reg, data);
   1076     } else
   1077 #endif
   1078 
   1079 #ifdef DNX_TEST_CHIPS_SUPPORT
   1080     if (SOC_IS_DNX_TEST_DEVICE(unit)
   1081 #if defined(PLISIM)
   1082         && !SAL_BOOT_PLISIM
   1083 #endif
   1084         ) {
   1085         rv = soc_dnxtestchip_reg_get(unit, reg, port, data);
   1086     } else
   1087 #endif /* DNX_TEST_CHIPS_SUPPORT */
   1088     {
   1089         addr = soc_reg_addr_get(unit, reg, port, index, SOC_REG_ADDR_OPTION_NONE, &block, &acc_type);
   1090         if (SOC_REG_IS_64(unit, reg)) {
   1091             soc_port_t _port;
   1092             soc_block_types_t regblktype = SOC_REG_INFO(unit, reg).block;
   1093             int blk, bindex;
   1094             if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1095                 rv = soc_reg_read(unit, reg, addr, data);
   1096             }
   1097 
   1098             else if (SOC_BLOCK_IN_LIST(regblktype, SOC_BLK_PORT) 
   1099 #ifdef BCM_SAND_SUPPORT
   1100                && !SOC_IS_SAND(unit)
   1101 #endif /* BCM_SAND_SUPPORT */
   1102 #ifdef BCM_BIGMAC_SUPPORT
   1103                && iterative_op_required(reg)
   1104 #endif /* BCM_BIGMAC_SUPPORT */
   1105                 ) {
   1106                 PBMP_HYPLITE_ITER(unit, _port) {
   1107                     blk = SOC_PORT_BLOCK(unit, _port);
   1108                     bindex = SOC_PORT_BINDEX(unit, _port);
   1109                     if ((SOC_BLOCK2SCH(unit, blk) == block) && (bindex == pindex)) {
   1110                         break;
   1111                     }
   1112                 }         
   1113                 if (!IS_HYPLITE_PORT(unit, port)) {
   1114                     rv = _soc_reg64_get(unit, block, acc_type, addr, data);
   1115                 }  
   1116 #ifdef BCM_BIGMAC_SUPPORT
   1117                 else
   1118                 {   
   1119                     rv = soc_reg64_get_iterative(unit, block, acc_type, addr, port, data);
   1120                 }
   1121 #endif            
   1122             } else {
   1123                 rv = _soc_reg64_get(unit, block, acc_type, addr, data);
   1124             }
   1125         } else {
   1126             uint32 data32;
   1127             if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1128                 rv = soc_reg32_read(unit, addr, &data32);
   1129             } else {
   1130                 rv = _soc_reg32_get(unit, block, acc_type, addr, &data32);
   1131             }
   1132             if (rv == SOC_E_NONE) {
   1133                 COMPILER_64_SET(*data, 0, data32);
   1134             }
   1135         }
   1136     }
   1137 
   1138     if (rv != SOC_E_NONE) {
   1139         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   1140           "soc_reg_get failed for %s\n"), SOC_REG_NAME(unit, reg)));
   1141     }
   1142     return rv;
   1143 }
   1144 
   1145 /*
   1146  * Read an internal SOC register through S-Channel messaging buffer.
   1147  * Handle register at any size 
   1148  */
   1149  
   1150 int
   1151 soc_reg_above_64_get(int unit, soc_reg_t reg, int port, int index, soc_reg_above_64_val_t data)
   1152 {
   1153     uint32 addr;
   1154     int block;
   1155     uint8 at; 
   1156     uint64 data64;
   1157     int rc;
   1158     int reg_size;
   1159     
   1160     if (!SOC_REG_IS_VALID(unit, reg)) {
   1161         return SOC_E_PARAM;
   1162     }
   1163     
   1164     SOC_REG_ABOVE_64_CLEAR(data);
   1165     
   1166 #ifdef CRASH_RECOVERY_SUPPORT
   1167 
   1168     /*     Use crash recovery defined callback for access*/
   1169     if (SOC_IS_DONE_INIT(unit))
   1170     {
   1171         if (BCM_UNIT_DO_HW_READ_WRITE(unit))
   1172         {
   1173             if(Hw_Log_List[unit].Access_cb.reg_above64_get)
   1174             {
   1175                 return Hw_Log_List[unit].Access_cb.reg_above64_get(unit, reg, port, index, data);
   1176             }
   1177         }
   1178     }
   1179 
   1180 #endif /* CRASH_RECOVERY_SUPPORT */
   1181 
   1182 #ifdef DNX_TEST_CHIPS_SUPPORT
   1183     if (SOC_IS_DNX_TEST_DEVICE(unit)
   1184 #if defined(PLISIM)
   1185         && !SAL_BOOT_PLISIM
   1186 #endif
   1187         ) {
   1188         return soc_dnxtestchip_reg_above_64_get(unit, reg, port, data);
   1189     }
   1190 #endif /* DNX_TEST_CHIPS_SUPPORT */
   1191 
   1192     /* Use user defined callback for access */
   1193     if(SOC_INFO(unit).reg_access.reg_above64_get) {
   1194         return SOC_INFO(unit).reg_access.reg_above64_get(unit, reg, port, index, data);
   1195     }
   1196 
   1197     if (SOC_REG_IS_ABOVE_64(unit, reg)) 
   1198     {
   1199         reg_size = SOC_REG_ABOVE_64_INFO(unit, reg).size;
   1200         addr = soc_reg_addr_get(unit, reg, port, index,
   1201                                 SOC_REG_ADDR_OPTION_NONE, &block, &at);
   1202         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1203             block = ((addr >> SOC_BLOCK_BP) & 0xf) | (((addr >> SOC_BLOCK_MSB_BP) & 0x3) << 4);
   1204         }
   1205         rc = soc_direct_reg_get(unit, block, addr, reg_size, data);
   1206 
   1207 #ifdef BROADCOM_DEBUG
   1208         if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   1209             _soc_reg_above_64_debug(unit, "get", block, addr, data);
   1210         }
   1211 #endif /* BROADCOM_DEBUG */
   1212 
   1213         if (rc != SOC_E_NONE) {
   1214             LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   1215               "soc_reg_above_64_get failed for %s\n"), SOC_REG_NAME(unit, reg)));
   1216         }
   1217         return rc;
   1218 
   1219     } 
   1220     else if (SOC_REG_IS_64(unit, reg)) {
   1221         COMPILER_64_SET(data64, data[1], data[0]);
   1222         rc = soc_reg_get(unit, reg, port, index, &data64);
   1223         data[0] = COMPILER_64_LO(data64);
   1224         data[1] = COMPILER_64_HI(data64);
   1225         return rc;
   1226     } 
   1227     else {
   1228         rc = soc_reg_get(unit, reg, port, index, &data64);
   1229         data[0] = COMPILER_64_LO(data64);
   1230         return rc;
   1231     }
   1232 }
   1233 
   1234 /*
   1235  * Read an internal SOC register through S-Channel messaging buffer.
   1236  * Uses sbusv1 format, before CMICm
   1237  * SHOULD not be called from other files, use soc_reg32_get() instead
   1238  */
   1239 
   1240 int
   1241 soc_reg32_read(int unit,
   1242                uint32 addr,
   1243                uint32 *data)
   1244 {
   1245     schan_msg_t schan_msg;
   1246     int rv, allow_intr = 0;
   1247     int dst_blk, src_blk, data_byte_len;
   1248     int opcode, err;
   1249 
   1250 #ifdef BCM_CMICM_SUPPORT
   1251     uint32 fsdata = 0;
   1252     int cmc = SOC_PCI_CMC(unit);
   1253 #endif
   1254 
   1255 #ifdef DNX_TEST_CHIPS_SUPPORT
   1256     if (SOC_IS_DNX_TEST_DEVICE(unit)
   1257 #if defined(PLISIM)
   1258         && !SAL_BOOT_PLISIM
   1259 #endif
   1260         ) {
   1261         return soc_dnxtestchip_reg32_read(unit, addr, data);
   1262     }
   1263 #endif /* DNX_TEST_CHIPS_SUPPORT */
   1264 
   1265 #ifdef BCM_CMICM_SUPPORT
   1266     if(soc_feature(unit, soc_feature_cmicm) &&
   1267         (NULL != SOC_CONTROL(unit)->fschanMutex)) {
   1268         FSCHAN_LOCK(unit);
   1269         soc_pci_write(unit, CMIC_CMCx_FSCHAN_ADDRESS_OFFSET(cmc), addr);
   1270         fsdata = soc_pci_read(unit, CMIC_CMCx_FSCHAN_DATA32_OFFSET(cmc));
   1271         FSCHAN_UNLOCK(unit);
   1272         *data = fsdata;
   1273     } else
   1274 #endif
   1275     {
   1276         /*
   1277          * Write message to S-Channel.
   1278          */
   1279         schan_msg_clear(&schan_msg);
   1280 
   1281         dst_blk = ((addr >> SOC_BLOCK_BP) & 0xf) | 
   1282             (((addr >> SOC_BLOCK_MSB_BP) & 0x3) << 4);
   1283         {
   1284             src_blk = SOC_IS_SHADOW(unit) ?
   1285                 0 : SOC_BLOCK2SCH(unit, CMIC_BLOCK(unit));
   1286             data_byte_len = SOC_IS_XGS12_FABRIC(unit) ? 8 : 4;
   1287         }
   1288         soc_schan_header_cmd_set(unit, &schan_msg.header,
   1289                                  READ_REGISTER_CMD_MSG, dst_blk, src_blk, 0,
   1290                                  data_byte_len, 0, 0);
   1291 
   1292         schan_msg.readcmd.address = addr;
   1293 
   1294         if(SOC_IS_SAND(unit)) {
   1295             allow_intr = 1;
   1296         }
   1297 
   1298         /* Write header word + address DWORD, read header word + data DWORD */
   1299         rv = soc_schan_op(unit, &schan_msg, 2, 2, allow_intr);
   1300         if (SOC_FAILURE(rv)) {
   1301 #if defined(BCM_XGS_SUPPORT)
   1302             int rv1, port = 0, index;
   1303 #endif /* BCM_XGS_SUPPORT */
   1304             soc_regaddrinfo_t ainfo;
   1305             
   1306             if (!soc_feature(unit, soc_feature_ser_parity)) {
   1307                 return rv;
   1308             }
   1309             soc_regaddrinfo_get(unit, &ainfo, addr);            
   1310             if (ainfo.reg != INVALIDr) {
   1311                 if (SOC_REG_IS_COUNTER(unit, ainfo.reg)) {
   1312                     *data = 0;
   1313                     /* Force correct */
   1314                     if (!SOC_REG_RETURN_SER_ERROR(unit)) {
   1315                         rv = SOC_E_NONE;
   1316                     }
   1317                 } 
   1318 #if defined(BCM_XGS_SUPPORT)
   1319                 else if (soc_feature(unit, soc_feature_regs_as_mem)) {
   1320                     if (SOC_REG_INFO(unit, ainfo.reg).regtype == soc_portreg) {
   1321                         port = ainfo.port;
   1322                     } else if (SOC_REG_INFO(unit, ainfo.reg).regtype == soc_cosreg) {
   1323                         port = ainfo.cos;
   1324                     }
   1325                     index = ainfo.idx != -1 ? ainfo.idx : 0;
   1326                     rv1 = soc_ser_reg32_cache_get(unit, ainfo.reg, port, index, data);
   1327                     if (rv1 != SOC_E_NONE) {
   1328                         if (SOC_REG_IS_DYNAMIC(unit, ainfo.reg)) {
   1329                             *data = 0;
   1330                         } else {
   1331                             return rv;
   1332                         }
   1333                     }
   1334                     /* Force correct */
   1335                     if (!SOC_REG_RETURN_SER_ERROR(unit)) {
   1336                         rv = SOC_E_NONE;
   1337                     }
   1338                 }
   1339 #endif /* BCM_XGS_SUPPORT */
   1340             } else {
   1341                 return rv;
   1342             }
   1343         }
   1344 
   1345         /* Check result */
   1346         soc_schan_header_status_get(unit, &schan_msg.header, &opcode, NULL,
   1347                                     NULL, &err, NULL, NULL);
   1348         if (!SOC_FAILURE(rv) && 
   1349             (opcode != READ_REGISTER_ACK_MSG || err != 0)) {
   1350             LOG_ERROR(BSL_LS_SOC_COMMON,
   1351                       (BSL_META_U(unit,
   1352                                   "soc_reg32_read: "
   1353                                   "invalid S-Channel reply, expected READ_REG_ACK:\n")));
   1354             soc_schan_dump(unit, &schan_msg, 2);
   1355             return SOC_E_INTERNAL;
   1356         }
   1357         *data = schan_msg.readresp.data[0];
   1358     }
   1359 #ifdef BROADCOM_DEBUG
   1360     if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   1361         _soc_reg_debug(unit, 32, "read", addr, 0, *data);
   1362     }
   1363 #endif /* BROADCOM_DEBUG */
   1364     _soc_snoop_reg(unit, 0, 0, addr,SOC_REG_SNOOP_READ, 0, *data);
   1365     return SOC_E_NONE;
   1366 }
   1367 
   1368 /*
   1369  * Read an internal SOC register through S-Channel messaging buffer.
   1370  */
   1371 
   1372 int
   1373 soc_reg32_get(int unit, soc_reg_t reg, int port, int index, uint32 *data)
   1374 {
   1375     uint32 addr;
   1376     int block = 0;
   1377     uint8 acc_type = 0;
   1378 
   1379     if (!SOC_REG_IS_VALID(unit, reg)) {
   1380         return SOC_E_PARAM;
   1381     }
   1382 
   1383     DNXC_MTA(dnxc_multithread_analyzer_log_resource_use(unit, MTA_RESOURCE_REG, reg, FALSE));
   1384 
   1385     if (SOC_REG_IS_ABOVE_32(unit, reg)) {
   1386 #if !defined(SOC_NO_NAMES)
   1387         LOG_CLI((BSL_META_U(unit,
   1388                             "reg %s is > 32 bit , but called with soc_reg32_get\n"), soc_reg_name[reg]));
   1389 #endif
   1390     }
   1391     assert(!SOC_REG_IS_ABOVE_32(unit, reg));
   1392 
   1393     /*     Use crash recovery defined callback for access*/
   1394 #ifdef CRASH_RECOVERY_SUPPORT
   1395     if (SOC_IS_DONE_INIT(unit))
   1396     {
   1397         if (BCM_UNIT_DO_HW_READ_WRITE(unit))
   1398         {
   1399             if(Hw_Log_List[unit].Access_cb.reg32_get)
   1400             {
   1401                 return Hw_Log_List[unit].Access_cb.reg32_get(unit, reg, port, index, data);
   1402             }
   1403         }
   1404     }
   1405 
   1406 #endif /* CRASH_RECOVERY_SUPPORT */
   1407 
   1408     /* Use user defined callback for access */
   1409     if(SOC_INFO(unit).reg_access.reg32_get) {
   1410         return SOC_INFO(unit).reg_access.reg32_get(unit, reg, port, index, data);
   1411     }
   1412 
   1413 #ifdef CANCUN_SUPPORT
   1414     if (SOC_REG_IS_CCH(unit, reg) && !(soc_property_get(unit,
   1415                               "skip_cancun_cch_reg_check", 0) ? TRUE : FALSE)) {
   1416         uint64 rval64;
   1417         int rv;
   1418 
   1419         if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CCH)) {
   1420             rv = soc_cancun_pseudo_reg_get(unit, reg, &rval64);
   1421             if(rv == SOC_E_NONE) {
   1422                 *data = COMPILER_64_LO(rval64);
   1423             }
   1424             return rv;
   1425         }
   1426     }
   1427 #endif
   1428 
   1429     addr = soc_reg_addr_get(unit, reg, port, index,
   1430                             SOC_REG_ADDR_OPTION_NONE, &block, &acc_type);
   1431 
   1432     if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1433         return soc_reg32_read(unit, addr, data);
   1434     }
   1435     return _soc_reg32_get(unit, block, acc_type, addr, data);
   1436 }
   1437 
   1438 /*
   1439  * Read an internal 64-bit SOC register through S-Channel messaging buffer.
   1440  */
   1441 int
   1442 soc_reg64_read(int unit,
   1443                uint32 addr,
   1444                uint64 *reg)
   1445 {
   1446     schan_msg_t schan_msg;
   1447     int rv, allow_intr = 0;
   1448     int dst_blk, src_blk, data_byte_len;
   1449     int opcode, err;
   1450 
   1451 #ifdef BCM_CMICM_SUPPORT
   1452     uint32 fsdatal = 0, fsdatah = 0;
   1453     int cmc = SOC_PCI_CMC(unit);
   1454 #endif
   1455 
   1456 #ifdef DNX_TEST_CHIPS_SUPPORT
   1457     if (SOC_IS_DNX_TEST_DEVICE(unit)
   1458 #if defined(PLISIM)
   1459         && !SAL_BOOT_PLISIM
   1460 #endif
   1461         ) {
   1462         return soc_dnxtestchip_reg64_read(unit, addr, reg);
   1463     }
   1464 #endif /* DNX_TEST_CHIPS_SUPPORT */
   1465 
   1466 #ifdef BCM_CMICM_SUPPORT
   1467     if(soc_feature(unit, soc_feature_cmicm) &&
   1468         (NULL != SOC_CONTROL(unit)->fschanMutex)) {
   1469         FSCHAN_LOCK(unit);
   1470         soc_pci_write(unit, CMIC_CMCx_FSCHAN_ADDRESS_OFFSET(cmc), addr);
   1471         fsdatal = soc_pci_read(unit, CMIC_CMCx_FSCHAN_DATA64_LO_OFFSET(cmc));
   1472         fsdatah = soc_pci_read(unit, CMIC_CMCx_FSCHAN_DATA64_HI_OFFSET(cmc));
   1473         FSCHAN_UNLOCK(unit);
   1474         COMPILER_64_SET(*reg, fsdatah, fsdatal);
   1475     } else
   1476 #endif
   1477     {
   1478         /*
   1479          * Write message to S-Channel.
   1480          */
   1481         schan_msg_clear(&schan_msg);
   1482 
   1483         dst_blk = ((addr >> SOC_BLOCK_BP) & 0xf) | 
   1484             (((addr >> SOC_BLOCK_MSB_BP) & 0x3) << 4);
   1485         {
   1486             src_blk = SOC_IS_SHADOW(unit) ?
   1487                 0 : SOC_BLOCK2SCH(unit, CMIC_BLOCK(unit));
   1488             data_byte_len = 8;
   1489         }
   1490         soc_schan_header_cmd_set(unit, &schan_msg.header,
   1491                                  READ_REGISTER_CMD_MSG, dst_blk, src_blk, 0,
   1492                                  data_byte_len, 0, 0);
   1493 
   1494         schan_msg.readcmd.address = addr;
   1495 
   1496         if(SOC_IS_SAND(unit)) {
   1497             allow_intr = 1;
   1498         }
   1499 
   1500         /* Write header word + address DWORD, read header word + data DWORD */
   1501         rv = soc_schan_op(unit, &schan_msg, 2, 3, allow_intr);
   1502         if (SOC_FAILURE(rv)) {
   1503 #if defined(BCM_XGS_SUPPORT)
   1504             int rv1, port = 0, index;
   1505 #endif /* BCM_XGS_SUPPORT */
   1506             soc_regaddrinfo_t ainfo;
   1507             
   1508             if (!soc_feature(unit, soc_feature_ser_parity)) {
   1509                 return rv;
   1510             }    
   1511             soc_regaddrinfo_get(unit, &ainfo, addr);            
   1512             if (ainfo.reg != INVALIDr) {
   1513                 if (SOC_REG_IS_COUNTER(unit, ainfo.reg)) {
   1514                     COMPILER_64_SET(*reg, 0, 0);
   1515                     /* Force correct */
   1516                     if (!SOC_REG_RETURN_SER_ERROR(unit)) {
   1517                         rv = SOC_E_NONE;
   1518                     }
   1519                 } 
   1520 #if defined(BCM_XGS_SUPPORT)
   1521                 else if (soc_feature(unit, soc_feature_regs_as_mem)) {
   1522                     if (SOC_REG_INFO(unit, ainfo.reg).regtype == soc_portreg) {
   1523                         port = ainfo.port;
   1524                     } else if (SOC_REG_INFO(unit, ainfo.reg).regtype == soc_cosreg) {
   1525                         port = ainfo.cos;
   1526                     }
   1527                     index = ainfo.idx != -1 ? ainfo.idx : 0;
   1528                     rv1 = soc_ser_reg_cache_get(unit, ainfo.reg, port, index, reg);
   1529                     if (rv1 != SOC_E_NONE) {
   1530                         if (SOC_REG_IS_DYNAMIC(unit, ainfo.reg)) {
   1531                             COMPILER_64_SET(*reg, 0, 0);
   1532                         } else {
   1533                             return rv;
   1534                         }
   1535                     }
   1536                     /* Force correct */
   1537                     if (!SOC_REG_RETURN_SER_ERROR(unit)) {
   1538                         rv = SOC_E_NONE;
   1539                     }
   1540                 }
   1541 #endif /* BCM_XGS_SUPPORT */
   1542             } else {
   1543                 return rv;
   1544             }
   1545         }
   1546 
   1547         /* Check result */
   1548         soc_schan_header_status_get(unit, &schan_msg.header, &opcode, NULL,
   1549                                     NULL, &err, NULL, NULL);
   1550         if (opcode != READ_REGISTER_ACK_MSG || err != 0) {
   1551             LOG_ERROR(BSL_LS_SOC_COMMON,
   1552                       (BSL_META_U(unit,
   1553                                   "soc_reg64_read: "
   1554                                   "invalid S-Channel reply, expected READ_REG_ACK:\n")));
   1555             soc_schan_dump(unit, &schan_msg, 2);
   1556             return SOC_E_INTERNAL;
   1557         }
   1558         COMPILER_64_SET(*reg, schan_msg.readresp.data[1],
   1559                         schan_msg.readresp.data[0]);
   1560     }
   1561 
   1562 #ifdef BROADCOM_DEBUG
   1563     if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   1564         _soc_reg_debug(unit, 64, "read", addr,
   1565                        schan_msg.readresp.data[1],
   1566                        schan_msg.readresp.data[0]);
   1567     }
   1568 #endif /* BROADCOM_DEBUG */
   1569     _soc_snoop_reg(unit, 0, 0, addr,SOC_REG_SNOOP_READ, 
   1570                    schan_msg.readresp.data[1], schan_msg.readresp.data[0]);
   1571 
   1572     return SOC_E_NONE;
   1573 }
   1574 
   1575 /*
   1576  * Read an internal 64-bit SOC register through S-Channel messaging buffer.
   1577  */
   1578 int
   1579 soc_reg64_get(int unit, soc_reg_t reg, int port, int index, uint64 *data)
   1580 {
   1581     uint32 addr;
   1582     int block = 0;
   1583     uint8 acc_type = 0;
   1584 
   1585     DNXC_MTA(dnxc_multithread_analyzer_log_resource_use(unit, MTA_RESOURCE_REG, reg, FALSE));
   1586 
   1587 #ifdef CANCUN_SUPPORT
   1588     if (SOC_REG_IS_CCH(unit, reg) && !(soc_property_get(unit,
   1589                               "skip_cancun_cch_reg_check", 0) ? TRUE : FALSE)) {
   1590         if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CCH)) {
   1591             return(soc_cancun_pseudo_reg_get(unit, reg, data));
   1592         }
   1593     }
   1594 #endif
   1595 
   1596 #ifdef CRASH_RECOVERY_SUPPORT
   1597     /*     Use crash recovery defined callback for access*/
   1598     if (SOC_IS_DONE_INIT(unit))
   1599     {
   1600         if (BCM_UNIT_DO_HW_READ_WRITE(unit))
   1601         {
   1602             if(Hw_Log_List[unit].Access_cb.reg64_get)
   1603             {
   1604                 return Hw_Log_List[unit].Access_cb.reg64_get(unit, reg, port, index, data);
   1605             }
   1606         }
   1607     }
   1608 #endif /* CRASH_RECOVERY_SUPPORT */
   1609 
   1610     /* Use user defined callback for access */
   1611     if(SOC_INFO(unit).reg_access.reg64_get) {
   1612         return SOC_INFO(unit).reg_access.reg64_get(unit, reg, port, index, data);
   1613     }
   1614 
   1615     addr = soc_reg_addr_get(unit, reg, port, index,
   1616                             SOC_REG_ADDR_OPTION_NONE, &block, &acc_type);
   1617     assert(SOC_REG_IS_64(unit, reg));
   1618     if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1619         return soc_reg64_read(unit, addr, data);
   1620     }
   1621     return _soc_reg64_get(unit, block, acc_type, addr, data);
   1622 }
   1623 
   1624 /*
   1625  * Read an internal SOC register through S-Channel messaging buffer
   1626  * with Raw Port Number.
   1627  */
   1628 int
   1629 soc_reg_rawport_get(int unit, soc_reg_t reg, int port, int index, uint64 *data)
   1630 {
   1631     uint32 addr;
   1632     int block = 0;
   1633     uint8 acc_type;
   1634 
   1635     if (!SOC_REG_IS_VALID(unit, reg)) {
   1636         return SOC_E_PARAM;
   1637     }
   1638 
   1639     if ((REG_PORT_ANY != port) &&
   1640         (port & (SOC_REG_ADDR_INSTANCE_MASK | SOC_REG_ADDR_BLOCK_ID_MASK | 
   1641                 SOC_REG_ADDR_SCHAN_ID_MASK | SOC_REG_ADDR_PHY_ACC_MASK))) {
   1642         LOG_ERROR(BSL_LS_SOC_COMMON,
   1643                   (BSL_META_U(unit,
   1644                               "This function is only for Raw Port Numbers \n")));
   1645         return SOC_E_FAIL;
   1646     }
   1647 #ifdef CRASH_RECOVERY_SUPPORT
   1648     /* Don't handle Special Accesses */
   1649     if((SOC_INFO(unit).reg_access.reg64_get) || /* User defined */
   1650        (SOC_REG_IS_ABOVE_64(unit, reg)) ||
   1651        (SOC_IS_DONE_INIT(unit) && BCM_UNIT_DO_HW_READ_WRITE(unit) &&
   1652         Hw_Log_List[unit].Access_cb.soc_reg_get)) {
   1653         LOG_ERROR(BSL_LS_SOC_COMMON,
   1654                   (BSL_META_U(unit,
   1655                               "Use soc_reg_get \n")));
   1656         return SOC_E_FAIL;
   1657     }
   1658 #else
   1659     if((SOC_INFO(unit).reg_access.reg64_get) || /* User defined */
   1660        (SOC_REG_IS_ABOVE_64(unit, reg))) {
   1661         LOG_ERROR(BSL_LS_SOC_COMMON,
   1662                   (BSL_META_U(unit,
   1663                               "Use soc_reg_get \n")));
   1664         return SOC_E_FAIL;
   1665     }
   1666 #endif /* CRASH_RECOVERY_SUPPORT */
   1667 
   1668     addr = soc_reg_addr_get(unit, reg, port, index,
   1669                             SOC_REG_ADDR_OPTION_PRESERVE_PORT,
   1670                             &block, &acc_type);
   1671 
   1672     if (SOC_REG_IS_64(unit, reg)) {
   1673         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1674             return soc_reg_read(unit, reg, addr, data);
   1675         } else {
   1676             return _soc_reg64_get(unit, block, acc_type, addr, data);
   1677         }
   1678     } else {
   1679         uint32 data32;
   1680         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   1681             SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &data32));
   1682         } else {
   1683             SOC_IF_ERROR_RETURN
   1684                 (_soc_reg32_get(unit, block, acc_type, addr, &data32));
   1685         }
   1686         COMPILER_64_SET(*data, 0, data32);
   1687     }
   1688     return SOC_E_NONE;
   1689 }
   1690 
   1691 int
   1692 soc_reg32_rawport_get(int unit, soc_reg_t reg, int port, int index, uint32 *data)
   1693 {
   1694     int rv;
   1695     uint64 d64;
   1696 
   1697     rv = soc_reg_rawport_get(unit, reg, port, index, &d64);
   1698     *data = COMPILER_64_LO(d64);
   1699     return rv;
   1700 }
   1701 
   1702 #ifdef BCM_BIGMAC_SUPPORT
   1703 /*
   1704  * Iterative write procedure for MAC registers on Hyperlite ports.
   1705  */
   1706 STATIC int
   1707 soc_reg64_write_iterative(int unit, uint32 addr, soc_port_t port,
   1708                           uint64 data)
   1709 {
   1710     int rv, i, diff;
   1711     uint64 xgxs_stat;
   1712     uint32 locked;
   1713     sal_usecs_t t1 = 0, t2;
   1714     soc_timeout_t to;
   1715     for (i = 0; i < 100; i++) {
   1716        /* Read PLL lock status */
   1717        soc_timeout_init(&to, 25 * MILLISECOND_USEC, 0);
   1718        do {
   1719            t1 = sal_time_usecs();
   1720            rv = READ_MAC_XGXS_STATr(unit, port, &xgxs_stat);
   1721            locked = soc_reg64_field32_get(unit, MAC_XGXS_STATr, xgxs_stat, 
   1722                                           TXPLL_LOCKf);
   1723            if (locked || SOC_FAILURE(rv)) {
   1724                break;
   1725            }
   1726        } while (!soc_timeout_check(&to));
   1727        if (SOC_FAILURE(rv)) {
   1728            return rv;
   1729        }
   1730        if (!locked) {
   1731            continue;
   1732        }
   1733        /* Write register value */
   1734        SOC_IF_ERROR_RETURN(soc_reg64_write(unit, addr, data));
   1735        /* Read PLL lock status */
   1736        SOC_IF_ERROR_RETURN(READ_MAC_XGXS_STATr(unit, port, &xgxs_stat));
   1737        locked = soc_reg64_field32_get(unit, MAC_XGXS_STATr, xgxs_stat, 
   1738                                       TXPLL_LOCKf);
   1739        t2 = sal_time_usecs();
   1740        diff = SAL_USECS_SUB(t2, t1);
   1741        if (locked && (diff < 20 * MILLISECOND_USEC)) {
   1742            return SOC_E_NONE;
   1743        }
   1744        LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1745                    (BSL_META_U(unit,
   1746                                "soc_reg64_write_iterative: WARNING: "
   1747                                "iteration %d PLL went out of lock"),
   1748                     i));
   1749     }
   1750     LOG_ERROR(BSL_LS_SOC_COMMON,
   1751               (BSL_META_U(unit,
   1752                           "soc_reg64_write_iterative: "
   1753                           "operation failed:\n"))); 
   1754     return SOC_E_FAIL;    
   1755 }
   1756 
   1757 #endif /* BCM_BIGMAC_SUPPORT */
   1758 
   1759 #ifdef BCM_TOMAHAWK3_SUPPORT
   1760 /*
   1761  * Write an internal 64-bit TH3 SOC register through S-Channel messaging buffer.
   1762  */
   1763 int
   1764 _soc_th3_reg64_set(int unit, soc_block_t block, int acc, uint32 addr, uint64 data)
   1765 {
   1766     schan_msg_t schan_msg;
   1767     int allow_intr = 0;
   1768 
   1769     /*
   1770      * Setup S-Channel command packet
   1771      *
   1772      * NOTE: the datalen field matters only for the Write Memory and
   1773      * Write Register commands, where it is used only by the CMIC to
   1774      * determine how much data to send, and is in units of bytes.
   1775      */
   1776 
   1777     schan_msg_clear(&schan_msg);
   1778 
   1779     soc_schan_header_cmd_set(unit, &schan_msg.header, WRITE_REGISTER_CMD_MSG,
   1780                              block, 0, acc, 8, 0, 0);
   1781 
   1782     schan_msg.writecmd.address = addr;
   1783     schan_msg.writecmd.data[0] = COMPILER_64_LO(data);
   1784     schan_msg.writecmd.data[1] = COMPILER_64_HI(data);
   1785 
   1786 #ifdef BROADCOM_DEBUG
   1787     if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   1788         _soc_reg_extended_debug(unit, 64, "write", block, acc, addr,
   1789                                 schan_msg.writecmd.data[1],
   1790                                 schan_msg.writecmd.data[0]);
   1791     }
   1792 #endif /* BROADCOM_DEBUG */
   1793     _soc_snoop_reg(unit, block, acc, addr,SOC_REG_SNOOP_WRITE, 
   1794                    schan_msg.writecmd.data[1],schan_msg.writecmd.data[0]);
   1795 
   1796     if(SOC_IS_SAND(unit)) {
   1797         allow_intr = 1;
   1798     }
   1799 
   1800     /* Write header word + address + 2*data DWORD */
   1801     /* Note: The hardware does not send WRITE_REGISTER_ACK_MSG. */
   1802     
   1803     
   1804 
   1805     return soc_schan_op(unit, &schan_msg, 4, 0, allow_intr);
   1806     
   1807 
   1808 }
   1809 #endif
   1810 
   1811 /*
   1812  * Write an internal 64-bit SOC register through S-Channel messaging buffer.
   1813  */
   1814 int
   1815 _soc_reg64_set(int unit, soc_block_t block, int acc, uint32 addr, uint64 data)
   1816 {
   1817     schan_msg_t schan_msg;
   1818     int allow_intr = 0, rv = 0;
   1819 #ifdef BCM_TOMAHAWK3_SUPPORT
   1820     uint16 dev_id;
   1821     uint8 rev_id;
   1822     int j;
   1823 
   1824     soc_cm_get_id(unit, &dev_id, &rev_id);
   1825     if ((acc == 9 || acc == 14) && (dev_id == BCM56983_DEVICE_ID)) {
   1826 
   1827         for (j = 0; j< 4; j++) {
   1828             switch(j) {
   1829                case 0 : acc = 0;
   1830                         break;
   1831                case 1 : acc = 1;
   1832                         break;
   1833                case 2 : acc = 6;
   1834                         break;
   1835                case 3 : acc = 7;
   1836                         break;
   1837             }
   1838             rv = _soc_th3_reg64_set(unit, block, acc, addr, data);
   1839             if ( rv < 0 ) {
   1840                 return rv;
   1841             }
   1842         }
   1843 
   1844     } else if (acc == 15 && (dev_id == BCM56983_DEVICE_ID)) {
   1845         for (j = 0; j < 2; j++) {
   1846             switch(j) {
   1847                 case 0 : acc = 0;
   1848                          break;
   1849                 case 1 : acc = 6;
   1850                          break;
   1851             }
   1852             rv = _soc_th3_reg64_set(unit, block, acc, addr, data);
   1853             if ( rv < 0 ) {
   1854                 return rv;
   1855             }
   1856         }
   1857     } else if (acc == 16 && (dev_id == BCM56983_DEVICE_ID)) {
   1858         acc = 0;
   1859         rv = _soc_th3_reg64_set(unit, block, acc, addr, data);
   1860         if ( rv < 0 ) {
   1861             return rv;
   1862         }
   1863     } else
   1864 #endif
   1865     {
   1866         /*
   1867          * Setup S-Channel command packet
   1868          *
   1869          * NOTE: the datalen field matters only for the Write Memory and
   1870          * Write Register commands, where it is used only by the CMIC to
   1871          * determine how much data to send, and is in units of bytes.
   1872          */
   1873     
   1874         schan_msg_clear(&schan_msg);
   1875     
   1876         soc_schan_header_cmd_set(unit, &schan_msg.header, WRITE_REGISTER_CMD_MSG,
   1877                                  block, 0, acc, 8, 0, 0);
   1878     
   1879         schan_msg.writecmd.address = addr;
   1880         schan_msg.writecmd.data[0] = COMPILER_64_LO(data);
   1881         schan_msg.writecmd.data[1] = COMPILER_64_HI(data);
   1882     
   1883 #ifdef BROADCOM_DEBUG
   1884         if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   1885             _soc_reg_extended_debug(unit, 64, "write", block, acc, addr,
   1886                                     schan_msg.writecmd.data[1],
   1887                                     schan_msg.writecmd.data[0]);
   1888         }
   1889 #endif /* BROADCOM_DEBUG */
   1890         _soc_snoop_reg(unit, block, acc, addr,SOC_REG_SNOOP_WRITE, 
   1891                        schan_msg.writecmd.data[1],schan_msg.writecmd.data[0]);
   1892     
   1893         if(SOC_IS_SAND(unit)) {
   1894             allow_intr = 1;
   1895         }
   1896     
   1897         /* Write header word + address + 2*data DWORD */
   1898         /* Note: The hardware does not send WRITE_REGISTER_ACK_MSG. */
   1899         
   1900         
   1901     
   1902         rv =  soc_schan_op(unit, &schan_msg, 4, 0, allow_intr);
   1903     }
   1904     return rv;
   1905 }
   1906 
   1907 void
   1908 soc_reg_watch_set(int unit, int value)
   1909 {
   1910     SOC_CONTROL(unit)->soc_reg_watch = value;
   1911     LOG_CLI((BSL_META("regwatch delta %s\n"),
   1912              value ? "on" : "off"));
   1913 }
   1914 
   1915 #ifdef BCM_BIGMAC_SUPPORT
   1916 
   1917 /*
   1918  * Iterative write procedure for MAC registers on Hyperlite ports.
   1919  */
   1920 STATIC int
   1921 soc_reg64_set_iterative(int unit, soc_block_t block, int acc, uint32 addr,
   1922                         soc_port_t port, uint64 data)
   1923 {
   1924     int rv, i, diff;
   1925     uint64 xgxs_stat;
   1926     uint32 locked;
   1927     sal_usecs_t t1 = 0, t2;
   1928     soc_timeout_t to;
   1929     for (i = 0; i < 100; i++) {
   1930        /* Read PLL lock status */
   1931        soc_timeout_init(&to, 25 * MILLISECOND_USEC, 0);
   1932        do {
   1933            t1 = sal_time_usecs();
   1934            rv = READ_MAC_XGXS_STATr(unit, port, &xgxs_stat);
   1935            locked = soc_reg64_field32_get(unit, MAC_XGXS_STATr, xgxs_stat, 
   1936                                           TXPLL_LOCKf);
   1937            if (locked || SOC_FAILURE(rv)) {
   1938                break;
   1939            }
   1940        } while (!soc_timeout_check(&to));
   1941        if (SOC_FAILURE(rv)) {
   1942            return rv;
   1943        }
   1944        if (!locked) {
   1945            continue;
   1946        }
   1947        /* Write register value */
   1948        SOC_IF_ERROR_RETURN(_soc_reg64_set(unit, block, acc, addr, data));
   1949        /* Read PLL lock status */
   1950        SOC_IF_ERROR_RETURN(READ_MAC_XGXS_STATr(unit, port, &xgxs_stat));
   1951        locked = soc_reg64_field32_get(unit, MAC_XGXS_STATr, xgxs_stat, 
   1952                                       TXPLL_LOCKf);
   1953        t2 = sal_time_usecs();
   1954        diff = SAL_USECS_SUB(t2, t1);
   1955        if (locked && (diff < 20 * MILLISECOND_USEC)) {
   1956            return SOC_E_NONE;
   1957        }
   1958        LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1959                    (BSL_META_U(unit,
   1960                                "soc_reg64_set_iterative: WARNING: "
   1961                                "iteration %d PLL went out of lock"),
   1962                     i));
   1963     }
   1964     LOG_ERROR(BSL_LS_SOC_COMMON,
   1965               (BSL_META_U(unit,
   1966                           "soc_reg64_set_iterative: "
   1967                           "operation failed:\n"))); 
   1968     return SOC_E_FAIL;    
   1969 }
   1970 
   1971 #endif /* BCM_BIGMAC_SUPPORT */
   1972 
   1973 /*
   1974  * Write an internal SOC register through S-Channel messaging buffer.
   1975  * Checks if the register is 32 or 64 bits.
   1976  */
   1977 
   1978 int
   1979 soc_reg_write(int unit, soc_reg_t reg, uint32 addr, uint64 data)
   1980 {
   1981 
   1982     if (!SOC_REG_IS_VALID(unit, reg)) {
   1983         return SOC_E_PARAM;
   1984     }
   1985 
   1986     DNXC_MTA(dnxc_multithread_analyzer_log_resource_use(unit, MTA_RESOURCE_REG, reg, TRUE));
   1987 
   1988     if (SOC_REG_IS_ABOVE_64(unit, reg)) {
   1989         LOG_ERROR(BSL_LS_SOC_COMMON,
   1990                   (BSL_META_U(unit,
   1991                               "soc_reg_write: "
   1992                               "Use soc_reg_above_64_set \n")));
   1993         
   1994         return SOC_E_FAIL;
   1995     }
   1996 
   1997 #ifdef DNX_TEST_CHIPS_SUPPORT
   1998     if (SOC_IS_DNX_TEST_DEVICE(unit)
   1999 #if defined(PLISIM)
   2000         && !SAL_BOOT_PLISIM
   2001 #endif
   2002         ) {
   2003         return soc_dnxtestchip_reg_write(unit, reg, addr, data);
   2004     }
   2005 #endif /* DNX_TEST_CHIPS_SUPPORT */
   2006 
   2007     if (SOC_REG_IS_64(unit, reg)) {
   2008         soc_port_t port;
   2009         soc_block_types_t regblktype = SOC_REG_INFO(unit, reg).block;
   2010         int blk, pindex, bindex, block;
   2011         pindex = (addr >> SOC_REGIDX_BP) & 0x3f;
   2012         block = ((addr >> SOC_BLOCK_BP) & 0xf) |
   2013                 (((addr >> SOC_BLOCK_MSB_BP) & 0x3) << 4);
   2014         if (SOC_BLOCK_IN_LIST(regblktype, SOC_BLK_PORT) 
   2015 #ifdef BCM_SAND_SUPPORT
   2016            && !SOC_IS_SAND(unit)
   2017 #endif /* BCM_SAND_SUPPORT */
   2018 #ifdef BCM_BIGMAC_SUPPORT
   2019            && iterative_op_required(reg)
   2020 #endif /* BCM_BIGMAC_SUPPORT */
   2021             ) {
   2022             PBMP_HYPLITE_ITER(unit, port) {
   2023                 blk = SOC_PORT_BLOCK(unit, port);
   2024                 bindex = SOC_PORT_BINDEX(unit, port);
   2025                 if ((SOC_BLOCK2SCH(unit, blk) == block) && (bindex == pindex)) {
   2026                     break;
   2027                 }
   2028             }         
   2029             if (!IS_HYPLITE_PORT(unit, port)) {
   2030                 return soc_reg64_write(unit, addr, data);
   2031             } 
   2032 #ifdef BCM_BIGMAC_SUPPORT
   2033             else {   
   2034                 return soc_reg64_write_iterative(unit, addr, port, data);
   2035             }
   2036 #endif /* BCM_BIGMAC_SUPPORT */           
   2037         } else {
   2038             return soc_reg64_write(unit, addr, data);
   2039         }
   2040     } else {
   2041         if (COMPILER_64_HI(data)) {
   2042             LOG_WARN(BSL_LS_SOC_COMMON,
   2043                      (BSL_META_U(unit,
   2044                                  "soc_reg_write: WARNING: "
   2045                                  "write to 32-bit reg %s with hi order data, 0x%x\n"),
   2046                       SOC_REG_NAME(unit, reg),
   2047                       COMPILER_64_HI(data)));
   2048         }
   2049         SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr,
   2050                                             COMPILER_64_LO(data)));
   2051     }
   2052 
   2053     return SOC_E_NONE;
   2054 }
   2055 
   2056 /*
   2057  * Write an internal SOC register through S-Channel messaging buffer.
   2058  */
   2059 int
   2060 _soc_reg32_set(int unit, soc_block_t block, int acc, uint32 addr, uint32 data)
   2061 {
   2062     schan_msg_t schan_msg;
   2063     int allow_intr=0;
   2064 
   2065     /*
   2066      * Setup S-Channel command packet
   2067      *
   2068      * NOTE: the datalen field matters only for the Write Memory and
   2069      * Write Register commands, where it is used only by the CMIC to
   2070      * determine how much data to send, and is in units of bytes.
   2071      */
   2072 
   2073     schan_msg_clear(&schan_msg);
   2074 
   2075     soc_schan_header_cmd_set(unit, &schan_msg.header, WRITE_REGISTER_CMD_MSG,
   2076                              block, 0, acc, 4, 0, 0);
   2077 
   2078     schan_msg.writecmd.address = addr;
   2079     schan_msg.writecmd.data[0] = data;
   2080 
   2081 #ifdef BROADCOM_DEBUG
   2082     if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   2083         _soc_reg_extended_debug(unit, 32, "write", block, acc, addr, 0, data);
   2084     }
   2085 #endif /* BROADCOM_DEBUG */
   2086     _soc_snoop_reg(unit, block, acc, addr,SOC_REG_SNOOP_WRITE, 0,data);
   2087 
   2088     if(SOC_IS_SAND(unit)) {
   2089         allow_intr = 1;
   2090     }
   2091 
   2092     /* Write header word + address + data DWORD */
   2093     /* Note: The hardware does not send WRITE_REGISTER_ACK_MSG. */
   2094     
   2095     
   2096 
   2097     return soc_schan_op(unit, &schan_msg, 3, 0, allow_intr);
   2098 }
   2099 
   2100 /*
   2101  * Write an internal SOC register through S-Channel messaging buffer.
   2102  * Checks if the register is 32 or 64 bits.
   2103  */
   2104 
   2105 int
   2106 soc_reg_set(int unit, soc_reg_t reg, int port, int index, uint64 data)
   2107 {
   2108     uint32 addr;
   2109     int block;
   2110     soc_reg_access_info_t access_info;
   2111     int rv;
   2112     int pindex = port;
   2113     if (!SOC_REG_IS_VALID(unit, reg)) {
   2114         return SOC_E_PARAM;
   2115     }
   2116 
   2117     DNXC_MTA(dnxc_multithread_analyzer_log_resource_use(unit, MTA_RESOURCE_REG, reg, TRUE));
   2118 
   2119     if (SOC_REG_IS_ABOVE_64(unit, reg)) {
   2120         LOG_ERROR(BSL_LS_SOC_COMMON,
   2121                   (BSL_META_U(unit,
   2122                               "soc_reg_set: "
   2123                               "Use soc_reg_above_64_set \n")));
   2124         
   2125         return SOC_E_FAIL;
   2126     }
   2127 
   2128     /* if reloading, don't write to register */
   2129     if (SOC_IS_RELOADING(unit))
   2130     {
   2131         return SOC_E_NONE;
   2132     }
   2133 
   2134 #ifdef CRASH_RECOVERY_SUPPORT
   2135 
   2136     /*     Use crash recovery defined callback for access*/
   2137     if (SOC_IS_DONE_INIT(unit))
   2138     {
   2139         if (BCM_UNIT_DO_HW_READ_WRITE(unit))
   2140         {
   2141             if(Hw_Log_List[unit].Access_cb.soc_reg_set)
   2142             {
   2143                 return Hw_Log_List[unit].Access_cb.soc_reg_set(unit, reg, port, index, data);
   2144             }
   2145         }
   2146     }
   2147 
   2148 #endif /* CRASH_RECOVERY_SUPPORT */    
   2149 
   2150     /* Use user defined callback for access */
   2151     if(SOC_INFO(unit).reg_access.reg64_set) {
   2152         return SOC_INFO(unit).reg_access.reg64_set(unit, reg, port, index, data);
   2153     }
   2154 
   2155 #ifdef CANCUN_SUPPORT
   2156     if (SOC_REG_IS_CCH(unit, reg) && !(soc_property_get(unit,
   2157                               "skip_cancun_cch_reg_check", 0) ? TRUE : FALSE)) {
   2158         soc_cancun_cch_reg_set(unit, reg, index, data);
   2159 
   2160         if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CCH)) {
   2161             return(soc_cancun_pseudo_reg_set(unit, reg, data));
   2162         }
   2163     }
   2164 #endif
   2165 
   2166 #ifdef DNX_TEST_CHIPS_SUPPORT
   2167     if (SOC_IS_DNX_TEST_DEVICE(unit)
   2168 #if defined(PLISIM)
   2169         && !SAL_BOOT_PLISIM
   2170 #endif
   2171         ) {
   2172         return soc_dnxtestchip_reg_set(unit, reg, port, data);
   2173     }
   2174 #endif /* DNX_TEST_CHIPS_SUPPORT */
   2175     rv = soc_reg_xaddr_get(unit, reg, port, index,
   2176       SOC_REG_ADDR_OPTION_WRITE, &access_info);
   2177     if (rv != SOC_E_NONE) {
   2178         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   2179           "soc_reg_set: failed to get register address")));
   2180         return rv;
   2181     }
   2182     addr = access_info.offset;
   2183     block = access_info.blk_list[0];
   2184     if (SOC_REG_IS_64(unit, reg)) {
   2185         soc_port_t _port;
   2186         soc_block_types_t regblktype = SOC_REG_INFO(unit, reg).block;
   2187         int blk, bindex;
   2188 
   2189 #if defined(BCM_XGS_SUPPORT)
   2190         if (soc_feature(unit, soc_feature_regs_as_mem)) {
   2191             (void)soc_ser_reg_cache_set(unit, reg, port, index, data);
   2192         }
   2193 #endif /* BCM_XGS_SUPPORT */
   2194         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   2195            return soc_reg_write(unit, reg, addr, data);
   2196         }
   2197         if (SOC_BLOCK_IN_LIST(regblktype, SOC_BLK_PORT) 
   2198 #ifdef BCM_SAND_SUPPORT
   2199            && !SOC_IS_SAND(unit)
   2200 #endif /* BCM_SAND_SUPPORT */
   2201 #ifdef BCM_BIGMAC_SUPPORT
   2202            && iterative_op_required(reg)
   2203 #endif /* BCM_BIGMAC_SUPPORT */
   2204             ) {
   2205             PBMP_HYPLITE_ITER(unit, _port) {
   2206                 blk = SOC_PORT_BLOCK(unit, _port);
   2207                 bindex = SOC_PORT_BINDEX(unit, _port);
   2208                 if ((SOC_BLOCK2SCH(unit, blk) == block) && (bindex == pindex)) {
   2209                     break;
   2210                 }
   2211             }         
   2212             if (!IS_HYPLITE_PORT(unit, port)) {
   2213                 return _soc_reg64_set(unit, block, access_info.acc_type, addr, data);
   2214             } 
   2215 #ifdef BCM_BIGMAC_SUPPORT
   2216             else {   
   2217                 return soc_reg64_set_iterative(unit, block, access_info.acc_type, addr,
   2218                                                port, data);
   2219             }
   2220 #endif /* BCM_BIGMAC_SUPPORT */           
   2221         } else {
   2222             for (block = 0; block < access_info.num_blks && rv == SOC_E_NONE; ++block) {
   2223                 rv = _soc_reg64_set(unit, access_info.blk_list[block], access_info.acc_type, addr, data);
   2224             }
   2225         }
   2226     } else {
   2227         uint32 data32;
   2228         if (COMPILER_64_HI(data)) {
   2229             LOG_WARN(BSL_LS_SOC_COMMON,
   2230                      (BSL_META_U(unit,
   2231                                  "soc_reg_set: WARNING: "
   2232                                  "write to 32-bit reg %s with hi order data, 0x%x\n"),
   2233                       SOC_REG_NAME(unit, reg),
   2234                       COMPILER_64_HI(data)));
   2235         }
   2236         data32 = COMPILER_64_LO(data);
   2237 #if defined(BCM_XGS_SUPPORT)
   2238         if (soc_feature(unit, soc_feature_regs_as_mem)) {
   2239             (void)soc_ser_reg32_cache_set(unit, reg, port, index, data32);
   2240         }
   2241 #endif /* BCM_XGS_SUPPORT */
   2242         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   2243             return soc_reg32_write(unit, addr, data32);
   2244         }
   2245         for (block = 0; block < access_info.num_blks && rv == SOC_E_NONE; ++block) {
   2246             rv = _soc_reg32_set(unit, access_info.blk_list[block], access_info.acc_type, addr, data32);
   2247         }
   2248     }
   2249 
   2250     if (rv != SOC_E_NONE) {
   2251         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   2252           "soc_reg_set failed for %s\n"), SOC_REG_NAME(unit, reg)));
   2253     }
   2254     return rv;
   2255 }
   2256 
   2257 /* Write to h/w - do not update reg cache */
   2258 int
   2259 soc_reg_set_nocache(int unit, soc_reg_t reg, int port, int index, uint64 data)
   2260 {
   2261     uint32 addr;
   2262     int block, rv;
   2263     int pindex = port;
   2264     soc_reg_access_info_t access_info;
   2265     if (!SOC_REG_IS_VALID(unit, reg)) {
   2266         return SOC_E_PARAM;
   2267     }
   2268 
   2269     DNXC_MTA(dnxc_multithread_analyzer_log_resource_use(unit, MTA_RESOURCE_REG, reg, TRUE));
   2270 
   2271     if (SOC_REG_IS_ABOVE_64(unit, reg)) {
   2272         LOG_ERROR(BSL_LS_SOC_COMMON,
   2273                   (BSL_META_U(unit,
   2274                               "soc_reg_set: "
   2275                               "Use soc_reg_above_64_set \n")));
   2276         
   2277         return SOC_E_FAIL;
   2278     }
   2279 
   2280     /* if reloading, don't write to register */
   2281     if (SOC_IS_RELOADING(unit))
   2282     {
   2283         return SOC_E_NONE;
   2284     }
   2285     
   2286 #ifdef CRASH_RECOVERY_SUPPORT
   2287 /*     Use crash recovery defined callback for access*/
   2288     if (SOC_IS_DONE_INIT(unit))
   2289     {
   2290         if (BCM_UNIT_DO_HW_READ_WRITE(unit))
   2291         {
   2292             if(Hw_Log_List[unit].Access_cb.soc_reg_set_nocache)
   2293             {
   2294                 return Hw_Log_List[unit].Access_cb.soc_reg_set_nocache(unit, reg, port, index, data);
   2295             }
   2296         }
   2297     }
   2298 #endif /* CRASH_RECOVERY_SUPPORT */
   2299     
   2300 #ifdef CANCUN_SUPPORT
   2301     if (SOC_REG_IS_CCH(unit, reg) && !(soc_property_get(unit,
   2302                               "skip_cancun_cch_reg_check", 0) ? TRUE : FALSE)) {
   2303         SOC_IF_ERROR_RETURN(soc_cancun_cch_reg_set(unit, reg, index, data));
   2304 
   2305         if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CCH)) {
   2306             return(soc_cancun_pseudo_reg_set(unit, reg, data));
   2307         }
   2308     }
   2309 #endif
   2310 
   2311     rv = soc_reg_xaddr_get(unit, reg, port, index,
   2312       SOC_REG_ADDR_OPTION_WRITE, &access_info);
   2313     if (rv != SOC_E_NONE) {
   2314         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   2315           "soc_reg_set_nocache: failed to get register address")));
   2316         return rv;
   2317     }
   2318     addr = access_info.offset;
   2319     block = access_info.blk_list[0];
   2320 
   2321     if (SOC_REG_IS_64(unit, reg)) {
   2322         soc_port_t _port;
   2323         soc_block_types_t regblktype = SOC_REG_INFO(unit, reg).block;
   2324         int blk, bindex;
   2325 
   2326         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   2327            return soc_reg_write(unit, reg, addr, data);
   2328         }
   2329         if (SOC_BLOCK_IN_LIST(regblktype, SOC_BLK_PORT) 
   2330 #ifdef BCM_SAND_SUPPORT
   2331            && !SOC_IS_SAND(unit)
   2332 #endif /* BCM_SAND_SUPPORT */
   2333 #ifdef BCM_BIGMAC_SUPPORT
   2334            && iterative_op_required(reg)
   2335 #endif /* BCM_BIGMAC_SUPPORT */
   2336             ) {
   2337             PBMP_HYPLITE_ITER(unit, _port) {
   2338                 blk = SOC_PORT_BLOCK(unit, _port);
   2339                 bindex = SOC_PORT_BINDEX(unit, _port);
   2340                 if ((SOC_BLOCK2SCH(unit, blk) == block) && (bindex == pindex)) {
   2341                     break;
   2342                 }
   2343             }         
   2344             if (!IS_HYPLITE_PORT(unit, port)) {
   2345                 return _soc_reg64_set(unit, block, access_info.acc_type, addr, data);
   2346             } 
   2347 #ifdef BCM_BIGMAC_SUPPORT
   2348             else {   
   2349                 return soc_reg64_set_iterative(unit, block, access_info.acc_type, addr,
   2350                                                port, data);
   2351             }
   2352 #endif /* BCM_BIGMAC_SUPPORT */           
   2353         } else {
   2354             for (block = 0; block < access_info.num_blks && rv == SOC_E_NONE; ++block) {
   2355                 rv = _soc_reg64_set(unit, access_info.blk_list[block], access_info.acc_type, addr, data);
   2356             }
   2357         }
   2358     } else {
   2359         uint32 data32;
   2360         if (COMPILER_64_HI(data)) {
   2361             LOG_WARN(BSL_LS_SOC_COMMON,
   2362                      (BSL_META_U(unit,
   2363                                  "soc_reg_set: WARNING: "
   2364                                  "write to 32-bit reg %s with hi order data, 0x%x\n"),
   2365                       SOC_REG_NAME(unit, reg),
   2366                       COMPILER_64_HI(data)));
   2367         }
   2368         data32 = COMPILER_64_LO(data);
   2369         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   2370             return soc_reg32_write(unit, addr, data32);
   2371         }
   2372         for (block = 0; block < access_info.num_blks && rv == SOC_E_NONE; ++block) {
   2373             rv = _soc_reg32_set(unit, access_info.blk_list[block], access_info.acc_type, addr, data32);
   2374         }
   2375     }
   2376 
   2377     return rv;
   2378 }
   2379 
   2380 /*
   2381  * Write an internal SOC register through S-Channel messaging buffer.
   2382  * Handle register at any size 
   2383  */
   2384 
   2385 int
   2386 soc_reg_above_64_set(int unit, soc_reg_t reg, int port, int index, soc_reg_above_64_val_t data)
   2387 {
   2388     uint32 addr;
   2389     int i, rv, reg_size;
   2390     uint64 data64;
   2391     soc_reg_access_info_t access_info;
   2392 
   2393     /* if reloading, don't write to register */
   2394     if (SOC_IS_RELOADING(unit))
   2395     {
   2396         return SOC_E_NONE;
   2397     }    
   2398     
   2399     if (!SOC_REG_IS_VALID(unit, reg)) {
   2400         return SOC_E_PARAM;
   2401     }
   2402                       
   2403     /*     Use crash recovery defined callback for access*/
   2404 #ifdef CRASH_RECOVERY_SUPPORT
   2405 
   2406     if (SOC_IS_DONE_INIT(unit))
   2407     {
   2408         if (BCM_UNIT_DO_HW_READ_WRITE(unit))
   2409         {
   2410             if(Hw_Log_List[unit].Access_cb.reg_above64_set)
   2411             {
   2412                 return Hw_Log_List[unit].Access_cb.reg_above64_set(unit, reg, port, index, data);
   2413             }
   2414         }
   2415     }
   2416 
   2417 #endif /* CRASH_RECOVERY_SUPPORT */
   2418 
   2419     /* Use user defined callback for access */
   2420     if(SOC_INFO(unit).reg_access.reg_above64_set) {
   2421         return SOC_INFO(unit).reg_access.reg_above64_set(unit, reg, port, index, data);
   2422     }
   2423 
   2424 #ifdef DNX_TEST_CHIPS_SUPPORT
   2425     if (SOC_IS_DNX_TEST_DEVICE(unit)
   2426 #if defined(PLISIM)
   2427         && !SAL_BOOT_PLISIM
   2428 #endif
   2429         ) {
   2430         return soc_dnxtestchip_reg_above_64_set(unit, reg, port, data);
   2431     }
   2432 #endif /* DNX_TEST_CHIPS_SUPPORT */
   2433     
   2434     if (SOC_REG_IS_ABOVE_64(unit, reg)) 
   2435     {
   2436         reg_size = SOC_REG_ABOVE_64_INFO(unit, reg).size;
   2437         rv = soc_reg_xaddr_get(unit, reg, port, index,
   2438           SOC_REG_ADDR_OPTION_WRITE, &access_info);
   2439         if (rv != SOC_E_NONE) {
   2440             LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   2441               "soc_reg64_set: failed to get register address")));
   2442             return rv;
   2443         }
   2444         addr = access_info.offset;
   2445         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   2446             access_info.blk_list[0] = ((addr >> SOC_BLOCK_BP) & 0xf) | (((addr >> SOC_BLOCK_MSB_BP) & 0x3) << 4);
   2447             access_info.num_blks = 1;
   2448         }
   2449 
   2450         for (i = 0; i < access_info.num_blks && rv == SOC_E_NONE; ++i) {
   2451 #ifdef BROADCOM_DEBUG
   2452         if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   2453                 _soc_reg_above_64_debug(unit, "set", access_info.blk_list[i], addr, data);
   2454         }
   2455 #endif /* BROADCOM_DEBUG */
   2456 
   2457             rv = soc_direct_reg_set(unit, access_info.blk_list[i], addr, reg_size, data);
   2458         }
   2459         if (rv != SOC_E_NONE) {
   2460             LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   2461               "soc_reg_above_64_set failed for %s\n"), SOC_REG_NAME(unit, reg)));
   2462         }
   2463         return rv;
   2464     } 
   2465     else if (SOC_REG_IS_64(unit, reg)) {
   2466         COMPILER_64_SET(data64, data[1], data[0]);
   2467         return soc_reg_set(unit, reg, port, index, data64);
   2468     } 
   2469     else {
   2470         COMPILER_64_SET(data64, 0, data[0]);
   2471         return soc_reg_set(unit, reg, port, index, data64);
   2472     }
   2473 }
   2474 
   2475 /*
   2476  * Write an internal SOC register through S-Channel messaging buffer.
   2477  */
   2478 
   2479 int
   2480 soc_reg32_write(int unit,
   2481                 uint32 addr,
   2482                 uint32 data)
   2483 {
   2484     schan_msg_t schan_msg;
   2485     int allow_intr=0;
   2486     int dst_blk, src_blk, data_byte_len;
   2487 #ifdef BCM_CMICM_SUPPORT
   2488     int cmc = SOC_PCI_CMC(unit);
   2489 #endif
   2490 
   2491 #ifdef BROADCOM_DEBUG
   2492     if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   2493         _soc_reg_debug(unit, 32, "write", addr, 0, data);
   2494     }
   2495 #endif /* BROADCOM_DEBUG */
   2496     _soc_snoop_reg(unit, 0, 0, addr,SOC_REG_SNOOP_WRITE, 0, data);
   2497 
   2498 #ifdef DNX_TEST_CHIPS_SUPPORT
   2499     if (SOC_IS_DNX_TEST_DEVICE(unit)
   2500 #if defined(PLISIM)
   2501         && !SAL_BOOT_PLISIM
   2502 #endif
   2503         ) {
   2504         return soc_dnxtestchip_reg32_write(unit, addr, data);
   2505     }
   2506 #endif /* DNX_TEST_CHIPS_SUPPORT */
   2507 
   2508 #ifdef BCM_CMICM_SUPPORT
   2509     if(soc_feature(unit, soc_feature_cmicm) &&
   2510         (NULL != SOC_CONTROL(unit)->fschanMutex)) {
   2511         FSCHAN_LOCK(unit);
   2512         soc_pci_write(unit, CMIC_CMCx_FSCHAN_ADDRESS_OFFSET(cmc), addr);
   2513         soc_pci_write(unit, CMIC_CMCx_FSCHAN_DATA32_OFFSET(cmc), data);
   2514         fschan_wait_idle(unit);
   2515         FSCHAN_UNLOCK(unit);
   2516         return SOC_E_NONE;
   2517     }
   2518 #endif /* CMICM */
   2519     /*
   2520      * Setup S-Channel command packet
   2521      *
   2522      * NOTE: the datalen field matters only for the Write Memory and
   2523      * Write Register commands, where it is used only by the CMIC to
   2524      * determine how much data to send, and is in units of bytes.
   2525      */
   2526 
   2527     schan_msg_clear(&schan_msg);
   2528 
   2529     dst_blk = ((addr >> SOC_BLOCK_BP) & 0xf) | 
   2530         (((addr >> SOC_BLOCK_MSB_BP) & 0x3) << 4);
   2531     data_byte_len = SOC_IS_XGS12_FABRIC(unit) ? 8 : 4;
   2532     {
   2533         src_blk = SOC_IS_SHADOW(unit) ?
   2534             0 : SOC_BLOCK2SCH(unit, CMIC_BLOCK(unit));
   2535     }
   2536     soc_schan_header_cmd_set(unit, &schan_msg.header, WRITE_REGISTER_CMD_MSG,
   2537                              dst_blk, src_blk, 0, data_byte_len, 0, 0);
   2538 
   2539     schan_msg.writecmd.address = addr;
   2540     schan_msg.writecmd.data[0] = data;
   2541 
   2542     if(SOC_IS_SAND(unit)) {
   2543         allow_intr = 1;
   2544     }
   2545 
   2546     /* Write header word + address + data DWORD */
   2547     /* Note: The hardware does not send WRITE_REGISTER_ACK_MSG. */
   2548     
   2549     
   2550 
   2551     return soc_schan_op(unit, &schan_msg, 3, 0, allow_intr);
   2552 
   2553 }
   2554 
   2555 /*
   2556  * Write an internal SOC register through S-Channel messaging buffer.
   2557  */
   2558 
   2559 int
   2560 soc_reg32_set(int unit, soc_reg_t reg, int port, int index, uint32 data)
   2561 {
   2562     uint32 addr;
   2563     int i, rv = 0;
   2564     soc_reg_access_info_t access_info;
   2565 #ifdef BCM_TOMAHAWK3_SUPPORT
   2566     int j=0, acc=0;
   2567     uint16 dev_id;
   2568     uint8 rev_id;
   2569 #endif
   2570     /* if reloading, don't write to register */
   2571     if (SOC_IS_RELOADING(unit))
   2572     {
   2573         return SOC_E_NONE;
   2574     }
   2575 #ifdef BCM_TOMAHAWK3_SUPPORT
   2576     soc_cm_get_id (unit, &dev_id, &rev_id);
   2577 #endif
   2578 
   2579     DNXC_MTA(dnxc_multithread_analyzer_log_resource_use(unit, MTA_RESOURCE_REG, reg, TRUE));
   2580 
   2581 #ifdef CRASH_RECOVERY_SUPPORT
   2582     /*     Use crash recovery defined callback for access*/
   2583 
   2584     if (SOC_IS_DONE_INIT(unit))
   2585     {
   2586         if (BCM_UNIT_DO_HW_READ_WRITE(unit))
   2587         {
   2588             if(Hw_Log_List[unit].Access_cb.reg32_set)
   2589             {
   2590                 return Hw_Log_List[unit].Access_cb.reg32_set(unit, reg, port, index, data);
   2591             }
   2592         }
   2593     }
   2594 #endif /* CRASH_RECOVERY_SUPPORT */
   2595 
   2596 
   2597     /* Use user defined callback for access */
   2598     if(SOC_INFO(unit).reg_access.reg32_set) {
   2599         return SOC_INFO(unit).reg_access.reg32_set(unit, reg, port, index, data);
   2600     }
   2601 
   2602 #ifdef CANCUN_SUPPORT
   2603     if (SOC_REG_IS_CCH(unit, reg) && !(soc_property_get(unit,
   2604                               "skip_cancun_cch_reg_check", 0) ? TRUE : FALSE)) {
   2605         uint64 data64;
   2606         COMPILER_64_SET(data64, 0, data);
   2607         SOC_IF_ERROR_RETURN(
   2608                 soc_cancun_cch_reg_set(unit, reg, index, data64));
   2609 
   2610         if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CCH)) {
   2611             return(soc_cancun_pseudo_reg_set(unit, reg, data64));
   2612         }
   2613     }
   2614 #endif
   2615 
   2616 #ifdef DNX_TEST_CHIPS_SUPPORT
   2617     if (SOC_IS_DNX_TEST_DEVICE(unit)
   2618 #if defined(PLISIM)
   2619         && !SAL_BOOT_PLISIM
   2620 #endif
   2621         ) {
   2622         return soc_dnxtestchip_reg32_set(unit, reg, port, data);
   2623     }
   2624 #endif /* DNX_TEST_CHIPS_SUPPORT */
   2625 
   2626     rv = soc_reg_xaddr_get(unit, reg, port, index,
   2627       SOC_REG_ADDR_OPTION_WRITE, &access_info);
   2628     if (rv != SOC_E_NONE) {
   2629         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   2630           "soc_reg32_set: failed to get register address")));
   2631         return rv;
   2632     }
   2633     addr = access_info.offset;
   2634     if (SOC_REG_IS_ABOVE_32(unit, reg)) {
   2635 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT)
   2636 #if !defined(SOC_NO_NAMES)
   2637         LOG_CLI((BSL_META_U(unit,
   2638                             "reg %s is not 32 bit\n"), soc_reg_name[reg]));
   2639 #endif
   2640 #endif
   2641 
   2642     }
   2643     assert(!SOC_REG_IS_ABOVE_32(unit, reg));
   2644 #if defined(BCM_XGS_SUPPORT)
   2645     if (soc_feature(unit, soc_feature_regs_as_mem)) {
   2646         (void)soc_ser_reg32_cache_set(unit, reg, port, index, data);
   2647     }
   2648 #endif /* BCM_XGS_SUPPORT */
   2649     if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   2650         return soc_reg32_write(unit, addr, data);
   2651     }
   2652 
   2653     for (i = 0; i < access_info.num_blks && rv == SOC_E_NONE; ++i) {
   2654 #ifdef BCM_TOMAHAWK3_SUPPORT
   2655         /* For 56983 Lower die SKU, we make sure DATA_SPLIT and DUPL writes get
   2656            converted into 4 unique writes since the OTP settings are not
   2657            available
   2658         */
   2659         if ((access_info.acc_type == 9 || access_info.acc_type == 14)  &&
   2660                             (dev_id == BCM56983_DEVICE_ID)) {
   2661            for (j = 0; j < 4; j++) {
   2662                switch(j) {
   2663                case 0 : acc = 0;
   2664                         break;
   2665                case 1 : acc = 1;
   2666                         break;
   2667                case 2 : acc = 6;
   2668                         break;
   2669                case 3 : acc = 7;
   2670                         break;
   2671                }
   2672                rv = _soc_reg32_set(unit, access_info.blk_list[i], acc, addr, data);
   2673            }
   2674         } else if (access_info.acc_type == 16  && (dev_id == BCM56983_DEVICE_ID)) {
   2675             acc = 0;
   2676             rv = _soc_reg32_set(unit, access_info.blk_list[i], acc, addr, data);
   2677         } else if (access_info.acc_type == 15  && (dev_id == BCM56983_DEVICE_ID)) {
   2678             for (j = 0; j < 2; j++) {
   2679                 switch(j) {
   2680                 case 0 : acc = 0;
   2681                          break;
   2682                 case 1 : acc = 6;
   2683                          break;
   2684                 }
   2685                 rv = _soc_reg32_set(unit, access_info.blk_list[i], acc, addr, data);
   2686             }
   2687         } else
   2688 #endif
   2689         {
   2690            rv = _soc_reg32_set(unit, access_info.blk_list[i], access_info.acc_type, addr, data);
   2691         }
   2692         if (rv != SOC_E_NONE) {
   2693             LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   2694                 "soc_reg32_set failed for %s failed\n"), SOC_REG_NAME(unit, reg)));
   2695         }
   2696     }
   2697     return rv;
   2698 }
   2699 
   2700 /*
   2701  * Write an internal 64-bit SOC register through S-Channel messaging buffer.
   2702  */
   2703 int
   2704 soc_reg64_write(int unit,
   2705                 uint32 addr,
   2706                 uint64 data)
   2707 {
   2708     schan_msg_t schan_msg;
   2709     int allow_intr=0;
   2710     int dst_blk, src_blk;
   2711 #ifdef BCM_CMICM_SUPPORT
   2712     int cmc = SOC_PCI_CMC(unit);
   2713 #endif
   2714 
   2715 #ifdef DNX_TEST_CHIPS_SUPPORT
   2716     if (SOC_IS_DNX_TEST_DEVICE(unit)
   2717 #if defined(PLISIM)
   2718         && !SAL_BOOT_PLISIM
   2719 #endif
   2720         ) {
   2721         return soc_dnxtestchip_reg64_write(unit, addr, data);
   2722     }
   2723 #endif /* DNX_TEST_CHIPS_SUPPORT */
   2724 
   2725 #ifdef BCM_CMICM_SUPPORT
   2726     if(soc_feature(unit, soc_feature_cmicm) &&
   2727         (NULL != SOC_CONTROL(unit)->fschanMutex)) {
   2728         FSCHAN_LOCK(unit);
   2729         soc_pci_write(unit, CMIC_CMCx_FSCHAN_ADDRESS_OFFSET(cmc), addr);
   2730         /* coverity[result_independent_of_operands] */
   2731        SOC_IF_ERROR_RETURN(soc_pci_write(unit, 
   2732                                           CMIC_CMCx_FSCHAN_DATA64_HI_OFFSET(cmc), 
   2733                                           COMPILER_64_HI(data)));
   2734         SOC_IF_ERROR_RETURN(soc_pci_write(unit, 
   2735                                           CMIC_CMCx_FSCHAN_DATA64_LO_OFFSET(cmc), 
   2736                                           COMPILER_64_LO(data)));
   2737 
   2738         fschan_wait_idle(unit);
   2739         FSCHAN_UNLOCK(unit);
   2740         return SOC_E_NONE;
   2741     }
   2742 #endif /* CMICM */
   2743     /*
   2744      * Setup S-Channel command packet
   2745      *
   2746      * NOTE: the datalen field matters only for the Write Memory and
   2747      * Write Register commands, where it is used only by the CMIC to
   2748      * determine how much data to send, and is in units of bytes.
   2749      */
   2750 
   2751     schan_msg_clear(&schan_msg);
   2752 
   2753     dst_blk = ((addr >> SOC_BLOCK_BP) & 0xf) | 
   2754         (((addr >> SOC_BLOCK_MSB_BP) & 0x3) << 4);
   2755     {
   2756         src_blk = SOC_IS_SHADOW(unit) ?
   2757             0 : SOC_BLOCK2SCH(unit, CMIC_BLOCK(unit));
   2758     }
   2759     soc_schan_header_cmd_set(unit, &schan_msg.header, WRITE_REGISTER_CMD_MSG,
   2760                              dst_blk, src_blk, 0, 8, 0, 0);
   2761 
   2762     schan_msg.writecmd.address = addr;
   2763     schan_msg.writecmd.data[0] = COMPILER_64_LO(data);
   2764     schan_msg.writecmd.data[1] = COMPILER_64_HI(data);
   2765 
   2766 #ifdef BROADCOM_DEBUG
   2767     if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   2768         _soc_reg_debug(unit, 64, "write", addr,
   2769                        schan_msg.writecmd.data[1],
   2770                        schan_msg.writecmd.data[0]);
   2771     }
   2772 #endif /* BROADCOM_DEBUG */
   2773     _soc_snoop_reg(unit, 0, 0, addr,SOC_REG_SNOOP_WRITE, 
   2774                    schan_msg.writecmd.data[1],schan_msg.writecmd.data[0]);
   2775 
   2776     if(SOC_IS_SAND(unit)) {
   2777         allow_intr = 1;
   2778     }
   2779 
   2780     /* Write header word + address + 2*data DWORD */
   2781     /* Note: The hardware does not send WRITE_REGISTER_ACK_MSG. */
   2782     
   2783     
   2784 
   2785     return soc_schan_op(unit, &schan_msg, 4, 0, allow_intr);
   2786 
   2787 }
   2788 
   2789 /*
   2790  * Write an internal 64-bit SOC register through S-Channel messaging buffer.
   2791  */
   2792 int
   2793 soc_reg64_set(int unit, soc_reg_t reg, int port, int index, uint64 data)
   2794 {
   2795     uint32 addr;
   2796     int i, rv;
   2797     soc_reg_access_info_t access_info;
   2798 #ifdef CRASH_RECOVERY_SUPPORT
   2799 
   2800     /*     Use crash recovery defined callback for access*/
   2801     if (SOC_IS_DONE_INIT(unit))
   2802     {
   2803         if (BCM_UNIT_DO_HW_READ_WRITE(unit))
   2804         {
   2805             if(Hw_Log_List[unit].Access_cb.reg64_set)
   2806             {
   2807                 return Hw_Log_List[unit].Access_cb.reg64_set(unit, reg, port, index, data);
   2808             }
   2809         }
   2810     }
   2811 
   2812 #endif /* CRASH_RECOVERY_SUPPORT */
   2813 
   2814     DNXC_MTA(dnxc_multithread_analyzer_log_resource_use(unit, MTA_RESOURCE_REG, reg, TRUE));
   2815 
   2816 #ifdef CANCUN_SUPPORT
   2817     if (SOC_REG_IS_CCH(unit, reg) && !(soc_property_get(unit,
   2818                               "skip_cancun_cch_reg_check", 0) ? TRUE : FALSE)) {
   2819         soc_cancun_cch_reg_set(unit, reg, index, data);
   2820 
   2821         if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CCH)) {
   2822             return(soc_cancun_pseudo_reg_set(unit, reg, data));
   2823         }
   2824     }
   2825 #endif
   2826     
   2827     /* Use user defined callback for access */
   2828     if(SOC_INFO(unit).reg_access.reg64_set) {
   2829         return SOC_INFO(unit).reg_access.reg64_set(unit, reg, port, index, data);
   2830     }
   2831 
   2832     rv = soc_reg_xaddr_get(unit, reg, port, index,
   2833       SOC_REG_ADDR_OPTION_WRITE, &access_info);
   2834     if (rv != SOC_E_NONE) {
   2835         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   2836           "soc_reg64_set: failed to get register address")));
   2837         return rv;
   2838     }
   2839     addr = access_info.offset;
   2840     assert(SOC_REG_IS_64(unit, reg));
   2841 #if defined(BCM_XGS_SUPPORT)
   2842     if (soc_feature(unit, soc_feature_regs_as_mem)) {
   2843         (void)soc_ser_reg_cache_set(unit, reg, port, index, data);
   2844     }
   2845 #endif /* BCM_XGS_SUPPORT */
   2846     if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   2847         return soc_reg64_write(unit, addr, data);
   2848     }
   2849     for (i = 0; i < access_info.num_blks && rv == SOC_E_NONE; ++i) {
   2850         rv = _soc_reg64_set(unit, access_info.blk_list[i], access_info.acc_type, addr, data);
   2851     }
   2852     return rv;
   2853 }
   2854 
   2855 /*
   2856  * Write an internal SOC register through S-Channel messaging buffer
   2857  * with Raw Port Number.
   2858  */
   2859 int
   2860 soc_reg_rawport_set(int unit, soc_reg_t reg, int port, int index, uint64 data)
   2861 {
   2862     uint32 addr;
   2863     int i, rv;
   2864     soc_reg_access_info_t access_info;
   2865 
   2866     if (!SOC_REG_IS_VALID(unit, reg)) {
   2867         return SOC_E_PARAM;
   2868     }
   2869 
   2870     if ((REG_PORT_ANY != port) &&
   2871         (port & (SOC_REG_ADDR_INSTANCE_MASK | SOC_REG_ADDR_BLOCK_ID_MASK | 
   2872                 SOC_REG_ADDR_SCHAN_ID_MASK | SOC_REG_ADDR_PHY_ACC_MASK))) {
   2873         LOG_ERROR(BSL_LS_SOC_COMMON,
   2874                   (BSL_META_U(unit,
   2875                               "This function is only for Raw Port Numbers \n")));
   2876         return SOC_E_FAIL;
   2877     }
   2878 
   2879 #ifdef CRASH_RECOVERY_SUPPORT
   2880 /* Don't handle Special Accesses */
   2881     if((SOC_INFO(unit).reg_access.reg64_set) || /* User defined */
   2882        (SOC_REG_IS_ABOVE_64(unit, reg)) ||
   2883        (SOC_IS_DONE_INIT(unit) && BCM_UNIT_DO_HW_READ_WRITE(unit) &&
   2884         Hw_Log_List[unit].Access_cb.soc_reg_set)) {
   2885         LOG_ERROR(BSL_LS_SOC_COMMON,
   2886                   (BSL_META_U(unit,
   2887                               "Use soc_reg_set \n")));
   2888         return SOC_E_FAIL;
   2889     }
   2890 #else
   2891     /* Don't handle Special Accesses */
   2892     if((SOC_INFO(unit).reg_access.reg64_set) || /* User defined */
   2893        (SOC_REG_IS_ABOVE_64(unit, reg))) {
   2894         LOG_ERROR(BSL_LS_SOC_COMMON,
   2895                   (BSL_META_U(unit,
   2896                               "Use soc_reg_set \n")));
   2897         return SOC_E_FAIL;
   2898     }
   2899 #endif /* CRASH_RECOVERY_SUPPORT */
   2900 
   2901     rv = soc_reg_xaddr_get(unit, reg, port, index, SOC_REG_ADDR_OPTION_WRITE |
   2902       SOC_REG_ADDR_OPTION_PRESERVE_PORT, &access_info);
   2903     if (rv != SOC_E_NONE) {
   2904         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   2905           "soc_reg_rawport_set: failed to get register address")));
   2906         return rv;
   2907     }
   2908     addr = access_info.offset;
   2909     if (SOC_REG_IS_64(unit, reg)) {
   2910 #if defined(BCM_XGS_SUPPORT)
   2911         if (soc_feature(unit, soc_feature_regs_as_mem)) {
   2912             (void)soc_ser_reg_cache_set(unit, reg, port, index, data);
   2913         }
   2914 #endif /* BCM_XGS_SUPPORT */
   2915         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   2916             return soc_reg_write(unit, reg, addr, data);
   2917         } else {
   2918             for (i = 0; i < access_info.num_blks && rv == SOC_E_NONE; ++i) {
   2919                 rv = _soc_reg64_set(unit, access_info.blk_list[i], access_info.acc_type, addr, data);
   2920             }
   2921         }
   2922     } else {
   2923         uint32 data32;
   2924         if (COMPILER_64_HI(data)) {
   2925             LOG_WARN(BSL_LS_SOC_COMMON,
   2926                      (BSL_META_U(unit,
   2927                                  "WARNING: "
   2928                                  "write to 32-bit reg %s with hi order data, 0x%x\n"),
   2929                       SOC_REG_NAME(unit, reg),
   2930                       COMPILER_64_HI(data)));
   2931         }
   2932         data32 = COMPILER_64_LO(data);
   2933 #if defined(BCM_XGS_SUPPORT)
   2934         if (soc_feature(unit, soc_feature_regs_as_mem)) {
   2935             (void)soc_ser_reg32_cache_set(unit, reg, port, index, data32);
   2936         }
   2937 #endif /* BCM_XGS_SUPPORT */
   2938 
   2939         if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   2940             return soc_reg32_write(unit, addr, data32);
   2941         } else {
   2942             for (i = 0; i < access_info.num_blks && rv == SOC_E_NONE; ++i) {
   2943                 rv = _soc_reg32_set(unit, access_info.blk_list[i], access_info.acc_type, addr, data32);
   2944         }
   2945     }
   2946     }
   2947     return rv;
   2948 }
   2949 
   2950 int
   2951 soc_reg32_rawport_set(int unit, soc_reg_t reg, int port, int index, uint32 data)
   2952 {
   2953     uint64 d64;
   2954 
   2955     COMPILER_64_SET(d64, 0, data);
   2956     return soc_reg_rawport_set(unit, reg, port, index, d64);
   2957 }
   2958 
   2959 /*
   2960  * Write internal register for a group of ports.
   2961  * The specified register must be a port reg (type soc_portreg).
   2962  */
   2963 
   2964 int
   2965 soc_reg_write_ports(int unit,
   2966                     soc_reg_t reg,
   2967                     pbmp_t pbmp,
   2968                     uint32 value)
   2969 {
   2970     soc_port_t        port;
   2971     soc_block_t       ptype; 
   2972     soc_block_types_t rtype;
   2973 
   2974     /* assert(reg is a port register) */
   2975     if (!SOC_REG_IS_VALID(unit, reg) ||
   2976         SOC_REG_INFO(unit, reg).regtype != soc_portreg) {
   2977         return SOC_E_UNAVAIL;
   2978     }
   2979 
   2980     rtype = SOC_REG_INFO(unit, reg).block;
   2981 
   2982     /*
   2983      * each port block type must match one of the register block types
   2984      * or the register block type can be the MMU
   2985      */
   2986     PBMP_ITER(pbmp, port) {
   2987         ptype = SOC_PORT_TYPE(unit, port);
   2988         if (SOC_BLOCK_IN_LIST(rtype, ptype) || SOC_BLOCK_IN_LIST(rtype, SOC_BLK_MMU)) {
   2989             if (soc_feature(unit, soc_feature_new_sbus_format)) {
   2990                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg,
   2991                                                   port, 0, value));
   2992             } else {
   2993 #if defined(BCM_XGS_SUPPORT)
   2994                 if (soc_feature(unit, soc_feature_regs_as_mem)) {
   2995                     (void)soc_ser_reg32_cache_set(unit, reg, port, 0, value);
   2996                 }
   2997 #endif /* BCM_XGS_SUPPORT */
   2998                 SOC_IF_ERROR_RETURN(soc_reg32_write(unit,
   2999                                     soc_reg_addr(unit, reg, port, 0), value));
   3000             }
   3001         }
   3002     }
   3003     return SOC_E_NONE;
   3004 }
   3005 
   3006 /*
   3007  * Write internal register for a block or group of blocks.
   3008  * The specified register must be a generic reg (type soc_genreg).
   3009  *
   3010  * This routine will write to all possible blocks for the given
   3011  * register.
   3012  */
   3013 int
   3014 soc_reg64_write_all_blocks(int unit,
   3015                            soc_reg_t reg,
   3016                            uint64 value)
   3017 {
   3018     int               blk, port;
   3019     soc_block_types_t rtype;
   3020 
   3021     /* assert(reg is not a port or cos register) */
   3022     if (!SOC_REG_IS_VALID(unit, reg) ||
   3023         SOC_REG_INFO(unit, reg).regtype != soc_genreg) {
   3024         return SOC_E_UNAVAIL;
   3025     }
   3026 
   3027     rtype = SOC_REG_INFO(unit, reg).block;
   3028 
   3029     SOC_BLOCKS_ITER(unit, blk, rtype) {
   3030         port = SOC_BLOCK_PORT(unit, blk);
   3031 #if defined(BCM_XGS_SUPPORT)
   3032         if (soc_feature(unit, soc_feature_regs_as_mem)) {
   3033             (void)soc_ser_reg_cache_set(unit, reg, port, 0, value);
   3034         }
   3035 #endif /* BCM_XGS_SUPPORT */        
   3036         if (soc_feature(unit, soc_feature_new_sbus_format)) {
   3037             SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, value));
   3038         } else {
   3039             SOC_IF_ERROR_RETURN(soc_reg_write(unit, reg,
   3040                                 soc_reg_addr(unit, reg, port, 0), value));
   3041         }
   3042     }
   3043     return SOC_E_NONE;
   3044 }
   3045 
   3046 /*
   3047  * Write internal register for a block or group of blocks.
   3048  * The specified register must be a generic reg (type soc_genreg).
   3049  *
   3050  * This routine will write to all possible blocks for the given
   3051  * register.
   3052  */
   3053 int
   3054 soc_reg_write_all_blocks(int unit,
   3055                          soc_reg_t reg,
   3056                          uint32 value)
   3057 {
   3058     uint64 val64;
   3059 
   3060     if (!SOC_REG_IS_VALID(unit, reg)) {
   3061         return SOC_E_PARAM;
   3062     }
   3063 
   3064     COMPILER_64_SET(val64, 0, value);
   3065     return soc_reg64_write_all_blocks(unit, reg, val64);
   3066 }
   3067 
   3068 /*
   3069  * Read a general register from any block that has a copy
   3070  */
   3071 int
   3072 soc_reg64_read_any_block(int unit,
   3073                          soc_reg_t reg,
   3074                          uint64 *datap)
   3075 {
   3076     int               blk, port;
   3077     soc_block_types_t rtype;
   3078 #ifdef CRASH_RECOVERY_SUPPORT
   3079     if (SOC_IS_DONE_INIT(unit))
   3080     {
   3081         if (BCM_UNIT_DO_HW_READ_WRITE(unit))
   3082         {
   3083           LOG_WARN(BSL_LS_SOC_COMMON,
   3084                      (BSL_META_U(unit, "soc_reg64_read_any_block: WARNING: "
   3085                                  "HW Log feature in unexpected function!!!\n")));
   3086         }
   3087     }
   3088 #endif /* CRASH_RECOVERY_SUPPORT */
   3089 
   3090     /* assert(reg is not a port or cos register) */
   3091     if (!SOC_REG_IS_VALID(unit, reg) ||
   3092         SOC_REG_INFO(unit, reg).regtype != soc_genreg) {
   3093         return SOC_E_UNAVAIL;
   3094     }
   3095 
   3096     rtype = SOC_REG_INFO(unit, reg).block;
   3097     SOC_BLOCKS_ITER(unit, blk, rtype) {
   3098         port = SOC_BLOCK_PORT(unit, blk);
   3099         if (soc_feature(unit, soc_feature_new_sbus_format)) {
   3100             SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, datap));
   3101         } else {
   3102             SOC_IF_ERROR_RETURN
   3103                 (soc_reg_read(unit, reg, soc_reg_addr(unit, reg, port, 0),
   3104                               datap));
   3105         }
   3106         break;
   3107     }
   3108     return SOC_E_NONE;
   3109 }
   3110 
   3111 /*
   3112  * Read a general register from any block that has a copy
   3113  */
   3114 int
   3115 soc_reg_read_any_block(int unit,
   3116                      soc_reg_t reg,
   3117                      uint32 *datap)
   3118 {
   3119     uint64 val64;
   3120 
   3121     SOC_IF_ERROR_RETURN(soc_reg64_read_any_block(unit, reg, &val64));
   3122     COMPILER_64_TO_32_LO(*datap, val64);
   3123 
   3124     return SOC_E_NONE;
   3125 }
   3126 
   3127 /****************************************************************
   3128  * Register field manipulation functions
   3129  */
   3130 
   3131 /* Define a macro so the assertion printout is informative. */
   3132 #define        REG_FIELD_IS_VALID        finfop
   3133 
   3134 /*
   3135  * Function:     soc_reg_field_length
   3136  * Purpose:      Return the length of a register field in bits.
   3137  *               Value is 0 if field is not found.
   3138  * Returns:      bits in field
   3139  */
   3140 int
   3141 soc_reg_field_length(int unit, soc_reg_t reg, soc_field_t field)
   3142 {
   3143     soc_field_info_t *finfop;
   3144 
   3145     if (!SOC_REG_IS_VALID(unit, reg)) {
   3146         return 0;
   3147     }
   3148 
   3149     SOC_FIND_FIELD(field,
   3150                    SOC_REG_INFO(unit, reg).fields,
   3151                    SOC_REG_INFO(unit, reg).nFields,
   3152                    finfop);
   3153     if (finfop == NULL) {
   3154         return 0;
   3155     }
   3156     return finfop->len;
   3157 }
   3158 
   3159 /*
   3160  * Function:     soc_reg_field_valid
   3161  * Purpose:      Determine if a field in a register is valid.
   3162  * Returns:      Returns TRUE  if field is found.
   3163  *               Returns FALSE if field is not found.
   3164  */
   3165 int
   3166 soc_reg_field_valid(int unit, soc_reg_t reg, soc_field_t field)
   3167 {
   3168     soc_field_info_t *finfop;
   3169 
   3170     if (!SOC_REG_IS_VALID(unit, reg)) {
   3171         return FALSE;
   3172     }
   3173 
   3174     SOC_FIND_FIELD(field,
   3175                    SOC_REG_INFO(unit, reg).fields,
   3176                    SOC_REG_INFO(unit, reg).nFields,
   3177                    finfop);
   3178     return (finfop != NULL);
   3179 }
   3180 
   3181 
   3182 /*
   3183  * Function:     soc_reg_field_get
   3184  * Purpose:      Get the value of a field from a register
   3185  * Parameters:
   3186  * Returns:      Value of field
   3187  */
   3188 uint32
   3189 soc_reg_field_get(int unit, soc_reg_t reg, uint32 regval, soc_field_t field)
   3190 {
   3191     soc_field_info_t *finfop;
   3192     uint32           val;
   3193 
   3194     if (!SOC_REG_IS_VALID(unit, reg)) {
   3195 #if !defined(SOC_NO_NAMES)
   3196         LOG_CLI((BSL_META_U(unit,
   3197                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3198 #endif
   3199         assert(SOC_REG_IS_VALID(unit, reg));
   3200     }
   3201 
   3202     SOC_FIND_FIELD(field,
   3203                    SOC_REG_INFO(unit, reg).fields,
   3204                    SOC_REG_INFO(unit, reg).nFields,
   3205                    finfop);
   3206 
   3207     if (finfop == NULL) {
   3208 #if !defined(SOC_NO_NAMES)
   3209         LOG_CLI((BSL_META_U(unit,
   3210                             "reg %s field %s is invalid\n"),
   3211                  soc_reg_name[reg], soc_fieldnames[field]));
   3212 #endif
   3213         assert(finfop);
   3214     }
   3215 
   3216     /*
   3217      * COVERITY
   3218      *
   3219      * assert validates the input for NULL
   3220      */
   3221     /* coverity[var_deref_op : FALSE] */
   3222     val = regval >> finfop->bp;
   3223     if (finfop->len < 32) {
   3224         return val & ((1 << finfop->len) - 1);
   3225     } else {
   3226         return val;
   3227     }
   3228 }
   3229 
   3230 /*
   3231  * Function:     soc_ftmh_cfg_get
   3232  * Purpose:      Get the value of FTMH_LB_KEY_EXT_ENf, FTMH_STACKING_EXT_ENABLEf into the given int pointers
   3233  */
   3234 int
   3235 soc_ftmh_cfg_get(int unit, int * p_cfg_ftmh_lb_key_ext_en, int * p_cfg_ftmh_stacking_ext_enable)
   3236 {
   3237         uint32
   3238             reg_val32;
   3239         int
   3240             rv = SOC_E_NONE;
   3241 
   3242         rv = READ_ECI_GLOBALFr(unit, &reg_val32);
   3243         *p_cfg_ftmh_lb_key_ext_en = soc_reg_field_get(unit, ECI_GLOBALFr, reg_val32, FTMH_LB_KEY_EXT_ENf);
   3244         *p_cfg_ftmh_stacking_ext_enable = soc_reg_field_get(unit, ECI_GLOBALFr, reg_val32, FTMH_STACKING_EXT_ENABLEf);
   3245 
   3246         return rv;
   3247 }
   3248 
   3249 /*
   3250  * Function:     soc_reg64_field_get
   3251  * Purpose:      Get the value of a field from a 64-bit register
   3252  * Parameters:
   3253  * Returns:      Value of field (64 bits)
   3254  */
   3255 uint64
   3256 soc_reg64_field_get(int unit, soc_reg_t reg, uint64 regval, soc_field_t field)
   3257 {
   3258     soc_field_info_t *finfop;
   3259     uint64           mask;
   3260 
   3261     if (!SOC_REG_IS_VALID(unit, reg)) {
   3262 #if !defined(SOC_NO_NAMES)
   3263         LOG_CLI((BSL_META_U(unit,
   3264                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3265 #endif
   3266         assert(SOC_REG_IS_VALID(unit, reg));
   3267     }
   3268 
   3269     SOC_FIND_FIELD(field,
   3270                    SOC_REG_INFO(unit, reg).fields,
   3271                    SOC_REG_INFO(unit, reg).nFields,
   3272                    finfop);
   3273     if (finfop == NULL) {
   3274 #if !defined(SOC_NO_NAMES)
   3275         LOG_CLI((BSL_META_U(unit,
   3276                             "reg %s field %s is invalid\n"),
   3277                  soc_reg_name[reg], soc_fieldnames[field]));
   3278 #endif
   3279         assert(finfop);
   3280     }
   3281 
   3282     /*
   3283      * COVERITY
   3284      *
   3285      * assert validates the input for NULL
   3286      */
   3287     /* coverity[var_deref_op : FALSE] */
   3288     COMPILER_64_MASK_CREATE(mask, finfop->len, 0);
   3289     COMPILER_64_SHR(regval, finfop->bp);
   3290     COMPILER_64_AND(regval, mask);
   3291 
   3292     return regval;
   3293 }
   3294 
   3295 /* 
   3296  * Function:     soc_reg64_field32_get
   3297  * Purpose:      Get the value of a field from a 64-bit register
   3298  * Parameters:
   3299  * Returns:      Value of field (32 bits)
   3300  */
   3301 uint32
   3302 soc_reg64_field32_get(int unit, soc_reg_t reg, uint64 regval,
   3303                       soc_field_t field)
   3304 {
   3305     soc_field_info_t *finfop;
   3306     uint32           val32;
   3307 
   3308     if (!SOC_REG_IS_VALID(unit, reg)) {
   3309 #if !defined(SOC_NO_NAMES)
   3310         LOG_CLI((BSL_META_U(unit,
   3311                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3312 #endif
   3313         assert(SOC_REG_IS_VALID(unit, reg));
   3314     }
   3315 
   3316     SOC_FIND_FIELD(field,
   3317                    SOC_REG_INFO(unit, reg).fields,
   3318                    SOC_REG_INFO(unit, reg).nFields,
   3319                    finfop);
   3320     if (finfop == NULL) {
   3321 #if !defined(SOC_NO_NAMES)
   3322         LOG_CLI((BSL_META_U(unit,
   3323                             "reg %s field %s is invalid\n"),
   3324                  soc_reg_name[reg], soc_fieldnames[field]));
   3325 #endif
   3326         assert(finfop);
   3327     }
   3328 
   3329     /*
   3330      * COVERITY
   3331      *
   3332      * assert validates the input for NULL
   3333      */
   3334     /* coverity[var_deref_op : FALSE] */
   3335     COMPILER_64_SHR(regval, finfop->bp);
   3336     COMPILER_64_TO_32_LO(val32, regval);
   3337     if (finfop->len < 32) {
   3338         return val32 & ((1 << finfop->len) - 1);
   3339     } else {
   3340         return val32;
   3341     }
   3342 }
   3343 
   3344 /*
   3345  * Function:     soc_reg_above_64_field_get
   3346  * Purpose:      Get the value of a field from a register
   3347  * Parameters:
   3348  * Returns:      Value of field
   3349  */
   3350 void
   3351 soc_reg_above_64_field_get(int unit, soc_reg_t reg, soc_reg_above_64_val_t regval, 
   3352                            soc_field_t field, soc_reg_above_64_val_t field_val)
   3353 {
   3354     soc_field_info_t *finfop;
   3355 
   3356     if (!SOC_REG_IS_VALID(unit, reg)) {
   3357 #if !defined(SOC_NO_NAMES)
   3358         LOG_CLI((BSL_META_U(unit,
   3359                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3360 #endif
   3361         assert(SOC_REG_IS_VALID(unit, reg));
   3362     }
   3363 
   3364     SOC_FIND_FIELD(field,
   3365                    SOC_REG_INFO(unit, reg).fields,
   3366                    SOC_REG_INFO(unit, reg).nFields,
   3367                    finfop);
   3368 
   3369     if (finfop == NULL) {
   3370 #if !defined(SOC_NO_NAMES)
   3371         LOG_CLI((BSL_META_U(unit,
   3372                             "reg %s field %s is invalid\n"),
   3373                  soc_reg_name[reg], soc_fieldnames[field]));
   3374 #endif
   3375         assert(finfop);
   3376     }
   3377     
   3378     
   3379     SOC_REG_ABOVE_64_CLEAR(field_val);
   3380     /*
   3381      * COVERITY
   3382      *
   3383      * assert validates the input for NULL
   3384      */
   3385     /* coverity[var_deref_op : FALSE] */
   3386     SHR_BITCOPY_RANGE(field_val, 0, regval, finfop->bp, finfop->len);
   3387     
   3388 }
   3389 /*
   3390  * Function:     soc_reg_above_64_field_read
   3391  * Purpose:      Read a register of any size, and get the value of a field sized up to any size.
   3392  * Parameters:
   3393  * Returns:      Value of field (32 bits)
   3394  */
   3395 int
   3396 soc_reg_above_64_field_read(int unit, soc_reg_t reg, soc_port_t port, int index, soc_field_t field, soc_reg_above_64_val_t out_field_val)
   3397 {   
   3398     int rc = SOC_E_NONE;
   3399     soc_reg_above_64_val_t data;
   3400     SOC_REG_ABOVE_64_CLEAR(data);
   3401     rc = soc_reg_above_64_get(unit, reg, port, index, data);
   3402     if (rc != SOC_E_NONE){
   3403         return rc;
   3404     }
   3405     soc_reg_above_64_field_get(unit, reg, data, field, out_field_val);
   3406     return rc;
   3407 }
   3408 /* 
   3409  * Function:     soc_reg_above_64_field32_get
   3410  * Purpose:      Get the value of a field sized up to 32 bit from a register of any size
   3411  * Parameters:
   3412  * Returns:      Value of field (32 bits)
   3413  */
   3414 uint32
   3415 soc_reg_above_64_field32_get(int unit, soc_reg_t reg, soc_reg_above_64_val_t regval, 
   3416                            soc_field_t field)
   3417 {
   3418     soc_field_info_t *finfop;
   3419     uint32 field_val = 0;
   3420 
   3421     if (!SOC_REG_IS_VALID(unit, reg)) {
   3422 #if !defined(SOC_NO_NAMES)
   3423         LOG_CLI((BSL_META_U(unit,
   3424                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3425 #endif
   3426         assert(SOC_REG_IS_VALID(unit, reg));
   3427     }
   3428 
   3429     SOC_FIND_FIELD(field,
   3430                    SOC_REG_INFO(unit, reg).fields,
   3431                    SOC_REG_INFO(unit, reg).nFields,
   3432                    finfop);
   3433 
   3434     if (finfop == NULL) {
   3435 #if !defined(SOC_NO_NAMES)
   3436         LOG_CLI((BSL_META_U(unit,
   3437                             "reg %s field %s is invalid\n"),
   3438                  soc_reg_name[reg], soc_fieldnames[field]));
   3439 #endif
   3440         assert(finfop);
   3441     } else if (finfop->len > 32) {
   3442 #if !defined(SOC_NO_NAMES)
   3443         LOG_CLI((BSL_META_U(unit,
   3444                             "reg %s field %s has a size of %u bits which is greater than 32\n"),
   3445                  soc_reg_name[reg], soc_fieldnames[field], (unsigned)finfop->len));
   3446 #endif
   3447         assert(0);
   3448     } else {
   3449 
   3450         SHR_BITCOPY_RANGE(&field_val, 0, regval, finfop->bp, finfop->len); /* get the field value */
   3451 
   3452     }
   3453     return field_val;
   3454 }
   3455 /*
   3456  * Function:     soc_reg_above_64_field32_read
   3457  * Purpose:      Read a register of any size, and get the value of a field sized up to 32 bit from it.
   3458  * Parameters:
   3459  * Returns:      Value of field (32 bits)
   3460  */
   3461 
   3462 int
   3463 soc_reg_above_64_field32_read(int unit, soc_reg_t reg, soc_port_t port, int index, soc_field_t field, uint32* out_field_val)
   3464 {   
   3465     int rc = SOC_E_NONE;
   3466     soc_reg_above_64_val_t data;
   3467     SOC_REG_ABOVE_64_CLEAR(data);
   3468     rc = soc_reg_above_64_get(unit, reg, port, index, data);
   3469     if (rc != SOC_E_NONE){
   3470         return rc;
   3471     }
   3472     *out_field_val = soc_reg_above_64_field32_get(unit,reg, data, field);
   3473     return rc;
   3474 }
   3475 /* 
   3476  * Function:     soc_reg_above_64_field64_get
   3477  * Purpose:      Get the value of a field sized up to 32 bit from a register of any size
   3478  * Parameters:
   3479  * Returns:      Value of field (32 bits)
   3480  */
   3481 
   3482 uint64
   3483 soc_reg_above_64_field64_get(int unit, soc_reg_t reg, soc_reg_above_64_val_t regval, 
   3484                            soc_field_t field)
   3485 {
   3486     soc_field_info_t *finfop;
   3487     uint64 fieldval;
   3488     
   3489     COMPILER_64_ZERO(fieldval);
   3490     if (!SOC_REG_IS_VALID(unit, reg)) {
   3491 #if !defined(SOC_NO_NAMES)
   3492         LOG_CLI((BSL_META_U(unit,
   3493                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3494 #endif
   3495         assert(SOC_REG_IS_VALID(unit, reg));
   3496     }
   3497 
   3498     SOC_FIND_FIELD(field,
   3499                    SOC_REG_INFO(unit, reg).fields,
   3500                    SOC_REG_INFO(unit, reg).nFields,
   3501                    finfop);
   3502     /* coverity[var_compare_op] */
   3503     if (finfop == NULL) {
   3504 #if !defined(SOC_NO_NAMES)
   3505         LOG_CLI((BSL_META_U(unit,
   3506                             "reg %s field %s is invalid\n"),
   3507                  soc_reg_name[reg], soc_fieldnames[field]));
   3508 #endif
   3509         assert(finfop);
   3510     } else if (finfop->len > 64) {
   3511 #if !defined(SOC_NO_NAMES)
   3512         LOG_CLI((BSL_META_U(unit,
   3513                             "reg %s field %s has a size of %u bits which is greater than 32\n"),
   3514                  soc_reg_name[reg], soc_fieldnames[field], (unsigned)finfop->len));
   3515 #endif
   3516         assert(0);
   3517     } else {
   3518         uint32 low = 0, hi = 0;
   3519         if (finfop->len > 32) {
   3520             SHR_BITCOPY_RANGE(&low, 0, regval, finfop->bp, 32); /* get the field value lsb word */
   3521             SHR_BITCOPY_RANGE(&hi, 0, regval, finfop->bp + 32, finfop->len - 32); /* get the field value msb word */
   3522         } else {
   3523             SHR_BITCOPY_RANGE(&low, 0, regval, finfop->bp, finfop->len); /* get the field value */
   3524         }
   3525         COMPILER_64_SET(fieldval, hi, low);
   3526     }
   3527     return fieldval;
   3528 }
   3529 /*
   3530  * Function:     soc_reg_above_64_field64_read
   3531  * Purpose:      Read a register of any size, and get the value of a field sized up to 64 bit from it.
   3532  * Parameters:
   3533  * Returns:      Value of field (32 bits)
   3534  */
   3535 int
   3536 soc_reg_above_64_field64_read(int unit, soc_reg_t reg, soc_port_t port, int index, soc_field_t field, uint64* out_field_val)
   3537 {   
   3538     int rc = SOC_E_NONE;
   3539     soc_reg_above_64_val_t data;
   3540     SOC_REG_ABOVE_64_CLEAR(data);
   3541     rc = soc_reg_above_64_get(unit, reg, port, index, data);
   3542     if (rc != SOC_E_NONE){
   3543         return rc;
   3544     }
   3545     *out_field_val = soc_reg_above_64_field64_get(unit,reg, data, field);
   3546     return rc;
   3547 }
   3548 
   3549 /* Define a macro so the assertion printout is informative. */
   3550 #define VALUE_TOO_BIG_FOR_FIELD                ((value & ~mask) != 0)
   3551 
   3552 /*
   3553  * Function:     soc_reg_field_validate
   3554  * Purpose:      Validate the value of a register's field.
   3555  * Parameters:
   3556  * Returns:      SOC_E_XXX
   3557  */
   3558 int
   3559 soc_reg_field_validate(int unit, soc_reg_t reg, soc_field_t field, uint32 value)
   3560 {
   3561     soc_field_info_t *finfop;
   3562     uint32           mask;
   3563 
   3564     if (!SOC_REG_IS_VALID(unit, reg)) {
   3565 #if !defined(SOC_NO_NAMES)
   3566         LOG_CLI((BSL_META_U(unit,
   3567                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3568 #endif
   3569         assert(SOC_REG_IS_VALID(unit, reg));
   3570     }
   3571 
   3572     SOC_FIND_FIELD(field,
   3573                    SOC_REG_INFO(unit, reg).fields,
   3574                    SOC_REG_INFO(unit, reg).nFields,
   3575                    finfop);
   3576                    
   3577     if (finfop == NULL) {
   3578 #if !defined(SOC_NO_NAMES)
   3579         LOG_CLI((BSL_META_U(unit,
   3580                             "reg %s field %s is invalid\n"),
   3581                  soc_reg_name[reg], soc_fieldnames[field]));
   3582 #endif
   3583         assert(finfop);
   3584     }
   3585 
   3586     /*
   3587      * COVERITY
   3588      *
   3589      * assert validates the input for NULL
   3590      */
   3591     /* coverity[var_deref_op : FALSE] */
   3592     if (finfop->len < 32) {
   3593       mask = (1 << finfop->len) - 1; 
   3594       if  (VALUE_TOO_BIG_FOR_FIELD) {
   3595             return SOC_E_PARAM;
   3596       }
   3597      }
   3598     
   3599     return SOC_E_NONE;
   3600 }
   3601 
   3602 /*
   3603  * Function:     soc_reg_signed_field_mask
   3604  * Purpose:      Chops high bits of signed value to fit in register field
   3605  * Parameters:
   3606  * Returns:      SOC_E_XXX
   3607  */
   3608 int
   3609 soc_reg_signed_field_mask(int unit, soc_reg_t reg, soc_field_t field, int32 value_in, uint32 *value_out)
   3610 {
   3611     soc_field_info_t *finfop;
   3612     int32            max_valid;
   3613     int32            min_valid;
   3614     uint32           mask;
   3615 
   3616     if (!SOC_REG_IS_VALID(unit, reg)) {
   3617 #if !defined(SOC_NO_NAMES)
   3618         LOG_CLI((BSL_META_U(unit,
   3619                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3620 #endif
   3621         assert(SOC_REG_IS_VALID(unit, reg));
   3622     }
   3623 
   3624     SOC_FIND_FIELD(field,
   3625                    SOC_REG_INFO(unit, reg).fields,
   3626                    SOC_REG_INFO(unit, reg).nFields,
   3627                    finfop);
   3628 
   3629     if (finfop == NULL) {
   3630 #if !defined(SOC_NO_NAMES)
   3631         LOG_CLI((BSL_META_U(unit,
   3632                             "reg %s field %s is invalid\n"),
   3633                  soc_reg_name[reg], soc_fieldnames[field]));
   3634 #endif
   3635         assert(finfop);
   3636     }
   3637 
   3638     /*
   3639      * COVERITY
   3640      *
   3641      * assert validates the input for NULL
   3642      */
   3643     /* coverity[var_deref_op : FALSE] */
   3644     if (finfop->len < 32) {
   3645         mask = (1 << finfop->len) - 1;
   3646 
   3647         *value_out = (((uint32)value_in) & mask);
   3648 
   3649         max_valid = (1 << (finfop->len-1)) - 1;
   3650         min_valid = -max_valid;
   3651 
   3652         if (value_in > max_valid || value_in < min_valid) {
   3653             return SOC_E_PARAM;
   3654         }
   3655     } else {
   3656         *value_out = (uint32) value_in;
   3657     }
   3658 
   3659     return SOC_E_NONE;
   3660 }
   3661 
   3662 /*
   3663  * Function:     soc_reg_unsigned_field_mask
   3664  * Purpose:      Chops high bits of unsigned value to fit in register field
   3665  * Parameters:
   3666  * Returns:      SOC_E_XXX
   3667  */
   3668 int
   3669 soc_reg_unsigned_field_mask(int unit, soc_reg_t reg, soc_field_t field, int32 value_in, uint32 *value_out)
   3670 {
   3671     soc_field_info_t *finfop;
   3672     uint32            max_valid;
   3673     uint32            min_valid;
   3674     uint32            mask;
   3675 
   3676     if (!SOC_REG_IS_VALID(unit, reg)) {
   3677 #if !defined(SOC_NO_NAMES)
   3678         LOG_CLI((BSL_META_U(unit,
   3679                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3680 #endif
   3681         assert(SOC_REG_IS_VALID(unit, reg));
   3682     }
   3683 
   3684     SOC_FIND_FIELD(field,
   3685                    SOC_REG_INFO(unit, reg).fields,
   3686                    SOC_REG_INFO(unit, reg).nFields,
   3687                    finfop);
   3688 
   3689     if (finfop == NULL) {
   3690 #if !defined(SOC_NO_NAMES)
   3691         LOG_CLI((BSL_META_U(unit,
   3692                             "reg %s field %s is invalid\n"),
   3693                  soc_reg_name[reg], soc_fieldnames[field]));
   3694 #endif
   3695         assert(finfop);
   3696     }
   3697 
   3698     if (finfop->len < 32) {
   3699         mask = (1 << finfop->len) - 1;
   3700 
   3701         *value_out = (((uint32)value_in) & mask);
   3702 
   3703         max_valid = (1 << finfop->len) - 1;
   3704         min_valid = 0;
   3705 
   3706         if (value_in > max_valid || value_in < min_valid) {
   3707             return SOC_E_PARAM;
   3708         }
   3709     } else {
   3710         *value_out = (uint32) value_in;
   3711     }
   3712 
   3713     return SOC_E_NONE;
   3714 }
   3715 
   3716 /*
   3717  * Function:     soc_reg_field_set
   3718  * Purpose:      Set the value of a register's field.
   3719  * Parameters:
   3720  * Returns:      void
   3721  */
   3722 void
   3723 soc_reg_field_set(int unit, soc_reg_t reg, uint32 *regval,
   3724                   soc_field_t field, uint32 value)
   3725 {
   3726     soc_field_info_t *finfop;
   3727     uint32           mask;
   3728 
   3729     if (!SOC_REG_IS_VALID(unit, reg)) {
   3730 #if !defined(SOC_NO_NAMES)
   3731         LOG_CLI((BSL_META_U(unit,
   3732                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3733 #endif
   3734         assert(SOC_REG_IS_VALID(unit, reg));
   3735     }
   3736 
   3737     SOC_FIND_FIELD(field,
   3738                    SOC_REG_INFO(unit, reg).fields,
   3739                    SOC_REG_INFO(unit, reg).nFields,
   3740                    finfop);
   3741     if (finfop == NULL) {
   3742 #if !defined(SOC_NO_NAMES)
   3743         LOG_CLI((BSL_META_U(unit,
   3744                             "reg %s field %s is invalid\n"),
   3745                  soc_reg_name[reg], soc_fieldnames[field]));
   3746 #endif
   3747         assert(finfop);
   3748     }
   3749 
   3750     if (finfop->len < 32) {
   3751         mask = (1 << finfop->len) - 1;
   3752    if  (VALUE_TOO_BIG_FOR_FIELD) {
   3753 #if !defined(SOC_NO_NAMES)
   3754         LOG_CLI((BSL_META_U(unit,
   3755                             "reg %s field %s is too big\n"),
   3756                  soc_reg_name[reg], soc_fieldnames[field]));
   3757 #endif
   3758         assert(!VALUE_TOO_BIG_FOR_FIELD);
   3759    }
   3760     } else {
   3761         mask = -1;
   3762     }
   3763 
   3764     *regval = (*regval & ~(mask << finfop->bp)) | value << finfop->bp;
   3765 }
   3766 
   3767 /*
   3768  * Function:     soc_reg_field_set
   3769  * Purpose:      Set the value of a register's field.
   3770  * Parameters:
   3771  * Returns:      void
   3772  */
   3773 void
   3774 soc_reg_above_64_field_set(int unit, soc_reg_t reg, soc_reg_above_64_val_t regval,
   3775                             soc_field_t field, CONST soc_reg_above_64_val_t value)
   3776 {
   3777     soc_field_info_t *finfop;
   3778 
   3779     if (!SOC_REG_IS_VALID(unit, reg)) {
   3780 #if !defined(SOC_NO_NAMES)
   3781         LOG_CLI((BSL_META_U(unit,
   3782                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3783 #endif
   3784         assert(SOC_REG_IS_VALID(unit, reg));
   3785     }
   3786 
   3787     SOC_FIND_FIELD(field,
   3788                    SOC_REG_INFO(unit, reg).fields,
   3789                    SOC_REG_INFO(unit, reg).nFields,
   3790                    finfop);
   3791     if (finfop == NULL) {
   3792 #if !defined(SOC_NO_NAMES)
   3793         LOG_CLI((BSL_META_U(unit,
   3794                             "reg %s field %s is invalid\n"),
   3795                  soc_reg_name[reg], soc_fieldnames[field]));
   3796 #endif
   3797         assert(finfop);
   3798     }
   3799     { /* Check if the field value will fit into the field: Verify that value's bits that do not fit in the field are all zeroes. */
   3800 
   3801         /*
   3802          * COVERITY
   3803          *
   3804          * assert validates the input for NULL
   3805          */
   3806         /* coverity[var_deref_op : FALSE] */
   3807         unsigned msb_bits = finfop->len % 32; /* Bits in msb word of field value */
   3808         unsigned idx      = finfop->len / 32; /* word Iteration index, starts with msb word of field. */
   3809 
   3810         if (msb_bits) { /* if the msb vaule word has left over bits unused */
   3811             assert (!(value[idx] & (((uint32)0xffffffff) << msb_bits))); /* verify the left over bits are zeros */
   3812             ++idx;
   3813         }
   3814         for (; idx < SOC_REG_ABOVE_64_MAX_SIZE_U32; ++idx) { /* verify the remaining words are zeros */
   3815             assert (!(value[idx]));
   3816         }
   3817     }
   3818     
   3819     SHR_BITCOPY_RANGE(regval, finfop->bp, value, 0, finfop->len);
   3820 
   3821 }
   3822 
   3823 /* 
   3824  * Function:     soc_reg_above_64_field32_set
   3825  * Purpose:      Set the value of a register's field; field must be <= 32 bits, any register size supported
   3826  * Parameters:
   3827  * Returns:      void
   3828  */
   3829 void
   3830 soc_reg_above_64_field32_set(int unit, soc_reg_t reg, soc_reg_above_64_val_t regval,
   3831                             soc_field_t field, uint32 value)
   3832 {
   3833     soc_field_info_t *finfop;
   3834 
   3835     if (!SOC_REG_IS_VALID(unit, reg)) {
   3836 #if !defined(SOC_NO_NAMES)
   3837         LOG_CLI((BSL_META_U(unit,
   3838                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3839 #endif
   3840         assert(SOC_REG_IS_VALID(unit, reg));
   3841     }
   3842 
   3843     SOC_FIND_FIELD(field,
   3844                    SOC_REG_INFO(unit, reg).fields,
   3845                    SOC_REG_INFO(unit, reg).nFields,
   3846                    finfop);
   3847     if (finfop == NULL) {
   3848 #if !defined(SOC_NO_NAMES)
   3849         LOG_CLI((BSL_META_U(unit,
   3850                             "reg %s field %s is invalid\n"),
   3851                  soc_reg_name[reg], soc_fieldnames[field]));
   3852 #endif
   3853         assert(finfop);
   3854     /* Check if the field value will fit into the field: Verify that value's bits that do not fit in the field are all zeroes. */
   3855     } else if (finfop->len > 32) {
   3856         SHR_BITCLR_RANGE(regval, finfop->bp + 32, finfop->len - 32);
   3857         SHR_BITCOPY_RANGE(regval, finfop->bp, &value, 0, 32);
   3858     } else {
   3859         if (finfop->len < 32 && value >= (((uint32)1) << finfop->len)) {
   3860 #if !defined(SOC_NO_NAMES)
   3861             LOG_CLI((BSL_META_U(unit,
   3862                                 "reg %s field %s is too small for value 0x%lx\n"),
   3863                      soc_reg_name[reg], soc_fieldnames[field],(unsigned long)value));
   3864 #endif
   3865             assert (0);
   3866         }
   3867         SHR_BITCOPY_RANGE(regval, finfop->bp, &value, 0, finfop->len);
   3868     }
   3869 
   3870 }
   3871 
   3872 
   3873 /* 
   3874  * Function:     soc_reg_above_64_field64_set
   3875  * Purpose:      Set the value of a register's field; field must be <= 64 bits, any register size supported
   3876  * Parameters:
   3877  * Returns:      void
   3878  */
   3879 void
   3880 soc_reg_above_64_field64_set(int unit, soc_reg_t reg, soc_reg_above_64_val_t regval,
   3881                             soc_field_t field, uint64 value)
   3882 {
   3883     soc_field_info_t *finfop;
   3884     uint32 value32;
   3885 
   3886     if (!SOC_REG_IS_VALID(unit, reg)) {
   3887 #if !defined(SOC_NO_NAMES)
   3888         LOG_CLI((BSL_META_U(unit,
   3889                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3890 #endif
   3891         assert(SOC_REG_IS_VALID(unit, reg));
   3892     }
   3893 
   3894     SOC_FIND_FIELD(field,
   3895                    SOC_REG_INFO(unit, reg).fields,
   3896                    SOC_REG_INFO(unit, reg).nFields,
   3897                    finfop);
   3898     if (finfop == NULL) {
   3899 #if !defined(SOC_NO_NAMES)
   3900         LOG_CLI((BSL_META_U(unit,
   3901                             "reg %s field %s is invalid\n"),
   3902                  soc_reg_name[reg], soc_fieldnames[field]));
   3903 #endif
   3904         assert(finfop);
   3905     /* Check if the field value will fit into the field: Verify that value's bits that do not fit in the field are all zeroes. */
   3906     } else if (finfop->len > 64) {
   3907         SHR_BITCLR_RANGE(regval, finfop->bp + 64, finfop->len - 64);
   3908 
   3909         value32 = COMPILER_64_LO(value);
   3910         SHR_BITCOPY_RANGE(regval, finfop->bp, &value32, 0, 32);
   3911 
   3912         value32 = COMPILER_64_HI(value);
   3913         SHR_BITCOPY_RANGE(regval, finfop->bp + 32, &value32, 0, 32);
   3914 
   3915     } else if (finfop->len <= 32 ) {
   3916         if (finfop->len < 32 && COMPILER_64_LO(value) >= (((uint32)1) << finfop->len)) {
   3917 #if !defined(SOC_NO_NAMES)
   3918             LOG_CLI((BSL_META_U(unit,
   3919                                 "reg %s field %s is too small for value 0x%lx\n"),
   3920                      soc_reg_name[reg], soc_fieldnames[field],(unsigned long)COMPILER_64_LO(value)));
   3921 #endif
   3922             assert (0);
   3923         }
   3924         value32 = COMPILER_64_LO(value);
   3925         SHR_BITCOPY_RANGE(regval, finfop->bp, &value32, 0, finfop->len);
   3926     } else { /*32<field lengh<=64*/
   3927         if (finfop->len < 64 && COMPILER_64_HI(value) >= (((uint32)1) << (finfop->len - 32))) {
   3928 #if !defined(SOC_NO_NAMES)
   3929             LOG_CLI((BSL_META_U(unit,
   3930                                 "reg %s field %s is too small for value 0x%lx\n"),
   3931                      soc_reg_name[reg], soc_fieldnames[field],(unsigned long)COMPILER_64_HI(value)));
   3932 #endif
   3933             assert (0);
   3934         }
   3935         value32 = COMPILER_64_LO(value);
   3936         SHR_BITCOPY_RANGE(regval, finfop->bp, &value32, 0, 32);
   3937 
   3938         value32 = COMPILER_64_HI(value);
   3939         SHR_BITCOPY_RANGE(regval, finfop->bp + 32, &value32, 0, finfop->len - 32);
   3940 
   3941     }
   3942 
   3943 }
   3944 #define        VALUE_TOO_BIG_FOR_FIELD64(mask)        (!COMPILER_64_IS_ZERO(mask))
   3945 
   3946 /*
   3947  * Function:     soc_reg64_field_validate
   3948  * Purpose:      Validate the value of a register's field.
   3949  * Parameters:
   3950  * Returns:      SOC_E_XXX
   3951  */
   3952 int
   3953 soc_reg64_field_validate(int unit, soc_reg_t reg, soc_field_t field, uint64 value)
   3954 {
   3955     soc_field_info_t *finfop;
   3956     uint64           mask;
   3957 
   3958     if (!SOC_REG_IS_VALID(unit, reg)) {
   3959 #if !defined(SOC_NO_NAMES)
   3960         LOG_CLI((BSL_META_U(unit,
   3961                             "reg %s is invalid\n"), soc_reg_name[reg]));
   3962 #endif
   3963         assert(SOC_REG_IS_VALID(unit, reg));
   3964     }
   3965 
   3966     SOC_FIND_FIELD(field,
   3967                    SOC_REG_INFO(unit, reg).fields,
   3968                    SOC_REG_INFO(unit, reg).nFields,
   3969                    finfop);
   3970                    
   3971     if (finfop == NULL) {
   3972 #if !defined(SOC_NO_NAMES)
   3973         LOG_CLI((BSL_META_U(unit,
   3974                             "reg %s field %s is invalid\n"),
   3975                  soc_reg_name[reg], soc_fieldnames[field]));
   3976 #endif
   3977         assert(finfop);
   3978     }
   3979 
   3980     /*
   3981      * COVERITY
   3982      *
   3983      * assert validates the input for NULL
   3984      */
   3985     /* coverity[var_deref_op : FALSE] */
   3986     if (finfop->len < 64) {
   3987         COMPILER_64_ZERO(mask);
   3988         COMPILER_64_ADD_32(mask, 1);
   3989         COMPILER_64_SHL(mask, finfop->len);
   3990         COMPILER_64_SUB_32(mask, 1);
   3991         COMPILER_64_NOT(mask);
   3992         COMPILER_64_AND(mask, value);
   3993         if(VALUE_TOO_BIG_FOR_FIELD64(mask))
   3994           return SOC_E_PARAM;
   3995 
   3996     } 
   3997     
   3998     return SOC_E_NONE;
   3999 }
   4000 
   4001 /*
   4002  * Function:     soc_reg64_field_set
   4003  * Purpose:      Set the value of a register's field.
   4004  * Parameters:
   4005  * Returns:      void
   4006  */
   4007 void
   4008 soc_reg64_field_set(int unit, soc_reg_t reg, uint64 *regval,
   4009                     soc_field_t field, uint64 value)
   4010 {
   4011     soc_field_info_t *finfop;
   4012     uint64           mask, tmp;
   4013 
   4014     if (!SOC_REG_IS_VALID(unit, reg)) {
   4015 #if !defined(SOC_NO_NAMES)
   4016         LOG_CLI((BSL_META_U(unit,
   4017                             "reg %s is invalid\n"), soc_reg_name[reg]));
   4018 #endif
   4019         assert(SOC_REG_IS_VALID(unit, reg));
   4020     }
   4021 
   4022     SOC_FIND_FIELD(field,
   4023                    SOC_REG_INFO(unit, reg).fields,
   4024                    SOC_REG_INFO(unit, reg).nFields,
   4025                    finfop);
   4026     if (finfop == NULL) {
   4027 #if !defined(SOC_NO_NAMES)
   4028         LOG_CLI((BSL_META_U(unit,
   4029                             "reg %s field %s is invalid\n"),
   4030                  soc_reg_name[reg], soc_fieldnames[field]));
   4031 #endif
   4032         assert(finfop);
   4033     }
   4034 
   4035     /*
   4036      * COVERITY
   4037      *
   4038      * assert validates the input for NULL
   4039      */
   4040     /* coverity[var_deref_op : FALSE] */
   4041     if (finfop->len < 64) {
   4042         COMPILER_64_SET(mask, 0, 1);
   4043         COMPILER_64_SHL(mask, finfop->len);
   4044         COMPILER_64_SUB_32(mask, 1);
   4045 #ifndef NDEBUG
   4046         /* assert(!VALUE_TOO_BIG_FOR_FIELD); */
   4047         tmp = mask;
   4048         COMPILER_64_NOT(tmp);
   4049         COMPILER_64_AND(tmp, value);
   4050         assert(!VALUE_TOO_BIG_FOR_FIELD64(tmp));
   4051 #endif
   4052     } else {
   4053         COMPILER_64_SET(mask, -1, -1);
   4054     }
   4055 
   4056     /* *regval = (*regval & ~(mask << finfop->bp)) | value << finfop->bp; */
   4057     tmp = mask;
   4058     COMPILER_64_SHL(tmp, finfop->bp);
   4059     COMPILER_64_NOT(tmp);
   4060     COMPILER_64_AND(*regval, tmp);
   4061     COMPILER_64_SHL(value, finfop->bp);
   4062     COMPILER_64_OR(*regval, value);
   4063 }
   4064 
   4065 /* 
   4066  * Function:     soc_reg64_field32_set
   4067  * Purpose:      Set the value of a register's field; field must be < 32 bits
   4068  * Parameters:
   4069  * Returns:      void
   4070  */
   4071 void
   4072 soc_reg64_field32_set(int unit, soc_reg_t reg, uint64 *regval,
   4073                       soc_field_t field, uint32 value)
   4074 {
   4075     soc_field_info_t *finfop;
   4076     uint64           mask, tmp;
   4077 
   4078     if (!SOC_REG_IS_VALID(unit, reg)) {
   4079 #if !defined(SOC_NO_NAMES)
   4080         LOG_CLI((BSL_META_U(unit,
   4081                             "reg %s is invalid\n"), soc_reg_name[reg]));
   4082 #endif
   4083         assert(SOC_REG_IS_VALID(unit, reg));
   4084     }
   4085 
   4086     SOC_FIND_FIELD(field,
   4087                    SOC_REG_INFO(unit, reg).fields,
   4088                    SOC_REG_INFO(unit, reg).nFields,
   4089                    finfop);
   4090     if (finfop == NULL) {
   4091 #if !defined(SOC_NO_NAMES)
   4092         LOG_CLI((BSL_META_U(unit,
   4093                             "reg %s field %s is invalid\n"),
   4094                  soc_reg_name[reg], soc_fieldnames[field]));
   4095 #endif
   4096         assert(finfop);
   4097     }
   4098 
   4099     /*
   4100      * COVERITY
   4101      *
   4102      * assert validates the input for NULL
   4103      */
   4104     /* coverity[var_deref_op : FALSE] */
   4105     if (finfop->len < 64) {
   4106         COMPILER_64_SET(mask, 0, 1);
   4107         COMPILER_64_SHL(mask, finfop->len);
   4108         COMPILER_64_SUB_32(mask, 1);
   4109     } else {
   4110         COMPILER_64_SET(mask, -1, -1);
   4111     }
   4112 
   4113     /* Mask value to fit in field.  Needed if passed-in value was signed. */
   4114     value &= COMPILER_64_LO(mask);
   4115 
   4116     /* *regval = (*regval & ~(mask << finfop->bp)) | value << finfop->bp; */
   4117     COMPILER_64_SHL(mask, finfop->bp);
   4118     COMPILER_64_NOT(mask);
   4119     COMPILER_64_AND(*regval, mask);
   4120     if (value != 0) {
   4121         COMPILER_64_SET(tmp, 0, value);
   4122         COMPILER_64_SHL(tmp, finfop->bp);
   4123         COMPILER_64_OR(*regval, tmp);
   4124     }
   4125 }
   4126 
   4127 /*
   4128  * Function:    soc_reg_addr
   4129  * Purpose:     calculate the address of a register
   4130  * Parameters:
   4131  *              unit  switch unit
   4132  *              reg   register number
   4133  *              port  port number or REG_PORT_ANY
   4134  *              index array index (or cos number)
   4135  * Returns:     register address suitable for soc_reg_read and friends
   4136  * Notes:       the block number to access is determined by the register
   4137  *              and the port number
   4138  *
   4139  * cpureg       00SSSSSS 00000000 0000RRRR RRRRRRRR
   4140  * genreg       00SSSSSS BBBB1000 0000RRRR RRRRRRRR
   4141  * portreg      00SSSSSS BBBB00PP PPPPRRRR RRRRRRRR
   4142  * cosreg       00SSSSSS BBBB01CC CCCCRRRR RRRRRRRR
   4143  *
   4144  * all regs of bcm88230
   4145  *              00000000 00001000 0000RRRR RRRRRRRR
   4146  *
   4147  * where        B+ is the 4 bit block number
   4148  *              P+ is the 6 bit port number (within a block or chip wide)
   4149  *              C+ is the 6 bit class of service
   4150  *              R+ is the 12 bit register number
   4151  *              S+ is the 6 bit Pipe stage
   4152  */
   4153 uint32
   4154 soc_reg_addr(int unit, soc_reg_t reg, int port, int index)
   4155 {
   4156     uint32            base;   /* base address from reg_info */
   4157     int               block = -1;  /* block number */
   4158     int               pindex = -1; /* register port/cos field */
   4159     int               gransh; /* index granularity shift */
   4160     soc_block_types_t regblktype;
   4161     soc_block_t       portblktype;
   4162     int               phy_port;
   4163     int               instance_mask = 0;
   4164     int               instance = -1;
   4165     
   4166 
   4167 #ifdef BCM_TOMAHAWK3_SUPPORT
   4168     soc_reg_t reg_excep_list[]={MMU_CRB_DEVICE_PORT_TO_MMU_PORT_MAPPINGr,
   4169                                 MMU_RQE_REPL_PORT_AGG_MAPr};
   4170     int reg_index, num_regs, add_exception = 0;
   4171 #endif
   4172     
   4173     if (SOC_CONTROL(unit)->soc_reg_watch) {
   4174         if (SOC_CONTROL(unit)->prev_reg != reg) {
   4175             LOG_CLI((BSL_META_U(unit, "%d:%s REG: %s\n"),
   4176                        unit, BSL_FUNC, SOC_REG_NAME(unit, reg)));
   4177             SOC_CONTROL(unit)->prev_reg = reg;
   4178         }
   4179     }
   4180 
   4181     if (!SOC_REG_IS_VALID(unit, reg)) {
   4182 #if !defined(SOC_NO_NAMES)
   4183         LOG_CLI((BSL_META_U(unit,
   4184                             "reg %s is invalid\n"), soc_reg_name[reg]));
   4185 #endif
   4186         assert(SOC_REG_IS_VALID(unit, reg));
   4187     }
   4188 
   4189 #ifdef DNX_TEST_CHIPS_SUPPORT
   4190     if (SOC_IS_DNX_TEST_DEVICE(unit)
   4191 #if defined(PLISIM)
   4192         && !SAL_BOOT_PLISIM
   4193 #endif
   4194         ) {
   4195         return soc_dnxtestchip_reg_addr(unit, reg, port, index);
   4196     }
   4197 #endif /* DNX_TEST_CHIPS_SUPPORT */
   4198 
   4199 #define SOC_REG_ADDR_INVALID_PORT 0 /* for asserts */
   4200 
   4201     {
   4202         portblktype = SOC_BLK_PORT;
   4203     }
   4204 
   4205     regblktype = SOC_REG_INFO(unit, reg).block;
   4206     if(REG_PORT_ANY != port) {
   4207         instance_mask = port & SOC_REG_ADDR_INSTANCE_MASK;
   4208         port &= (~SOC_REG_ADDR_INSTANCE_MASK);
   4209     }
   4210     
   4211 
   4212     if(!instance_mask) {
   4213         if (port >= 0) {
   4214             if (SOC_BLOCK_IN_LIST(regblktype, portblktype)) {
   4215                 assert(SOC_PORT_VALID(unit, port));
   4216                 if (soc_feature(unit, soc_feature_logical_port_num)) {
   4217                     /*
   4218                      * COVERITY
   4219                      *
   4220                      * assert validates the port
   4221                      */
   4222                     /* coverity[overrun-local : FALSE] */
   4223                     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   4224                 } else {
   4225                     phy_port = port;
   4226                 }
   4227                 block = SOC_PORT_BLOCK(unit, phy_port);
   4228                 pindex = SOC_PORT_BINDEX(unit, phy_port);
   4229             } else {
   4230                 block = pindex = -1; /* multiple non-port block */
   4231             }
   4232         } else if (port == REG_PORT_ANY) {
   4233             block = pindex = -1;
   4234             if(soc_portreg == SOC_REG_INFO(unit, reg).regtype ) {
   4235                 PBMP_ALL_ITER(unit, port) { /* try enabled ports */
   4236                     if (soc_feature(unit, soc_feature_logical_port_num)) {
   4237                         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   4238                     } else {
   4239                         phy_port = port;
   4240                     }
   4241                     block = SOC_PORT_BLOCK(unit, phy_port);
   4242                     pindex = SOC_PORT_BINDEX(unit, phy_port);
   4243                     if (SOC_BLOCK_IN_LIST(regblktype, portblktype)) { /* match reg type */
   4244                         if (SOC_BLOCK_IS_TYPE(unit, block, regblktype)) {
   4245                             break;
   4246                         }
   4247                         block = -1;
   4248                     } else { /* match any port */
   4249                         break;
   4250                     }
   4251                 }
   4252                 if (block < 0) {
   4253                     assert(SOC_REG_ADDR_INVALID_PORT); /* invalid port */
   4254                 }
   4255             }
   4256         } else {
   4257         port &= ~SOC_REG_ADDR_INSTANCE_MASK;
   4258         block = pindex = -1;
   4259         }
   4260     }
   4261 
   4262         if (REG_PORT_ANY == port ||instance_mask || !SOC_BLOCK_IN_LIST(regblktype, portblktype)) {
   4263             switch (SOC_REG_FIRST_BLK_TYPE(regblktype)) {
   4264             case SOC_BLK_ARL:
   4265                 block = ARL_BLOCK(unit);
   4266                 break;
   4267             case SOC_BLK_IPIPE:
   4268                 block = IPIPE_BLOCK(unit);
   4269                 break;
   4270             case SOC_BLK_IPIPE_HI:
   4271                 block = IPIPE_HI_BLOCK(unit);
   4272                 break;
   4273             case SOC_BLK_EPIPE:
   4274                 block = EPIPE_BLOCK(unit);
   4275                 break;
   4276             case SOC_BLK_EPIPE_HI:
   4277                 block = EPIPE_HI_BLOCK(unit);
   4278                 break;
   4279             case SOC_BLK_IGR:
   4280                 block = IGR_BLOCK(unit);
   4281                 break;
   4282             case SOC_BLK_EGR:
   4283                 block = EGR_BLOCK(unit);
   4284                 break;
   4285             case SOC_BLK_BSE:
   4286                 block = BSE_BLOCK(unit);
   4287                 break;
   4288             case SOC_BLK_CSE:
   4289                 block = CSE_BLOCK(unit);
   4290                 break;
   4291             case SOC_BLK_HSE:
   4292                 block = HSE_BLOCK(unit);
   4293                 break;
   4294             case SOC_BLK_BSAFE:
   4295                 block = BSAFE_BLOCK(unit);
   4296                 break;
   4297             case SOC_BLK_OTPC:
   4298                 instance = 0;
   4299                 block = OTPC_BLOCK(unit, instance);
   4300                 break;
   4301             case SOC_BLK_MMU:
   4302                 block = MMU_BLOCK(unit);
   4303                 break;
   4304             case SOC_BLK_MCU:
   4305                 block = MCU_BLOCK(unit);
   4306                 break;
   4307             case SOC_BLK_CMIC:
   4308                 block = CMIC_BLOCK(unit);
   4309                 break;
   4310             case SOC_BLK_IPROC:
   4311                 block = IPROC_BLOCK(unit);
   4312                 break;
   4313             case SOC_BLK_CRYPTO:
   4314                 block = CRYPTO_BLOCK(unit);
   4315                 break;
   4316             case SOC_BLK_ESM:
   4317                 block = ESM_BLOCK(unit);
   4318                 break;
   4319             case SOC_BLK_PORT_GROUP4:
   4320                 block = PG4_BLOCK(unit, port);
   4321                 break;
   4322             case SOC_BLK_PORT_GROUP5:
   4323                 block = PG5_BLOCK(unit, port);
   4324                 break;
   4325             case SOC_BLK_TOP:
   4326                 block = TOP_BLOCK(unit);
   4327                 break;
   4328             case SOC_BLK_LLS:
   4329                 block = LLS_BLOCK(unit);
   4330                 break;
   4331             case SOC_BLK_CES:
   4332                 block = CES_BLOCK(unit);
   4333                 break;
   4334             case SOC_BLK_CI:
   4335                 if (port >= 3) {
   4336                     assert(SOC_REG_ADDR_INVALID_PORT); /* invalid instance */
   4337                 } else {
   4338                     block = CI_BLOCK(unit, port);
   4339                 }
   4340                 break;
   4341             case SOC_BLK_IL:
   4342                 if (SOC_IS_SHADOW(unit)) {
   4343                     if (port == 9) {
   4344                         block = IL0_BLOCK(unit);
   4345                     } else if (port == 13) {
   4346                         block = IL1_BLOCK(unit);
   4347                     }
   4348                     pindex = 0;
   4349                 }
   4350                 break;
   4351             case SOC_BLK_MS_ISEC:
   4352                 if (SOC_IS_SHADOW(unit)) {
   4353                     if (port >= 1 && port <= 4) {
   4354                         block = MS_ISEC0_BLOCK(unit);
   4355                         pindex = port - 1;
   4356                     } else {
   4357                         block = MS_ISEC1_BLOCK(unit);
   4358                         pindex = port - 5;
   4359                     }
   4360                 }
   4361                 break;
   4362             case SOC_BLK_MS_ESEC:
   4363                 if (SOC_IS_SHADOW(unit)) {
   4364                     if (port >= 1 && port <= 4) {
   4365                         block = MS_ESEC0_BLOCK(unit);
   4366                         pindex = port - 1;
   4367                     } else {
   4368                         block = MS_ESEC1_BLOCK(unit);
   4369                         pindex = port - 5;
   4370                     }
   4371                 }
   4372                 break;
   4373             case SOC_BLK_IECELL:
   4374 #if defined(BCM_METROLITE_SUPPORT)
   4375                 if (SOC_IS_METROLITE(unit)) {
   4376                     soc_ml_iecell_port_reg_blk_idx_get(unit, port,
   4377                         SOC_BLK_IECELL, &block, &pindex);
   4378                 } else
   4379 #endif
   4380 #if defined (BCM_SABER2_SUPPORT)
   4381                 if (SOC_IS_SABER2(unit)) {
   4382                     soc_sb2_iecell_port_reg_blk_idx_get(unit, port,
   4383                         SOC_BLK_IECELL, &block, &pindex);
   4384                 } 
   4385 #endif
   4386                 break;
   4387             case SOC_BLK_TXLP:
   4388 #if defined(BCM_KATANA2_SUPPORT)
   4389                 if (SOC_IS_KATANA2(unit)) {
   4390                     soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   4391                         SOC_BLK_TXLP, &block, &pindex);
   4392                 }
   4393 #endif
   4394                 break;
   4395             case SOC_BLK_RXLP:
   4396 #if defined(BCM_KATANA2_SUPPORT)
   4397                 if (SOC_IS_KATANA2(unit)) {
   4398                     soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   4399                         SOC_BLK_RXLP, &block, &pindex);
   4400                 }
   4401 #endif
   4402                 break;
   4403             case SOC_BLK_OAMP:
   4404 #if defined(BCM_SABER2_SUPPORT) || defined (BCM_METROLITE_SUPPORT)
   4405                 block = OAMP_BLOCK(unit);
   4406 #endif
   4407                 break;
   4408 
   4409             case SOC_BLK_CW:
   4410                 if (SOC_IS_SHADOW(unit)) {
   4411                     block = CW_BLOCK(unit);
   4412                 }
   4413                 break;
   4414             case SOC_BLK_ECI:
   4415                 block = ECI_BLOCK(unit);
   4416                 break;
   4417             case SOC_BLK_OCCG:
   4418                 block = OCCG_BLOCK(unit);
   4419                 break;
   4420             case SOC_BLK_DCH:
   4421                 if(REG_PORT_ANY != port)
   4422                     block = DCH_BLOCK(unit, port);
   4423                 else
   4424                     block = DCH_BLOCK(unit, 0);
   4425                 break;
   4426             case SOC_BLK_DCL:
   4427                 if(REG_PORT_ANY != port)
   4428                     block = DCL_BLOCK(unit, port);
   4429                 else
   4430                     block = DCL_BLOCK(unit, 0);
   4431                 break;
   4432             case SOC_BLK_DCMA:
   4433                 if(REG_PORT_ANY != port)
   4434                     block = DCMA_BLOCK(unit, port);
   4435                 else
   4436                     block = DCMA_BLOCK(unit, 0);
   4437                 break;
   4438             case SOC_BLK_DCMB:
   4439                 if(REG_PORT_ANY != port)
   4440                     block = DCMB_BLOCK(unit, port);
   4441                 else
   4442                     block = DCMB_BLOCK(unit, 0);
   4443                 break;
   4444             case SOC_BLK_DCMC:
   4445                 block = DCMC_BLOCK(unit);
   4446                 break;
   4447             case SOC_BLK_CCS:
   4448                 if(REG_PORT_ANY != port)
   4449                     block = CCS_BLOCK(unit, port);
   4450                 else
   4451                     block = CCS_BLOCK(unit, 0);
   4452                 break;
   4453             case SOC_BLK_RTP:
   4454                 block = RTP_BLOCK(unit);
   4455                 break;
   4456             case SOC_BLK_MESH_TOPOLOGY:
   4457                 block = MESH_TOPOLOGY_BLOCK(unit);
   4458                 break;
   4459             case SOC_BLK_FMAC:
   4460                 if(REG_PORT_ANY != port)
   4461                     block = FMAC_BLOCK(unit, port);
   4462                 else
   4463                     block = FMAC_BLOCK(unit, 0);
   4464                 break;
   4465             case SOC_BLK_IPSEC_SPU_WRAPPER_TOP:
   4466                 if(REG_PORT_ANY != port)
   4467                     block = IPSEC_SPU_WRAPPER_TOP_BLOCK(unit, port);
   4468                 else
   4469                     block = IPSEC_SPU_WRAPPER_TOP_BLOCK(unit, 0);
   4470                 break;
   4471             case SOC_BLK_FSRD:
   4472                 if(REG_PORT_ANY != port)
   4473                     block = FSRD_BLOCK(unit, port);
   4474                 else
   4475                     block = FSRD_BLOCK(unit, 0);
   4476                 break;
   4477             case SOC_BLK_HBC:
   4478                 if(REG_PORT_ANY != port)
   4479                     block = HBC_BLOCK(unit, port);
   4480                 else
   4481                     block = HBC_BLOCK(unit, 0);
   4482                 break;
   4483             case SOC_BLK_BRDC_FMACH:
   4484                 block = BRDC_FMACH_BLOCK(unit);
   4485                 break;
   4486             case SOC_BLK_BRDC_FMACL:
   4487                 block = BRDC_FMACL_BLOCK(unit);
   4488                 break;
   4489             case SOC_BLK_BRDC_FSRD:
   4490                 block = BRDC_FSRD_BLOCK(unit);
   4491                 break;
   4492             case SOC_BLK_BRDC_HBC:
   4493                 block = BRDC_HBC_BLOCK(unit);
   4494                 break;
   4495             case SOC_BLK_MXQ:
   4496                 if(REG_PORT_ANY != port)
   4497                     block = MXQ_BLOCK(unit, port);
   4498                 else
   4499                     block = MXQ_BLOCK(unit, 0);
   4500                 break;
   4501             case SOC_BLK_PLL:
   4502                 block = PLL_BLOCK(unit);
   4503                 break;
   4504             case SOC_BLK_NIF:
   4505                 block = NIF_BLOCK(unit);
   4506                 break;
   4507             default:
   4508                     block = -1; /* unknown non-port block */
   4509                     break;
   4510             }
   4511         }
   4512 
   4513     assert(block >= 0); /* block must be valid */
   4514 
   4515     /* determine final block, pindex, and index */
   4516     gransh = 0;
   4517     switch (SOC_REG_INFO(unit, reg).regtype) {
   4518     case soc_cpureg:
   4519     case soc_mcsreg:
   4520     case soc_iprocreg:
   4521         block = -1;
   4522         pindex = 0;
   4523         gransh = 2; /* 4 byte granularity */
   4524         break;
   4525     case soc_portreg:
   4526         if (!SOC_BLOCK_IN_LIST(regblktype, portblktype) &&
   4527             !(SOC_IS_SHADOW(unit) &&
   4528              (SOC_BLOCK_IS(regblktype, SOC_BLK_MS_ISEC) || 
   4529               SOC_BLOCK_IS(regblktype, SOC_BLK_MS_ESEC)))
   4530 #if defined(BCM_KATANA2_SUPPORT)
   4531               && !(SOC_IS_KATANA2(unit) &&
   4532              (SOC_BLOCK_IS(regblktype, SOC_BLK_TXLP) || 
   4533               SOC_BLOCK_IS(regblktype, SOC_BLK_RXLP)))
   4534 #endif
   4535 /* Need to check : SABER2 */
   4536 #if defined(BCM_SABER2_SUPPORT)
   4537               && !(SOC_IS_SABER2(unit) &&
   4538              (SOC_BLOCK_IS(regblktype, SOC_BLK_IECELL)))
   4539 #endif
   4540             ) {
   4541             if (soc_feature(unit, soc_feature_logical_port_num) &&
   4542                 block == MMU_BLOCK(unit)) {
   4543 #ifdef BCM_TOMAHAWK3_SUPPORT
   4544                 /*MMU register with device port indexing*/
   4545                 num_regs = sizeof(reg_excep_list) / sizeof(soc_reg_t);
   4546                 for (reg_index = 0;reg_index < num_regs; reg_index++) {
   4547                     if (reg_excep_list[reg_index] == reg) {
   4548                         add_exception = 1;
   4549                         break;
   4550                     }
   4551                 }
   4552                 if (add_exception) {
   4553                             pindex = port;
   4554                 } else
   4555 #endif
   4556                 {
   4557                 /* coverity[negative_returns : FALSE] */
   4558                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   4559                 pindex = SOC_INFO(unit).port_p2m_mapping[phy_port];
   4560                 }
   4561             } else {
   4562                 pindex = port;
   4563             }
   4564         }
   4565         break;
   4566     case soc_cosreg:
   4567         assert(index >= 0 && index < NUM_COS(unit));
   4568         pindex = index;
   4569         index = 0;
   4570         break;
   4571     case soc_customreg:
   4572     case soc_genreg:
   4573         pindex = 0;
   4574         break;
   4575     default:
   4576         assert(0); /* unknown register type */
   4577         break;
   4578     }
   4579 
   4580     /* put together address: base|block|pindex + index */
   4581     base = SOC_REG_INFO(unit, reg).offset;
   4582     LOG_VERBOSE(BSL_LS_SOC_REG,
   4583                 (BSL_META_U(unit,
   4584                             "base: %x "), base));
   4585         
   4586     if (block >= 0) {
   4587         base |= ((SOC_BLOCK2OFFSET(unit, block) & 0xf) << SOC_BLOCK_BP) |
   4588                  (((SOC_BLOCK2OFFSET(unit, block) >> 4) & 0x3) <<
   4589                  SOC_BLOCK_MSB_BP);
   4590     }
   4591     
   4592     if (pindex) {
   4593         base |= pindex << SOC_REGIDX_BP;
   4594     }
   4595     
   4596     if (SOC_REG_IS_ARRAY(unit, reg)) {
   4597         assert(index >= SOC_REG_INFO(unit, reg).first_array_index && index < SOC_REG_NUMELS(unit, reg) + SOC_REG_INFO(unit, reg).first_array_index);
   4598 #if defined(BCM_SABER2_SUPPORT)
   4599         if (SOC_IS_SABER2(unit) && block == OAMP_BLOCK(unit)) {
   4600             base += (index - SOC_REG_INFO(unit, reg).first_array_index)*(SOC_REG_ELEM_SKIP(unit, reg) << 8);
   4601         } else
   4602 #endif
   4603         {
   4604         base += (index - SOC_REG_INFO(unit, reg).first_array_index)*SOC_REG_ELEM_SKIP(unit, reg);
   4605         }
   4606     } else if (index && SOC_REG_ARRAY(unit, reg)) {
   4607         assert(index >= 0 && index < SOC_REG_NUMELS(unit, reg));
   4608         if (index && SOC_REG_ARRAY2(unit, reg)) {
   4609             base += ((index*2) << gransh);
   4610         } else if (index && SOC_REG_ARRAY4(unit, reg)) {
   4611             base += ((index * 4) << gransh);
   4612         } else {
   4613             base += (index << gransh);
   4614         }
   4615     }
   4616     LOG_VERBOSE(BSL_LS_SOC_REG,
   4617                 (BSL_META_U(unit,
   4618                             "addr: %x, block: %d, index: %d, pindex: %d, gransh: %d\n"),
   4619                  base, block, index, pindex, gransh));
   4620     return base;
   4621 }
   4622 
   4623 /*
   4624  * Function:    soc_reg_xaddr_get
   4625  * Purpose:     calculate the address of a register
   4626  * Parameters:
   4627  *     unit       - SOC unit number
   4628  *     reg        - Register number
   4629  *     port       - Port number or REG_PORT_ANY or SOC_CORE_ALL for DNX blockswith an instance per core
   4630  *     index      - Array index (or cos number)
   4631  *     options    - Flag to indicate special handling to calculate
   4632  *                  the HW register address: SOC_REG_ADDR_OPTION_xxx
   4633  *     access_info- (OUT) Register access info: address, schan block IDs, access type
   4634  *
   4635  * Returns:     success
   4636  * Notes:       the block number/s to access is determined by the register
   4637  *              and the port number
   4638  */
   4639 int soc_reg_xaddr_get(int unit, soc_reg_t reg, int port, int index,
   4640                       uint32 options, soc_reg_access_info_t *access_info)
   4641 {
   4642     uint32            base;        /* base address from reg_info */
   4643     int               block = -1;  /* block number */
   4644     int               pindex = -1; /* register port/cos field */
   4645     int               gransh;      /* index granularity shift */
   4646     soc_block_types_t regblktype;
   4647     soc_block_t       portblktype;
   4648     uint32            phy_port = 0;
   4649     int               instance = -1, i;
   4650     int               instance_mask = 0, block_id_mask = 0, schan_id_mask = 0, phy_acc_mask = 0;
   4651     int               port_num_blktype;
   4652     int               block_core = 0;
   4653     int               is_write;
   4654     int               preserve_port;
   4655     int               *soc_blocks = NULL;
   4656 #ifdef BCM_TOMAHAWK3_SUPPORT
   4657     soc_reg_t reg_excep_list[]={MMU_CRB_DEVICE_PORT_TO_MMU_PORT_MAPPINGr,
   4658                                 MMU_RQE_REPL_PORT_AGG_MAPr};
   4659     int reg_index, num_regs, add_exception = 0;
   4660     int               stage_id;
   4661 #endif
   4662     
   4663     COMPILER_REFERENCE(is_write);
   4664 
   4665     if (SOC_CONTROL(unit)->soc_reg_watch) {
   4666         if (SOC_CONTROL(unit)->prev_reg != reg) {
   4667             LOG_CLI((BSL_META_U(unit, "%d:%s REG: %s\n"),
   4668                        unit, BSL_FUNC, SOC_REG_NAME(unit, reg)));
   4669             SOC_CONTROL(unit)->prev_reg = reg;
   4670         }
   4671     }
   4672 
   4673 
   4674     if (!soc_feature(unit, soc_feature_new_sbus_format)) {
   4675         access_info->offset = soc_reg_addr(unit, reg, port, index);
   4676         access_info->num_blks = 0;
   4677         return SOC_E_NONE;
   4678     }
   4679     access_info->num_blks = 1;
   4680     
   4681     if (!SOC_REG_IS_VALID(unit, reg)) {
   4682 #if !defined(SOC_NO_NAMES)
   4683         LOG_CLI((BSL_META_U(unit,
   4684                             "reg %s is invalid\n"), soc_reg_name[reg]));
   4685 #endif
   4686         assert(SOC_REG_IS_VALID(unit, reg));
   4687     }
   4688 
   4689 #define SOC_REG_ADDR_INVALID_PORT 0 /* for asserts */
   4690 
   4691     access_info->acc_type = SOC_REG_ACC_TYPE(unit, reg);
   4692 
   4693     portblktype = SOC_BLK_PORT;
   4694     port_num_blktype = SOC_DRIVER(unit)->port_num_blktype > 1 ?
   4695         SOC_DRIVER(unit)->port_num_blktype : 1;
   4696 
   4697     access_info->blk_list[0] = 0;/* not really needed, just to avoid coverity defect */
   4698 
   4699     /* Get options */
   4700     is_write = options & SOC_REG_ADDR_OPTION_WRITE;
   4701     preserve_port = options & SOC_REG_ADDR_OPTION_PRESERVE_PORT;
   4702 
   4703     if ((REG_PORT_ANY != port) && (SOC_CORE_ALL != port)) {
   4704         instance_mask = port & SOC_REG_ADDR_INSTANCE_MASK;
   4705         block_id_mask = port & SOC_REG_ADDR_BLOCK_ID_MASK;
   4706         schan_id_mask = port & SOC_REG_ADDR_SCHAN_ID_MASK;
   4707         phy_acc_mask = port & SOC_REG_ADDR_PHY_ACC_MASK;
   4708         port &= (~ (SOC_REG_ADDR_INSTANCE_MASK | SOC_REG_ADDR_BLOCK_ID_MASK 
   4709                     | SOC_REG_ADDR_SCHAN_ID_MASK | SOC_REG_ADDR_PHY_ACC_MASK));
   4710     }
   4711 
   4712 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DNX_SUPPORT)
   4713     /* Use core broadcast writes when possible for more efficient writes */
   4714     if (SOC_IS_ARAD(unit) || SOC_IS_DNX(unit) || SOC_IS_DNXF(unit)) {
   4715         instance = block_core = (port == SOC_CORE_ALL || port == REG_PORT_ANY) ?
   4716                      (is_write ? SOC_CORE_ALL : 0) : port;
   4717     }
   4718 #endif /* BCM_PETRA_SUPPORT || BCM_DNX_SUPPORT */
   4719     
   4720     regblktype = SOC_REG_INFO(unit, reg).block;
   4721 
   4722 #ifdef BCM_DNX_SUPPORT
   4723     if (SOC_IS_DNX(unit) && (soc_customreg == SOC_REG_INFO(unit,reg).regtype)
   4724         && (SOC_REG_FIRST_BLK_TYPE(regblktype) == SOC_BLK_ILE)
   4725         && (port != SOC_CORE_ALL) && (port != SOC_BLOCK_ALL)) {
   4726         /* for custom register, ILKN, the instance is meaningless */
   4727         instance = block_core = 0;
   4728     }
   4729 #endif
   4730 
   4731 #ifdef BCM_TOMAHAWK3_SUPPORT
   4732     if (SOC_IS_TOMAHAWK3(unit)) {
   4733        /* Since TH3 has the dummy blocks CDMAC defined in the regsfile, we need
   4734           to assign them to the CDPORT block */
   4735         if (regblktype[0] == SOC_BLK_CDMAC) {
   4736             regblktype[0] = SOC_BLK_CDPORT;
   4737         }
   4738     }
   4739 #endif
   4740 
   4741     if (!block_id_mask && !schan_id_mask && !instance_mask && port >= 0) {
   4742         if (SOC_BLOCK_IN_LIST(regblktype, portblktype)) {
   4743             if (preserve_port || phy_acc_mask) {
   4744                 phy_port = port;
   4745 
   4746 #ifdef BCM_JERICHO_SUPPORT
   4747                 if (SOC_IS_JERICHO(unit)) {
   4748                     /* translate phy port to phy port with qsgmii offset */
   4749                     SOC_IF_ERROR_RETURN(MBCM_DPP_SOC_DRIVER_CALL(unit, mbcm_dpp_qsgmii_offsets_add, (unit, phy_port, &phy_port)));
   4750                 }
   4751 #endif /* BCM_JERICHO_SUPPORT */
   4752 
   4753             } else {
   4754                 assert(SOC_PORT_VALID(unit, port)); 
   4755                 if (soc_feature(unit, soc_feature_logical_port_num)) {
   4756                     /*
   4757                      * COVERITY
   4758                      *
   4759                      * assert validates the port
   4760                      */
   4761                     /* coverity[overrun-local : FALSE] */ 
   4762                     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   4763                 } else {
   4764                     phy_port = port;
   4765                 }
   4766             }
   4767             for (i = 0; i < port_num_blktype; i++) {
   4768 #ifdef BCM_KATANA2_SUPPORT
   4769                 /* Override port blocks with Linkphy Blocks.. */
   4770                 if(SOC_IS_KATANA2(unit) &&
   4771                     (SOC_REG_FIRST_BLK_TYPE(regblktype) == SOC_BLK_TXLP) ) {
   4772                     soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   4773                         SOC_BLK_TXLP, &block, &pindex);
   4774                     break;
   4775                 } else if(SOC_IS_KATANA2(unit) &&
   4776                     (SOC_REG_FIRST_BLK_TYPE(regblktype) == SOC_BLK_RXLP) ) {
   4777                     soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   4778                         SOC_BLK_RXLP, &block, &pindex);
   4779                     break;
   4780 #ifdef BCM_METROLITE_SUPPORT
   4781                 } else if((SOC_IS_METROLITE(unit)) &&
   4782                     (SOC_REG_FIRST_BLK_TYPE(regblktype) == SOC_BLK_IECELL)) {
   4783                     soc_ml_iecell_port_reg_blk_idx_get(unit, port,
   4784                         SOC_BLK_IECELL, &block, &pindex);
   4785                     break;
   4786 #endif
   4787 #if defined (BCM_SABER2_SUPPORT)
   4788                 } else if((SOC_IS_SABER2(unit)) &&
   4789                     (SOC_REG_FIRST_BLK_TYPE(regblktype) == SOC_BLK_IECELL)) {
   4790                     soc_sb2_iecell_port_reg_blk_idx_get(unit, port,
   4791                         SOC_BLK_IECELL, &block, &pindex);
   4792                     break;
   4793 #endif
   4794                 }
   4795 #endif
   4796 #ifdef BCM_GREYHOUND_SUPPORT
   4797                 if(SOC_IS_GREYHOUND(unit) &&
   4798                     (SOC_REG_FIRST_BLK_TYPE(regblktype) == SOC_BLK_XLPORT) ) {
   4799                     if (soc_greyhound_pgw_reg_blk_index_get(unit, reg, port, NULL,
   4800                         &block, &pindex, 0) > 0){
   4801                         break;
   4802                     }                        
   4803                 }
   4804 #endif
   4805                 block = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   4806 
   4807 #ifdef BCM_APACHE_SUPPORT
   4808                 if (SOC_IS_APACHE(unit)) {
   4809                     SOC_IF_ERROR_RETURN(soc_apache_port_reg_blk_index_get
   4810                                 (unit, port, SOC_REG_FIRST_BLK_TYPE(regblktype), &block));
   4811                 }
   4812 #endif
   4813                 if (block < 0) {
   4814                     break;
   4815                 }
   4816                 if (SOC_BLOCK_IN_LIST(regblktype,
   4817                                       SOC_BLOCK_TYPE(unit, block))) {
   4818                     pindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
   4819                     break;
   4820                 }
   4821                 
   4822                 else if (SOC_IS_JERICHO(unit) && SOC_PORT_IDX_BLOCK(unit, phy_port, i + 1) == -1) {
   4823                     break;
   4824                 }
   4825                 else if (SOC_IS_DNX(unit)) {
   4826                     if( (regblktype[0] == SOC_BLK_CDMAC) && (SOC_BLOCK_TYPE(unit, block) == SOC_BLK_CDPORT) ) {
   4827                         /*
   4828                          * DNX only: get pindex, in case of CDMAC.
   4829                          * SOC_PORT_IDX_BLOCK returns CDPORT, therefore check type of block is CDPORT.
   4830                          */
   4831                         pindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
   4832                         break;
   4833                     }
   4834                 }
   4835             }
   4836         } else {
   4837             block = pindex = -1; /* multiple non-port block */
   4838         }
   4839     } else if (port == REG_PORT_ANY) {
   4840         block = pindex = -1;
   4841         if (SOC_BLOCK_IN_LIST(regblktype, portblktype)) {
   4842             PBMP_ALL_ITER(unit, port) { /* try enabled ports */
   4843                 if (soc_feature(unit, soc_feature_logical_port_num)) {
   4844                     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   4845                 } else {
   4846                     phy_port = port;
   4847                 }
   4848                 for (i = 0; i < port_num_blktype; i++) {
   4849                     block = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   4850                     if (block < 0) {
   4851                         break;
   4852                     }
   4853                     if (SOC_BLOCK_IN_LIST
   4854                         (regblktype, SOC_BLOCK_TYPE(unit, block))) {
   4855                         pindex = SOC_PORT_IDX_BINDEX(unit, phy_port,
   4856                                                      i);
   4857                         break;
   4858                     }
   4859                 }
   4860                 if (i == port_num_blktype) {
   4861                     continue;
   4862                 }
   4863                 if (block >= 0) {
   4864                     break;
   4865                 }
   4866             }
   4867             if (block < 0) {
   4868                 assert(SOC_REG_ADDR_INVALID_PORT); /* invalid port */
   4869             }
   4870         } else { /* match any port */
   4871             if (!SOC_IS_SAND(unit)) {
   4872                 PBMP_ALL_ITER(unit, port) { /* try enabled ports */
   4873                     break;
   4874                 }
   4875             }
   4876         }
   4877     } else if (port != SOC_CORE_ALL){
   4878         port &= ~(SOC_REG_ADDR_INSTANCE_MASK | SOC_REG_ADDR_BLOCK_ID_MASK | SOC_REG_ADDR_SCHAN_ID_MASK);
   4879         instance = port;
   4880         block = pindex = -1;
   4881     }
   4882     
   4883 #if defined (BCM_KATANA2_SUPPORT)
   4884     if (SOC_IS_KATANA2(unit)) {
   4885         if (((SOC_BLK_RXLP == SOC_REG_FIRST_BLK_TYPE(regblktype)) || 
   4886              (SOC_BLK_TXLP == SOC_REG_FIRST_BLK_TYPE(regblktype))) &&
   4887             (soc_portreg != SOC_REG_INFO(unit, reg).regtype)) {
   4888             instance_mask = 1;
   4889         }
   4890     }
   4891 #endif
   4892 #if defined (BCM_SABER2_SUPPORT)
   4893     if (SOC_IS_SABER2(unit)) {
   4894         if ((SOC_BLK_IECELL == SOC_REG_FIRST_BLK_TYPE(regblktype)) &&
   4895             (soc_portreg != SOC_REG_INFO(unit, reg).regtype)) {
   4896             instance_mask = 1;
   4897         }
   4898     }
   4899 #endif
   4900 
   4901     if ((!block_id_mask) && (!schan_id_mask) && (REG_PORT_ANY == port || instance_mask || !SOC_BLOCK_IN_LIST(regblktype, portblktype))) {
   4902         int blkport = port;
   4903         if (port == REG_PORT_ANY || port == SOC_CORE_ALL) {
   4904             blkport = 0;
   4905         }
   4906         switch (SOC_REG_FIRST_BLK_TYPE(regblktype)) {
   4907         case SOC_BLK_ARL:
   4908             block = ARL_BLOCK(unit);
   4909             break;
   4910         case SOC_BLK_IPIPE:
   4911             block = IPIPE_BLOCK(unit);
   4912             break;
   4913         case SOC_BLK_IPIPE_HI:
   4914             block = IPIPE_HI_BLOCK(unit);
   4915             break;
   4916         case SOC_BLK_EPIPE:
   4917             block = EPIPE_BLOCK(unit);
   4918             break;
   4919         case SOC_BLK_EPIPE_HI:
   4920             block = EPIPE_HI_BLOCK(unit);
   4921             break;
   4922         case SOC_BLK_IGR:
   4923             block = IGR_BLOCK(unit);
   4924             break;
   4925         case SOC_BLK_EGR:
   4926             block = EGR_BLOCK(unit);
   4927             break;
   4928         case SOC_BLK_BSE:
   4929             block = BSE_BLOCK(unit);
   4930             break;
   4931         case SOC_BLK_CSE:
   4932             block = CSE_BLOCK(unit);
   4933             break;
   4934         case SOC_BLK_HSE:
   4935             block = HSE_BLOCK(unit);
   4936             break;
   4937         case SOC_BLK_SYS:
   4938             break;
   4939         case SOC_BLK_BSAFE:
   4940             block = BSAFE_BLOCK(unit);
   4941             break;
   4942         case SOC_BLK_OTPC:
   4943             block = OTPC_BLOCK(unit, blkport);
   4944             break;
   4945         case SOC_BLK_MMU:
   4946             block = MMU_BLOCK(unit);
   4947             break;
   4948         case SOC_BLK_MMU_SED:
   4949             block = MMU_SED_BLOCK(unit);
   4950             break;
   4951         case SOC_BLK_MMU_GLB:
   4952             block = MMU_GLB_BLOCK(unit);
   4953             break;
   4954         case SOC_BLK_MMU_XPE:
   4955             block = MMU_XPE_BLOCK(unit);
   4956             break;
   4957         case SOC_BLK_MMU_SC:
   4958             block = MMU_SC_BLOCK(unit);
   4959             break;
   4960         case SOC_BLK_MCU:
   4961             block = MCU_BLOCK(unit);
   4962             break;
   4963         case SOC_BLK_CMIC:
   4964             block = CMIC_BLOCK(unit);
   4965             break;
   4966         case SOC_BLK_IPROC:
   4967             block = IPROC_BLOCK(unit);
   4968             break;
   4969         case SOC_BLK_CRYPTO:
   4970             block = CRYPTO_BLOCK(unit);
   4971             break;
   4972         case SOC_BLK_ESM:
   4973             block = ESM_BLOCK(unit);
   4974             break;
   4975         case SOC_BLK_PORT_GROUP4:
   4976             block = PG4_BLOCK(unit, port);
   4977             break;
   4978         case SOC_BLK_PORT_GROUP5:
   4979             block = PG5_BLOCK(unit, port);
   4980             break;
   4981         case SOC_BLK_TOP:
   4982             block = TOP_BLOCK(unit);
   4983             break;
   4984         case SOC_BLK_SER:
   4985             block = SER_BLOCK(unit);
   4986             break;
   4987         case SOC_BLK_AVS:
   4988             block = AVS_BLOCK(unit);
   4989             break;
   4990         case SOC_BLK_AXP:
   4991             block = AXP_BLOCK(unit);
   4992             break;
   4993         case SOC_BLK_ISM:
   4994             block = ISM_BLOCK(unit);
   4995             break;
   4996         case SOC_BLK_ETU:
   4997             block = ETU_BLOCK(unit);
   4998             break;
   4999         case SOC_BLK_ETU_WRAP:
   5000             block = ETU_WRAP_BLOCK(unit);
   5001             break;
   5002         case SOC_BLK_IBOD:
   5003             block = IBOD_BLOCK(unit);
   5004             break;
   5005         case SOC_BLK_LLS:
   5006             block = LLS_BLOCK(unit);
   5007             break;
   5008         case SOC_BLK_CES:
   5009             block = CES_BLOCK(unit);
   5010             break;
   5011         case SOC_BLK_PGW_CL:
   5012             if (instance_mask) {
   5013                 instance = port;
   5014             } else{
   5015                 /* coverity[overrun-local : FALSE] */
   5016                 instance = SOC_INFO(unit).port_group[port];
   5017             }
   5018             block = PGW_CL_BLOCK(unit, instance);
   5019             break;
   5020         case SOC_BLK_PMQPORT:
   5021         case SOC_BLK_PMQ:
   5022             /* coverity[overrun-local : FALSE] */
   5023             block = PMQ_BLOCK(unit, blkport);
   5024             break;
   5025         case SOC_BLK_PGW_GE:
   5026             block = PGW_GE_BLOCK(unit, instance);
   5027             break;
   5028         case SOC_BLK_IL:
   5029             if (SOC_IS_SHADOW(unit)) {
   5030                 if (port == 9) {
   5031                     block = IL0_BLOCK(unit);
   5032                 } else if (port == 13) {
   5033                     block = IL1_BLOCK(unit);
   5034                 }
   5035                 pindex = 0;
   5036             }
   5037             break;
   5038         case SOC_BLK_MS_ISEC:
   5039             if (SOC_IS_SHADOW(unit)) {
   5040                 if (port >= 1 && port <= 4) {
   5041                     block = MS_ISEC0_BLOCK(unit);
   5042                     pindex = port - 1;
   5043                 } else {
   5044                     block = MS_ISEC1_BLOCK(unit);
   5045                     pindex = port - 5;
   5046                 }
   5047             }
   5048             break;
   5049         case SOC_BLK_MS_ESEC:
   5050             if (SOC_IS_SHADOW(unit)) {
   5051                 if (port >= 1 && port <= 4) {
   5052                     block = MS_ESEC0_BLOCK(unit);
   5053                     pindex = port - 1;
   5054                 } else {
   5055                     block = MS_ESEC1_BLOCK(unit);
   5056                     pindex = port - 5;
   5057                 }
   5058             }
   5059             break;
   5060         case SOC_BLK_CW:
   5061             if (SOC_IS_SHADOW(unit)) {
   5062                 block = CW_BLOCK(unit);
   5063             }
   5064             break;
   5065         case SOC_BLK_CM:
   5066             break;
   5067         case SOC_BLK_CO:
   5068             break;
   5069         case SOC_BLK_CI:
   5070             if (SOC_IS_KATANA2(unit)) {
   5071                 block = CI_BLOCK(unit, port);
   5072             }
   5073             break;
   5074         case SOC_BLK_CX:
   5075             break;
   5076         case SOC_BLK_LRA:
   5077             break;
   5078         case SOC_BLK_LRB:
   5079             break;
   5080         case SOC_BLK_OC:
   5081             break;
   5082         case SOC_BLK_PB:
   5083             break;
   5084         case SOC_BLK_PD:
   5085             break;
   5086         case SOC_BLK_PP:
   5087             break;
   5088         case SOC_BLK_PR:
   5089             break;
   5090         case SOC_BLK_PT:
   5091             break;
   5092         case SOC_BLK_QM:
   5093             break;
   5094         case SOC_BLK_RC:
   5095             break;
   5096         case SOC_BLK_TMA:
   5097             break;
   5098         case SOC_BLK_TMB:
   5099             break;
   5100         case SOC_BLK_TM_QE:
   5101             break;
   5102         case SOC_BLK_TP:
   5103             break;
   5104 #if defined(BCM_KATANA2_SUPPORT)
   5105         case SOC_BLK_TXLP:
   5106             if (SOC_IS_KATANA2(unit)) {
   5107                 soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   5108                     SOC_BLK_TXLP, &block, &pindex);
   5109             }
   5110             break;
   5111         case SOC_BLK_RXLP:
   5112             if (SOC_IS_KATANA2(unit)) {
   5113                 soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   5114                     SOC_BLK_RXLP, &block, &pindex);
   5115             }
   5116             break;
   5117 #endif
   5118         case SOC_BLK_IECELL:
   5119 #if defined(BCM_METROLITE_SUPPORT)
   5120             if (SOC_IS_METROLITE(unit)) {
   5121                 soc_ml_iecell_port_reg_blk_idx_get(unit, port,
   5122                     SOC_BLK_IECELL, &block, &pindex);
   5123             }
   5124 #endif
   5125 #if defined (BCM_SABER2_SUPPORT)
   5126             if (SOC_IS_SABER2(unit)) {
   5127                 soc_sb2_iecell_port_reg_blk_idx_get(unit, port,
   5128                     SOC_BLK_IECELL, &block, &pindex);
   5129             }
   5130 #endif
   5131             break;
   5132             /* DPP */
   5133         case SOC_BLK_CFC:
   5134 #ifdef BCM_DNX_SUPPORT
   5135             if (SOC_IS_DNX(unit) && block_core == SOC_CORE_ALL) {
   5136                 block = SOC_CORE_ALL;
   5137                 soc_blocks = SOC_INFO(unit).cfc_block;
   5138             } else
   5139 #endif
   5140             {
   5141         	block = CFC_BLOCK(unit, blkport);
   5142             }
   5143             break;
   5144         case SOC_BLK_OCB:
   5145         	block = OCB_BLOCK(unit, block_core);
   5146             soc_blocks = SOC_INFO(unit).ocb_blocks;
   5147             break;
   5148         case SOC_BLK_CRPS:
   5149 #ifdef BCM_DNX_SUPPORT
   5150             if (SOC_IS_DNX(unit) && block_core == SOC_CORE_ALL) {
   5151                 block = SOC_CORE_ALL;
   5152                 soc_blocks = SOC_INFO(unit).crps_blocks;
   5153             } else
   5154 #endif
   5155             {
   5156             block = CRPS_BLOCK(unit, blkport);
   5157             }
   5158             break;
   5159         case SOC_BLK_EPRE:
   5160         	block = EPRE_BLOCK(unit, block_core);
   5161             soc_blocks = SOC_INFO(unit).epre_blocks;
   5162             break;
   5163         case SOC_BLK_IPPF:
   5164         	block = IPPF_BLOCK(unit, block_core);
   5165             soc_blocks = SOC_INFO(unit).ippf_blocks;
   5166             break;
   5167         case SOC_BLK_MDB_ARM:
   5168         	block = MDB_ARM_BLOCK(unit);
   5169             break;
   5170         case SOC_BLK_CDPORT:
   5171         	block = CDPORT_BLOCK(unit, blkport);
   5172             break;
   5173 #ifdef BCM_DNX_SUPPORT
   5174         case SOC_BLK_CLPORT:
   5175             block = CLPORT_BLOCK(unit, blkport);
   5176             break;
   5177 #endif
   5178         case SOC_BLK_CDMAC:
   5179             block = CDMAC_BLOCK(unit, blkport);
   5180             break;
   5181         case SOC_BLK_FDTL:
   5182             block = FDTL_BLOCK(unit);
   5183             break;
   5184         case SOC_BLK_ECI:
   5185             block = ECI_BLOCK(unit);
   5186             break;
   5187         case SOC_BLK_EGQ:
   5188             block = EGQ_BLOCK(unit, block_core);
   5189             break;
   5190         case SOC_BLK_FCR:
   5191             block = FCR_BLOCK(unit);
   5192             break;
   5193         case SOC_BLK_FCT:
   5194             block = FCT_BLOCK(unit);
   5195             break;
   5196         case SOC_BLK_FDR:
   5197 #ifdef BCM_DNX_SUPPORT
   5198             if (SOC_IS_DNX(unit) && block_core == SOC_CORE_ALL) {
   5199                 block = SOC_CORE_ALL;
   5200                 soc_blocks = SOC_INFO(unit).fdr_blocks;
   5201             } else
   5202 #endif
   5203             {
   5204             block = FDR_BLOCK(unit, blkport);
   5205             }
   5206             break;
   5207         case SOC_BLK_FDA:
   5208             block = FDA_BLOCK(unit);
   5209             break;
   5210         case SOC_BLK_FDT:
   5211             block = FDT_BLOCK(unit);
   5212             break;
   5213         case SOC_BLK_MESH_TOPOLOGY:
   5214             block = MESH_TOPOLOGY_BLOCK(unit);
   5215             break;
   5216         case SOC_BLK_IDR:
   5217             block = IDR_BLOCK(unit);
   5218             break;
   5219         case SOC_BLK_IHB:
   5220             block = IHB_BLOCK(unit, block_core);
   5221             break;
   5222         case SOC_BLK_IHP:
   5223             block = IHP_BLOCK(unit, block_core);
   5224             break;
   5225         case SOC_BLK_IPS:
   5226             block = IPS_BLOCK(unit, block_core);
   5227             soc_blocks = SOC_INFO(unit).ips_blocks;
   5228             break;
   5229         case SOC_BLK_IPT:
   5230 #ifdef BCM_DNX_SUPPORT
   5231             if (SOC_IS_DNX(unit) && block_core == SOC_CORE_ALL) {
   5232                 block = SOC_CORE_ALL;
   5233                 soc_blocks = SOC_INFO(unit).ipt_blocks;
   5234             } else
   5235 #endif
   5236             {
   5237             block = IPT_BLOCK(unit, blkport);
   5238             }
   5239             break;
   5240         case SOC_BLK_IQM:
   5241             block = IQM_BLOCK(unit, block_core);
   5242             soc_blocks = SOC_INFO(unit).iqm_blocks;
   5243             break;
   5244         case SOC_BLK_PQP:
   5245             block = PQP_BLOCK(unit, block_core);
   5246             soc_blocks = SOC_INFO(unit).pqp_blocks;
   5247             break;
   5248         case SOC_BLK_KAPS:
   5249             block = KAPS_BLOCK(unit, blkport);
   5250             break;
   5251         case SOC_BLK_KAPS_BBS:
   5252             block = KAPS_BBS_BLOCK(unit,instance);
   5253             break;
   5254         case SOC_BLK_ILB:
   5255             block = ILB_BLOCK(unit);
   5256             break;
   5257         case SOC_BLK_IEP:
   5258             block = IEP_BLOCK(unit);
   5259             break;
   5260         case SOC_BLK_IMP:
   5261             block = IMP_BLOCK(unit);
   5262             break;
   5263         case SOC_BLK_SPB:
   5264             block = SPB_BLOCK(unit, block_core);
   5265             soc_blocks = SOC_INFO(unit).spb_blocks;
   5266             break;
   5267         case SOC_BLK_ITE:
   5268             block = ITE_BLOCK(unit);
   5269             break;
   5270         case SOC_BLK_DDP:
   5271 #ifdef BCM_DNX_SUPPORT
   5272             if (block_core == SOC_CORE_ALL && SOC_IS_DNX(unit)) {
   5273                 block = SOC_CORE_ALL;
   5274                 soc_blocks = SOC_INFO(unit).ddp_blocks;
   5275             } else
   5276 #endif
   5277             {
   5278             block = DDP_BLOCK(unit, blkport);
   5279             }
   5280             break;
   5281         case SOC_BLK_TXQ:
   5282             block = TXQ_BLOCK(unit);
   5283             break;
   5284         case SOC_BLK_TAR:
   5285             block = TAR_BLOCK(unit);
   5286             break;
   5287         case SOC_BLK_PTS:
   5288             block = PTS_BLOCK(unit);
   5289             break;
   5290         case SOC_BLK_SQM:
   5291             block = SQM_BLOCK(unit, blkport);
   5292             break;
   5293         case SOC_BLK_IPSEC:
   5294             block = IPSEC_BLOCK(unit);
   5295             break;
   5296         case SOC_BLK_IPSEC_SPU_WRAPPER_TOP:
   5297             block = IPSEC_SPU_WRAPPER_TOP_BLOCK(unit, instance);
   5298             break;
   5299         case SOC_BLK_DQM:
   5300             block = DQM_BLOCK(unit, block_core);
   5301             soc_blocks = SOC_INFO(unit).dqm_blocks;
   5302             break;
   5303         case SOC_BLK_ECGM:
   5304             block = ECGM_BLOCK(unit, block_core);
   5305             soc_blocks = SOC_INFO(unit).ecgm_blocks;
   5306             break;
   5307         case SOC_BLK_IDB:
   5308             block = IDB_BLOCK(unit);
   5309             break;
   5310         case SOC_BLK_PEM:
   5311             block = PEM_BLOCK(unit, blkport);
   5312             break;
   5313 
   5314         case SOC_BLK_IRE:
   5315 #ifdef BCM_DNX_SUPPORT
   5316             if (SOC_IS_DNX(unit) && block_core == SOC_CORE_ALL) {
   5317                 block = SOC_CORE_ALL;
   5318                 soc_blocks = SOC_INFO(unit).ire_blocks;
   5319             } else
   5320 #endif
   5321             {
   5322             block = IRE_BLOCK(unit, blkport);
   5323             }
   5324             break;
   5325         case SOC_BLK_IRR:
   5326             block = IRR_BLOCK(unit);
   5327             break;
   5328         case SOC_BLK_FMAC:
   5329             block = FMAC_BLOCK(unit, blkport);
   5330             break;
   5331         case SOC_BLK_XLP:
   5332             block = XLP_BLOCK(unit, blkport);
   5333             break;
   5334         case SOC_BLK_CLP:
   5335             block = CLP_BLOCK(unit, blkport);
   5336             break;
   5337         case SOC_BLK_NBI:
   5338             block = NBI_BLOCK(unit);
   5339             break;
   5340         case SOC_BLK_CGM:
   5341             block = CGM_BLOCK(unit, block_core);
   5342             soc_blocks = SOC_INFO(unit).cgm_blocks;
   5343             break;
   5344         case SOC_BLK_OAMP:
   5345             block = OAMP_BLOCK(unit);
   5346             break;
   5347         case SOC_BLK_OLP:
   5348             block = OLP_BLOCK(unit);
   5349             break;
   5350         case SOC_BLK_SIF:
   5351             block = SIF_BLOCK(unit, block_core);
   5352             soc_blocks = SOC_INFO(unit).sif_blocks;
   5353             break;
   5354 	    case SOC_BLK_MCP:
   5355             block = MCP_BLOCK(unit, block_core);
   5356             soc_blocks = SOC_INFO(unit).mcp_blocks;
   5357             break;
   5358         case SOC_BLK_ITPP:
   5359             block = ITPP_BLOCK(unit, block_core);
   5360             soc_blocks = SOC_INFO(unit).itpp_blocks;
   5361             break;
   5362         case SOC_BLK_ITPPD:
   5363             block = ITPPD_BLOCK(unit, block_core);
   5364             soc_blocks = SOC_INFO(unit).itppd_blocks;
   5365             break;
   5366         case SOC_BLK_PDM:
   5367             block = PDM_BLOCK(unit, block_core);
   5368             soc_blocks = SOC_INFO(unit).pdm_blocks;
   5369             break;
   5370         case SOC_BLK_BDM:
   5371             block = BDM_BLOCK(unit, block_core);
   5372             soc_blocks = SOC_INFO(unit).bdm_blocks;
   5373             break;
   5374         case SOC_BLK_CDU:
   5375             block = CDU_BLOCK(unit, blkport);
   5376             break;
   5377         case SOC_BLK_CDUM:
   5378             block = CDUM_BLOCK(unit, block_core);
   5379             soc_blocks = SOC_INFO(unit).cdum_blocks;
   5380             break;
   5381         case SOC_BLK_EPS:
   5382             block = EPS_BLOCK(unit, block_core);
   5383             soc_blocks = SOC_INFO(unit).eps_blocks;
   5384             break;
   5385 
   5386         case SOC_BLK_DDHA:
   5387             block = DDHA_BLOCK(unit, blkport);
   5388             break;
   5389 
   5390         case SOC_BLK_DDHB:
   5391             block = DDHB_BLOCK(unit, blkport);
   5392             break;
   5393 
   5394         case SOC_BLK_DHC:
   5395             block = DHC_BLOCK(unit, blkport);
   5396             break;
   5397 
   5398         case SOC_BLK_DMU:
   5399             block = DMU_BLOCK(unit, blkport);
   5400             break;
   5401 
   5402         case SOC_BLK_ETPPC:
   5403             block = ETPPC_BLOCK(unit, block_core);
   5404             soc_blocks = SOC_INFO(unit).etppc_blocks;
   5405             break;
   5406 
   5407         case SOC_BLK_EVNT:
   5408             block = EVNT_BLOCK(unit, blkport);
   5409             break;
   5410 
   5411         case SOC_BLK_HBC:
   5412             block = HBC_BLOCK(unit, blkport);
   5413             break;
   5414 
   5415         case SOC_BLK_ILE:
   5416             block = ILE_BLOCK(unit, block_core);
   5417             soc_blocks = SOC_INFO(unit).ile_blocks;
   5418             break;
   5419         case SOC_BLK_CLU:
   5420             block = CLU_BLOCK(unit, block_core);
   5421             soc_blocks = SOC_INFO(unit).clu_blocks;
   5422             break;
   5423         case SOC_BLK_CLUP:
   5424             block = CLUP_BLOCK(unit, block_core);
   5425             soc_blocks = SOC_INFO(unit).clup_blocks;
   5426             break;
   5427         case SOC_BLK_CLMAC:
   5428             block = CLMAC_BLOCK(unit, block_core);
   5429             soc_blocks = SOC_INFO(unit).clmac_blocks;
   5430             break;
   5431         case SOC_BLK_ESB:
   5432             block = ESB_BLOCK(unit);
   5433             break;
   5434         case SOC_BLK_ILU:
   5435             block = ILU_BLOCK(unit, blkport);
   5436             break;
   5437         case SOC_BLK_NMG:
   5438             block = NMG_BLOCK(unit, block_core);
   5439             soc_blocks = SOC_INFO(unit).nmg_blocks;
   5440             break;
   5441 
   5442         case SOC_BLK_IPPE:
   5443             block = IPPE_BLOCK(unit, block_core);
   5444             soc_blocks = SOC_INFO(unit).ippe_blocks;
   5445             break;
   5446 
   5447         case SOC_BLK_TCAM:
   5448             block = TCAM_BLOCK(unit, block_core);
   5449             soc_blocks = SOC_INFO(unit).tcam_blocks;
   5450             break;
   5451 
   5452         case SOC_BLK_TDU:
   5453             block = TDU_BLOCK(unit, block_core);
   5454             soc_blocks = SOC_INFO(unit).tdu_blocks;
   5455             break;
   5456 
   5457         case SOC_BLK_MTM:
   5458             block = MTM_BLOCK(unit);
   5459             break;
   5460         case SOC_BLK_HBM:
   5461             block = HBM_BLOCK(unit, blkport);
   5462             break;
   5463         case SOC_BLK_RQP:
   5464             block = RQP_BLOCK(unit, block_core);
   5465             soc_blocks = SOC_INFO(unit).rqp_blocks;
   5466             break;
   5467         case SOC_BLK_FQP:
   5468             block = FQP_BLOCK(unit, block_core);
   5469             soc_blocks = SOC_INFO(unit).fqp_blocks;
   5470             break;
   5471         case SOC_BLK_HBMC:
   5472             block = HBMC_BLOCK(unit, blkport);
   5473             break;
   5474         case SOC_BLK_MDB:
   5475             block = MDB_BLOCK(unit);
   5476             break;
   5477         case SOC_BLK_ERPP:
   5478             block = ERPP_BLOCK(unit, block_core);
   5479             soc_blocks = SOC_INFO(unit).erpp_blocks;
   5480             break;
   5481         case SOC_BLK_ETPPA:
   5482             block = ETPPA_BLOCK(unit, block_core);
   5483             soc_blocks = SOC_INFO(unit).etppa_blocks;
   5484             break;
   5485         case SOC_BLK_ETPPB:
   5486             block = ETPPB_BLOCK(unit, block_core);
   5487             soc_blocks = SOC_INFO(unit).etppb_blocks;
   5488             break;
   5489         case SOC_BLK_MACT:
   5490             block = MACT_BLOCK(unit);
   5491             break;
   5492         case SOC_BLK_IPPA:
   5493             block = IPPA_BLOCK(unit, block_core);
   5494             soc_blocks = SOC_INFO(unit).ippa_blocks;
   5495             break;
   5496         case SOC_BLK_IPPB:
   5497             block = IPPB_BLOCK(unit, block_core);
   5498             soc_blocks = SOC_INFO(unit).ippb_blocks;
   5499             break;
   5500         case SOC_BLK_IPPC:
   5501             block = IPPC_BLOCK(unit, block_core);
   5502             soc_blocks = SOC_INFO(unit).ippc_blocks;
   5503             break;
   5504         case SOC_BLK_IPPD:
   5505             block = IPPD_BLOCK(unit, block_core);
   5506             soc_blocks = SOC_INFO(unit).ippd_blocks;
   5507             break;
   5508         case SOC_BLK_FSRD:
   5509             block = FSRD_BLOCK(unit, blkport);
   5510             break;
   5511         case SOC_BLK_RTP:
   5512             block = RTP_BLOCK(unit);
   5513             break;
   5514         case SOC_BLK_SCH:
   5515             block = SCH_BLOCK(unit, block_core);
   5516             soc_blocks = SOC_INFO(unit).sch_blocks;
   5517             break;
   5518         case SOC_BLK_EPNI:
   5519             block = EPNI_BLOCK(unit, block_core);
   5520             soc_blocks = SOC_INFO(unit).epni_blocks;
   5521             break;
   5522         case SOC_BLK_DRCA:
   5523             block = DRCA_BLOCK(unit);
   5524             break;
   5525         case SOC_BLK_DRCB:
   5526             block = DRCB_BLOCK(unit);
   5527             break;
   5528         case SOC_BLK_DRCC:
   5529             block = DRCC_BLOCK(unit);
   5530             break;
   5531         case SOC_BLK_DRCD:
   5532             block = DRCD_BLOCK(unit);
   5533             break;
   5534         case SOC_BLK_DRCE:
   5535             block = DRCE_BLOCK(unit);
   5536             break;
   5537         case SOC_BLK_DRCF:
   5538             block = DRCF_BLOCK(unit);
   5539             break;
   5540         case SOC_BLK_DRCG:
   5541             block = DRCG_BLOCK(unit);
   5542             break;
   5543         case SOC_BLK_DRCH:
   5544             block = DRCH_BLOCK(unit);
   5545             break;
   5546         case SOC_BLK_EDB:
   5547 #ifdef BCM_DNX_SUPPORT
   5548             if (SOC_IS_DNX(unit) && block_core == SOC_CORE_ALL) {
   5549                 block = SOC_CORE_ALL;
   5550                 soc_blocks = SOC_INFO(unit).edb_blocks;
   5551             } else
   5552 #endif
   5553             {
   5554             block = EDB_BLOCK(unit, blkport);
   5555             }
   5556             break;
   5557         case SOC_BLK_ILKN_PMH:
   5558             block = ILKN_PMH_BLOCK(unit);
   5559             break;
   5560         case SOC_BLK_IPST:
   5561             block = IPST_BLOCK(unit);
   5562             break;
   5563         case SOC_BLK_IQMT:
   5564             block = IQMT_BLOCK(unit);
   5565             break;
   5566         case SOC_BLK_PPDB_A:
   5567             block = PPDB_A_BLOCK(unit);
   5568             break;
   5569         case SOC_BLK_PPDB_B:
   5570             block = PPDB_B_BLOCK(unit);
   5571             break;
   5572         case SOC_BLK_ILKN_PML:
   5573             block = ILKN_PML_BLOCK(unit, blkport);
   5574             break;
   5575         case SOC_BLK_MRPS:
   5576             block = MRPS_BLOCK(unit, instance);
   5577             soc_blocks = SOC_INFO(unit).mrps_blocks;
   5578             break;
   5579         case SOC_BLK_MTRPS_EM:
   5580             block = MTRPS_EM_BLOCK(unit, instance);
   5581             break;
   5582         case SOC_BLK_NBIL:
   5583             block = NBIL_BLOCK(unit, blkport);
   5584             break;
   5585         case SOC_BLK_NBIH:
   5586             block = NBIH_BLOCK(unit);
   5587             break;
   5588         case SOC_BLK_DRCBROADCAST:
   5589             block = DRCBROADCAST_BLOCK(unit);
   5590             break;
   5591         case SOC_BLK_BRDC_FSRD:
   5592             block = BRDC_FSRD_BLOCK(unit);
   5593             break;
   5594         case SOC_BLK_BRDC_FMAC:
   5595             block = BRDC_FMAC_BLOCK(unit);
   5596             break;
   5597         case SOC_BLK_BRDC_HBC:
   5598             block = BRDC_HBC_BLOCK(unit);
   5599             break;
   5600         case SOC_BLK_BRDC_CCH:
   5601             block = BRDC_CCH_BLOCK(unit);
   5602             break;
   5603         case SOC_BLK_BRDC_CGM:
   5604             block = BRDC_CGM_BLOCK(unit);
   5605             break;
   5606         case SOC_BLK_BRDC_EGQ:
   5607             block = BRDC_EGQ_BLOCK(unit);
   5608             break;
   5609         case SOC_BLK_BRDC_EPNI:
   5610             block = BRDC_EPNI_BLOCK(unit);
   5611             break;
   5612         case SOC_BLK_BRDC_IHB:
   5613             block = BRDC_IHB_BLOCK(unit);
   5614             break;
   5615         case SOC_BLK_BRDC_IHP:
   5616             block = BRDC_IHP_BLOCK(unit);
   5617             break;
   5618         case SOC_BLK_BRDC_IPS:
   5619             block = BRDC_IPS_BLOCK(unit);
   5620             break;
   5621         case SOC_BLK_BRDC_IQM:
   5622             block = BRDC_IQM_BLOCK(unit);
   5623             break;
   5624         case SOC_BLK_BRDC_SCH:
   5625             block = BRDC_SCH_BLOCK(unit);
   5626             break;
   5627 #ifdef DNX_TEST_CHIPS_SUPPORT
   5628         case SOC_BLK_PRM:
   5629             block = PRM_BLOCK(unit);
   5630             break;
   5631         case SOC_BLK_BLH:
   5632             block = BLH_BLOCK(unit, blkport);
   5633             break;
   5634         case SOC_BLK_AM_TOP:
   5635             block = AM_TOP_BLOCK(unit);
   5636             break;
   5637 #endif /* DNX_TEST_CHIPS_SUPPORT */
   5638         /* DFE  blocks*/
   5639         case SOC_BLK_DCH:
   5640             block=DCH_BLOCK(unit,blkport);
   5641             break;
   5642         case SOC_BLK_DCL:
   5643             block=DCL_BLOCK(unit,blkport);
   5644             break;
   5645         case SOC_BLK_OCCG:
   5646             block=OCCG_BLOCK(unit);
   5647             break;
   5648         case SOC_BLK_DCM:
   5649             block=DCM_BLOCK(unit,blkport);
   5650             break;
   5651         case SOC_BLK_DCMC:
   5652             block = DCMC_BLOCK(unit);
   5653             break;
   5654         case SOC_BLK_CCS:
   5655             block=CCS_BLOCK(unit,blkport);
   5656             break;
   5657         case SOC_BLK_BRDC_FMAC_AC:
   5658             block=BRDC_FMAC_AC_BLOCK(unit);
   5659             break;
   5660         case SOC_BLK_BRDC_FMAC_BD:
   5661             block=BRDC_FMAC_BD_BLOCK(unit);
   5662             break;
   5663         case SOC_BLK_BRDC_DCH:
   5664             block=BRDC_DCH_BLOCK(unit);
   5665             break;
   5666         case SOC_BLK_BRDC_DCL:
   5667             block=BRDC_DCL_BLOCK(unit);
   5668             break;
   5669         case SOC_BLK_BRDC_DCM:
   5670             block=BRDC_DCM_BLOCK(unit);
   5671             break;
   5672         case SOC_BLK_BRDC_CCS:
   5673             block=BRDC_CCS_BLOCK(unit);
   5674             break;
   5675         case SOC_BLK_DCML:
   5676             block=DCML_BLOCK(unit, blkport);
   5677             break;
   5678         case SOC_BLK_MCT:
   5679             block=MCT_BLOCK(unit);
   5680             break;
   5681         case SOC_BLK_QRH:
   5682             block=QRH_BLOCK(unit, blkport);
   5683             break;
   5684         case SOC_BLK_CCH:
   5685             block=CCH_BLOCK(unit, blkport);
   5686             break;
   5687         case SOC_BLK_LCM:
   5688             block=LCM_BLOCK(unit, blkport);
   5689             break;
   5690         case SOC_BLK_BRDC_DCML:
   5691             block=BRDC_DCML_BLOCK(unit);
   5692             break;
   5693         case SOC_BLK_BRDC_QRH:
   5694             block=BRDC_QRH_BLOCK(unit);
   5695             break;
   5696         case SOC_BLK_BRDC_LCM:
   5697             block=BRDC_LCM_BLOCK(unit);
   5698             break;
   5699         case SOC_BLK_GPORT:
   5700             block=GPORT_BLOCK(unit, blkport);
   5701             break;
   5702         case SOC_BLK_MXQ:
   5703             block=MXQ_BLOCK(unit, blkport);
   5704             break;
   5705         case SOC_BLK_PLL:
   5706             block=PLL_BLOCK(unit);
   5707             break;
   5708         case SOC_BLK_NIF:
   5709             block=NIF_BLOCK(unit);
   5710             break;
   5711         case SOC_BLK_MMU_ITM:
   5712             block = MMU_ITM_BLOCK(unit);
   5713             break;
   5714         case SOC_BLK_MMU_EB:
   5715             block = MMU_EB_BLOCK(unit);
   5716             break;
   5717         case SOC_BLK_CEV:
   5718             block = CEV_BLOCK(unit);
   5719             break;
   5720         case SOC_BLK_MACSEC :
   5721             block = MACSEC_BLOCK(unit);
   5722             break;    
   5723         case SOC_BLK_TAF:
   5724             block = TAF_BLOCK(unit);
   5725             break;
   5726         default:
   5727             block = -1; /* unknown non-port block */
   5728             break;
   5729         }
   5730     } else if(block_id_mask) {
   5731         block = port;
   5732     }
   5733 
   5734     if(!schan_id_mask) {
   5735         if(block < 0) {
   5736             assert(block == SOC_CORE_ALL); /* block must be valid */
   5737         }
   5738     }
   5739 
   5740     /* determine final block, pindex, and index */
   5741     gransh = 0;
   5742     switch (SOC_REG_INFO(unit, reg).regtype) {
   5743     case soc_cpureg:
   5744     case soc_mcsreg:
   5745     case soc_iprocreg:
   5746         block = -1;
   5747         pindex = 0;
   5748         gransh = 2; /* 4 byte granularity */
   5749         break;
   5750     case soc_ppportreg:
   5751     case soc_portreg:
   5752         if (!SOC_BLOCK_IN_LIST(regblktype, portblktype) && 
   5753             !(SOC_BLOCK_IN_LIST(regblktype, SOC_BLK_MS_ISEC)) && 
   5754             !(SOC_BLOCK_IN_LIST(regblktype, SOC_BLK_MS_ESEC)) &&
   5755             !(SOC_BLOCK_IN_LIST(regblktype, SOC_BLK_TXLP)) && 
   5756             !(SOC_BLOCK_IN_LIST(regblktype, SOC_BLK_RXLP))) {
   5757             if (soc_feature(unit, soc_feature_logical_port_num) &&
   5758                 (block == MMU_BLOCK(unit) ||
   5759                  block == MMU_SED_BLOCK(unit) ||
   5760                  block == MMU_GLB_BLOCK(unit) ||
   5761                  block == MMU_XPE_BLOCK(unit) ||
   5762                  block == MMU_SED_BLOCK(unit) ||
   5763                  block == MMU_ITM_BLOCK(unit) ||
   5764                  block == MMU_EB_BLOCK(unit) ||
   5765                  block == MMU_SC_BLOCK(unit))) {
   5766                 if (preserve_port) {
   5767                     phy_port = port;
   5768                     pindex = port;
   5769                 } else {
   5770 #ifdef BCM_TOMAHAWK3_SUPPORT
   5771                     /*MMU register with device port indexing*/
   5772                     num_regs = sizeof(reg_excep_list) / sizeof(soc_reg_t);
   5773                     for (reg_index = 0;reg_index < num_regs; reg_index++) {
   5774                         if (reg_excep_list[reg_index] == reg) {
   5775                             add_exception = 1;
   5776                             break;
   5777                         }
   5778                     }
   5779                     if (add_exception) {
   5780                                 pindex = port;
   5781                     } else
   5782 
   5783 #endif
   5784                     {
   5785                     /* coverity[overrun-local : FALSE] */
   5786                     /* coverity[negative_returns : FALSE] */
   5787                     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   5788                     pindex = SOC_INFO(unit).port_p2m_mapping[phy_port];
   5789                     if (pindex < 0) {
   5790                         pindex = SOC_INFO(unit).max_port_p2m_mapping[phy_port];
   5791                     }
   5792                     assert(pindex >= 0);
   5793                 }
   5794                 }
   5795 #ifdef BCM_TRIUMPH3_SUPPORT
   5796                 /* We do not want any more of these exceptions in the code */
   5797                 if (SOC_IS_TRIUMPH3(unit) && (reg == MMU_INTFO_CONGST_STr)) {
   5798                     pindex = port;
   5799                 }
   5800 #endif
   5801             } else {
   5802                 pindex = port;
   5803 #if defined(BCM_METROLITE_SUPPORT)              
   5804                 METROLITE_GET_REG_THDI_PORT(unit, port, reg, pindex)
   5805 #endif
   5806             }
   5807             gransh = 8;
   5808         }
   5809 #ifdef BCM_TOMAHAWK3_SUPPORT
   5810         /* Since there are two CDMAC0 and CDMAC1, we need to determine which
   5811            stage does this port belong to for the per port registers.
   5812            For CDPORT registers, the stage is 0 and CDMAC_0 registers, it is 1
   5813            while for CDMAC_1 it is 2 */
   5814         if (SOC_IS_TOMAHAWK3(unit)) {
   5815             if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CDPORT)) {
   5816                if ((SOC_REG_INFO(unit, reg).offset & 0x000F0000) ==
   5817                                 CDMAC_OFFSET_CNT) {
   5818                    stage_id = ((((phy_port - 1) >> 2) & 1) == 0) ?
   5819                                       CDMAC0_STAGE_ID : CDMAC1_STAGE_ID;
   5820                    if (stage_id == CDMAC0_STAGE_ID) {
   5821                         pindex = pindex | 0x04000000;
   5822                         break;
   5823                    } else {
   5824                         pindex = pindex & 3;
   5825                         pindex = pindex | 0x08000000;
   5826                         break;
   5827                    }
   5828                }
   5829             }
   5830         }
   5831 #endif
   5832 #ifdef BCM_DNX_SUPPORT
   5833         /* Since there are two CDMAC0 and CDMAC1, we need to determine which
   5834            stage does this port belong to for the per port registers.
   5835            For CDPORT registers, the stage is 0 and CDMAC_0 registers, it is 1
   5836            while for CDMAC_1 it is 2 */
   5837         if (SOC_IS_DNX(unit) && SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CDMAC) &&
   5838            (SOC_REG_INFO(unit, reg).offset & 0x000F0000) == CDMAC_OFFSET_CNT) {
   5839             if ((phy_port & 4) == 0) { /* is it CDMAC0_STAGE_ID */
   5840                 pindex = pindex | 0x04000000;
   5841             } else {
   5842                 pindex = pindex & 3;
   5843                 pindex = pindex | 0x08000000;
   5844             }
   5845         }
   5846 #endif
   5847 
   5848         break;
   5849     case soc_cosreg:
   5850         assert(index >= 0 && index < NUM_COS(unit));
   5851         pindex = index;
   5852         index = 0;
   5853         break;
   5854     case soc_pipereg:
   5855     case soc_xpereg:
   5856     case soc_itmreg:
   5857     case soc_ebreg:
   5858     case soc_slicereg:
   5859     case soc_layerreg:
   5860         gransh = 8;
   5861         pindex = port;
   5862         break;
   5863     case soc_customreg:
   5864     case soc_genreg:
   5865         gransh = 8;
   5866         pindex = 0;
   5867 #ifdef BCM_TOMAHAWK3_SUPPORT
   5868         /* Since there are two CDMAC0 and CDMAC1, we need to determine which
   5869          * CDMAC/stage id does this register belong to.
   5870          * For CDMAC_0 registers, it is 1, while for CDMAC_1 it is 2 */
   5871         if (SOC_IS_TOMAHAWK3(unit)) {
   5872             if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CDPORT)) {
   5873                 if ((SOC_REG_INFO(unit, reg).offset & 0x000F0000) ==
   5874                                 CDMAC_OFFSET_CNT) {
   5875                     stage_id = ((((phy_port - 1) >> 2) & 1) == 0) ?
   5876                                       CDMAC0_STAGE_ID : CDMAC1_STAGE_ID;
   5877                     if (stage_id == CDMAC0_STAGE_ID) {
   5878                         pindex = pindex | 0x04000000;
   5879                         break;
   5880                     } else {
   5881                         pindex = pindex | 0x08000000;
   5882                         break;
   5883                     }
   5884                 }
   5885             }
   5886         }
   5887 #endif
   5888         if (SOC_IS_GREYHOUND2(unit) &&
   5889             (block == TAF_BLOCK(unit))) {
   5890             /* Base address decision of GH2 TAF block */
   5891             gransh = 0;
   5892             pindex = index;
   5893             index = 0;
   5894         } else {
   5895             gransh = 8;
   5896             pindex = 0;
   5897 #ifdef BCM_DNX_SUPPORT
   5898             /* Since there are two CDMAC0 and CDMAC1, we need to determine which
   5899              * CDMAC/stage id does this register belong to.
   5900              * For CDMAC_0 registers, it is 1, while for CDMAC_1 it is 2 */
   5901             if (SOC_IS_DNX(unit) && SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CDMAC)) {
   5902                 if ((SOC_REG_INFO(unit, reg).offset & 0x000F0000) == CDMAC_OFFSET_CNT) {
   5903 
   5904                    if (instance_mask)
   5905                    {
   5906                        /* use the block instance for selecting CDMAC stage */
   5907                        pindex = ((port & 1) == 0) ? 0x04000000 : 0x08000000;
   5908                    }
   5909                    else
   5910                    {
   5911                        if ((phy_port & 4) == 0) { /* is it CDMAC0_STAGE_ID */
   5912                            pindex = pindex | 0x04000000;
   5913                        } else {
   5914                            pindex = pindex | 0x08000000;
   5915                        }
   5916                    }
   5917 
   5918                 }
   5919             }
   5920 #endif
   5921         }
   5922         break;
   5923     default:
   5924         assert(0); /* unknown register type */
   5925         break;
   5926     }
   5927 
   5928     /* put together address: base|block|pindex + index */
   5929     base = SOC_REG_INFO(unit, reg).offset;
   5930 
   5931     /* Base address decision of GH2 TAF block */
   5932     if (SOC_IS_GREYHOUND2(unit) &&
   5933         (SOC_REG_INFO(unit, reg).regtype == soc_genreg) &&
   5934         (block == TAF_BLOCK(unit)) &&
   5935         (SOC_REG_NUMELS(unit, reg) == 128)) {
   5936         base &= ~(1 << SOC_RT_BP);
   5937     }
   5938 
   5939     LOG_VERBOSE(BSL_LS_SOC_REG,
   5940                 (BSL_META_U(unit,
   5941                             "base: %x "), base));
   5942 
   5943     if(schan_id_mask) {
   5944         access_info->blk_list[0] = port;
   5945     } else if (block >= 0) {
   5946         access_info->blk_list[0] = SOC_BLOCK_INFO(unit, block).cmic;
   5947     } else if (block == SOC_CORE_ALL) {
   5948         if (SOC_IS_DNX(unit)) {
   5949             /* Fill the output s-channel block ID list */
   5950 #ifdef BCM_DNX_SUPPORT
   5951             /* Get the number of active cores */
   5952             access_info->num_blks = dnx_data_device.general.nof_cores_get(unit);
   5953             for (block_core = 0; block_core < access_info->num_blks; ++block_core) { 
   5954                 access_info->blk_list[block_core] = soc_blocks != NULL ? SOC_BLOCK_INFO(unit, soc_blocks[block_core]).cmic : -1;
   5955             }
   5956 #endif /* BCM_DNX_SUPPORT */
   5957         } else {
   5958             access_info->blk_list[0] = soc_blocks != NULL ? SOC_BLOCK_INFO(unit, soc_blocks[0]).cmic : -1;
   5959     }
   5960     
   5961     } 
   5962     if (pindex != -1) {
   5963         base |= pindex;
   5964     }
   5965     
   5966     if (SOC_REG_IS_ARRAY(unit, reg)) {
   5967         assert(index >= SOC_REG_INFO(unit, reg).first_array_index && index < SOC_REG_NUMELS(unit, reg) + SOC_REG_INFO(unit, reg).first_array_index);
   5968 #if defined(BCM_SABER2_SUPPORT)
   5969         if (SOC_IS_SABER2(unit) && block == OAMP_BLOCK(unit)) {
   5970             base += (index - SOC_REG_INFO(unit, reg).first_array_index)*(SOC_REG_ELEM_SKIP(unit, reg) << 8);
   5971         } else
   5972 #endif
   5973         {
   5974         base += (index - SOC_REG_INFO(unit, reg).first_array_index)*SOC_REG_ELEM_SKIP(unit, reg);
   5975         }
   5976     }  else if (index && SOC_REG_ARRAY(unit, reg)) {
   5977         if (index && SOC_REG_ARRAY2(unit, reg)) {
   5978             assert(index >= 0 && index < 2 * SOC_REG_NUMELS(unit, reg));
   5979             base += ((index*2) << gransh);
   5980         } else if (index && SOC_REG_ARRAY4(unit, reg)) {
   5981             assert(index >= 0 && index < 4 * SOC_REG_NUMELS(unit, reg));
   5982             base += ((index * 4) << gransh);             
   5983         } else {
   5984             assert(index >= 0 && index < SOC_REG_NUMELS(unit, reg));
   5985             base += (index << gransh);
   5986         }
   5987     }
   5988     LOG_VERBOSE(BSL_LS_SOC_REG,
   5989                 (BSL_META_U(unit,
   5990                             "addr new: %x, block: %d, index: %d, pindex: %d, gransh: %d\n"),
   5991                  base, access_info->blk_list[0], index, pindex, gransh));
   5992     access_info->offset = base;
   5993     return SOC_E_NONE;
   5994 }
   5995 
   5996 
   5997 /*
   5998  * Function:    soc_reg_addr_get
   5999  * Purpose:     calculate the address of a register
   6000  * Parameters:
   6001  *     unit       - SOC unit number
   6002  *     reg        - Register number
   6003  *     port       - Port number or REG_PORT_ANY
   6004  *     index      - Array index (or cos number)
   6005  *     options    - Flag to indicate special handling to calculate
   6006  *                  the HW register address: SOC_REG_ADDR_OPTION_xxx
   6007  *     blk        - (OUT) ...
   6008  *     acc_type   - (OUT) Register access type
   6009  *
   6010  * Returns:     register address suitable for soc_reg_get and friends
   6011  * Notes:       the block number to access is determined by the register
   6012  *              and the port number
   6013  *
   6014  * cpureg       00SSSSSS 00000000 0000RRRR RRRRRRRR
   6015  * genreg       00SSSSSS BBBB1000 0000RRRR RRRRRRRR
   6016  * portreg      00SSSSSS BBBB00PP PPPPRRRR RRRRRRRR
   6017  * cosreg       00SSSSSS BBBB01CC CCCCRRRR RRRRRRRR
   6018  *
   6019  * all regs of bcm88230
   6020  *              00000000 00001000 0000RRRR RRRRRRRR
   6021  *
   6022  * where        B+ is the 4 bit block number
   6023  *              P+ is the 6 bit port number (within a block or chip wide)
   6024  *              C+ is the 6 bit class of service
   6025  *              R+ is the 12 bit register number
   6026  *              S+ is the 6 bit Pipe stage
   6027  */
   6028 uint32
   6029 soc_reg_addr_get(int unit, soc_reg_t reg, int port, int index, uint32 options,
   6030                  int *blk, uint8 *acc_type)
   6031 {
   6032     soc_reg_access_info_t access_info;
   6033 
   6034     if (soc_reg_xaddr_get(unit, reg, port, index, options, &access_info) == SOC_E_NONE) {
   6035         if (access_info.num_blks > 0) {
   6036             *blk = access_info.blk_list[0]; /* (single) s-channel block ID */
   6037             *acc_type = access_info.acc_type; /* access type */
   6038         }
   6039         return access_info.offset; /* register offset/address in its block */
   6040     }
   6041     LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   6042       "soc_reg_addr_get: failed to get register address")));
   6043     return -1; /* invalid address */
   6044 }
   6045 
   6046 int
   6047 soc_regaddrlist_alloc(soc_regaddrlist_t *addrlist)
   6048 {
   6049     if ((addrlist->ainfo = sal_alloc(_SOC_MAX_REGLIST *
   6050                 sizeof(soc_regaddrinfo_t), "regaddrlist")) == NULL) {
   6051         return SOC_E_MEMORY;
   6052     }
   6053     addrlist->count = 0;
   6054     memset(addrlist->ainfo, 0, sizeof(soc_regaddrinfo_t));
   6055 
   6056     return SOC_E_NONE;
   6057 }
   6058 
   6059 int
   6060 soc_regaddrlist_free(soc_regaddrlist_t *addrlist)
   6061 {
   6062     if (addrlist->ainfo) {
   6063         sal_free(addrlist->ainfo);
   6064     }
   6065 
   6066     return SOC_E_NONE;
   6067 }
   6068 
   6069 /*
   6070  * Function:   soc_reg_fields32_modify
   6071  * Purpose:    Modify the value of a fields in a register.
   6072  * Parameters:
   6073  *       unit         - (IN) SOC unit number.
   6074  *       reg          - (IN) Register.
   6075  *       port         - (IN) Port number.
   6076  *       field_count  - (IN) Number of fields to modify.
   6077  *       fields       - (IN) Modified fields array.
   6078  *       values       - (IN) New value for each member of fields array.
   6079  * Returns:
   6080  *       BCM_E_XXX
   6081  */
   6082 int
   6083 soc_reg_fields32_modify(int unit, soc_reg_t reg, soc_port_t port,
   6084                         int field_count, soc_field_t *fields, uint32 *values)
   6085 {
   6086     uint64 data64;      /* Current 64 bit register data.  */
   6087     uint64 odata64;     /* Original 64 bit register data. */
   6088     uint32 data32;      /* Current 32 bit register data.  */
   6089     uint32 odata32;     /* Original 32 bit register data. */
   6090     uint32 reg_addr;    /* Register address.              */
   6091     int idx;            /* Iteration index.               */
   6092     uint32 max_val;     /* Max value to fit the field     */
   6093     int field_len;      /* Bit length of the field        */
   6094 
   6095     /* Check that register is a valid one for this unit. */
   6096     if (!SOC_REG_IS_VALID(unit, reg)) {
   6097         return SOC_E_PARAM;
   6098     }
   6099 
   6100     if ((NULL == fields) || (NULL == values)) {
   6101         return SOC_E_PARAM;
   6102     }
   6103 
   6104     /*  Fields & values sanity check. */
   6105     for (idx = 0; idx < field_count; idx++) {
   6106 
   6107         /* Make sure field is present in register. */
   6108         if (!soc_reg_field_valid(unit, reg, fields[idx])) {
   6109             return SOC_E_PARAM;
   6110         }
   6111         /* Make sure value can fit into field */
   6112         field_len = soc_reg_field_length(unit, reg, fields[idx]);
   6113         max_val = (field_len < 32) ? ((1 << field_len) - 1) : 0xffffffff;
   6114         if (values[idx] > max_val) {
   6115             return SOC_E_PARAM;
   6116         }
   6117     }
   6118 
   6119     if (soc_feature(unit, soc_feature_new_sbus_format)) {
   6120         if (SOC_REG_IS_64(unit, reg)) {
   6121 
   6122             /* Read current register value. */
   6123             SOC_IF_ERROR_RETURN(soc_reg64_get(unit, reg, port, 0, &data64));
   6124             odata64 = data64;
   6125 
   6126             /* Update fields with new values. */
   6127             for (idx = 0; idx < field_count; idx ++) {
   6128                 soc_reg64_field32_set(unit, reg, &data64, fields[idx], values[idx]);
   6129             }
   6130             if (COMPILER_64_NE(data64, odata64)) {
   6131                 /* Write new register value back to hw. */
   6132                 SOC_IF_ERROR_RETURN(soc_reg64_set(unit, reg, port, 0, data64));
   6133             }
   6134         } else {
   6135             if (soc_cpureg == SOC_REG_TYPE(unit,  reg)) {
   6136                 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, port);
   6137                 /* Read PCI register value. */
   6138                 SOC_IF_ERROR_RETURN(soc_pci_getreg(unit, reg_addr, &data32));
   6139 #ifdef BCM_IPROC_SUPPORT
   6140             } else if (soc_iprocreg == SOC_REG_TYPE(unit,  reg)) {
   6141                 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, port);
   6142                 SOC_IF_ERROR_RETURN(soc_iproc_getreg(unit, reg_addr, &data32));
   6143 #endif
   6144             } else {
   6145                 reg_addr = 0;  /* Compiler warning defense. */
   6146                 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &data32));
   6147             }
   6148             odata32 = data32;
   6149 
   6150             for (idx = 0; idx < field_count; idx ++) {
   6151                 soc_reg_field_set(unit, reg, &data32, fields[idx], values[idx]);
   6152             }
   6153             if (data32 != odata32) {
   6154                 /* Write new register value back to hw. */
   6155                 if (soc_cpureg == SOC_REG_TYPE(unit,  reg)) {
   6156                     SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr, data32));
   6157 #ifdef BCM_IPROC_SUPPORT
   6158                 } else if (soc_iprocreg == SOC_REG_TYPE(unit,  reg)) {
   6159                     SOC_IF_ERROR_RETURN(soc_iproc_setreg(unit, reg_addr, data32));
   6160 #endif
   6161                 } else {
   6162                     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, data32));
   6163                 }
   6164             }
   6165         }
   6166     } else {
   6167         /* Calculate register address. */
   6168         reg_addr = soc_reg_addr(unit, reg, port, 0);
   6169 
   6170         if (SOC_REG_IS_64(unit, reg)) {
   6171 
   6172             /* Read current register value. */
   6173             SOC_IF_ERROR_RETURN(soc_reg64_read(unit, reg_addr, &data64));
   6174             odata64 = data64;
   6175 
   6176             /* Update fields with new values. */
   6177             for (idx = 0; idx < field_count; idx ++) {
   6178                 soc_reg64_field32_set(unit, reg, &data64, fields[idx], values[idx]);
   6179             }
   6180             if (COMPILER_64_NE(data64, odata64)) {
   6181 #if defined(BCM_XGS_SUPPORT)
   6182                 if (soc_feature(unit, soc_feature_regs_as_mem)) {
   6183                     (void)soc_ser_reg_cache_set(unit, reg, port, 0, data64);
   6184                 }
   6185 #endif /* BCM_XGS_SUPPORT */                
   6186                 /* Write new register value back to hw. */
   6187                 SOC_IF_ERROR_RETURN(soc_reg64_write(unit, reg_addr, data64));
   6188             }
   6189         } else {
   6190             if (soc_cpureg == SOC_REG_TYPE(unit,  reg)) {
   6191                 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, port);
   6192                 /* Read PCI register value. */
   6193                 /* coverity[result_independent_of_operands] */
   6194                 SOC_IF_ERROR_RETURN(soc_pci_getreg(unit, reg_addr, &data32));
   6195             } else {
   6196                 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &data32));
   6197             }
   6198 
   6199             odata32 = data32;
   6200 
   6201             for (idx = 0; idx < field_count; idx ++) {
   6202                 soc_reg_field_set(unit, reg, &data32, fields[idx], values[idx]);
   6203             }
   6204             if (data32 != odata32) {
   6205                 /* Write new register value back to hw. */
   6206                 if (soc_cpureg == SOC_REG_TYPE(unit,  reg)) {
   6207                     /* coverity[result_independent_of_operands] */
   6208                     SOC_IF_ERROR_RETURN(soc_pci_write(unit, reg_addr, data32));
   6209                 } else {
   6210 #if defined(BCM_XGS_SUPPORT)
   6211                     if (soc_feature(unit, soc_feature_regs_as_mem)) {
   6212                         (void)soc_ser_reg32_cache_set(unit, reg, port, 0, data32);
   6213                     }
   6214 #endif /* BCM_XGS_SUPPORT */
   6215                     SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, data32));
   6216                 }
   6217             }
   6218         }
   6219     }
   6220     return (SOC_E_NONE);
   6221 }
   6222 
   6223 /*
   6224  * Function:   soc_reg_field32_modify
   6225  * Purpose:    Modify the value of a field in a register.
   6226  * Parameters:
   6227  *       unit  - (IN) SOC unit number.
   6228  *       reg   - (IN) Register.
   6229  *       port  - (IN) Port number.
   6230  *       field - (IN) Modified field.
   6231  *       value - (IN) New field value.
   6232  * Returns:
   6233  *       SOC_E_XXX
   6234  */
   6235 int
   6236 soc_reg_field32_modify(int unit, soc_reg_t reg, soc_port_t port, 
   6237                        soc_field_t field, uint32 value)
   6238 {
   6239     return soc_reg_fields32_modify(unit, reg, port, 1, &field, &value);
   6240 }
   6241 
   6242 int
   6243 soc_reg_port_valid(int unit, soc_reg_t reg, soc_port_t port) {
   6244     if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, reg).block, SOC_BLK_XLPORT) &&
   6245         SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, reg).block, SOC_BLK_MXQPORT)) {
   6246         /* This register is valid for both port blocks */
   6247         if (!IS_XL_PORT(unit, port) && !IS_MXQ_PORT(unit, port)) {
   6248            return FALSE;
   6249         }
   6250     } else if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_XLPORT) &&
   6251                !IS_XL_PORT(unit, port)) {
   6252             return FALSE;
   6253     } else if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_MXQPORT) &&
   6254                !IS_MXQ_PORT(unit, port)) {
   6255             return FALSE;
   6256     }
   6257     return TRUE;
   6258 }
   6259 
   6260 
   6261 /*
   6262  * Function:   soc_reg_above_64_field32_modify
   6263  * Purpose:    Modify the value of a 32 bit field in any size register.
   6264  * Parameters:
   6265  *       unit  - (IN) SOC unit number.
   6266  *       reg   - (IN) Register.
   6267  *       port  - (IN) Port number.
   6268  *       index - (IN) instance index
   6269  *       field - (IN) Modified field.
   6270  *       value - (IN) New field value.
   6271  * Returns:
   6272  *       SOC_E_XXX
   6273  */
   6274 int
   6275 soc_reg_above_64_field32_modify(int unit, soc_reg_t reg, soc_port_t port, 
   6276                        int index, soc_field_t field, uint32 value)
   6277 {
   6278     int rc;
   6279     soc_reg_above_64_val_t data;
   6280     SOC_REG_ABOVE_64_CLEAR(data);
   6281     rc = soc_reg_above_64_get(unit, reg, port, index, data);
   6282     if (rc != SOC_E_NONE){
   6283         return rc;
   6284     }
   6285     soc_reg_above_64_field32_set(unit, reg, data, field, value);
   6286     rc = soc_reg_above_64_set(unit, reg, port, index, data);
   6287     if (rc != SOC_E_NONE){
   6288         return rc;
   6289     }
   6290     return SOC_E_NONE;
   6291 }
   6292 
   6293 /*
   6294  * Function:   soc_reg_above_64_field32_modify
   6295  * Purpose:    Modify the value of a 32 bit field in any size register.
   6296  * Parameters:
   6297  *       unit  - (IN) SOC unit number.
   6298  *       reg   - (IN) Register.
   6299  *       port  - (IN) Port number.
   6300  *       index - (IN) instance index
   6301  *       field - (IN) Modified field.
   6302  *       value - (IN) New field value.
   6303  * Returns:
   6304  *       SOC_E_XXX
   6305  */
   6306 int
   6307 soc_reg_above_64_field64_modify(int unit, soc_reg_t reg, soc_port_t port, 
   6308                        int index, soc_field_t field, uint64 value)
   6309 {
   6310     int rc;
   6311     soc_reg_above_64_val_t 
   6312         data;
   6313     SOC_REG_ABOVE_64_CLEAR(data);
   6314     rc = soc_reg_above_64_get(unit, reg, port, index, data);
   6315     if (rc != SOC_E_NONE){
   6316         return rc;
   6317     }
   6318     soc_reg_above_64_field64_set(unit, reg, data, field, value);
   6319     rc = soc_reg_above_64_set(unit, reg, port, index, data);
   6320     if (rc != SOC_E_NONE){
   6321         return rc;
   6322     }
   6323     return SOC_E_NONE;
   6324 }
   6325 
   6326 /*
   6327  * Function:    soc_reg_port_idx_valid
   6328  * Purpose:     Determine if a register of a given 
   6329  *                   index and port is valid.
   6330  * Returns:      Returns TRUE  if register is valid.
   6331  *               Returns FALSE if register is not valid.
   6332  */
   6333 int
   6334 soc_reg_port_idx_valid(int unit, soc_reg_t reg, soc_port_t port, int idx)
   6335 {
   6336     soc_numelport_set_t *numelports;
   6337     uint32 *portslist;
   6338     int i, numellist_idx, indx;
   6339 
   6340 
   6341     if (!SOC_REG_IS_VALID(unit, reg)) {
   6342         return FALSE;
   6343     }
   6344 
   6345     /* idx is -1 means "any/all indexes..". so, check for Index 0 */
   6346     indx = (idx == -1) ? 0 : idx;
   6347 
   6348 #ifdef BCM_KATANA2_SUPPORT
   6349     if (SOC_IS_KATANA2(unit)) {
   6350         
   6351         if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_TXLP)) {
   6352             if (soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   6353                 SOC_BLK_TXLP, NULL, NULL) != SOC_E_NONE) {
   6354                 /* Not a TXLP Port */
   6355                 return FALSE;
   6356             }
   6357         } else if (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_RXLP)) {
   6358             if (soc_kt2_linkphy_port_reg_blk_idx_get(unit, port,
   6359                 SOC_BLK_RXLP, NULL, NULL) != SOC_E_NONE) {
   6360                 /* Not a RXLP Port */
   6361                 return FALSE;
   6362             }
   6363 #ifdef BCM_METROLITE_SUPPORT
   6364         } else if (SOC_IS_METROLITE(unit) && (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_IECELL))) {
   6365             if (soc_ml_iecell_port_reg_blk_idx_get(unit, port,
   6366                 SOC_BLK_IECELL, NULL, NULL) != SOC_E_NONE) {
   6367                 /* Not a IECELL Port */
   6368                 return FALSE;
   6369             }
   6370 #endif
   6371 #if defined (BCM_SABER2_SUPPORT)
   6372         } else if (SOC_IS_SABER2(unit) && (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_IECELL))) {
   6373             if (soc_sb2_iecell_port_reg_blk_idx_get(unit, port,
   6374                 SOC_BLK_IECELL, NULL, NULL) != SOC_E_NONE) {
   6375                 /* Not a IECELL Port */
   6376                 return FALSE;
   6377             }
   6378 #endif
   6379         }
   6380     }
   6381 #endif
   6382 
   6383     numellist_idx = SOC_REG_NUMELPORTLIST_IDX(unit, reg);
   6384     if (numellist_idx == -1) {
   6385      /* No PORTLIST or NUMEL_PERPORT */
   6386 #ifdef BCM_SABER2_SUPPORT
   6387         if (SOC_IS_SABER2(unit)) {
   6388             return soc_reg_port_valid(unit, reg, port);
   6389         }
   6390 #endif
   6391         return TRUE;
   6392     }
   6393 
   6394 #ifdef BCM_GREYHOUND2_SUPPORT
   6395     /* GREYHOUND2 should use MMU port rather than logical port while checking PERPort MMU register */
   6396     if(SOC_IS_GREYHOUND2(unit) && (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_MMU))) {
   6397         if (soc_feature(unit, soc_feature_logical_port_num)) {
   6398             port = SOC_INFO(unit).port_l2p_mapping[port];
   6399             port = SOC_INFO(unit).port_p2m_mapping[port];
   6400         }
   6401     }
   6402 #endif
   6403 
   6404     numelports = soc_numelports_list[numellist_idx];
   6405     i=0;
   6406     while (numelports[i].f_idx != -1) {
   6407         if ((indx >= numelports[i].f_idx) && (indx <= numelports[i].l_idx)) {
   6408             portslist = soc_ports_list[numelports[i].pl_idx];
   6409             if (portslist[port /32] & (1 << (port % 32))) {
   6410                 return TRUE;
   6411             } else {
   6412                 return FALSE;
   6413             }
   6414         }
   6415         i++;
   6416     }
   6417     /* If idx is not found in the numel list, then it is just PORTLIST, not NUMELS_PERPORT */
   6418     portslist = soc_ports_list[numelports[0].pl_idx];
   6419     if (portslist[port /32] & (1 << (port % 32))) {
   6420         return TRUE;
   6421     } else {
   6422         return FALSE;
   6423     }
   6424 }
   6425 
   6426 /*
   6427  * Function:   soc_reg_egress_cell_count_get
   6428  * Purpose:    Retrieves the number of egress cells for a <port, cos> pair.
   6429  * Parameters:
   6430  *       unit  - (IN) SOC unit number.
   6431  *       port  - (IN) Port number.
   6432  *       cos   - (IN) COS queue.
   6433  *       data  - (OUT) Cell count.
   6434  * Returns:
   6435  *       SOC_E_XXX
   6436  */
   6437 int
   6438 soc_reg_egress_cell_count_get(int unit, soc_port_t port, int cos, uint32 *data)
   6439 {
   6440     if (!SOC_PORT_VALID(unit, port) || cos < 0 || cos >= NUM_COS(unit)) {
   6441         return SOC_E_PARAM;
   6442     }
   6443     SOC_IF_ERROR_RETURN(READ_COSLCCOUNTr(unit, port, cos, data));
   6444     return SOC_E_NONE;
   6445 }
   6446 
   6447 #ifdef BCM_CMICM_SUPPORT
   6448 
   6449 soc_cmicm_reg_t cmicm_regs[] = CMICM_REG_INIT;
   6450 
   6451 STATIC soc_cmicm_reg_t
   6452 *soc_cmicm_srch (uint32 addr) {
   6453     int start = 0;
   6454     int end = NUM_CMICM_REGS - 1;
   6455     int mid = (start + end) >> 1;
   6456     while (start <= end && cmicm_regs[mid].addr != addr) {
   6457         if (cmicm_regs[mid].addr > addr) {
   6458             end = mid - 1;
   6459         } else {
   6460             start = mid + 1;
   6461         }
   6462         mid = (start + end) >> 1;
   6463     }
   6464     return (cmicm_regs[mid].addr == addr) ? &(cmicm_regs[mid]) : NULL;
   6465 }
   6466 
   6467 soc_cmicm_reg_t
   6468 *soc_cmicm_reg_get (uint32 idx) {
   6469     return &(cmicm_regs[idx]);
   6470 }
   6471 
   6472 soc_reg_t
   6473 soc_cmicm_addr_reg (uint32 addr) {
   6474     soc_cmicm_reg_t *cmreg = soc_cmicm_srch(addr);
   6475     return (cmreg == NULL)?INVALIDr:cmreg->reg;
   6476 }
   6477 
   6478 char *
   6479 soc_cmicm_addr_name (uint32 addr) {
   6480     soc_cmicm_reg_t *cmreg = soc_cmicm_srch(addr);
   6481     return (cmreg == NULL)?"???":cmreg->name;
   6482 }
   6483 #endif 
   6484 
   6485 
   6486 uint32
   6487 soc_pci_mcs_read(int unit, uint32 addr) {
   6488 
   6489 #ifdef BCM_CMICM_SUPPORT
   6490     uint32 page = (addr & 0xffff8000);
   6491     uint32 off = (addr & 0x00007fff);
   6492     uint32 data = 0;
   6493 
   6494     if (soc_feature(unit, soc_feature_cmicm)) {
   6495         soc_pci_write(unit, CMIC_PIO_MCS_ACCESS_PAGE_OFFSET, page);
   6496 
   6497         /* Read back to ensure write is complete */
   6498         page = soc_pci_read(unit, CMIC_PIO_MCS_ACCESS_PAGE_OFFSET);
   6499 
   6500         /* Hardcoded for now.. use reg addr if & when available in regfile */
   6501         data = soc_pci_read(unit, (0x38000 + off));
   6502 #ifdef BROADCOM_DEBUG
   6503         if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   6504             _soc_reg_debug(unit, 32, "read", addr, 0, data);
   6505         }
   6506 #endif /* BROADCOM_DEBUG */
   6507         /* _soc_snoop_reg(unit, 0, 0, addr,SOC_REG_SNOOP_READ,0,data); */
   6508         return data;
   6509     }
   6510 #endif /* BCM_CMICM_SUPPORT */
   6511 
   6512     return 0;
   6513 }
   6514 
   6515 int
   6516 soc_pci_mcs_getreg(int unit, uint32 addr, uint32 *data_ptr) {
   6517     *data_ptr = soc_pci_mcs_read(unit, addr);
   6518     return SOC_E_NONE;
   6519 }
   6520 
   6521 int
   6522 soc_pci_mcs_write(int unit, uint32 addr, uint32 data) {
   6523 #ifdef BCM_CMICM_SUPPORT
   6524     uint32 page = (addr & 0xffff8000);
   6525     uint32 off = (addr & 0x00007fff);
   6526 
   6527     if (soc_feature(unit, soc_feature_cmicm)) {
   6528 #ifdef BROADCOM_DEBUG
   6529         if (bsl_check(bslLayerSoc, bslSourceReg, bslSeverityNormal, unit)) {
   6530             _soc_reg_debug(unit, 32, "write", addr, 0, data);
   6531         }
   6532 #endif /* BROADCOM_DEBUG */
   6533         /* _soc_snoop_reg(unit, 0, 0, addr,SOC_REG_SNOOP_WRITE,0,data); */
   6534 
   6535         soc_pci_write(unit, CMIC_PIO_MCS_ACCESS_PAGE_OFFSET, page);
   6536 
   6537         /* Read back to ensure write is complete */
   6538         page = soc_pci_read(unit, CMIC_PIO_MCS_ACCESS_PAGE_OFFSET);
   6539 
   6540         /* Hardcoded for now.. use reg addr if & when available in regfile */
   6541         return soc_pci_write(unit, (0x38000 + off), data);
   6542     }
   6543 #endif /* BCM_CMICM_SUPPORT */
   6544 
   6545     return 0;
   6546 }
   6547 
   6548 /* Get register length in bytes */
   6549 int
   6550 soc_reg_bytes(int unit, soc_reg_t reg) {
   6551 
   6552     int              bits = 0;
   6553     soc_reg_info_t   *regp;
   6554     int              i, bytes;
   6555     soc_field_info_t *fieldp;
   6556 
   6557      if (!SOC_REG_IS_VALID(unit, reg)) {
   6558 #if !defined(SOC_NO_NAMES)
   6559         LOG_CLI((BSL_META_U(unit,
   6560                             "reg %s is invalid\n"), soc_reg_name[reg]));
   6561 #endif /* !SOC_NO_NAMES */
   6562         assert(SOC_REG_IS_VALID(unit, reg));
   6563     }
   6564     regp = &(SOC_REG_INFO(unit, reg));
   6565 
   6566     for (i = 0; i < (int)(regp->nFields); i++) {
   6567         fieldp = &(regp->fields[i]);
   6568         bits = ((fieldp->len + fieldp->bp) > bits)? 
   6569             (fieldp->len + fieldp->bp): bits;
   6570     }
   6571     bytes = BITS2BYTES(bits);
   6572     return bytes;
   6573 }
   6574 
   6575 /* Get register length in bits */
   6576 int
   6577 soc_reg_bits(int unit, soc_reg_t reg) {
   6578 
   6579     int              bits = 0;
   6580     soc_reg_info_t   *regp;
   6581     int              i;
   6582     soc_field_info_t *fieldp;
   6583 
   6584     if (!SOC_REG_IS_VALID(unit, reg)) {
   6585 #if !defined(SOC_NO_NAMES)
   6586         LOG_CLI((BSL_META_U(unit,
   6587                             "reg %s is invalid\n"), soc_reg_name[reg]));
   6588 #endif /* !SOC_NO_NAMES */
   6589         return 0;
   6590     }
   6591     regp = &(SOC_REG_INFO(unit, reg));
   6592 
   6593     for (i = 0; i < (int)(regp->nFields); i++) {
   6594         fieldp = &(regp->fields[i]);
   6595         bits = ((fieldp->len + fieldp->bp) > bits)? 
   6596             (fieldp->len + fieldp->bp): bits;
   6597     }
   6598     
   6599     return bits;
   6600 }
   6601 
   6602 /* 
   6603  * Function:     
   6604  *     soc_reg_snoop_register 
   6605  * Purpose:
   6606  *      Registers a snooping call back for specific memory.
   6607  *      Call back will be called on Read or Write operations
   6608  *      on the register according to specified flags
   6609  * Parameters:          
   6610  *      unit         -  (IN) BCM device number.
   6611  *      reg          -  (IN) Register to register a call back for.
   6612  *      flags        -  (IN) SOC_REGS_SNOOP_XXX flags.
   6613  *      snoop_cv     -  (IN) User provided call back, NULL for unregister
   6614  *      user_data    -  (IN) user provided data to be passed to call back function
   6615  * Returns:
   6616  *      None
   6617  */     
   6618 void 
   6619 soc_reg_snoop_register(int unit, soc_reg_t reg, uint32 flags,
   6620                       soc_reg_snoop_cb_t snoop_cb, void *user_data)
   6621 {  
   6622     soc_reg_info_t      *reg_info_p;
   6623         
   6624     if (!SOC_REG_IS_VALID(unit, reg)) {
   6625 #if defined(BCM_ESW_SUPPORT) && !defined(SOC_NO_NAMES)
   6626         LOG_CLI((BSL_META_U(unit,
   6627                             "reg %s is invalid\n"), soc_reg_name[reg]));
   6628 #endif
   6629         assert(SOC_REG_IS_VALID(unit, reg));
   6630     }
   6631 
   6632     reg_info_p = &SOC_REG_INFO(unit, reg);
   6633 
   6634     assert(NULL != snoop_cb);
   6635 
   6636     reg_info_p->snoop_cb = snoop_cb;
   6637     reg_info_p->snoop_user_data = user_data;
   6638     reg_info_p->snoop_flags = flags;
   6639 
   6640     return;
   6641 }
   6642 
   6643 /*
   6644  * Function:
   6645  *     soc_reg_snoop_unregister
   6646  * Purpose:
   6647  *      Unregisters a snooping call back for specific register.
   6648  *      this function will not fail even if call back was not previously
   6649  *      registered.
   6650  * Parameters:
   6651  *      unit         -  (IN) BCM device number.
   6652  *      reg          -  (IN) Register to register a call back for.
   6653  * Returns:
   6654  *      None
   6655  */
   6656 void
   6657 soc_reg_snoop_unregister(int unit, soc_reg_t reg)
   6658 {  
   6659     soc_reg_info_t      *reg_info_p;
   6660 
   6661     if (!SOC_REG_IS_VALID(unit, reg)) {
   6662 #if defined(BCM_ESW_SUPPORT) && !defined(SOC_NO_NAMES)
   6663         LOG_CLI((BSL_META_U(unit,
   6664                             "reg %s is invalid\n"), soc_reg_name[reg]));
   6665 #endif
   6666         assert(SOC_REG_IS_VALID(unit, reg));
   6667     }
   6668 
   6669     reg_info_p = &SOC_REG_INFO(unit, reg);
   6670 
   6671     reg_info_p->snoop_cb = NULL;
   6672     reg_info_p->snoop_user_data = NULL;
   6673     reg_info_p->snoop_flags = 0;
   6674 
   6675     return;
   6676 }
   6677 
   6678 /*
   6679  * This function allows registration of user defined callbacks for
   6680  * registers and memories operations.
   6681  */
   6682 int 
   6683 soc_reg_access_func_register(int unit, soc_reg_access_t* reg_access) 
   6684 {
   6685     SOC_INFO(unit).reg_access = *reg_access;
   6686 
   6687     return SOC_E_NONE;
   6688 }
   6689 
   6690 
   6691 int
   6692 soc_custom_reg32_get(int unit, soc_reg_t reg, int port, int index, uint32 *data)
   6693 {
   6694     soc_reg32_get_f custom_reg32_get = SOC_INFO(unit).custom_reg_access.custom_reg32_get;
   6695 
   6696     if (!custom_reg32_get) {
   6697         LOG_CLI((BSL_META_U(unit, "custom function not defined\n")));
   6698         return SOC_E_FAIL;
   6699     }
   6700 
   6701     return custom_reg32_get(unit, reg, port, index, data);
   6702 }
   6703 
   6704 int
   6705 soc_custom_reg32_set(int unit, soc_reg_t reg, int port, int index, uint32 data)
   6706 {
   6707     soc_reg32_set_f custom_reg32_set = SOC_INFO(unit).custom_reg_access.custom_reg32_set;
   6708 
   6709     if (!custom_reg32_set) {
   6710         LOG_CLI((BSL_META_U(unit, "custom function not defined\n")));
   6711         return SOC_E_FAIL;
   6712     }
   6713 
   6714     return custom_reg32_set(unit, reg, port, index, data);
   6715 }
   6716 
   6717 int
   6718 soc_custom_reg64_get(int unit, soc_reg_t reg, int port, int index, uint64 *data)
   6719 {
   6720     soc_reg64_get_f custom_reg64_get = SOC_INFO(unit).custom_reg_access.custom_reg64_get;
   6721 
   6722     if (!custom_reg64_get) {
   6723         LOG_CLI((BSL_META_U(unit, "custom function not defined\n")));
   6724         return SOC_E_FAIL;
   6725     }
   6726 
   6727     return custom_reg64_get(unit, reg, port, index, data);
   6728 }
   6729 
   6730 int
   6731 soc_custom_reg64_set(int unit, soc_reg_t reg, int port, int index, uint64 data)
   6732 {
   6733     soc_reg64_set_f custom_reg64_set = SOC_INFO(unit).custom_reg_access.custom_reg64_set;
   6734 
   6735     if (!custom_reg64_set) {
   6736         LOG_CLI((BSL_META_U(unit, "custom function not defined\n")));
   6737         return SOC_E_FAIL;
   6738     }
   6739 
   6740     return custom_reg64_set(unit, reg, port, index, data);
   6741 }
   6742 
   6743 int
   6744 soc_custom_reg_above_64_get(int unit, soc_reg_t reg, int port, int index, soc_reg_above_64_val_t data)
   6745 {
   6746     soc_reg_above64_get_f custom_reg_above64_get = SOC_INFO(unit).custom_reg_access.custom_reg_above64_get;
   6747 
   6748     if (!custom_reg_above64_get) {
   6749         LOG_CLI((BSL_META_U(unit, "custom function not defined\n")));
   6750         return SOC_E_FAIL;
   6751     }
   6752 
   6753     return custom_reg_above64_get(unit, reg, port, index, data);
   6754 }
   6755 
   6756 int
   6757 soc_custom_reg_above_64_set(int unit, soc_reg_t reg, int port, int index, soc_reg_above_64_val_t data)
   6758 {
   6759     soc_reg_above64_set_f custom_reg_above64_set = SOC_INFO(unit).custom_reg_access.custom_reg_above64_set;
   6760 
   6761     if (!custom_reg_above64_set) {
   6762         LOG_CLI((BSL_META_U(unit, "custom function not defined\n")));
   6763         return SOC_E_FAIL;
   6764     }
   6765 
   6766     return custom_reg_above64_set(unit, reg, port, index, data);
   6767 }
   6768 
   6769  
   6770 /* 
   6771  * Function:     
   6772  *     soc_reg_field_acc_mode_get 
   6773  * Purpose:
   6774  *      indicate if a register or a field is readonly/writeonly. 
   6775  * Parameters:          
   6776  *      unit         -  (IN) BCM device number.
   6777  *      reg          -  (IN) Register 
   6778  *      field        -  (IN) field, if invalid then check readonly/writeonly on the register
   6779  *      is_read_only  -  (OUT) read only indication for the register or the field
   6780  *      is_write_only -  (OUT) write only indication for the register or the field
   6781  * Returns:
   6782  *      None
   6783  */  
   6784 void
   6785 soc_reg_field_acc_mode_get(
   6786     int unit,
   6787     soc_reg_t reg,
   6788     soc_field_t field,
   6789     uint32 *is_read_only,
   6790     uint32 *is_write_only)
   6791 {
   6792     soc_field_info_t *finfop;
   6793 
   6794     *is_read_only = 0;
   6795     *is_write_only = 0;
   6796 
   6797     if (!SOC_REG_IS_VALID(unit, reg))
   6798     {
   6799 #if !defined(SOC_NO_NAMES)
   6800         LOG_CLI((BSL_META_U(unit, "reg %s is invalid\n"), soc_reg_name[reg]));
   6801 #endif
   6802         assert(SOC_REG_IS_VALID(unit, reg));
   6803     }
   6804 
   6805     if (field == INVALIDf)
   6806     {
   6807         if (SOC_REG_INFO(unit, reg).flags & SOC_REG_FLAG_RO)
   6808         {
   6809             *is_read_only = 1;
   6810         }
   6811         return;
   6812     }
   6813 
   6814     SOC_FIND_FIELD(field, SOC_REG_INFO(unit, reg).fields, SOC_REG_INFO(unit, reg).nFields, finfop);
   6815     if (finfop == NULL)
   6816     {
   6817 #if !defined(SOC_NO_NAMES)
   6818         LOG_CLI((BSL_META_U(unit, "reg %s field %s is invalid\n"), soc_reg_name[reg], soc_fieldnames[field]));
   6819 #endif
   6820         assert(finfop);
   6821     }
   6822 
   6823     if (finfop->flags & SOCF_RO)
   6824     {
   6825         *is_read_only = 1;
   6826     }
   6827 
   6828     if (finfop->flags & SOCF_WO)
   6829     {
   6830         *is_write_only = 1;
   6831     }
   6832 
   6833 }
   6834 
   6835 #endif /* defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) || defined(PORTMOD_SUPPORT)*/
   6836 
   6837