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

drv.c (168910B)


      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  * StrataSwitch driver
      8  */
      9 
     10 #include <soc/drv.h>
     11 #ifdef _SHR_BSL_H_
     12 #error Header file soc/drv.h must not include bsl.h directly or indirectly
     13 #endif
     14 
     15 #include <shared/bsl.h>
     16 
     17 #include <sal/appl/sal.h>
     18 #include <sal/core/libc.h>
     19 #include <shared/alloc.h>
     20 #include <shared/switch.h>
     21 #include <shared/bitop.h>
     22 #include <sal/core/spl.h>
     23 #include <sal/core/sync.h>
     24 #include <sal/core/boot.h>
     25 #include <sal/core/dpc.h>
     26 
     27 #include <soc/cm.h>
     28 #include <soc/drv.h>
     29 #include <soc/dma.h>
     30 #include <soc/register.h>
     31 #include <soc/debug.h>
     32 #if defined(BCM_PETRA_SUPPORT)
     33 #include <soc/dpp/drv.h>
     34 #endif
     35 #ifdef BCM_DNX_SUPPORT
     36 #include <soc/dnx/drv.h>
     37 #include <soc/dnxc/drv.h>
     38 #endif
     39 #ifdef BCM_DFE_SUPPORT
     40 #include <soc/dfe/cmn/dfe_drv.h>
     41 #endif
     42 #ifdef BCM_DNXF_SUPPORT
     43 #include <soc/dnxf/cmn/dnxf_drv.h>
     44 #endif
     45 #ifdef BCM_WARM_BOOT_SUPPORT
     46 #include <soc/mem.h>
     47 #endif
     48 #ifdef BCM_CMICM_SUPPORT
     49 #include <soc/cmicm.h>
     50 #endif
     51 #ifdef BCM_IPROC_SUPPORT
     52 #include <soc/iproc.h>
     53 #endif
     54 #ifdef INCLUDE_AVS
     55 #include <soc/avs.h>
     56 #endif /* INCLUDE_AVS */
     57 #if defined(PORTMOD_SUPPORT) && defined(BCM_ESW_SUPPORT)
     58 #include <soc/esw/portctrl.h>
     59 #include <soc/phy/phymod_sim.h>
     60 #endif
     61 
     62 #ifdef ADAPTER_SERVER_MODE
     63 #define DRV_ADAPTER_SERVER_SUFFIX "_ADAPTER"
     64 #endif /*ADAPTER_SERVER_MODE*/
     65 
     66 /*
     67  * Driver global variables
     68  *
     69  *   soc_control: per-unit driver control structure
     70  *   soc_persist: persistent per-unit driver control structure
     71  *   soc_ndev: the number of units created
     72  *   soc_ndev_attached: the number of units attached
     73  *   soc_family_suffix: a family suffix, configured by soc property soc_family.
     74  *     Used what parsing soc properties.
     75  *     If configured, and property.unit, property.chip and property.group was not
     76  *     found, property.family is searched for.
     77  */
     78 soc_control_t   *soc_control[SOC_MAX_NUM_DEVICES];
     79 soc_persist_t   *soc_persist[SOC_MAX_NUM_DEVICES];
     80 int             soc_ndev = 0;
     81 /* soc_ndev_idx2dev_map maps the devices logical id to the physical device id
     82  * e.g. if we have two devides with ids 0 and 2 and hence soc_ndev is 2,
     83  * we will have this status: 
     84  * soc_ndev_idx2dev_map[0] will be 0, and
     85  * soc_ndev_idx2dev_map[1] will be 2.
     86  */
     87 int             soc_ndev_idx2dev_map[SOC_MAX_NUM_DEVICES];
     88 int             soc_eth_ndev = 0;
     89 int             soc_ndev_attached = 0;
     90 int             soc_all_ndev;
     91 uint32          soc_state[SOC_MAX_NUM_DEVICES];
     92 char            *soc_family_suffix[SOC_MAX_NUM_DEVICES] = {0};
     93 
     94 /*   soc_wb_mim_state: indicate that all virtual ports / VPNs are MiM */
     95 /*                     Level 1 warm boot only */
     96 #ifdef BCM_WARM_BOOT_SUPPORT
     97 int             soc_wb_mim_state[SOC_MAX_NUM_DEVICES];
     98 #endif
     99 
    100 #if defined(BCM_SAND_SUPPORT)
    101 
    102 int soc_get_reg_first_block_id(int unit,soc_reg_t reg,uint32 *block)
    103 {
    104   soc_reg_info_t reg_info = SOC_REG_INFO(unit, reg);
    105   int block_type = SOC_REG_FIRST_BLK_TYPE(reg_info.block);
    106   int blk=-1;
    107   int schan;
    108 
    109   SOC_BLOCK_ITER(unit, blk, block_type) {
    110       schan =  SOC_BLOCK_INFO(unit,blk).schan;
    111       *block = schan;
    112       return SOC_E_NONE;
    113   }
    114  
    115   LOG_ERROR(BSL_LS_SOC_COMMON,
    116     (BSL_META_U(unit,
    117                 "Cant Find block-id for reg %d\n"),
    118      reg));
    119 
    120   return SOC_E_UNAVAIL;
    121 
    122 }
    123 #endif /* defined(BCM_SAND_SUPPORT) */
    124 
    125 /*
    126  * Function:
    127  *      soc_misc_init
    128  * Purpose:
    129  *      Initialize miscellaneous chip registers
    130  * Parameters:
    131  *      unit - unit number
    132  * Returns:
    133  *      SOC_E_XXX
    134  */
    135 int
    136 soc_misc_init(int unit)
    137 {
    138     LOG_VERBOSE(BSL_LS_SOC_COMMON,
    139                 (BSL_META_U(unit,
    140                             "soc_misc_init\n")));
    141 
    142     if (!soc_attached(unit)) {
    143         return SOC_E_INIT;
    144     }
    145 
    146     if (SOC_IS_RCPU_ONLY(unit)) {
    147         return SOC_E_NONE;
    148     }
    149 
    150     /* Perform Chip-Dependent Initializations */
    151 
    152     if (SOC_FUNCTIONS(unit)) {
    153         if (SOC_FUNCTIONS(unit)->soc_misc_init) {
    154 #ifdef BCM_XGS_SUPPORT
    155             if (SOC_IS_XGS(unit)) {
    156                 /* Enable accelerated mem clear in case misc init is called
    157                    again */
    158                 SOC_MEM_CLEAR_HW_ACC_SET(unit, 1);
    159             }
    160 #endif /* BCM_XGS_SUPPORT */
    161             SOC_IF_ERROR_RETURN(SOC_FUNCTIONS(unit)->soc_misc_init(unit));
    162 #ifdef BCM_XGS_SUPPORT
    163             if (SOC_IS_XGS(unit)) {
    164                 /* Disable accelerated mem clear after misc init */
    165                 SOC_MEM_CLEAR_HW_ACC_SET(unit, 0);
    166             }
    167 #endif /* BCM_XGS_SUPPORT */
    168         }
    169 
    170 #ifdef INCLUDE_AVS
    171         if (soc_feature(unit, soc_feature_avs_openloop)) {
    172             soc_avs_openloop_main(unit);
    173         }
    174 #endif /* INCLUDE_AVS  */
    175 
    176     }
    177 
    178 #if defined(PORTMOD_SUPPORT) && defined(BCM_ESW_SUPPORT)
    179     if (SOC_USE_PORTCTRL(unit)) {
    180         SOC_IF_ERROR_RETURN(soc_esw_portctrl_init(unit));
    181         if (soc_property_get(unit, spn_PHY_SIMUL, 0) || SAL_BOOT_PLISIM) {
    182 #if defined (BCM_WARM_BOOT_SUPPORT)
    183             if (SOC_WARM_BOOT(unit)) {
    184                     SOC_IF_ERROR_RETURN(soc_physim_scache_recovery(unit));
    185             } else {
    186                 SOC_IF_ERROR_RETURN(soc_physim_scache_allocate(unit));
    187             }
    188 #endif /* BCM_WARM_BOOT_SUPPORT */
    189         }
    190     }
    191 #endif
    192 
    193     return SOC_E_NONE;
    194 }
    195 
    196 void
    197 soc_family_suffix_update(int unit)
    198 {
    199     soc_family_suffix[unit] = soc_property_get_str(unit, spn_SOC_FAMILY);
    200 }
    201 
    202 /*
    203  * Function:
    204  *      soc_init
    205  * Purpose:
    206  *      Initialize a StrataSwitch without resetting it.
    207  * Parameters:
    208  *      unit - StrataSwitch unit #
    209  * Returns:
    210  *      SOC_E_XXX
    211  */
    212 int
    213 soc_init(int unit)
    214 {
    215     soc_family_suffix_update(unit);
    216 
    217 #if defined(BCM_PETRA_SUPPORT)
    218     if (SOC_IS_DPP(unit)) {
    219         return (soc_dpp_init(unit, SOC_DPP_RESET_ACTION_OUT_RESET));
    220     }
    221 #endif /* defined(BCM_PETRA_SUPPORT) */
    222 #if defined(BCM_DFE_SUPPORT)
    223     if(SOC_IS_DFE(unit)) {
    224         return (soc_dfe_init(unit,FALSE));
    225     }
    226 #endif /*  defined(BCM_DFE_SUPPORT)  */
    227 #if defined(BCM_DNXF_SUPPORT)
    228     if(SOC_IS_DNXF(unit)) {
    229         return (soc_dnxf_init(unit,FALSE));
    230     }
    231 #endif /*  defined(BCM_DNXF_SUPPORT)  */
    232     {
    233 #ifdef BCM_ESW_SUPPORT
    234         return(soc_do_init(unit, FALSE));
    235 #endif
    236     }
    237 
    238     return SOC_E_UNAVAIL;
    239 }
    240 
    241 /*
    242  * Function:
    243  *      soc_deinit
    244  * Purpose:
    245  *      DeInitialize a Device.
    246  * Parameters:
    247  *      unit - Device unit #
    248  * Returns:
    249  *      SOC_E_XXX
    250  */
    251 int
    252 soc_deinit(int unit)
    253 {
    254 #if defined(BCM_PETRA_SUPPORT)
    255     if (SOC_IS_DPP(unit)) {
    256         return (soc_dpp_deinit(unit));
    257     }
    258 #endif /* defined(BCM_PETRA_SUPPORT) */
    259 
    260 #if defined(BCM_DFE_SUPPORT)
    261     if (SOC_IS_DFE(unit)) {
    262         return (soc_dfe_deinit(unit));
    263     }
    264 #endif /* defined(BCM_DFE_SUPPORT) */
    265 #if defined(BCM_DNXF_SUPPORT)
    266     if (SOC_IS_DNXF(unit)) {
    267         return (soc_dnxf_deinit(unit));
    268     }
    269 #endif /* defined(BCM_DNXF_SUPPORT) */
    270     /*inform that detaching device is done*/
    271     SOC_DETACH(unit,0);
    272 
    273     return SOC_E_UNAVAIL;
    274 }
    275 
    276 /*
    277  * Function:
    278  *      soc_device_reset
    279  * Purpose:
    280  *      Perform different device reset modes/actions.
    281  * Parameters:
    282  *      unit - Device unit #
    283  *      mode - reset mode: hard reset, soft reset, init ....
    284  *      action - im/out/inout.
    285  * Returns:
    286  *      SOC_E_XXX
    287  */
    288 int
    289 soc_device_reset(int unit, int mode, int action)
    290 {
    291 
    292 #if defined(BCM_PETRA_SUPPORT)
    293     if (SOC_IS_DPP(unit)) {
    294         return (soc_dpp_device_reset(unit, mode, action));
    295     }
    296 #endif /* defined(BCM_PETRA_SUPPORT) */
    297 
    298 #if defined(BCM_DNX_SUPPORT)
    299     if (SOC_IS_DNX(unit)) {
    300         return (soc_dnx_device_reset(unit, mode, action));
    301     }
    302 #endif
    303 
    304 #ifdef BCM_DFE_SUPPORT
    305     if (SOC_IS_DFE(unit))
    306     {
    307         return (soc_dfe_device_reset(unit, mode, action));
    308     }
    309 #endif
    310 
    311 #ifdef BCM_DNXF_SUPPORT
    312     if (SOC_IS_DNXF(unit))
    313     {
    314         return (soc_dnxf_device_reset(unit, mode, action));
    315     }
    316 #endif
    317 
    318     return SOC_E_UNAVAIL;
    319 }
    320 
    321 /*
    322  * Function:
    323  *      soc_reset_init
    324  * Purpose:
    325  *      Reset and initialize a StrataSwitch.
    326  * Parameters:
    327  *      unit - StrataSwitch unit #
    328  * Returns:
    329  *      SOC_E_XXX
    330  */
    331 int
    332 soc_reset_init(int unit)
    333 {
    334     soc_family_suffix[unit] = soc_property_get_str(unit, spn_SOC_FAMILY);
    335 #if defined(BCM_PETRA_SUPPORT)
    336     if (SOC_IS_DPP(unit)) {
    337         return (soc_dpp_init(unit, SOC_DPP_RESET_ACTION_INOUT_RESET));
    338     } else
    339 #endif /* defined(BCM_PETRA_SUPPORT) */
    340 #if defined(BCM_DFE_SUPPORT)
    341     if (SOC_IS_DFE(unit)) {
    342         return (soc_dfe_init(unit, TRUE));
    343     } else
    344 #endif /* BCM_DFE_SUPPORT */
    345 #if defined(BCM_DNXF_SUPPORT)
    346     if (SOC_IS_DNXF(unit)) {
    347         return (soc_dnxf_init(unit, TRUE));
    348     } else
    349 #endif /* BCM_DNXF_SUPPORT */
    350     {
    351 #ifdef BCM_ESW_SUPPORT
    352         return(soc_do_init(unit, TRUE));
    353 #endif
    354     }
    355 
    356     return SOC_E_UNAVAIL;
    357 }
    358 
    359 /*
    360  * Function:
    361  *    soc_dev_name
    362  * Purpose:
    363  *    Return official name (or optionally nickname) of attached chip.
    364  * Parameters:
    365  *      unit - unit number
    366  * Returns:
    367  *    Pointer to static string
    368  */
    369 
    370 const char *
    371 soc_dev_name(int unit)
    372 {
    373     const char *name = soc_cm_get_name(unit);
    374     return (name == NULL ? "<UNKNOWN>" : name);
    375 }
    376 
    377 /*
    378  * Function:
    379  *    soc_attached
    380  * Purpose:
    381  *    Check if a specified SOC device is probed and attached.
    382  * Returns:
    383  *    TRUE if attached, FALSE otherwise.
    384  */
    385 int
    386 soc_attached(int unit)
    387 {
    388     if (!SOC_UNIT_VALID(unit)) {
    389         return(0);
    390     }
    391 
    392     return ((SOC_CONTROL(unit)->soc_flags & SOC_F_ATTACHED) != 0);
    393 }
    394 
    395 /*
    396  * Function:
    397  *      _str_to_val
    398  * Purpose:
    399  *      Convert string to value
    400  * Parameters:
    401  *      str - (IN) value string
    402  *      val - (OUT) converted value
    403  *      scale - (IN) scale up factor (for decimal only)
    404  *                   1 means to multiply by 10 before return
    405  *                   2 means to multiply by 100 before return
    406  *                   ...
    407  *      suffix - (OUT) the unit specified in the property (for decimal only)
    408  *                     'b' for 100b, or 'c' for 500c, ...
    409  * Notes:
    410  *      The string is parsed as a C-style numeric constant.
    411  */
    412 STATIC char *
    413 _str_to_val(const char *str, int *val, int scale, char *suffix)
    414 {
    415     uint32 abs_val;
    416     int neg, base, shift;
    417     unsigned char symbol;
    418 
    419     if (*str == '0' && str[1] != '.' && str[1] != ',') {
    420         str++;
    421 
    422         symbol = *str | 0x20;
    423         if (symbol == 'x') { /* hexadecimal */
    424             str++;
    425             for (abs_val = 0; *str != '\0'; str++) {
    426                 symbol = *str - '0';
    427                 if (symbol < 10) {
    428                     abs_val = (abs_val << 4) | symbol;
    429                     continue;
    430                 }
    431                 symbol = (*str | 0x20) - 'a';
    432                 if (symbol < 6) {
    433                     abs_val = (abs_val << 4) | (symbol + 10);
    434                     continue;
    435                 }
    436                 break;
    437             }
    438         } else {
    439             if (symbol == 'b') { /* binary */
    440                 base = 2;
    441                 shift = 1;
    442                 str++;
    443             } else { /* octal */
    444                 base = 8;
    445                 shift = 3;
    446             }
    447             for (abs_val = 0; *str != '\0'; str++) {
    448                 symbol = *str - '0';
    449                 if (symbol < base) {
    450                     abs_val = (abs_val << shift) | symbol;
    451                     continue;
    452                 }
    453                 break;
    454             }
    455         }
    456         *val = abs_val;
    457         *suffix = (*str == ',') ? ',' : '\0';
    458     } else {
    459         if (*str == '-') {
    460             str++;
    461             neg = TRUE;
    462         } else {
    463             neg = FALSE;
    464         }
    465         for (abs_val = 0; *str != '\0'; str++) {
    466             symbol = *str - '0';
    467             if (symbol < 10) {
    468                 abs_val = abs_val * 10 + symbol;
    469                 continue;
    470             }
    471             break;
    472         }
    473         if (*str == '.') {
    474             str++;
    475             for (; scale > 0 && *str != '\0'; scale--, str++) {
    476                 symbol = *str - '0';
    477                 if (symbol < 10) {
    478                     abs_val = abs_val * 10 + symbol;
    479                     continue;
    480                 }
    481                 break;
    482             }
    483         }
    484         for (; scale > 0; scale--) {
    485             abs_val *= 10;
    486         }
    487 
    488         *val = neg ? -(int)abs_val : (int)abs_val;
    489         *suffix = *str;
    490     }
    491 
    492     return (char *)str;
    493 }
    494 
    495 /*
    496  * Function:
    497  *  soc_property_get_str
    498  * Purpose:
    499  *  Retrieve a global configuration property string.
    500  * Parameters:
    501  *  unit - unit number
    502  *  name - base name of property to look up
    503  * Notes:
    504  *  Each property requested is looked up with one suffix after
    505  *  another until it is found.  Suffixes are tried in the following
    506  *  order:
    507  *  .<unit-num>     (e.g. ".0")
    508  *  .<CHIP_TYPE>    (e.g. BCM5680_B0)
    509  *  .<CHIP_GROUP>   (e.g. BCM5680)
    510  *  <nothing>
    511  */
    512 char *
    513 soc_property_get_str(int unit, const char *name)
    514 {
    515     if (unit >= 0) {
    516         /* length of name + \0 */
    517         int     l = sal_strlen(name) + 1;
    518         int     ltemp;
    519         char    name_exp[SOC_PROPERTY_NAME_MAX], *s;
    520 
    521         if (sal_snprintf(name_exp, SOC_PROPERTY_NAME_MAX,  
    522                          "%s.%d", name, unit) >= SOC_PROPERTY_NAME_MAX) {
    523             LOG_ERROR(BSL_LS_SOC_COMMON,
    524               (BSL_META_U(unit,
    525                           "Unsupported soc_property length for %s.%d. "
    526                           "Max soc property length:%d\n"), 
    527                name, unit, SOC_PROPERTY_NAME_MAX));
    528             return NULL;
    529         }
    530         if ((s = soc_cm_config_var_get(unit, name_exp)) != NULL) {
    531             return s;
    532         }
    533 
    534         /* Remaining operations require that the unit is attached */
    535         if (soc_attached(unit)) {
    536 
    537             ltemp = sal_strlen(SOC_UNIT_NAME(unit));
    538 
    539             /* check the length of <name>.<unit_name>\0 */
    540             if ((l + 1 + ltemp) > SOC_PROPERTY_NAME_MAX) {
    541                 return NULL;
    542             }
    543             sal_strncpy(name_exp + l, SOC_UNIT_NAME(unit), ltemp);
    544             if (ltemp)
    545                 *(name_exp + l + ltemp) = '\0';
    546             if ((s = soc_cm_config_var_get(unit, name_exp)) != NULL) {
    547                 return s;
    548             }
    549 
    550             ltemp = sal_strlen(SOC_UNIT_GROUP(unit));
    551 
    552 #if defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPORT)
    553             /*
    554              * Reading <name>.<group name>_<revision name>
    555              * For example: BCM8869X_B0
    556              * Assuming: <group name> and <chip name without revision> are different but has the same length
    557              */
    558             if (soc_feature(unit, soc_feature_prop_suffix_group_with_revision))
    559             {
    560                 int ltemp_unit_name;
    561                 ltemp_unit_name = sal_strlen(SOC_UNIT_NAME(unit));
    562                 sal_strncpy(name_exp + l, SOC_UNIT_NAME(unit), ltemp_unit_name);
    563                 sal_strncpy(name_exp + l, SOC_UNIT_GROUP(unit), ltemp);
    564                 if (ltemp)
    565                     *(name_exp + l + ltemp_unit_name) = '\0';
    566                 if ((s = soc_cm_config_var_get(unit, name_exp)) != NULL) {
    567                     return s;
    568                 }
    569             }
    570 #endif /*BCM_DNX_SUPPORT || BCM_DNXF_SUPPORT */
    571 
    572 #if defined(BCM_DNX_SUPPORT) && defined(ADAPTER_SERVER_MODE)
    573             if (SOC_IS_DNX(unit)){
    574                 int len_adapter;
    575                 len_adapter = sal_strlen(DRV_ADAPTER_SERVER_SUFFIX);
    576 
    577                 /* check the length of <name>.<unit_group>_ADAPTER */
    578                 if ((l + 1 + ltemp + len_adapter) > SOC_PROPERTY_NAME_MAX) {
    579                     return NULL;
    580                 }
    581                 sal_strncpy(name_exp + l, SOC_UNIT_GROUP(unit), ltemp);
    582                 sal_strncpy(name_exp + l + ltemp, DRV_ADAPTER_SERVER_SUFFIX, len_adapter);
    583                 if (ltemp)
    584                     *(name_exp + l + ltemp + len_adapter) = '\0';
    585                 if ((s = soc_cm_config_var_get(unit, name_exp)) != NULL) {
    586                     return s;
    587                 }
    588             }
    589 #endif /*BCM_DNX_SUPPORT && ADAPTER_SERVER_MODE*/
    590 
    591             /* check the length of <name>.<unit_group> */
    592             if ((l + 1 + ltemp) > SOC_PROPERTY_NAME_MAX) {
    593                 return NULL;
    594             }
    595             sal_strncpy(name_exp + l, SOC_UNIT_GROUP(unit), ltemp);
    596             if (ltemp)
    597                 *(name_exp + l + ltemp) = '\0';
    598             if ((s = soc_cm_config_var_get(unit, name_exp)) != NULL) {
    599                 return s;
    600             }
    601 
    602 #if defined(BCM_PETRA_SUPPORT)
    603             /* workaround to include 88375,88680 in 88675 */
    604             if ( (sal_strstr(SOC_UNIT_GROUP(unit),"BCM88375")) || (sal_strstr(SOC_UNIT_GROUP(unit),"BCM88680")) ) {
    605                 sal_strncpy(name_exp + l, "BCM88675", ltemp);
    606             } else if ( sal_strstr(SOC_UNIT_GROUP(unit),"BCM88270") ) {
    607             /* workaround to include 88270 in 88470 */
    608                 sal_strncpy(name_exp + l, "BCM88470", ltemp);
    609             }
    610             if (ltemp)
    611                 *(name_exp + l + ltemp) = '\0';
    612             if ((s = soc_cm_config_var_get(unit, name_exp)) != NULL) {
    613                 return s;
    614             }
    615 #endif
    616 
    617             if (soc_family_suffix[unit]) {
    618                 ltemp = sal_strlen(soc_family_suffix[unit]);
    619 
    620                 /* check the length of <name>.<soc_family_suffix> */
    621                 if ((l + 1 + ltemp) > SOC_PROPERTY_NAME_MAX) {
    622                     return NULL;
    623                 }
    624                 sal_strncpy(name_exp + l, soc_family_suffix[unit], ltemp);
    625                 if (ltemp)
    626                     *(name_exp + l + ltemp) = '\0';
    627                 if ((s = soc_cm_config_var_get(unit, name_exp)) != NULL) {
    628                     return s;
    629                 }
    630             }
    631         }
    632     }
    633 
    634     return soc_cm_config_var_get(unit, name);
    635 }
    636 
    637 /*
    638  * Function:
    639  *      soc_property_get
    640  * Purpose:
    641  *      Retrieve a global configuration numeric value.
    642  * Parameters:
    643  *      unit - unit number
    644  *      name - base name of numeric property to look up
    645  *      defl - default value of numeric property
    646  * Notes:
    647  *      See soc_property_get_str for suffix handling.
    648  *      The string is parsed as a C-style numeric constant.
    649  */
    650 
    651 uint32
    652 soc_property_get(int unit, const char *name, uint32 defl)
    653 {
    654     char        *s;
    655 
    656     if ((s = soc_property_get_str(unit, name)) == NULL) {
    657         return defl;
    658     }
    659 
    660     return _shr_ctoi(s);
    661 }
    662 
    663 /*
    664  * Function:
    665  *      soc_property_obj_attr_get
    666  * Purpose:
    667  *      Retrieve a global configuration numeric value and its unit for the
    668  *      specified prefix, object and attribute.
    669  * Parameters:
    670  *      unit - unit number
    671  *      prefix - prefix name of the numeric property to look up
    672  *      obj - object name of the numeric property to look up
    673  *      index - object index of the numeric property to look up
    674  *      attr - attribute name of the numeric property to look up
    675  *      scale - scale up factor (see _str_to_val)
    676  *      suffix - the unit specified in the property (see _str_to_val)
    677  *      defl - default value of numeric property
    678  * Notes:
    679  *      The variable name is lookup up with a number of object suffixes
    680  *      until it is found.
    681  *              prefix.obj1.attr    attribute of a particular object instance
    682  *              prefix.obj.attr     attribute of the object type
    683  *      If none are found then the default value in defl is returned.
    684  *      See soc_property_get_str for other suffix handling in property name.
    685  *      See _str_to_val for value string handling.
    686  *      The string is parsed as a C-style numeric constant.
    687  */
    688 
    689 uint32
    690 soc_property_obj_attr_get(int unit, const char *prefix, const char *obj,
    691                           int index, const char *attr, int scale,
    692                           char *suffix, uint32 defl)
    693 {
    694     char        *str;
    695     int         val;
    696     char        prop[SOC_PROPERTY_NAME_MAX];
    697 
    698     str = NULL;
    699 
    700 
    701     if (index != -1) {
    702         if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
    703                          "%s.%s%d.%s", prefix, obj, index, attr) >= SOC_PROPERTY_NAME_MAX) {
    704             LOG_ERROR(BSL_LS_SOC_COMMON,
    705               (BSL_META_U(unit,
    706                           "Unsupported soc_property length for %s.%s%d.%s. "
    707                           "Max soc property length:%d\n"), 
    708                prefix, obj, index, attr, SOC_PROPERTY_NAME_MAX));
    709             return defl; 
    710         }
    711         str = soc_property_get_str(unit, prop);
    712     }
    713 
    714     if (str == NULL) {
    715         if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
    716                          "%s.%s.%s", prefix, obj, attr) >= SOC_PROPERTY_NAME_MAX) {
    717             LOG_ERROR(BSL_LS_SOC_COMMON,
    718               (BSL_META_U(unit,
    719                           "Unsupported soc_property length for %s.%s.%s. "
    720                           "Max soc property length:%d\n"), 
    721                prefix, obj, attr, SOC_PROPERTY_NAME_MAX));
    722             return defl; 
    723         }
    724         str = soc_property_get_str(unit, prop);
    725     }
    726 
    727     if (str == NULL) {
    728         return defl;
    729     }
    730 
    731     (void)_str_to_val(str, &val, scale, suffix);
    732     return (uint32)val;
    733 }
    734 
    735 /*
    736  * Function:
    737  *      soc_property_get_pbmp
    738  * Purpose:
    739  *      Retrieve a global configuration bitmap value.
    740  * Parameters:
    741  *      unit - unit number
    742  *      name - base name of numeric property to look up
    743  *      defneg - should default bitmap be all 1's?
    744  * Notes:
    745  *      See soc_property_get_str for suffix handling.
    746  *      The string can be more than 32 bits worth of
    747  *      data if it is in hex format (0x...).  If not
    748  *      hex, it is treated as a 32 bit value.
    749  */
    750 
    751 pbmp_t
    752 soc_property_get_pbmp(int unit, const char *name, int defneg)
    753 {
    754     pbmp_t      bm;
    755     char        *s;
    756 
    757     if ((s = soc_property_get_str(unit, name)) == NULL) {
    758         SOC_PBMP_CLEAR(bm);
    759         if (defneg) {
    760             SOC_PBMP_NEGATE(bm, bm);
    761         }
    762         return bm;
    763     }
    764     if (_shr_pbmp_decode(s, &bm) < 0) {
    765         SOC_PBMP_CLEAR(bm);
    766     }
    767     return bm;
    768 }
    769 
    770 /*
    771  * Function:
    772  *      soc_property_get_pbmp_default
    773  * Purpose:
    774  *      Retrieve a global configuration bitmap value with specific default.
    775  * Parameters:
    776  *      unit - unit number
    777  *      name - base name of numeric property to look up
    778  *      def_pbmp - default bitmap
    779  * Notes:
    780  *      See soc_property_get_str for suffix handling.
    781  *      The string can be more than 32 bits worth of
    782  *      data if it is in hex format (0x...).  If not
    783  *      hex, it is treated as a 32 bit value.
    784  */
    785 
    786 pbmp_t
    787 soc_property_get_pbmp_default(int unit, const char *name,
    788                               pbmp_t def_pbmp)
    789 {
    790     pbmp_t      bm;
    791     char        *s;
    792 
    793     if ((s = soc_property_get_str(unit, name)) == NULL) {
    794         SOC_PBMP_ASSIGN(bm, def_pbmp);
    795         return bm;
    796     }
    797     if (_shr_pbmp_decode(s, &bm) < 0) {
    798         SOC_PBMP_CLEAR(bm);
    799     }
    800     return bm;
    801 }
    802 
    803 /*
    804  * Function:
    805  *      soc_property_suffix_num_str_get
    806  * Purpose:
    807  *      Retrieve a per-enumerated suffix global configuration bitmap value.
    808  * Parameters:
    809  *      unit - unit number
    810  *      num - enumerated suffix for which property is applicable
    811  *      name - base name of numeric property to look up
    812  *      suffix - suffix of numeric property to look up
    813  *      pbmp_def - default value of bitmap property
    814  * Notes:
    815  *      The variable name is lookup up with a number of suffixes
    816  *      until it is found.
    817  *              name_"suffix"0  enumerated suffix name
    818  *              name            plain name
    819  *      If none are found then the default value in pbmp_def is returned.
    820  *      See soc_property_get_str for additional suffix handling.
    821  *      The string is parsed as an hexadecimal value
    822  */
    823 
    824 pbmp_t
    825 soc_property_suffix_num_pbmp_get(int unit, int num, const char *name,
    826                             const char *suffix, soc_pbmp_t pbmp_def)
    827 {
    828     pbmp_t      bm;
    829     char        *s;
    830 
    831     if ((s = soc_property_suffix_num_str_get(unit, num, name, suffix)) == NULL) {
    832         SOC_PBMP_ASSIGN(bm, pbmp_def);
    833         return bm;
    834     }
    835     if (_shr_pbmp_decode(s, &bm) < 0) {
    836         SOC_PBMP_ASSIGN(bm, pbmp_def);
    837     }
    838     return bm;
    839 }
    840 
    841 
    842 /*
    843  * Function:
    844  *      soc_property_get_bitmap_default
    845  * Purpose:
    846  *      Retrieve a global configuration bitmap value with specific default.
    847  * Parameters:
    848  *      unit - unit number
    849  *      name - base name of numeric property to look up
    850  *      def_bitmap - default bitmap
    851  *      bitmap - reterived bitmap
    852  * Notes:
    853  *      See soc_property_get_str for suffix handling.
    854  *      The string can be more than 32 bits worth of
    855  *      data if it is in hex format (0x...).  If not
    856  *      hex, it is treated as a 32 bit value.
    857  */
    858 
    859 void
    860 soc_property_get_bitmap_default(int unit, const char *name,
    861                               uint32 *bitmap, int max_words, uint32 *def_bitmap)
    862 {
    863     char        *s;
    864 
    865     if ((s = soc_property_get_str(unit, name)) == NULL) {
    866         sal_memcpy(bitmap, def_bitmap, sizeof(uint32) * max_words);
    867         return;
    868     }
    869     if (shr_bitop_str_decode(s, bitmap, max_words) < 0) {
    870         sal_memset(bitmap, 0, sizeof(uint32) * max_words);
    871         return;
    872     }
    873 }
    874 
    875 /*
    876  * Function:
    877  *      soc_property_get_csv
    878  * Purpose:
    879  *      Retrieve a global configuration comma-separated value in an array.
    880  * Parameters:
    881  *      unit - unit number
    882  *      name - base name of numeric property to look up
    883  *      val_array - Integer array to put the values
    884  *      val_max - Maximum number of elements to put into the array
    885  * Notes:
    886  *      Returns the count of values read.
    887  */
    888 
    889 int
    890 soc_property_get_csv(int unit, const char *name,
    891                           int val_max, int *val_array)
    892 {
    893     char *str, suffix;
    894     int count;
    895 
    896     str = soc_property_get_str(unit, name);
    897     if (str == NULL) {
    898         return 0;
    899     }
    900 
    901     count = 0;
    902     for (count = 0; count < val_max; count++) {
    903         str = _str_to_val(str, &val_array[count], 0, &suffix);
    904         if (suffix == ',') {
    905             str++;
    906         } else {
    907             count++;
    908             break;
    909         }
    910     }
    911 
    912     return count;
    913 }
    914 
    915 /*
    916  * Function:
    917  *      soc_property_port_get
    918  * Purpose:
    919  *      Retrieve a per-port global configuration value
    920  * Parameters:
    921  *      unit - unit number
    922  *      port - Zero-based port number.
    923  *      name - base name of numeric property to look up
    924  *      defl - default value of numeric property
    925  * Notes:
    926  *      The variable name is lookup up with a number of suffixes
    927  *      until it is found.
    928  *              name_fe0        port name
    929  *              name_fe         port type
    930  *              name_port1      logical port number (one based)
    931  *              name.port1      physical port number (one based)
    932  *              name_1          BCM API port number (untranslated)
    933  *              name            plain name
    934  *      If none are found then NULL is returned
    935  *      See soc_property_get_str for additional suffix handling.
    936  *      The string is parsed as a C-style numeric constant.
    937  */
    938 
    939 char *
    940 soc_property_port_get_str(int unit, soc_port_t port,
    941                           const char *name)
    942 {
    943     char        *s, *p;
    944     char        prop[SOC_PROPERTY_NAME_MAX], prop_alter[SOC_PROPERTY_NAME_MAX];
    945     int         pno;
    946 
    947     /*
    948      * Try "name_fe0" if in valid range (can be out of range for
    949      * subport / internal)
    950      */
    951     if (port < SOC_MAX_NUM_PORTS) {        
    952         
    953         if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
    954                          "%s_%s", name, SOC_PORT_NAME(unit, port)) >= SOC_PROPERTY_NAME_MAX) {
    955             LOG_ERROR(BSL_LS_SOC_COMMON,
    956               (BSL_META_U(unit,
    957                           "Unsupported soc_property length for %s_%s. "
    958                           "Max soc property length:%d\n"), 
    959                name, SOC_PORT_NAME(unit, port), SOC_PROPERTY_NAME_MAX));
    960             return NULL; 
    961         }
    962 
    963         if ((s = soc_property_get_str(unit, prop)) != NULL) {
    964             return s;
    965         }
    966 
    967         /* Try alternative name if available */
    968         if (SOC_PORT_NAME_ALTER_VALID(unit, port))
    969         {
    970             if (sal_snprintf(prop_alter, SOC_PROPERTY_NAME_MAX, 
    971                              "%s_%s", name, SOC_PORT_NAME_ALTER(unit, port)) >= SOC_PROPERTY_NAME_MAX) {
    972                 LOG_ERROR(BSL_LS_SOC_COMMON,
    973                   (BSL_META_U(unit,
    974                               "Unsupported soc_property length for %s_%s. "
    975                               "Max soc property length:%d\n"), 
    976                    name, SOC_PORT_NAME_ALTER(unit, port), SOC_PROPERTY_NAME_MAX));
    977                 return NULL; 
    978             }
    979 
    980             if ((s = soc_property_get_str(unit, prop_alter)) != NULL) {
    981                 return s;
    982             }
    983         }
    984 
    985         /* Try "name_fe" (strip off trailing digits) */
    986         p = &prop[sal_strlen(prop)-1];
    987         while (*p >= '0' && *p <= '9') {
    988           --p;
    989         }
    990         *++p = '\0';
    991         if ((s = soc_property_get_str(unit, prop)) != NULL) {
    992           return s;
    993         }
    994 
    995         /* Try alternative name if available */
    996         if (SOC_PORT_NAME_ALTER_VALID(unit, port))
    997         {
    998             p = &prop_alter[sal_strlen(prop_alter)-1];
    999             while (*p >= '0' && *p <= '9') {
   1000               --p;
   1001             }
   1002             *++p = '\0';
   1003             if ((s = soc_property_get_str(unit, prop_alter)) != NULL) {
   1004               return s;
   1005             }
   1006         }
   1007     }
   1008 
   1009     /* Try "name.port%d" for explicit match first */
   1010     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1011                      "%s.port%d", name, port+1) >= SOC_PROPERTY_NAME_MAX) {
   1012         LOG_ERROR(BSL_LS_SOC_COMMON,
   1013           (BSL_META_U(unit,
   1014                       "Unsupported soc_property length for %s.port%d. "
   1015                       "Max soc property length:%d\n"), 
   1016            name, port+1, SOC_PROPERTY_NAME_MAX));
   1017         return NULL; 
   1018     }
   1019     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1020         return s;
   1021     }
   1022 
   1023     /*
   1024      * Try "name_port1": search for matching port number.
   1025      * In the case of the SOC_PORT macros, "port" is being
   1026      * passed in as a ptype, not a variable.
   1027      */
   1028     for (pno = 0; pno < SOC_PORT_NUM(unit, port); pno++) {
   1029         if (SOC_PORT(unit, port, pno) == port) {
   1030             if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1031                              "%s_port%d", name, pno+1) >= SOC_PROPERTY_NAME_MAX) {
   1032                 LOG_ERROR(BSL_LS_SOC_COMMON,
   1033                   (BSL_META_U(unit,
   1034                               "Unsupported soc_property length for %s.port%d. "
   1035                               "Max soc property length:%d\n"), 
   1036                    name, pno+1, SOC_PROPERTY_NAME_MAX));
   1037                 return NULL; 
   1038             }
   1039             if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1040                 return s;
   1041             }            
   1042             break;
   1043         }
   1044     }
   1045 
   1046 
   1047     /* Try "name_%d" for raw logical port match */
   1048     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1049                      "%s_%d", name, port) >= SOC_PROPERTY_NAME_MAX) {
   1050         LOG_ERROR(BSL_LS_SOC_COMMON,
   1051           (BSL_META_U(unit,
   1052                       "Unsupported soc_property length for %s_%d. "
   1053                       "Max soc property length:%d\n"), 
   1054            name, port, SOC_PROPERTY_NAME_MAX));
   1055         return NULL; 
   1056     }
   1057     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1058         return s;
   1059     }
   1060 
   1061     /* try plain "name" */
   1062 
   1063     if ((s = soc_property_get_str(unit, name)) != NULL) {
   1064         return s;
   1065     }
   1066 
   1067     return NULL;
   1068 }
   1069 
   1070 /*
   1071  * Function:
   1072  *      soc_property_port_get
   1073  * Purpose:
   1074  *      Retrieve a per-port global configuration numeric value.
   1075  * Parameters:
   1076  *      unit - unit number
   1077  *      port - Zero-based port number.
   1078  *      name - base name of numeric property to look up
   1079  *      defl - default value of numeric property
   1080  * Notes:
   1081  *      See soc_property_port_get_str for parsing details.
   1082  */
   1083 
   1084 uint32
   1085 soc_property_port_get(int unit, soc_port_t port,
   1086                       const char *name, uint32 defl)
   1087 {
   1088     char        *s;
   1089 
   1090     s = soc_property_port_get_str(unit, port, name);
   1091     if (s) {
   1092       return _shr_ctoi(s);
   1093     }
   1094 
   1095     return defl;
   1096 }
   1097 
   1098 /*
   1099  * Function:
   1100  *      soc_property_port_num_get
   1101  * Purpose:
   1102  *      Retrieve a per-port global configuration value
   1103  * Parameters:
   1104  *      unit - unit number
   1105  *      port - Zero-based port number.
   1106  *      name - base name of numeric property to look up
   1107  *      defl - default value of numeric property
   1108  * Notes:
   1109  *      The variable name is lookup up with a number of suffixes
   1110  *      until it is found.
   1111  *              name_1          BCM API port number (untranslated)
   1112  *      If none are found then NULL is returned
   1113  *      See soc_property_get_str for additional suffix handling.
   1114  *      The string is parsed as a C-style numeric constant.
   1115  */
   1116 
   1117 char *
   1118 soc_property_port_num_get_str(int unit, soc_port_t port,
   1119                           const char *name)
   1120 {
   1121     char        *s;
   1122     char        prop[SOC_PROPERTY_NAME_MAX];
   1123 
   1124     /* Try "name_%d" for raw logical port match */
   1125     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1126                      "%s_%d", name, port) >= SOC_PROPERTY_NAME_MAX) {
   1127         LOG_ERROR(BSL_LS_SOC_COMMON,
   1128           (BSL_META_U(unit,
   1129                       "Unsupported soc_property length for %s_%d. "
   1130                       "Max soc property length:%d\n"), 
   1131            name, port, SOC_PROPERTY_NAME_MAX));
   1132         return NULL; 
   1133     }
   1134     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1135         return s;
   1136     }
   1137 
   1138     return NULL;
   1139 }
   1140 
   1141 /*
   1142  * Function:
   1143  *      soc_property_port_num_get
   1144  * Purpose:
   1145  *      Retrieve a per-port global configuration numeric value.
   1146  * Parameters:
   1147  *      unit - unit number
   1148  *      port - Zero-based port number.
   1149  *      name - base name of numeric property to look up
   1150  *      defl - default value of numeric property
   1151  * Notes:
   1152  *      See soc_property_port_get_str for parsing details.
   1153  */
   1154 
   1155 uint32
   1156 soc_property_port_num_get(int unit, soc_port_t port,
   1157                       const char *name, uint32 defl)
   1158 {
   1159     char        *s;
   1160 
   1161     s = soc_property_port_num_get_str(unit, port, name);
   1162     if (s) {
   1163       return _shr_ctoi(s);
   1164     }
   1165 
   1166     return defl;
   1167 }
   1168 
   1169 /*
   1170  * Function:
   1171  *      soc_property_phy_get_str
   1172  * Purpose:
   1173  *      Retrieve a per-phy global configuration value
   1174  * Parameters:
   1175  *      unit - unit number
   1176  *      pport - physical port number
   1177  *      phy_num - PHY number in chain (1: innermost external PHY)
   1178  *      phy_port - PHY port (0:line, 1:system)
   1179  *      lane - PHY lane number on selected PHY port
   1180  *      name - base name of numeric property to look up
   1181  * Notes:
   1182  *      The variable name is looked up up with a number of suffixes
   1183  *      until a match is found:
   1184  *              name{1.2}       physical port number + PHY number
   1185  *              name{1}         physical port number (match any PHY number)
   1186  *              name{1.2.0.1}   physical port number + PHY number/port/lane
   1187  *      If no match is found, then the physical port number is
   1188  *      converted to a logical port number and sent through
   1189  *      soc_property_port_get_str for additional matching.
   1190  */
   1191 
   1192 char *
   1193 soc_property_phy_get_str(int unit, int pport,
   1194                          int phy_num, int phy_port, int lane,
   1195                          const char *name)
   1196 {
   1197     char        *s;
   1198     char        prop[SOC_PROPERTY_NAME_MAX];
   1199     soc_port_t  port;
   1200     int         len;
   1201 
   1202     if (phy_num >= 0) {
   1203         /* Try "name{%d.%d.%d.%d}" for exact PHY lane match */
   1204         len = sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, "%s{%d.%d.%d.%d}",
   1205                            name, pport, phy_num, phy_port, lane);
   1206         if (len >= SOC_PROPERTY_NAME_MAX) {
   1207             LOG_ERROR(BSL_LS_SOC_COMMON,
   1208                       (BSL_META_U(unit,
   1209                                   "SOC property %s{%d.%d.%d.%d} too long. "
   1210                                   "Max soc property length: %d\n"), 
   1211                        name, pport, phy_num, phy_port, lane,
   1212                        SOC_PROPERTY_NAME_MAX));
   1213             return NULL; 
   1214         }
   1215         if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1216             return s;
   1217         }
   1218         /* Try "name{%d.%d.%d}" for exact PHY port match */
   1219         len = sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, "%s{%d.%d.%d}",
   1220                            name, pport, phy_num, phy_port);
   1221         if (len >= SOC_PROPERTY_NAME_MAX) {
   1222             LOG_ERROR(BSL_LS_SOC_COMMON,
   1223                       (BSL_META_U(unit,
   1224                                   "SOC property %s{%d.%d.%d} too long. "
   1225                                   "Max soc property length: %d\n"), 
   1226                        name, pport, phy_num, phy_port,
   1227                        SOC_PROPERTY_NAME_MAX));
   1228             return NULL; 
   1229         }
   1230         if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1231             return s;
   1232         }
   1233         /* Try "name{%d.%d}" for exact PHY match */
   1234         len = sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, "%s{%d.%d}",
   1235                            name, pport, phy_num);
   1236         if (len >= SOC_PROPERTY_NAME_MAX) {
   1237             LOG_ERROR(BSL_LS_SOC_COMMON,
   1238                       (BSL_META_U(unit,
   1239                                   "SOC property %s{%d.%d} too long. "
   1240                                   "Max soc property length: %d\n"), 
   1241                        name, pport, phy_num,
   1242                        SOC_PROPERTY_NAME_MAX));
   1243             return NULL; 
   1244         }
   1245         if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1246             return s;
   1247         }
   1248     }
   1249 
   1250     /* Try "name{%d}" for specific physical port match */
   1251     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1252                      "%s{%d}", name, pport) >= SOC_PROPERTY_NAME_MAX) {
   1253         LOG_ERROR(BSL_LS_SOC_COMMON,
   1254           (BSL_META_U(unit,
   1255                       "SOC property %s{%d} too long. "
   1256                       "Max soc property length: %d\n"), 
   1257            name, pport, SOC_PROPERTY_NAME_MAX));
   1258         return NULL; 
   1259     }
   1260     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1261         return s;
   1262     }
   1263 
   1264     if (SOC_PORT_VALID_RANGE(unit, pport)) {
   1265         port = pport;
   1266         if (soc_feature(unit, soc_feature_logical_port_num)) {
   1267             port = SOC_INFO(unit).port_p2l_mapping[pport];
   1268         }
   1269         return soc_property_port_get_str(unit, port, name);
   1270     }
   1271 
   1272     return NULL;
   1273 }
   1274 
   1275 /*
   1276  * Function:
   1277  *      soc_property_phy_get
   1278  * Purpose:
   1279  *      Retrieve a per-PHY global configuration numeric value.
   1280  * Parameters:
   1281  *      unit - unit number
   1282  *      port - physical port number
   1283  *      phy_num - PHY number in chain
   1284  *      phy_port - PHY port
   1285  *      lane - PHY lane number on selected PHY port
   1286  *      name - base name of numeric property to look up
   1287  *      defl - default value of numeric property
   1288  * Notes:
   1289  *      See soc_property_phy_get_str for parsing details.
   1290  */
   1291 
   1292 uint32
   1293 soc_property_phy_get(int unit, int port,
   1294                      int phy_num, int phy_port, int lane,
   1295                      const char *name, uint32 defl)
   1296 {
   1297     char        *s;
   1298 
   1299     s = soc_property_phy_get_str(unit, port, phy_num, phy_port, lane, name);
   1300     if (s) {
   1301         return _shr_ctoi(s);
   1302     }
   1303 
   1304     return defl;
   1305 }
   1306 
   1307 /*
   1308  * Function:
   1309  *      soc_property_phys_port_get
   1310  * Purpose:
   1311  *      Retrieve a per-physical port global configuration numeric value.
   1312  * Parameters:
   1313  *      unit - unit number
   1314  *      pport - physical port number
   1315  *      name - base name of numeric property to look up
   1316  *      defl - default value of numeric property
   1317  * Notes:
   1318  *      See soc_property_phy_get_str for parsing details.
   1319  */
   1320 
   1321 uint32
   1322 soc_property_phys_port_get(int unit, int pport,
   1323                            const char *name, uint32 defl)
   1324 {
   1325     char        *s;
   1326 
   1327     s = soc_property_phy_get_str(unit, pport, -1, -1, -1, name);
   1328     if (s) {
   1329         return _shr_ctoi(s);
   1330     }
   1331 
   1332     return defl;
   1333 }
   1334 
   1335 /*
   1336  * Function:
   1337  *      soc_property_port_obj_attr_get
   1338  * Purpose:
   1339  *      Retrieve a global configuration numeric value and its unit for the
   1340  *      specified prefix, object and attribute.
   1341  * Parameters:
   1342  *      unit - unit number
   1343  *      port - Zero-based port number.
   1344  *      prefix - prefix name of the numeric property to look up
   1345  *      obj - object name of the numeric property to look up
   1346  *      index - object index of the numeric property to look up
   1347  *      attr - attribute name of the numeric property to look up
   1348  *      scale - scale up factor (see _str_to_val)
   1349  *      suffix - the unit specified in the property (see _str_to_val)
   1350  *      defl - default value of numeric property
   1351  * Notes:
   1352  *      The variable name is lookup up with a number of object suffixes
   1353  *      until it is found.
   1354  *              prefix.obj1.attr    attribute of a particular object instance
   1355  *              prefix.obj.attr     attribute of the object type
   1356  *      If none are found then the default value in defl is returned.
   1357  *      See soc_property_port_get_str for other suffix handling in property
   1358  *      name.
   1359  *      See _str_to_val for value string handling.
   1360  *      The string is parsed as a C-style numeric constant.
   1361  */
   1362 
   1363 uint32
   1364 soc_property_port_obj_attr_get(int unit, soc_port_t port, const char *prefix,
   1365                                const char *obj, int index, const char *attr,
   1366                                int scale, char *suffix, uint32 defl)
   1367 {
   1368     char        *str;
   1369     int         val;
   1370     char        prop[SOC_PROPERTY_NAME_MAX];
   1371 
   1372     str = NULL;
   1373 
   1374     if (index != -1) {
   1375         if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1376                          "%s.%s%d.%s", prefix, obj, index, attr) >= SOC_PROPERTY_NAME_MAX) {
   1377             LOG_ERROR(BSL_LS_SOC_COMMON,
   1378               (BSL_META_U(unit,
   1379                           "Unsupported soc_property length for %s.%s%d.%s. "
   1380                           "Max soc property length:%d\n"), 
   1381                prefix, obj, index, attr, SOC_PROPERTY_NAME_MAX));
   1382             return defl; 
   1383 
   1384         }
   1385         str = soc_property_port_get_str(unit, port, prop);
   1386     }
   1387 
   1388     if (str == NULL) {
   1389         if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1390                          "%s.%s.%s", prefix, obj, attr) >= SOC_PROPERTY_NAME_MAX) {
   1391             LOG_ERROR(BSL_LS_SOC_COMMON,
   1392               (BSL_META_U(unit,
   1393                           "Unsupported soc_property length for %s.%s.%s. "
   1394                           "Max soc property length:%d\n"), 
   1395                prefix, obj, attr, SOC_PROPERTY_NAME_MAX));
   1396             return defl; 
   1397 
   1398         }
   1399         str = soc_property_port_get_str(unit, port, prop);
   1400     }
   1401 
   1402     if (str == NULL) {
   1403         return defl;
   1404     }
   1405 
   1406     (void)_str_to_val(str, &val, scale, suffix);
   1407     return (uint32)val;
   1408 }
   1409 
   1410 int
   1411 soc_property_port_get_csv(int unit, soc_port_t port, const char *name,
   1412                           int val_max, int *val_array)
   1413 {
   1414     char *str, suffix;
   1415     int count;
   1416 
   1417     str = soc_property_port_get_str(unit, port, name);
   1418     if (str == NULL) {
   1419         return 0;
   1420     }
   1421 
   1422     count = 0;
   1423     for (count = 0; count < val_max; count++) {
   1424         str = _str_to_val(str, &val_array[count], 0, &suffix);
   1425         if (suffix == ',') {
   1426             str++;
   1427         } else {
   1428             count++;
   1429             break;
   1430         }
   1431     }
   1432 
   1433     return count;
   1434 }
   1435 
   1436 /*
   1437  * Function:
   1438  *      soc_property_cos_get
   1439  * Purpose:
   1440  *      Retrieve a per-port global configuration value
   1441  * Parameters:
   1442  *      unit - unit number
   1443  *      cos - Zero-based cos number.
   1444  *      name - base name of numeric property to look up
   1445  *      defl - default value of numeric property
   1446  * Notes:
   1447  *      The variable name is lookup up with a number of suffixes
   1448  *      until it is found.
   1449  *              name.cos1       cos number (one based)
   1450  *              name            plain name
   1451  *      If none are found then NULL is returned
   1452  *      See soc_property_get_str for additional suffix handling.
   1453  *      The string is parsed as a C-style numeric constant.
   1454  */
   1455 
   1456 char *
   1457 soc_property_cos_get_str(int unit, soc_cos_t cos,
   1458                           const char *name)
   1459 {
   1460     char        *s;
   1461     char        prop[SOC_PROPERTY_NAME_MAX];
   1462 
   1463     /* try "name.cos%d" for explicit match first */
   1464     /* check length of <name>.cos<cos>\0 */
   1465     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1466                      "%s.cos%d", name, (cos + 1)) >= SOC_PROPERTY_NAME_MAX) {
   1467             LOG_ERROR(BSL_LS_SOC_COMMON,
   1468               (BSL_META_U(unit,
   1469                           "Unsupported soc_property length for %s.cos%d. "
   1470                           "Max soc property length:%d\n"), 
   1471                name, (cos + 1), SOC_PROPERTY_NAME_MAX));
   1472             return NULL; 
   1473     }
   1474     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1475         return(s);
   1476     }
   1477     /* try plain "name" */
   1478     if ((s = soc_property_get_str(unit, name)) != NULL) {
   1479         return(s);
   1480     }
   1481 
   1482     return(NULL);
   1483 }
   1484 
   1485 
   1486 /*
   1487  * Function:
   1488  *      soc_property_cos_get
   1489  * Purpose:
   1490  *      Retrieve a per-cos global configuration numeric value.
   1491  * Parameters:
   1492  *      unit - unit number
   1493  *      cos - Zero-based cos number.
   1494  *      name - base name of numeric property to look up
   1495  *      defl - default value of numeric property
   1496  * Notes:
   1497  *      The variable name is lookup up with a number of suffixes
   1498  *      until it is found.
   1499  *              name_cos1       cos number (one based)
   1500  *              name            plain name
   1501  *      If none are found then the default value in defl is returned.
   1502  *      See soc_property_get_str for additional suffix handling.
   1503  *      The string is parsed as a C-style numeric constant.
   1504  */
   1505 uint32
   1506 soc_property_cos_get(int unit, soc_cos_t cos,
   1507                                     const char *name, uint32 defl)
   1508 {
   1509     char        *s;
   1510 
   1511     s = soc_property_cos_get_str(unit, cos, name);
   1512     if (s) {
   1513       return _shr_ctoi(s);
   1514     }
   1515 
   1516     return defl;
   1517 }
   1518 
   1519 
   1520 /*
   1521  * Function:
   1522  *      soc_property_suffix_num_get
   1523  * Purpose:
   1524  *      Retrieve a per-enumerated suffix global configuration numeric value.
   1525  * Parameters:
   1526  *      unit - unit number
   1527  *      num - enumerated suffix for which property is applicable
   1528  *      name - base name of numeric property to look up
   1529  *      suffix - suffix of numeric property to look up
   1530  *      defl - default value of numeric property
   1531  * Notes:
   1532  *      The variable name is lookup up with a number of suffixes
   1533  *      until it is found.
   1534  *              name_"suffix"0  enumerated suffix name
   1535  *              name            plain name
   1536  *      If none are found then the default value in defl is returned.
   1537  *      See soc_property_get_str for additional suffix handling.
   1538  *      The string is parsed as a C-style numeric constant.
   1539  */
   1540 
   1541 uint32
   1542 soc_property_suffix_num_get(int unit, int num, const char *name,
   1543                             const char *suffix, uint32 defl)
   1544 {
   1545     char        *s;
   1546     char        prop[SOC_PROPERTY_NAME_MAX];
   1547 
   1548     /* try "name_'suffix'0" */
   1549     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1550                      "%s_%s%1d", name, suffix, num) >= SOC_PROPERTY_NAME_MAX) {
   1551         LOG_ERROR(BSL_LS_SOC_COMMON,
   1552           (BSL_META_U(unit,
   1553                       "Unsupported soc_property length for %s_%s%1d. "
   1554                       "Max soc property length:%d\n"), 
   1555            name, suffix, num, SOC_PROPERTY_NAME_MAX));
   1556         return defl; 
   1557     }
   1558     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1559         return _shr_ctoi(s);
   1560     }
   1561 
   1562     /* try "name.port%d.suffix" for explicit match first */
   1563     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1564                      "%s.port%d.%s", name, num+1, suffix) >= SOC_PROPERTY_NAME_MAX) {
   1565         LOG_ERROR(BSL_LS_SOC_COMMON,
   1566           (BSL_META_U(unit,
   1567                       "Unsupported soc_property length for %s.port%d.%s. "
   1568                       "Max soc property length:%d\n"),  
   1569            name, num+1, suffix, SOC_PROPERTY_NAME_MAX));
   1570         return defl; 
   1571     }
   1572     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1573         return _shr_ctoi(s);
   1574     }
   1575 
   1576     /* try "name_'suffix'" */
   1577     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1578                      "%s_%s", name, suffix) >= SOC_PROPERTY_NAME_MAX) {
   1579         LOG_ERROR(BSL_LS_SOC_COMMON,
   1580           (BSL_META_U(unit,
   1581                       "Unsupported soc_property length for %s_%s. "
   1582                       "Max soc property length:%d\n"),  
   1583            name, suffix, SOC_PROPERTY_NAME_MAX));
   1584         return defl; 
   1585     }
   1586     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1587         return _shr_ctoi(s);
   1588     }
   1589 
   1590     /* try plain "name" */
   1591     if ((s = soc_property_get_str(unit, name)) != NULL) {
   1592         return _shr_ctoi(s);
   1593     }
   1594 
   1595     return defl;
   1596 }
   1597 
   1598 /*
   1599  * Function:
   1600  *      soc_property_suffix_num_get_only_suffix
   1601  * Purpose:
   1602  *      Retrieve a per-enumerated suffix global configuration numeric value.
   1603  * Parameters:
   1604  *      unit - unit number
   1605  *      num - enumerated suffix for which property is applicable
   1606  *      name - base name of numeric property to look up
   1607  *      suffix - suffix of numeric property to look up
   1608  *      defl - default value of numeric property
   1609  * Notes:
   1610  *      The variable name is lookup up with a number of suffixes
   1611  *      until it is found.
   1612  *              name_"suffix"0  enumerated suffix name
   1613  *      If none are found then the default value in defl is returned.
   1614  *      See soc_property_get_str for additional suffix handling.
   1615  *      The string is parsed as a C-style numeric constant.
   1616  */
   1617 
   1618 uint32
   1619 soc_property_suffix_num_get_only_suffix(int unit, int num, const char *name,
   1620                             const char *suffix, uint32 defl)
   1621 {
   1622     char        *s;
   1623     char        prop[SOC_PROPERTY_NAME_MAX];
   1624 
   1625     /* try "name_'suffix'0" */
   1626     /* check length of <name>_<suffix><num>\0 */
   1627     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1628                      "%s_%s%1d", name, suffix, num) >= SOC_PROPERTY_NAME_MAX) {
   1629         LOG_ERROR(BSL_LS_SOC_COMMON,
   1630           (BSL_META_U(unit,
   1631                       "Unsupported soc_property length for %s_%s%1d. "
   1632                       "Max soc property length:%d\n"), 
   1633            name, suffix, num, SOC_PROPERTY_NAME_MAX));
   1634         return defl; 
   1635     }
   1636     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1637         return _shr_ctoi(s);
   1638     }
   1639 
   1640     /* try "name.port%d.suffix" for explicit match first */
   1641     /* check length of <name>.port<num>.<suffix>\0 */
   1642     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1643                      "%s.port%d.%s", name, num+1, suffix) >= SOC_PROPERTY_NAME_MAX) {
   1644         LOG_ERROR(BSL_LS_SOC_COMMON,
   1645           (BSL_META_U(unit,
   1646                       "Unsupported soc_property length for %s.port%d.%s. "
   1647                       "Max soc property length:%d\n"), 
   1648            name, num+1, suffix, SOC_PROPERTY_NAME_MAX));
   1649         return defl; 
   1650     }
   1651     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1652         return _shr_ctoi(s);
   1653     }
   1654 
   1655     /* try "name_'suffix'" */
   1656     /* check length of <name>_<suffix>\0 */
   1657     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1658                      "%s_%s", name, suffix) >= SOC_PROPERTY_NAME_MAX) {
   1659         LOG_ERROR(BSL_LS_SOC_COMMON,
   1660           (BSL_META_U(unit,
   1661                       "Unsupported soc_property length for %s_%s. "
   1662                       "Max soc property length:%d\n"), 
   1663            name, suffix, SOC_PROPERTY_NAME_MAX));
   1664         return defl; 
   1665     }
   1666     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1667         return _shr_ctoi(s);
   1668     }
   1669 
   1670     return defl;
   1671 }
   1672 
   1673 /*
   1674  * Function:
   1675  *      soc_property_suffix_num_str_get
   1676  * Purpose:
   1677  *      Retrieve a per-enumerated suffix global configuration numeric value.
   1678  * Parameters:
   1679  *      unit - unit number
   1680  *      num - enumerated suffix for which property is applicable
   1681  *      name - base name of numeric property to look up
   1682  *      suffix - suffix of numeric property to look up
   1683  *      defl - default value of numeric property
   1684  * Notes:
   1685  *      The variable name is lookup up with a number of suffixes
   1686  *      until it is found.
   1687  *              name_"suffix"0  enumerated suffix name
   1688  *              name            plain name
   1689  *      If none are found then the default value in defl is returned.
   1690  *      See soc_property_get_str for additional suffix handling.
   1691  *      The string is parsed as a C-style numeric constant.
   1692  */
   1693 
   1694 
   1695 char*
   1696 soc_property_suffix_num_str_get(int unit, int num, const char *name,
   1697                             const char *suffix)
   1698 {
   1699     char        *s;
   1700     char        prop[SOC_PROPERTY_NAME_MAX];
   1701 
   1702     /* try "name_'suffix'0" */
   1703     /* check length of <name>_<suffix>\0 */
   1704     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1705                      "%s_%s%1d", name, suffix, num) >= SOC_PROPERTY_NAME_MAX) {
   1706         LOG_ERROR(BSL_LS_SOC_COMMON,
   1707           (BSL_META_U(unit,
   1708                       "Unsupported soc_property length for %s_%s%1d. "
   1709                       "Max soc property length:%d\n"), 
   1710            name, suffix, num, SOC_PROPERTY_NAME_MAX));
   1711         return NULL; 
   1712     }
   1713     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1714         return s;
   1715     }
   1716 
   1717 
   1718     /* try "name.port%d.suffix" for explicit match first */
   1719     /* check length of <name>.port<num>.<suffix>\0 */
   1720     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1721                      "%s.port%d.%s", name, num+1, suffix) >= SOC_PROPERTY_NAME_MAX) {
   1722         LOG_ERROR(BSL_LS_SOC_COMMON,
   1723           (BSL_META_U(unit,
   1724                       "Unsupported soc_property length for %s.port%d.%s. "
   1725                       "Max soc property length:%d\n"), 
   1726            name, num+1, suffix, SOC_PROPERTY_NAME_MAX));
   1727         return NULL; 
   1728     }
   1729     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1730         return s;
   1731     }
   1732 
   1733     /* try "name_'suffix'" */
   1734     /* check length of <name>_<suffix>\0 */
   1735     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1736                      "%s_%s", name, suffix) >= SOC_PROPERTY_NAME_MAX) {
   1737         LOG_ERROR(BSL_LS_SOC_COMMON,
   1738           (BSL_META_U(unit,
   1739                       "Unsupported soc_property length for %s_%s. "
   1740                       "Max soc property length:%d\n"), 
   1741            name, suffix, SOC_PROPERTY_NAME_MAX));
   1742         return NULL; 
   1743     }
   1744     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1745         return s;
   1746     }
   1747 
   1748     /* try plain "name" */
   1749     if ((s = soc_property_get_str(unit, name)) != NULL) {
   1750         return s;
   1751     }
   1752 
   1753     return NULL;
   1754 }
   1755 
   1756 
   1757 /*
   1758  * Function:
   1759  *      soc_property_suffix_num_only_suffix_str_get
   1760  * Purpose:
   1761  *      Retrieve a per-enumerated suffix global configuration numeric value.
   1762  * Parameters:
   1763  *      unit - unit number
   1764  *      num - enumerated suffix for which property is applicable
   1765  *      name - base name of numeric property to look up
   1766  *      suffix - suffix of numeric property to look up
   1767  *      defl - default value of numeric property
   1768  * Notes:
   1769  *      The variable name is lookup up with a number of suffixes
   1770  *      until it is found.
   1771  *              name_"suffix"0  enumerated suffix name
   1772  *              name            plain name
   1773  *      If none are found then the default value in defl is returned.
   1774  *      See soc_property_get_str for additional suffix handling.
   1775  *      The string is parsed as a C-style numeric constant.
   1776  */
   1777 
   1778 
   1779 char*
   1780 soc_property_suffix_num_only_suffix_str_get(int unit, int num, const char *name,
   1781                             const char *suffix)
   1782 {
   1783     char        *s;
   1784     char        prop[SOC_PROPERTY_NAME_MAX];
   1785 
   1786     /* try "name_'suffix'0" */
   1787     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1788                      "%s_%s%1d", name, suffix, num) >= SOC_PROPERTY_NAME_MAX) {
   1789         LOG_ERROR(BSL_LS_SOC_COMMON,
   1790           (BSL_META_U(unit,
   1791                       "Unsupported soc_property length for %s_%s%1d. "
   1792                       "Max soc property length:%d\n"), 
   1793            name, suffix, num, SOC_PROPERTY_NAME_MAX));
   1794         return NULL; 
   1795     }
   1796     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1797         return s;
   1798     }
   1799 
   1800     /* try "name.port%d.suffix" for explicit match first */
   1801     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1802                      "%s.port%d.%s", name, num+1, suffix) >= SOC_PROPERTY_NAME_MAX) {
   1803         LOG_ERROR(BSL_LS_SOC_COMMON,
   1804           (BSL_META_U(unit,
   1805                       "Unsupported soc_property length for %s.port%d.%s. "
   1806                       "Max soc property length:%d\n"), 
   1807            name, num+1, suffix, SOC_PROPERTY_NAME_MAX));
   1808         return NULL; 
   1809     }
   1810     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1811         return s;
   1812     }
   1813 
   1814     /* try "name_'suffix'" */
   1815     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1816                      "%s_%s", name, suffix) >= SOC_PROPERTY_NAME_MAX) {
   1817         LOG_ERROR(BSL_LS_SOC_COMMON,
   1818           (BSL_META_U(unit,
   1819                       "Unsupported soc_property length for %s_%s. "
   1820                       "Max soc property length:%d\n"), 
   1821            name, suffix, SOC_PROPERTY_NAME_MAX));
   1822         return NULL; 
   1823 
   1824     }
   1825     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1826         return s;
   1827     }
   1828 
   1829     return NULL;
   1830 }
   1831 /*
   1832  * Function:
   1833  *      soc_property_port_suffix_num_get
   1834  * Purpose:
   1835  *      Retrieve a per-port, per-enumerated suffix global
   1836  *      configuration numeric value.
   1837  * Parameters:
   1838  *      unit - unit number
   1839  *      port - Zero-based port number.
   1840  *      num - enumerated suffix for which property is applicable
   1841  *      name - base name of numeric property to look up
   1842  *      suffix - suffix of numeric property to look up
   1843  *      defl - default value of numeric property
   1844  * Notes:
   1845  *      The variable name is lookup up with a number of suffixes
   1846  *      until it is found.
   1847  *              name_"suffix"0_port  enumerated suffix name per port
   1848  *              name_"suffix"0       enumerated suffix name
   1849  *              name_port            plain name per port
   1850  *              name                 plain name
   1851  *      If none are found then the default value in defl is returned.
   1852  *      See soc_property_get_str for additional suffix handling.
   1853  *      The string is parsed as a C-style numeric constant.
   1854  */
   1855 
   1856 uint32
   1857 soc_property_port_suffix_num_get(int unit, soc_port_t port,
   1858                                  int num, const char *name,
   1859                                  const char *suffix, uint32 defl)
   1860 {
   1861     char        *s;
   1862     char        prop[SOC_PROPERTY_NAME_MAX];
   1863 
   1864     /* "name_'suffix'#" */
   1865     /* check length of <name>_<suffix><num>\0 */
   1866     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1867                      "%s_%s%1d", name, suffix, num) >= SOC_PROPERTY_NAME_MAX) {
   1868         LOG_ERROR(BSL_LS_SOC_COMMON,
   1869           (BSL_META_U(unit,
   1870                       "Unsupported soc_property length for %s_%s%1d. "
   1871                       "Max soc property length:%d\n"), 
   1872            name, suffix, num, SOC_PROPERTY_NAME_MAX));
   1873         return defl; 
   1874     }
   1875 
   1876     /* try "name_'suffix'#" per port*/
   1877     if ((s = soc_property_port_get_str(unit, port, prop)) != NULL) {
   1878         return _shr_ctoi(s);
   1879     }
   1880 
   1881     /* try "name_'suffix'#" */
   1882     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1883         return _shr_ctoi(s);
   1884     }
   1885 
   1886     /* "name_'suffix'" */
   1887     /* check length of <name>_<suffix>\0 */
   1888     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1889                      "%s_%s", name, suffix) >= SOC_PROPERTY_NAME_MAX) {
   1890         LOG_ERROR(BSL_LS_SOC_COMMON,
   1891           (BSL_META_U(unit,
   1892                       "Unsupported soc_property length for %s_%s. "
   1893                       "Max soc property length:%d\n"), 
   1894            name, suffix, SOC_PROPERTY_NAME_MAX));
   1895         return defl; 
   1896     }
   1897     /* try "name_'suffix'" per port */
   1898     if ((s = soc_property_port_get_str(unit, port, prop)) != NULL) {
   1899         return _shr_ctoi(s);
   1900     }
   1901 
   1902     /* try "name_'suffix'"*/
   1903     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1904         return _shr_ctoi(s);
   1905     }
   1906 
   1907 
   1908     /* try plain "name" per port*/
   1909     if ((s = soc_property_port_get_str(unit, port, name)) != NULL) {
   1910         return _shr_ctoi(s);
   1911     }
   1912 
   1913     /* try plain "name" */
   1914     if ((s = soc_property_get_str(unit, name)) != NULL) {
   1915         return _shr_ctoi(s);
   1916     }
   1917 
   1918     return defl;
   1919 }
   1920 
   1921 
   1922 uint32
   1923 soc_property_port_suffix_num_match_port_get(int unit, soc_port_t port,
   1924                                  int num, const char *name,
   1925                                  const char *suffix, uint32 defl)
   1926 {
   1927     char        *s;
   1928     char        prop[SOC_PROPERTY_NAME_MAX];
   1929 
   1930     /* "name_'suffix'" */
   1931     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1932                      "%s_%s_%d", name, suffix, port) >= SOC_PROPERTY_NAME_MAX) {
   1933         LOG_ERROR(BSL_LS_SOC_COMMON,
   1934           (BSL_META_U(unit,
   1935                       "Unsupported soc_property length for %s_%s. "
   1936                       "Max soc property length:%d\n"), 
   1937            name, suffix, SOC_PROPERTY_NAME_MAX));
   1938         return defl; 
   1939     }
   1940     /* only check "name_'suffix'" per port */
   1941     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   1942         return _shr_ctoi(s);
   1943     }
   1944 
   1945     return defl;
   1946 
   1947 }
   1948 
   1949 
   1950 /*
   1951  * Function:
   1952  *      soc_property_port_suffix_num_get_str
   1953  * Purpose:
   1954  *      Retrieve a per-port, per-enumerated suffix global
   1955  *      configuration string value.
   1956  * Parameters:
   1957  *      unit - unit number
   1958  *      port - Zero-based port number.
   1959  *      num - enumerated suffix for which property is applicable
   1960  *      name - base name of numeric property to look up
   1961  *      suffix - suffix of numeric property to look up
   1962  * Notes:
   1963  *      The variable name is lookup up with a number of suffixes
   1964  *      until it is found.
   1965  *              name_"suffix"0_port  enumerated suffix name per port
   1966  *              name_"suffix"0       enumerated suffix name
   1967  *              name_port            plain name per port
   1968  *              name                 plain name
   1969  *      If none are found then the NULL is returned.
   1970  *      See soc_property_get_str for additional suffix handling.
   1971  *      The string is parsed as a C-style numeric constant.
   1972  */
   1973 
   1974 char*
   1975 soc_property_port_suffix_num_get_str(int unit, soc_port_t port,
   1976                                  int num, const char *name,
   1977                                  const char *suffix)
   1978 {
   1979     char        *s;
   1980     char        prop[SOC_PROPERTY_NAME_MAX];
   1981 
   1982     /* "name_'suffix'#" */ 
   1983     /* check length of <name>_<suffix><num>\0 */
   1984     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   1985                      "%s_%s%1d", name, suffix, num) >= SOC_PROPERTY_NAME_MAX) {
   1986         LOG_ERROR(BSL_LS_SOC_COMMON,
   1987           (BSL_META_U(unit,
   1988                       "Unsupported soc_property length for %s_%s%1d. "
   1989                       "Max soc property length:%d\n"), 
   1990            name, suffix, num, SOC_PROPERTY_NAME_MAX));
   1991         return NULL; 
   1992     }
   1993     /* try "name_'suffix'#" per port*/
   1994     if ((s = soc_property_port_get_str(unit, port, prop)) != NULL) {
   1995         return s;
   1996     }
   1997 
   1998     /* try "name_'suffix'#" */
   1999     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   2000         return s;
   2001     }
   2002 
   2003 
   2004     /* "name_'suffix'" */
   2005     /* check length of <name>_<suffix>\0 */
   2006     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   2007                      "%s_%s", name, suffix) >= SOC_PROPERTY_NAME_MAX) {
   2008         LOG_ERROR(BSL_LS_SOC_COMMON,
   2009           (BSL_META_U(unit,
   2010                       "Unsupported soc_property length for %s_%s. "
   2011                       "Max soc property length:%d\n"), 
   2012            name, suffix, SOC_PROPERTY_NAME_MAX));
   2013         return NULL;
   2014     }
   2015     /* try "name_'suffix'" per port */
   2016     if ((s = soc_property_port_get_str(unit, port, prop)) != NULL) {
   2017         return s;
   2018     }
   2019     /* try "name_'suffix'"*/
   2020     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   2021         return s;
   2022     }
   2023 
   2024     /* try plain "name" per port*/
   2025     if ((s = soc_property_port_get_str(unit, port, name)) != NULL) {
   2026         return s;
   2027     }
   2028 
   2029     /* try plain "name" */
   2030     if ((s = soc_property_get_str(unit, name)) != NULL) {
   2031         return s;
   2032     }
   2033 
   2034     return NULL;
   2035 }
   2036 
   2037 
   2038 /*
   2039  * Function:
   2040  *      soc_property_uc_get_str
   2041  * Purpose:
   2042  *      Retrieve a per-uc global configuration value
   2043  * Parameters:
   2044  *      unit - unit number
   2045  *      uc - Microcontroller number. 0 is PCI Host.
   2046  *      name - base name of numeric property to look up
   2047  * Notes:
   2048  *      The variable name is lookup up with a number of suffixes
   2049  *      until it is found.
   2050  *              name_"suffix"   suffix is pci | uc0 | uc1 ...
   2051  *              name            plain name
   2052  *      If none are found then NULL is returned.
   2053  *      See soc_property_get_str for additional suffix handling.
   2054  *      The string is parsed as a C-style numeric constant.
   2055  */
   2056 char *
   2057 soc_property_uc_get_str(int unit, int uc,
   2058                           const char *name)
   2059 {
   2060     char        *s;
   2061     char        prop[SOC_PROPERTY_NAME_MAX];
   2062 
   2063     /* try "name_uc%d" for explicit match first */
   2064     if (0 == uc) {
   2065         /* check length of <name>_pci\0 */
   2066         if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX,  
   2067                          "%s_pci", name) >= SOC_PROPERTY_NAME_MAX) {
   2068             LOG_ERROR(BSL_LS_SOC_COMMON,
   2069               (BSL_META_U(unit,
   2070                           "Unsupported soc_property length for %s_pci. "
   2071                           "Max soc property length:%d\n"), 
   2072                name, SOC_PROPERTY_NAME_MAX));
   2073             return NULL;
   2074 
   2075         }
   2076         if ((s = soc_property_get_str(unit, prop)) != NULL) {
   2077             return(s);
   2078         }
   2079     } else {
   2080 
   2081         /* check length of <name>_uc<uc>\0 */
   2082         if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   2083                          "%s_uc%d", name, (uc - 1)) >= SOC_PROPERTY_NAME_MAX) {
   2084             LOG_ERROR(BSL_LS_SOC_COMMON,
   2085               (BSL_META_U(unit,
   2086                           "Unsupported soc_property length for %s_uc%d. "
   2087                           "Max soc property length:%d\n"), 
   2088                name, (uc - 1), SOC_PROPERTY_NAME_MAX));
   2089             return NULL;
   2090         }
   2091         if ((s = soc_property_get_str(unit, prop)) != NULL) {
   2092             return(s);
   2093         }
   2094     }    
   2095 
   2096     /* try plain "name" */
   2097     if ((s = soc_property_get_str(unit, name)) != NULL) {
   2098         return(s);
   2099     }
   2100 
   2101     return(NULL);
   2102 }
   2103 
   2104 /*
   2105  * Function:
   2106  *      soc_property_uc_get
   2107  * Purpose:
   2108  *      Retrieve a per-uc global configuration value
   2109  * Parameters:
   2110  *      unit - unit number
   2111  *      uc - Microcontroller number. 0 is PCI Host.
   2112  *      name - base name of numeric property to look up
   2113  *      defl - default value of numeric property
   2114  * Notes:
   2115  *      The variable name is lookup up with a number of suffixes
   2116  *      until it is found.
   2117  *              name_"suffix"   suffix is pci | uc0 | uc1 ...
   2118  *              name            plain name
   2119  *      If none are found then the default value in defl is returned.
   2120  *      See soc_property_get_str for additional suffix handling.
   2121  *      The string is parsed as a C-style numeric constant.
   2122  */
   2123 uint32
   2124 soc_property_uc_get(int unit, int uc,
   2125                     const char *name, uint32 defl)
   2126 {
   2127     char        *s;
   2128 
   2129     s = soc_property_uc_get_str(unit, uc, name);
   2130     if (s) {
   2131       return _shr_ctoi(s);
   2132     }
   2133 
   2134     return defl;
   2135 }
   2136 
   2137 /*
   2138  * Function:
   2139  *      soc_property_ci_get_str
   2140  * Purpose:
   2141  *      Retrieve a per-ci global configuration value
   2142  * Parameters:
   2143  *      unit - unit number
   2144  *      ci - Chip Intergface Number.
   2145  *      name - base name of numeric property to look up
   2146  * Notes:
   2147  *      The variable name is lookup up with a number of suffixes
   2148  *      until it is found.
   2149  *              name_"suffix"   suffix is ci0 | ci1 ...
   2150  *              name            plain name
   2151  *      If none are found then NULL is returned.
   2152  *      See soc_property_get_str for additional suffix handling.
   2153  *      The string is parsed as a C-style numeric constant.
   2154  */
   2155 char *
   2156 soc_property_ci_get_str(int unit, int ci,
   2157                           const char *name)
   2158 {
   2159     char        *s;
   2160     char        prop[SOC_PROPERTY_NAME_MAX];
   2161 
   2162     /* try "name_ci%d" for explicit match first */
   2163     /* check length of <name>_ci<ci>\0 */
   2164     if (sal_snprintf(prop, SOC_PROPERTY_NAME_MAX, 
   2165                      "%s_ci%d", name, ci) >= SOC_PROPERTY_NAME_MAX) {
   2166         LOG_ERROR(BSL_LS_SOC_COMMON,
   2167           (BSL_META_U(unit,
   2168                       "Unsupported soc_property length for %s_ci%d. "
   2169                       "Max soc property length:%d\n"), 
   2170            name, ci, SOC_PROPERTY_NAME_MAX));
   2171         return NULL;
   2172     }
   2173     if ((s = soc_property_get_str(unit, prop)) != NULL) {
   2174         return(s);
   2175     }
   2176     /* try plain "name" */
   2177     if ((s = soc_property_get_str(unit, name)) != NULL) {
   2178         return(s);
   2179     }
   2180 
   2181     return(NULL);
   2182 }
   2183 
   2184 /*
   2185  * Function:
   2186  *      soc_property_ci_get
   2187  * Purpose:
   2188  *      Retrieve a per-ci global configuration value
   2189  * Parameters:
   2190  *      unit - unit number
   2191  *      ci - Chip Intergface Number.
   2192  *      name - base name of numeric property to look up
   2193  *      defl - default value of numeric property
   2194  * Notes:
   2195  *      The variable name is lookup up with a number of suffixes
   2196  *      until it is found.
   2197  *              name_"suffix"   suffix is ci0 | ci1 ...
   2198  *              name            plain name
   2199  *      If none are found then the default value in defl is returned.
   2200  *      See soc_property_get_str for additional suffix handling.
   2201  *      The string is parsed as a C-style numeric constant.
   2202  */
   2203 uint32
   2204 soc_property_ci_get(int unit, int ci,
   2205                     const char *name, uint32 defl)
   2206 {
   2207     char        *s;
   2208 
   2209     s = soc_property_ci_get_str(unit, ci, name);
   2210     if (s) {
   2211       return _shr_ctoi(s);
   2212     }
   2213 
   2214     return defl;
   2215 }
   2216 
   2217 /*
   2218  * Function:
   2219  *      soc_property_ci_get_csv
   2220  * Purpose:
   2221  *      Retrieve a per-ci global configuration comma-separated value in an array.
   2222  * Parameters:
   2223  *      unit - unit number
   2224  *      ci - Chip Intergface Number.
   2225  *      name - base name of numeric property to look up
   2226  *      val_array - Integer array to put the values
   2227  *      val_max - Maximum number of elements to put into the array
   2228  * Notes:
   2229  *      Returns the count of values read.
   2230  *      The variable name is lookup up with a number of suffixes
   2231  *      until it is found.
   2232  *              name_"suffix"   suffix is ci0 | ci1 ...
   2233  *              name            plain name
   2234  *      If none are found then the default value in defl is returned.
   2235  *      See soc_property_ci_get_str for additional suffix handling.
   2236  *      The string is parsed as a C-style numeric constant.
   2237  */
   2238 int
   2239 soc_property_ci_get_csv(int unit, int ci, const char *name,
   2240                           int val_max, int *val_array)
   2241 {
   2242     char *str, suffix;
   2243     int count;
   2244 
   2245     str = soc_property_ci_get_str(unit, ci, name);
   2246     if (str == NULL) {
   2247         return 0;
   2248     }
   2249 
   2250     count = 0;
   2251     for (count = 0; count < val_max; count++) {
   2252         str = _str_to_val(str, &val_array[count], 0, &suffix);
   2253         if (suffix == ',') {
   2254             str++;
   2255         } else {
   2256             count++;
   2257             break;
   2258         }
   2259     }
   2260 
   2261     return count;
   2262 }
   2263 
   2264 soc_block_name_t        soc_block_port_names[] =
   2265         SOC_BLOCK_PORT_NAMES_INITIALIZER;
   2266 soc_block_name_t        soc_block_names[] =
   2267         SOC_BLOCK_NAMES_INITIALIZER;
   2268 
   2269 
   2270 soc_block_name_t        soc_dpp_block_port_names[] =
   2271         SOC_BLOCK_DPP_PORT_NAMES_INITIALIZER;
   2272 soc_block_name_t        soc_dpp_block_names[] =
   2273         SOC_BLOCK_DPP_NAMES_INITIALIZER;
   2274 
   2275 char *
   2276 soc_block_port_name_lookup_ext(soc_block_t blk, int unit)
   2277 {
   2278     int         i;
   2279 
   2280     {
   2281         for (i = 0; soc_block_port_names[i].blk != SOC_BLK_NONE; i++) {
   2282             if (soc_block_port_names[i].blk == blk) {
   2283                 if (blk == SOC_BLK_GXPORT) {
   2284                     if (SOC_IS_TD_TT(unit) && !SOC_IS_HELIX5(unit)) {
   2285                         return "xlport";
   2286                     }
   2287                 } else if (blk == SOC_BLK_BSAFE) {
   2288                     if (SOC_IS_TD_TT(unit)) {
   2289                         return "otpc";
   2290                     }
   2291                 }
   2292                 return soc_block_port_names[i].name;
   2293             }
   2294         }
   2295     }
   2296     return "?";
   2297 }
   2298 
   2299 char *
   2300 soc_block_name_lookup_ext(soc_block_t blk, int unit)
   2301 {
   2302     int         i;
   2303 
   2304 #if defined(BCM_SAND_SUPPORT)
   2305     if (SOC_IS_SAND(unit)) {
   2306         for (i = 0; soc_dpp_block_names[i].blk != SOC_BLK_NONE; i++) {
   2307             if (soc_dpp_block_names[i].blk == blk) {
   2308                 return soc_dpp_block_names[i].name;
   2309             }
   2310         }
   2311     }
   2312     else
   2313 #endif
   2314 
   2315     {
   2316         for (i = 0; soc_block_names[i].blk != SOC_BLK_NONE; i++) {
   2317             if (soc_block_names[i].blk == blk) {
   2318                 if (blk == SOC_BLK_GXPORT) {
   2319                     if (SOC_IS_TD_TT(unit) && !SOC_IS_HELIX5(unit)) {
   2320                         return "xlport";
   2321                     }
   2322                 } else if (blk == SOC_BLK_BSAFE) {
   2323                     if (SOC_IS_TD_TT(unit)) {
   2324                         return "otpc";
   2325                     }
   2326                 }
   2327                 return soc_block_names[i].name;
   2328             }
   2329         }
   2330     }
   2331     return "?";
   2332 }
   2333 
   2334 soc_block_t
   2335 soc_block_port_name_match(char *name)
   2336 {
   2337     int         i;
   2338 
   2339     
   2340     for (i = 0; soc_block_port_names[i].blk != SOC_BLK_NONE; i++) {
   2341         if (sal_strcmp(soc_block_port_names[i].name, name) == 0) {
   2342             return soc_block_port_names[i].blk;
   2343         }
   2344     }
   2345     return SOC_BLK_NONE;
   2346 }
   2347 
   2348 soc_block_t
   2349 soc_block_name_match(int unit, char *name)
   2350 {
   2351     int         i;
   2352 
   2353 #if defined(BCM_SAND_SUPPORT)
   2354     if (SOC_IS_SAND(unit))
   2355     {
   2356         for (i = 0; soc_dpp_block_names[i].blk != SOC_BLK_NONE; i++)
   2357         {
   2358             if (sal_strncasecmp(soc_dpp_block_names[i].name, name, strlen(soc_dpp_block_names[i].name)) == 0)
   2359             {
   2360                 return soc_dpp_block_names[i].blk;
   2361             }
   2362         }
   2363     }
   2364     else
   2365 #endif
   2366     {
   2367         
   2368         for (i = 0; soc_block_names[i].blk != SOC_BLK_NONE; i++) {
   2369             if (sal_strcmp(soc_block_names[i].name, name) == 0) {
   2370                 return soc_block_names[i].blk;
   2371             }
   2372         }
   2373     }
   2374     return SOC_BLK_NONE;
   2375 }
   2376 
   2377 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT)
   2378 /*
   2379  * Function:
   2380  *      soc_xport_type_update
   2381  * Purpose:
   2382  *      Rewrite the SOC control port structures to reflect the 10G port mode,
   2383  *      and reinitialize the port
   2384  * Parameters:
   2385  *      unit - XGS unit #.
   2386  *      port - XGS port # on unit.
   2387  *      mode - (0 fo iee,1 for higig variants,encap value for other modes ) 
   2388  * Returns:
   2389  *      None.
   2390  * Notes:
   2391  *      Must pause linkscan and take COUNTER_LOCK before calling this.
   2392  */
   2393 void
   2394 soc_xport_type_update(int unit, soc_port_t port, int mode)
   2395 {
   2396 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_BRADLEY_SUPPORT)
   2397     soc_info_t          *si;
   2398     soc_port_t          it_port;
   2399     int                 blk, blktype;
   2400     int                 port_speed;
   2401 
   2402     si = &SOC_INFO(unit);
   2403 
   2404     /* We need to lock the SOC structures until we finish the update */
   2405     SOC_CONTROL_LOCK(unit);
   2406 
   2407     port_speed = (0 != si->port_init_speed[port]) ?
   2408                  si->port_init_speed[port] : si->port_speed_max[port];
   2409     if (mode == 1) {
   2410         SOC_PBMP_PORT_ADD(si->st.bitmap, port);
   2411         SOC_PBMP_PORT_ADD(si->hg.bitmap, port);
   2412         SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
   2413         SOC_PBMP_PORT_REMOVE(si->ce.bitmap, port);
   2414         SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
   2415         SOC_PBMP_PORT_REMOVE(si->cpri.bitmap, port);
   2416         SOC_PBMP_PORT_REMOVE(si->rsvd4.bitmap, port);
   2417     } else if( mode == SOC_ENCAP_CPRI) {
   2418         SOC_PBMP_PORT_REMOVE(si->st.bitmap, port);
   2419         SOC_PBMP_PORT_ADD(si->cpri.bitmap, port);
   2420         SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
   2421         SOC_PBMP_PORT_REMOVE(si->ce.bitmap, port);
   2422         SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
   2423         SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port);
   2424         SOC_PBMP_PORT_REMOVE(si->rsvd4.bitmap, port);
   2425     } else if( mode == SOC_ENCAP_RSVD4) {
   2426         SOC_PBMP_PORT_REMOVE(si->st.bitmap, port);
   2427         SOC_PBMP_PORT_ADD(si->rsvd4.bitmap, port);
   2428         SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
   2429         SOC_PBMP_PORT_REMOVE(si->ce.bitmap, port);
   2430         SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
   2431         SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port);
   2432         SOC_PBMP_PORT_REMOVE(si->cpri.bitmap, port);
   2433     } else {
   2434         SOC_PBMP_PORT_ADD(si->ether.bitmap, port);
   2435         if ((port_speed >= 100000) && (si->port_speed_max[port] >= 100000)){
   2436             SOC_PBMP_PORT_ADD(si->ce.bitmap, port);
   2437         } else if ((port_speed < 10000) && (si->port_speed_max[port] < 10000)) {
   2438             SOC_PBMP_PORT_ADD(si->ge.bitmap, port);
   2439         } else {
   2440             SOC_PBMP_PORT_ADD(si->xe.bitmap, port);
   2441         }
   2442         SOC_PBMP_PORT_REMOVE(si->st.bitmap, port);
   2443         SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port);
   2444         SOC_PBMP_PORT_REMOVE(si->cpri.bitmap, port);
   2445         SOC_PBMP_PORT_REMOVE(si->rsvd4.bitmap, port);
   2446     }
   2447 
   2448 #define RECONFIGURE_PORT_TYPE_INFO(ptype) \
   2449     si->ptype.num = 0; \
   2450     si->ptype.min = si->ptype.max = -1; \
   2451     PBMP_ITER(si->ptype.bitmap, it_port) { \
   2452         si->ptype.port[si->ptype.num++] = it_port; \
   2453         if (si->ptype.min < 0) { \
   2454             si->ptype.min = it_port; \
   2455         } \
   2456         if (it_port > si->ptype.max) { \
   2457             si->ptype.max = it_port; \
   2458         } \
   2459     }
   2460 
   2461     /* Recalculate port type data */
   2462     RECONFIGURE_PORT_TYPE_INFO(ether);
   2463     RECONFIGURE_PORT_TYPE_INFO(st);
   2464     RECONFIGURE_PORT_TYPE_INFO(hg);
   2465     RECONFIGURE_PORT_TYPE_INFO(xe);
   2466     RECONFIGURE_PORT_TYPE_INFO(ge);
   2467     RECONFIGURE_PORT_TYPE_INFO(ce);
   2468     RECONFIGURE_PORT_TYPE_INFO(cpri);
   2469     RECONFIGURE_PORT_TYPE_INFO(rsvd4);
   2470 #undef  RECONFIGURE_PORT_TYPE_INFO
   2471 
   2472     soc_dport_map_update(unit);
   2473 
   2474     /* Resolve block membership for registers */
   2475     if (SOC_IS_FB_FX_HX(unit)) { /* Not HBS */
   2476         for (blk = 0; SOC_BLOCK_INFO(unit, blk).type >= 0; blk++) {
   2477             blktype = SOC_BLOCK_INFO(unit, blk).type;
   2478             switch (blktype) {
   2479             case SOC_BLK_IPIPE:
   2480                 if (!mode) {
   2481                     SOC_PBMP_PORT_ADD(si->block_bitmap[blk], port);
   2482                 } else {
   2483                     SOC_PBMP_PORT_REMOVE(si->block_bitmap[blk], port);
   2484                 }
   2485                 break;
   2486             case SOC_BLK_IPIPE_HI:
   2487                 if (mode) {
   2488                     SOC_PBMP_PORT_ADD(si->block_bitmap[blk], port);
   2489                 } else {
   2490                     SOC_PBMP_PORT_REMOVE(si->block_bitmap[blk], port);
   2491                 }
   2492                 break;
   2493             case SOC_BLK_EPIPE:
   2494                 if (!mode) {
   2495                     SOC_PBMP_PORT_ADD(si->block_bitmap[blk], port);
   2496                 } else {
   2497                     SOC_PBMP_PORT_REMOVE(si->block_bitmap[blk], port);
   2498                 }
   2499                 break;
   2500             case SOC_BLK_EPIPE_HI:
   2501                 if (mode) {
   2502                     SOC_PBMP_PORT_ADD(si->block_bitmap[blk], port);
   2503                 } else {
   2504                     SOC_PBMP_PORT_REMOVE(si->block_bitmap[blk], port);
   2505                 }
   2506                 break;
   2507             }
   2508         }
   2509     }
   2510 
   2511     /* Release SOC structures lock */
   2512     SOC_CONTROL_UNLOCK(unit);
   2513 
   2514 #else /* BCM_FIREBOLT_SUPPORT || BCM_BRADLEY_SUPPORT */
   2515     COMPILER_REFERENCE(unit);
   2516     COMPILER_REFERENCE(port);
   2517     COMPILER_REFERENCE(mode);
   2518 #endif
   2519 }
   2520 
   2521 /*
   2522  * Function:
   2523  *      soc_xport_type_mode_update
   2524  * Purpose:
   2525  *      Rewrite the SOC control port structures to reflect the current port 
   2526  *      mode, and reinitialize the port.
   2527  *
   2528  *      This function is simular to soc_xport_type_update() but the differnce 
   2529  *      here is the encap type updated will check higig encap modes of 
   2530  *      {HG/HG2/HG2-LITE/IEEE} for different encap bitmap assignment.
   2531  * Parameters:
   2532  *      unit - XGS unit #.
   2533  *      port - XGS port # on unit.
   2534  *      hg_mode - (IEEE/HG/HG2/HG2-LITE)
   2535  * Returns:
   2536  *      None.
   2537  * Notes:
   2538  *      Must pause linkscan and take COUNTER_LOCK before calling this.
   2539  */
   2540 void
   2541 soc_xport_type_mode_update(int unit, soc_port_t port, int hg_mode)
   2542 {
   2543     soc_info_t          *si;
   2544     soc_port_t          it_port;
   2545 
   2546     si = &SOC_INFO(unit);
   2547 
   2548     /* We need to lock the SOC structures until we finish the update */
   2549     SOC_CONTROL_LOCK(unit);
   2550 
   2551     if (hg_mode != SOC_ENCAP_IEEE) {
   2552         SOC_PBMP_PORT_ADD(si->st.bitmap, port);
   2553         SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
   2554         /* special process for HG-Lite support to avoid wrong PBMP assignment. 
   2555         *
   2556         * Note :
   2557         *  the 'to_hg_port' for this special design must carry proper encap mode 
   2558         *  instead of TRUE/FALSE only.
   2559         */
   2560         if (hg_mode == SOC_ENCAP_HIGIG2_LITE) {
   2561             SOC_PBMP_PORT_ADD(si->hl.bitmap, port);
   2562             /* for XE or GE no more pbmp update, 
   2563              *  for HG remove HG and add XE 
   2564              */
   2565             if (IS_HG_PORT(unit, port)) {
   2566                 SOC_PBMP_PORT_ADD(si->xe.bitmap, port);
   2567                 SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port);
   2568             }
   2569         } else {
   2570             /* for HG/HG2 case (GE port expected not allowed here) */
   2571             SOC_PBMP_PORT_ADD(si->hg.bitmap, port);
   2572             SOC_PBMP_PORT_REMOVE(si->hl.bitmap, port);
   2573             SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
   2574         }
   2575     } else {
   2576         /* To IEEE mode */
   2577         if (IS_HG_PORT(unit, port)) {
   2578             SOC_PBMP_PORT_ADD(si->xe.bitmap, port);
   2579         }
   2580         SOC_PBMP_PORT_ADD(si->ether.bitmap, port);
   2581         SOC_PBMP_PORT_REMOVE(si->st.bitmap, port);
   2582         SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port);
   2583         SOC_PBMP_PORT_REMOVE(si->hl.bitmap, port);
   2584     }
   2585 
   2586 #define RECONFIGURE_PORT_TYPE_INFO(ptype) \
   2587     si->ptype.num = 0; \
   2588     si->ptype.min = si->ptype.max = -1; \
   2589     PBMP_ITER(si->ptype.bitmap, it_port) { \
   2590         si->ptype.port[si->ptype.num++] = it_port; \
   2591         if (si->ptype.min < 0) { \
   2592             si->ptype.min = it_port; \
   2593         } \
   2594         if (it_port > si->ptype.max) { \
   2595             si->ptype.max = it_port; \
   2596         } \
   2597     }
   2598 
   2599     /* Recalculate port type data */
   2600     RECONFIGURE_PORT_TYPE_INFO(ether);
   2601     RECONFIGURE_PORT_TYPE_INFO(st);
   2602     RECONFIGURE_PORT_TYPE_INFO(hg);
   2603     RECONFIGURE_PORT_TYPE_INFO(xe);
   2604 #undef  RECONFIGURE_PORT_TYPE_INFO
   2605 
   2606     soc_dport_map_update(unit);
   2607 
   2608     /* Release SOC structures lock */
   2609     SOC_CONTROL_UNLOCK(unit);
   2610 }
   2611 
   2612 /*
   2613  * Function:
   2614  *      soc_pci_burst_enable
   2615  * Purpose:
   2616  *      Turn on read/write bursting in the cmic
   2617  * Parameters:
   2618  *      unit - unit number
   2619  *
   2620  * Our hardware by default does not accept burst transactions.
   2621  * These transactions need to be enabled in the CMIC_CONFIG register
   2622  * before a burst is performed or the cmic will hang.
   2623  *
   2624  * This code should be called directly after endian configuration to
   2625  * enable bursting as soon as possible.
   2626  */
   2627 
   2628 void
   2629 soc_pci_burst_enable(int unit)
   2630 {
   2631     uint32 reg;
   2632 
   2633     /* Make sure these reads/writes are not combined */
   2634     sal_usleep(1000);
   2635 
   2636     /* Enable Read/Write bursting in the CMIC */
   2637 #ifdef BCM_CMICM_SUPPORT
   2638     if(soc_feature(unit, soc_feature_cmicm)) {
   2639         return;
   2640     }
   2641 #endif /* CMICM Support */
   2642 #ifdef BCM_CMICX_SUPPORT
   2643     if(soc_feature(unit, soc_feature_cmicx)) {
   2644         return;
   2645     }
   2646 #endif /* CMICX Support */
   2647 
   2648     reg = soc_pci_read(unit, CMIC_CONFIG);
   2649     reg |= (CC_RD_BRST_EN | CC_WR_BRST_EN);
   2650     soc_pci_write(unit, CMIC_CONFIG, reg);
   2651 
   2652     /* Make sure our previous write is not combined */
   2653     sal_usleep(1000);
   2654 }
   2655 /*
   2656  * Function:    soc_endian_get
   2657  * Purpose:     Returns the required endian configuration for this device.
   2658  *              For iProc-based switch designs the CMIC PIO endianness
   2659  *              configuration is shared for the internal and external
   2660  *              CPU hosts, and in this case we force the internal PIO
   2661  *              interface to little endian and perform any required PCI
   2662  *              endianness conversion in the iProc PCI interfce.
   2663  *
   2664  * Parameters:  dev     - device handle
   2665  *              pio     - (OUTPUT) receives the PIO endian configuration.
   2666  *              packet  - (OUTPUT) receives the PACKET endian configuration.
   2667  *              other   - (OUTPUT) receives the OTHER endian configuration.
   2668  *
   2669  * Returns:     SOC_E_XXX
   2670  */
   2671 
   2672 void
   2673 soc_endian_get(int unit, int *pio, int *packet, int *other)
   2674 {
   2675     soc_cm_get_endian(unit, pio, packet, other);
   2676 
   2677 #ifdef BCM_IPROC_SUPPORT
   2678     if (soc_feature(unit, soc_feature_iproc)) {
   2679         if ((soc_cm_get_bus_type(unit) & SOC_PCI_DEV_TYPE) && *pio) {
   2680             /*
   2681              * If big_pio is set, then we assume that the iProc
   2682              * PCI bridge will byte-swap all access types,
   2683              * i.e. both PIO and DMA access.
   2684              *
   2685              * In order to avoid double-swapping, we then need to
   2686              * invert the DMA endianness setting in the CMIC.
   2687              */
   2688             *other ^= 1;
   2689             *packet ^= 1;
   2690             *pio ^= 1;
   2691         }
   2692     }
   2693 #endif
   2694 #if defined(CMIC_SOFT_BYTE_SWAP)
   2695     *pio ^= 1;
   2696 #endif /* CMIC_SOFT_BYTE_SWAP */
   2697 }
   2698 
   2699 /*
   2700  * Function:
   2701  *      soc_endian_config (private)
   2702  * Purpose:
   2703  *      Utility routine for configuring CMIC endian select register.
   2704  * Parameters:
   2705  *      unit - unit number
   2706  */
   2707 
   2708 void
   2709 soc_endian_config(int unit)
   2710 {
   2711     uint32          val = 0;
   2712     int             big_pio, big_packet, big_other;
   2713 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)
   2714     int cmc, cmc_start, cmc_end;
   2715 #endif
   2716 
   2717     soc_endian_get(unit, &big_pio, &big_packet, &big_other);
   2718 
   2719 #ifdef BCM_CMICX_SUPPORT
   2720     if (soc_feature(unit, soc_feature_cmicx)) {
   2721         int y;
   2722         cmc_start = 0;
   2723         cmc_end = SOC_CMCS_NUM(unit) - 1;
   2724 
   2725 
   2726         for (cmc = cmc_start; cmc <= cmc_end; cmc++) {
   2727             if (big_packet) {
   2728                 for(y = 0; y < CMICX_N_DMA_CHAN; y++) {
   2729                     soc_cmicx_pktdma_data_endian_set(unit, cmc, y, big_packet);
   2730                 }
   2731                 /* Set Tx header endian same as packet DMA endian */
   2732                 soc_cmicx_pktdma_hdr_endian_set(unit, 0, 0, big_packet);
   2733             }
   2734             if (big_other) {
   2735                 /* Set Packet DMA Descriptor and EP_TO_CPU_HDR Endianness */
   2736                 for(y = 0; y < CMICX_N_DMA_CHAN; y++) {
   2737                     soc_cmicx_pktdma_desc_endian_set(unit, cmc, y, big_other);
   2738                     /*
   2739                      * For DMA channel0 in CMC0 which is used for transmission,
   2740                      * header endian setting should be same as packet DMA endian.
   2741                      * For other CMCs' channels which are used for receive,
   2742                      * EP_TO_CPU_HDR endian setting should be same as DCB endian.
   2743                      */
   2744                     if (cmc != 0 || y != 0) {
   2745                         /* Set Rx EP_TO_CPU_HDR endian same as DCB endian */
   2746                         soc_cmicx_pktdma_hdr_endian_set(unit, cmc, y, big_other);
   2747                     }
   2748                 }
   2749 #ifdef BCM_SBUSDMA_SUPPORT
   2750                 if (soc_feature(unit, soc_feature_sbusdma)) {
   2751                     uint32 num_sbusdma;
   2752                     num_sbusdma = soc_sbusdma_cmc_max_num_ch_get(unit);
   2753                     for(y = 0; y < num_sbusdma; y++) {
   2754                         soc_sbusdma_ch_endian_set(unit, cmc, y, 1);
   2755                     }
   2756                 }
   2757 #endif
   2758 #ifdef BCM_FIFODMA_SUPPORT
   2759                 for(y = 0; y < CMICX_N_FIFODMA_CHAN; y++) {
   2760                     soc_fifodma_ch_endian_set(unit, y, 1);
   2761                 }
   2762 #endif
   2763             }
   2764         }
   2765     }
   2766 #endif
   2767 
   2768 #ifdef BCM_CMICM_SUPPORT
   2769     if (soc_feature(unit, soc_feature_cmicm)) {
   2770         int y;
   2771         uint32 pio_endian = (big_pio) ? 0x01010101 : 0;
   2772 
   2773         /*
   2774          * Configure endianness for PCI PIO accesss.
   2775          *
   2776          * Note that this register has no effect for iProc-based
   2777          * switch designs.
   2778          */
   2779         soc_pci_write(unit, CMIC_COMMON_PCIE_PIO_ENDIANESS_OFFSET, pio_endian);
   2780 
   2781 #ifdef BCM_IPROC_SUPPORT
   2782         if (soc_feature(unit, soc_feature_iproc)) {
   2783            WRITE_CMIC_COMMON_UC0_PIO_ENDIANESSr(unit, pio_endian);
   2784         }
   2785 #endif
   2786         if (soc_feature(unit, soc_feature_cmicm_multi_dma_cmc)) {
   2787             cmc_start = 0;
   2788             cmc_end = SOC_CMCS_NUM(unit) - 1;
   2789         } else {
   2790             cmc_start = SOC_PCI_CMC(unit);
   2791             cmc_end = cmc_start;
   2792         }
   2793 
   2794         for (cmc = cmc_start; cmc <= cmc_end; cmc++) {
   2795             if (big_packet) {
   2796                 for(y = 0; y < N_DMA_CHAN; y++) {
   2797                     val = soc_pci_read(unit, CMIC_CMCx_CHy_DMA_CTRL_OFFSET(cmc,y));
   2798                     val |= PKTDMA_BIG_ENDIAN;
   2799                     soc_pci_write(unit, CMIC_CMCx_CHy_DMA_CTRL_OFFSET(cmc,y), val);
   2800                 }
   2801             }
   2802             if (big_other) {
   2803                 /* Set Packet DMA Descriptor Endianness */
   2804                 for(y = 0; y < N_DMA_CHAN; y++) {
   2805                     val = soc_pci_read(unit, CMIC_CMCx_CHy_DMA_CTRL_OFFSET(cmc,y));
   2806                     val |= PKTDMA_DESC_BIG_ENDIAN;
   2807                     soc_pci_write(unit, CMIC_CMCx_CHy_DMA_CTRL_OFFSET(cmc,y), val);
   2808                 }
   2809 #ifdef BCM_SBUSDMA_SUPPORT
   2810                 if (soc_feature(unit, soc_feature_sbusdma)) {
   2811                     for(y=0; y < CMIC_CMCx_SBUSDMA_CHAN_MAX ; y++) {
   2812                         /* dma/slam */
   2813                         val = soc_pci_read(unit, CMIC_CMCx_SBUSDMA_CHy_REQUEST(cmc, y));
   2814                         soc_reg_field_set(unit, CMIC_CMC0_SBUSDMA_CH0_REQUESTr, &val,
   2815                                 HOSTMEMWR_ENDIANESSf, 1);
   2816                         soc_reg_field_set(unit, CMIC_CMC0_SBUSDMA_CH0_REQUESTr, &val,
   2817                                 HOSTMEMRD_ENDIANESSf, 1);
   2818                         soc_pci_write(unit, CMIC_CMCx_SBUSDMA_CHy_REQUEST(cmc,y), val);
   2819 
   2820                         val = soc_pci_read(unit, CMIC_CMCx_SBUSDMA_CHy_CONTROL(cmc, y));
   2821 
   2822                         soc_reg_field_set(unit, CMIC_CMC0_SBUSDMA_CH0_CONTROLr,
   2823                                      &val, DESCRIPTOR_ENDIANESSf, 1);
   2824                         soc_pci_write(unit,  CMIC_CMCx_SBUSDMA_CHy_CONTROL(cmc, y), val);
   2825                     }
   2826                 } else
   2827 #endif
   2828                 {
   2829                     /* Set SLAM DMA Endianness */
   2830                     val = soc_pci_read(unit, CMIC_CMCx_SLAM_DMA_CFG_OFFSET(cmc));
   2831                     val |= SLDMA_BIG_ENDIAN;
   2832                     soc_pci_write(unit, CMIC_CMCx_SLAM_DMA_CFG_OFFSET(cmc), val);
   2833 
   2834                     /* Set STATS DMA Endianness */
   2835                     val = soc_pci_read(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc));
   2836                     val |= STDMA_BIG_ENDIAN;
   2837                     soc_pci_write(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc), val);
   2838 
   2839                     /* Set TABLE DMA Endianness */
   2840                     val = soc_pci_read(unit, CMIC_CMCx_TABLE_DMA_CFG_OFFSET(cmc));
   2841                     val |= TDMA_BIG_ENDIAN;
   2842                     soc_pci_write(unit, CMIC_CMCx_TABLE_DMA_CFG_OFFSET(cmc), val);
   2843                 }
   2844 
   2845                 /* Set FIFO DMA Endianness */
   2846                 for(y = 0; y < N_DMA_CHAN; y++) {
   2847                     val = soc_pci_read(unit, CMIC_CMCx_FIFO_CHy_RD_DMA_CFG_OFFSET(cmc,y));
   2848                     val |= FIFODMA_BIG_ENDIAN;
   2849                     soc_pci_write(unit, CMIC_CMCx_FIFO_CHy_RD_DMA_CFG_OFFSET(cmc,y), val);
   2850                 }
   2851 
   2852                 /* Set Cross Coupled Memory Endianness */
   2853                 /* NA for PCI */
   2854             }
   2855         }
   2856     } else
   2857 #endif
   2858     {
   2859         if (big_pio) {
   2860             val |= ES_BIG_ENDIAN_PIO;
   2861         }
   2862 
   2863         if (big_packet) {
   2864             val |= ES_BIG_ENDIAN_DMA_PACKET;
   2865         }
   2866 
   2867         if (big_other) {
   2868             val |= ES_BIG_ENDIAN_DMA_OTHER;
   2869         }
   2870 
   2871         if ((SOC_IS_HAWKEYE(unit) || SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit)) &&
   2872              soc_property_get(unit, spn_EB2_2BYTES_BIG_ENDIAN, 0)) {
   2873             val |= EN_BIG_ENDIAN_EB2_2B_SEL;
   2874         }
   2875 #ifdef BCM_SHADOW_SUPPORT
   2876         if (SOC_IS_SHADOW(unit) && soc_property_get(unit, spn_DEVICE_EB_VLI, 0)) {
   2877             val = 0x30000030;
   2878         }
   2879 #endif
   2880         soc_pci_write(unit, CMIC_ENDIAN_SELECT, val);
   2881     }
   2882 }
   2883 
   2884 void
   2885 soc_pci_ep_config(int unit, int pcie)
   2886 {
   2887 #if defined(BCM_IPROC_SUPPORT) && defined(BCM_CMICM_SUPPORT)
   2888     uint32 rval;
   2889     int pci_num = pcie;
   2890     int base_cmc = SOC_PCI_CMC(unit);
   2891     int num_of_cmc = 1;
   2892     int cmc;
   2893     char *propkey;
   2894     int configure_one_to_one_remap[CMIC_CMC_NUM_MAX] = {TRUE, TRUE, TRUE};
   2895     uint32 remap_entries_reserved;
   2896     
   2897     if(SOC_IS_DPP(unit)){
   2898         num_of_cmc = SOC_PCI_CMCS_NUM(unit);
   2899     }
   2900     
   2901     if (soc_feature(unit, soc_feature_iproc) &&
   2902         soc_feature(unit, soc_feature_cmicm) &&
   2903         (soc_cm_get_bus_type(unit) & SOC_PCI_DEV_TYPE)) {
   2904 
   2905         if (pcie == -1) { /* Auto-Detect PCI # */
   2906             if ((soc_cm_get_bus_type(unit) & SOC_DEV_BUS_ALT)) {
   2907                 pci_num = 1;
   2908             } else {
   2909                 pci_num = 0;
   2910             }
   2911         }
   2912         /* consider remap_entries_reserved!=0 only for cmc=1 and pci_cmc=0 */
   2913         /* this is the only constelation that the remap management is allowed */
   2914         propkey = spn_HOST_MEMORY_ADDRESS_REMAP_ENTRIES_RESERVED_CMC;
   2915         for(cmc=base_cmc;cmc<num_of_cmc+base_cmc;cmc++)
   2916         {
   2917             remap_entries_reserved = soc_property_port_get(unit, cmc, propkey, 0);
   2918             if(remap_entries_reserved != 0)
   2919             {
   2920                if ((cmc == 1) && (base_cmc == 0))
   2921                {
   2922                    configure_one_to_one_remap[cmc] = FALSE;
   2923                }
   2924             }
   2925         }
   2926 
   2927         if (pci_num == 0) {
   2928             for(cmc=base_cmc;cmc<num_of_cmc+base_cmc;cmc++){
   2929                 if ((SOC_IS_JERICHO(unit)) && (configure_one_to_one_remap[cmc] == FALSE))
   2930                 {       
   2931                     /** don't remap at all here. it will be made once allocating new host_buff and setting HOSTMEM_START_ADDRESS */
   2932                     /** see function _soc_mem_sbus_fifo_dma_start_memreg and _soc_mem_address_remap_allocation_init  */
   2933                 }
   2934                 else
   2935                 {
   2936                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_0_OFFSET(cmc), 0x144D2450);
   2937                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_1_OFFSET(cmc), 0x19617595);
   2938                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(cmc), 0x1E75C6DA);
   2939                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_3_OFFSET(cmc), 0x1f);                    
   2940                 }
   2941 
   2942             }
   2943         } else {
   2944             for(cmc=base_cmc;cmc<num_of_cmc+base_cmc;cmc++){
   2945                 if ((SOC_IS_JERICHO(unit)) && (configure_one_to_one_remap[cmc] == FALSE))
   2946                 {
   2947                     /** don't remap at all here. it will be made once allocating new host_buff and setting HOSTMEM_START_ADDRESS */
   2948                     /** see function _soc_mem_sbus_fifo_dma_start_memreg and _soc_mem_address_remap_allocation_init */                    
   2949                 }
   2950                 else
   2951                 {
   2952                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_0_OFFSET(cmc), 0x248e2860);
   2953                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_1_OFFSET(cmc), 0x29a279a5);
   2954                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(cmc), 0x2eb6caea);
   2955                     soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_3_OFFSET(cmc), 0x2f);                                
   2956                 }
   2957 
   2958                 rval = soc_pci_read(unit, CMIC_CMCx_PCIE_MISCEL_OFFSET(cmc));
   2959                 soc_reg_field_set(unit, CMIC_CMC0_PCIE_MISCELr,
   2960                                 &rval, MSI_ADDR_SELf, 1);
   2961                 soc_pci_write(unit, CMIC_CMCx_PCIE_MISCEL_OFFSET(cmc), rval);
   2962             }
   2963         }
   2964     }
   2965 #endif
   2966 }
   2967 
   2968 /*
   2969  * Function:
   2970  *      soc_autoz_set
   2971  * Purpose:
   2972  *      Set the autoz bit in the active mac
   2973  * Parameters:
   2974  *      unit - SOC unit #
   2975  *      port - port number on device.
   2976  *      enable - Boolean value to set state
   2977  * Returns:
   2978  *      SOC_E_XXX
   2979  */
   2980 int
   2981 soc_autoz_set(int unit, soc_port_t port, int enable)
   2982 {
   2983     /* XGS (Hercules): AutoZ not supported */
   2984     return SOC_E_NONE;
   2985 }
   2986 
   2987 /*
   2988  * Function:
   2989  *      soc_autoz_get
   2990  * Purpose:
   2991  *      Get the state of the autoz bit in the active MAC
   2992  * Parameters:
   2993  *      unit - SOC unit #
   2994  *      port - port number on device.
   2995  *      enable - (OUT) Boolean pointer to return state
   2996  * Returns:
   2997  *      SOC_E_XXX
   2998  */
   2999 int
   3000 soc_autoz_get(int unit, soc_port_t port, int *enable)
   3001 {
   3002     /* XGS (Hercules): AutoZ not supported */
   3003     *enable = 0;
   3004     return SOC_E_NONE;
   3005 }
   3006 
   3007 #endif /* defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) */
   3008 
   3009 
   3010 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) || defined(PORTMOD_SUPPORT)
   3011 
   3012 int
   3013 soc_event_register(int unit, soc_event_cb_t cb, void *userdata)
   3014 {
   3015     soc_control_t       *soc;
   3016     soc_event_cb_list_t *curr, *prev;
   3017 
   3018 
   3019     /* Input validation */
   3020     if (!SOC_UNIT_VALID(unit)) {
   3021         return SOC_E_UNIT;
   3022     }
   3023 
   3024     if (NULL == cb) {
   3025         return SOC_E_PARAM;
   3026     }
   3027 
   3028     soc = SOC_CONTROL(unit);
   3029     curr = prev = soc->ev_cb_head;
   3030 
   3031     if (NULL == curr) { /* Fist time a call back registered */
   3032         curr = (soc_event_cb_list_t *)sal_alloc(sizeof(soc_event_cb_list_t),
   3033                                                "event call back linked list");
   3034         if (NULL == curr) {
   3035             return SOC_E_MEMORY;
   3036         }
   3037         curr->cb = cb;
   3038         curr->userdata = userdata;
   3039         curr->next = NULL;
   3040         soc->ev_cb_head = curr;
   3041     } else { /* Not a first registered callback */
   3042         while (NULL != curr) {
   3043             if ((curr->cb == cb) && (curr->userdata == userdata)) {
   3044                 /* call back with exact same userdata exists - nothing to be done */
   3045                 return SOC_E_NONE;
   3046             }
   3047             prev = curr;
   3048             curr = prev->next;
   3049         }
   3050         curr = (soc_event_cb_list_t *)sal_alloc(sizeof(soc_event_cb_list_t),
   3051                                                "event call back linked list");
   3052         if (NULL == curr) {
   3053             return SOC_E_MEMORY;
   3054         }
   3055         curr->cb = cb;
   3056         curr->userdata = userdata;
   3057         curr->next = NULL;
   3058         prev->next = curr;
   3059     }
   3060 
   3061     return SOC_E_NONE;
   3062 }
   3063 
   3064 int
   3065 soc_event_unregister(int unit, soc_event_cb_t cb, void *userdata)
   3066 {
   3067     soc_control_t       *soc;
   3068     soc_event_cb_list_t *curr, *prev;
   3069 
   3070     /* Input validation */
   3071     if (!SOC_UNIT_VALID(unit)) {
   3072         return SOC_E_UNIT;
   3073     }
   3074 
   3075     if (NULL == cb) {
   3076         return SOC_E_PARAM;
   3077     }
   3078 
   3079     soc = SOC_CONTROL(unit);
   3080     curr = prev = soc->ev_cb_head;
   3081 
   3082     while (NULL != curr) {
   3083         if (curr->cb == cb) {
   3084             if ((NULL != userdata) && (curr->userdata != userdata)) {
   3085                 /* No match keep searching */
   3086                 prev = curr;
   3087                 curr = curr->next;
   3088                 continue;
   3089             }
   3090             /* if cb & userdata matches or userdata is NULL -> delete */
   3091             if (curr == soc->ev_cb_head) {
   3092                 soc->ev_cb_head = curr->next;
   3093                 sal_free((void *)curr);
   3094                 break;
   3095             }
   3096             prev->next = curr->next;
   3097             sal_free((void *)curr);
   3098             break;
   3099         }
   3100         prev = curr;
   3101         curr = curr->next;
   3102     }
   3103 
   3104     return (SOC_E_NONE);
   3105 }
   3106 
   3107 int
   3108 soc_event_generate(int unit,  soc_switch_event_t event, uint32 arg1,
   3109                    uint32 arg2, uint32 arg3)
   3110 {
   3111     soc_control_t       *soc;
   3112     soc_event_cb_list_t *curr, *curr_next;
   3113     soc_event_cb_t      curr_cb;
   3114 
   3115     /* Input validation */
   3116     if (!SOC_UNIT_VALID(unit)) {
   3117         return SOC_E_UNIT;
   3118     }
   3119 
   3120 #ifdef _SOC_SER_ENABLE_CLI_DBG
   3121     if ((event == SOC_SWITCH_EVENT_PARITY_ERROR) &&
   3122         SOC_MEM_IS_VALID(unit, arg2)) {
   3123         LOG_ERROR(BSL_LS_SOC_COMMON,
   3124                       (BSL_META_U(unit,
   3125                             "unit %d SOC_SWITCH_EVENT_PARITY_ERROR, "
   3126                             "correction_type = %d mem %s, index %d\n"),
   3127                  unit, arg1, SOC_MEM_NAME(unit, arg2), arg3));
   3128     }
   3129     if ((event == SOC_SWITCH_EVENT_PARITY_ERROR) &&
   3130         (arg1 == SOC_SWITCH_EVENT_DATA_ERROR_LOG)) {
   3131         LOG_ERROR(BSL_LS_SOC_COMMON,
   3132                       (BSL_META_U(unit,
   3133                             "unit %d SOC_SWITCH_EVENT_DATA_ERROR_LOG, "
   3134                             "log_id = %0d, arg3 = %0d \n"),
   3135                  unit, arg2, arg3));
   3136     }
   3137 #endif /* _SOC_SER_ENABLE_CLI_DBG */
   3138 
   3139     soc = SOC_CONTROL(unit);
   3140     curr = soc->ev_cb_head;
   3141     if (NULL != curr) {
   3142         curr_cb = curr->cb;
   3143         /* coverity[copy_paste_error] */
   3144         curr_next = curr->next; 
   3145 
   3146         while ((NULL != curr) && (curr->next == curr_next)) {
   3147             curr_cb(unit, event, arg1, arg2, arg3, curr->userdata);
   3148 
   3149             if (curr_next != NULL) {
   3150                 curr_cb = curr_next->cb; 
   3151                 curr_next = curr_next->next;
   3152             }
   3153             curr = curr->next;
   3154         }
   3155     }
   3156 
   3157     return (SOC_E_NONE);
   3158 }
   3159 
   3160 void
   3161 soc_event_assert(const char *expr, const char *file, int line)
   3162 {
   3163     uint32 arg1, arg3;
   3164 
   3165     arg1 = PTR_TO_INT(file);
   3166     arg3 = PTR_HI_TO_INT(file);
   3167 
   3168     soc_event_generate(0, SOC_SWITCH_EVENT_ASSERT_ERROR, arg1, line, arg3);
   3169    _default_assert(expr, file, line);
   3170 }
   3171 
   3172 #endif /*defined(BCM_ESW_SUPPORT) || defined(PORTMOD_SUPPORT) */
   3173 
   3174 
   3175 #if defined(BCM_XGS3_SWITCH_SUPPORT) || defined(BCM_PETRA_SUPPORT)
   3176 /*
   3177  * LCPLL lock check for FBX devices
   3178  */
   3179 void
   3180 soc_xgxs_lcpll_lock_check(int unit)
   3181 {
   3182     if ((!SAL_BOOT_PLISIM) && (!SAL_BOOT_QUICKTURN) &&
   3183         soc_feature(unit, soc_feature_xgxs_lcpll)) {
   3184         uint32 val;
   3185         int pll_lock_usec = 500000;
   3186         int locked = 0;
   3187         int retry = 3;
   3188         soc_timeout_t to;
   3189 
   3190         /* Check if LCPLL locked */
   3191         while (!locked && retry--) {
   3192             soc_timeout_init(&to, pll_lock_usec, 0);
   3193             while (!soc_timeout_check(&to)) {
   3194 #if defined(BCM_RAVEN_SUPPORT)
   3195                 if (SOC_REG_IS_VALID(unit, CMIC_XGXS_PLL_STATUSr)) {
   3196                     READ_CMIC_XGXS_PLL_STATUSr(unit, &val);
   3197                     locked = soc_reg_field_get(unit, CMIC_XGXS_PLL_STATUSr,
   3198                                             val, CMIC_XG_PLL_LOCKf);
   3199                 } else
   3200 #endif
   3201                 {
   3202                     READ_CMIC_XGXS_PLL_CONTROL_2r(unit, &val);
   3203                     locked = soc_reg_field_get(unit, CMIC_XGXS_PLL_CONTROL_2r,
   3204                                                val, PLL_SM_FREQ_PASSf);
   3205                 }
   3206                 if (locked) {
   3207                     break;
   3208                 }
   3209             }
   3210             if (!locked) {
   3211                 READ_CMIC_XGXS_PLL_CONTROL_1r(unit, &val);
   3212                 soc_reg_field_set(unit, CMIC_XGXS_PLL_CONTROL_1r, &val,
   3213                                   RESETf, 1);
   3214                 WRITE_CMIC_XGXS_PLL_CONTROL_1r(unit, val);
   3215                 sal_usleep(100);
   3216 
   3217                 READ_CMIC_XGXS_PLL_CONTROL_1r(unit, &val);
   3218                 val |= 0xf0000000;
   3219                 WRITE_CMIC_XGXS_PLL_CONTROL_1r(unit, val);
   3220                 sal_usleep(100);
   3221 
   3222                 READ_CMIC_XGXS_PLL_CONTROL_1r(unit, &val);
   3223                 soc_reg_field_set(unit, CMIC_XGXS_PLL_CONTROL_1r, &val,
   3224                                   RESETf, 0);
   3225                 WRITE_CMIC_XGXS_PLL_CONTROL_1r(unit, val);
   3226                 sal_usleep(50);
   3227             }
   3228         }
   3229 
   3230         if (!locked) {
   3231             LOG_ERROR(BSL_LS_SOC_COMMON,
   3232                       (BSL_META_U(unit,
   3233                                   "fbx_lcpll_lock_check: LCPLL not locked on unit %d "
   3234                                   "status = 0x%08x\n"),
   3235                        unit, val));
   3236         }
   3237     }
   3238 }
   3239 #endif /* BCM_XGS3_SWITCH_SUPPORT || BCM_PETRA_SUPPORT*/
   3240 
   3241 
   3242 #if defined(BCM_BIGMAC_SUPPORT) || defined(BCM_PETRA_SUPPORT) || defined(BCM_XMAC_SUPPORT)
   3243 /* Reset XGXS (unicore, hyperlite, ...) via BigMAC fusion interface or port
   3244  * registers */
   3245 int
   3246 soc_xgxs_reset(int unit, soc_port_t port)
   3247 {
   3248     soc_reg_t           reg;
   3249     uint64              rval64;
   3250 #ifdef BCM_IPROC_SUPPORT
   3251     uint32              rval;
   3252 #endif
   3253     int                 reset_sleep_usec;
   3254     soc_field_t rstb_hw, rstb_mdioregs, rstb_pll,
   3255                 txd1_g_fifo_restb, txd10_g_fifo_restb,
   3256                 pwrdwn, pwrdwn_pll;
   3257 
   3258     reset_sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   3259 
   3260     reg = MAC_XGXS_CTRLr;
   3261 #if defined(BCM_TRIUMPH_SUPPORT)
   3262     if (SOC_IS_TR_VL(unit) && !SOC_IS_TRIUMPH2(unit) && !SOC_IS_APOLLO(unit) &&
   3263          !SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANE(unit) && !SOC_IS_VALKYRIE2(unit) &&
   3264         (port == 6 || port == 7 || port == 18 || port == 19 ||
   3265          port == 35 || port == 36 || port == 46 || port == 47)) {
   3266         reg = XGPORT_XGXS_CTRLr;
   3267     }
   3268 #endif /* BCM_TRIUMPH_SUPPORT */
   3269 #if defined(BCM_SCORPION_SUPPORT)
   3270     if (SOC_IS_SC_CQ(unit) && (port >= 25 && port <= 28)) {
   3271         reg = QGPORT_MAC_XGXS_CTRLr;
   3272     }
   3273 #endif /* BCM_SCORPION_SUPPORT */
   3274 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT)
   3275     if (SOC_IS_TD_TT(unit) || SOC_IS_SHADOW(unit)) {
   3276         reg = XLPORT_XGXS_CTRL_REGr;
   3277     }
   3278 #endif /* BCM_TRIDENT_SUPPORT */
   3279 #if defined(BCM_KATANA_SUPPORT)
   3280     if (SOC_IS_KATANAX(unit) && !SOC_IS_SABER2(unit)) {
   3281         reg = XPORT_XGXS_CTRLr;
   3282     }
   3283 #endif /* BCM_KATANA_SUPPORT */
   3284 #if defined(BCM_SABER2_SUPPORT)
   3285     if(SOC_IS_SABER2(unit)) {
   3286         if(IS_MXQ_PORT(unit, port)) {
   3287             reg = XPORT_XGXS_CTRLr;
   3288         } else {
   3289             reg = XLPORT_XGXS0_CTRL_REGr;
   3290         }
   3291     }
   3292 #endif
   3293 #if defined(BCM_TRIUMPH3_SUPPORT)
   3294     if (SOC_IS_TRIUMPH3(unit)) {
   3295         reg = PORT_XGXS0_CTRL_REGr;
   3296     }
   3297 #endif /* BCM_TRIUMPH3_SUPPORT */
   3298 #if defined(BCM_PETRA_SUPPORT)
   3299     if (SOC_IS_ARAD(unit)) {
   3300         reg = PORT_XGXS_0_CTRL_REGr;
   3301     }
   3302 #endif /* BCM_PETRA_SUPPORT */
   3303 
   3304     if (((SOC_IS_HELIX4(unit) && SOC_INFO(unit).port_l2p_mapping[port] == 49) ||
   3305          (SOC_IS_KATANA2(unit) && port == 40)) &&
   3306          (soc_cm_get_bus_type(unit) & SOC_PCI_DEV_TYPE)) {
   3307             /* REFSEL=2'b01, REFDIV=2'b00, REF_TERM_SEL=1'b1. */
   3308             SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3309             if (SOC_IS_HELIX4(unit)) {
   3310                 soc_reg64_field32_set(unit, reg, &rval64, REFSELf, 1);
   3311             }
   3312             if (SOC_IS_KATANA2(unit)) {
   3313                 soc_reg64_field32_set(unit, reg, &rval64, REFSELf, 0); 
   3314             }
   3315             soc_reg64_field32_set(unit, reg, &rval64, REF_TERM_SELf, 1);
   3316             soc_reg64_field32_set(unit, reg, &rval64, REFDIVf, 0);
   3317             soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   3318             SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3319 #ifdef BCM_IPROC_SUPPORT
   3320             SOC_IF_ERROR_RETURN(READ_IPROC_WRAP_MISC_CONTROLr(unit, &rval));
   3321             if (SOC_IS_HELIX4(unit)) {
   3322                 soc_reg_field_set(unit, IPROC_WRAP_MISC_CONTROLr, &rval,
   3323                                                QUAD_SERDES_CTRL_SELf, 0);
   3324             } else if (SOC_IS_KATANA2(unit)) {
   3325                 soc_reg_field_set(unit, IPROC_WRAP_MISC_CONTROLr, &rval,
   3326                                             UNICORE_SERDES_CTRL_SELf, 0);
   3327             }
   3328             SOC_IF_ERROR_RETURN(WRITE_IPROC_WRAP_MISC_CONTROLr(unit, rval));
   3329 #endif
   3330     }
   3331 
   3332 #if defined(BCM_XGS3_SWITCH_SUPPORT) || defined(BCM_PETRA_SUPPORT)
   3333     if (SOC_REG_FIELD_VALID(unit, reg, LCREFENf) ||
   3334         SOC_REG_FIELD_VALID(unit, reg, LCREF_ENf)) {
   3335         int lcpll;
   3336         soc_field_t lcpll_f;
   3337 
   3338         lcpll_f = SOC_REG_FIELD_VALID(unit, reg, LCREFENf) ? LCREFENf : LCREF_ENf;
   3339         /*
   3340          * Reference clock selection
   3341          */
   3342         lcpll = soc_property_port_get(unit, port, spn_XGXS_LCPLL,
   3343                                       SAL_BOOT_QUICKTURN ? 0 : 1);
   3344         if (lcpll && !SOC_IS_ARAD(unit)) { /* Internal LCPLL reference clock */
   3345             /* Double-check LCPLL lock */
   3346             soc_xgxs_lcpll_lock_check(unit);
   3347         }
   3348         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3349         soc_reg64_field32_set(unit, reg, &rval64, lcpll_f, lcpll ? 1 : 0);
   3350         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3351     }
   3352 #endif /* BCM_XGS3_SWITCH_SUPPORT || BCM_PETRA_SUPPORT*/
   3353 
   3354 #ifdef BCM_PETRA_SUPPORT
   3355     if (SOC_IS_ARAD(unit)) {
   3356         pwrdwn = PWR_DWNf;
   3357         pwrdwn_pll = PWR_DWN_PLLf;
   3358         rstb_hw = RST_B_HWf;
   3359         rstb_mdioregs = RST_B_MDIOREGSf;
   3360         rstb_pll = RST_B_PLLf;
   3361         txd1_g_fifo_restb = TXD_1_G_FIFO_RST_Bf;
   3362         txd10_g_fifo_restb = TXD_10_G_FIFO_RST_Bf;
   3363     } else
   3364 #endif /* BCM_PETRA_SUPPORT */
   3365     {
   3366         pwrdwn = PWRDWNf;
   3367         pwrdwn_pll = PWRDWN_PLLf;
   3368         rstb_hw = RSTB_HWf;
   3369         rstb_mdioregs = RSTB_MDIOREGSf;
   3370         rstb_pll = RSTB_PLLf;
   3371         txd1_g_fifo_restb = TXD1G_FIFO_RSTBf;
   3372         txd10_g_fifo_restb = TXD10G_FIFO_RSTBf;
   3373     }
   3374 
   3375     /*
   3376      * XGXS MAC initialization steps.
   3377      *
   3378      * A minimum delay is required between various initialization steps.
   3379      * There is no maximum delay.  The values given are very conservative
   3380      * including the timeout for PLL lock.
   3381      */
   3382     /* Release reset (if asserted) to allow bigmac to initialize */
   3383     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3384     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   3385     if (soc_reg_field_valid(unit, reg, pwrdwn)) {
   3386         soc_reg64_field32_set(unit, reg, &rval64, pwrdwn, 0);
   3387     }
   3388     if (soc_reg_field_valid(unit, reg, pwrdwn_pll)) {
   3389         soc_reg64_field32_set(unit, reg, &rval64, pwrdwn_pll, 0);
   3390     }
   3391     if (soc_reg_field_valid(unit,reg, HW_RSTLf)) {
   3392         soc_reg64_field32_set(unit, reg, &rval64, HW_RSTLf, 1);
   3393     } else if (soc_reg_field_valid(unit,reg, rstb_hw)) {
   3394         soc_reg64_field32_set(unit, reg, &rval64, rstb_hw, 1);
   3395     }
   3396     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3397     sal_usleep(reset_sleep_usec);
   3398 
   3399     /* Power down and reset */
   3400     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3401     if (soc_reg_field_valid(unit, reg, pwrdwn)) {
   3402         soc_reg64_field32_set(unit, reg, &rval64, pwrdwn, 1);
   3403     }
   3404     if (soc_reg_field_valid(unit, reg, pwrdwn_pll)) {
   3405         soc_reg64_field32_set(unit, reg, &rval64, pwrdwn_pll, 1);
   3406     }
   3407     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 1);
   3408     if (soc_reg_field_valid(unit, reg, HW_RSTLf)) {
   3409         soc_reg64_field32_set(unit, reg, &rval64, HW_RSTLf, 0);
   3410     } else if (soc_reg_field_valid(unit, reg, rstb_hw)) {
   3411         soc_reg64_field32_set(unit, reg, &rval64, rstb_hw, 0);
   3412     }
   3413     if (soc_reg_field_valid(unit, reg, TXFIFO_RSTLf)) {
   3414         soc_reg64_field32_set(unit, reg, &rval64, TXFIFO_RSTLf, 0);
   3415     } else if (soc_reg_field_valid(unit, reg, txd1_g_fifo_restb)) {
   3416         soc_reg64_field32_set(unit, reg, &rval64,
   3417                               txd1_g_fifo_restb, 0);
   3418         soc_reg64_field32_set(unit, reg, &rval64,
   3419                               txd10_g_fifo_restb, 0);
   3420     }
   3421     if (soc_reg_field_valid(unit, reg, AFIFO_RSTf)) {
   3422         soc_reg64_field32_set(unit, reg, &rval64, AFIFO_RSTf, 1);
   3423     }
   3424 
   3425     if (SOC_IS_TRX(unit) || SOC_IS_ARAD(unit)) { /* How about Bradley */
   3426         if (soc_reg_field_valid(unit,reg, rstb_mdioregs)) {
   3427         soc_reg64_field32_set(unit, reg, &rval64, rstb_mdioregs, 0);
   3428         }
   3429         if (soc_reg_field_valid(unit,reg, rstb_pll)) {
   3430         soc_reg64_field32_set(unit, reg, &rval64, rstb_pll, 0);
   3431         }
   3432         if (soc_reg_field_valid(unit,reg, BIGMACRSTLf)) {
   3433             soc_reg64_field32_set(unit, reg, &rval64, BIGMACRSTLf, 0);
   3434         }
   3435     }
   3436     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3437     sal_usleep(reset_sleep_usec);
   3438 
   3439     /*
   3440      * Bring up both digital and analog clocks
   3441      *
   3442      * NOTE: Many MAC registers are not accessible until the PLL is locked.
   3443      * An S-Channel timeout will occur before that.
   3444      */
   3445     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3446     if (soc_reg_field_valid(unit, reg, pwrdwn)) {
   3447         soc_reg64_field32_set(unit, reg, &rval64, pwrdwn, 0);
   3448     }
   3449     if (soc_reg_field_valid(unit, reg, pwrdwn_pll)) {
   3450         soc_reg64_field32_set(unit, reg, &rval64, pwrdwn_pll, 0);
   3451     }
   3452     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   3453     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3454     sal_usleep(reset_sleep_usec);
   3455 
   3456     /* Bring XGXS out of reset, AFIFO_RST stays 1.  */
   3457     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3458     if (soc_reg_field_valid(unit, reg, HW_RSTLf)) {
   3459         soc_reg64_field32_set(unit, reg, &rval64, HW_RSTLf, 1);
   3460     } else if (soc_reg_field_valid(unit, reg, rstb_hw)) {
   3461         soc_reg64_field32_set(unit, reg, &rval64, rstb_hw, 1);
   3462     }
   3463     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3464     sal_usleep(reset_sleep_usec);
   3465 
   3466     if (SOC_IS_TRX(unit) || SOC_IS_ARAD(unit)) { /* How about Bradley */
   3467         /* Bring MDIO registers out of reset */
   3468         if (soc_reg_field_valid(unit,reg, rstb_mdioregs)) {
   3469         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3470         soc_reg64_field32_set(unit, reg, &rval64, rstb_mdioregs, 1);
   3471         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3472         }
   3473 
   3474         /* Activate all clocks */
   3475         if (soc_reg_field_valid(unit,reg, rstb_pll)) {
   3476         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3477         soc_reg64_field32_set(unit, reg, &rval64, rstb_pll, 1);
   3478         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3479         }
   3480 
   3481         /* Bring BigMac out of reset*/
   3482         if (soc_reg_field_valid(unit,reg, BIGMACRSTLf)) {
   3483             SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3484             soc_reg64_field32_set(unit, reg, &rval64, BIGMACRSTLf, 1);
   3485             SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3486         }
   3487     }
   3488 
   3489     /* Bring Tx FIFO out of reset */
   3490     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3491     if (soc_reg_field_valid(unit, reg, TXFIFO_RSTLf)) {
   3492         soc_reg64_field32_set(unit, reg, &rval64, TXFIFO_RSTLf, 1);
   3493     } else if (soc_reg_field_valid(unit, reg, txd1_g_fifo_restb)) {
   3494         soc_reg64_field32_set(unit, reg, &rval64,
   3495                               txd1_g_fifo_restb, 0xf);
   3496         soc_reg64_field32_set(unit, reg, &rval64,
   3497                               txd10_g_fifo_restb, 1);
   3498     }
   3499     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3500 
   3501 #if defined(BCM_HELIX15_SUPPORT) || defined(BCM_FELIX15_SUPPORT) || \
   3502     defined(BCM_FIREBOLT2_SUPPORT)
   3503     /* Release LMD reset */
   3504     if (soc_feature(unit, soc_feature_lmd)) {
   3505 #if defined(BCM_FIREBOLT2_SUPPORT)
   3506         if (SOC_REG_IS_VALID(unit, CMIC_1000_BASE_X_MODEr)) {
   3507             uint32 lmd_cmic, lmd_bmp, lmd_ether_bmp;
   3508             int hg_offset;
   3509 
   3510             hg_offset = port - SOC_HG_OFFSET(unit);
   3511 
   3512             /*
   3513              * COVERITY
   3514              * It is kept intentional, API may be modified to return error
   3515              */
   3516             /* coverity[result_independent_of_operands] */
   3517             SOC_IF_ERROR_RETURN
   3518                 (READ_CMIC_1000_BASE_X_MODEr(unit, &lmd_cmic));
   3519             lmd_bmp =
   3520                 soc_reg_field_get(unit, CMIC_1000_BASE_X_MODEr,
   3521                                   lmd_cmic, LMD_ENABLEf);
   3522             lmd_ether_bmp =
   3523                 soc_reg_field_get(unit, CMIC_1000_BASE_X_MODEr,
   3524                                   lmd_cmic, LMD_1000BASEX_ENABLEf);
   3525             if (IS_LMD_ENABLED_PORT(unit, port)) {
   3526                 lmd_bmp |= (1 << hg_offset);
   3527                 if (IS_XE_PORT(unit,port)) {
   3528                     lmd_ether_bmp |= (1 << hg_offset);
   3529                 } else {
   3530                     lmd_ether_bmp &= ~(1 << hg_offset);
   3531                 }
   3532             } else {
   3533                 lmd_bmp &= ~(1 << hg_offset);
   3534                 lmd_ether_bmp &= ~(1 << hg_offset);
   3535             }
   3536             soc_reg_field_set(unit, CMIC_1000_BASE_X_MODEr,
   3537                               &lmd_cmic, LMD_ENABLEf, lmd_bmp);
   3538             soc_reg_field_set(unit, CMIC_1000_BASE_X_MODEr, &lmd_cmic,
   3539                               LMD_1000BASEX_ENABLEf, lmd_ether_bmp);
   3540 
   3541             /*
   3542              * COVERITY
   3543              * It is kept intentional, API may be modified to return error
   3544              */
   3545             /* coverity[result_independent_of_operands] */
   3546             SOC_IF_ERROR_RETURN
   3547                 (WRITE_CMIC_1000_BASE_X_MODEr(unit, lmd_cmic));
   3548         }
   3549 #endif /* BCM_FIREBOLT2_SUPPORT */
   3550 
   3551         SOC_IF_ERROR_RETURN(READ_MAC_CTRLr(unit, port, &rval64));
   3552         soc_reg64_field32_set(unit, MAC_CTRLr, &rval64, LMD_RSTBf, 1);
   3553         SOC_IF_ERROR_RETURN(WRITE_MAC_CTRLr(unit, port, rval64));
   3554     }
   3555 #endif /* BCM_HELIX15_SUPPORT || BCM_FELIX15_SUPPORT ||
   3556         * BCM_FIREBOLT2_SUPPORT */
   3557     return SOC_E_NONE;
   3558 }
   3559 
   3560 int
   3561 soc_xgxs_in_reset(int unit, soc_port_t port)
   3562 {
   3563     soc_reg_t           reg;
   3564     uint64              rval64;
   3565     int                 reset_sleep_usec;
   3566     soc_field_t rstb_hw, rstb_mdioregs, rstb_pll,
   3567                 txd1_g_fifo_restb, txd10_g_fifo_restb,
   3568                 pwrdwn, pwrdwn_pll;
   3569 
   3570     reset_sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   3571 
   3572     reg = MAC_XGXS_CTRLr;
   3573 #if defined(BCM_TRIUMPH_SUPPORT)
   3574     if (SOC_IS_TR_VL(unit) && !SOC_IS_TRIUMPH2(unit) && !SOC_IS_APOLLO(unit) &&
   3575          !SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANE(unit) && !SOC_IS_VALKYRIE2(unit) &&
   3576         (port == 6 || port == 7 || port == 18 || port == 19 ||
   3577          port == 35 || port == 36 || port == 46 || port == 47)) {
   3578         reg = XGPORT_XGXS_CTRLr;
   3579     }
   3580 #endif /* BCM_TRIUMPH_SUPPORT */
   3581 #if defined(BCM_SCORPION_SUPPORT)
   3582     if (SOC_IS_SC_CQ(unit) && (port >= 25 && port <= 28)) {
   3583         reg = QGPORT_MAC_XGXS_CTRLr;
   3584     }
   3585 #endif /* BCM_SCORPION_SUPPORT */
   3586 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT)
   3587     if (SOC_IS_TD_TT(unit) || SOC_IS_SHADOW(unit)) {
   3588         reg = XLPORT_XGXS_CTRL_REGr;
   3589     }
   3590 #endif /* BCM_TRIDENT_SUPPORT */
   3591 #if defined(BCM_KATANA_SUPPORT)
   3592     if (SOC_IS_KATANAX(unit)) {
   3593         reg = XPORT_XGXS_CTRLr;
   3594     }
   3595 #endif /* BCM_KATANA_SUPPORT */
   3596 #if defined(BCM_SABER2_SUPPORT)
   3597     if(SOC_IS_SABER2(unit)) {
   3598         if(IS_MXQ_PORT(unit, port)) {
   3599             reg = XPORT_XGXS_CTRLr;
   3600         } else {
   3601             reg = XLPORT_XGXS0_CTRL_REGr;
   3602         }
   3603     }
   3604 #endif
   3605 #if defined(BCM_TRIUMPH3_SUPPORT)
   3606     if (SOC_IS_TRIUMPH3(unit)) {
   3607         reg = PORT_XGXS0_CTRL_REGr;
   3608     }
   3609 #endif /* BCM_TRIUMPH3_SUPPORT */
   3610 #if defined(BCM_PETRA_SUPPORT)
   3611     if (SOC_IS_ARAD(unit)) {
   3612         reg = PORT_XGXS_0_CTRL_REGr;
   3613     }
   3614 #endif /* BCM_PETRA_SUPPORT */
   3615 
   3616 #if defined(BCM_XGS3_SWITCH_SUPPORT) || defined(BCM_PETRA_SUPPORT)
   3617     if (SOC_REG_FIELD_VALID(unit, reg, LCREFENf) ||
   3618         SOC_REG_FIELD_VALID(unit, reg, LCREF_ENf)) {
   3619         int lcpll;
   3620         soc_field_t lcpll_f;
   3621 
   3622         lcpll_f = SOC_REG_FIELD_VALID(unit, reg, LCREFENf) ? LCREFENf : LCREF_ENf;
   3623         /*
   3624          * Reference clock selection
   3625          */
   3626         lcpll = soc_property_port_get(unit, port, spn_XGXS_LCPLL,
   3627                                       SAL_BOOT_QUICKTURN ? 0 : 1);
   3628         if (lcpll && !SOC_IS_ARAD(unit)) { /* Internal LCPLL reference clock */
   3629             /* Double-check LCPLL lock */
   3630             soc_xgxs_lcpll_lock_check(unit);
   3631         }
   3632         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3633         soc_reg64_field32_set(unit, reg, &rval64, lcpll_f, lcpll ? 1 : 0);
   3634         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3635     }
   3636 #endif /* BCM_XGS3_SWITCH_SUPPORT || BCM_PETRA_SUPPORT*/
   3637 
   3638 #ifdef BCM_PETRA_SUPPORT
   3639     if (SOC_IS_ARAD(unit)) {
   3640         pwrdwn = PWR_DWNf;
   3641         pwrdwn_pll = PWR_DWN_PLLf;
   3642         rstb_hw = RST_B_HWf;
   3643         rstb_mdioregs = RST_B_MDIOREGSf;
   3644         rstb_pll = RST_B_PLLf;
   3645         txd1_g_fifo_restb = TXD_1_G_FIFO_RST_Bf;
   3646         txd10_g_fifo_restb = TXD_10_G_FIFO_RST_Bf;
   3647     } else
   3648 #endif /* BCM_PETRA_SUPPORT */
   3649     {
   3650         pwrdwn = PWRDWNf;
   3651         pwrdwn_pll = PWRDWN_PLLf;
   3652         rstb_hw = RSTB_HWf;
   3653         rstb_mdioregs = RSTB_MDIOREGSf;
   3654         rstb_pll = RSTB_PLLf;
   3655         txd1_g_fifo_restb = TXD1G_FIFO_RSTBf;
   3656         txd10_g_fifo_restb = TXD10G_FIFO_RSTBf;
   3657     }
   3658 
   3659     /*
   3660      * XGXS MAC initialization steps.
   3661      *
   3662      * A minimum delay is required between various initialization steps.
   3663      * There is no maximum delay.  The values given are very conservative
   3664      * including the timeout for PLL lock.
   3665      */
   3666     /* Release reset (if asserted) to allow bigmac to initialize */
   3667     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3668     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   3669     if (soc_reg_field_valid(unit, reg, pwrdwn)) {
   3670         soc_reg64_field32_set(unit, reg, &rval64, pwrdwn, 0);
   3671     }
   3672     if (soc_reg_field_valid(unit, reg, pwrdwn_pll)) {
   3673         soc_reg64_field32_set(unit, reg, &rval64, pwrdwn_pll, 0);
   3674     }
   3675     if (soc_reg_field_valid(unit,reg, HW_RSTLf)) {
   3676         soc_reg64_field32_set(unit, reg, &rval64, HW_RSTLf, 1);
   3677     } else if (soc_reg_field_valid(unit,reg, rstb_hw)) {
   3678         soc_reg64_field32_set(unit, reg, &rval64, rstb_hw, 1);
   3679     }
   3680     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3681     sal_usleep(reset_sleep_usec);
   3682 
   3683     /* Power down and reset */
   3684     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3685     if (soc_reg_field_valid(unit, reg, pwrdwn)) {
   3686         soc_reg64_field32_set(unit, reg, &rval64, pwrdwn, 1);
   3687     }
   3688     if (soc_reg_field_valid(unit, reg, pwrdwn_pll)) {
   3689         soc_reg64_field32_set(unit, reg, &rval64, pwrdwn_pll, 1);
   3690     }
   3691     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 1);
   3692     if (soc_reg_field_valid(unit, reg, HW_RSTLf)) {
   3693         soc_reg64_field32_set(unit, reg, &rval64, HW_RSTLf, 0);
   3694     } else if (soc_reg_field_valid(unit, reg, rstb_hw)) {
   3695         soc_reg64_field32_set(unit, reg, &rval64, rstb_hw, 0);
   3696     }
   3697     if (soc_reg_field_valid(unit, reg, TXFIFO_RSTLf)) {
   3698         soc_reg64_field32_set(unit, reg, &rval64, TXFIFO_RSTLf, 0);
   3699     } else if (soc_reg_field_valid(unit, reg, txd1_g_fifo_restb)) {
   3700         soc_reg64_field32_set(unit, reg, &rval64,
   3701                               txd1_g_fifo_restb, 0);
   3702         soc_reg64_field32_set(unit, reg, &rval64,
   3703                               txd10_g_fifo_restb, 0);
   3704     }
   3705     if (soc_reg_field_valid(unit, reg, AFIFO_RSTf)) {
   3706         soc_reg64_field32_set(unit, reg, &rval64, AFIFO_RSTf, 1);
   3707     }
   3708 
   3709     if (SOC_IS_TRX(unit) || SOC_IS_ARAD(unit)) { /* How about Bradley */
   3710         soc_reg64_field32_set(unit, reg, &rval64, rstb_mdioregs, 0);
   3711         soc_reg64_field32_set(unit, reg, &rval64, rstb_pll, 0);
   3712         if (soc_reg_field_valid(unit,reg, BIGMACRSTLf)) {
   3713             soc_reg64_field32_set(unit, reg, &rval64, BIGMACRSTLf, 0);
   3714         }
   3715     }
   3716     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3717     sal_usleep(reset_sleep_usec);
   3718 
   3719     return SOC_E_NONE;
   3720 }
   3721 
   3722 #endif /* BCM_BIGMAC_SUPPORT || BCM_PETRA_SUPPORT*/
   3723 
   3724 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_PETRA_SUPPORT)
   3725 int
   3726 soc_wc_xgxs_reset(int unit, soc_port_t port, int reg_idx)
   3727 {
   3728 #if defined(BCM_TRIUMPH3_SUPPORT)
   3729     const static soc_reg_t tr3_regs[] = {
   3730         PORT_XGXS0_CTRL_REGr,
   3731         PORT_XGXS1_CTRL_REGr,
   3732         PORT_XGXS2_CTRL_REGr
   3733     };
   3734 #endif /* BCM_TRIUMPH3_SUPPORT */
   3735 #ifdef BCM_PETRA_SUPPORT
   3736     const static soc_reg_t arad_regs[] = {
   3737         PORT_XGXS_0_CTRL_REGr,
   3738         PORT_XGXS_1_CTRL_REGr,
   3739         PORT_XGXS_2_CTRL_REGr
   3740     };
   3741 #endif /* BCM_TRIUMPH3_SUPPORT */
   3742     soc_reg_t   reg;
   3743     uint64      rval64;
   3744     int         reset_sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   3745     int         lcpll;
   3746     soc_field_t rstb_hw, rstb_mdioregs, rstb_pll,
   3747                 txd1_g_fifo_restb, txd10_g_fifo_restb,
   3748                 pwrdwn, pwrdwn_pll;
   3749 
   3750 #if defined(BCM_TRIUMPH3_SUPPORT)
   3751     if (SOC_IS_TRIUMPH3(unit)) {
   3752         reg = tr3_regs[reg_idx];
   3753     } else
   3754 #endif /* BCM_TRIUMPH3_SUPPORT */
   3755 #ifdef BCM_PETRA_SUPPORT
   3756     if (SOC_IS_ARAD(unit)) {
   3757         reg = arad_regs[reg_idx];
   3758     } else
   3759 #endif /* BCM_PETRA_SUPPORT */
   3760     {
   3761         reg = XLPORT_XGXS_CTRL_REGr;
   3762     }
   3763 
   3764 #ifdef BCM_PETRA_SUPPORT
   3765     if (SOC_IS_ARAD(unit)) {
   3766         pwrdwn = PWR_DWNf;
   3767         pwrdwn_pll = PWR_DWN_PLLf;
   3768         rstb_hw = RST_B_HWf;
   3769         rstb_mdioregs = RST_B_MDIOREGSf;
   3770         rstb_pll = RST_B_PLLf;
   3771         txd1_g_fifo_restb = TXD_1_G_FIFO_RST_Bf;
   3772         txd10_g_fifo_restb = TXD_10_G_FIFO_RST_Bf;
   3773     } else
   3774 #endif /* BCM_PETRA_SUPPORT */
   3775     {
   3776         pwrdwn = PWRDWNf;
   3777         pwrdwn_pll = PWRDWN_PLLf;
   3778         rstb_hw = RSTB_HWf;
   3779         rstb_mdioregs = RSTB_MDIOREGSf;
   3780         rstb_pll = RSTB_PLLf;
   3781         txd1_g_fifo_restb = TXD1G_FIFO_RSTBf;
   3782         txd10_g_fifo_restb = TXD10G_FIFO_RSTBf;
   3783     }
   3784 
   3785     /*
   3786      * Reference clock selection
   3787      */
   3788     lcpll = soc_property_port_get(unit, port, spn_XGXS_LCPLL,
   3789                                   SAL_BOOT_QUICKTURN ? 0 : 1);
   3790     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3791     soc_reg64_field32_set(unit, reg, &rval64, LCREF_ENf, lcpll ? 1 : 0);
   3792     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3793 
   3794     /*
   3795      * XGXS MAC initialization steps.
   3796      *
   3797      * A minimum delay is required between various initialization steps.
   3798      * There is no maximum delay.  The values given are very conservative
   3799      * including the timeout for PLL lock.
   3800      */
   3801     /* Release reset (if asserted) to allow xmac/cmac to initialize */
   3802     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   3803     soc_reg64_field32_set(unit, reg, &rval64, pwrdwn, 0);
   3804     soc_reg64_field32_set(unit, reg, &rval64, pwrdwn_pll, 0);
   3805     soc_reg64_field32_set(unit, reg, &rval64, rstb_hw, 1);
   3806     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3807     sal_usleep(reset_sleep_usec);
   3808 
   3809     /* Power down and reset */
   3810     soc_reg64_field32_set(unit, reg, &rval64, pwrdwn, 1);
   3811     soc_reg64_field32_set(unit, reg, &rval64, pwrdwn_pll, 1);
   3812     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 1);
   3813     soc_reg64_field32_set(unit, reg, &rval64, rstb_hw, 0);
   3814     soc_reg64_field32_set(unit, reg, &rval64, rstb_mdioregs, 0);
   3815     soc_reg64_field32_set(unit, reg, &rval64, rstb_pll, 0);
   3816     soc_reg64_field32_set(unit, reg, &rval64, txd1_g_fifo_restb, 0);
   3817     soc_reg64_field32_set(unit, reg, &rval64, txd10_g_fifo_restb, 0);
   3818     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3819     sal_usleep(reset_sleep_usec);
   3820 
   3821     /*
   3822      * Bring up both digital and analog clocks
   3823      *
   3824      * NOTE: Many MAC registers are not accessible until the PLL is locked.
   3825      * An S-Channel timeout will occur before that.
   3826      */
   3827     soc_reg64_field32_set(unit, reg, &rval64, pwrdwn, 0);
   3828     soc_reg64_field32_set(unit, reg, &rval64, pwrdwn_pll, 0);
   3829     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   3830     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3831     sal_usleep(reset_sleep_usec);
   3832 
   3833     /* Bring XGXS out of reset */
   3834     soc_reg64_field32_set(unit, reg, &rval64, rstb_hw, 1);
   3835     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3836     sal_usleep(reset_sleep_usec);
   3837 
   3838     /* Bring MDIO registers out of reset */
   3839     soc_reg64_field32_set(unit, reg, &rval64, rstb_mdioregs, 1);
   3840     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3841 
   3842     /* Activate all clocks */
   3843     soc_reg64_field32_set(unit, reg, &rval64, rstb_pll, 1);
   3844     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3845 
   3846     /* Bring Tx FIFO out of reset */
   3847     soc_reg64_field32_set(unit, reg, &rval64, txd1_g_fifo_restb, 0xf);
   3848     soc_reg64_field32_set(unit, reg, &rval64, txd10_g_fifo_restb, 1);
   3849     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3850 
   3851     return SOC_E_NONE;
   3852 }
   3853 
   3854 int
   3855 soc_wc_xgxs_in_reset(int unit, soc_port_t port, int reg_idx)
   3856 {
   3857 #ifdef BCM_TRIUMPH3_SUPPORT
   3858     const static soc_reg_t tr3_regs[] = {
   3859         PORT_XGXS0_CTRL_REGr,
   3860         PORT_XGXS1_CTRL_REGr,
   3861         PORT_XGXS2_CTRL_REGr
   3862     };
   3863 #endif /* BCM_TRIUMPH3_SUPPORT */
   3864 #ifdef BCM_PETRA_SUPPORT
   3865     const static soc_reg_t arad_regs[] = {
   3866         PORT_XGXS_0_CTRL_REGr,
   3867         PORT_XGXS_1_CTRL_REGr,
   3868         PORT_XGXS_2_CTRL_REGr
   3869     };
   3870 #endif /* BCM_TRIUMPH3_SUPPORT */
   3871     soc_reg_t   reg;
   3872     uint64      rval64;
   3873     int         reset_sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   3874     int         lcpll;
   3875     soc_field_t rstb_hw, rstb_mdioregs, rstb_pll,
   3876                 txd1_g_fifo_restb, txd10_g_fifo_restb,
   3877                 pwrdwn, pwrdwn_pll;
   3878 
   3879 #ifdef BCM_TRIUMPH3_SUPPORT
   3880     if (SOC_IS_TRIUMPH3(unit)) {
   3881         reg = tr3_regs[reg_idx];
   3882     } else
   3883 #endif /* BCM_TRIUMPH3_SUPPORT */
   3884 #ifdef BCM_PETRA_SUPPORT
   3885     if (SOC_IS_ARAD(unit)) {
   3886         reg = arad_regs[reg_idx];
   3887     } else
   3888 #endif /* BCM_PETRA_SUPPORT */
   3889     {
   3890         reg = XLPORT_XGXS_CTRL_REGr;
   3891     }
   3892 
   3893 #ifdef BCM_PETRA_SUPPORT
   3894     if (SOC_IS_ARAD(unit)) {
   3895         pwrdwn = PWR_DWNf;
   3896         pwrdwn_pll = PWR_DWN_PLLf;
   3897         rstb_hw = RST_B_HWf;
   3898         rstb_mdioregs = RST_B_MDIOREGSf;
   3899         rstb_pll = RST_B_PLLf;
   3900         txd1_g_fifo_restb = TXD_1_G_FIFO_RST_Bf;
   3901         txd10_g_fifo_restb = TXD_10_G_FIFO_RST_Bf;
   3902     } else
   3903 #endif /* BCM_PETRA_SUPPORT */
   3904     {
   3905         pwrdwn = PWRDWNf;
   3906         pwrdwn_pll = PWRDWN_PLLf;
   3907         rstb_hw = RSTB_HWf;
   3908         rstb_mdioregs = RSTB_MDIOREGSf;
   3909         rstb_pll = RSTB_PLLf;
   3910         txd1_g_fifo_restb = TXD1G_FIFO_RSTBf;
   3911         txd10_g_fifo_restb = TXD10G_FIFO_RSTBf;
   3912     }
   3913 
   3914     /*
   3915      * Reference clock selection
   3916      */
   3917     lcpll = soc_property_port_get(unit, port, spn_XGXS_LCPLL,
   3918                                   SAL_BOOT_QUICKTURN ? 0 : 1);
   3919     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   3920     soc_reg64_field32_set(unit, reg, &rval64, LCREF_ENf, lcpll ? 1 : 0);
   3921     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3922 
   3923     /*
   3924      * XGXS MAC initialization steps.
   3925      *
   3926      * A minimum delay is required between various initialization steps.
   3927      * There is no maximum delay.  The values given are very conservative
   3928      * including the timeout for PLL lock.
   3929      */
   3930     /* Release reset (if asserted) to allow xmac/cmac to initialize */
   3931     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   3932     soc_reg64_field32_set(unit, reg, &rval64, pwrdwn, 0);
   3933     soc_reg64_field32_set(unit, reg, &rval64, pwrdwn_pll, 0);
   3934     soc_reg64_field32_set(unit, reg, &rval64, rstb_hw, 1);
   3935     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3936     sal_usleep(reset_sleep_usec);
   3937 
   3938     /* Power down and reset */
   3939     soc_reg64_field32_set(unit, reg, &rval64, pwrdwn, 1);
   3940     soc_reg64_field32_set(unit, reg, &rval64, pwrdwn_pll, 1);
   3941     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 1);
   3942     soc_reg64_field32_set(unit, reg, &rval64, rstb_hw, 0);
   3943     soc_reg64_field32_set(unit, reg, &rval64, rstb_mdioregs, 0);
   3944     soc_reg64_field32_set(unit, reg, &rval64, rstb_pll, 0);
   3945     soc_reg64_field32_set(unit, reg, &rval64, txd1_g_fifo_restb, 0);
   3946     soc_reg64_field32_set(unit, reg, &rval64, txd10_g_fifo_restb, 0);
   3947     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   3948     sal_usleep(reset_sleep_usec);
   3949 
   3950     return SOC_E_NONE;
   3951 }
   3952 
   3953 int
   3954 soc_wc_xgxs_pll_check(int unit, soc_port_t port, int reg_idx)
   3955 {
   3956 #ifdef BCM_TRIUMPH3_SUPPORT
   3957     const static soc_reg_t tr3_regs[] = {
   3958         PORT_XGXS0_STATUS_GEN_REGr,
   3959         PORT_XGXS1_STATUS_GEN_REGr,
   3960         PORT_XGXS2_STATUS_GEN_REGr
   3961     };
   3962 #endif /* BCM_TRIUMPH3_SUPPORT */
   3963     soc_reg_t   reg;
   3964     uint32      rval;
   3965     int         phy_port, block, retry;
   3966     int         lock_sleep_usec = 5000;
   3967 
   3968 #ifdef BCM_TRIUMPH3_SUPPORT
   3969     if (SOC_IS_TRIUMPH3(unit)) {
   3970         reg = tr3_regs[reg_idx];
   3971     } else
   3972 #endif /* BCM_TRIUMPH3_SUPPORT */
   3973     {
   3974         reg = XLPORT_XGXS_STATUS_GEN_REGr;
   3975     }
   3976 
   3977     retry = 10;
   3978 
   3979     /* Check TxPLL lock status */
   3980     while (retry > 0) {
   3981         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
   3982         if (soc_reg_field_get(unit, reg, rval, TXPLL_LOCKf)) {
   3983             return SOC_E_NONE;
   3984         }
   3985         sal_usleep(lock_sleep_usec);
   3986         retry--;
   3987     }
   3988 
   3989     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   3990     block = SOC_PORT_BLOCK(unit, phy_port);
   3991     LOG_ERROR(BSL_LS_SOC_COMMON,
   3992               (BSL_META_U(unit,
   3993                           "unit %d %s TXPLL not locked\n"),
   3994                unit, SOC_BLOCK_NAME(unit, block)));
   3995     return SOC_E_NONE;
   3996 }
   3997 
   3998 int
   3999 soc_wc_xgxs_power_down(int unit, soc_port_t port, int reg_idx)
   4000 {
   4001 #if defined(BCM_TRIUMPH3_SUPPORT)
   4002     const static soc_reg_t tr3_regs[] = {
   4003         PORT_XGXS0_CTRL_REGr,
   4004         PORT_XGXS1_CTRL_REGr,
   4005         PORT_XGXS2_CTRL_REGr
   4006     };
   4007 #endif /* BCM_TRIUMPH3_SUPPORT */
   4008     soc_reg_t   reg;
   4009     uint64      rval64;
   4010 
   4011 #if defined(BCM_TRIUMPH3_SUPPORT)
   4012     if (SOC_IS_TRIUMPH3(unit)) {
   4013         reg = tr3_regs[reg_idx];
   4014     } else
   4015 #endif /* BCM_TRIUMPH3_SUPPORT */
   4016     {
   4017         reg = XLPORT_XGXS_CTRL_REGr;
   4018     }
   4019 
   4020     /* Power down and reset */
   4021     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   4022     soc_reg64_field32_set(unit, reg, &rval64, PWRDWNf, 1);
   4023     soc_reg64_field32_set(unit, reg, &rval64, PWRDWN_PLLf, 1);
   4024     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 1);
   4025     soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 0);
   4026     soc_reg64_field32_set(unit, reg, &rval64, RSTB_MDIOREGSf, 0);
   4027     soc_reg64_field32_set(unit, reg, &rval64, RSTB_PLLf, 0);
   4028     soc_reg64_field32_set(unit, reg, &rval64, TXD1G_FIFO_RSTBf, 0);
   4029     soc_reg64_field32_set(unit, reg, &rval64, TXD10G_FIFO_RSTBf, 0);
   4030     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4031     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   4032                 (BSL_META_U(unit,
   4033                             "Power down wc for port: %d\n"), port));
   4034     return SOC_E_NONE;
   4035 }
   4036 #endif /* BCM_TRIDENT_SUPPORT */
   4037 
   4038 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || defined(BCM_SABER2_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
   4039 /*
   4040  * function: _soc_xgxs_reset_single_tsc
   4041  * purpose:  reset a single TSC associate with a TD2/TD2+ port
   4042 */
   4043 STATIC soc_error_t
   4044 _soc_xgxs_reset_single_tsc(int unit, soc_port_t port, soc_reg_t reg) {
   4045 
   4046     int         sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   4047     int         lcpll;
   4048     uint64      rval64;
   4049     /*
   4050      * Reference clock selection
   4051      */
   4052     lcpll = soc_property_port_get(unit, port, spn_XGXS_LCPLL,
   4053                                   SAL_BOOT_QUICKTURN ? 0 : 1);
   4054     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   4055     if (SOC_IS_TOMAHAWK3(unit) && reg == CDPORT_XGXS0_CTRL_REGr) {
   4056 #if 0
   4057         
   4058         soc_reg64_field32_set(unit, reg, &rval64, PLL0_REFIN_ENf, lcpll ? 1 : 0);
   4059         soc_reg64_field32_set(unit, reg, &rval64, PLL1_REFIN_ENf, lcpll ? 1 : 0);
   4060 #endif
   4061     } else {
   4062     soc_reg64_field32_set(unit, reg, &rval64, REFIN_ENf, lcpll ? 1 : 0);
   4063     }
   4064     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4065 #if 0
   4066     
   4067     /* For TH3 field is named differently */
   4068     if (SOC_IS_TOMAHAWK3(unit)) {
   4069         if (soc_reg_field_valid(unit, reg, TSC_IDDQf)) {
   4070             soc_reg64_field32_set(unit, reg, &rval64, TSC_IDDQf, 0);
   4071         }
   4072     }
   4073 #endif
   4074     /*
   4075      * For TH+/TH2/Apache B0 default behaviour of CLPORT port IDDQ is changed,
   4076      * TH2 default behaviour of XLPORT IDDQ is changed,
   4077      * port init sequence must be adjusted to bring tsc out of reset properly
   4078      */
   4079     if (soc_feature(unit, soc_feature_iddq_new_default) &&
   4080         ((reg == CLPORT_XGXS0_CTRL_REGr) ||
   4081         (SOC_IS_TOMAHAWK2(unit) && reg == XLPORT_XGXS0_CTRL_REGr) ||
   4082         (SOC_IS_MONTEREY(unit) && reg == XLPORT_XGXS0_CTRL_REGr) ||
   4083         (SOC_IS_TOMAHAWK3(unit) && reg == XLPORT_XGXS0_CTRL_REGr))) {
   4084         if (soc_reg_field_valid(unit, reg, IDDQf)) {
   4085             soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   4086         }
   4087     }
   4088 
   4089     if (SOC_IS_GREYHOUND2(unit)) {
   4090         if ((reg == XLPORT_XGXS0_CTRL_REGr) ||
   4091             (reg == CLPORT_XGXS0_CTRL_REGr)) {
   4092             if (soc_reg_field_valid(unit, reg, IDDQf)) {
   4093                 soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   4094             }
   4095         }
   4096     }
   4097 
   4098     /* Deassert power down */
   4099     /* For TH3 field is named differently */
   4100     if (SOC_IS_TOMAHAWK3(unit) && reg == CDPORT_XGXS0_CTRL_REGr) {
   4101         soc_reg64_field32_set(unit, reg, &rval64, TSC_PWRDWNf, 0);
   4102     } else {
   4103     soc_reg64_field32_set(unit, reg, &rval64, PWRDWNf, 0);
   4104     }
   4105     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4106     sal_usleep(sleep_usec);
   4107 
   4108     /*for TH3 PM8x50, we need to choose TVCO clk source, chip default is PLL0
   4109     however for TH3 need to use PLL1*/
   4110     if (SOC_IS_TOMAHAWK3(unit) && reg == CDPORT_XGXS0_CTRL_REGr) {
   4111         soc_reg64_field32_set(unit, reg, &rval64, TSC_CLK_SELf, 1);
   4112     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4113     sal_usleep(sleep_usec);
   4114     }
   4115 
   4116     /* Reset XGXS */
   4117     /* For TH3 field is named differently */
   4118     if (SOC_IS_TOMAHAWK3(unit) && reg == CDPORT_XGXS0_CTRL_REGr) {
   4119         soc_reg64_field32_set(unit, reg, &rval64, TSC_RSTBf, 0);
   4120     } else {
   4121     soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 0);
   4122     }
   4123     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4124     sal_usleep(sleep_usec+10000);
   4125 
   4126     /* Bring XGXS out of reset */
   4127     /* For TH3 field is named differently */
   4128     if (SOC_IS_TOMAHAWK3(unit) && reg == CDPORT_XGXS0_CTRL_REGr) {
   4129         soc_reg64_field32_set(unit, reg, &rval64, TSC_RSTBf, 1);
   4130     } else {
   4131     soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 1);
   4132     }
   4133     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4134     sal_usleep(sleep_usec);
   4135 
   4136     /* Bring reference clock out of reset */
   4137     if (soc_reg_field_valid(unit, reg, RSTB_REFCLKf)) {
   4138         soc_reg64_field32_set(unit, reg, &rval64, RSTB_REFCLKf, 1);
   4139         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4140     }
   4141     /* Activate clocks */
   4142     if (soc_reg_field_valid(unit, reg, RSTB_PLLf)) {
   4143         soc_reg64_field32_set(unit, reg, &rval64, RSTB_PLLf, 1);
   4144         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4145     }
   4146     return SOC_E_NONE;
   4147 }
   4148 
   4149 /*
   4150  * function: _soc_xgxs_powerdown_single_tsc
   4151  * purpose:  Powerdown a single TSC associate with a TD2/TH/TD2+/TH2 port
   4152  */
   4153 STATIC soc_error_t
   4154 _soc_xgxs_powerdown_single_tsc(int unit, soc_port_t port, soc_reg_t reg) {
   4155 
   4156     int         sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   4157     int         lcpll;
   4158     uint64      rval64;
   4159     /*
   4160      * Reference clock selection
   4161      */
   4162     lcpll = soc_property_port_get(unit, port, spn_XGXS_LCPLL,
   4163                                   SAL_BOOT_QUICKTURN ? 0 : 1);
   4164     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   4165     soc_reg64_field32_set(unit, reg, &rval64, REFIN_ENf, lcpll ? 1 : 0);
   4166 
   4167     /*
   4168      * For TH+/TH2/Apache B0 default behaviour of CLPORT port IDDQ is changed,
   4169      * TH2 default befhavior of XLPORT IDDQ is changed,
   4170      * port init sequence must be adjusted to bring tsc out of reset properly
   4171      */
   4172     if (soc_feature(unit, soc_feature_iddq_new_default) &&
   4173         ((reg == CLPORT_XGXS0_CTRL_REGr) || (reg == PMQ_XGXS0_CTRL_REGr) ||
   4174          ((SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) &&
   4175           (reg == XLPORT_XGXS0_CTRL_REGr)))) {
   4176         if (soc_reg_field_valid(unit, reg, IDDQf)) {
   4177             soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   4178         }
   4179     }
   4180 
   4181     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4182 
   4183     if (soc_feature(unit, soc_feature_iddq_new_default) &&
   4184         ((reg == CLPORT_XGXS0_CTRL_REGr) ||
   4185          ((SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) &&
   4186           (reg == XLPORT_XGXS0_CTRL_REGr)))) {
   4187         sal_usleep(sleep_usec);
   4188     }
   4189 
   4190     /* Deassert power down */
   4191     soc_reg64_field32_set(unit, reg, &rval64, PWRDWNf, 0);
   4192     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4193     sal_usleep(sleep_usec);
   4194 
   4195     /* Reset XGXS */
   4196     soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 0);
   4197     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4198 
   4199     return SOC_E_NONE;
   4200 }
   4201 
   4202 /*
   4203  * function: _soc_xgxs_powerup_single_tsc
   4204  * purpose:  Powerup a single TSC associate with a TD2/TH/TD2+/TH2 port
   4205  */
   4206 STATIC soc_error_t
   4207 _soc_xgxs_powerup_single_tsc(int unit, soc_port_t port, soc_reg_t reg) {
   4208 
   4209     int         sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   4210     uint64      rval64;
   4211 
   4212     /* Bring XGXS out of reset */
   4213     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &rval64));
   4214     soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 1);
   4215     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4216     sal_usleep(sleep_usec);
   4217 
   4218     /* Bring reference clock out of reset */
   4219     if (soc_reg_field_valid(unit, reg, RSTB_REFCLKf)) {
   4220         soc_reg64_field32_set(unit, reg, &rval64, RSTB_REFCLKf, 1);
   4221         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4222     }
   4223     /* Activate clocks */
   4224     if (soc_reg_field_valid(unit, reg, RSTB_PLLf)) {
   4225         soc_reg64_field32_set(unit, reg, &rval64, RSTB_PLLf, 1);
   4226         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, 0, rval64));
   4227     }
   4228     return SOC_E_NONE;
   4229 }
   4230 
   4231 /*
   4232  * function: _soc_xgxs_reset_tsc_triplet
   4233  * purpose:  reset a TSC-12 associate with a TD2+ 100G port
   4234  */
   4235 STATIC soc_error_t
   4236 _soc_xgxs_reset_tsc_triplet(int unit, soc_port_t port) {
   4237     /*
   4238      * TD2+ 100G case, PGWs have TSCs mapped as follows.
   4239      * (This mapping is common for all PGWs regardless of Odd/Even)
   4240      *  PGW_TSC0_CTRL_REGr,->|       |
   4241      *  PGW_TSC1_CTRL_REGr,->|TSC-12 |
   4242      *  PGW_TSC2_CTRL_REGr,->|       |
   4243      *  PGW_TSC3_CTRL_REGr -> TSC-4
   4244      * All 3 Control registers associated with a TSC-12 must be reset for
   4245      * a 100G port to be reset.
   4246      */
   4247     const static soc_reg_t ctrl_regs_td2plus[] = {
   4248         PGW_TSC0_CTRL_REGr,
   4249         PGW_TSC1_CTRL_REGr,
   4250         PGW_TSC2_CTRL_REGr,
   4251         PGW_TSC3_CTRL_REGr,
   4252     };
   4253     int         sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   4254     int         lcpll;
   4255     int         i;
   4256     uint64      rval64;
   4257 
   4258     /*This sequence is the same as in _soc_xgxs_reset_single_tsc, but across
   4259      *all 3 TSC-4s within a TSC-12
   4260      */
   4261     /* Reference clock selection */
   4262     for (i = 0; i < 3; i++) {
   4263         lcpll = soc_property_port_get(unit, port, spn_XGXS_LCPLL,
   4264                                       SAL_BOOT_QUICKTURN ? 0 : 1);
   4265         SOC_IF_ERROR_RETURN(soc_reg_get(unit, ctrl_regs_td2plus[i], port, 0,
   4266                             &rval64));
   4267         soc_reg64_field32_set(unit, ctrl_regs_td2plus[i], &rval64, REFIN_ENf,
   4268                               lcpll ? 1 : 0);
   4269         SOC_IF_ERROR_RETURN(soc_reg_set(unit, ctrl_regs_td2plus[i], port, 0,
   4270                             rval64));
   4271     }
   4272 
   4273     /* Deassert power down */
   4274     for (i = 0; i < 3; i++) {
   4275         soc_reg64_field32_set(unit, ctrl_regs_td2plus[i], &rval64, PWRDWNf, 0);
   4276         SOC_IF_ERROR_RETURN(soc_reg_set(unit, ctrl_regs_td2plus[i], port, 0,
   4277                             rval64));
   4278         sal_usleep(sleep_usec);
   4279     }
   4280 
   4281     /* Reset XGXS */
   4282     for (i = 0; i < 3; i++) {
   4283         soc_reg64_field32_set(unit, ctrl_regs_td2plus[i], &rval64, RSTB_HWf, 0);
   4284         SOC_IF_ERROR_RETURN(soc_reg_set(unit, ctrl_regs_td2plus[i], port, 0,
   4285                             rval64));
   4286         sal_usleep(sleep_usec+10000);
   4287     }
   4288 
   4289     /* Bring XGXS out of reset */
   4290     for (i = 0; i < 3; i++) {
   4291         soc_reg64_field32_set(unit, ctrl_regs_td2plus[i], &rval64, RSTB_HWf, 1);
   4292         SOC_IF_ERROR_RETURN(soc_reg_set(unit, ctrl_regs_td2plus[i], port, 0,
   4293                             rval64));
   4294         sal_usleep(sleep_usec);
   4295     }
   4296 
   4297     /* Bring reference clock out of reset */
   4298     for (i = 0; i < 3; i++) {
   4299         if (soc_reg_field_valid(unit, ctrl_regs_td2plus[i], RSTB_REFCLKf)) {
   4300             soc_reg64_field32_set(unit, ctrl_regs_td2plus[i], &rval64,
   4301                                   RSTB_REFCLKf, 1);
   4302             SOC_IF_ERROR_RETURN(soc_reg_set(unit, ctrl_regs_td2plus[i], port, 0,
   4303                                             rval64));
   4304         }
   4305     }
   4306 
   4307     /* Activate clocks */
   4308     for (i = 0; i < 3; i++) {
   4309         if (soc_reg_field_valid(unit, ctrl_regs_td2plus[i], RSTB_PLLf)) {
   4310             soc_reg64_field32_set(unit, ctrl_regs_td2plus[i], &rval64,
   4311                                   RSTB_PLLf, 1);
   4312             SOC_IF_ERROR_RETURN(soc_reg_set(unit, ctrl_regs_td2plus[i], port, 0,
   4313                                             rval64));
   4314         }
   4315     }
   4316     return SOC_E_NONE;
   4317 }
   4318 
   4319 /* Check the port argument is indicating a block id */
   4320 #define SOC_IS_BLKID_PORT(_blkid_port)  \
   4321     (_blkid_port & SOC_REG_ADDR_BLOCK_ID_MASK)
   4322 /* Get the block type from the port argument which is a block id */
   4323 #define SOC_BLOCK_TYPE_BLKID_PORT(_u, _blkid_port)   \
   4324     (SOC_BLOCK_TYPE(_u, (_blkid_port & ~SOC_REG_ADDR_BLOCK_ID_MASK)))
   4325 
   4326 /*
   4327  * function: soc_tsc_xgxs_reset
   4328  * purpose:  Reset all TSCs associated with the passed port.
   4329 */
   4330 soc_error_t
   4331 soc_tsc_xgxs_reset(int unit, soc_port_t port, int reg_idx)
   4332 {
   4333     soc_error_t rv = SOC_E_NONE;
   4334     const static soc_reg_t ctrl_regs[] = {
   4335         XLPORT_XGXS0_CTRL_REGr,
   4336         XLPORT_XGXS0_CTRL_REGr,
   4337         XLPORT_XGXS0_CTRL_REGr,
   4338         XLPORT_XGXS0_CTRL_REGr,
   4339     };
   4340     const static soc_reg_t cxxport_ctrl_regs[] = {
   4341         CXXPORT_XGXS0_CTRL0_REGr,
   4342         CXXPORT_XGXS0_CTRL1_REGr,
   4343         CXXPORT_XGXS0_CTRL2_REGr,
   4344     };
   4345 
   4346     soc_reg_t reg = ctrl_regs[reg_idx];
   4347 
   4348     if ((port > 0) && SOC_IS_BLKID_PORT(port)) {
   4349         if (SOC_BLOCK_TYPE_BLKID_PORT(unit, port) == SOC_BLK_PMQ) {
   4350             reg = GPORT_XGXS0_CTRL_REGr;
   4351         }
   4352     } else if (IS_CXX_PORT(unit, port)) {
   4353         reg = cxxport_ctrl_regs[reg_idx];
   4354     } else if (IS_CL_PORT(unit, port) || IS_CLG2_PORT(unit, port)) {
   4355         reg = CLPORT_XGXS0_CTRL_REGr;
   4356     } else if (IS_CD_PORT(unit, port)) {
   4357         reg = CDPORT_XGXS0_CTRL_REGr;
   4358     } 
   4359 
   4360     if ((!SOC_IS_TRIDENT2X(unit)
   4361             && !SOC_IS_TITAN2PLUS(unit))
   4362                     || SOC_IS_APACHE(unit)) {
   4363         rv = _soc_xgxs_reset_single_tsc(unit, port, reg);
   4364     } else {
   4365         int block_num;
   4366         int pgw_block;
   4367         const static soc_reg_t ctrl_regs_td2plus[] = {
   4368             PGW_TSC0_CTRL_REGr,
   4369             PGW_TSC1_CTRL_REGr,
   4370             PGW_TSC2_CTRL_REGr,
   4371             PGW_TSC3_CTRL_REGr,
   4372         };
   4373 
   4374         /* For blocks which are not valid resetting the TSC can crash the SDK */
   4375         block_num = (SOC_INFO(unit).port_l2p_mapping[port]-1)/16;
   4376         pgw_block =PGW_CL_BLOCK(unit, block_num);
   4377         if ( pgw_block < 0 || !SOC_INFO(unit).block_valid[pgw_block]) {
   4378             return rv;
   4379         }
   4380         if (!SOC_IS_TD2P_TT2P(unit)) {
   4381             reg = ctrl_regs[reg_idx];
   4382         } else {
   4383             reg = ctrl_regs_td2plus[reg_idx];
   4384         }
   4385         /* for TD2 and TD2+ non-100G ports, reset only one TSC*/
   4386         if (!SOC_IS_TD2P_TT2P(unit) ||
   4387             SOC_INFO(unit).port_speed_max[port] < 100000) {
   4388             rv = _soc_xgxs_reset_single_tsc(unit, port, reg);
   4389         } else {
   4390             rv = _soc_xgxs_reset_tsc_triplet(unit, port);
   4391         }
   4392     }
   4393     return rv;
   4394 }
   4395 
   4396 /*
   4397  * function: soc_tsc_xgxs_power_mode
   4398  * purpose:  Reset all TSCs associated with the passed port.
   4399 */
   4400 soc_error_t
   4401 soc_tsc_xgxs_power_mode(int unit, soc_port_t port, int reg_idx, int power_down)
   4402 {
   4403     soc_error_t rv = SOC_E_NONE;
   4404     soc_reg_t reg = XLPORT_XGXS0_CTRL_REGr;
   4405 
   4406     /* must check if "port" is a block before IS_CL_PORT */
   4407     if (SOC_IS_BLKID_PORT(port)) {
   4408         if (SOC_BLOCK_TYPE_BLKID_PORT(unit, port) == SOC_BLK_PMQPORT) {
   4409             reg = PMQ_XGXS0_CTRL_REGr;
   4410         }
   4411     } else if (IS_CL_PORT(unit, port)) {
   4412         reg = CLPORT_XGXS0_CTRL_REGr;
   4413 
   4414 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   4415         /* CLPORT act as refclk master should always be active */
   4416         if (soc_feature(unit, soc_feature_pm_refclk_master)) {
   4417             int clport_blk, phy_port;
   4418             soc_info_t *si = &SOC_INFO(unit);
   4419 
   4420             phy_port = si->port_l2p_mapping[port];
   4421             clport_blk = SOC_PORT_BLOCK(unit, phy_port);
   4422             if (SHR_BITGET(si->pm_ref_master_bitmap, clport_blk)) {
   4423                 return SOC_E_NONE;
   4424             }
   4425         }
   4426 #endif
   4427     }
   4428 
   4429     if (power_down) {
   4430         rv = _soc_xgxs_powerdown_single_tsc(unit, port, reg);
   4431     } else {
   4432         rv = _soc_xgxs_powerup_single_tsc(unit, port, reg);
   4433     }
   4434     return rv;
   4435 }
   4436 
   4437 int
   4438 soc_tsc_xgxs_pll_check(int unit, soc_port_t port, int reg_idx)
   4439 {
   4440     const static soc_field_t status_fields[] = {
   4441         TSC_0_AFE_PLL_LOCKf, TSC_1_AFE_PLL_LOCKf,
   4442         TSC_2_AFE_PLL_LOCKf, TSC_3_AFE_PLL_LOCKf,
   4443         TSC_4_AFE_PLL_LOCKf, TSC_5_AFE_PLL_LOCKf,
   4444         TSC_6_AFE_PLL_LOCKf, TSC_7_AFE_PLL_LOCKf,
   4445         TSC_8_AFE_PLL_LOCKf, TSC_9_AFE_PLL_LOCKf,
   4446         TSC_10_AFE_PLL_LOCKf, TSC_11_AFE_PLL_LOCKf,
   4447         TSC_12_AFE_PLL_LOCKf, TSC_13_AFE_PLL_LOCKf,
   4448         TSC_14_AFE_PLL_LOCKf, TSC_15_AFE_PLL_LOCKf,
   4449         TSC_16_AFE_PLL_LOCKf, TSC_17_AFE_PLL_LOCKf,
   4450         TSC_18_AFE_PLL_LOCKf, TSC_19_AFE_PLL_LOCKf,
   4451         TSC_20_AFE_PLL_LOCKf, TSC_21_AFE_PLL_LOCKf,
   4452         TSC_22_AFE_PLL_LOCKf, TSC_23_AFE_PLL_LOCKf,
   4453         TSC_24_AFE_PLL_LOCKf, TSC_25_AFE_PLL_LOCKf,
   4454         TSC_26_AFE_PLL_LOCKf, TSC_27_AFE_PLL_LOCKf,
   4455         TSC_28_AFE_PLL_LOCKf, TSC_29_AFE_PLL_LOCKf,
   4456         TSC_30_AFE_PLL_LOCKf, TSC_31_AFE_PLL_LOCKf,
   4457     };
   4458     soc_reg_t   reg;
   4459     soc_field_t field;
   4460     uint32      rval;
   4461     int         retry;
   4462     int         lock_sleep_usec = 5000;
   4463 
   4464     reg = TOP_TSC_AFE_PLL_STATUSr;
   4465     field = status_fields[SOC_INFO(unit).port_serdes[port]];
   4466 
   4467     retry = 10;
   4468 
   4469     /* Check TxPLL lock status */
   4470     while (retry > 0) {
   4471         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   4472         if (soc_reg_field_get(unit, reg, rval, field)) {
   4473             return SOC_E_NONE;
   4474         }
   4475         sal_usleep(lock_sleep_usec);
   4476         retry--;
   4477     }
   4478 
   4479     LOG_ERROR(BSL_LS_SOC_COMMON,
   4480               (BSL_META_U(unit,
   4481                           "unit %d TSC %d TXPLL not locked\n"),
   4482                unit, SOC_INFO(unit).port_serdes[port]));
   4483     return SOC_E_NONE;
   4484 }
   4485 #endif /* BCM_TRIDENT2_SUPPORT || BCM_HURRICANE2_SUPPORT */
   4486 
   4487 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   4488 /*
   4489  * Function:
   4490  *      soc_xgxs_reset_master_tsc
   4491  * Purpose:
   4492  *      Reset TSCs that need to be initialized to master mode.
   4493  *      In Tomahawk2, there are 8 port macros that will driven directly from
   4494  *      the system board and they will act as the refclk master to drive the
   4495  *      other instances. These port macros should always be initialized to
   4496  *      master mode and should always be active.
   4497  * Parameters:
   4498  *      unit - SOC unit #
   4499  * Returns:
   4500  *      SOC_E_XXX
   4501  */
   4502 
   4503 int
   4504 soc_xgxs_reset_master_tsc(int unit)
   4505 {
   4506     soc_info_t *si = &SOC_INFO(unit);
   4507     int clport_blk, block;
   4508     uint64 rval64;
   4509     uint32 addr;
   4510     uint8 at;
   4511     soc_reg_t reg = CLPORT_XGXS0_CTRL_REGr;
   4512     int sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   4513 
   4514     if (soc_feature(unit, soc_feature_pm_refclk_master)) {
   4515 
   4516         addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0, TRUE, &block, &at);
   4517 
   4518         SHR_BIT_ITER(si->pm_ref_master_bitmap, SOC_MAX_NUM_BLKS, clport_blk) {
   4519             block = SOC_BLOCK_INFO(unit, clport_blk).cmic;
   4520 
   4521             /* Set TSC in master mode */
   4522             SOC_REG_RST_VAL_GET(unit, CLPORT_XGXS0_CTRL_REGr, rval64);
   4523             soc_reg64_field32_set(unit, reg, &rval64, REFIN_ENf, 0);
   4524             soc_reg64_field32_set(unit, reg, &rval64, REFOUT_ENf, 1);
   4525             SOC_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64));
   4526 
   4527             /*
   4528              * For TH2 default behaviour of CLPORT port IDDQ is changed, port
   4529              * init sequence must be adjusted to bring tsc out of reset properly
   4530              */
   4531             if (soc_feature(unit, soc_feature_iddq_new_default)) {
   4532                 if (soc_reg_field_valid(unit, reg, IDDQf)) {
   4533                     soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   4534                 }
   4535             }
   4536 
   4537             /* Deassert power down */
   4538             soc_reg64_field32_set(unit, reg, &rval64, PWRDWNf, 0);
   4539             SOC_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64));
   4540             sal_usleep(sleep_usec);
   4541 
   4542             /* Reset XGXS */
   4543             soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 0);
   4544             SOC_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64));
   4545 
   4546             sal_usleep(sleep_usec + 10000);
   4547 
   4548             /* Bring XGXS out of reset */
   4549             soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 1);
   4550             SOC_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64));
   4551             sal_usleep(sleep_usec);
   4552         }
   4553     }
   4554 
   4555     return SOC_E_NONE;
   4556 }
   4557 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */
   4558 
   4559 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
   4560 int
   4561 soc_pm_power_mode_set(int unit, soc_port_t port, int reg_idx, int power_down)
   4562 {
   4563 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) || \
   4564     defined(BCM_SABER2_SUPPORT)
   4565     SOC_IF_ERROR_RETURN
   4566         (soc_tsc_xgxs_power_mode(unit, port, reg_idx, power_down));
   4567 #endif
   4568     return SOC_E_NONE;
   4569 }
   4570 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */
   4571 
   4572 #if defined(BCM_GREYHOUND2_SUPPORT)
   4573 /*
   4574  * function: soc_sgmii4px2_reset
   4575  * purpose:  Reset all SGMII4PX2.
   4576  */
   4577 soc_error_t
   4578 soc_sgmii4px2_reset(int unit, soc_port_t port, int reg_idx)
   4579 {
   4580     const static soc_reg_t ctrl_regs[] = {
   4581         GPORT_SGMII0_CTRL_REGr,
   4582         GPORT_SGMII1_CTRL_REGr
   4583     };
   4584     uint32      rval;
   4585     int         sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   4586 
   4587     soc_reg_t reg = ctrl_regs[reg_idx];
   4588 
   4589     /*
   4590      * Reference clock selection
   4591      */
   4592     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
   4593     soc_reg_field_set(unit, reg, &rval, IDDQf, 1);
   4594     soc_reg_field_set(unit, reg, &rval, PWRDWNf, 1);
   4595     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   4596     sal_usleep(sleep_usec);
   4597 
   4598     /* Analog section powered */
   4599     soc_reg_field_set(unit, reg, &rval, IDDQf, 0);
   4600     /* Deassert power down */
   4601     soc_reg_field_set(unit, reg, &rval, PWRDWNf, 0);
   4602     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   4603     sal_usleep(sleep_usec);
   4604 
   4605     /* Bring SGMII out of reset */
   4606     soc_reg_field_set(unit, reg, &rval, RSTB_HWf, 1);
   4607     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   4608     sal_usleep(sleep_usec);
   4609 
   4610     /* Activate MDIO on SGMII */
   4611     soc_reg_field_set(unit, reg, &rval, RSTB_MDIOREGSf, 1);
   4612     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   4613     sal_usleep(sleep_usec);
   4614 
   4615     /* Activate clocks */
   4616     soc_reg_field_set(unit, reg, &rval, RSTB_PLLf, 1);
   4617     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   4618 
   4619     return SOC_E_NONE;
   4620 }
   4621 #endif /* BCM_GREYHOUND2_SUPPORT */
   4622 
   4623 int soc_is_valid_block_instance(int unit, soc_block_types_t block_types,
   4624                                 int block_instance, int *is_valid)
   4625 {
   4626 
   4627     int nof_block_instances;
   4628 
   4629     if (is_valid == NULL) {
   4630         return SOC_E_PARAM;
   4631     }
   4632 
   4633     if (block_instance < 0) {
   4634         return SOC_E_PARAM;
   4635     }
   4636 
   4637     /*default*/
   4638     nof_block_instances = 0;
   4639 
   4640 #ifdef BCM_DFE_SUPPORT
   4641     if(SOC_IS_DFE(unit)) {
   4642         int rv = soc_dfe_nof_block_instances(unit, block_types, &nof_block_instances);
   4643         SOC_IF_ERROR_RETURN(rv);
   4644     }
   4645 #endif
   4646 #ifdef BCM_DNXF_SUPPORT
   4647     if(SOC_IS_DNXF(unit)) {
   4648         int rv = soc_dnxf_nof_block_instances(unit, block_types, &nof_block_instances);
   4649         SOC_IF_ERROR_RETURN(rv);
   4650     }
   4651 #endif
   4652 #ifdef BCM_PETRA_SUPPORT
   4653     if(SOC_IS_ARAD(unit)) {
   4654         int rv = soc_dpp_nof_block_instances(unit, block_types, &nof_block_instances);
   4655         SOC_IF_ERROR_RETURN(rv);
   4656     }
   4657 #endif
   4658 
   4659 #ifdef BCM_DNX_SUPPORT
   4660     if(SOC_IS_DNX(unit)) {
   4661         int rv = soc_dnxc_nof_block_instances(unit, block_types, &nof_block_instances);
   4662         SOC_IF_ERROR_RETURN(rv);
   4663     }
   4664 #endif
   4665     *is_valid = (block_instance < nof_block_instances );
   4666 
   4667     return SOC_E_NONE;
   4668 }
   4669 
   4670 /*
   4671  * Function:
   4672  *      soc_phy_firmware_load
   4673  * Purpose:
   4674  *      Load firmware into internal SerDes core.
   4675  * Parameters:
   4676  *      unit - unit number
   4677  *      port - port number on device.
   4678  *      fw_data - firmware (binary byte array)
   4679  *      fw_size - size of firmware (in bytes)
   4680  * Returns:
   4681  *      SOC_E_XXX
   4682  * Notes:
   4683  *      This function is simply a wrapper for a device-specific implementation.
   4684  */
   4685 
   4686 int
   4687 soc_phy_firmware_load(int unit, int port, uint8 *fw_data, int fw_size)
   4688 {
   4689     soc_phy_firmware_load_f firmware_load;
   4690 
   4691     firmware_load = SOC_FUNCTIONS(unit)->soc_phy_firmware_load;
   4692     if (firmware_load != NULL) {
   4693         return firmware_load(unit, port, fw_data, fw_size);
   4694     }
   4695     return SOC_E_UNAVAIL;
   4696 }
   4697 
   4698 
   4699 #ifdef BCM_LEDPROC_SUPPORT
   4700 
   4701 /*
   4702  * Function:
   4703  *      soc_ledproc_config
   4704  * Purpose:
   4705  *      Load a program into the LED microprocessor from a buffer
   4706  *      and start it running.
   4707  * Parameters:
   4708  *      unit - StrataSwitch unit #
   4709  *      program - Array of up to 256 program bytes
   4710  *      bytes - Number of bytes in array, 0 to disable ledproc, upper 16bit
   4711  *              specifies which LED processor(0,1,2, ...).
   4712  * Notes:
   4713  *      Also clears the LED processor data RAM from 0x80-0xff
   4714  *      so the LED program has a known state at startup.
   4715  */
   4716 
   4717 int
   4718 soc_ledproc_config(int unit, const uint8 *program, int bytes)
   4719 {
   4720     int         offset;
   4721     uint32      val;
   4722     uint32      led_ctrl;
   4723     uint32      led_prog_base;
   4724     uint32      led_data_base;
   4725 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   4726     int         led_num;
   4727 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_TRIUMPH3_SUPPORT */
   4728 
   4729     if (!soc_feature(unit, soc_feature_led_proc)) {
   4730         return SOC_E_UNAVAIL;
   4731     }
   4732 
   4733 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   4734     led_num = (bytes >> 16) & 0xff;  /* led processor instance */
   4735 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_TRIUMPH3_SUPPORT */
   4736     bytes &= 0xffff;
   4737 
   4738 #ifdef BCM_TOMAHAWK_SUPPORT
   4739     if (SOC_IS_TOMAHAWK(unit) && soc_feature(unit, soc_feature_led_cmicd_v2)) {
   4740         /* CMICd v2 supports 3 LED processors */
   4741         if (led_num == 0) {
   4742             led_ctrl = CMIC_LEDUP0_CTRL_OFFSET;
   4743             led_prog_base = CMIC_LEDUP0_PROGRAM_RAM_OFFSET;
   4744             led_data_base = CMIC_LEDUP0_DATA_RAM_OFFSET;
   4745         } else if (led_num == 1) {
   4746             led_ctrl = CMIC_LEDUP1_CTRL_OFFSET;
   4747             led_prog_base = CMIC_LEDUP1_PROGRAM_RAM_OFFSET;
   4748             led_data_base = CMIC_LEDUP1_DATA_RAM_OFFSET;
   4749         } else if (led_num == 2) {
   4750             led_ctrl = CMIC_LEDUP2_CTRL_OFFSET;
   4751             led_prog_base = CMIC_LEDUP2_PROGRAM_RAM_OFFSET;
   4752             led_data_base = CMIC_LEDUP2_DATA_RAM_OFFSET;
   4753         } else {
   4754             return SOC_E_PARAM;
   4755         }
   4756     } else
   4757 #endif /* BCM_TOMAHAWK_SUPPORT */
   4758 #ifdef BCM_TOMAHAWK2_SUPPORT
   4759     if (SOC_IS_TOMAHAWK2(unit) && soc_feature(unit, soc_feature_led_cmicd_v4)) {
   4760         /* CMICd v4 supports 5 LED processors */
   4761         if (led_num == 0) {
   4762             led_ctrl = CMIC_LEDUP0_CTRL_OFFSET;
   4763             led_prog_base = CMIC_LEDUP0_PROGRAM_RAM_OFFSET;
   4764             led_data_base = CMIC_LEDUP0_DATA_RAM_OFFSET;
   4765         } else if (led_num == 1) {
   4766             led_ctrl = CMIC_LEDUP1_CTRL_OFFSET;
   4767             led_prog_base = CMIC_LEDUP1_PROGRAM_RAM_OFFSET;
   4768             led_data_base = CMIC_LEDUP1_DATA_RAM_OFFSET;
   4769         } else if (led_num == 2) {
   4770             led_ctrl = CMIC_LEDUP2_CTRL_OFFSET;
   4771             led_prog_base = CMIC_LEDUP2_PROGRAM_RAM_OFFSET;
   4772             led_data_base = CMIC_LEDUP2_DATA_RAM_OFFSET;
   4773         } else if (led_num == 3) {
   4774             led_ctrl = CMIC_LEDUP3_CTRL_OFFSET;
   4775             led_prog_base = CMIC_LEDUP3_PROGRAM_RAM_OFFSET;
   4776             led_data_base = CMIC_LEDUP3_DATA_RAM_OFFSET;
   4777         } else if (led_num == 4) {
   4778             led_ctrl = CMIC_LEDUP4_CTRL_OFFSET;
   4779             led_prog_base = CMIC_LEDUP4_PROGRAM_RAM_OFFSET;
   4780             led_data_base = CMIC_LEDUP4_DATA_RAM_OFFSET;
   4781         } else {
   4782             return SOC_E_PARAM;
   4783         }
   4784     } else
   4785 #endif /* BCM_TOMAHAWK2_SUPPORT */
   4786 #ifdef BCM_CMICM_SUPPORT
   4787     if (soc_feature(unit, soc_feature_cmicm)) {
   4788 #if defined(BCM_TRIDENT2_SUPPORT)
   4789         /* CMICm supports 2 LED processors */
   4790         if (SOC_IS_TD2_TT2(unit)) {
   4791             if (led_num == 0) {
   4792                 led_ctrl = CMIC_LEDUP0_CTRL_OFFSET;
   4793                 led_prog_base = CMIC_LEDUP0_PROGRAM_RAM_OFFSET;
   4794                 led_data_base = CMIC_LEDUP0_DATA_RAM_OFFSET;
   4795             } else if (led_num == 1) {
   4796                 led_ctrl = CMIC_LEDUP1_CTRL_OFFSET;
   4797                 led_prog_base = CMIC_LEDUP1_PROGRAM_RAM_OFFSET;
   4798                 led_data_base = CMIC_LEDUP1_DATA_RAM_OFFSET;
   4799             } else {
   4800                 return SOC_E_PARAM;
   4801             }
   4802         } else 
   4803 #endif
   4804 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   4805         if (SOC_IS_TRIUMPH3(unit) || SOC_IS_GREYHOUND2(unit)) {
   4806             if (led_num == 0) {
   4807                 led_ctrl = CMIC_LEDUP0_CTRL_OFFSET;
   4808                 led_prog_base = CMIC_LEDUP0_PROGRAM_RAM_OFFSET;
   4809                 led_data_base = CMIC_LEDUP0_DATA_RAM_OFFSET;
   4810             } else if (led_num == 1) {
   4811                 led_ctrl = CMIC_LEDUP1_CTRL_OFFSET;
   4812                 led_prog_base = CMIC_LEDUP1_PROGRAM_RAM_OFFSET;
   4813                 led_data_base = CMIC_LEDUP1_DATA_RAM_OFFSET;
   4814             } else {
   4815                 return SOC_E_PARAM;
   4816             }
   4817         } else
   4818 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_GREYHOUND2_SUPPORT */
   4819         {
   4820             led_ctrl = CMIC_LEDUP0_CTRL_OFFSET;
   4821             led_prog_base = CMIC_LEDUP0_PROGRAM_RAM_OFFSET;
   4822             led_data_base = CMIC_LEDUP0_DATA_RAM_OFFSET;
   4823         }
   4824     } else
   4825 #endif 
   4826 
   4827     /* use soc_feature if more switches use two ledprocs */
   4828 #ifdef BCM_TRIDENT_SUPPORT
   4829     if (SOC_IS_TD_TT(unit)) {
   4830         if (led_num == 0) {
   4831             led_ctrl = CMICE_LEDUP0_CTRL;
   4832             led_prog_base = CMICE_LEDUP0_PROGRAM_RAM_BASE;
   4833             led_data_base = CMICE_LEDUP0_DATA_RAM_BASE;
   4834         } else if (led_num == 1) { /* Trident only has two */
   4835             led_ctrl = CMICE_LEDUP1_CTRL;
   4836             led_prog_base = CMICE_LEDUP1_PROGRAM_RAM_BASE;
   4837             led_data_base = CMICE_LEDUP1_DATA_RAM_BASE;
   4838         } else {
   4839             return SOC_E_PARAM;
   4840         }
   4841     } else
   4842 #endif /* BCM_TRIDENT_SUPPORT */
   4843 
   4844 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   4845 #ifdef BCM_CMICM_SUPPORT
   4846     if (SOC_IS_TRIUMPH3(unit) || SOC_IS_GREYHOUND2(unit)) {
   4847         if (led_num == 0) {
   4848             led_ctrl = CMIC_LEDUP0_CTRL_OFFSET;
   4849             led_prog_base = CMIC_LEDUP0_PROGRAM_RAM_OFFSET;
   4850             led_data_base = CMIC_LEDUP0_DATA_RAM_OFFSET;
   4851         } else if (led_num == 1) {
   4852             led_ctrl = CMIC_LEDUP1_CTRL_OFFSET;
   4853             led_prog_base = CMIC_LEDUP1_PROGRAM_RAM_OFFSET;
   4854             led_data_base = CMIC_LEDUP1_DATA_RAM_OFFSET;
   4855         } else {
   4856             return SOC_E_PARAM;
   4857         }
   4858     } else
   4859 #endif
   4860 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_GREYHOUND2_SUPPORT */
   4861     {
   4862         /* Only Single LED Processor used.. */
   4863         led_ctrl = CMIC_LED_CTRL;
   4864         led_prog_base = CMIC_LED_PROGRAM_RAM_BASE;
   4865         led_data_base = CMIC_LED_DATA_RAM_BASE;
   4866     }
   4867 
   4868     val = soc_pci_read(unit, led_ctrl);
   4869     val &= ~LC_LED_ENABLE;
   4870     soc_pci_write(unit, led_ctrl, val);
   4871 
   4872     if (bytes == 0) {
   4873         return SOC_E_NONE;
   4874     }
   4875 
   4876     for (offset = 0; offset < CMIC_LED_PROGRAM_RAM_SIZE; offset++) {
   4877         soc_pci_write(unit,
   4878                         led_prog_base + CMIC_LED_REG_SIZE * offset,
   4879                         (offset < bytes) ? (uint32) program[offset] : 0);
   4880     }
   4881 
   4882     for (offset = 0x80; offset < CMIC_LED_DATA_RAM_SIZE; offset++) {
   4883         soc_pci_write(unit,
   4884                         led_data_base + CMIC_LED_REG_SIZE * offset,
   4885                         0);
   4886     }
   4887 
   4888     val = soc_pci_read(unit, led_ctrl);
   4889     val |= LC_LED_ENABLE;
   4890     soc_pci_write(unit, led_ctrl, val);
   4891 
   4892     return SOC_E_NONE;
   4893 }
   4894 
   4895 #endif /* BCM_LEDPROC_SUPPORT */
   4896 
   4897 /*******************************************
   4898 * @function soc_sbusdma_lock_init
   4899 * purpose API to Initialize SBUSDMA
   4900 * locks and Semaphores. This will also be used
   4901 * for TSLAMDMA and TABLEDMA
   4902 *
   4903 * @param unit [in] unit
   4904 *
   4905 * @returns SOC_E_NONE
   4906 * @returns SOC_E_XXX
   4907 *
   4908 * @end
   4909  */
   4910 int soc_sbusdma_lock_init(int unit)
   4911 {
   4912     soc_control_t *soc = SOC_CONTROL(unit);
   4913     int cmc, ch;
   4914 
   4915     /* init locks */
   4916     soc->tdma_enb = 0;
   4917     soc->tslam_enb = 0;
   4918     for (cmc = 0; cmc < SOC_CMCS_NUM_MAX; cmc++) {
   4919         for (ch = 0; ch < SOC_SBUSDMA_CH_PER_CMC; ch++) {
   4920             soc->sbusDmaMutexs[cmc][ch] = NULL;
   4921             soc->sbusDmaIntrs[cmc][ch] = NULL;
   4922         }
   4923     }
   4924     if (SAL_BOOT_QUICKTURN) {
   4925         soc->sbusDmaTimeout = SBUS_TIMEOUT_QT;
   4926     } else {
   4927         soc->sbusDmaTimeout = SBUS_TIMEOUT;
   4928     }
   4929     soc->sbusDmaTimeout = soc_property_get(unit, spn_DMA_DESC_TIMEOUT_USEC,
   4930                                        soc->sbusDmaTimeout);
   4931     SOC_STAT(unit)->err_sbusdma_intr_res = 0;
   4932     /* by default it will be cmc0 when there is no multi pci cmc property */
   4933     if (soc->sbusDmaTimeout) {
   4934         for (cmc = 0; cmc < SOC_PCI_CMCS_NUM(unit); cmc++) {
   4935             for (ch = 0; ch < SOC_SBUSDMA_CH_PER_CMC; ch++) {
   4936                 soc->sbusDmaMutexs[cmc][ch] = sal_mutex_create("SbusDMA");
   4937                 if (soc->sbusDmaMutexs[cmc][ch] == NULL) {
   4938                     LOG_ERROR(BSL_LS_SOC_COMMON,
   4939                           (BSL_META_U(unit,
   4940                           "failed to allocate sbusDmaMutexs")));
   4941                     (void)soc_sbusdma_lock_deinit(unit);
   4942                     return SOC_E_MEMORY;
   4943                 }
   4944                 soc->sbusDmaIntrs[cmc][ch] = sal_sem_create("SBUSDMA interrupt",
   4945                                                             sal_sem_BINARY, 0);
   4946                 if (soc->sbusDmaIntrs[cmc][ch] == NULL) {
   4947                     LOG_ERROR(BSL_LS_SOC_COMMON,
   4948                           (BSL_META_U(unit,
   4949                           "failed to allocate sbusDmaIntrs")));
   4950                     (void)soc_sbusdma_lock_deinit(unit);
   4951                     return SOC_E_MEMORY;
   4952                 }
   4953             }
   4954         }
   4955 
   4956         soc->sbusDmaIntrEnb = soc_property_get(unit,
   4957                                                spn_DMA_DESC_INTR_ENABLE, 0);
   4958     }
   4959 
   4960     /* Init TDMA/ TSLAM */
   4961 
   4962     if (soc_feature(unit, soc_feature_table_dma) &&
   4963         soc_property_get(unit, spn_TABLE_DMA_ENABLE, 1)) {
   4964         if (SAL_BOOT_QUICKTURN) {
   4965             soc->tableDmaTimeout = TDMA_TIMEOUT_QT;
   4966         } else {
   4967             soc->tableDmaTimeout = TDMA_TIMEOUT;
   4968 #ifdef BCM_CMICX_SUPPORT
   4969         if(soc_feature(unit, soc_feature_cmicx)) {
   4970             soc->tableDmaTimeout = 3 * TDMA_TIMEOUT;
   4971         }
   4972 #endif /* CMICX Support */
   4973         }
   4974         soc->tableDmaTimeout = soc_property_get(unit, spn_TDMA_TIMEOUT_USEC,
   4975                                                 soc->tableDmaTimeout);
   4976         soc->tableDmaIntrEnb = soc_property_get(unit,
   4977                                                     spn_TDMA_INTR_ENABLE, 1);
   4978         soc->tdma_enb = 1;
   4979     }
   4980 
   4981     if (soc_feature(unit, soc_feature_tslam_dma) &&
   4982         soc_property_get(unit, spn_TSLAM_DMA_ENABLE, 1)) {
   4983         if (SAL_BOOT_QUICKTURN) {
   4984             soc->tslamDmaTimeout = TSLAM_TIMEOUT_QT;
   4985         } else {
   4986             soc->tslamDmaTimeout = TSLAM_TIMEOUT;
   4987 #ifdef BCM_CMICX_SUPPORT
   4988     if(soc_feature(unit, soc_feature_cmicx)) {
   4989         soc->tslamDmaTimeout = 3 * TSLAM_TIMEOUT;
   4990     }
   4991 #endif /* CMICX Support */
   4992         }
   4993         soc->tslamDmaTimeout = soc_property_get(unit, spn_TSLAM_TIMEOUT_USEC,
   4994                                                 soc->tslamDmaTimeout);
   4995         soc->tslamDmaIntrEnb = soc_property_get(unit,
   4996                                               spn_TSLAM_INTR_ENABLE, 1);
   4997         soc->tslam_enb = 1;
   4998     }
   4999 
   5000     /* Init default channels */
   5001     soc->tdma_ch = 0;
   5002     soc->tslam_ch = 1;
   5003 #ifdef BCM_SBUSDMA_SUPPORT
   5004     soc->desc_ch = 2;
   5005 #endif
   5006 
   5007 #if defined(BCM_SAND_SUPPORT)
   5008     /* In the current DMA implementation, SLAM and table DMA need to both be enabled or disabled */
   5009     if (soc->tslam_enb != soc->tdma_enb && SOC_IS_SAND(unit)) {
   5010         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "SLAM DMA and table DMA need to both be either enabled or disabled\n")));
   5011         return SOC_E_PARAM;
   5012     }
   5013 #endif /* defined(BCM_SAND_SUPPORT) */
   5014     return SOC_E_NONE;
   5015 }
   5016 
   5017 /*******************************************
   5018 * @function soc_sbusdma_lock_deinit
   5019 * purpose API to deinit SBUSDMA
   5020 * locks and Semaphores
   5021 *
   5022 * @param unit [in] unit
   5023 *
   5024 * @returns SOC_E_NONE
   5025 *
   5026 * @end
   5027  */
   5028 int soc_sbusdma_lock_deinit(int unit)
   5029 {
   5030     soc_control_t *soc = SOC_CONTROL(unit);
   5031     int cmc, ch;
   5032 
   5033     for (cmc = 0; cmc < SOC_PCI_CMCS_NUM(unit); cmc++) {
   5034         for (ch = 0; ch < SOC_SBUSDMA_CH_PER_CMC; ch++) {
   5035             if (soc->sbusDmaMutexs[cmc][ch]) {
   5036                 sal_mutex_destroy(soc->sbusDmaMutexs[cmc][ch]);
   5037                 soc->sbusDmaMutexs[cmc][ch] = NULL;
   5038             }
   5039             if (soc->sbusDmaIntrs[cmc][ch]) {
   5040                 sal_sem_destroy(soc->sbusDmaIntrs[cmc][ch]);
   5041                 soc->sbusDmaIntrs[cmc][ch] = NULL;
   5042             }
   5043         }
   5044     }
   5045     soc->tdma_enb = 0;
   5046     soc->tslam_enb = 0;
   5047     return SOC_E_NONE;
   5048 }
   5049 static soc_chip_info_vectors_t chip_info_vect;
   5050 
   5051 int
   5052 soc_chip_info_vect_config(soc_chip_info_vectors_t *vect)
   5053 {
   5054     if (vect == NULL) {
   5055         return SOC_E_PARAM;
   5056     }
   5057 
   5058     chip_info_vect = *vect;
   5059 
   5060     return SOC_E_NONE;
   5061 }
   5062 
   5063 int
   5064 soc_icid_default_get(int unit, uint8 *data, int size)
   5065 {
   5066     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   5067                 (BSL_META("Get default ICID data length "
   5068                           "%d bytes.\n"), size));
   5069 
   5070     if (!data) {
   5071         return SOC_E_PARAM;
   5072     }
   5073 
   5074     if (chip_info_vect.icid_get) {
   5075         if (chip_info_vect.icid_get(unit, data, size) < 0) {
   5076             return SOC_E_UNAVAIL;
   5077         }
   5078     } else {
   5079         return SOC_E_UNAVAIL;
   5080     }
   5081 
   5082     return SOC_E_NONE;
   5083 }
   5084 
   5085 /*
   5086  * Function:
   5087  *      soc_cpu_flow_ctrl
   5088  * Purpose:
   5089  *      Enable/Disable flow control assertion from CMIC to MMU.
   5090  * Parameters:
   5091  *      unit - Unit to init
   5092  *      enable - Enable/Disable flow control assertion.
   5093  * Returns:
   5094  *      SOC_E_XXX
   5095  */
   5096 int
   5097 soc_cpu_flow_ctrl(int unit, int enable) {
   5098 
   5099     /* Input validation */
   5100     if (!SOC_UNIT_VALID(unit)) {
   5101         return SOC_E_UNIT;
   5102     }
   5103 
   5104 #if defined(BCM_HURRICANE2_SUPPORT)
   5105     if (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit) ||
   5106         SOC_IS_GREYHOUND(unit)) {
   5107         uint32 addr, fval, rval = 0;
   5108 
   5109         if (enable) {
   5110             fval = 0x00000000;
   5111         } else {
   5112             fval = 0xffffffff;
   5113         }
   5114         soc_reg_field_set(unit, CMIC_PKT_COS_0r, &rval, COSf, fval);
   5115         addr = soc_reg_addr(unit, CMIC_PKT_COS_0r, REG_PORT_ANY, 0);
   5116         soc_pci_write(unit, addr, rval);
   5117         soc_reg_field_set(unit, CMIC_PKT_COS_1r, &rval, COSf, fval);
   5118         addr = soc_reg_addr(unit, CMIC_PKT_COS_1r, REG_PORT_ANY, 0);
   5119         soc_pci_write(unit, addr, rval);
   5120     }
   5121 #endif /* BCM_HURRICANE2_SUPPORT */
   5122     return SOC_E_NONE;
   5123 }
   5124