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

helix5.c (284316B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        helix5.c
      8  * Purpose:
      9  * Requires:
     10  */
     11 
     12 
     13 #include <shared/bsl.h>
     14 
     15 #include <sal/core/boot.h>
     16 #include <sal/core/dpc.h>
     17 #include <shared/bsl.h>
     18 #include <soc/tdm/core/tdm_top.h>
     19 #ifdef BCM_CMICX_SUPPORT
     20 #include <soc/cmicx.h>
     21 #endif
     22 
     23 #include <soc/bradley.h>
     24 #include <soc/drv.h>
     25 #include <soc/error.h>
     26 #include <soc/debug.h>
     27 #include <soc/mem.h>
     28 #include <soc/i2c.h>
     29 #include <soc/l2x.h>
     30 
     31 #ifdef BCM_HELIX5_SUPPORT
     32 
     33 #include <soc/mmu_config.h>
     34 #include <soc/helix5.h>
     35 #include <soc/helix5_tdm.h>
     36 #include <soc/tomahawk.h>
     37 #include <soc/esw/cancun.h>
     38 #include <soc/soc_ser_log.h>
     39 #include <soc/pstats.h>
     40 #include <soc/flexport/helix5/helix5_flexport.h>
     41 #include <soc/esw/portctrl.h>
     42 #include <soc/scache.h>
     43 #include <soc/bondoptions.h>
     44 #include <shared/pack.h>
     45 
     46 #define HX5_NUM_PHY_PORT                (79)
     47 #define HX5_NUM_PORT                    (72)
     48 #define HX5_NUM_MMU_PORT                (72)
     49 
     50 #define ETHER_MODE                      0
     51 #define Q_MODE                          1
     52 
     53 #define PMQ0_FIRST_PHY_PORT             1
     54 
     55 #define HX5_PORT_BLOCK_BASE_PORT(port)                              \
     56         SOC_INFO(unit).port_l2p_mapping[port] <= 48 ?               \
     57         (1 + ((SOC_INFO(unit).port_l2p_mapping[port] - 1) & ~0xF)) :\
     58         (1 + ((SOC_INFO(unit).port_l2p_mapping[port] - 1) & ~0x3));
     59 
     60 #define IS_MGMT_PORT(unit,port) IS_MANAGEMENT_PORT(unit, port)
     61 
     62 
     63 int
     64 _soc_hx5_port_speed_cap[SOC_MAX_NUM_DEVICES][HELIX5_PHY_PORTS_PER_DEV];
     65 
     66 static const struct {
     67     int port;
     68     int phy_port;
     69     int pipe;
     70     int idb_port;
     71     int mmu_port;
     72 } hx5_anc_ports[] = {
     73     { 0,   0,   0, 70, 70 },  /* cpu port */
     74     { 70,  77,  0, 71, 71 },  /* loopback port */
     75     { 71,  78,  0, 69, 69 },  /* FAE port */
     76 };
     77 
     78 static const soc_reg_t pvtmon_result_reg[] = {
     79     TOP_PVTMON_RESULT_0r, TOP_PVTMON_RESULT_1r,
     80     TOP_PVTMON_RESULT_2r, TOP_PVTMON_RESULT_3r,
     81     TOP_PVTMON_RESULT_4r, TOP_PVTMON_RESULT_5r,
     82     TOP_PVTMON_RESULT_6r
     83 };
     84 
     85 extern int soc_td3_hash_mutex_init (int unit);
     86 
     87 egr_vlan_xlate_1_hash_control_entry_t       egr_vlan_1_hash_control;
     88 egr_vlan_xlate_2_hash_control_entry_t       egr_vlan_2_hash_control;
     89 egr_vp_vlan_membership_hash_control_entry_t egr_vp_vlan_mbm_hash_control;
     90 exact_match_hash_control_entry_t            exact_match_hash_control;
     91 ing_vp_vlan_membership_hash_control_entry_t ing_vp_vlan_mbm_hash_control;
     92 l2_entry_hash_control_entry_t               l2_entry_hash_control;
     93 l3_entry_hash_control_entry_t               l3_entry_hash_control;
     94 mpls_entry_hash_control_entry_t             mpls_entry_hash_control;
     95 vlan_xlate_1_hash_control_entry_t           vlan_1_hash_control;
     96 vlan_xlate_2_hash_control_entry_t           vlan_2_hash_control;
     97 uft_shared_banks_control_entry_t            uft_shared_banks_control;
     98 ip_uat_shared_banks_control_entry_t         ip_uat_shared_banks_control;
     99 ep_uat_shared_banks_control_entry_t         ep_uat_shared_banks_control;
    100 ft_key_ss0_shared_banks_control_entry_t     ft_key_ss0_shared_banks_control;
    101 ft_key_ss1_shared_banks_control_entry_t     ft_key_ss1_shared_banks_control;
    102 
    103 /*
    104  * Function:
    105  *      soc_helix5_mem_config
    106  * Purpose:
    107  *      Configure depth of UFT/UAT memories
    108  * Parameters:
    109  *      unit (IN)    - switch unit
    110  * Returns:
    111  *      SOC_E_*
    112  */
    113 int
    114 soc_helix5_mem_config(int unit)
    115 {
    116     soc_persist_t *sop;
    117     int l2_entries, fixed_l2_entries, shared_l2_banks;
    118     int num_ipv6_128b_entries = 0;
    119     int config_v6_entries = 0;
    120     int defip_config = 0;
    121 #define _SOC_HX5_DEFIP_MAX_TCAMS    8
    122 #define _SOC_HX5_DEFIP_TCAM_DEPTH   1024 /* HX5 has 8 tcams of 1K deep depth  */
    123     int l3_entries, fixed_l3_entries, shared_l3_banks;
    124     int fpem_entries, shared_fpem_banks;
    125     int mpls_entries, vlan_xlate_1_entries, vlan_xlate_2_entries;
    126     int alpm_enable = 0;
    127     int mpls_4k_banks;
    128     int vlan_xlate_1_4k_banks;
    129     int vlan_xlate_2_4k_banks;
    130     int egr_vlan_xlate_1_entries, egr_vlan_xlate_2_entries;
    131     int egr_vlan_xlate_1_banks, egr_vlan_xlate_2_banks;
    132     int num_lag_rh_flowset_entries;
    133 
    134     sop = SOC_PERSIST(unit);
    135 
    136     /*  UFT BANK SIZING
    137      *
    138      * bank 0-1 are dedicated L2 banks (8k entries per bank)
    139      * bank 8-9 are dedicated L3 banks (8k entries per bank)
    140      * bank 2-7 are shared banks (16k L2/L3 or 8k FPEM entries
    141      *                              or 24k ALPM entries per bank)
    142      */
    143 
    144     l2_entries = soc_property_get(unit, spn_L2_MEM_ENTRIES, 16 * 1024);
    145     fixed_l2_entries = 16 * 1024;  /* 16k dedicated L2 entries, (8k * 2 banks) */
    146     if (l2_entries <= fixed_l2_entries) {
    147         l2_entries = fixed_l2_entries;
    148         shared_l2_banks = 0;
    149     } else {
    150         l2_entries -= fixed_l2_entries;
    151         shared_l2_banks = (l2_entries + (16 * 1024 - 1)) / (16 * 1024);
    152         l2_entries = fixed_l2_entries + shared_l2_banks * 16 * 1024;
    153     }
    154 
    155     l3_entries = soc_property_get(unit, spn_L3_MEM_ENTRIES, 16 * 1024);
    156     fixed_l3_entries = 16 * 1024;  /* 16k dedicated L3 entries, (8k * 2 banks) */
    157     if (l3_entries <= fixed_l3_entries) {
    158         l3_entries = fixed_l3_entries;
    159         shared_l3_banks = 0;
    160     } else {
    161         l3_entries -= fixed_l3_entries;
    162         shared_l3_banks = (l3_entries + (16 * 1024 - 1)) / (16 * 1024);
    163         l3_entries = fixed_l3_entries + shared_l3_banks * 16 * 1024;
    164     }
    165 
    166     fpem_entries = soc_property_get(unit, spn_FPEM_MEM_ENTRIES, 0);
    167     shared_fpem_banks = (fpem_entries + (8 * 1024 - 1)) / (8 * 1024);
    168     /* Allocate atleast 2 banks to FP for dual hash benefits */
    169     if(shared_fpem_banks == 1) {
    170         if ((shared_l2_banks + shared_l3_banks) > 6) {
    171             LOG_ERROR(BSL_LS_SOC_COMMON,
    172                         (BSL_META_U(unit,
    173                                     "Config Error - Atleast two shared UFT"
    174                                     "banks should be allocated to FPEM. \n")));
    175             return SOC_E_PARAM;
    176         }
    177         shared_fpem_banks = 2;
    178     }
    179     fpem_entries = shared_fpem_banks * 8 * 1024;
    180 
    181     if (shared_l2_banks + shared_l3_banks + shared_fpem_banks > 6) {
    182         return SOC_E_PARAM;
    183     }
    184 
    185     if (soc_feature(unit, soc_feature_alpm)) {
    186         alpm_enable = soc_property_get(unit, spn_L3_ALPM_ENABLE, 0);
    187     }
    188 
    189     /* ALPM needs either 4 banks or 6 banks depending on ALPM bank mode.
    190      * If more than 2 banks are already allocated to non ALPM tables (L2, L3,
    191      * FPEM), then ALPM needs cannot be satisfied */
    192     if ((alpm_enable) &&
    193         (shared_l2_banks + shared_l3_banks + shared_fpem_banks > 2)) {
    194         return SOC_E_PARAM;
    195     }
    196 
    197     _soc_alpm_mode[unit] = alpm_enable;
    198 
    199     /* IUAT BANK SIZING
    200      *
    201 	 * Banks 0-7 are shared banks of size 4k per bank
    202      */
    203 
    204     mpls_entries = soc_property_get(unit, spn_MPLS_MEM_ENTRIES, 8192);
    205     mpls_4k_banks = (mpls_entries + (4 * 1024 -1)) / 4096;
    206     mpls_entries = mpls_4k_banks * 4 * 1024;
    207 
    208     vlan_xlate_1_entries = soc_property_get(unit, spn_VLAN_XLATE_1_MEM_ENTRIES, 8192);
    209     vlan_xlate_1_4k_banks = (vlan_xlate_1_entries + (4 * 1024 -1)) / 4096;
    210     vlan_xlate_1_entries = vlan_xlate_1_4k_banks * 4 * 1024;
    211 
    212     vlan_xlate_2_entries = soc_property_get(unit, spn_VLAN_XLATE_2_MEM_ENTRIES, 8192);
    213     vlan_xlate_2_4k_banks = (vlan_xlate_2_entries + (4 * 1024 -1)) / 4096;
    214     vlan_xlate_2_entries = vlan_xlate_2_4k_banks * 4 * 1024;
    215 
    216     if (mpls_4k_banks + vlan_xlate_1_4k_banks + vlan_xlate_2_4k_banks > 8) {
    217         return SOC_E_PARAM;
    218     }
    219 
    220     /* EUAT BANK SIZING
    221      *
    222      * Banks 0-3 are shared banks of size 4k per bank
    223      */
    224 
    225     egr_vlan_xlate_1_entries = soc_property_get(unit, spn_EGR_VLAN_XLATE_1_MEM_ENTRIES, 8192);
    226     egr_vlan_xlate_1_banks = (egr_vlan_xlate_1_entries + (4 * 1024 - 1)) / 4096;
    227     egr_vlan_xlate_1_entries = egr_vlan_xlate_1_banks * 4 * 1024;
    228 
    229     egr_vlan_xlate_2_entries = soc_property_get(unit, spn_EGR_VLAN_XLATE_2_MEM_ENTRIES, 8192);
    230     egr_vlan_xlate_2_banks = (egr_vlan_xlate_2_entries + (4 * 1024 - 1)) / 4096;
    231     egr_vlan_xlate_2_entries = egr_vlan_xlate_2_banks * 4 * 1024;
    232 
    233     if (egr_vlan_xlate_1_banks + egr_vlan_xlate_2_banks > 4) {
    234         return SOC_E_PARAM;
    235     }
    236 
    237     /* LP memory sizing per 8k entries
    238      * Memory Bank with 1W,2W,4W support - 3.5k entries
    239      * Memory Bank with 1W,2W support    - 3k entries
    240      * Memory Bank with 1W support       - 2k entries
    241      */
    242 
    243     /* Adjust L2 table size */
    244     sop->memState[L2Xm].index_max = l2_entries - 1;
    245     sop->memState[L2_ENTRY_SINGLEm].index_max = l2_entries - 1;
    246     sop->memState[L2_ENTRY_ONLY_SINGLEm].index_max = l2_entries - 1;
    247     sop->memState[L2_ENTRY_ECCm].index_max = l2_entries - 1;
    248     sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 4 - 1;
    249     sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 4 - 1;
    250     /* 2k per dedicated L2 bank, 7k per shared L2 bank */
    251     sop->memState[L2_ENTRY_LPm].index_max = ((2 * 2 * 1024) +
    252                                              (shared_l2_banks * 7 * 1024) - 1);
    253 
    254     /* Adjust L3 table size */
    255     sop->memState[L3_ENTRY_SINGLEm].index_max = l3_entries - 1;
    256     sop->memState[L3_ENTRY_ONLY_SINGLEm].index_max = l3_entries - 1;
    257     sop->memState[L3_ENTRY_ECCm].index_max = l3_entries - 1;
    258     sop->memState[L3_ENTRY_DOUBLEm].index_max = l3_entries / 2 - 1;
    259     sop->memState[L3_ENTRY_ONLY_DOUBLEm].index_max = l3_entries / 2 - 1;
    260     sop->memState[L3_ENTRY_QUADm].index_max = l3_entries / 4 - 1;
    261     sop->memState[L3_ENTRY_ONLY_QUADm].index_max = l3_entries / 4 - 1;
    262     sop->memState[L3_ENTRY_HIT_ONLYm].index_max = l3_entries / 4 - 1;
    263     /* 3.5k per dedicated L3 bank, 7k per shared L2 bank */
    264     sop->memState[L3_ENTRY_LPm].index_max = ((7 * 1024) +
    265                                             (shared_l3_banks * 7 * 1024) - 1);
    266 
    267     /* Adjust FP exact match table size */
    268     sop->memState[EXACT_MATCH_ECCm].index_max = fpem_entries * 2 - 1;
    269     sop->memState[EXACT_MATCH_ECC_PIPE0m].index_max = fpem_entries * 2 - 1;
    270     sop->memState[EXACT_MATCH_2m].index_max = fpem_entries - 1;
    271     sop->memState[EXACT_MATCH_2_PIPE0m].index_max = fpem_entries - 1;
    272     sop->memState[EXACT_MATCH_2_ENTRY_ONLYm].index_max = fpem_entries - 1;
    273     sop->memState[EXACT_MATCH_2_ENTRY_ONLY_PIPE0m].index_max = fpem_entries - 1;
    274     sop->memState[EXACT_MATCH_4m].index_max = fpem_entries / 2 - 1;
    275     sop->memState[EXACT_MATCH_4_PIPE0m].index_max = fpem_entries / 2 - 1;
    276     sop->memState[EXACT_MATCH_4_ENTRY_ONLYm].index_max = fpem_entries / 2 - 1;
    277     sop->memState[EXACT_MATCH_4_ENTRY_ONLY_PIPE0m].index_max = fpem_entries / 2 - 1;
    278     sop->memState[EXACT_MATCH_HIT_ONLYm].index_max = fpem_entries / 2 - 1;
    279     /* 7k per shared FPEM bank */
    280     sop->memState[EXACT_MATCH_LPm].index_max = ((shared_fpem_banks * 7 * 1024) - 1);
    281     sop->memState[EXACT_MATCH_LP_PIPE0m].index_max = ((shared_fpem_banks * 7 * 1024) - 1);
    282 
    283     /* Adjust MPLS table size */
    284     sop->memState[MPLS_ENTRY_SINGLEm].index_max = mpls_entries - 1;
    285     sop->memState[MPLS_ENTRYm].index_max = mpls_entries / 2 - 1;
    286     /* 1.5k per IUAT bank */
    287     sop->memState[MPLS_ENTRY_LPm].index_max = (((mpls_4k_banks * 1536) - 1));
    288     sop->memState[MPLS_ENTRY_ECCm].index_max = mpls_entries - 1;
    289 
    290     /* Adjust VLAN_XLATE_1 table size */
    291     sop->memState[VLAN_XLATE_1_SINGLEm].index_max = vlan_xlate_1_entries - 1;
    292     sop->memState[VLAN_XLATE_1_DOUBLEm].index_max = vlan_xlate_1_entries / 2 - 1;
    293     /* 1.5k per IUAT bank */
    294     sop->memState[VLAN_XLATE_1_LPm].index_max = (vlan_xlate_1_4k_banks * 1536) - 1;
    295     sop->memState[VLAN_XLATE_1_ECCm].index_max = vlan_xlate_1_entries - 1;
    296 
    297     /* Adjust VLAN_XLATE_2 table size */
    298     sop->memState[VLAN_XLATE_2_SINGLEm].index_max = vlan_xlate_2_entries - 1;
    299     sop->memState[VLAN_XLATE_2_DOUBLEm].index_max = vlan_xlate_2_entries / 2 - 1;
    300     /* 1.5k per IUAT bank */
    301     sop->memState[VLAN_XLATE_2_LPm].index_max = (vlan_xlate_2_4k_banks * 1536) - 1;
    302     sop->memState[VLAN_XLATE_2_ECCm].index_max = vlan_xlate_2_entries - 1;
    303 
    304     /* Adjust EGR_VLAN_XLATE_1 table size */
    305     sop->memState[EGR_VLAN_XLATE_1_SINGLEm].index_max = egr_vlan_xlate_1_entries - 1;
    306     sop->memState[EGR_VLAN_XLATE_1_DOUBLEm].index_max = egr_vlan_xlate_1_entries / 2 - 1;
    307     /* 1.5k per EUAT bank */
    308     sop->memState[EGR_VLAN_XLATE_1_LPm].index_max = (egr_vlan_xlate_1_banks * 1536) - 1;
    309     sop->memState[EGR_VLAN_XLATE_1_ECCm].index_max = egr_vlan_xlate_1_entries - 1;
    310 
    311     /* Adjust EGR_VLAN_XLATE_2 table size */
    312     sop->memState[EGR_VLAN_XLATE_2_SINGLEm].index_max = egr_vlan_xlate_2_entries - 1;
    313     sop->memState[EGR_VLAN_XLATE_2_DOUBLEm].index_max = egr_vlan_xlate_2_entries / 2 - 1;
    314     /* 1.5k per EUAT bank */
    315     sop->memState[EGR_VLAN_XLATE_2_LPm].index_max = (egr_vlan_xlate_2_banks * 1536) - 1;
    316     sop->memState[EGR_VLAN_XLATE_2_ECCm].index_max = egr_vlan_xlate_2_entries - 1;
    317 
    318     SOC_CONTROL(unit)->l3_defip_max_tcams = _SOC_HX5_DEFIP_MAX_TCAMS;
    319     SOC_CONTROL(unit)->l3_defip_tcam_size = _SOC_HX5_DEFIP_TCAM_DEPTH;
    320     if (soc_property_get(unit, "l3_defip_sizing", TRUE)) {
    321         if (!alpm_enable) {
    322             defip_config = soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1);
    323 
    324             num_ipv6_128b_entries = soc_property_get(unit,
    325                                         spn_NUM_IPV6_LPM_128B_ENTRIES,
    326                                         (defip_config ? 2048 : 0));
    327             num_ipv6_128b_entries = num_ipv6_128b_entries +
    328                                     (num_ipv6_128b_entries % 2);
    329 
    330             config_v6_entries = num_ipv6_128b_entries;
    331             if (soc_property_get(unit, spn_LPM_SCALING_ENABLE, 0)) {
    332                 num_ipv6_128b_entries = 0;
    333                 if (!soc_property_get(unit, spn_LPM_IPV6_128B_RESERVED, 1)) {
    334                     config_v6_entries = ((config_v6_entries /
    335                                         SOC_CONTROL(unit)->l3_defip_tcam_size) +
    336                                         ((config_v6_entries %
    337                                          SOC_CONTROL(unit)->l3_defip_tcam_size)
    338                                         ? 1 : 0)) * SOC_CONTROL(unit)->l3_defip_tcam_size;
    339                 }
    340             }
    341             sop->memState[L3_DEFIP_PAIR_128m].index_max =
    342                                               num_ipv6_128b_entries - 1;
    343             sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max =
    344                                               num_ipv6_128b_entries - 1;
    345             sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max =
    346                                               num_ipv6_128b_entries - 1;
    347             sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max =
    348                                               num_ipv6_128b_entries - 1;
    349             sop->memState[L3_DEFIPm].index_max =
    350                                      (SOC_CONTROL(unit)->l3_defip_max_tcams *
    351                                      SOC_CONTROL(unit)->l3_defip_tcam_size) -
    352                                      (num_ipv6_128b_entries * 2) - 1;
    353 
    354             sop->memState[L3_DEFIP_ONLYm].index_max =
    355                                           sop->memState[L3_DEFIPm].index_max;
    356             sop->memState[L3_DEFIP_DATA_ONLYm].index_max =
    357                                           sop->memState[L3_DEFIPm].index_max;
    358             sop->memState[L3_DEFIP_HIT_ONLYm].index_max =
    359                                           sop->memState[L3_DEFIPm].index_max;
    360             SOC_CONTROL(unit)->l3_defip_index_remap = num_ipv6_128b_entries;
    361         } else {
    362             if (soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1)) {
    363                 /* slightly different processing for v6-128 */
    364                 num_ipv6_128b_entries = soc_property_get(unit,
    365                                             spn_NUM_IPV6_LPM_128B_ENTRIES,
    366                                             2048);
    367                 num_ipv6_128b_entries = num_ipv6_128b_entries +
    368                                         (num_ipv6_128b_entries % 2);
    369                 config_v6_entries = num_ipv6_128b_entries;
    370                 sop->memState[L3_DEFIP_PAIR_128m].index_max =
    371                                         num_ipv6_128b_entries - 1;
    372                 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max =
    373                                         num_ipv6_128b_entries - 1;
    374                 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max =
    375                                         num_ipv6_128b_entries - 1;
    376                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max =
    377                                         num_ipv6_128b_entries - 1;
    378                 sop->memState[L3_DEFIPm].index_max =
    379                                   (SOC_CONTROL(unit)->l3_defip_max_tcams *
    380                                   SOC_CONTROL(unit)->l3_defip_tcam_size) -
    381                                   (num_ipv6_128b_entries * 2) - 1;
    382                 sop->memState[L3_DEFIP_ONLYm].index_max =
    383                                         sop->memState[L3_DEFIPm].index_max;
    384                 sop->memState[L3_DEFIP_DATA_ONLYm].index_max =
    385                                         sop->memState[L3_DEFIPm].index_max;
    386                 sop->memState[L3_DEFIP_HIT_ONLYm].index_max =
    387                                         sop->memState[L3_DEFIPm].index_max;
    388 
    389                 SOC_CONTROL(unit)->l3_defip_index_remap =
    390                                         (num_ipv6_128b_entries / 2) * 2;
    391             } else {
    392                 sop->memState[L3_DEFIP_PAIR_128m].index_max = -1;
    393                 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1;
    394                 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1;
    395                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1;
    396             }
    397         }
    398         soc_l3_defip_indexes_init(unit, config_v6_entries);
    399     }
    400 
    401     /* Adjust ALPM table size */
    402     if (alpm_enable) {
    403         /* The check below is sufficient because if ALPM mode is enabled
    404          * and number of shared banks used is > 2 we return SOC_E_PARAM
    405          * in code at the top of this function.
    406          */
    407         if (shared_l2_banks + shared_l3_banks + shared_fpem_banks > 0) {
    408             sop->memState[L3_DEFIP_ALPM_RAWm].index_max =
    409                 (sop->memState[L3_DEFIP_ALPM_RAWm].index_max * 4) / 6;
    410             sop->memState[L3_DEFIP_ALPM_IPV4m].index_max =
    411                 (sop->memState[L3_DEFIP_ALPM_IPV4m].index_max * 4) / 6;
    412             sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max =
    413                 (sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max * 4) / 6;
    414             sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max =
    415                 (sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max * 4) / 6;
    416             sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max =
    417                 (sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max * 4) / 6;
    418             sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max =
    419                 (sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max * 4) / 6;
    420             sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max =
    421                 (sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max * 4) / 6;
    422             sop->memState[L3_DEFIP_ALPM_ECCm].index_max =
    423                 (sop->memState[L3_DEFIP_ALPM_ECCm].index_max * 4) / 6;
    424         }
    425     } else {
    426         sop->memState[L3_DEFIP_ALPM_RAWm].index_max = -1;
    427         sop->memState[L3_DEFIP_ALPM_IPV4m].index_max = -1;
    428         sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max = -1;
    429         sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max = -1;
    430         sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max = -1;
    431         sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max = -1;
    432         sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max = -1;
    433         sop->memState[L3_DEFIP_ALPM_ECCm].index_max = -1;
    434     }
    435 
    436     /* Adjust MY_STATION_TCAM table in Emulator */
    437     if (SAL_BOOT_QUICKTURN) {
    438         sop->memState[MY_STATION_TCAMm].index_max = 31;
    439         sop->memState[MY_STATION_TCAM_2m].index_max =
    440             sop->memState[MY_STATION_TCAMm].index_max;
    441         sop->memState[MY_STATION_TCAM_2_DATA_ONLYm].index_max =
    442             sop->memState[MY_STATION_TCAMm].index_max;
    443         sop->memState[MY_STATION_TCAM_2_ENTRY_ONLYm].index_max =
    444             sop->memState[MY_STATION_TCAMm].index_max;
    445         sop->memState[MY_STATION_TCAM_DATA_ONLYm].index_max =
    446             sop->memState[MY_STATION_TCAMm].index_max;
    447         sop->memState[MY_STATION_TCAM_ENTRY_ONLYm].index_max =
    448             sop->memState[MY_STATION_TCAMm].index_max;
    449     }
    450 
    451     SOC_IF_ERROR_RETURN(soc_trident3_init_alpm2_memory(unit));
    452 
    453     /* Enhanced hashing  LAG/TRUNK config
    454      * LAG/TRUNK share the same flow set table used in RH
    455      * 32k is shared between LAG and HGT for
    456      * - 16k each - default
    457      * - 32K dedicated to HGT RH
    458      * - 32K dedicated to LAG RH
    459      */
    460     num_lag_rh_flowset_entries = soc_property_get(unit,
    461             spn_TRUNK_RESILIENT_HASH_TABLE_SIZE, 16384);
    462 
    463     switch (num_lag_rh_flowset_entries) {
    464         case 0:
    465             sop->memState[RH_LAG_FLOWSETm].index_max = -1;
    466             break;
    467         case 32768:
    468             sop->memState[RH_HGT_FLOWSETm].index_max = -1;
    469             break;
    470         case 16384:
    471             sop->memState[RH_HGT_FLOWSETm].index_max = 16383;
    472             sop->memState[RH_LAG_FLOWSETm].index_max = 16383;
    473             break;
    474         default:
    475             return SOC_E_CONFIG;
    476     }
    477 
    478     /* Adjust the Flow-tracker session table size based on the
    479        supported size, these features would have been set based
    480        on the OTP values */
    481     if (soc_feature(unit, soc_feature_flowtracker_ver_1_8K_ft_table)) {
    482         /* 3 banks x 4k */
    483         sop->memState[FT_KEY_SINGLEm].index_max = 12287;
    484         sop->memState[FT_KEY_DOUBLEm].index_max = 6143;
    485         sop->memState[FT_KEY_DOUBLE_PIPE0m].index_max = 6143;
    486         sop->memState[FT_KEY_ECCm].index_max = 12287;
    487     } else if (soc_feature(unit, soc_feature_flowtracker_ver_1_16K_ft_table)) {
    488         /* 5 banks x 4k */
    489         sop->memState[FT_KEY_SINGLEm].index_max = 20479;
    490         sop->memState[FT_KEY_DOUBLEm].index_max = 10239;
    491         sop->memState[FT_KEY_DOUBLE_PIPE0m].index_max = 10239;
    492         sop->memState[FT_KEY_ECCm].index_max = 20479;
    493     }
    494 
    495     return SOC_E_NONE;
    496 }
    497 
    498 /*
    499  * cpu port (mmu port 70): 48 queues (2570-2617)
    500  * loopback port (mmu port 71): 10 queues (2560-2569)
    501  */
    502 int
    503 soc_helix5_num_cosq_init_port(int unit, int port)
    504 {
    505     soc_info_t *si;
    506     int mmu_port;
    507 
    508     si = &SOC_INFO(unit);
    509 
    510     mmu_port = SOC_TD3_MMU_PORT(unit, port);
    511 
    512     if (IS_CPU_PORT(unit, port)) {
    513         si->port_num_cosq[port] = 48;
    514         si->port_cosq_base[port] = SOC_HX5_CPU_MCQ_BASE;
    515     } else if (IS_LB_PORT(unit, port)) {
    516         si->port_num_cosq[port] = 10;
    517         si->port_cosq_base[port] = SOC_HX5_LB_MCQ_BASE;
    518     } else if (mmu_port < 16) {
    519         si->port_num_cosq[port] = 26;
    520         si->port_cosq_base[port] =   mmu_port * 26;
    521         si->port_num_uc_cosq[port] = 26;
    522         si->port_uc_cosq_base[port] = mmu_port * 26;
    523         si->port_num_ext_cosq[port] = 0;
    524     } else {
    525         si->port_num_cosq[port] = 16;
    526         si->port_cosq_base[port] =  SOC_HX5_DOWNLINK_PORTQ_BASE + (mmu_port - 16)  * 16;
    527         si->port_num_uc_cosq[port] = 16;
    528         si->port_uc_cosq_base[port] = SOC_HX5_DOWNLINK_PORTQ_BASE + (mmu_port - 16)  * 16;
    529         si->port_num_ext_cosq[port] = 0;
    530     }
    531 
    532     return SOC_E_NONE;
    533 }
    534 
    535 /*
    536  * cpu port (mmu port 70): 48 queues (1290-1337)
    537  * loopback port (mmu port 71): 10 queues (1280-1289)
    538  */
    539 int
    540 soc_helix5_num_cosq_init(int unit)
    541 {
    542     int port;
    543 
    544     PBMP_ALL_ITER(unit, port) {
    545         if (!IS_FAE_PORT(unit, port)) {
    546             SOC_IF_ERROR_RETURN
    547                 (soc_helix5_num_cosq_init_port(unit, port));
    548         }
    549     }
    550 
    551     return SOC_E_NONE;
    552 }
    553 
    554 
    555 STATIC int
    556 soc_helix5_max_frequency_get(int unit,  uint16 dev_id, uint8 rev_id,
    557                                int skew_id, int *frequency)
    558 {
    559     if (soc_feature(unit, soc_feature_untethered_otp)) {
    560         /* Fill from default_frequecy, if soc_property exists from the same, overwrite
    561            and also check the default is not greater than the max_frequecy */
    562         *frequency = SOC_BOND_INFO(unit)->default_core_freq;
    563         *frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, *frequency);
    564         if (*frequency > SOC_BOND_INFO(unit)->max_core_freq) {
    565             return SOC_E_PARAM;
    566         }
    567     } else {
    568         switch (dev_id) {
    569         case BCM56370_DEVICE_ID:
    570             *frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, HX5_CLK_893MHZ);
    571             break;
    572         default:
    573             return SOC_E_INTERNAL;
    574         }
    575     }
    576 
    577     return SOC_E_NONE;
    578 }
    579 
    580 /* Function to get the number of ports present in a given Port Macro */
    581 STATIC int
    582 soc_hx5_ports_per_pm_get(int unit, int pm_id)
    583 {
    584     soc_info_t *si;
    585     int phy_port, num_ports = 0, i;
    586 
    587     si = &SOC_INFO(unit);
    588     if (pm_id >= _HX5_PBLKS_PER_DEV(unit)) {
    589        return SOC_E_PARAM;
    590     }
    591     phy_port = 1 + (pm_id * _HX5_PORTS_PER_PBLK);
    592 
    593     for (i = 0; i < _HX5_PORTS_PER_PBLK; ) {
    594         if (si->port_p2l_mapping[phy_port + i] != -1) {
    595             num_ports ++;
    596             i += si->port_num_lanes[si->port_p2l_mapping[phy_port + i]];
    597         } else {
    598             i ++;
    599         }
    600     }
    601     return num_ports;
    602 }
    603 
    604 STATIC int
    605 _soc_hx5_port_flex_init(int unit, int is_any_cap)
    606 {
    607     soc_info_t *si;
    608     int pm, blk_idx, blk_type, i;
    609     int flex_en, phy_base, max_ports, port, phy_port;
    610     int qmode = 0;
    611 
    612     si = &SOC_INFO(unit);
    613     SHR_BITCLR_RANGE(si->flexible_pm_bitmap, 0, SOC_MAX_NUM_BLKS);
    614 
    615     /* portmap_x=y:speed:i */
    616     /* portmap_x=y:speed:cap */
    617     if (SOC_PBMP_NOT_NULL(SOC_PORT_DISABLED_BITMAP(unit, all)) || is_any_cap) {
    618         SHR_BITSET_RANGE(si->flexible_pm_bitmap, 1, SOC_MAX_NUM_BLKS);
    619     } else {
    620         /* port_flex_enable{x}=<0...1> */
    621         /* port_flex_enable_corex=<0...1> */
    622         /* port_flex_enable=<0...1> */
    623         for (phy_port = 1; phy_port <= HELIX5_GPHY_PORTS_PER_PIPE; phy_port++) {
    624             port = si->port_p2l_mapping[phy_port];
    625             if (port == -1) {
    626                 continue;
    627             }
    628             soc_helix5_port_qsgmii_mode_get(unit, port, &qmode);
    629             if (qmode) {
    630                 continue;
    631             }
    632             pm = si->port_serdes[port];
    633             phy_base = HX5_PORT_BLOCK_BASE_PORT(port);
    634             /* port_flex_enable_corex=<0...1> */
    635             flex_en = soc_property_suffix_num_get_only_suffix
    636                         (unit, pm, spn_PORT_FLEX_ENABLE, "core", -1);
    637             /* port_flex_enable{x}=<0...1> */
    638             /* port_flex_enable=<0...1> */
    639             if (flex_en == -1) {
    640                 flex_en = soc_property_phys_port_get
    641                             (unit, phy_base, spn_PORT_FLEX_ENABLE, 0);
    642             }
    643             for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
    644                 blk_idx = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
    645                 if (flex_en && (blk_idx != -1)) {
    646                     SHR_BITSET(si->flexible_pm_bitmap, blk_idx);
    647                 }
    648             }
    649         }
    650     }
    651 
    652     si->flex_eligible =
    653         (!SHR_BITNULL_RANGE(si->flexible_pm_bitmap, 1, SOC_MAX_NUM_BLKS));
    654 
    655     /* port_flex_max_ports */
    656     memset(&(si->pm_max_ports), 0xff, sizeof(si->pm_max_ports));
    657     for (phy_port = 1; phy_port <= HELIX5_GPHY_PORTS_PER_PIPE; phy_port++) {
    658         port = si->port_p2l_mapping[phy_port];
    659         if (port == -1) {
    660             continue;
    661         }
    662         soc_helix5_port_qsgmii_mode_get(unit, port, &qmode);
    663         if (qmode) {
    664             continue;
    665         }
    666         pm = si->port_serdes[port];
    667         phy_base = HX5_PORT_BLOCK_BASE_PORT(port);
    668         for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) {
    669             blk_idx = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
    670             if (blk_idx == -1) {
    671                 continue;
    672             }
    673             blk_type = SOC_BLOCK_TYPE(unit, blk_idx);
    674             if (SHR_BITGET(si->flexible_pm_bitmap, blk_idx)) {
    675                 /* port_flex_max_ports{x}=y */
    676                 max_ports = soc_property_phys_port_get(unit,
    677                     phy_base, spn_PORT_FLEX_MAX_PORTS, -1);
    678                 /* port_flex_max_ports_corex=y */
    679                 if (max_ports == -1) {
    680                     max_ports = soc_property_suffix_num_get(unit, pm,
    681                         spn_PORT_FLEX_MAX_PORTS, "core", 16);
    682                 }
    683                 /* validation check */
    684                 if ((max_ports < 0) || (max_ports > 16) ) {
    685                     LOG_CLI((BSL_META_U(unit,
    686                         "Core %d: Bad port_flex_max_ports %d"),
    687                         pm, max_ports));
    688                     return SOC_E_CONFIG;
    689                 }
    690                 si->pm_max_ports[blk_idx] = max_ports;
    691             } else {
    692                 si->pm_max_ports[blk_idx] = blk_type == SOC_BLK_GXPORT ? 16 : 4;
    693             }
    694         }
    695     }
    696     return SOC_E_NONE;
    697 }
    698 
    699 #define PORT_IS_FALCON(unit, phy_port) \
    700         ((phy_port > 64) && (phy_port <= 76)) ? 1 : 0
    701 
    702 STATIC int
    703 _soc_hx5_port_lanes_set(int unit, int phy_port, int *lanes, int port_bandwidth)
    704 {
    705     if (PORT_IS_FALCON(unit, phy_port)) {
    706         *lanes =   (port_bandwidth > 53000) ? 4
    707                  : (port_bandwidth > 42000) ? 2
    708                  : (port_bandwidth > 27000) ? 2
    709                  : (20000 == SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(port_bandwidth)) ? 2
    710                  : 1;
    711     } else {
    712         *lanes =   (port_bandwidth > 21000) ? 4
    713                  : (port_bandwidth > 11000) ? 2
    714                  : 1;
    715     }
    716 
    717     if (soc_property_phys_port_get(unit, 1, spn_PORT_GMII_MODE, 0) == 0) {
    718         if (phy_port >=5 && phy_port <= 16) {
    719             return SOC_E_CONFIG;
    720         }
    721     }
    722     if (soc_property_phys_port_get(unit, 17, spn_PORT_GMII_MODE, 0) == 0) {
    723         if (phy_port >= 21 && phy_port <= 32) {
    724             return SOC_E_CONFIG;
    725         }
    726     }
    727     if (soc_property_phys_port_get(unit, 33, spn_PORT_GMII_MODE, 0) == 0) {
    728         if (phy_port >= 37 && phy_port <= 48) {
    729             return SOC_E_CONFIG;
    730         }
    731     }
    732 
    733     return ((*lanes == -1) ? SOC_E_CONFIG : SOC_E_NONE);
    734 }
    735 
    736 int
    737 soc_hx5_port_oversub_get(int unit, int phy_port, int logical_port)
    738 {
    739     soc_pbmp_t pbmp;
    740     int oversub_mode = 0, oversub = 0;
    741 
    742     SOC_PBMP_CLEAR(pbmp);
    743 
    744     oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0);
    745 
    746     if (oversub_mode == 0) {
    747         oversub = 0;
    748     } else if (oversub_mode == 1) {
    749         oversub = 1;
    750     } else if (oversub_mode == 2) {
    751         pbmp = soc_property_get_pbmp(unit, spn_PBMP_OVERSUBSCRIBE, 0);
    752         if (SOC_PBMP_MEMBER(pbmp, logical_port)) {
    753             oversub = 1;
    754         }
    755         if (phy_port > 0) {
    756             oversub = soc_property_phys_port_get(unit, phy_port,
    757                           spn_PORT_OVERSUBSCRIBE, oversub);
    758         }
    759     }
    760     return oversub;
    761 }
    762 
    763 STATIC void
    764 _soc_hx5_mmu_idb_ports_assign(int unit)
    765 {
    766     int port, phy_port, mmu_port_os, mmu_port_lr;
    767     soc_info_t *si;
    768 
    769     si = &SOC_INFO(unit);
    770     if  (SOC_WARM_BOOT(unit) && (si->flex_eligible) ) {
    771         /* Port mappings recovered from Scache */
    772         return;
    773     }
    774 
    775 
    776     mmu_port_os = 0;
    777 
    778     /* PHY Ports: 61-64
    779      * MMU/IDB Ports: 0-3
    780      */
    781     for (phy_port = 61; phy_port <= 64; phy_port++, mmu_port_os++) {
    782         si->port_p2m_mapping[phy_port] = mmu_port_os;
    783         si->port_m2p_mapping[mmu_port_os] = phy_port;
    784 
    785         port = si->port_p2l_mapping[phy_port];
    786         if (port == -1) {
    787             continue;
    788         }
    789         si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port];
    790     }
    791 
    792     /* PHY Ports: 69-72
    793      * MMU/IDB Ports: 4-7
    794      */
    795     for (phy_port = 69; phy_port <= 72; phy_port++, mmu_port_os++) {
    796         si->port_p2m_mapping[phy_port] = mmu_port_os;
    797         si->port_m2p_mapping[mmu_port_os] = phy_port;
    798 
    799         port = si->port_p2l_mapping[phy_port];
    800         if (port == -1) {
    801             continue;
    802         }
    803         si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port];
    804     }
    805 
    806     /* PHY Ports: 65-68
    807      * MMU/IDB Ports: 8-11
    808      */
    809     for (phy_port = 65; phy_port <= 68; phy_port++, mmu_port_os++) {
    810         si->port_p2m_mapping[phy_port] = mmu_port_os;
    811         si->port_m2p_mapping[mmu_port_os] = phy_port;
    812 
    813         port = si->port_p2l_mapping[phy_port];
    814         if (port == -1) {
    815             continue;
    816         }
    817         si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port];
    818     }
    819 
    820     /* PHY Ports: 73-76
    821      * MMU/IDB Ports: 12-15
    822      */
    823     for (phy_port = 73; phy_port <= 76; phy_port++, mmu_port_os++) {
    824         si->port_p2m_mapping[phy_port] = mmu_port_os;
    825         si->port_m2p_mapping[mmu_port_os] = phy_port;
    826 
    827         port = si->port_p2l_mapping[phy_port];
    828         if (port == -1) {
    829             continue;
    830         }
    831         si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port];
    832     }
    833 
    834     mmu_port_lr = mmu_port_os;
    835 
    836     
    837     for (phy_port = 1; phy_port <= 4; phy_port++, mmu_port_os++) {
    838         si->port_p2m_mapping[phy_port] = mmu_port_os;
    839         si->port_m2p_mapping[mmu_port_os] = phy_port;
    840 
    841         port = si->port_p2l_mapping[phy_port];
    842         if (port == -1) {
    843             continue;
    844         }
    845         si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port];
    846     }
    847 
    848     /* PHY Ports: 17-20
    849      * MMU/IDB Ports: 20-23
    850      */
    851     for (phy_port = 17; phy_port <= 20; phy_port++, mmu_port_os++) {
    852         si->port_p2m_mapping[phy_port] = mmu_port_os;
    853         si->port_m2p_mapping[mmu_port_os] = phy_port;
    854 
    855         port = si->port_p2l_mapping[phy_port];
    856         if (port == -1) {
    857             continue;
    858         }
    859         si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port];
    860     }
    861 
    862     /* PHY Ports: 33-36
    863      * MMU/IDB Ports: 24-27
    864      */
    865     for (phy_port = 33; phy_port <= 36; phy_port++, mmu_port_os++) {
    866         si->port_p2m_mapping[phy_port] = mmu_port_os;
    867         si->port_m2p_mapping[mmu_port_os] = phy_port;
    868 
    869         port = si->port_p2l_mapping[phy_port];
    870         if (port == -1) {
    871             continue;
    872         }
    873         si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port];
    874     }
    875 
    876     /* PHY Ports: 49-60
    877      * MMU/IDB Ports: 40-51
    878      */
    879     for (phy_port = 49; phy_port <= 60; phy_port++) {
    880         si->port_p2m_mapping[phy_port] = phy_port - 9;
    881         si->port_m2p_mapping[phy_port - 9] = phy_port;
    882 
    883         port = si->port_p2l_mapping[phy_port];
    884         if (port == -1) {
    885             continue;
    886         }
    887         si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port];
    888     }
    889 
    890     /* PHY Ports: 1-60
    891      * MMU/IDB Ports within 16-68
    892      *
    893      * When DL ports are in LR we use a running number
    894      * In Line-rate config PM4x10Q can be in GMII mode (upto 16 lanes)
    895      */
    896     for (phy_port = 1; phy_port <= 60; phy_port++) {
    897         port = si->port_p2l_mapping[phy_port];
    898         if ((port == -1) || IS_OVERSUB_PORT(unit, port)) {
    899             continue;
    900         }
    901 
    902         si->port_p2m_mapping[phy_port] = mmu_port_lr;
    903         si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port];
    904         si->port_m2p_mapping[mmu_port_lr] = phy_port;
    905         mmu_port_lr++;
    906     }
    907 
    908     return;
    909 }
    910 
    911 int
    912 soc_helix5_port_config_init(int unit, uint16 dev_id)
    913 {
    914     soc_info_t *si;
    915     char *config_str, *sub_str, *sub_str_end;
    916     static const char str_2p5[] = "2.5";
    917     char str_buf[8];
    918     int rv;
    919     int num_port, num_phy_port, num_mmu_port;
    920     int port, phy_port, mmu_port;
    921     int pipe, index, bandwidth_cap, is_any_cap = FALSE;
    922     int port_bandwidth;
    923     char option1, option2;
    924 
    925     si = &SOC_INFO(unit);
    926 
    927     num_phy_port = HX5_NUM_PHY_PORT;
    928     num_port = HX5_NUM_PORT;
    929     num_mmu_port = HX5_NUM_MMU_PORT;
    930 
    931     soc_helix5_max_frequency_get(unit, dev_id, -1, -1, &si->frequency);
    932 
    933     si->bandwidth = 2048000;
    934 
    935 
    936     si->oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0);
    937 
    938     for (phy_port = 0; phy_port < num_phy_port; phy_port++) {
    939         si->port_p2l_mapping[phy_port] = -1;
    940         si->port_p2m_mapping[phy_port] = -1;
    941     }
    942     for (port = 0; port < num_port; port++) {
    943         si->port_l2p_mapping[port] = -1;
    944         si->port_l2i_mapping[port] = -1;
    945         si->port_speed_max[port] = -1;
    946         si->port_group[port] = -1;
    947         si->port_serdes[port] = -1;
    948         si->port_pipe[port] = -1;
    949         si->port_num_lanes[port] = -1;
    950     }
    951     for (mmu_port = 0; mmu_port < num_mmu_port; mmu_port++) {
    952         si->port_m2p_mapping[mmu_port] = -1;
    953     }
    954     SOC_PBMP_CLEAR(si->eq_pbm);
    955     SOC_PBMP_CLEAR(si->management_pbm);
    956     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    957         SOC_PBMP_CLEAR(si->pipe_pbm[pipe]);
    958     };
    959     SOC_PBMP_CLEAR(si->oversub_pbm);
    960     SOC_PBMP_CLEAR(si->all.disabled_bitmap);
    961 
    962     /* Populate the fixed mapped ports */
    963     for (index = 0; index < COUNTOF(hx5_anc_ports); index++) {
    964         port = hx5_anc_ports[index].port;
    965         phy_port = hx5_anc_ports[index].phy_port;
    966         pipe = hx5_anc_ports[index].pipe;;
    967 
    968         si->port_l2p_mapping[port] = phy_port;
    969         si->port_l2i_mapping[port] = hx5_anc_ports[index].idb_port;
    970         si->port_p2l_mapping[phy_port] = port;
    971         si->port_p2m_mapping[phy_port] = hx5_anc_ports[index].mmu_port;
    972         si->port_pipe[port] = pipe;
    973         SOC_PBMP_PORT_ADD(si->pipe_pbm[pipe], port);
    974     }
    975 
    976     rv = SOC_E_NONE;
    977     for (port = 1; port < num_port; port++) {
    978         if (si->port_l2p_mapping[port] != -1) { /* fixed mapped port */
    979             continue;
    980         }
    981 
    982         config_str = soc_property_port_get_str(unit, port, spn_PORTMAP);
    983         if (config_str == NULL) {
    984             continue;
    985         }
    986 
    987         /*
    988          * portmap_<port>=<physical port number>:<bandwidth in Gb>[:<bandwidth cap in Gb/i(inactive)/1/2/4(num lanes)>][:<i>]
    989          * eg:    portmap_1=1:100
    990          *     or portmap_1=1:40
    991          *     or portmap_1=1:40:i
    992          *     or portmap_1=1:40:2
    993          *     or portmap_1=1:40:2:i
    994          *     or portmap_1=1:10:100
    995          */
    996         sub_str = config_str;
    997 
    998         /* Parse physical port number */
    999         phy_port = sal_ctoi(sub_str, &sub_str_end);
   1000         if (sub_str == sub_str_end) {
   1001             LOG_CLI((BSL_META_U(unit,
   1002                                 "Port %d: Missing physical port information \"%s\"\n"),
   1003                      port, config_str));
   1004             rv = SOC_E_FAIL;
   1005             continue;
   1006         }
   1007         if (phy_port < 0 || phy_port >= num_phy_port) {
   1008             LOG_CLI((BSL_META_U(unit,
   1009                                 "Port %d: Invalid physical port number %d\n"),
   1010                      port, phy_port));
   1011             rv = SOC_E_FAIL;
   1012             continue;
   1013         }
   1014         if (port > 64) {
   1015             LOG_CLI((BSL_META_U(unit,
   1016                                 "Port %d: Invalid logical port number %d\n"),
   1017                      port, port));
   1018             rv = SOC_E_FAIL;
   1019             continue;
   1020         }
   1021         /* coverity[check_after_sink : FALSE] */
   1022         if (si->port_p2l_mapping[phy_port] != -1) {
   1023             LOG_CLI((BSL_META_U(unit,
   1024                                 "Port %d: Physical port %d is used by port %d\n"),
   1025                      port, phy_port, si->port_p2l_mapping[phy_port]));
   1026             rv = SOC_E_FAIL;
   1027             continue;
   1028         }
   1029 
   1030         /* Skip ':' between physical port number and bandwidth */
   1031         sub_str = sub_str_end;
   1032         if (*sub_str != '\0') {
   1033             if (*sub_str != ':') {
   1034                 LOG_CLI((BSL_META_U(unit,
   1035                                     "Port %d: Bad config string \"%s\"\n"),
   1036                          port, config_str));
   1037                 rv = SOC_E_FAIL;
   1038                 continue;
   1039             }
   1040             sub_str++;
   1041         }
   1042 
   1043         /* Parse bandwidth */
   1044         for (index = 0; index < sizeof(str_2p5) - 1; index++) {
   1045             if (sub_str[index] == '\0') {
   1046                 break;
   1047             }
   1048             str_buf[index] = sub_str[index];
   1049         }
   1050         str_buf[index] = '\0';
   1051         if (!sal_strcmp(str_buf, str_2p5)) {
   1052             port_bandwidth = 2500;
   1053             sub_str_end = &sub_str[sizeof(str_2p5) - 1];
   1054         } else {
   1055             port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000;
   1056             if (sub_str == sub_str_end) {
   1057                 LOG_CLI((BSL_META_U(unit,
   1058                                     "Port %d: Missing bandwidth information \"%s\"\n"),
   1059                          port, config_str));
   1060                 rv = SOC_E_FAIL;
   1061                 continue;
   1062             }
   1063             switch (port_bandwidth) {
   1064             case 1000:
   1065             case 5000:
   1066             case 10000:
   1067             case 11000:
   1068             case 20000:
   1069             case 21000:
   1070             case 25000:
   1071             case 27000:
   1072             case 40000:
   1073             case 42000:
   1074             case 50000:
   1075             case 53000:
   1076             case 100000:
   1077                 break;
   1078             default:
   1079                 LOG_CLI((BSL_META_U(unit,
   1080                                     "Port %d: Invalid bandwidth %d Gb\n"),
   1081                          port, port_bandwidth / 1000));
   1082                 rv = SOC_E_FAIL;
   1083                 continue;
   1084             }
   1085         }
   1086 
   1087         /* Check if option presents */
   1088         option1 = 0; option2 = 0;
   1089         sub_str = sub_str_end;
   1090         if (*sub_str != '\0') {
   1091             /* Skip ':' between bandwidth and options */
   1092             /* Skip ':' between bandwidth and bandwidth cap or options */
   1093             if (*sub_str != ':') {
   1094                 LOG_CLI((BSL_META_U(unit,
   1095                                     "Port %d: Bad config string \"%s\"\n"),
   1096                          port, config_str));
   1097                 rv = SOC_E_FAIL;
   1098                 continue;
   1099             }
   1100             sub_str++;
   1101 
   1102             if (*sub_str != '\0') {
   1103                 /* Parse bandwidth cap or options */
   1104                 bandwidth_cap = sal_ctoi(sub_str, &sub_str_end) * 1000;
   1105                 switch (bandwidth_cap) {
   1106                 case 20000:
   1107                 case 21000:
   1108                 case 25000:
   1109                 case 27000:
   1110                 case 40000:
   1111                 case 42000:
   1112                 case 50000:
   1113                 case 53000:
   1114                 case 100000:
   1115                     sub_str = sub_str_end;
   1116                     _soc_hx5_port_speed_cap[unit][port] = bandwidth_cap;
   1117                     /* Flex config detected, port speed cap specified */
   1118                     is_any_cap = TRUE;
   1119                     break;
   1120                 default:
   1121                     if (!(*sub_str == 'i' || *sub_str == '1' ||
   1122                           *sub_str == 'm' || *sub_str == '2' ||
   1123                           *sub_str == '4')) {
   1124                         LOG_CLI((BSL_META_U(unit,
   1125                                             "Port %d: Bad config string "
   1126                                             "\"%s\"\n"),
   1127                              port, config_str));
   1128                         rv = SOC_E_FAIL;
   1129                         continue;
   1130                     } else {
   1131                         option1 = *sub_str;
   1132                         sub_str++;
   1133                     }
   1134                 }
   1135 
   1136                 /* Check if more options present */
   1137                 if (*sub_str != '\0') {
   1138                     /* Skip ':' between options */
   1139                     if (*sub_str != ':') {
   1140                         LOG_CLI((BSL_META_U(unit,
   1141                                             "Port %d: Bad config string \"%s\"\n"),
   1142                                  port, config_str));
   1143                         rv = SOC_E_FAIL;
   1144                         continue;
   1145                     }
   1146                     sub_str++;
   1147 
   1148                     if (*sub_str != 'i' && *sub_str != 'm') {
   1149                         LOG_CLI((BSL_META_U(unit,
   1150                                             "Port %d: Bad config string \"%s\"\n"),
   1151                                  port, config_str));
   1152                         rv = SOC_E_FAIL;
   1153                         continue;
   1154                     }
   1155                     option2 = *sub_str;
   1156                     sub_str++;
   1157                 }
   1158             }
   1159         }
   1160 
   1161         /* Check trailing string */
   1162         if (*sub_str != '\0') {
   1163             LOG_CLI((BSL_META_U(unit,
   1164                                 "Port %d: Bad config string \"%s\"\n"),
   1165                      port, config_str));
   1166             rv = SOC_E_FAIL;
   1167             continue;
   1168         }
   1169 
   1170         /* Update soc_info */
   1171         si->port_l2p_mapping[port] = phy_port;
   1172         si->port_p2l_mapping[phy_port] = port;
   1173         pipe = 0;
   1174 
   1175         si->port_pipe[port] = pipe;
   1176         SOC_PBMP_PORT_ADD(si->pipe_pbm[pipe], port);
   1177         si->port_speed_max[port] = port_bandwidth;
   1178         si->port_init_speed[port] = port_bandwidth;
   1179         if (option1 == 'i') {
   1180             SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port);
   1181             si->port_num_lanes[port] = -1;
   1182         } else {
   1183             uint32 mask;
   1184             switch (option1) {
   1185             case '1': si->port_num_lanes[port] = 1; break;
   1186             case '2': si->port_num_lanes[port] = 2; break;
   1187             case '4': si->port_num_lanes[port] = 4; break;
   1188             default:
   1189                 if (SOC_FAILURE(_soc_hx5_port_lanes_set(unit, phy_port,
   1190                                                         &si->port_num_lanes[port],
   1191                                                         port_bandwidth))) {
   1192                     rv = SOC_E_FAIL;
   1193                 }
   1194                 break;
   1195             }
   1196             SOC_IF_ERROR_RETURN(soc_hx5_support_speeds(unit, port, &mask));
   1197             if (!(SOC_PA_SPEED(port_bandwidth) & mask)) {
   1198                 rv = SOC_E_FAIL;
   1199             }
   1200         }
   1201 
   1202         if (option2 == 'i') {
   1203             SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port);
   1204             si->port_num_lanes[port] = -1;
   1205         }
   1206         if (soc_hx5_port_oversub_get(unit, phy_port, port)) {
   1207             SOC_PBMP_PORT_ADD(si->oversub_pbm, port);
   1208         }
   1209         if (phy_port <= 48) {
   1210             si->port_serdes[port] = (phy_port - 1) / _HX5_PORTS_PER_PMQ_PBLK;
   1211         } else {
   1212             si->port_serdes[port] = ((phy_port - 1) / _HX5_PORTS_PER_PBLK) - 9;
   1213         }
   1214     }
   1215 
   1216 
   1217     /* get flex port properties */
   1218     if (SOC_FAILURE(_soc_hx5_port_flex_init(unit, is_any_cap))) {
   1219         rv = SOC_E_FAIL;
   1220     }
   1221 
   1222     _soc_hx5_mmu_idb_ports_assign(unit);
   1223 #if defined(BCM_WARM_BOOT_SUPPORT)
   1224     if (si->flex_eligible) {
   1225         if (SOC_WARM_BOOT(unit)) {
   1226             SOC_IF_ERROR_RETURN(soc_hx5_flexport_scache_recovery(unit));
   1227         } else {
   1228             SOC_IF_ERROR_RETURN(soc_hx5_flexport_scache_allocate(unit));
   1229         }
   1230     }
   1231 #endif
   1232 
   1233     
   1234 
   1235     si->xpe_ipipe_map[0] = 1;
   1236     si->xpe_epipe_map[0] = 1;
   1237     si->sc_ipipe_map[0] = 1;
   1238     si->sc_epipe_map[0] = 1;
   1239     si->ipipe_xpe_map[0] = 1;
   1240     si->epipe_xpe_map[0] = 1;
   1241     si->ipipe_sc_map[0] = 1;
   1242     si->epipe_sc_map[0] = 1;
   1243 
   1244     return rv;
   1245 }
   1246 
   1247 static uint32 _soc_hx5_temp_mon_mask[SOC_MAX_NUM_DEVICES];
   1248 
   1249 /*
   1250  * Function:
   1251  *      _soc_hx5_alpm_addr_xlate_set
   1252  * Purpose:
   1253  *      Config addrss translation for ALPM UFT tables
   1254  *      addr [BITS 17:12] = Entry_Per_Bank * Bank + Entry
   1255  * Parameters:
   1256  *      unit (IN)         - switch unit
   1257  *      mem (IN)          - Memory id.
   1258  *      max_bank_ent (IN) - Max number of entries per bank
   1259  *      max_bank (IN)     - Max number of banks
   1260  * Returns:
   1261  *      SOC_E_*
   1262  */
   1263 STATIC int
   1264 _soc_hx5_alpm_addr_xlate_set(int unit, soc_mem_t mem,
   1265                              int max_bank_ent, int max_bank)
   1266 {
   1267    /* ALPM adressing:
   1268     * Bits [11:0] - Bucket number (max 4k buckets)
   1269     * Bits [14:12] - Bank id (max 6 banks)
   1270     * Bits [17:15] - Entry type (depends on view, max 6)
   1271     * Since Bank number is not power of 2, bits [14:12] do not correctly represent Bank id
   1272     * In HW this is resolved by introducing address translation tables for each view
   1273     * L3_DEFIP_ALPM_IPV4_ADDR_XLATE
   1274     * L3_DEFIP_ALPM_IPV4_1_ADDR_XLATE
   1275     * L3_DEFIP_ALPM_IPV6_64_ADDR_XLATE
   1276     * L3_DEFIP_ALPM_IPV6_64_1_ADDR_XLATE
   1277     * L3_DEFIP_ALPM_IPV6_128_ADDR_XLATE
   1278     * L3_DEFIP_ALPM_RAW_ADDR_XLATE
   1279     * L3_DEFIP_ALPM_ECC_ADDR_XLATE
   1280     * Bits [17:12] become lookup index into these tables which tells the Bank id and Entry type
   1281     */
   1282     int     rv = SOC_E_NONE;
   1283     int     i = 0;
   1284     int     idx_min = 0;
   1285     int     idx_max = 0;
   1286     int     size = 0;
   1287     uint8  *mbuf = NULL;
   1288     void   *entry_ptr;
   1289 
   1290     idx_min = soc_mem_index_min(unit, mem);
   1291     idx_max = max_bank_ent * max_bank - 1;
   1292 
   1293     if (idx_max > soc_mem_index_max(unit, mem)) {
   1294         return SOC_E_INTERNAL;
   1295     }
   1296 
   1297     size = SOC_MEM_TABLE_BYTES(unit, mem);
   1298     mbuf = soc_cm_salloc(unit, size, SOC_MEM_NAME(unit, mem));
   1299     if (NULL == mbuf) {
   1300         return SOC_E_MEMORY;
   1301     }
   1302 
   1303     /*  i = addr [BITS 17:12] = Entry_Per_Bank *  BANK_MAP + ENTRY_MAP */
   1304     for (i = idx_min; i <= idx_max; i++) {
   1305 
   1306         entry_ptr = soc_mem_table_idx_to_pointer(unit, mem,
   1307                                                  void *, mbuf, i);
   1308         sal_memcpy(entry_ptr, soc_mem_entry_null(unit, mem),
   1309                    soc_mem_entry_words(unit, mem) * sizeof(uint32));
   1310 
   1311         soc_mem_field32_set(unit, mem, entry_ptr, ENTRY_MAPf,
   1312                             i / max_bank);
   1313         soc_mem_field32_set(unit, mem, entry_ptr, BANK_MAPf,
   1314                             i % max_bank);
   1315     }
   1316 
   1317     rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY,
   1318                              idx_min, idx_max, mbuf);
   1319     soc_cm_sfree(unit, mbuf);
   1320 
   1321     return rv;
   1322 }
   1323 
   1324 int
   1325 soc_helix5_uft_uat_config(int unit)
   1326 {
   1327 
   1328     int index, shared_bank_offset = 2;
   1329     int num_l2_banks, num_l3_banks, num_fpem_banks = 0;
   1330     int dedicated_banks = 2;
   1331     int offset_base, offset_multiplier ;
   1332     int mpls_4k_banks;
   1333     int vlan_xlate_1_4k_banks;
   1334     int vlan_xlate_2_4k_banks;
   1335     int egr_vlan_xlate_1_banks, egr_vlan_xlate_2_banks;
   1336     uint32 hash_control_entry[4], shared_hash_control_entry[4],
   1337     shared_4k_hash_control_entry[4];
   1338     static const soc_field_t logical_to_physical_fields[] = {
   1339         LOGICAL_BANK_0_PHYSICAL_BANK_LOCATIONf,
   1340         LOGICAL_BANK_1_PHYSICAL_BANK_LOCATIONf,
   1341         LOGICAL_BANK_2_PHYSICAL_BANK_LOCATIONf,
   1342         LOGICAL_BANK_3_PHYSICAL_BANK_LOCATIONf,
   1343         LOGICAL_BANK_4_PHYSICAL_BANK_LOCATIONf,
   1344         LOGICAL_BANK_5_PHYSICAL_BANK_LOCATIONf,
   1345         LOGICAL_BANK_6_PHYSICAL_BANK_LOCATIONf,
   1346         LOGICAL_BANK_7_PHYSICAL_BANK_LOCATIONf,
   1347         LOGICAL_BANK_8_PHYSICAL_BANK_LOCATIONf,
   1348         LOGICAL_BANK_9_PHYSICAL_BANK_LOCATIONf
   1349     };
   1350     static const soc_field_t dedicated_fields[] = {
   1351         HASH_OFFSET_DEDICATED_BANK_0f, HASH_OFFSET_DEDICATED_BANK_1f
   1352     };
   1353     static const soc_field_t shared_fields[] = {
   1354         B0_HASH_OFFSETf, B1_HASH_OFFSETf, B2_HASH_OFFSETf,
   1355         B3_HASH_OFFSETf, B4_HASH_OFFSETf, B5_HASH_OFFSETf
   1356     };
   1357     /* UFT/UAT control memories programming */
   1358     SOC_IF_ERROR_RETURN
   1359         (soc_helix5_hash_bank_count_get(unit, L2Xm, &num_l2_banks));
   1360     SOC_IF_ERROR_RETURN
   1361         (soc_helix5_hash_bank_count_get(unit, L3_ENTRY_ONLY_SINGLEm,
   1362                                           &num_l3_banks));
   1363     SOC_IF_ERROR_RETURN
   1364         (soc_helix5_hash_bank_count_get(unit, EXACT_MATCH_2m,
   1365                                           &num_fpem_banks));
   1366     SOC_IF_ERROR_RETURN
   1367         (soc_helix5_hash_bank_count_get(unit, EGR_VLAN_XLATE_1_SINGLEm,
   1368                                           &egr_vlan_xlate_1_banks));
   1369     SOC_IF_ERROR_RETURN
   1370         (soc_helix5_hash_bank_count_get(unit, EGR_VLAN_XLATE_2_SINGLEm,
   1371                                           &egr_vlan_xlate_2_banks));
   1372     SOC_IF_ERROR_RETURN
   1373         (soc_helix5_hash_bank_count_get(unit, MPLS_ENTRY_SINGLEm,
   1374                                           &mpls_4k_banks));
   1375     SOC_IF_ERROR_RETURN
   1376         (soc_helix5_hash_bank_count_get(unit, VLAN_XLATE_1_SINGLEm,
   1377                                           &vlan_xlate_1_4k_banks));
   1378     SOC_IF_ERROR_RETURN
   1379         (soc_helix5_hash_bank_count_get(unit, VLAN_XLATE_2_SINGLEm,
   1380                                           &vlan_xlate_2_4k_banks));
   1381 
   1382     if (soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) {
   1383         int non_alpm = num_fpem_banks + num_l3_banks +
   1384                        num_l2_banks - 2 * (dedicated_banks);
   1385         sal_memset(hash_control_entry, 0,
   1386                     sizeof(uft_shared_banks_control_entry_t));
   1387         SOC_IF_ERROR_RETURN
   1388         (READ_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1389                                              hash_control_entry));
   1390         if ((non_alpm) && (non_alpm <= 2)) {
   1391             /* If Shared banks are used between ALPM and non-ALPM memories,
   1392              * then ALPM uses Shared Bank B2, B3, B4, B5 and non-ALPM uses
   1393              * B6, B7 banks
   1394              */
   1395             soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm,
   1396                                 hash_control_entry, ALPM_MODEf, 1);
   1397             soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm,
   1398                                 hash_control_entry, BANK_BYPASS_LPf, 0xf);
   1399             SOC_IF_ERROR_RETURN
   1400                 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r,
   1401                                         REG_PORT_ANY, ALPM_BANK_MODEf, 1));
   1402             (void)soc_trident3_set_alpm_banks(unit, 4);
   1403             shared_bank_offset += 4;
   1404         } else {
   1405             soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm,
   1406                                 hash_control_entry, ALPM_MODEf, 0);
   1407             soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm,
   1408                                 hash_control_entry, BANK_BYPASS_LPf, 0x3f);
   1409             SOC_IF_ERROR_RETURN
   1410                 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r,
   1411                                         REG_PORT_ANY, ALPM_BANK_MODEf, 0));
   1412             (void)soc_trident3_set_alpm_banks(unit, 6);
   1413         }
   1414         SOC_IF_ERROR_RETURN
   1415         (WRITE_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1416                                              hash_control_entry));
   1417         /* Addrss translation for ALPM UFT tables */
   1418         if (soc_feature(unit, soc_feature_alpm_addr_xlate)) {
   1419             int       max_bank_ent[] = {6, 4, 4, 3, 2, 1, 4};
   1420             soc_mem_t alpm_mem[]     = {L3_DEFIP_ALPM_IPV4_ADDR_XLATEm,
   1421                                         L3_DEFIP_ALPM_IPV4_1_ADDR_XLATEm,
   1422                                         L3_DEFIP_ALPM_IPV6_64_ADDR_XLATEm,
   1423                                         L3_DEFIP_ALPM_IPV6_64_1_ADDR_XLATEm,
   1424                                         L3_DEFIP_ALPM_IPV6_128_ADDR_XLATEm,
   1425                                         L3_DEFIP_ALPM_RAW_ADDR_XLATEm,
   1426                                         L3_DEFIP_ALPM_ECC_ADDR_XLATEm};
   1427 
   1428             for (index = 0; index < 7; index++) {
   1429                 SOC_IF_ERROR_RETURN(
   1430                     _soc_hx5_alpm_addr_xlate_set(unit, alpm_mem[index],
   1431                                                  max_bank_ent[index],
   1432                                                  soc_trident3_get_alpm_banks(unit)));
   1433             }
   1434         }
   1435     }
   1436 
   1437     sal_memset(shared_hash_control_entry, 0,
   1438                 sizeof(uft_shared_banks_control_entry_t));
   1439     SOC_IF_ERROR_RETURN
   1440         (READ_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1441                                         shared_hash_control_entry));
   1442     sal_memset(hash_control_entry, 0, sizeof(l2_entry_hash_control_entry_t));
   1443     SOC_IF_ERROR_RETURN
   1444         (READ_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, hash_control_entry));
   1445     soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm , hash_control_entry,
   1446                         HASH_TABLE_BANK_CONFIGf, (((1 << dedicated_banks) - 1)
   1447                         | (((1 << (num_l2_banks - dedicated_banks)) - 1) <<
   1448                         shared_bank_offset)));
   1449     for (index = dedicated_banks ; index < num_l2_banks ; index++) {
   1450         soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm , hash_control_entry,
   1451                             logical_to_physical_fields[index],
   1452                             index + shared_bank_offset - dedicated_banks);
   1453     }
   1454 
   1455     offset_multiplier = 64 / num_l2_banks;
   1456     offset_base = 64 % num_l2_banks;
   1457 
   1458     for (index = 0; index < dedicated_banks; index++) {
   1459         soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm, hash_control_entry,
   1460                             dedicated_fields[index], offset_base + (index *
   1461                             offset_multiplier));
   1462     }
   1463 
   1464     for (index = dedicated_banks; index < num_l2_banks; index++) {
   1465         soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm,
   1466                             shared_hash_control_entry, shared_fields[index -
   1467                             dedicated_banks], offset_base +
   1468                             (index * offset_multiplier));
   1469     }
   1470 
   1471     SOC_IF_ERROR_RETURN
   1472         (WRITE_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, hash_control_entry));
   1473 
   1474     sal_memset(hash_control_entry, 0, sizeof(exact_match_hash_control_entry_t));
   1475     SOC_IF_ERROR_RETURN
   1476         (READ_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1477                                             hash_control_entry));
   1478     shared_bank_offset += (num_l2_banks - dedicated_banks) ;
   1479 
   1480     /* Handle case where fpem banks are set to 0 */
   1481     if (num_fpem_banks) {
   1482         offset_multiplier = 64 / num_fpem_banks;
   1483         offset_base = 64 % num_fpem_banks;
   1484     }
   1485 
   1486     soc_mem_field32_set(unit, EXACT_MATCH_HASH_CONTROLm, hash_control_entry,
   1487                       HASH_TABLE_BANK_CONFIGf,
   1488                       ((1 << num_fpem_banks) - 1) << shared_bank_offset);
   1489     for (index = 0 ; index < num_fpem_banks; index++) {
   1490         soc_mem_field32_set(unit, EXACT_MATCH_HASH_CONTROLm , hash_control_entry,
   1491                           logical_to_physical_fields[index], index +
   1492                           shared_bank_offset);
   1493         soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm,
   1494                             shared_hash_control_entry,
   1495                             shared_fields[shared_bank_offset + index -
   1496                             dedicated_banks],
   1497                             offset_base + (index * offset_multiplier));
   1498     }
   1499 
   1500     SOC_IF_ERROR_RETURN
   1501         (WRITE_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1502                                             hash_control_entry));
   1503 
   1504     sal_memset(hash_control_entry, 0, sizeof(l3_entry_hash_control_entry_t));
   1505     SOC_IF_ERROR_RETURN
   1506         (READ_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1507                                         hash_control_entry));
   1508     shared_bank_offset += num_fpem_banks;
   1509     offset_multiplier = 64 / num_l3_banks;
   1510     offset_base = 64 % num_l3_banks;
   1511     soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, hash_control_entry,
   1512                         HASH_TABLE_BANK_CONFIGf, ((((1 << (num_l3_banks -
   1513                         dedicated_banks)) - 1) << shared_bank_offset) |
   1514                         (((1 << dedicated_banks) - 1) << 8)));
   1515 
   1516     for (index = 0; index < dedicated_banks; index++) {
   1517         soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, hash_control_entry,
   1518                             dedicated_fields[index], offset_base + (index *
   1519                             offset_multiplier));
   1520     }
   1521 
   1522     for (index = dedicated_banks ; index < num_l3_banks ; index++) {
   1523         soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, hash_control_entry,
   1524                           logical_to_physical_fields[index],
   1525                           index + shared_bank_offset - dedicated_banks);
   1526         soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm,
   1527                             shared_hash_control_entry,
   1528                             shared_fields[shared_bank_offset + index -
   1529                             (dedicated_banks * 2)],
   1530                             offset_base + (index * offset_multiplier));
   1531     }
   1532     SOC_IF_ERROR_RETURN
   1533         (WRITE_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1534                                         hash_control_entry));
   1535     SOC_IF_ERROR_RETURN
   1536         (WRITE_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1537                                         shared_hash_control_entry));
   1538 
   1539     sal_memset(shared_hash_control_entry, 0,
   1540                 sizeof(ep_uat_shared_banks_control_entry_t));
   1541     sal_memset(hash_control_entry, 0,
   1542                 sizeof(egr_vlan_xlate_1_hash_control_entry_t));
   1543 
   1544     if (egr_vlan_xlate_1_banks) {
   1545         offset_base = 64 % egr_vlan_xlate_1_banks;
   1546         offset_multiplier = 64 / egr_vlan_xlate_1_banks;
   1547     }
   1548 
   1549     SOC_IF_ERROR_RETURN
   1550         (READ_EP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1551                                             shared_hash_control_entry));
   1552     SOC_IF_ERROR_RETURN
   1553         (READ_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1554                                                 hash_control_entry));
   1555     soc_mem_field32_set(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm,
   1556                         hash_control_entry, HASH_TABLE_BANK_CONFIGf,
   1557                         ((1 << egr_vlan_xlate_1_banks) - 1)) ;
   1558 
   1559     for(index = 0; index < egr_vlan_xlate_1_banks; index++) {
   1560         soc_mem_field32_set(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm,
   1561                             hash_control_entry,
   1562                             logical_to_physical_fields[index],
   1563                             index);
   1564         soc_mem_field32_set(unit, EP_UAT_SHARED_BANKS_CONTROLm,
   1565                             shared_hash_control_entry, shared_fields[index],
   1566                             offset_base + (index * offset_multiplier));
   1567     }
   1568     SOC_IF_ERROR_RETURN
   1569         (WRITE_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1570                                                 hash_control_entry));
   1571 
   1572     sal_memset(hash_control_entry, 0,
   1573                 sizeof(egr_vlan_xlate_2_hash_control_entry_t));
   1574 
   1575     if (egr_vlan_xlate_2_banks) {
   1576         offset_base = 64 % egr_vlan_xlate_2_banks;
   1577         offset_multiplier = 64 / egr_vlan_xlate_2_banks;
   1578     }
   1579 
   1580     SOC_IF_ERROR_RETURN
   1581         (READ_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1582                                                 hash_control_entry));
   1583     soc_mem_field32_set(unit, EGR_VLAN_XLATE_2_HASH_CONTROLm, hash_control_entry,
   1584                         HASH_TABLE_BANK_CONFIGf,
   1585                         ((1 << egr_vlan_xlate_2_banks) - 1) <<
   1586                         egr_vlan_xlate_1_banks) ;
   1587 
   1588     for(index = 0; index < egr_vlan_xlate_2_banks; index++) {
   1589         soc_mem_field32_set(unit, EGR_VLAN_XLATE_2_HASH_CONTROLm,
   1590                             hash_control_entry,
   1591                             logical_to_physical_fields[index],
   1592                             index + egr_vlan_xlate_1_banks);
   1593         soc_mem_field32_set(unit, EP_UAT_SHARED_BANKS_CONTROLm,
   1594                             shared_hash_control_entry, shared_fields[index +
   1595                             egr_vlan_xlate_1_banks], offset_base + (index *
   1596                             offset_multiplier));
   1597     }
   1598     SOC_IF_ERROR_RETURN
   1599         (WRITE_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1600                                                 hash_control_entry));
   1601     SOC_IF_ERROR_RETURN
   1602         (WRITE_EP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1603                                                 shared_hash_control_entry));
   1604 
   1605     sal_memset(shared_hash_control_entry, 0,
   1606                 sizeof(ip_uat_shared_banks_control_entry_t));
   1607     sal_memset(shared_4k_hash_control_entry, 0,
   1608                 sizeof(ip_uat_shared_banks_control_entry_t));
   1609     sal_memset(hash_control_entry, 0,
   1610                 sizeof(mpls_entry_hash_control_entry_t));
   1611     SOC_IF_ERROR_RETURN
   1612         (READ_IP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1613                                                 shared_hash_control_entry));
   1614     SOC_IF_ERROR_RETURN
   1615         (READ_IP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1616                                                 shared_4k_hash_control_entry));
   1617     SOC_IF_ERROR_RETURN
   1618         (READ_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1619                                                 hash_control_entry));
   1620 
   1621     if (mpls_4k_banks) {
   1622         offset_base = 64 % (mpls_4k_banks);
   1623         offset_multiplier = 64 / (mpls_4k_banks);
   1624     }
   1625     soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry,
   1626                         HASH_TABLE_BANK_CONFIGf, ((1 << mpls_4k_banks) - 1));
   1627     for(index = 0; index < mpls_4k_banks; index++) {
   1628         soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry,
   1629                             logical_to_physical_fields[index], index);
   1630         soc_mem_field32_set(unit, IP_UAT_SHARED_BANKS_CONTROLm,
   1631                             shared_4k_hash_control_entry, shared_fields[index],
   1632                             offset_base + ( index * offset_multiplier));
   1633     }
   1634 
   1635     SOC_IF_ERROR_RETURN
   1636         (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1637                                                 hash_control_entry));
   1638 
   1639     sal_memset(hash_control_entry, 0,
   1640                 sizeof(vlan_xlate_1_hash_control_entry_t));
   1641     SOC_IF_ERROR_RETURN
   1642         (READ_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1643                                                 hash_control_entry));
   1644     if (vlan_xlate_1_4k_banks) {
   1645         offset_base = 64 % (vlan_xlate_1_4k_banks);
   1646         offset_multiplier = 64 / (vlan_xlate_1_4k_banks);
   1647     }
   1648     soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm, hash_control_entry,
   1649                         HASH_TABLE_BANK_CONFIGf, ((((1 << vlan_xlate_1_4k_banks)
   1650                         - 1) << mpls_4k_banks)));
   1651 
   1652     for(index = 0; index < vlan_xlate_1_4k_banks; index++) {
   1653         soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm,
   1654                             hash_control_entry,
   1655                             logical_to_physical_fields[index], index +
   1656                             mpls_4k_banks);
   1657         soc_mem_field32_set(unit, IP_UAT_SHARED_BANKS_CONTROLm,
   1658                             shared_4k_hash_control_entry, shared_fields[index +
   1659                             mpls_4k_banks], offset_base + (index *
   1660                             offset_multiplier));
   1661     }
   1662 
   1663     SOC_IF_ERROR_RETURN
   1664         (WRITE_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1665                                                 hash_control_entry));
   1666 
   1667     sal_memset(hash_control_entry, 0,
   1668                 sizeof(vlan_xlate_2_hash_control_entry_t));
   1669     SOC_IF_ERROR_RETURN
   1670         (READ_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1671                                                 hash_control_entry));
   1672     if (vlan_xlate_2_4k_banks) {
   1673         offset_base = 64 % (vlan_xlate_2_4k_banks);
   1674         offset_multiplier = 64 / (vlan_xlate_2_4k_banks);
   1675     }
   1676     soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm, hash_control_entry,
   1677                         HASH_TABLE_BANK_CONFIGf, ((((1 << vlan_xlate_2_4k_banks)
   1678                         - 1) << (mpls_4k_banks + vlan_xlate_1_4k_banks))));
   1679 
   1680     for(index = 0; index < vlan_xlate_2_4k_banks; index++) {
   1681         soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm, hash_control_entry,
   1682                             logical_to_physical_fields[index], index +
   1683                             mpls_4k_banks + vlan_xlate_1_4k_banks);
   1684         soc_mem_field32_set(unit, IP_UAT_SHARED_BANKS_CONTROLm,
   1685                             shared_4k_hash_control_entry, shared_fields[index +
   1686                             mpls_4k_banks + vlan_xlate_1_4k_banks], offset_base
   1687                             + (index * offset_multiplier));
   1688     }
   1689 
   1690     SOC_IF_ERROR_RETURN
   1691         (WRITE_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1692                                                 hash_control_entry));
   1693     SOC_IF_ERROR_RETURN
   1694         (WRITE_IP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1695                                                 shared_4k_hash_control_entry));
   1696 
   1697     /* Create a mutex for s/w re-ordering */
   1698     SOC_IF_ERROR_RETURN(soc_td3_hash_mutex_init (unit));
   1699 
   1700     return SOC_E_NONE;
   1701 }
   1702 
   1703 
   1704 /*
   1705  *  PM4X10_QTC core has two work modes: Q(QTC) mode and Ethernet(XLPORT) mode.
   1706  *  In QTC mode, QTC is reset via register PMQ_XGXS0_CTRL_REGr which is belong to SOC_BLK_PMQPORT block.
   1707  *  In Eth mode, TSC is reset via register XLPORT_XGXS0_CTRL_REGr which is belong to SOC_BLK_XLPORT block.
   1708  *  To reset QTC or TSC core, the work mode must be identified by register CHIP_CONFIGr which is configured in soc_helix5_chip_reset.
   1709  */
   1710 int
   1711 soc_helix5_port_reset(int unit)
   1712 {
   1713     int blk, port;
   1714     uint32 rval;
   1715     uint64 rval64;
   1716     uint32 index, qtc_mode = ETHER_MODE;
   1717     int sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   1718 
   1719     SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) {
   1720         port = SOC_BLOCK_PORT(unit, blk);
   1721 
   1722         SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_CONTROLr(unit, port, &rval));
   1723         soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 1);
   1724         SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval));
   1725         sal_udelay(10);
   1726         soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0);
   1727         if (soc_reg_field_valid(unit, CLPORT_MAC_CONTROLr, SYS_16B_INTF_MODEf) &&
   1728             soc_feature(unit, soc_feature_clmac_16byte_interface_mode)) {
   1729             soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, SYS_16B_INTF_MODEf, 1);
   1730         }
   1731         SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval));
   1732     }
   1733 
   1734     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   1735         port = SOC_BLOCK_PORT(unit, blk);
   1736         SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, port, &rval));
   1737         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 1);
   1738         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval));
   1739         sal_udelay(10);
   1740         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0);
   1741         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval));
   1742 
   1743         if (IS_QSGMII_PORT(unit, port)) {
   1744             continue;
   1745         }
   1746 
   1747         SOC_IF_ERROR_RETURN(soc_reg_get(unit, XLPORT_XGXS0_CTRL_REGr, port, 0, &rval64));
   1748         soc_reg64_field32_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval64, REFSELf, 5);
   1749         SOC_IF_ERROR_RETURN(soc_reg_set(unit, XLPORT_XGXS0_CTRL_REGr, port, 0, rval64));
   1750     }
   1751 
   1752      SOC_BLOCK_ITER(unit, blk, SOC_BLK_PMQPORT) {
   1753         port = blk | SOC_REG_ADDR_BLOCK_ID_MASK;
   1754         index = SOC_BLOCK_NUMBER(unit, blk);
   1755 
   1756         SOC_IF_ERROR_RETURN(soc_reg_get(unit, CHIP_CONFIGr, index, 0, &rval64));
   1757         qtc_mode = soc_reg64_field32_get(unit, CHIP_CONFIGr, rval64, QMODEf);
   1758         if (qtc_mode == Q_MODE) {
   1759             SOC_IF_ERROR_RETURN(soc_reg_get(unit, PMQ_XGXS0_CTRL_REGr, port, 0, &rval64));
   1760             soc_reg64_field32_set(unit, PMQ_XGXS0_CTRL_REGr, &rval64, REFSELf, 5);
   1761             SOC_IF_ERROR_RETURN(soc_reg_set(unit, PMQ_XGXS0_CTRL_REGr, port, 0, rval64));
   1762         }
   1763     }
   1764 
   1765     /* Power off CLPORT blocks */
   1766     SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) {
   1767         port = SOC_BLOCK_PORT(unit, blk);
   1768         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 1));
   1769     }
   1770     sal_usleep(sleep_usec + 10000);
   1771     /* Power on CLPORT blocks */
   1772     SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) {
   1773         port = SOC_BLOCK_PORT(unit, blk);
   1774         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 0));
   1775     }
   1776 
   1777     /* Power off XLPORT blocks */
   1778     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   1779         port = SOC_BLOCK_PORT(unit, blk);
   1780         if (IS_QSGMII_PORT(unit, port)) {
   1781             continue;
   1782         }
   1783 
   1784         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 1));
   1785     }
   1786     sal_usleep(sleep_usec + 10000);
   1787     /* Power on XLPORT blocks */
   1788     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   1789         port = SOC_BLOCK_PORT(unit, blk);
   1790         if (IS_QSGMII_PORT(unit, port)) {
   1791             continue;
   1792         }
   1793 
   1794         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 0));
   1795     }
   1796 
   1797     /* Power off PMQ blocks */
   1798     SOC_BLOCK_ITER(unit, blk, SOC_BLK_PMQPORT) {
   1799         port = blk | SOC_REG_ADDR_BLOCK_ID_MASK;
   1800         index = SOC_BLOCK_NUMBER(unit, blk);
   1801 
   1802         SOC_IF_ERROR_RETURN(soc_reg_get(unit, CHIP_CONFIGr, index, 0, &rval64));
   1803         qtc_mode = soc_reg64_field32_get(unit, CHIP_CONFIGr, rval64, QMODEf);
   1804         if (qtc_mode == Q_MODE) {
   1805             SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 1));
   1806         }
   1807     }
   1808     sal_usleep(sleep_usec + 10000);
   1809     /* Power on PMQ blocks */
   1810     SOC_BLOCK_ITER(unit, blk, SOC_BLK_PMQPORT) {
   1811         port = blk | SOC_REG_ADDR_BLOCK_ID_MASK;
   1812         index = SOC_BLOCK_NUMBER(unit, blk);
   1813 
   1814         SOC_IF_ERROR_RETURN(soc_reg_get(unit, CHIP_CONFIGr, index, 0, &rval64));
   1815         qtc_mode = soc_reg64_field32_get(unit, CHIP_CONFIGr, rval64, QMODEf);
   1816         if (qtc_mode == Q_MODE) {
   1817             SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 0));
   1818         }
   1819     }
   1820 
   1821     return SOC_E_NONE;
   1822 }
   1823 
   1824 STATIC int
   1825 _soc_helix5_port_mapping_init(int unit)
   1826 {
   1827     soc_info_t *si;
   1828     int port, phy_port, idb_port, i;
   1829     soc_reg_t reg;
   1830     soc_mem_t mem;
   1831     uint32 rval;
   1832     uint32 entry[SOC_MAX_MEM_WORDS];
   1833     int pipe = 0;
   1834     int max_idx = 0;
   1835 
   1836     si = &SOC_INFO(unit);
   1837 
   1838     /* Ingress IDB to device port mapping */
   1839     sal_memset(&entry, 0, sizeof(entry));
   1840     mem = SOC_MEM_UNIQUE_ACC(unit, ING_PHY_TO_IDB_PORT_MAPm)[pipe];
   1841 
   1842     /* Set all entries to 0x7f as default */
   1843     soc_mem_field32_set(unit, mem, &entry, IDB_PORTf, 0x7f);
   1844     soc_mem_field32_set(unit, mem, &entry, VALIDf, 0);
   1845     max_idx = soc_mem_index_max(unit, ING_PHY_TO_IDB_PORT_MAPm);
   1846     for (phy_port = 0; phy_port <= max_idx; phy_port++) {
   1847         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, &entry));
   1848     }
   1849 
   1850     /* Ingress IDB to device port mapping */
   1851     sal_memset(&entry, 0,
   1852                sizeof(ing_idb_to_device_port_number_mapping_table_entry_t));
   1853     mem = SOC_MEM_UNIQUE_ACC(unit, ING_IDB_TO_DEVICE_PORT_NUMBER_MAPPING_TABLEm)[pipe];
   1854     /* Set all entries to 0x7f since Device Port No. 0 corresponds to CPU port*/
   1855     soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, 0x7f);
   1856     for (idb_port = 0; idb_port < HX5_NUM_PORT; idb_port++) {
   1857         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, idb_port, &entry));
   1858     }
   1859 
   1860     /* Ancillary ports */
   1861     for (i = 0; i < COUNTOF(hx5_anc_ports); i++) {
   1862         idb_port = hx5_anc_ports[i].idb_port;
   1863         phy_port = si->port_m2p_mapping[idb_port];
   1864         port = si->port_p2l_mapping[phy_port];
   1865 
   1866         soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, port);
   1867         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, idb_port, &entry));
   1868 
   1869         /* Egress device port to physical port mapping */
   1870         rval = 0;
   1871         reg = EGR_DEVICE_TO_PHYSICAL_PORT_NUMBER_MAPPINGr;
   1872         soc_reg_field_set(unit, reg, &rval, PHYSICAL_PORT_NUMBERf, phy_port);
   1873         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   1874 
   1875         /* MMU port to physical port mapping */
   1876         rval = 0;
   1877         reg = MMU_PORT_TO_PHY_PORT_MAPPINGr;
   1878         soc_reg_field_set(unit, reg, &rval, PHY_PORTf, phy_port);
   1879         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   1880 
   1881         /* MMU port to device port mapping */
   1882         rval = 0;
   1883         reg = MMU_PORT_TO_DEVICE_PORT_MAPPINGr;
   1884         soc_reg_field_set(unit, reg, &rval, DEVICE_PORTf, port);
   1885         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   1886     }
   1887     /* Ingress GPP port to device port mapping */
   1888     mem = SYS_PORTMAPm;
   1889     sal_memset(&entry, 0, sizeof(sys_portmap_entry_t));
   1890     for (port = 0; port < HX5_NUM_PORT; port++) {
   1891         soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, port);
   1892         SOC_IF_ERROR_RETURN
   1893             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, port, &entry));
   1894     }
   1895 
   1896 
   1897 #if 0
   1898     /* Mapping for Front Panel ports handled in DV flexport code */
   1899     for (port = 0; port < HX5_NUM_PORT; port++) {
   1900         idb_port = si->port_l2i_mapping[port];
   1901 
   1902         if (idb_port == -1) {
   1903             continue;
   1904         }
   1905         soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, port);
   1906         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, idb_port, &entry));
   1907     }
   1908 
   1909     /* Ingress physical to IDB port mapping
   1910      * This table is programmed only for front panel ports
   1911      */
   1912     sal_memset(&entry, 0, sizeof(ing_phy_to_idb_port_map_entry_t));
   1913     mem = SOC_MEM_UNIQUE_ACC(unit, ING_PHY_TO_IDB_PORT_MAPm)[pipe];
   1914     for (phy_port = 1; phy_port <= _HX5_PORTS_PER_PIPE; phy_port++) {
   1915         port = si->port_p2l_mapping[phy_port];
   1916 
   1917         if (port != -1) {
   1918             idb_port = si->port_l2i_mapping[port];
   1919             if (idb_port == -1) {
   1920                 return SOC_E_INTERNAL;
   1921             }
   1922 
   1923             soc_mem_field32_set(unit, mem, &entry, IDB_PORTf, idb_port);
   1924             soc_mem_field32_set(unit, mem, &entry, VALIDf, 1);
   1925         } else {
   1926             soc_mem_field32_set(unit, mem, &entry, VALIDf, 0);
   1927         }
   1928 
   1929         SOC_IF_ERROR_RETURN
   1930             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port - 1, &entry));
   1931     }
   1932 
   1933     /* Ingress device port to GPP port mapping
   1934      * PORT_TAB.SRC_SYS_PORT_ID is programmed in the general port config
   1935      * init routine _bcm_fb_port_cfg_init()
   1936      */
   1937 
   1938     /* Egress device port to physical port mapping */
   1939     rval = 0;
   1940     reg = EGR_DEVICE_TO_PHYSICAL_PORT_NUMBER_MAPPINGr;
   1941     PBMP_ALL_ITER(unit, port) {
   1942         soc_reg_field_set(unit, reg, &rval, PHYSICAL_PORT_NUMBERf,
   1943                           si->port_l2p_mapping[port]);
   1944         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   1945     }
   1946 
   1947     /* MMU port to physical port mapping */
   1948     rval = 0;
   1949     reg = MMU_PORT_TO_PHY_PORT_MAPPINGr;
   1950     PBMP_ALL_ITER(unit, port) {
   1951         soc_reg_field_set(unit, reg, &rval, PHY_PORTf,
   1952                           si->port_l2p_mapping[port]);
   1953         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   1954     }
   1955 
   1956     /* MMU port to device port mapping */
   1957     rval = 0;
   1958     reg = MMU_PORT_TO_DEVICE_PORT_MAPPINGr;
   1959     PBMP_ALL_ITER(unit, port) {
   1960         soc_reg_field_set(unit, reg, &rval, DEVICE_PORTf, port);
   1961         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   1962     }
   1963 #endif
   1964     return SOC_E_NONE;
   1965 }
   1966 
   1967 /*
   1968  * Function:
   1969  *      _soc_helix5_latency_config
   1970  * Purpose:
   1971  *      Configure latency in SLOT_PIPELINE_CONFIG register
   1972  * Parameters:
   1973  *      unit (IN)    - switch unit
   1974  * Returns:
   1975  *      SOC_E_*
   1976  */
   1977 
   1978 STATIC int
   1979 _soc_helix5_latency_config(int unit)
   1980 {
   1981     soc_reg_t reg;
   1982     uint32 rval;
   1983     uint32 latency, pipe_latency_full = 455;
   1984     int frequency, dpp_clk_ratio_x10;
   1985     soc_info_t *si = &SOC_INFO(unit);
   1986 
   1987     frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, si->frequency);
   1988     dpp_clk_ratio_x10 = (frequency > CCLK_FREQ_1012MHZ)? 15:10;
   1989 
   1990     reg = SLOT_PIPELINE_CONFIGr;
   1991     rval = 0;
   1992     latency = (pipe_latency_full * dpp_clk_ratio_x10 / 10) - 6 + 5;
   1993     if ((dpp_clk_ratio_x10 == 15) && (pipe_latency_full % 2)) {
   1994         latency += 1;   /* To round up. */
   1995     }
   1996     soc_reg_field_set(unit, reg, &rval, LATENCYf, latency);
   1997     soc_reg_field_set(unit, reg, &rval, WR_ENf, 1);
   1998     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1999 
   2000     return SOC_E_NONE;
   2001 }
   2002 
   2003 
   2004 /*
   2005  * Function:
   2006  *      _soc_hx5_set_idb_dpp_ctrl
   2007  * Purpose:
   2008  *      Configure IDB DPP credits
   2009  * Parameters:
   2010  *      unit (IN)    - switch unit
   2011  * Returns:
   2012  *      SOC_E_*
   2013  */
   2014 static int
   2015 _soc_hx5_set_idb_dpp_ctrl(int unit)
   2016 {
   2017     soc_reg_t reg;
   2018     uint32 pipe_map, in_progress;
   2019     int pipe;
   2020     uint32 rval, rval0;
   2021     int pipe_init_usec;
   2022     soc_timeout_t to;
   2023     static const soc_reg_t idb_dpp_ctrl[2] = {
   2024         IDB_DPP_CTRL_PIPE0r, IDB_DPP_CTRL_PIPE1r
   2025     };
   2026 
   2027     soc_trident3_pipe_map_get(unit, &pipe_map);
   2028 
   2029     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2030         if (!(pipe_map & (1 << pipe))) {
   2031             continue;
   2032         }
   2033         reg = idb_dpp_ctrl[pipe];
   2034         rval = 0;
   2035         /*SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));*/
   2036         soc_reg_field_set(unit, reg, &rval, MAX_REF_CNTf, 4);
   2037         soc_reg_field_set(unit, reg, &rval, MAX_SBUS_CNTf, 4);
   2038         soc_reg_field_set(unit, reg, &rval, CREDITSf, 36);
   2039         soc_reg_field_set(unit, reg, &rval, DONEf, 0);
   2040         soc_reg_field_set(unit, reg, &rval, STARTf, 1);
   2041         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   2042     }
   2043 
   2044     /* For simulation, set timeout to 10 sec.  Otherwise, timeout = 50 ms */
   2045     if (SAL_BOOT_SIMULATION) {
   2046         pipe_init_usec = 10000000;
   2047     } else {
   2048         pipe_init_usec = 50000;
   2049     }
   2050     soc_timeout_init(&to, pipe_init_usec, 0);
   2051 
   2052     /* Wait for DPP credit initialization done */
   2053     in_progress = pipe_map;
   2054     do {
   2055         for (pipe = 0; pipe < NUM_PIPE(unit) && in_progress; pipe++) {
   2056             reg = SOC_REG_UNIQUE_ACC(unit, IDB_DPP_CTRLr)[pipe];
   2057             if (in_progress & (1 << pipe)) { /* not done yet */
   2058                 SOC_IF_ERROR_RETURN
   2059                     (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval0));
   2060                 if (soc_reg_field_get(unit, reg, rval0, DONEf)) {
   2061                     in_progress ^= (1 << pipe);
   2062                 }
   2063             }
   2064         }
   2065         if (soc_timeout_check(&to)) {
   2066             LOG_WARN(BSL_LS_SOC_COMMON,
   2067                      (BSL_META_U(unit,
   2068                                  "unit %d : IDB_DPP_CTRL timeout\n"), unit));
   2069             break;
   2070         }
   2071     } while (in_progress != 0);
   2072 
   2073     return SOC_E_NONE;
   2074 }
   2075 
   2076 STATIC int
   2077 _soc_helix5_tdm_init(int unit, soc_port_schedule_state_t *port_schedule_state)
   2078 {
   2079     soc_control_t *soc = SOC_CONTROL(unit);
   2080     soc_info_t *si = &SOC_INFO(unit);
   2081     soc_port_map_type_t *in_portmap;
   2082     int port, speed;
   2083     int i = 0;
   2084     if (soc->tdm_info == NULL) {
   2085         soc->tdm_info = sal_alloc(sizeof(_soc_helix5_tdm_temp_t),
   2086                                     "Helix5 TDM info");
   2087         if (soc->tdm_info == NULL) {
   2088             return SOC_E_MEMORY;
   2089         }
   2090         sal_memset(soc->tdm_info, 0, sizeof(_soc_helix5_tdm_temp_t));
   2091     }
   2092     sal_memset(port_schedule_state, 0, sizeof(soc_port_schedule_state_t));
   2093 #if defined(BCM_WARM_BOOT_SUPPORT)
   2094     if (SOC_WARM_BOOT(unit)) {
   2095         SOC_IF_ERROR_RETURN(soc_hx5_tdm_scache_recovery(unit));
   2096         return SOC_E_NONE;
   2097     } else {
   2098         SOC_IF_ERROR_RETURN(soc_hx5_tdm_scache_allocate(unit));
   2099     }
   2100 #endif
   2101     /* Core clock frequency */
   2102     port_schedule_state->frequency = si->frequency;
   2103     port_schedule_state->bandwidth = si->bandwidth;
   2104     port_schedule_state->io_bandwidth = si->io_bandwidth;
   2105     port_schedule_state->lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);;
   2106     port_schedule_state->is_flexport = 0;
   2107 
   2108     /* Construct in_port_map */
   2109     in_portmap = &port_schedule_state->in_port_map;
   2110     PBMP_PORT_ITER(unit, port) {
   2111         if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
   2112             continue;
   2113         }
   2114         if (IS_HG_PORT(unit, port)) {
   2115             speed = soc_port_speed_higig2eth(si->port_speed_max[port]);
   2116             port_schedule_state->resource[i].encap = SOC_ENCAP_HIGIG2;
   2117         } else {
   2118             speed = si->port_speed_max[port];
   2119         }
   2120         in_portmap->log_port_speed[port] = speed;
   2121         in_portmap->port_num_lanes[port] = si->port_num_lanes[port];
   2122 
   2123         port_schedule_state->resource[i].physical_port = si->port_l2p_mapping[port];
   2124         port_schedule_state->resource[i].logical_port = port;
   2125         port_schedule_state->resource[i].idb_port = si->port_l2i_mapping[port];
   2126         port_schedule_state->resource[i].mmu_port = si->port_l2i_mapping[port];
   2127         port_schedule_state->resource[i].num_lanes = si->port_num_lanes[port];
   2128         port_schedule_state->resource[i].speed = speed;
   2129         port_schedule_state->resource[i].pipe = 0;
   2130         port_schedule_state->resource[i].oversub = IS_OVERSUB_PORT(unit, port) ? 1 : 0;
   2131         port_schedule_state->nport = ++i;
   2132     }
   2133     sal_memcpy(in_portmap->port_p2l_mapping, si->port_p2l_mapping,
   2134                 sizeof(int)*HELIX5_TDM_PHY_PORTS_PER_DEV);
   2135     sal_memcpy(in_portmap->port_l2p_mapping, si->port_l2p_mapping,
   2136                 sizeof(int)*_HX5_TDM_DEV_PORTS_PER_DEV);
   2137     sal_memcpy(in_portmap->port_p2m_mapping, si->port_p2m_mapping,
   2138                 sizeof(int)*HELIX5_TDM_PHY_PORTS_PER_DEV);
   2139     sal_memcpy(in_portmap->port_m2p_mapping, si->port_m2p_mapping,
   2140                 sizeof(int)*_HX5_TDM_MMU_PORTS_PER_DEV);
   2141     sal_memcpy(in_portmap->port_l2i_mapping, si->port_l2i_mapping,
   2142                 sizeof(int)*_HX5_TDM_DEV_PORTS_PER_DEV);
   2143     sal_memcpy(&in_portmap->physical_pbm, &si->physical_pbm, sizeof(pbmp_t));
   2144     sal_memcpy(&in_portmap->hg2_pbm, &si->hg.bitmap, sizeof(pbmp_t));
   2145     sal_memcpy(&in_portmap->management_pbm, &si->management_pbm,
   2146                 sizeof(pbmp_t));
   2147     sal_memcpy(&in_portmap->oversub_pbm, &si->oversub_pbm, sizeof(pbmp_t));
   2148 
   2149     SOC_IF_ERROR_RETURN(soc_hx5_port_schedule_tdm_init(unit, port_schedule_state));
   2150     SOC_IF_ERROR_RETURN(soc_hx5_tdm_init(unit, port_schedule_state));
   2151     SOC_IF_ERROR_RETURN(soc_helix5_reconfigure_ports(unit, port_schedule_state));
   2152     SOC_IF_ERROR_RETURN(soc_hx5_soc_tdm_update(unit, port_schedule_state));
   2153 
   2154     return SOC_E_NONE;
   2155 }
   2156 
   2157 /* IDB, EDB configuration for Front Panel ports handled in DV flexport code */
   2158 STATIC int
   2159 _soc_helix5_edb_init(int unit)
   2160 {
   2161     uint32 entry[SOC_MAX_MEM_WORDS];
   2162     int i;
   2163 
   2164     for (i = 0; i < COUNTOF(hx5_anc_ports); i++) {
   2165         /* Configure egress mmu cell credit */
   2166         sal_memset(entry, 0, sizeof(egr_mmu_cell_credit_entry_t));
   2167         soc_EGR_MMU_CELL_CREDITm_field32_set(unit, &entry, CREDITf, 11);
   2168         SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CELL_CREDITm
   2169             (unit, MEM_BLOCK_ALL, hx5_anc_ports[i].phy_port, &entry));
   2170 
   2171         /* Configure egress transmit start count */
   2172         sal_memset(entry, 0, sizeof(egr_xmit_start_count_pipe0_entry_t));
   2173         soc_EGR_XMIT_START_COUNT_PIPE0m_field32_set(unit, &entry, THRESHOLDf, 7);
   2174         SOC_IF_ERROR_RETURN(WRITE_EGR_XMIT_START_COUNT_PIPE0m
   2175             (unit, MEM_BLOCK_ALL, hx5_anc_ports[i].port * 16, &entry));
   2176 
   2177         /* Enable egress */
   2178         sal_memset(entry, 0, sizeof(egr_enable_entry_t));
   2179         soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1);
   2180         SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEm
   2181             (unit, MEM_BLOCK_ALL, hx5_anc_ports[i].phy_port, entry));
   2182     }
   2183     return SOC_E_NONE;
   2184 }
   2185 
   2186 STATIC int
   2187 _soc_helix5_idb_init(int unit)
   2188 {
   2189     soc_reg_t reg;
   2190     uint32 rval0;
   2191 
   2192     /* Toggle cpu port cell assembly reset to send initial credit to EP */
   2193     reg = IDB_CA_CPU_CONTROLr;
   2194     rval0 = 0;
   2195     soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1);
   2196     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0));
   2197     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0));
   2198 
   2199     /* Toggle loopback cell assembly reset to send initial credit to EP */
   2200     reg = IDB_CA_LPBK_CONTROLr;
   2201     rval0 = 0;
   2202     soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1);
   2203     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0));
   2204     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0));
   2205 
   2206     /* Toggle FAE port cell assembly reset to send initial credit to EP */
   2207     reg = IDB_CA_BSK_CONTROLr;
   2208     rval0 = 0;
   2209     soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1);
   2210     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0));
   2211     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0));
   2212 
   2213     _soc_hx5_set_idb_dpp_ctrl(unit);
   2214 
   2215     return SOC_E_NONE;
   2216 }
   2217 
   2218 /* For a given logical port, return the OBM id and the lane number
   2219  * OBM id is nothing but the Serdes/PortMacro number
   2220  * Note: HX5 has three different OBM register sets
   2221  */
   2222 int
   2223 soc_helix5_port_obm_info_get(int unit, soc_port_t port,
   2224                                int *obm_id, int *lane)
   2225 {
   2226     soc_info_t *si;
   2227     soc_port_t phy_port;
   2228     int port_block_base;
   2229 
   2230     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
   2231         return SOC_E_PARAM;
   2232     }
   2233     si = &SOC_INFO(unit);
   2234     phy_port = si->port_l2p_mapping[port];
   2235     port_block_base = HX5_PORT_BLOCK_BASE_PORT(port);
   2236     if (lane != NULL) {
   2237         *lane = (phy_port - port_block_base) / 4;
   2238     }
   2239 
   2240     *obm_id = si->port_serdes[port];
   2241 
   2242     return SOC_E_NONE;
   2243 }
   2244 
   2245 extern int
   2246 (*_phy_tsce_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *, int);
   2247 extern int
   2248 (*_phy_tscf_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *, int);
   2249 
   2250 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad)    \
   2251                             ((_phy_reg) |= ((_phyad) & 0x1f) << 19)
   2252 
   2253 STATIC int
   2254 _soc_helix5_mdio_addr_to_port(uint32 phy_addr)
   2255 {
   2256     int bus, offset;
   2257 
   2258     /* Must be internal MDIO address */
   2259     if ((phy_addr & 0x80) == 0) {
   2260         return 0;
   2261     }
   2262 
   2263     /*
   2264      * Internal phy address:
   2265      * bus 0 phy 1 to 24 are mapped to Physical port 1 to 48
   2266      * bus 1 phy 1 to 16 are mapped to Physical port 49 to 64
   2267      * bus 2 phy 1 to 24 are mapped to Physical port 65 to 76
   2268      * bus 3 phy 1 to 24 are mapped to Physical port IPROC PM
   2269      */
   2270     bus = PHY_ID_BUS_NUM(phy_addr);
   2271     if (bus > 3) {
   2272         return 0;
   2273     }
   2274     switch (bus) {
   2275     case 0: offset = 0;
   2276         break;
   2277     case 1: offset = 48;
   2278         break;
   2279     case 2: offset = 64;
   2280         break;
   2281     case 3: offset = 76;
   2282         break;
   2283     default:
   2284         return 0;
   2285     }
   2286 
   2287     return (phy_addr & 0x1f) + offset;
   2288 }
   2289 
   2290 STATIC int
   2291 _soc_helix5_tscx_reg_read(int unit, uint32 phy_addr,
   2292                             uint32 phy_reg, uint32 *phy_data)
   2293 {
   2294     int rv, blk, blk_i, blktype, port;
   2295     int qmod, inst;
   2296     uint64 rval64;
   2297     int phy_port = _soc_helix5_mdio_addr_to_port(phy_addr);
   2298 
   2299     port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   2300     blk = SOC_PORT_BLOCK(unit, phy_port);
   2301     LOG_INFO(BSL_LS_SOC_MII,
   2302              (BSL_META_U(unit,
   2303                          "soc_helix5_tscx_reg_read[%d]: %d/%d/%d/%d\n"),
   2304               unit, phy_addr, phy_port, port, blk));
   2305     TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr);
   2306 
   2307     if(phy_port < 49){
   2308         inst = (phy_port - 1) / 16;
   2309         SOC_IF_ERROR_RETURN(soc_reg_get(unit, CHIP_CONFIGr, inst, 0, &rval64));
   2310         qmod = soc_reg64_field32_get(unit, CHIP_CONFIGr, rval64, QMODEf);
   2311 
   2312         for (blk_i = 0; SOC_BLOCK_INFO(unit, blk_i).type >= 0; blk_i++) {
   2313             blktype = SOC_BLOCK_INFO(unit, blk_i).type;
   2314             if ((blktype == (qmod ? SOC_BLK_PMQPORT : SOC_BLK_XLPORT)) && (SOC_BLOCK_INFO(unit, blk_i).number == inst)) {
   2315                 blk = blk_i;
   2316                 break;
   2317             }
   2318         }
   2319     }
   2320 
   2321     rv = soc_sbus_tsc_reg_read(unit, port, blk, phy_addr,
   2322                                phy_reg, phy_data);
   2323     return rv;
   2324 }
   2325 
   2326 STATIC int
   2327 _soc_helix5_tscx_reg_write(int unit, uint32 phy_addr,
   2328                              uint32 phy_reg, uint32 phy_data)
   2329 {
   2330     int rv, blk, blk_i, blktype, port;
   2331     int phy_port = _soc_helix5_mdio_addr_to_port(phy_addr);
   2332     int qmod, inst;
   2333     uint64 rval64;
   2334 
   2335     port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   2336     blk = SOC_PORT_BLOCK(unit, phy_port);
   2337     LOG_INFO(BSL_LS_SOC_MII,
   2338              (BSL_META_U(unit,
   2339                          "soc_helix5_tscx_reg_write[%d]: %d/%d/%d/%d\n"),
   2340               unit, phy_addr, phy_port, port, blk));
   2341     TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr);
   2342 
   2343     if(phy_port < 49){
   2344         inst = (phy_port - 1) / 16;
   2345         SOC_IF_ERROR_RETURN(soc_reg_get(unit, CHIP_CONFIGr, inst, 0, &rval64));
   2346         qmod = soc_reg64_field32_get(unit, CHIP_CONFIGr, rval64, QMODEf);
   2347 
   2348         for (blk_i = 0; SOC_BLOCK_INFO(unit, blk_i).type >= 0; blk_i++) {
   2349             blktype = SOC_BLOCK_INFO(unit, blk_i).type;
   2350             if ((blktype == (qmod ? SOC_BLK_PMQPORT : SOC_BLK_XLPORT)) && (SOC_BLOCK_INFO(unit, blk_i).number == inst)) {
   2351                 blk = blk_i;
   2352                 break;
   2353             }
   2354         }
   2355     }
   2356 
   2357     rv = soc_sbus_tsc_reg_write(unit, port, blk, phy_addr,
   2358                                 phy_reg, phy_data);
   2359     return rv;
   2360 }
   2361 
   2362 STATIC int
   2363 _soc_helix5_ft_bank_config(int unit)
   2364 {
   2365     soc_mem_t mem;
   2366     int ft_banks;
   2367     ft_key_hash_control_entry_t ft_key_ctrl;
   2368 
   2369     if (soc_feature(unit, soc_feature_flowtracker_ver_1_8K_ft_table)) {
   2370         ft_banks = 0x7;
   2371     } else if (soc_feature(unit, soc_feature_flowtracker_ver_1_16K_ft_table)) {
   2372         ft_banks = 0x1f;
   2373     } else {
   2374         ft_banks = 0x1ff;
   2375     }
   2376 
   2377     SOC_IF_ERROR_RETURN(soc_mem_read(unit, FT_KEY_HASH_CONTROLm,
   2378                                      MEM_BLOCK_ANY, 0, &ft_key_ctrl));
   2379 
   2380     /* Enable banks for flowtracking. */
   2381     soc_mem_field32_set(unit, FT_KEY_HASH_CONTROLm, &ft_key_ctrl,
   2382         HASH_TABLE_BANK_CONFIGf, ft_banks);
   2383 
   2384     soc_mem_field32_set(unit, FT_KEY_HASH_CONTROLm, &ft_key_ctrl,
   2385         HASH_TABLE_TEST_MODEf, 0);
   2386 
   2387     SOC_IF_ERROR_RETURN(soc_mem_write(unit, FT_KEY_HASH_CONTROLm,
   2388         MEM_BLOCK_ALL, 0, &ft_key_ctrl));
   2389 
   2390     mem = FT_KEY_SS0_SHARED_BANKS_CONTROLm;
   2391     soc_mem_field32_set(unit, mem,
   2392             (void *) &ft_key_ss0_shared_banks_control, B0_HASH_OFFSETf, 6);
   2393     soc_mem_field32_set(unit, mem,
   2394             (void *) &ft_key_ss0_shared_banks_control, B1_HASH_OFFSETf, 12);
   2395     soc_mem_field32_set(unit, mem,
   2396             (void *) &ft_key_ss0_shared_banks_control, B2_HASH_OFFSETf, 18);
   2397     soc_mem_field32_set(unit, mem,
   2398             (void *) &ft_key_ss0_shared_banks_control, B3_HASH_OFFSETf, 24);
   2399     soc_mem_field32_set(unit, mem,
   2400             (void *) &ft_key_ss0_shared_banks_control, B4_HASH_OFFSETf, 30);
   2401     BCM_IF_ERROR_RETURN(WRITE_FT_KEY_SS0_SHARED_BANKS_CONTROLm(unit,
   2402                 MEM_BLOCK_ANY, 0, (void *) &ft_key_ss0_shared_banks_control));
   2403 
   2404     mem = FT_KEY_SS1_SHARED_BANKS_CONTROLm;
   2405     soc_mem_field32_set(unit, mem,
   2406             (void *) &ft_key_ss1_shared_banks_control, B0_HASH_OFFSETf, 6);
   2407     soc_mem_field32_set(unit, mem,
   2408             (void *) &ft_key_ss1_shared_banks_control, B1_HASH_OFFSETf, 12);
   2409     soc_mem_field32_set(unit, mem,
   2410             (void *) &ft_key_ss1_shared_banks_control, B2_HASH_OFFSETf, 18);
   2411     soc_mem_field32_set(unit, mem,
   2412             (void *) &ft_key_ss1_shared_banks_control, B3_HASH_OFFSETf, 24);
   2413     BCM_IF_ERROR_RETURN(WRITE_FT_KEY_SS1_SHARED_BANKS_CONTROLm(unit,
   2414                 MEM_BLOCK_ANY, 0, (void *) &ft_key_ss1_shared_banks_control));
   2415 
   2416     return SOC_E_NONE;
   2417 }
   2418 
   2419 
   2420 STATIC int
   2421 _soc_helix5_init_hash_control_reset(int unit) {
   2422 
   2423     soc_mem_field32_set(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm,
   2424           &egr_vlan_1_hash_control, HASH_TABLE_BANK_CONFIGf, 0xf);
   2425     SOC_IF_ERROR_RETURN
   2426         (WRITE_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2427                                              &egr_vlan_1_hash_control));
   2428 
   2429     soc_mem_field32_set(unit, EGR_VLAN_XLATE_2_HASH_CONTROLm,
   2430           &egr_vlan_2_hash_control, HASH_TABLE_BANK_CONFIGf, 0);
   2431     SOC_IF_ERROR_RETURN
   2432         (WRITE_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2433                                              &egr_vlan_2_hash_control));
   2434 
   2435     SOC_IF_ERROR_RETURN
   2436         (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2437                                      &egr_vp_vlan_mbm_hash_control));
   2438 
   2439     soc_mem_field32_set(unit, EXACT_MATCH_HASH_CONTROLm,
   2440           &exact_match_hash_control, HASH_TABLE_BANK_CONFIGf, 0x0);
   2441     SOC_IF_ERROR_RETURN
   2442         (WRITE_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2443                                              &exact_match_hash_control));
   2444 
   2445     SOC_IF_ERROR_RETURN
   2446         (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2447                                      &ing_vp_vlan_mbm_hash_control));
   2448 
   2449     soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm,
   2450             &l2_entry_hash_control, HASH_TABLE_BANK_CONFIGf, 0x3);
   2451     SOC_IF_ERROR_RETURN
   2452         (WRITE_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2453                                              &l2_entry_hash_control));
   2454 
   2455     soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm,
   2456           &l3_entry_hash_control, HASH_TABLE_BANK_CONFIGf, 0xffc);
   2457     SOC_IF_ERROR_RETURN
   2458         (WRITE_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2459                                              &l3_entry_hash_control));
   2460 
   2461     soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm,
   2462           &mpls_entry_hash_control, HASH_TABLE_BANK_CONFIGf, 0x0);
   2463     SOC_IF_ERROR_RETURN
   2464         (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2465                                              &mpls_entry_hash_control));
   2466 
   2467     soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm,
   2468           &vlan_1_hash_control, HASH_TABLE_BANK_CONFIGf, 0xff);
   2469     SOC_IF_ERROR_RETURN
   2470         (WRITE_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2471                                              &vlan_1_hash_control));
   2472 
   2473     soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm,
   2474           &vlan_2_hash_control, HASH_TABLE_BANK_CONFIGf, 0x0);
   2475     SOC_IF_ERROR_RETURN
   2476         (WRITE_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2477                                              &vlan_2_hash_control));
   2478 
   2479     SOC_IF_ERROR_RETURN
   2480         (WRITE_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2481                               &uft_shared_banks_control));
   2482 
   2483     SOC_IF_ERROR_RETURN
   2484         (WRITE_IP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2485                               &ip_uat_shared_banks_control));
   2486 
   2487     SOC_IF_ERROR_RETURN
   2488         (WRITE_EP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2489                               &ep_uat_shared_banks_control));
   2490 
   2491     SOC_IF_ERROR_RETURN
   2492         (WRITE_FT_KEY_SS0_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2493                                &ft_key_ss0_shared_banks_control));
   2494 
   2495     SOC_IF_ERROR_RETURN
   2496         (WRITE_FT_KEY_SS1_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2497                                &ft_key_ss1_shared_banks_control));
   2498 
   2499      return SOC_E_NONE;
   2500 }
   2501 
   2502 int
   2503 soc_helix5_chip_reset(int unit)
   2504 {
   2505 #define _SOC_HX5_TEMP_MAX   130
   2506 #define _SOC_HX5_DEF_TEMP_MAX   90
   2507     int index;
   2508     uint32 to_usec, temp_mask;
   2509     uint32 rval, temp_thr;
   2510     int pm = 0, field = 0, fval = 0, reg = 0, pipe = 0;
   2511     int frequency = -1, freq_sel = 0;
   2512     uint64 rval64;
   2513     soc_field_t fields[4];
   2514     uint32 values[4];
   2515 
   2516     static const soc_reg_t temp_thr_reg[] = {
   2517         TOP_PVTMON_0_INTR_THRESHOLDr, TOP_PVTMON_1_INTR_THRESHOLDr,
   2518         TOP_PVTMON_2_INTR_THRESHOLDr, TOP_PVTMON_3_INTR_THRESHOLDr,
   2519         TOP_PVTMON_4_INTR_THRESHOLDr, TOP_PVTMON_5_INTR_THRESHOLDr,
   2520         TOP_PVTMON_6_INTR_THRESHOLDr
   2521     };
   2522     static const char *temp_thr_prop[] = {
   2523         "temp0_threshold", "temp1_threshold", "temp2_threshold",
   2524         "temp3_threshold", "temp4_threshold", "temp5_threshold",
   2525         "temp6_threshold"
   2526     };
   2527     static soc_field_t egr_reset_fields[] = {
   2528         PM0_RESETf, PM1_RESETf, PM2_RESETf, PM3_RESETf,
   2529         PM4_RESETf, PM5_RESETf, PM6_RESETf, PM7_RESETf,
   2530         PM8_RESETf, PM9_RESETf
   2531     };
   2532 
   2533     soc_info_t *si = &SOC_INFO(unit);
   2534 
   2535     to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) :
   2536                                    (10 * MILLISECOND_USEC);
   2537 
   2538     soc_helix5_sbus_ring_map_config(unit);
   2539 
   2540     sal_usleep(to_usec);
   2541     /* Reset IP, EP, MMU and port macros */
   2542     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, 0x0));
   2543 
   2544 
   2545     /* If frequency is specificed use it , else use the si->frequency */
   2546     if (frequency == -1) {
   2547         frequency = si->frequency;
   2548     }
   2549 
   2550     if (frequency > -1) {
   2551         switch (frequency) {
   2552         case 893:
   2553             freq_sel = 0;
   2554             break;
   2555         case 762:
   2556             freq_sel = 1;
   2557             break;
   2558         case 668:
   2559             freq_sel = 2;
   2560             break;
   2561         case 587:
   2562             freq_sel = 3;
   2563             break;
   2564         case 543:
   2565             freq_sel = 4;
   2566             break;
   2567         case 450:
   2568             freq_sel = 5;
   2569             break;
   2570         case 400:
   2571             freq_sel = 6;
   2572             break;
   2573         default:
   2574             LOG_ERROR(BSL_LS_SOC_COMMON,
   2575                         (BSL_META_U(unit,
   2576                                     "Config Error - "
   2577                          "Invalid frequency set: %d\n"), si->frequency));
   2578             return SOC_E_PARAM;
   2579         }
   2580 
   2581         fields[0] = CORE_CLK_0_FREQ_SELf;
   2582         values[0] = freq_sel;
   2583         fields[1] = SW_CORE_CLK_0_SEL_ENf;
   2584         values[1] = 1;
   2585         SOC_IF_ERROR_RETURN
   2586             (soc_reg_fields32_modify(unit, TOP_CORE_CLK_FREQ_SELr,
   2587                                      REG_PORT_ANY, 2, fields, values));
   2588     } else {
   2589         LOG_ERROR(BSL_LS_SOC_COMMON,
   2590                     (BSL_META_U(unit,
   2591                                 "Config Error - "
   2592                      "Invalid frequency set: %d\n"), si->frequency));
   2593             return SOC_E_PARAM;
   2594     }
   2595 
   2596     /* Bring PLLs out of reset */
   2597     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   2598     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   2599                         TOP_TS_PLL_RST_Lf, 0);
   2600     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   2601                         TOP_XG_PLL0_RST_Lf, 0);
   2602     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   2603                         TOP_XG_PLL1_RST_Lf, 0);
   2604 
   2605     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   2606 
   2607     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   2608                         TOP_TS_PLL_RST_Lf, 1);
   2609     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   2610                         TOP_XG_PLL0_RST_Lf, 1);
   2611     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   2612                         TOP_XG_PLL1_RST_Lf, 1);
   2613 
   2614     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   2615 
   2616     /* Give time to lock */
   2617     sal_usleep(to_usec);
   2618 
   2619     /* De-assert TS PLL, BS PLL0/1 post reset and bring AVS out of reset */
   2620     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   2621     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   2622                        TOP_TS_PLL_POST_RST_Lf, 1);
   2623     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   2624                        TOP_XG_PLL0_POST_RST_Lf, 1);
   2625     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   2626                        TOP_XG_PLL1_POST_RST_Lf, 1);
   2627 
   2628     soc_reg_field_set(unit,TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 1);
   2629     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   2630 
   2631     sal_usleep(to_usec);
   2632 
   2633     /* Enable high temperature interrupt monitoring.
   2634      * Default on: pvtmon6 (close to core_plls at center of die).
   2635      */
   2636     temp_mask = soc_property_get(unit, "temp_monitor_select", 1<<6);
   2637     /* The above is a 9 bit mask to indicate which temp sensor to hook up to
   2638      * the interrupt.
   2639      */
   2640     rval = 0;
   2641     for (index = 0; index <COUNTOF(temp_thr_reg); index++) {
   2642         uint32 trval;
   2643 
   2644         /* Temp = 434.10 - o_ADC_data * 0.53504
   2645          * data = (434.10 - temp)/0.53504 = (434100-(temp*1000))/535
   2646          * Note: Since this is a high temp value we can safely assume it to
   2647          * always be a +ive number. This is in degrees celcius.
   2648          */
   2649         temp_thr = soc_property_get(unit, temp_thr_prop[index],
   2650                                     _SOC_HX5_TEMP_MAX);
   2651         if (temp_thr > _SOC_HX5_TEMP_MAX) {
   2652             LOG_ERROR(BSL_LS_SOC_COMMON,
   2653                       (BSL_META_U(unit,
   2654                           "Unsupported temp value %d !! Max %d. Using %d.\n"),
   2655                           temp_thr, _SOC_HX5_TEMP_MAX, _SOC_HX5_DEF_TEMP_MAX));
   2656             temp_thr = _SOC_HX5_DEF_TEMP_MAX;
   2657         }
   2658         /* Convert temperature to config data */
   2659         temp_thr = (434100-(temp_thr*1000))/535;
   2660         SOC_IF_ERROR_RETURN
   2661             (soc_reg32_get(unit, temp_thr_reg[index], REG_PORT_ANY, 0, &trval));
   2662         soc_reg_field_set(unit, temp_thr_reg[index], &trval, MIN_THRESHOLDf,
   2663                           temp_thr);
   2664         SOC_IF_ERROR_RETURN
   2665             (soc_reg32_set(unit, temp_thr_reg[index], REG_PORT_ANY, 0, trval));
   2666         if (temp_mask & (1 << index)) {
   2667             rval |= (1 << ((index * 2) + 1)); /* 2 bits per pvtmon, using min */
   2668         }
   2669     }
   2670     _soc_hx5_temp_mon_mask[unit] = temp_mask;
   2671 
   2672     SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_INTR_MASKr(unit, rval));
   2673     /* Enable temp mon interrupt */
   2674 #ifdef BCM_CMICX_SUPPORT
   2675     if (soc_feature(unit, soc_feature_cmicx)) {
   2676         
   2677         /* (void)soc_cmicm_intr3_enable(unit, 0x4); PVTMON_INTR bit 2 */
   2678     }
   2679 #endif
   2680 
   2681     /* Bring IP, EP, MMU and port macros out of reset */
   2682     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, 0x3fff));
   2683     sal_usleep(to_usec);
   2684 
   2685     /* PM4x10Q QSGMII mode control
   2686      */
   2687     reg = TOP_MISC_GENERIC_CONTROLr;
   2688     rval = 0;
   2689     if (soc_property_phys_port_get(unit, 1, spn_PORT_GMII_MODE, 0)) {
   2690         soc_reg_field_set(unit, reg, &rval, PM4X10Q_0_QSGMII_MODE_ENf, 0x1);
   2691         soc_reg_field32_modify(unit, CHIP_CONFIGr, 0, QMODEf, 1);
   2692     }
   2693     if (soc_property_phys_port_get(unit, 17, spn_PORT_GMII_MODE, 0)) {
   2694         soc_reg_field_set(unit, reg, &rval, PM4X10Q_1_QSGMII_MODE_ENf, 0x1);
   2695         soc_reg_field32_modify(unit, CHIP_CONFIGr, 1, QMODEf, 1);
   2696     }
   2697     if (soc_property_phys_port_get(unit, 33, spn_PORT_GMII_MODE, 0)) {
   2698         soc_reg_field_set(unit, reg, &rval, PM4X10Q_2_QSGMII_MODE_ENf, 0x1);
   2699         soc_reg_field32_modify(unit, CHIP_CONFIGr, 2, QMODEf, 1);
   2700     }
   2701     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   2702 
   2703     /* Reset egress hardware resource */
   2704     reg = SOC_REG_UNIQUE_ACC(unit, EGR_PORT_BUFFER_SFT_RESET_0r)[pipe];
   2705 
   2706     SOC_IF_ERROR_RETURN
   2707         (soc_reg64_get(unit, reg, REG_PORT_ANY, 0, &rval64));
   2708     for ( pm = 0; pm < sizeof(egr_reset_fields)/sizeof(soc_field_t); pm++) {
   2709         field = egr_reset_fields[pm];
   2710         fval = 4;
   2711         soc_reg64_field32_set(unit, reg, &rval64, field, fval);
   2712     }
   2713     /* Write the value to enable 4 lanes on the PM */
   2714     SOC_IF_ERROR_RETURN(soc_reg64_set(unit, reg, REG_PORT_ANY, 0, rval64));
   2715 
   2716     /* Set it back to zero now */
   2717     for ( pm = 0; pm < sizeof(egr_reset_fields)/sizeof(soc_field_t); pm++) {
   2718         field = egr_reset_fields[pm];
   2719         fval = 0;
   2720         soc_reg64_field32_set(unit, reg, &rval64, field, fval);
   2721     }
   2722     SOC_IF_ERROR_RETURN(soc_reg64_set(unit, reg, REG_PORT_ANY, 0, rval64));
   2723 
   2724     if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) {
   2725         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROL_64r,
   2726                                                    REG_PORT_ANY,
   2727                                                    IS_TDM_ECC_ENf,1));
   2728         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROL_64r,
   2729                                                    REG_PORT_ANY,
   2730                                                    CA_CPU_ECC_ENABLEf,1));
   2731         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROL_64r,
   2732                                                    REG_PORT_ANY,
   2733                                                    CA_LPBK_ECC_ENABLEf,1));
   2734     }
   2735 
   2736     SOC_IF_ERROR_RETURN(soc_trident3_init_idb_memory(unit));
   2737     SOC_IF_ERROR_RETURN(_soc_helix5_init_hash_control_reset(unit));
   2738     SOC_IF_ERROR_RETURN(soc_helix5_uft_uat_config(unit));
   2739     SOC_IF_ERROR_RETURN(_soc_helix5_ft_bank_config(unit));
   2740 
   2741     if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) {
   2742         SOC_IF_ERROR_RETURN(soc_trident3_clear_all_memory(unit));
   2743     }
   2744 
   2745     if (soc_feature(unit, soc_feature_turbo_boot)) {
   2746         uint32 def_val = 0;
   2747 
   2748         if (!(SOC_CONTROL(unit)->soc_flags & SOC_F_ALL_MODULES_INITED)) {
   2749             def_val = 1;
   2750         }
   2751         if (soc_property_get(unit, "clear_on_hw_resetting", def_val)) {
   2752             SOC_HW_RESET_START(unit);
   2753         }
   2754     }
   2755 
   2756 #ifdef BCM_HELIX5_SUPPORT
   2757     /* For HX5 A WAR is needed when reading 'CHIP_CONFIGr', since the fields
   2758        PMD_PLL_CTRL_REFLK_DIV2f/PMD_PLL_CTRL_REFLK_DIV4f are swapped (Write
   2759        into the register is fine)
   2760 
   2761        Here at init, based on the feature we enable the flag and also save
   2762        the the address of the register to use it when reg read is done */
   2763     if (soc_feature(unit, soc_feature_chip_config_read_war)) {
   2764         int block = 0;
   2765         uint8 access_type = 0;
   2766 
   2767         si->hx5_chip_config_war_enable = 1;
   2768         si->hx5_chip_config_address = -1;
   2769         si->hx5_chip_config_address = soc_reg_addr_get(unit,
   2770                                               CHIP_CONFIGr,
   2771                                               REG_PORT_ANY, 0,
   2772                                               SOC_REG_ADDR_OPTION_NONE,
   2773                                               &block, &access_type);
   2774         if (si->hx5_chip_config_address == -1) {
   2775             LOG_ERROR(BSL_LS_SOC_COMMON,
   2776                         (BSL_META_U(unit,
   2777                          "Config Error - Invalid address for"
   2778                          "CHIP_CONFIG reg\n")));
   2779                 return SOC_E_PARAM;
   2780         }
   2781     }
   2782 #endif
   2783 
   2784     return SOC_E_NONE;
   2785 }
   2786 
   2787 
   2788 #ifdef BCM_CMICX_SUPPORT
   2789 STATIC int
   2790 _soc_hx5_ledup_init(int unit)
   2791 {
   2792     soc_info_t *si = &SOC_INFO(unit);
   2793     int freq;
   2794     uint32 rval, clk_half_period, refresh_period;
   2795 
   2796     /* WAR: Let LED accumulation work. */
   2797     SOC_IF_ERROR_RETURN(READ_IPROC_WRAP_MISC_CONTROLr(unit, &rval));
   2798     soc_reg_field_set(unit, IPROC_WRAP_MISC_CONTROLr, &rval,
   2799                       IPROC_PM_RST_Lf, 1);
   2800     SOC_IF_ERROR_RETURN(WRITE_IPROC_WRAP_MISC_CONTROLr(unit, rval));
   2801 
   2802     /* freq in KHz */
   2803     freq = (si->frequency) * 1000;
   2804 
   2805     /* For LED refresh period = 33 ms (about 30Hz)  */
   2806 
   2807     /* refresh period
   2808      * = (required refresh period in sec)*(switch clock frequency in Hz)
   2809      */
   2810     refresh_period = (freq * 33);
   2811 
   2812     rval = 0;
   2813     soc_reg_field_set(unit, U0_LED_REFRESH_CTRLr, &rval,
   2814                       REFRESH_CYCLE_PERIODf, refresh_period);
   2815 
   2816     SOC_IF_ERROR_RETURN(WRITE_U0_LED_REFRESH_CTRLr(unit, rval));
   2817 
   2818     /* For LED clock period */
   2819     /* LEDCLK_HALF_PERIOD
   2820      *  = [(required LED clock period in sec)/2]*(M0SS clock frequency in Hz)
   2821      *
   2822      *  Where M0SS freqency is 858MHz and
   2823      *  Typical LED clock period is 200ns(5MHz) = 2*10^-7
   2824      */
   2825     freq = 858 * 1000000;
   2826     clk_half_period = (freq + 2500000) / 5000000;
   2827     clk_half_period = clk_half_period / 2;
   2828 
   2829     rval = 0;
   2830     soc_reg_field_set(unit, U0_LED_CLK_DIV_CTRLr, &rval,
   2831                       LEDCLK_HALF_PERIODf, clk_half_period);
   2832 
   2833     SOC_IF_ERROR_RETURN(WRITE_U0_LED_CLK_DIV_CTRLr(unit, rval));
   2834 
   2835 
   2836     SOC_IF_ERROR_RETURN(READ_U0_LED_ACCU_CTRLr(unit, &rval));
   2837 
   2838     /* Physical port 1 is the first port of TSC0 */
   2839     if (soc_property_phys_port_get(unit, PMQ0_FIRST_PHY_PORT, spn_PORT_GMII_MODE, 0)) {
   2840         /* If TSC0 in Q mode */
   2841         soc_reg_field_set(unit, U0_LED_ACCU_CTRLr, &rval,
   2842                           LAST_PORTf, 15);
   2843     } else {
   2844         /* If TSC0 in ethernet mode */
   2845         soc_reg_field_set(unit, U0_LED_ACCU_CTRLr, &rval,
   2846                           LAST_PORTf, 0);
   2847     }
   2848     SOC_IF_ERROR_RETURN(WRITE_U0_LED_ACCU_CTRLr(unit, rval));
   2849 
   2850     /* To initialize M0s for LED or Firmware Link Scan*/
   2851     if (soc_feature(unit, soc_feature_cmicx) && !(SAL_BOOT_PLISIM || SAL_BOOT_BCMSIM)) {
   2852         /* On Helix5 (iProc 16), M0 is needed to be rest as re-running rc.soc */
   2853         rval = 1;
   2854         SOC_IF_ERROR_RETURN(WRITE_U0_M0SS_CONTROLr(unit, rval));
   2855         sal_udelay(10);
   2856         SOC_IF_ERROR_RETURN(soc_iproc_m0_init(unit));
   2857     }
   2858     return SOC_E_NONE;
   2859 }
   2860 #endif /* BCM_CMICX_SUPPORT */
   2861 
   2862 STATIC int
   2863 _soc_helix5_misc_init(int unit)
   2864 {
   2865     soc_control_t *soc;
   2866     soc_info_t *si;
   2867     soc_mem_t mem;
   2868     uint64 rval64;
   2869     uint32 entry[SOC_MAX_MEM_WORDS], rval;
   2870     soc_pbmp_t pbmp;
   2871     int port;
   2872     int parity_enable;
   2873     modport_map_subport_entry_t map_entry;
   2874     soc_field_t fields[2];
   2875     uint32 values[2];
   2876 
   2877     uint32 mc_ctrl = 0;
   2878 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
   2879     int num_overlay_ecmp_rh_flowset_entries;
   2880     int ecmp_levels = 1;
   2881 #endif
   2882     int num_lag_rh_flowset_entries;
   2883     soc = SOC_CONTROL(unit);
   2884     si = &SOC_INFO(unit);
   2885 
   2886     /* Stop the mem scan task before all of the parity init takes place */
   2887     SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit));
   2888     SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_stop(unit));
   2889 
   2890     parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE);
   2891     if (parity_enable) {
   2892         if (!SOC_WARM_BOOT(unit)) {
   2893             /* Certain mems/regs need to be cleared before enabling SER */
   2894             SOC_IF_ERROR_RETURN(soc_trident3_clear_mmu_memory(unit));
   2895             /*SOC_IF_ERROR_RETURN(_soc_helix5_clear_all_port_data(unit));*/
   2896         }
   2897         soc_ser_alpm_cache_check(unit);
   2898         soc_ser_log_init(unit, NULL, 0);
   2899 
   2900         SOC_IF_ERROR_RETURN(soc_hx5_ser_enable_all(unit, TRUE));
   2901         soc_hx5_ser_register(unit);
   2902 
   2903         /*Initialize chip-specific functions for SER testing*/
   2904         soc_hx5_ser_test_register(unit);
   2905     }
   2906 
   2907     SOC_IF_ERROR_RETURN(_soc_trident3_init_mmu_memory(unit));
   2908     SOC_IF_ERROR_RETURN(READ_MMU_GCFG_MISCCONFIGr(unit, &rval));
   2909     soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, PARITY_ENf, parity_enable ? 1 : 0);
   2910     soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, REFRESH_ENf, 1);
   2911     SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval));
   2912 
   2913     if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) {
   2914         SOC_IF_ERROR_RETURN(
   2915             _soc_cancun_load_status_clear(unit, CANCUN_SOC_FILE_TYPE_CIH));
   2916         /* Dummy call to clear garbage h/w values */
   2917         SOC_IF_ERROR_RETURN
   2918             (soc_helix5_temperature_monitor_get(unit,
   2919                                                   COUNTOF(pvtmon_result_reg),
   2920                                                   NULL,
   2921                                                   NULL));
   2922     }
   2923 
   2924     SOC_IF_ERROR_RETURN(soc_helix5_uft_uat_config(unit));
   2925     SOC_IF_ERROR_RETURN(_soc_helix5_ft_bank_config(unit));
   2926 
   2927     soc_cancun_init(unit);
   2928     _soc_helix5_latency_config(unit);
   2929     SOC_IF_ERROR_RETURN(_soc_helix5_port_mapping_init(unit));
   2930 
   2931     if (!SAL_BOOT_XGSSIM) {
   2932         int rv;
   2933         soc_port_schedule_state_t *port_schedule_state;
   2934         if (soc->tdm_info == NULL) {
   2935             soc->tdm_info = sal_alloc(sizeof(_soc_helix5_tdm_temp_t),
   2936                                       "Helix5 TDM info");
   2937             if (soc->tdm_info == NULL) {
   2938                 return SOC_E_MEMORY;
   2939             }
   2940         }
   2941         port_schedule_state = sal_alloc(sizeof(soc_port_schedule_state_t),
   2942                                         "Helix5 soc_port_schedule_state_t");
   2943         if (port_schedule_state == NULL) {
   2944             return SOC_E_MEMORY;
   2945         }
   2946 
   2947         rv = _soc_helix5_tdm_init(unit, port_schedule_state);
   2948 
   2949         sal_free(port_schedule_state);
   2950         if (SOC_FAILURE(rv)) {
   2951             return rv;
   2952         }
   2953     }
   2954     SOC_IF_ERROR_RETURN(_soc_helix5_idb_init(unit));
   2955     SOC_IF_ERROR_RETURN(_soc_helix5_edb_init(unit));
   2956 
   2957     sal_memset(entry, 0, sizeof(cpu_pbm_entry_t));
   2958     soc_mem_pbmp_field_set(unit, CPU_PBMm, entry, BITMAPf, &PBMP_CMIC(unit));
   2959     SOC_IF_ERROR_RETURN
   2960         (soc_mem_write(unit, CPU_PBMm, MEM_BLOCK_ALL, 0, entry));
   2961 
   2962     sal_memset(entry, 0, sizeof(cpu_pbm_2_entry_t));
   2963     soc_mem_pbmp_field_set(unit, CPU_PBM_2m, entry, BITMAPf, &PBMP_CMIC(unit));
   2964     SOC_IF_ERROR_RETURN
   2965         (soc_mem_write(unit, CPU_PBM_2m, MEM_BLOCK_ALL, 0, entry));
   2966 
   2967 #if __GNUC__ > 6
   2968 #pragma GCC diagnostic push
   2969 #pragma GCC diagnostic ignored "-Wmemset-elt-size"
   2970 #endif
   2971     /*
   2972      * We are NOT doing a sal_memset(entry,0,sizeof(entry)) for
   2973      * performance reasons, because the actual soc_mem_field_set()
   2974      * will only write sizeof(device_loopback_ports_bitmap_entry_t)=17
   2975      * bytes while sizeof(entry)=SOC_MAX_MEM_BYTES can be up to 651
   2976      * depending on which devices are compiled in.
   2977      */
   2978     sal_memset(entry, 0, sizeof(device_loopback_ports_bitmap_entry_t));
   2979 #if __GNUC__ > 6
   2980 #pragma GCC diagnostic pop
   2981 #endif
   2982     soc_mem_pbmp_field_set(unit, DEVICE_LOOPBACK_PORTS_BITMAPm, entry, BITMAPf,
   2983                            &PBMP_LB(unit));
   2984     SOC_IF_ERROR_RETURN
   2985         (soc_mem_write(unit, DEVICE_LOOPBACK_PORTS_BITMAPm, MEM_BLOCK_ALL, 0,
   2986                        entry));
   2987 
   2988     PBMP_LB_ITER(unit, port) {
   2989         mem = SOC_MEM_UNIQUE_ACC(unit, MULTIPASS_LOOPBACK_BITMAPm)
   2990             [si->port_pipe[port]];
   2991         sal_memset(entry, 0, sizeof(multipass_loopback_bitmap_entry_t));
   2992         SOC_PBMP_PORT_SET(pbmp, port);
   2993         soc_mem_pbmp_field_set(unit, mem, &entry, BITMAPf, &pbmp);
   2994         SOC_IF_ERROR_RETURN
   2995             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 0, entry));
   2996     }
   2997 
   2998     sal_memset(entry, 0, sizeof(egr_ing_port_entry_t));
   2999     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1);
   3000     PBMP_HG_ITER(unit, port) {
   3001         SOC_IF_ERROR_RETURN
   3002             (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, port, entry));
   3003     }
   3004     SOC_IF_ERROR_RETURN
   3005         (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, si->cpu_hg_index,
   3006                        entry));
   3007     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 2);
   3008     PBMP_LB_ITER(unit, port) {
   3009         SOC_IF_ERROR_RETURN
   3010             (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, port, entry));
   3011     }
   3012 
   3013     /* Enable dual hash tables */
   3014     SOC_IF_ERROR_RETURN(soc_trident3_hash_init(unit));
   3015 
   3016     sal_memset(&map_entry, 0, sizeof(map_entry));
   3017     soc_mem_field32_set(unit, MODPORT_MAP_SUBPORTm, &map_entry, ENABLEf, 1);
   3018 
   3019     /* my_modid and other modid related initialization */
   3020     PBMP_ALL_ITER(unit, port) {
   3021         /* configure logical port numbers */
   3022         soc_mem_field32_set(unit, MODPORT_MAP_SUBPORTm, &map_entry,
   3023                             DESTf, port);
   3024         SOC_IF_ERROR_RETURN(WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ALL,
   3025                                                         port, &map_entry));
   3026     }
   3027 
   3028     /* setting up my_modid */
   3029     SOC_IF_ERROR_RETURN(READ_MY_MODID_SET_2_64r(unit, &rval64));
   3030 
   3031     soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64,
   3032                           MODID_0_VALIDf, 1);
   3033     soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64,
   3034                           MODID_0f, SOC_BASE_MODID(unit));
   3035 
   3036     SOC_IF_ERROR_RETURN(WRITE_MY_MODID_SET_2_64r(unit, rval64));
   3037 
   3038     SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &rval64));
   3039     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
   3040                           L3SRC_HIT_ENABLEf, 1);
   3041     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
   3042                           L2DST_HIT_ENABLEf, 1);
   3043     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
   3044                           APPLY_EGR_MASK_ON_L2f, 1);
   3045     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
   3046                           APPLY_EGR_MASK_ON_L3f, 1);
   3047     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
   3048                           ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */
   3049     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
   3050                           ARP_VALIDATION_ENf, 1);
   3051     if (soc_feature(unit, soc_feature_port_lag_failover)) {
   3052         soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
   3053                 IGNORE_HG_HDR_LAG_FAILOVERf, 0);
   3054     } else {
   3055     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
   3056                           IGNORE_HG_HDR_LAG_FAILOVERf, 1);
   3057     }
   3058     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
   3059                           APPLY_HG_MGID_ADJUSTf, 0xFF);
   3060 
   3061     SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, rval64));
   3062     /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which
   3063      * causes the outer tag to be removed from packets that don't have
   3064      * a hit in the egress vlan tranlation table. Set to 0 to disable this.
   3065      */
   3066     /* Programming EGR_VLAN_CONTROL_1m table */
   3067 #if 0
   3068     /* Can't call bcm function in soc layer. */
   3069     if (soc_feature(unit, soc_feature_egr_all_profile)) {
   3070         PBMP_ALL_ITER(unit, port) {
   3071             soc_field_t flds = {VT_MISS_UNTAGf, REMARK_OUTER_DOT1Pf};
   3072             uint32 vals = {0, 1};
   3073             BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_fields_set(unit,
   3074                 port, EGR_VLAN_CONTROL_1m, flds, vals);
   3075         }
   3076     }
   3077 #endif
   3078 
   3079     SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
   3080     SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit));
   3081     SOC_PBMP_REMOVE(pbmp, PBMP_FAE_ALL(unit));
   3082     SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm,
   3083                                      MEM_BLOCK_ANY, 0, &entry));
   3084     soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, BITMAPf,
   3085                            &pbmp);
   3086     SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm,
   3087                                       MEM_BLOCK_ANY, 0, &entry));
   3088 
   3089     /* Multicast range initialization */
   3090     SOC_IF_ERROR_RETURN
   3091         (soc_hbx_higig2_mcast_sizes_set(unit,
   3092              soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE,
   3093                               SOC_HBX_MULTICAST_RANGE_DEFAULT),
   3094              soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE,
   3095                               soc_mem_index_count(unit, L2MCm)),
   3096              soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE,
   3097                               soc_mem_index_count(unit, L3_IPMCm))));
   3098 
   3099     soc->mcast_size = soc_property_get(unit, spn_MULTICAST_L2_RANGE,
   3100                                         soc_mem_index_count(unit, L2MCm));
   3101     soc->ipmc_size =  soc_property_get(unit, spn_MULTICAST_L3_RANGE,
   3102                                         soc_mem_index_count(unit, L3_IPMCm));
   3103 
   3104     SOC_IF_ERROR_RETURN(READ_MC_CONTROL_4r(unit, &mc_ctrl));
   3105 
   3106     soc_reg_field_set(unit, MC_CONTROL_4r, &mc_ctrl,
   3107                       ALLOW_IPMC_INDEX_WRAP_AROUNDf, 1);
   3108     SOC_IF_ERROR_RETURN
   3109         (WRITE_MC_CONTROL_4r(unit, mc_ctrl));
   3110 
   3111     
   3112     _phy_tsce_firmware_set_helper[unit] = soc_trident3_tscx_firmware_set;
   3113     _phy_tscf_firmware_set_helper[unit] = soc_trident3_tscx_firmware_set;
   3114 
   3115     /* Check if Hierarchical ECMP mode is set */
   3116     if (soc_property_get(unit, spn_L3_ECMP_LEVELS, 1) == 2) {
   3117         uint32 rval = 0;
   3118         uint32 ecmp_mode = 1;
   3119         soc_reg_field_set(unit, ECMP_CONFIGr, &rval, ECMP_MODEf, ecmp_mode);
   3120         SOC_IF_ERROR_RETURN(WRITE_ECMP_CONFIGr(unit, rval));
   3121     } else {
   3122         uint32 rval = 0;
   3123         uint32 ecmp_mode = 0;
   3124         soc_reg_field_set(unit, ECMP_CONFIGr, &rval, ECMP_MODEf, ecmp_mode);
   3125         SOC_IF_ERROR_RETURN(WRITE_ECMP_CONFIGr(unit, rval));
   3126 
   3127     }
   3128     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROLr,
   3129                         REG_PORT_ANY, ECMP_FLOWSET_TABLE_CONFIGf, 1));
   3130 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
   3131     ecmp_levels = soc_property_get(unit, spn_L3_ECMP_LEVELS, 1);
   3132     if ((soc_feature(unit, soc_feature_riot) ||
   3133         soc_feature(unit, soc_feature_multi_level_ecmp)) &&
   3134         (ecmp_levels > 1) && soc_mem_index_count(unit,RH_ECMP_FLOWSETm)) {
   3135 
   3136         num_overlay_ecmp_rh_flowset_entries = soc_property_get(unit,
   3137                 spn_RIOT_OVERLAY_ECMP_RESILIENT_HASH_SIZE, 0);
   3138 
   3139         if (SOC_FIELD_RANGE_CHECK(
   3140             num_overlay_ecmp_rh_flowset_entries, 0, 16384)) {
   3141             num_overlay_ecmp_rh_flowset_entries = 16384;
   3142         }
   3143 
   3144         switch (num_overlay_ecmp_rh_flowset_entries) {
   3145             case 0:
   3146                 break;
   3147             case 16384:
   3148                 if (soc_mem_index_count(unit,RH_ECMP_FLOWSETm) >= 16384) {
   3149                     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
   3150                                         ENHANCED_HASHING_CONTROLr,
   3151                                         REG_PORT_ANY,
   3152                                         ECMP_FLOWSET_TABLE_CONFIGf, 2));
   3153                 } else {
   3154                     LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   3155                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   3156                     FUNCTION_NAME(),
   3157                     soc_mem_index_count(unit,RH_ECMP_FLOWSETm),
   3158                     num_overlay_ecmp_rh_flowset_entries));
   3159                     return SOC_E_CONFIG;
   3160                 }
   3161                 break;
   3162             default:
   3163                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   3164                     "%s: Value for overlay RH entries is not correct : %d \n"),
   3165                     FUNCTION_NAME(),  num_overlay_ecmp_rh_flowset_entries));
   3166                 return SOC_E_CONFIG;
   3167         }
   3168     }
   3169 #endif
   3170 
   3171     /* Setup SW2_IFP_DST_ACTION_CONTROLr */
   3172     fields[0] = HGTRUNK_RES_ENf;
   3173     values[0] = 1;
   3174     fields[1] = LAG_RES_ENf;
   3175     values[1] = 1;
   3176     SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit,
   3177                 SW2_IFP_DST_ACTION_CONTROLr, REG_PORT_ANY, 2, fields, values));
   3178 
   3179     /* Enhanced hashing  LAG/TRUNK config
   3180      * LAG/TRUNK share the same flow set table used in RH
   3181      * 32k is shared between LAG and HGT for
   3182      * - 16k each - default
   3183      * - 32K dedicated to HGT RH
   3184      * - 32K dedicated to LAG RH
   3185      */
   3186     num_lag_rh_flowset_entries = soc_property_get(unit,
   3187             spn_TRUNK_RESILIENT_HASH_TABLE_SIZE, 16384);
   3188 
   3189     switch (num_lag_rh_flowset_entries) {
   3190         case 0:
   3191             SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
   3192                                 ENHANCED_HASHING_CONTROL_2r,
   3193                                 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf,
   3194                                 1));
   3195             break;
   3196         case 32768:
   3197             SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
   3198                                 ENHANCED_HASHING_CONTROL_2r,
   3199                                 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf,
   3200                                 0));
   3201             break;
   3202         case 16384:
   3203             SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
   3204                                 ENHANCED_HASHING_CONTROL_2r,
   3205                                 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf,
   3206                                 2));
   3207             break;
   3208         default:
   3209             return SOC_E_CONFIG;
   3210     }
   3211     SOC_IF_ERROR_RETURN
   3212         (soc_counter_tomahawk_status_enable(unit, TRUE));
   3213 
   3214 #ifdef BCM_CMICX_SUPPORT
   3215     if (soc_feature(unit, soc_feature_cmicx) &&
   3216         !(SAL_BOOT_PLISIM || SAL_BOOT_BCMSIM))
   3217     {
   3218         SOC_IF_ERROR_RETURN(_soc_hx5_ledup_init(unit));
   3219     }
   3220 #endif /* BCM_CMICX_SUPPORT */
   3221 
   3222     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3223                 (BSL_META_U(unit,
   3224                             "MISC Init completed (u=%d)\n"), unit));
   3225 
   3226     /* Mem Scan thread start should be the last step in Misc init */
   3227     if (parity_enable) {
   3228         SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit));
   3229         SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_start(unit));
   3230     }
   3231 
   3232     return SOC_E_NONE;
   3233 }
   3234 
   3235 /*
   3236  * Function used for global resource reservation (MCQE / RQE / Buf cell).
   3237  * Input state: Total hardware resource.
   3238  * Output state: Resource available for admission control.
   3239  */
   3240 STATIC void
   3241 _soc_hx5_mmu_config_dev_reserve(int unit, _soc_mmu_device_info_t *devcfg,
   3242                                 int lossless)
   3243 {
   3244     int port, pm, asf_rsvd = 0;
   3245     uint32 total_mcq = 0, num_ports = 0;
   3246     uint32 cpu_cnt = 1, lb_cnt = 2, mgmt_cnt = 1;
   3247     soc_info_t *si = &SOC_INFO(unit);
   3248 
   3249     /* Device reservation for RQE Entry */
   3250     devcfg->total_rqe_queue_entry -= _HX5_MMU_RQE_ENTRY_RSVD_PER_XPE;
   3251 
   3252     /* Device reservation for MCQ Entry - 6 entries for each MC queue */
   3253     if (si->flex_eligible) {
   3254         for (pm = 0; pm < _HX5_PBLKS_PER_DEV(unit); pm++) {
   3255             num_ports += soc_hx5_ports_per_pm_get(unit, pm);
   3256         }
   3257         total_mcq += (num_ports * SOC_HX5_NUM_MCAST_QUEUE_PER_PORT);
   3258     } else {
   3259         PBMP_ALL_ITER(unit, port) {
   3260             if (IS_CPU_PORT(unit, port) ||
   3261                 IS_LB_PORT(unit,port) ||
   3262                 IS_MGMT_PORT(unit,port)) {
   3263                 continue;
   3264             }
   3265             total_mcq += si->port_num_cosq[port];
   3266         }
   3267     }
   3268     total_mcq += ((cpu_cnt * SOC_HX5_NUM_CPU_QUEUES) +
   3269                   (lb_cnt + mgmt_cnt) * SOC_HX5_NUM_MCAST_QUEUE_PER_PORT);
   3270 
   3271     devcfg->total_mcq_entry -= ((total_mcq * _HX5_MCQE_RSVD_PER_MCQ) +
   3272                                 _HX5_TDM_MCQE_RSVD_OVERSHOOT);
   3273 
   3274     devcfg->mmu_total_cell -= asf_rsvd;
   3275 }
   3276 
   3277 STATIC void
   3278 _soc_hx5_mmu_init_dev_config(int unit, _soc_mmu_device_info_t *devcfg,
   3279                              int lossless)
   3280 {
   3281     if (devcfg == NULL) {
   3282         LOG_FATAL(BSL_LS_SOC_COMMON,
   3283                  (BSL_META_U(unit,
   3284                             "MMU config data error\
   3285                             (u=%d)\n"), unit));
   3286         return;
   3287     }
   3288     sal_memset(devcfg, 0, sizeof(_soc_mmu_device_info_t));
   3289 
   3290     devcfg->max_pkt_byte = _HX5_MMU_MAX_PACKET_BYTES;
   3291     devcfg->mmu_hdr_byte = _HX5_MMU_PACKET_HEADER_BYTES;
   3292     devcfg->jumbo_pkt_size = _HX5_MMU_JUMBO_FRAME_BYTES;
   3293     devcfg->default_mtu_size = _HX5_MMU_DEFAULT_MTU_BYTES;
   3294     devcfg->mmu_cell_size = _HX5_MMU_BYTES_PER_CELL;
   3295     devcfg->mmu_total_cell = _HX5_MMU_TOTAL_CELLS_PER_XPE;
   3296     devcfg->num_pg = _HX5_MMU_NUM_PG;
   3297     devcfg->num_service_pool = _HX5_MMU_NUM_POOL;
   3298     devcfg->flags = SOC_MMU_CFG_F_PORT_MIN | SOC_MMU_CFG_F_PORT_POOL_MIN |
   3299                     SOC_MMU_CFG_F_RQE | SOC_MMU_CFG_F_EGR_MCQ_ENTRY;
   3300     devcfg->total_mcq_entry = _HX5_MMU_TOTAL_MCQ_ENTRY(unit);
   3301     devcfg->rqe_queue_num = 11;
   3302     devcfg->total_rqe_queue_entry = _HX5_MMU_TOTAL_RQE_ENTRY(unit);
   3303 
   3304     _soc_hx5_mmu_config_dev_reserve(unit, devcfg, lossless);
   3305 }
   3306 
   3307 STATIC void
   3308 _soc_hx5_mmu_sw_info_config (int unit, _soc_hx5_mmu_sw_config_info_t * swcfg,
   3309                              int lossless)
   3310 {
   3311     /* Default settings is lossless */
   3312     swcfg->mmu_egr_queue_min = 0;
   3313     swcfg->mmu_egr_qgrp_min = 0;
   3314     swcfg->mmu_total_pri_groups = 8;
   3315     swcfg->mmu_active_pri_groups = 1;
   3316     swcfg->mmu_pg_min = 7;
   3317     swcfg->mmu_port_min = 0;
   3318     swcfg->mmu_mc_egr_qentry_min = 4;
   3319     swcfg->mmu_rqe_qentry_min = 8;
   3320     swcfg->mmu_rqe_queue_min = 7;
   3321     if (lossless == 0)
   3322     {
   3323         swcfg->mmu_egr_queue_min = 7;
   3324         swcfg->mmu_egr_qgrp_min = 14;
   3325         swcfg->mmu_pg_min = 0;
   3326     }
   3327 }
   3328 
   3329 STATIC int
   3330 _soc_hx5_default_pg_headroom(int unit, soc_port_t port,
   3331                             int lossless)
   3332 {
   3333     int speed = 1000, hdrm = 0;
   3334     uint8 port_oversub = 0;
   3335 
   3336     if (IS_CPU_PORT(unit, port)) {
   3337         return 69;
   3338     } else if (!lossless) {
   3339         return 0;
   3340     } else if (IS_LB_PORT(unit, port)) {
   3341         return 160;
   3342     }
   3343 
   3344     speed = SOC_INFO(unit).port_speed_max[port];
   3345 
   3346     if (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port)) {
   3347         port_oversub = 1;
   3348     }
   3349     if (speed <= 1000) {
   3350         hdrm = 118;
   3351     } else if (speed == 2500) {
   3352         hdrm = 120;
   3353     }else if ((speed > 2500) && (speed <= 11000)) {
   3354         hdrm = port_oversub ? 194 : 160;
   3355     } else if ((speed > 11000) && (speed <= 21000)) {
   3356         hdrm = port_oversub ? 251 : 197;
   3357     } else if ((speed > 21000) && (speed <= 27000)) {
   3358         hdrm = port_oversub ? 308 : 254;
   3359     } else if ((speed > 27000) && (speed <= 42000)) {
   3360         hdrm = port_oversub ? 402 : 273;
   3361     } else if ((speed > 42000) && (speed <= 53000)) {
   3362         hdrm = port_oversub ? 431 : 350;
   3363     } else if (speed >= 100000) {
   3364         hdrm = port_oversub ? 766 : 572;
   3365     } else {
   3366         hdrm = port_oversub ? 194 : 160;
   3367     }
   3368     return hdrm;
   3369 }
   3370 
   3371 /*
   3372  * Default phase_1 MMU settings about headroom, guarantee, dynamic, color, ...
   3373  * which depend on single port/queue/qgroup/pg...
   3374  * Input state: Available for admission in devcfg, configured swcfg.
   3375  * Output state: Independent data filled in buf.
   3376  * Version 1.1
   3377  */
   3378 STATIC void
   3379 _soc_hx5_mmu_config_buf_phase1(int unit, _soc_mmu_cfg_buf_t *buf,
   3380                                _soc_mmu_device_info_t *devcfg,
   3381                                _soc_hx5_mmu_sw_config_info_t *swcfg,
   3382                                int lossless)
   3383 {
   3384     soc_info_t *si;
   3385     _soc_mmu_cfg_buf_pool_t *buf_pool;
   3386     _soc_mmu_cfg_buf_port_t *buf_port;
   3387     _soc_mmu_cfg_buf_port_pool_t *buf_port_pool;
   3388     _soc_mmu_cfg_buf_prigroup_t *buf_prigroup;
   3389     _soc_mmu_cfg_buf_queue_t *buf_queue;
   3390     _soc_mmu_cfg_buf_qgroup_t *queue_grp;
   3391     _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue;
   3392     int max_packet_cells, default_mtu_cells;
   3393     int port, idx;
   3394     int total_pool_size = 0, asf_rsvd = 0;
   3395     int rqe_entry_shared_total, qmin;
   3396 
   3397     si = &SOC_INFO(unit);
   3398 
   3399     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3400                 (BSL_META_U(unit,
   3401                             "Initializing default MMU config phase 1(u=%d)\n"), unit));
   3402     max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte +
   3403                                                    devcfg->mmu_hdr_byte,
   3404                                                    devcfg->mmu_cell_size);
   3405     default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size +
   3406                                                    devcfg->mmu_hdr_byte,
   3407                                                    devcfg->mmu_cell_size);
   3408 
   3409     total_pool_size = devcfg->mmu_total_cell + asf_rsvd; /* Add back ASF reserved. */
   3410 
   3411     buf->headroom = max_packet_cells;   /* 1 packet per pipe. */
   3412 
   3413     rqe_entry_shared_total = devcfg->total_rqe_queue_entry -
   3414         (_HX5_MMU_NUM_RQE_QUEUES * swcfg->mmu_rqe_qentry_min);
   3415 
   3416     for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   3417         buf_pool = &buf->pools[idx];
   3418         if (idx == 0) {  /* 100% scale up by 100 */
   3419             buf_pool->size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
   3420             buf_pool->yellow_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
   3421             buf_pool->red_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
   3422             buf_pool->total_mcq_entry = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
   3423             buf_pool->total_rqe_entry = rqe_entry_shared_total;
   3424         } else {
   3425             buf_pool->size = 0;
   3426             buf_pool->yellow_size = 0;
   3427             buf_pool->red_size = 0;
   3428             buf_pool->total_mcq_entry = 0;
   3429             buf_pool->total_rqe_entry = 0;
   3430         }
   3431     }
   3432 
   3433     for (idx = 0; idx < SOC_HX5_MMU_CFG_QGROUP_MAX; idx++) {
   3434         queue_grp = &buf->qgroups[idx];
   3435         /* resume limits - accounted for 8 cell granularity */
   3436         queue_grp->pool_resume = 16;
   3437         queue_grp->yellow_resume = 16;
   3438         queue_grp->red_resume = 16;
   3439         queue_grp->guarantee = swcfg->mmu_egr_qgrp_min;
   3440         if (lossless) {
   3441             queue_grp->discard_enable = 0;
   3442         } else {
   3443             queue_grp->discard_enable = 1;
   3444         }
   3445     }
   3446 
   3447     PBMP_ALL_ITER(unit, port) {
   3448         if (port >= SOC_MMU_CFG_PORT_MAX) {
   3449             break;
   3450         }
   3451         buf_port = &buf->ports[port];
   3452 
   3453         /* internal priority to priority group mapping */
   3454         for (idx = 0; idx < _HX5_MMU_NUM_INT_PRI; idx++) {
   3455             buf_port->pri_to_prigroup[idx] = 7;
   3456         }
   3457 
   3458         /* priority group to pool mapping */
   3459         for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) {
   3460             buf_port->prigroups[idx].pool_idx = 0;
   3461         }
   3462 
   3463         for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   3464             buf_port_pool = &buf_port->pools[idx];
   3465             buf_port_pool->guarantee = 0;
   3466             buf_port_pool->pool_limit = 0;
   3467             buf_port_pool->pool_resume = 0;
   3468             if (idx == 0) {
   3469                 buf_port_pool->pool_limit = total_pool_size;
   3470                 buf_port_pool->pool_resume = total_pool_size -
   3471                                              (default_mtu_cells * 2);
   3472             }
   3473         }
   3474 
   3475         buf_port->pkt_size = max_packet_cells;
   3476 
   3477         /* priority group */
   3478         for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) {
   3479             buf_prigroup = &buf_port->prigroups[idx];
   3480             buf_prigroup->guarantee = 0;
   3481             buf_prigroup->user_delay = -1;
   3482             buf_prigroup->switch_delay = -1;
   3483             buf_prigroup->pkt_size = max_packet_cells;
   3484             buf_prigroup->device_headroom_enable = 0;
   3485             buf_prigroup->pool_floor = 0;
   3486             buf_prigroup->headroom = 0;
   3487             buf_prigroup->pool_resume = 0;
   3488             buf_prigroup->flow_control_enable = 0;
   3489             if (idx == 7) {
   3490                 buf_prigroup->device_headroom_enable = 1;
   3491                 buf_prigroup->flow_control_enable = lossless;
   3492                 buf_prigroup->headroom =
   3493                     _soc_hx5_default_pg_headroom(unit, port, lossless);
   3494                 if (lossless) {
   3495                     buf_prigroup->guarantee = swcfg->mmu_pg_min;
   3496                 }
   3497             }
   3498         }
   3499 
   3500         /* multicast queue */
   3501         if (IS_CPU_PORT(unit, port) ||
   3502             IS_LB_PORT(unit,port)) {
   3503             qmin = swcfg->mmu_egr_queue_min;
   3504         } else {
   3505             qmin = 0;
   3506         }
   3507         for (idx = 0; idx < si->port_num_cosq[port]; idx++) {
   3508             buf_queue = &buf_port->queues[idx];
   3509             buf_queue->qgroup_id = -1;
   3510             buf_queue->guarantee = qmin;
   3511             buf_queue->mcq_entry_guarantee = swcfg->mmu_mc_egr_qentry_min;
   3512             buf_queue->color_discard_enable = 0;
   3513             if (lossless) {
   3514                 buf_queue->discard_enable = 0;
   3515                 /* resume limits - accounted for 8 cell granularity */
   3516                 buf_queue->pool_resume = 16;
   3517             } else {
   3518                 buf_queue->discard_enable = 1;
   3519                 /* resume limits - accounted for 8 cell granularity */
   3520                 buf_queue->pool_resume = 16;
   3521             }
   3522         }
   3523 
   3524         /* unicast queue */
   3525         for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) {
   3526             buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx];
   3527             buf_queue->qgroup_id = -1;
   3528             buf_queue->guarantee = 0;
   3529             buf_queue->color_discard_enable = 0;
   3530             buf_queue->qgroup_min_enable = 1;
   3531             buf_queue->discard_enable = 1;
   3532             buf_queue->qgroup_id = 0;
   3533             if (lossless) {
   3534                 buf_queue->discard_enable = 0;
   3535                 /* resume limits - accounted for 8 cell granularity */
   3536                 buf_queue->pool_resume = 16;
   3537                 buf_queue->yellow_resume = 16;
   3538                 buf_queue->red_resume = 16;
   3539             } else {
   3540                 /* resume limits - accounted for 8 cell granularity */
   3541                 buf_queue->pool_resume = 16;
   3542                 buf_queue->yellow_resume = 16;
   3543                 buf_queue->red_resume = 16;
   3544             }
   3545         }
   3546 
   3547         /* queue to pool mapping */
   3548         for (idx = 0;
   3549              idx < si->port_num_cosq[port] + si->port_num_uc_cosq[port]; idx++) {
   3550             buf_port->queues[idx].pool_idx = 0;
   3551         }
   3552     }
   3553 
   3554     /* RQE */
   3555     for (idx = 0; idx < _HX5_MMU_NUM_RQE_QUEUES; idx++) {
   3556         buf_rqe_queue = &buf->rqe_queues[idx];
   3557         buf_rqe_queue->pool_idx = 0;
   3558         buf_rqe_queue->guarantee = swcfg->mmu_rqe_queue_min;
   3559         if (lossless) {
   3560             buf_rqe_queue->discard_enable = 0;
   3561         } else {
   3562             buf_rqe_queue->discard_enable = 1;
   3563         }
   3564     }
   3565 }
   3566 
   3567 /*
   3568  * Default phase_2 MMU settings about shared buffer limit, which depends on
   3569  * guaranteed/headroom buffers on all port/queue/qgroup/pg/...
   3570  * Input state: _soc_mmu_cfg_buf_calculate processed buf.
   3571  * Output state: All necessary data filled in buf.
   3572  * Version 1.1
   3573  */
   3574 STATIC void
   3575 _soc_hx5_mmu_config_buf_phase2(int unit, _soc_mmu_cfg_buf_t *buf,
   3576                                _soc_mmu_device_info_t *devcfg,
   3577                                _soc_hx5_mmu_sw_config_info_t *swcfg,
   3578                                int lossless)
   3579 {
   3580     soc_info_t *si;
   3581     _soc_mmu_cfg_buf_pool_t *buf_pool;
   3582     _soc_mmu_cfg_buf_port_t *buf_port;
   3583     _soc_mmu_cfg_buf_prigroup_t *buf_prigroup;
   3584     _soc_mmu_cfg_buf_queue_t *buf_queue;
   3585     _soc_mmu_cfg_buf_qgroup_t *queue_grp;
   3586     _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue;
   3587     int port, idx, pm, ports[3] = {0};
   3588     int pg_hdrm_ob[] = {690, 372, 240}; /* PG headroom of 1/2/4-port PortMacro */
   3589     int total_pool_size = 0;
   3590     int ing_rsvd_total = 0, egr_rsvd_total = 0;
   3591     int ing_shared_total, egr_shared_total;
   3592     int total_rsvd_qmin = 0;
   3593     uint32 color_limit = 0;
   3594     uint32 num_ports = 0, mgmt_cnt = 0, cpu_cnt = 0, lb_cnt = 0;
   3595     uint32 cpu_hdrm = 0, lb_hdrm = 0, mgmt_hdrm = 0;
   3596 
   3597     si = &SOC_INFO(unit);
   3598 
   3599     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   3600                 (BSL_META_U(unit,
   3601                             "Initializing default MMU config phase 2(u=%d)\n"), unit));
   3602 
   3603     buf_pool = &buf->pools[0];
   3604     total_pool_size = devcfg->mmu_total_cell; /* per XPE limit */
   3605     total_rsvd_qmin = swcfg->mmu_egr_queue_min * (SOC_HX5_NUM_CPU_QUEUES +
   3606                         _HX5_MMU_NUM_LBK_QUEUES );
   3607 
   3608     PBMP_ALL_ITER(unit, port) {
   3609         if (IS_CPU_PORT(unit, port)) {
   3610             cpu_cnt++;
   3611             cpu_hdrm = _soc_hx5_default_pg_headroom(unit, port, lossless);
   3612         } else if (IS_LB_PORT(unit,port)) {
   3613             lb_cnt++;
   3614             lb_hdrm = _soc_hx5_default_pg_headroom(unit, port, lossless);
   3615         } else {
   3616             num_ports++;
   3617         }
   3618     }
   3619     if (si->flex_eligible) {
   3620         num_ports = 0;
   3621         for (pm = 0; pm < _HX5_PBLKS_PER_DEV(unit); pm++) {
   3622             port = soc_hx5_ports_per_pm_get(unit, pm);
   3623             if (port == 1) {
   3624                 ports[0]++;
   3625             } else if (port == 2) {
   3626                 ports[1]++;
   3627            } else if ((port == 4) || (port == 3)) {
   3628                 ports[2]++;
   3629                 port = 4;
   3630             }
   3631             num_ports += port;
   3632         }
   3633 
   3634         if (lossless) {
   3635             ing_rsvd_total += (buf->headroom +
   3636                 swcfg->mmu_active_pri_groups*(
   3637                 ports[0]*pg_hdrm_ob[0] + 2*ports[1]*pg_hdrm_ob[1] +
   3638                 4*ports[2]*pg_hdrm_ob[2] + cpu_cnt*cpu_hdrm + lb_cnt*lb_hdrm) +
   3639                 swcfg->mmu_pg_min*swcfg->mmu_active_pri_groups*(
   3640                 num_ports + cpu_cnt + lb_cnt + mgmt_cnt) +
   3641                 swcfg->mmu_port_min*swcfg->mmu_active_pri_groups*(
   3642                 num_ports + cpu_cnt + lb_cnt + mgmt_cnt));
   3643             /* Management port is not included during Total PG
   3644              * headroom calculation */
   3645             buf_pool->prigroup_headroom -= mgmt_hdrm;
   3646         } else {
   3647             ing_rsvd_total += buf->headroom + cpu_hdrm;
   3648         }
   3649     } else {
   3650         if (lossless) {
   3651             /* Management port is not included during Total PG
   3652              * headroom calculation */
   3653             buf_pool->prigroup_headroom -= mgmt_hdrm;
   3654         }
   3655         ing_rsvd_total += (buf->headroom + buf_pool->prigroup_headroom +
   3656                            buf_pool->prigroup_guarantee);
   3657     }
   3658 
   3659     egr_rsvd_total += total_rsvd_qmin +
   3660                        ((num_ports + mgmt_cnt) * swcfg->mmu_egr_qgrp_min) +
   3661                        (swcfg->mmu_rqe_queue_min * _HX5_MMU_NUM_RQE_QUEUES);
   3662 
   3663     if (lossless) {
   3664         ing_rsvd_total += egr_rsvd_total;
   3665     }
   3666 
   3667     buf_pool->total_mcq_entry = _HX5_MMU_TOTAL_MCQ_ENTRY(unit) -
   3668                                  (_HX5_MAX_MMU_MCQE_PER_XPE * _HX5_MCQE_RSVD_PER_MCQ) -
   3669                                  _HX5_TDM_MCQE_RSVD_OVERSHOOT;
   3670 
   3671     buf_pool->mcq_entry_reserved = _HX5_MAX_MMU_MCQE_PER_XPE * 4;
   3672 
   3673 
   3674     ing_shared_total = total_pool_size - ing_rsvd_total;
   3675     egr_shared_total = total_pool_size - egr_rsvd_total;
   3676 
   3677     swcfg->ing_shared_total = ing_shared_total;
   3678     swcfg->egr_shared_total = egr_shared_total;
   3679 
   3680     LOG_VERBOSE(BSL_LS_SOC_MMU,
   3681                 (BSL_META_U(unit,
   3682                             "MMU config: Total Shared size: ingress %d egress %d\n"),
   3683                             ing_shared_total, egr_shared_total));
   3684 
   3685     color_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
   3686 
   3687     for (idx = 0; idx < SOC_HX5_MMU_CFG_QGROUP_MAX; idx++) {
   3688         queue_grp = &buf->qgroups[idx];
   3689         if (lossless) {
   3690             queue_grp->pool_scale = -1;
   3691             queue_grp->pool_limit = egr_shared_total;
   3692             queue_grp->red_limit = egr_shared_total;
   3693             queue_grp->yellow_limit = egr_shared_total;
   3694         } else {
   3695             queue_grp->pool_scale = 8;
   3696             queue_grp->pool_limit = 0;
   3697             queue_grp->red_limit = color_limit;
   3698             queue_grp->yellow_limit = color_limit;
   3699         }
   3700     }
   3701 
   3702     PBMP_ALL_ITER(unit, port) {
   3703         if (port >= SOC_MMU_CFG_PORT_MAX) {
   3704             break;
   3705         }
   3706         buf_port = &buf->ports[port];
   3707 
   3708         /* priority group */
   3709         for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) {
   3710             buf_prigroup = &buf_port->prigroups[idx];
   3711             buf_prigroup->pool_limit = 0;
   3712             buf_prigroup->pool_scale = -1;
   3713             if (idx == 7) {
   3714                 if (lossless) {
   3715                     buf_prigroup->pool_scale = 8;
   3716                 } else {
   3717                     buf_prigroup->pool_limit = ing_shared_total;
   3718                 }
   3719             }
   3720         }
   3721 
   3722         /* multicast queue */
   3723         for (idx = 0; idx < si->port_num_cosq[port]; idx++) {
   3724             buf_queue = &buf_port->queues[idx];
   3725             if (lossless) {
   3726                 buf_queue->pool_scale = -1;
   3727                 buf_queue->pool_limit = egr_shared_total;
   3728                 buf_queue->yellow_limit = egr_shared_total;
   3729                 buf_queue->red_limit = egr_shared_total;
   3730             } else {
   3731                 buf_queue->pool_scale = 8;
   3732                 buf_queue->pool_limit = 0;
   3733                 buf_queue->yellow_limit = color_limit;
   3734                 buf_queue->red_limit = color_limit;
   3735             }
   3736         }
   3737 
   3738         /* unicast queue */
   3739         for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) {
   3740             buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx];
   3741             if (lossless) {
   3742                 buf_queue->pool_scale = -1;
   3743                 buf_queue->pool_limit = egr_shared_total;
   3744                 buf_queue->red_limit = egr_shared_total;
   3745                 buf_queue->yellow_limit = egr_shared_total;
   3746             } else {
   3747                 buf_queue->pool_scale = 8;
   3748                 buf_queue->pool_limit = 0;
   3749                 buf_queue->red_limit = color_limit;
   3750                 buf_queue->yellow_limit = color_limit;
   3751             }
   3752         }
   3753     }
   3754 
   3755     /* RQE */
   3756     for (idx = 0; idx < _HX5_MMU_NUM_RQE_QUEUES; idx++) {
   3757         buf_rqe_queue = &buf->rqe_queues[idx];
   3758         if (lossless) {
   3759             buf_rqe_queue->pool_scale = -1;
   3760             buf_rqe_queue->pool_limit = egr_shared_total;
   3761             buf_rqe_queue->red_limit = egr_shared_total;
   3762             buf_rqe_queue->yellow_limit = egr_shared_total;
   3763         } else {
   3764             buf_rqe_queue->pool_scale = 8;
   3765             buf_rqe_queue->pool_limit = 0;
   3766             buf_rqe_queue->red_limit = color_limit;
   3767             buf_rqe_queue->yellow_limit = color_limit;
   3768         }
   3769     }
   3770 }
   3771 
   3772 STATIC int
   3773 _soc_hx5_pool_scale_to_limit(int size, int scale)
   3774 {
   3775     int factor = 1000;
   3776 
   3777     switch (scale) {
   3778         case 7: factor = 875; break;
   3779         case 6: factor = 750; break;
   3780         case 5: factor = 625; break;
   3781         case 4: factor = 500; break;
   3782         case 3: factor = 375; break;
   3783         case 2: factor = 250; break;
   3784         case 1: factor = 125; break;
   3785         case 0:
   3786         default:
   3787             factor = 1000; break;
   3788     }
   3789     return (size * factor)/1000;
   3790 }
   3791 
   3792 STATIC int
   3793 _soc_hx5_mmu_config_buf_set_hw_port(int unit, int port, _soc_mmu_cfg_buf_t *buf,
   3794                                _soc_mmu_device_info_t *devcfg, int lossless,
   3795                                _soc_hx5_mmu_sw_config_info_t *swcfg)
   3796 {
   3797     soc_info_t *si;
   3798     _soc_mmu_cfg_buf_pool_t *buf_pool;
   3799     _soc_mmu_cfg_buf_port_t *buf_port;
   3800     _soc_mmu_cfg_buf_port_pool_t *buf_port_pool;
   3801     thdi_port_sp_config_entry_t thdi_sp_config;
   3802     thdi_port_pg_config_entry_t pg_config_mem;
   3803     _soc_mmu_cfg_buf_prigroup_t *buf_prigroup;
   3804     _soc_mmu_cfg_buf_queue_t *buf_queue;
   3805     uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS];
   3806     soc_reg_t reg = INVALIDr;
   3807     soc_mem_t mem0, mem1, mem2, mem3;
   3808     uint32 fval, rval;
   3809     int base, numq, enable;
   3810     int idx, midx, pri, index1;
   3811     int default_mtu_cells, limit, rlimit;
   3812     int pipe;
   3813 
   3814     static const soc_mem_t mmu_thdi_port_mem[] = {
   3815         THDI_PORT_SP_CONFIGm,
   3816         THDI_PORT_PG_CONFIGm
   3817     };
   3818     static const soc_mem_t mmu_thdo_q_uc_mem[] = {
   3819         MMU_THDU_CONFIG_QUEUEm,
   3820         MMU_THDU_OFFSET_QUEUEm,
   3821         MMU_THDU_Q_TO_QGRP_MAPm
   3822     };
   3823     static const soc_mem_t mmu_thdo_port_uc_mem[] = {
   3824         MMU_THDU_CONFIG_PORTm,
   3825         MMU_THDU_RESUME_PORTm
   3826     };
   3827     static const soc_mem_t mmu_thdo_q_mc_mem[] = {
   3828         MMU_THDM_DB_QUEUE_CONFIGm,
   3829         MMU_THDM_DB_QUEUE_OFFSETm,
   3830         MMU_THDM_MCQE_QUEUE_CONFIGm,
   3831         MMU_THDM_MCQE_QUEUE_OFFSETm
   3832     };
   3833 
   3834     static const soc_mem_t mmu_thdo_port_mc_mem[] = {
   3835         MMU_THDM_DB_PORTSP_CONFIGm,
   3836         MMU_THDM_MCQE_PORTSP_CONFIGm
   3837     };
   3838 
   3839     static const soc_field_t prigroup_reg[] = {
   3840         THDI_PORT_PRI_GRP0r, THDI_PORT_PRI_GRP1r
   3841     };
   3842     static const soc_field_t prigroup_field[] = {
   3843         PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf,
   3844         PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf,
   3845         PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf,
   3846         PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf
   3847     };
   3848     static const soc_field_t prigroup_spid_field[] = {
   3849         PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf,
   3850         PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf
   3851     };
   3852 
   3853     si = &SOC_INFO(unit);
   3854     default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size +
   3855                                                    devcfg->mmu_hdr_byte,
   3856                                                    devcfg->mmu_cell_size);
   3857 
   3858     /* internal priority to priority group mapping */
   3859     buf_port = &buf->ports[port];
   3860 
   3861     for (idx = 0; idx < COUNTOF(prigroup_field); idx++) {
   3862         if (idx % 8 == 0) { /* 8 fields per register */
   3863             reg = prigroup_reg[idx / 8];
   3864             rval = 0;
   3865         }
   3866         soc_reg_field_set(unit, reg, &rval, prigroup_field[idx],
   3867                 buf_port->pri_to_prigroup[idx]);
   3868         if (idx % 8 == 7) { /* 8 fields per register */
   3869             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   3870         }
   3871     }
   3872 
   3873     /* Input port per port settings */
   3874     pipe = si->port_pipe[port];
   3875     buf_port = &buf->ports[port];
   3876     rval = 0;
   3877     for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) {
   3878         soc_reg_field_set(unit, THDI_PORT_PG_SPIDr, &rval,
   3879                           prigroup_spid_field[idx],
   3880                           buf_port->prigroups[idx].pool_idx);
   3881     }
   3882     SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_PG_SPIDr(unit, port, rval));
   3883 
   3884     /* Per port per pool settings */
   3885     mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdi_port_mem[0])[pipe];
   3886     if (mem0 != INVALIDm) {
   3887         for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   3888             buf_port_pool = &buf_port->pools[idx];
   3889             midx = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mmu_thdi_port_mem[0],
   3890                                                idx);
   3891             sal_memset(&thdi_sp_config, 0, sizeof(thdi_sp_config));
   3892             soc_mem_field32_set(unit, mem0, &thdi_sp_config,
   3893                                 PORT_SP_MIN_LIMITf, buf_port_pool->guarantee);
   3894             soc_mem_field32_set(unit, mem0, &thdi_sp_config,
   3895                             PORT_SP_RESUME_LIMITf, buf_port_pool->pool_resume);
   3896             soc_mem_field32_set(unit, mem0, &thdi_sp_config,
   3897                                 PORT_SP_MAX_LIMITf, buf_port_pool->pool_limit);
   3898             SOC_IF_ERROR_RETURN
   3899                 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL,
   3900                                midx, &thdi_sp_config));
   3901         }
   3902     }
   3903 
   3904     fval = 0;
   3905     for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) {
   3906         if (buf_port->prigroups[idx].flow_control_enable != 0) {
   3907             for (pri=0; pri < 16; pri++) {
   3908                 if (buf_port->pri_to_prigroup[pri] == idx) {
   3909                     fval |= 1 << pri;
   3910                 }
   3911             }
   3912         }
   3913     }
   3914 
   3915     rval = 0;
   3916     soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
   3917                       INPUT_PORT_RX_ENABLEf, 1);
   3918     if (port == CMIC_PORT (unit)) {
   3919         fval = 0;
   3920     }
   3921     soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
   3922                       PORT_PRI_XON_ENABLEf, fval);
   3923     soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
   3924                       PORT_PAUSE_ENABLEf, fval ? 1 : 0);
   3925     SOC_IF_ERROR_RETURN(WRITE_THDI_INPUT_PORT_XON_ENABLESr(unit,
   3926                         port, rval));
   3927 
   3928     rval = 0;
   3929     soc_reg_field_set(unit, THDI_PORT_MAX_PKT_SIZEr, &rval,
   3930                       PORT_MAX_PKT_SIZEf, buf_port->pkt_size);
   3931     SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_MAX_PKT_SIZEr(unit, rval));
   3932 
   3933     /* Input port per port per priority group settings */
   3934     mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdi_port_mem[1])[pipe];
   3935     if (mem1 != INVALIDm) {
   3936         for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) {
   3937             buf_prigroup = &buf->ports[port].prigroups[idx];
   3938 
   3939             midx = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mmu_thdi_port_mem[1],
   3940                                                idx);
   3941             sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem));
   3942             soc_mem_field32_set(unit, mem1, &pg_config_mem,
   3943                                 PG_MIN_LIMITf, buf_prigroup->guarantee);
   3944 
   3945             if (buf_prigroup->pool_scale != -1) {
   3946                 soc_mem_field32_set(unit, mem1, &pg_config_mem,
   3947                                     PG_SHARED_DYNAMICf, 1);
   3948                 soc_mem_field32_set(unit, mem1, &pg_config_mem,
   3949                                     PG_SHARED_LIMITf,
   3950                                     buf_prigroup->pool_scale);
   3951             } else {
   3952                 soc_mem_field32_set(unit, mem1, &pg_config_mem,
   3953                                     PG_SHARED_LIMITf,
   3954                                     buf_prigroup->pool_limit);
   3955             }
   3956 
   3957             soc_mem_field32_set(unit, mem1, &pg_config_mem,
   3958                                 PG_GBL_HDRM_ENf,
   3959                                 buf_prigroup->device_headroom_enable);
   3960             if (!IS_FAE_PORT(unit, port)) {
   3961                 soc_mem_field32_set(unit, mem1, &pg_config_mem,
   3962                         PG_HDRM_LIMITf, buf_prigroup->headroom);
   3963 
   3964                 soc_mem_field32_set(unit, mem1, &pg_config_mem, PG_RESET_OFFSETf,
   3965                         0);
   3966 
   3967                 soc_mem_field32_set(unit, mem1, &pg_config_mem,
   3968                         PG_RESET_FLOORf, buf_prigroup->pool_floor);
   3969             }
   3970             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, midx,
   3971                                 &pg_config_mem));
   3972         }
   3973     }
   3974 
   3975     /***********************************
   3976      * THDO
   3977  */
   3978     /* Output port per port per queue setting for regular multicast queue */
   3979     pipe = si->port_pipe[port];
   3980     numq = si->port_num_cosq[port];
   3981     base = si->port_cosq_base[port];
   3982 
   3983     mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[0])[pipe];
   3984     mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[1])[pipe];
   3985     if ((numq != 0) && (mem0 != INVALIDm) && (mem1 != INVALIDm)) {
   3986         for (idx = 0; idx < numq; idx++) {
   3987             buf_queue = &buf->ports[port].queues[idx];
   3988 
   3989             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t));
   3990 
   3991             soc_mem_field32_set(unit, mem0, entry0, Q_MIN_LIMITf, 0);
   3992             soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_ENABLEf, 1);
   3993             soc_mem_field32_set(unit, mem0, entry0, Q_COLOR_LIMIT_DYNAMICf, 1);
   3994             soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_DYNAMICf, 1);
   3995             soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_ALPHAf,  8);
   3996             soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_LIMITf, 8);
   3997             soc_mem_field32_set(unit, mem0, entry0, Q_SPIDf, 0);
   3998 
   3999             SOC_IF_ERROR_RETURN
   4000                 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, base + idx, entry0));
   4001 
   4002             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_entry_t));
   4003 
   4004             soc_mem_field32_set(unit, mem1, entry0, RESUME_OFFSETf, 2);
   4005             soc_mem_field32_set(unit, mem1, entry0,
   4006                                 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0);
   4007             soc_mem_field32_set(unit, mem1, entry0,
   4008                                 RED_RESUME_OFFSET_PROFILE_SELf, 0);
   4009             SOC_IF_ERROR_RETURN
   4010                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry0));
   4011 
   4012             rval = 0;
   4013             SOC_IF_ERROR_RETURN(
   4014                     WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0,
   4015                         2));
   4016 
   4017             rval = 0;
   4018             SOC_IF_ERROR_RETURN(
   4019                     WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0,
   4020                         2));
   4021         }
   4022     }
   4023 
   4024     mem2 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[2])[pipe];
   4025     mem3 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[3])[pipe];
   4026     if ((numq != 0) && (mem2 != INVALIDm) && (mem3 != INVALIDm)) {
   4027         for (idx = 0; idx < numq; idx++) {
   4028             buf_queue = &buf->ports[port].queues[idx];
   4029             buf_pool = &buf->pools[buf_queue->pool_idx];
   4030             if (buf_pool->total == 0) {
   4031                 continue;
   4032             }
   4033             sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_entry_t));
   4034 
   4035             soc_mem_field32_set(unit, mem2, entry0, Q_MIN_LIMITf, 1);
   4036             soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1);
   4037             soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_DYNAMICf, 1);
   4038             soc_mem_field32_set(unit, mem2, entry0, Q_COLOR_LIMIT_DYNAMICf, 1);
   4039             soc_mem_field32_set(unit, mem2, entry0, Q_SHARED_ALPHAf, 8);
   4040             soc_mem_field32_set(unit, mem2, entry0, Q_SHARED_LIMITf, 8);
   4041             soc_mem_field32_set(unit, mem2, entry0, Q_SPIDf, 0);
   4042 
   4043             SOC_IF_ERROR_RETURN
   4044                 (soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx, entry0));
   4045 
   4046             sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_offset_entry_t));
   4047 
   4048             soc_mem_field32_set(unit, mem3, entry0, RESUME_OFFSETf, 1);
   4049             soc_mem_field32_set(unit, mem3, entry0,
   4050                                 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0);
   4051             soc_mem_field32_set(unit, mem3, entry0,
   4052                                 RED_RESUME_OFFSET_PROFILE_SELf, 0);
   4053             SOC_IF_ERROR_RETURN
   4054                 (soc_mem_write(unit, mem3, MEM_BLOCK_ALL, base + idx, entry0));
   4055 
   4056             rval = 0;
   4057             SOC_IF_ERROR_RETURN(
   4058                     WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0,
   4059                         1));
   4060 
   4061             rval = 0;
   4062             SOC_IF_ERROR_RETURN(
   4063                     WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0,
   4064                         1));
   4065         }
   4066     }
   4067 
   4068     /* Per  port per pool */
   4069     for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   4070         buf_port_pool = &buf->ports[port].pools[idx];
   4071         if (buf_port_pool->pool_limit == 0) {
   4072             continue;
   4073         }
   4074 
   4075         limit = buf_port_pool->pool_limit;
   4076         rlimit = limit - (default_mtu_cells * 2);
   4077 
   4078         if(lossless) {
   4079            enable = (!IS_OVERSUB_PORT(unit, port) && si->port_speed_max[port] <= 2500) ? 1 : 0;
   4080         }else {
   4081            enable = 1;
   4082         }
   4083 
   4084         mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_mc_mem[0])[pipe];
   4085         if (mem0 == INVALIDm) {
   4086             continue;
   4087         }
   4088 
   4089         index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port,
   4090                                              mmu_thdo_port_mc_mem[0], idx);
   4091         sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_entry_t));
   4092 
   4093         soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMITf, limit);
   4094         soc_mem_field32_set(unit, mem0, entry0, RED_SHARED_LIMITf,
   4095                             sal_ceil_func(limit, 8));
   4096         soc_mem_field32_set(unit, mem0, entry0, YELLOW_SHARED_LIMITf,
   4097                             sal_ceil_func(limit, 8));
   4098 
   4099         soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMIT_ENABLEf, enable);
   4100 
   4101         soc_mem_field32_set(unit, mem0, entry0, SHARED_RESUME_LIMITf,
   4102                             sal_ceil_func(rlimit, 8));
   4103         soc_mem_field32_set(unit, mem0, entry0, YELLOW_RESUME_LIMITf,
   4104                             sal_ceil_func(rlimit, 8));
   4105         soc_mem_field32_set(unit, mem0, entry0, RED_RESUME_LIMITf,
   4106                             sal_ceil_func(rlimit, 8));
   4107 
   4108         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem0, MEM_BLOCK_ALL,
   4109                             index1, entry0));
   4110 
   4111         mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_mc_mem[1])[pipe];
   4112         if (mem1 == INVALIDm) {
   4113             continue;
   4114         }
   4115         buf_pool = &buf->pools[idx];
   4116         sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_entry_t));
   4117 
   4118         limit = _HX5_MMU_TOTAL_MCQ_ENTRY(unit);
   4119 
   4120         soc_mem_field32_set(unit, mem1, entry0, SHARED_LIMITf,
   4121                             (sal_ceil_func(limit, 4)) - 1);
   4122         soc_mem_field32_set(unit, mem1, entry0, YELLOW_SHARED_LIMITf,
   4123                             (sal_ceil_func(limit, 8)) - 1);
   4124         soc_mem_field32_set(unit, mem1, entry0, RED_SHARED_LIMITf,
   4125                             (sal_ceil_func(limit, 8)) - 1);
   4126 
   4127         soc_mem_field32_set(unit, mem1, entry0, SHARED_LIMIT_ENABLEf, enable);
   4128 
   4129         soc_mem_field32_set(unit, mem1, entry0, SHARED_RESUME_LIMITf,
   4130                             (sal_ceil_func(limit, 8)) - 2);
   4131         soc_mem_field32_set(unit, mem1, entry0, YELLOW_RESUME_LIMITf,
   4132                             (sal_ceil_func(limit, 8)) - 2);
   4133         soc_mem_field32_set(unit, mem1, entry0, RED_RESUME_LIMITf,
   4134                             (sal_ceil_func(limit, 8)) - 2);
   4135 
   4136         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL,
   4137                             index1, entry0));
   4138     }
   4139 
   4140     /* Output port per port per queue setting for regular unicast queue */
   4141     pipe = si->port_pipe[port];
   4142     /* per port regular unicast queue */
   4143     numq = si->port_num_uc_cosq[port];
   4144     base = si->port_uc_cosq_base[port];
   4145 
   4146     mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[0])[pipe];
   4147     mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[1])[pipe];
   4148     mem2 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[2])[pipe];
   4149     if ((numq != 0) &&
   4150         (mem0 != INVALIDm) && (mem1 != INVALIDm) && (mem2 != INVALIDm)) {
   4151         for (idx = 0; idx < numq; idx++) {
   4152             buf_queue = &buf->ports[port].queues[si->port_num_cosq[port] + idx];
   4153 
   4154             sal_memset(entry0, 0, sizeof(mmu_thdu_config_queue_entry_t));
   4155             sal_memset(entry1, 0, sizeof(mmu_thdu_offset_queue_entry_t));
   4156 
   4157             soc_mem_field32_set(unit, mem0, entry0,
   4158                                 Q_MIN_LIMIT_CELLf, buf_queue->guarantee);
   4159             if (buf_queue->pool_scale != -1) {
   4160                 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_DYNAMIC_CELLf, 1);
   4161                 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_ALPHA_CELLf,
   4162                                     buf_queue->pool_scale);
   4163             } else {
   4164                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
   4165                 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_LIMIT_CELLf,
   4166                                     buf_queue->pool_limit);
   4167             }
   4168             soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_CELLf,
   4169                                 sal_ceil_func(buf_queue->pool_resume, 8));
   4170 
   4171             if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
   4172                     (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
   4173                 soc_mem_field32_set(unit, mem0, entry0,
   4174                                     Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
   4175                 soc_mem_field32_set(unit, mem0, entry0, LIMIT_YELLOW_CELLf,
   4176                         buf_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG);
   4177                 soc_mem_field32_set(unit, mem0, entry0, LIMIT_RED_CELLf,
   4178                         buf_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG);
   4179             } else {
   4180                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
   4181                 soc_mem_field32_set(unit, mem0, entry0, LIMIT_YELLOW_CELLf,
   4182                                     sal_ceil_func(buf_queue->yellow_limit, 8));
   4183                 soc_mem_field32_set(unit, mem0, entry0, LIMIT_RED_CELLf,
   4184                                     sal_ceil_func(buf_queue->red_limit, 8));
   4185             }
   4186             soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_YELLOW_CELLf,
   4187                                 sal_ceil_func(buf_queue->yellow_resume, 8));
   4188             soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_RED_CELLf,
   4189                                 sal_ceil_func(buf_queue->red_resume, 8));
   4190             SOC_IF_ERROR_RETURN
   4191                 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, base + idx, entry0));
   4192 
   4193             SOC_IF_ERROR_RETURN
   4194                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry1));
   4195 
   4196             sal_memset(entry0, 0, sizeof(mmu_thdo_q_to_qgrp_map_entry_t));
   4197 
   4198             if (buf_queue->qgroup_id >= 0) {
   4199                 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, 1);
   4200                 if (buf_queue->qgroup_min_enable) {
   4201                     soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf, 1);
   4202                 }
   4203             }
   4204             if (buf_queue->discard_enable) {
   4205                 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1);
   4206             }
   4207 
   4208             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx,
   4209                                 entry0));
   4210         }
   4211     }
   4212 
   4213     /* Per  port per pool unicast */
   4214     for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   4215         buf_pool = &buf->pools[idx];
   4216 
   4217         if (IS_LB_PORT(unit, port) || IS_CPU_PORT(unit, port)
   4218             || IS_FAE_PORT(unit, port)) {
   4219              continue;
   4220         }
   4221 
   4222         if (buf_pool->total == 0) {
   4223             continue;
   4224         }
   4225 
   4226         limit = buf->ports[port].pools[idx].pool_limit;
   4227 
   4228         mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_uc_mem[0])[pipe];
   4229         mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_uc_mem[1])[pipe];
   4230         if ((mem0 == INVALIDm) || (mem1 == INVALIDm)) {
   4231             continue;
   4232         }
   4233         index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port,
   4234                                              mmu_thdo_port_uc_mem[0], idx);
   4235         sal_memset(entry0, 0, sizeof(mmu_thdu_config_port_entry_t));
   4236         sal_memset(entry1, 0, sizeof(mmu_thdu_resume_port_entry_t));
   4237 
   4238         soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMITf, limit);
   4239         soc_mem_field32_set(unit, mem1, entry1, SHARED_RESUMEf,
   4240                             sal_ceil_func((limit - (default_mtu_cells * 2)),
   4241                             8));
   4242 
   4243         soc_mem_field32_set(unit, mem0, entry0, YELLOW_LIMITf,
   4244                             sal_ceil_func(limit, 8));
   4245         soc_mem_field32_set(unit, mem1, entry1, YELLOW_RESUMEf,
   4246                             sal_ceil_func((limit - (default_mtu_cells*2)),
   4247                             8));
   4248 
   4249         soc_mem_field32_set(unit, mem0, entry0, RED_LIMITf,
   4250                             sal_ceil_func(limit, 8));
   4251         soc_mem_field32_set(unit, mem1, entry1, RED_RESUMEf,
   4252                             sal_ceil_func((limit - (default_mtu_cells * 2)),
   4253                             8));
   4254 
   4255         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem0, MEM_BLOCK_ALL,
   4256                             index1, entry0));
   4257         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL,
   4258                             index1, entry1));
   4259     }
   4260 
   4261     return SOC_E_NONE;
   4262 }
   4263 
   4264 STATIC int
   4265 _soc_hx5_mmu_config_buf_set_hw_global(int unit, _soc_mmu_cfg_buf_t *buf,
   4266                                _soc_mmu_device_info_t *devcfg, int lossless,
   4267                                _soc_hx5_mmu_sw_config_info_t *swcfg)
   4268 {
   4269     _soc_mmu_cfg_buf_pool_t *buf_pool;
   4270     _soc_mmu_cfg_buf_qgroup_t *queue_grp;
   4271     mmu_thdo_config_qgroup_entry_t cfg_qgrp;
   4272     mmu_thdo_offset_qgroup_entry_t offset_qgrp;
   4273     _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue;
   4274     soc_mem_t mem0, mem1;
   4275     uint32 fval, rval, rval2, rval3;
   4276     int rqlen, idx, pval;
   4277     int jumbo_frame_cells, default_mtu_cells, limit;
   4278     int pipe;
   4279     uint64 rval64;
   4280     int pool_resume = 0;
   4281 
   4282      static const soc_mem_t mmu_thdo_qgrp_uc_mem[] = {
   4283          MMU_THDU_CONFIG_QGROUPm,
   4284          MMU_THDU_OFFSET_QGROUPm
   4285     };
   4286 
   4287     jumbo_frame_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->jumbo_pkt_size +
   4288                                                     devcfg->mmu_hdr_byte,
   4289                                                     devcfg->mmu_cell_size);
   4290     default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size +
   4291                                                    devcfg->mmu_hdr_byte,
   4292                                                    devcfg->mmu_cell_size);
   4293     pool_resume = 2 * jumbo_frame_cells;
   4294 
   4295     rval = 0;
   4296     fval = _HX5_MMU_PHYSICAL_CELLS_PER_XPE - _HX5_MMU_RSVD_CELLS_CFAP_PER_XPE;
   4297     soc_reg_field_set(unit, CFAPFULLTHRESHOLDSETr, &rval, CFAPFULLSETPOINTf,
   4298                       fval);
   4299     SOC_IF_ERROR_RETURN(
   4300         soc_trident3_xpe_reg32_set(unit, CFAPFULLTHRESHOLDSETr, -1, -1,
   4301                                    -1, rval));
   4302 
   4303     rval = 0;
   4304     soc_reg_field_set(unit, CFAPFULLTHRESHOLDRESETr, &rval,
   4305                       CFAPFULLRESETPOINTf, fval - (2 * jumbo_frame_cells));
   4306     SOC_IF_ERROR_RETURN(
   4307         soc_trident3_xpe_reg32_set(unit, CFAPFULLTHRESHOLDRESETr, -1, -1,
   4308                                    -1, rval));
   4309 
   4310     rval = 0;
   4311     soc_reg_field_set(unit, CFAPBANKFULLr, &rval, LIMITf,
   4312                       _HX5_MMU_CFAP_BANK_FULL_LIMIT);
   4313     for (idx = 0; idx < SOC_REG_NUMELS(unit, CFAPBANKFULLr); idx++) {
   4314         SOC_IF_ERROR_RETURN(
   4315             soc_trident3_xpe_reg32_set(unit, CFAPBANKFULLr, -1, -1,
   4316                                        idx, rval));
   4317     }
   4318 
   4319     rval = 0;
   4320     SOC_IF_ERROR_RETURN(READ_MMU_SCFG_TOQ_MC_CFG0r(unit, &rval));
   4321     soc_reg_field_set(unit, MMU_SCFG_TOQ_MC_CFG0r, &rval,
   4322                       MCQE_FULL_THRESHOLDf, 0);
   4323     SOC_IF_ERROR_RETURN(WRITE_MMU_SCFG_TOQ_MC_CFG0r(unit, rval));
   4324 
   4325     rval = 0;
   4326         SOC_IF_ERROR_RETURN
   4327             (soc_reg32_get(unit, THDI_HDRM_POOL_CFGr, 0, 0, &rval));
   4328         soc_reg_field_set(unit, THDI_HDRM_POOL_CFGr, &rval,
   4329                           PEAK_COUNT_UPDATE_EN_HPf, 0);
   4330         SOC_IF_ERROR_RETURN
   4331             (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, 0, 0, rval));
   4332     /* Input thresholds */
   4333     rval = 0;
   4334     soc_reg_field_set(unit, THDI_GLOBAL_HDRM_LIMITr,
   4335                       &rval, GLOBAL_HDRM_LIMITf, buf->headroom );
   4336     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, THDI_GLOBAL_HDRM_LIMITr,
   4337                                       REG_PORT_ANY, 0, rval));
   4338 
   4339     for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   4340         buf_pool = &buf->pools[idx];
   4341         if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) {
   4342             continue;
   4343         }
   4344 
   4345         limit = swcfg->ing_shared_total;
   4346 
   4347         rval = 0;
   4348         soc_reg_field_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, &rval, LIMITf,
   4349                           limit);
   4350         SOC_IF_ERROR_RETURN(
   4351             soc_trident3_xpe_reg32_set(unit, THDI_BUFFER_CELL_LIMIT_SPr,
   4352                                        -1, -1, idx, rval));
   4353 
   4354         rval = 0;
   4355         soc_reg_field_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, &rval,
   4356                           OFFSETf, pool_resume);
   4357         SOC_IF_ERROR_RETURN(
   4358             soc_trident3_xpe_reg32_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr,
   4359                                        -1, -1, idx, rval));
   4360 
   4361         rval = 0;
   4362         soc_reg_field_set(unit, THDI_HDRM_BUFFER_CELL_LIMIT_HPr, &rval,
   4363                           LIMITf, buf_pool->prigroup_headroom);
   4364         SOC_IF_ERROR_RETURN(
   4365             soc_trident3_xpe_reg32_set(unit, THDI_HDRM_BUFFER_CELL_LIMIT_HPr,
   4366                                        -1, -1, idx, rval));
   4367     }
   4368 
   4369     rval = 0;
   4370     SOC_IF_ERROR_RETURN(
   4371         soc_trident3_xpe_reg32_set(unit, THDI_BUFFER_CELL_LIMIT_PUBLIC_POOLr,
   4372                                    -1, -1, 0, rval));
   4373 
   4374     /* output thresholds */
   4375     SOC_IF_ERROR_RETURN(READ_OP_THDU_CONFIGr(unit, &rval));
   4376     soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval,
   4377                       ENABLE_QUEUE_AND_GROUP_TICKETf, 1);
   4378     soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval,
   4379                       ENABLE_UPDATE_COLOR_RESUMEf, 0);
   4380     soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Bf, 1);
   4381     soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Af, 0);
   4382     SOC_IF_ERROR_RETURN(WRITE_OP_THDU_CONFIGr(unit, rval));
   4383 
   4384     rval = 0;
   4385     SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval));
   4386     soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval,
   4387                       MOP_POLICYf, 1);
   4388     SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval));
   4389 
   4390     rval = 0;
   4391     SOC_IF_ERROR_RETURN(READ_MMU_THDR_DB_CONFIGr(unit, &rval));
   4392     soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval,
   4393                       MOP_POLICY_1Bf, 1);
   4394     SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIGr(unit, rval));
   4395 
   4396     /* per service pool settings */
   4397     for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   4398         buf_pool = &buf->pools[idx];
   4399         if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) {
   4400             continue;
   4401         }
   4402 
   4403         limit = swcfg->egr_shared_total;
   4404 
   4405         rval = 0;
   4406         soc_reg_field_set(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, &rval,
   4407                           SHARED_LIMITf, limit);
   4408         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_SHARED_LIMITr(unit,
   4409                                                                  idx,
   4410                                                                  rval));
   4411 
   4412         rval = 0;
   4413         soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr,
   4414                           &rval, YELLOW_SHARED_LIMITf, sal_ceil_func(limit, 8));
   4415         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr(unit,
   4416                                                                         idx,
   4417                                                                         rval));
   4418 
   4419         rval = 0;
   4420         soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_SHARED_LIMITr,
   4421                           &rval, RED_SHARED_LIMITf, sal_ceil_func(limit, 8));
   4422         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_SHARED_LIMITr(unit,
   4423                                                                      idx,
   4424                                                                      rval));
   4425 
   4426         rval = 0;
   4427         soc_reg_field_set(unit, MMU_THDM_DB_POOL_RESUME_LIMITr,
   4428                           &rval, RESUME_LIMITf, sal_floor_func(limit, 8));
   4429         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RESUME_LIMITr(unit,
   4430                                                                  idx,
   4431                                                                  rval));
   4432 
   4433         rval = 0;
   4434         soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr,
   4435                           &rval, YELLOW_RESUME_LIMITf, sal_floor_func(limit, 8));
   4436         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr(unit,
   4437                                                                         idx,
   4438                                                                         rval));
   4439 
   4440         rval = 0;
   4441         soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_RESUME_LIMITr,
   4442                           &rval, RED_RESUME_LIMITf, sal_floor_func(limit, 8));
   4443         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_RESUME_LIMITr(unit,
   4444                                                                      idx,
   4445                                                                      rval));
   4446 
   4447         /* mcq entries */
   4448         limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved;
   4449 
   4450         rval = 0;
   4451         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr,
   4452                           &rval, SHARED_LIMITf, sal_ceil_func(limit, 4));
   4453         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_SHARED_LIMITr(unit,
   4454                                                                    idx, rval));
   4455 
   4456         rval = 0;
   4457         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr,
   4458                           &rval, YELLOW_SHARED_LIMITf, sal_ceil_func(limit, 8));
   4459         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr(unit,
   4460                                                                    idx, rval));
   4461 
   4462         rval = 0;
   4463         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr,
   4464                           &rval, RED_SHARED_LIMITf, sal_ceil_func(limit, 8));
   4465         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr(unit,
   4466                                                                    idx, rval));
   4467 
   4468         rval = 0;
   4469         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RESUME_LIMITr,
   4470                           &rval, RESUME_LIMITf, sal_ceil_func(limit, 8));
   4471         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RESUME_LIMITr(unit,
   4472                                                                    idx, rval));
   4473 
   4474         rval = 0;
   4475         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr,
   4476                           &rval, YELLOW_RESUME_LIMITf, sal_ceil_func(limit, 8));
   4477         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr(unit,
   4478                                                                    idx, rval));
   4479 
   4480         rval = 0;
   4481         soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr,
   4482                           &rval, RED_RESUME_LIMITf, sal_ceil_func(limit, 8));
   4483         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr(unit,
   4484                                                                    idx, rval));
   4485     }
   4486 
   4487     /* configure Q-groups */
   4488     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   4489         for (idx = 0; idx < SOC_HX5_MMU_CFG_QGROUP_MAX; idx++) {
   4490             mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_qgrp_uc_mem[0])[pipe];
   4491             mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_qgrp_uc_mem[1])[pipe];
   4492             if ((mem0 == INVALIDm) || (mem1 == INVALIDm)) {
   4493                 continue;
   4494             }
   4495             queue_grp = &buf->qgroups[idx];
   4496 
   4497 
   4498             sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp));
   4499             sal_memset(&offset_qgrp, 0, sizeof(offset_qgrp));
   4500 
   4501             soc_mem_field32_set(unit, mem0, &cfg_qgrp,
   4502                                 Q_MIN_LIMIT_CELLf, queue_grp->guarantee);
   4503 
   4504             if (queue_grp->pool_scale != -1) {
   4505                 soc_mem_field32_set(unit, mem0, &cfg_qgrp,
   4506                                     Q_SHARED_ALPHA_CELLf,
   4507                                     queue_grp->pool_scale);
   4508                 soc_mem_field32_set(unit, mem0, &cfg_qgrp,
   4509                                     Q_LIMIT_DYNAMIC_CELLf, 1);
   4510             } else {
   4511                 soc_mem_field32_set(unit, mem0, &cfg_qgrp,
   4512                                     Q_SHARED_LIMIT_CELLf,
   4513                                     queue_grp->pool_limit);
   4514             }
   4515 
   4516             if ((queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
   4517                 (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
   4518                 soc_mem_field32_set(unit, mem0, &cfg_qgrp,
   4519                                     Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
   4520             }
   4521 
   4522             if (queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) {
   4523                 pval = _soc_hx5_pool_scale_to_limit(queue_grp->pool_limit,
   4524                           queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG);
   4525                 soc_mem_field32_set(unit, mem0, &cfg_qgrp,
   4526                                     LIMIT_RED_CELLf, sal_ceil_func(pval, 8));
   4527 
   4528             } else {
   4529                 soc_mem_field32_set(unit, mem0, &cfg_qgrp,
   4530                                     LIMIT_RED_CELLf,
   4531                                     sal_ceil_func(queue_grp->red_limit, 8));
   4532             }
   4533 
   4534             if (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) {
   4535                 pval = _soc_hx5_pool_scale_to_limit(queue_grp->pool_limit,
   4536                           queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG);
   4537                 soc_mem_field32_set(unit, mem0, &cfg_qgrp,
   4538                                     LIMIT_YELLOW_CELLf, sal_ceil_func(pval, 8));
   4539 
   4540             } else {
   4541                 soc_mem_field32_set(unit, mem0, &cfg_qgrp,
   4542                                     LIMIT_YELLOW_CELLf,
   4543                                     sal_ceil_func(queue_grp->yellow_limit, 8));
   4544             }
   4545 
   4546             soc_mem_field32_set(unit, mem1, &offset_qgrp,
   4547                                 RESET_OFFSET_CELLf,
   4548                                 sal_ceil_func(queue_grp->pool_resume, 8));
   4549             soc_mem_field32_set(unit, mem1, &offset_qgrp,
   4550                                 RESET_OFFSET_YELLOW_CELLf,
   4551                                 sal_ceil_func(queue_grp->pool_resume, 8));
   4552             soc_mem_field32_set(unit, mem1, &offset_qgrp,
   4553                                 RESET_OFFSET_RED_CELLf,
   4554                                 sal_ceil_func(queue_grp->pool_resume, 8));
   4555             SOC_IF_ERROR_RETURN
   4556                     (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, idx, &cfg_qgrp));
   4557             SOC_IF_ERROR_RETURN
   4558                     (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, idx, &offset_qgrp));
   4559         }
   4560     }
   4561 
   4562     /* RQE */
   4563     for (idx = 0; idx < _HX5_MMU_NUM_RQE_QUEUES; idx++) {
   4564         buf_rqe_queue = &buf->rqe_queues[idx];
   4565 
   4566         rval = 0;
   4567         soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_MIN_PRIQr,
   4568                           &rval, MIN_LIMITf, buf_rqe_queue->guarantee);
   4569         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_MIN_PRIQr(unit, idx, rval));
   4570 
   4571         rval = 0;
   4572         rval2 = 0;
   4573         rval3 = 0;
   4574         COMPILER_64_SET(rval64, 0, 0);
   4575         soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr,
   4576                             &rval, SPIDf, buf_rqe_queue->pool_idx);
   4577 
   4578         if ((buf_rqe_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
   4579             (buf_rqe_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
   4580             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr,
   4581                               &rval, COLOR_LIMIT_DYNAMICf, 1);
   4582             soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
   4583                 SHARED_RED_LIMITf,
   4584                 buf_rqe_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG);
   4585             soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
   4586                 SHARED_YELLOW_LIMITf,
   4587                 buf_rqe_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG);
   4588         } else {
   4589             soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
   4590                               SHARED_RED_LIMITf,
   4591                               sal_ceil_func(buf_rqe_queue->red_limit, 8));
   4592 
   4593             soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
   4594                               SHARED_YELLOW_LIMITf,
   4595                               sal_ceil_func(buf_rqe_queue->yellow_limit, 8));
   4596         }
   4597 
   4598         soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf,
   4599                           (buf_rqe_queue->discard_enable ? 1 : 0));
   4600 
   4601         if (buf_rqe_queue->pool_scale != -1) {
   4602             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr,
   4603                               &rval, DYNAMIC_ENABLEf, 1);
   4604             soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval64,
   4605                               SHARED_ALPHAf, buf_rqe_queue->pool_scale);
   4606         } else {
   4607             soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval64,
   4608                               SHARED_LIMITf, buf_rqe_queue->pool_limit);
   4609         }
   4610         soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval64,
   4611                           RESET_OFFSETf, 2);
   4612 
   4613         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, rval));
   4614         SOC_IF_ERROR_RETURN(soc_reg64_set(unit, MMU_THDR_DB_CONFIG_PRIQr, REG_PORT_ANY, idx, rval64));
   4615         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_COLOR_PRIQr(unit,
   4616                                                                 idx, rval3));
   4617 
   4618         rval = 0;
   4619         soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr,
   4620                           &rval, RESET_OFFSET_REDf, 2);
   4621         soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr,
   4622                           &rval, RESET_OFFSET_YELLOWf,2);
   4623         SOC_IF_ERROR_RETURN(
   4624                   WRITE_MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval));
   4625 
   4626         /* queue entry */
   4627         buf_pool = &buf->pools[buf_rqe_queue->pool_idx];
   4628         rval = 0;
   4629         soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_MIN_PRIQr,
   4630                           &rval, MIN_LIMITf,
   4631                           sal_ceil_func(buf_rqe_queue->guarantee, 8));
   4632         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_MIN_PRIQr(unit, idx, rval));
   4633 
   4634         rval = 0;
   4635         rval2 = 0;
   4636         rval3 = 0;
   4637         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr,
   4638                           &rval, SPIDf, buf_rqe_queue->pool_idx);
   4639 
   4640         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr,
   4641                           &rval, COLOR_LIMIT_DYNAMICf, (!lossless));
   4642         soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr,
   4643                           &rval3, SHARED_RED_LIMITf,
   4644                           lossless? (sal_ceil_func(buf_pool->total_rqe_entry,
   4645                           8)): 0);
   4646         soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr,
   4647                           &rval3, SHARED_YELLOW_LIMITf,
   4648                           lossless? (sal_ceil_func(buf_pool->total_rqe_entry,
   4649                           8)): 0);
   4650 
   4651         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval,
   4652                           LIMIT_ENABLEf, !lossless);
   4653         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr,
   4654                           &rval, DYNAMIC_ENABLEf, (!lossless));
   4655 
   4656         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2,
   4657                           SHARED_LIMITf,
   4658                           lossless? (sal_ceil_func(buf_pool->total_rqe_entry,
   4659                           8)): 8);
   4660         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2,
   4661                           RESET_OFFSETf, 1);
   4662 
   4663         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG1_PRIQr(unit, idx, rval));
   4664         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_PRIQr(unit, idx, rval2));
   4665         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_COLOR_PRIQr(unit, idx, rval3));
   4666 
   4667         rval = 0;
   4668         soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr,
   4669                           &rval, RESET_OFFSET_REDf,
   4670                           sal_ceil_func(default_mtu_cells, 8));
   4671         soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr,
   4672                           &rval, RESET_OFFSET_YELLOWf,
   4673                           sal_ceil_func(default_mtu_cells, 8));
   4674         SOC_IF_ERROR_RETURN(
   4675                   WRITE_MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval));
   4676 
   4677     }
   4678 
   4679     /* per pool RQE settings */
   4680     for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   4681         buf_pool = &buf->pools[idx];
   4682         if (((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) ||
   4683             (buf_pool->total == 0)) {
   4684             continue;
   4685         }
   4686 
   4687         limit = swcfg->egr_shared_total;
   4688 
   4689         COMPILER_64_SET(rval64, 0, 0);
   4690         soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_SPr,
   4691                               &rval64, SHARED_LIMITf, limit);
   4692         soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_SPr, &rval64,
   4693             RESUME_LIMITf, sal_ceil_func((limit - (default_mtu_cells * 2)), 8));
   4694         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_SPr(unit, idx, rval64));
   4695 
   4696         rval = 0;
   4697         soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval,
   4698                           SHARED_RED_LIMITf,
   4699                           sal_ceil_func(limit, 8));
   4700         soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval,
   4701                           SHARED_YELLOW_LIMITf,
   4702                           sal_ceil_func(limit, 8));
   4703         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_SP_SHARED_LIMITr(unit, idx, rval));
   4704 
   4705         rval = 0;
   4706         soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval,
   4707                           RESUME_RED_LIMITf,
   4708                           sal_ceil_func((limit - (default_mtu_cells * 2)), 8));
   4709         soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval,
   4710                           RESUME_YELLOW_LIMITf,
   4711                           sal_ceil_func((limit - (default_mtu_cells * 2)), 8));
   4712         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr(unit,
   4713                                                                      idx, rval));
   4714 
   4715         rqlen = sal_ceil_func(buf_pool->total_rqe_entry, 8);
   4716         if (rqlen == 0) {
   4717             continue;
   4718         }
   4719 
   4720         rval = 0;
   4721         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval,
   4722                           SHARED_LIMITf, rqlen);
   4723         soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval,
   4724                           RESUME_LIMITf, rqlen - 1);
   4725         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_SPr(unit, idx, rval));
   4726 
   4727         rval = 0;
   4728         soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval,
   4729                           SHARED_RED_LIMITf, rqlen);
   4730         soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval,
   4731                           SHARED_YELLOW_LIMITf, rqlen);
   4732         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr(unit,
   4733                                                                      idx,
   4734                                                                      rval));
   4735 
   4736         rval = 0;
   4737         soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval,
   4738                           RESUME_RED_LIMITf, rqlen - 1);
   4739         soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval,
   4740                           RESUME_YELLOW_LIMITf, rqlen - 1);
   4741         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr(unit,
   4742                                                                      idx, rval));
   4743     }
   4744 
   4745 
   4746     /* Device level config setting */
   4747 #if 0
   4748     if (soc_property_get(unit, spn_PORT_UC_MC_ACCOUNTING_COMBINE, 0)) {
   4749         SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval));
   4750         soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval,
   4751                           UC_MC_PORTSP_COMB_ACCT_ENABLEf, 1);
   4752         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval));
   4753     }
   4754 #endif
   4755     return SOC_E_NONE;
   4756 }
   4757 
   4758 STATIC int
   4759 _soc_hx5_mmu_config_buf_set_hw(int unit, _soc_mmu_cfg_buf_t *buf,
   4760                                _soc_mmu_device_info_t *devcfg, int lossless,
   4761                                _soc_hx5_mmu_sw_config_info_t *swcfg)
   4762 {
   4763     int port;
   4764 
   4765     SOC_IF_ERROR_RETURN
   4766         (_soc_hx5_mmu_config_buf_set_hw_global(unit, buf, devcfg, lossless,
   4767                                                swcfg));
   4768 
   4769     PBMP_ALL_ITER(unit, port) {
   4770        SOC_IF_ERROR_RETURN
   4771             (_soc_hx5_mmu_config_buf_set_hw_port(unit, port, buf, devcfg,
   4772                                                  lossless, swcfg));
   4773     }
   4774 
   4775     return SOC_E_NONE;
   4776 }
   4777 
   4778 int
   4779 soc_hx5_mmu_config_init_port(int unit, int port)
   4780 {
   4781     int rv;
   4782     int lossless = 1;
   4783     _soc_mmu_cfg_buf_t *buf;
   4784     _soc_mmu_device_info_t devcfg;
   4785     _soc_hx5_mmu_sw_config_info_t swcfg;
   4786 
   4787     buf = soc_mmu_cfg_alloc(unit);
   4788     if (!buf) {
   4789         return SOC_E_MEMORY;
   4790     }
   4791 
   4792     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);
   4793 
   4794     SOC_INFO(unit).mmu_lossless = lossless;
   4795     _soc_hx5_mmu_init_dev_config(unit, &devcfg, lossless);
   4796     _soc_hx5_mmu_sw_info_config (unit, &swcfg, lossless);
   4797 
   4798 
   4799     /* Calculate the buf - global as well as per port
   4800      * but _soc_hx5_mmu_config_buf_set_hw_port is only called
   4801      * for that port - since it is flex operation - we don't
   4802      * touch any other port */
   4803     _soc_hx5_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless);
   4804 
   4805     if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) {
   4806         /* Override default config */
   4807         _soc_mmu_cfg_buf_read(unit, buf, &devcfg);
   4808     }
   4809     rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg);
   4810     if (SOC_FAILURE(rv)) {
   4811         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   4812                 (BSL_META_U(unit,
   4813                             "MMU config: Use default setting\n")));
   4814         _soc_hx5_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless);
   4815         SOC_IF_ERROR_RETURN
   4816             (_soc_mmu_cfg_buf_calculate(unit, buf, &devcfg));
   4817     }
   4818 
   4819     _soc_hx5_mmu_config_buf_phase2(unit, buf, &devcfg, &swcfg, lossless);
   4820     /* Override default phase 2 config */
   4821     if (SOC_SUCCESS(rv)) {
   4822         if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) {
   4823             _soc_mmu_cfg_buf_read(unit, buf, &devcfg);
   4824         }
   4825     }
   4826     rv = _soc_hx5_mmu_config_buf_set_hw_port(unit, port, buf, &devcfg,
   4827                                              lossless, &swcfg);
   4828 
   4829     soc_mmu_cfg_free(unit, buf);
   4830 
   4831     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   4832                 (BSL_META_U(unit,
   4833                             "MMU THDI/THDO init done\n")));
   4834     return rv;
   4835 }
   4836 
   4837 STATIC int
   4838 soc_hx5_mmu_config_init(int unit, int test_only)
   4839 {
   4840     int rv;
   4841     int lossless = 1;
   4842     _soc_mmu_cfg_buf_t *buf;
   4843     _soc_mmu_device_info_t devcfg;
   4844     _soc_hx5_mmu_sw_config_info_t swcfg;
   4845 
   4846     buf = soc_mmu_cfg_alloc(unit);
   4847     if (!buf) {
   4848         return SOC_E_MEMORY;
   4849     }
   4850 
   4851     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);
   4852 
   4853     _soc_hx5_mmu_init_dev_config(unit, &devcfg, lossless);
   4854     _soc_hx5_mmu_sw_info_config (unit, &swcfg, lossless);
   4855 
   4856     _soc_hx5_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless);
   4857     if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) {
   4858         /* Override default config */
   4859         _soc_mmu_cfg_buf_read(unit, buf, &devcfg);
   4860     }
   4861     rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg);
   4862     if (!test_only) {
   4863         if (SOC_FAILURE(rv)) {
   4864             LOG_VERBOSE(BSL_LS_SOC_COMMON,
   4865                         (BSL_META_U(unit,
   4866                                     "MMU config: Use default setting\n")));
   4867             _soc_hx5_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless);
   4868             SOC_IF_ERROR_RETURN
   4869                 (_soc_mmu_cfg_buf_calculate(unit, buf, &devcfg));
   4870         }
   4871 
   4872         _soc_hx5_mmu_config_buf_phase2(unit, buf, &devcfg, &swcfg, lossless);
   4873         /* Override default phase 2 config */
   4874         if (SOC_SUCCESS(rv)) {
   4875             if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) {
   4876                 _soc_mmu_cfg_buf_read(unit, buf, &devcfg);
   4877             }
   4878         }
   4879         rv = _soc_hx5_mmu_config_buf_set_hw(unit, buf, &devcfg, lossless, &swcfg);
   4880     }
   4881 
   4882     soc_mmu_cfg_free(unit, buf);
   4883 
   4884     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   4885                 (BSL_META_U(unit,
   4886                             "MMU THDI/THDO init done\n")));
   4887     return rv;
   4888 }
   4889 
   4890 STATIC int
   4891 _soc_hx5_thdo_hw_set(int unit, soc_port_t port, int enable)
   4892 {
   4893     uint64 rval64, rval64_tmp;
   4894     int pipe, i;
   4895     int split, pos;
   4896     soc_reg_t reg[3][2] = {
   4897         {
   4898             THDU_OUTPUT_PORT_RX_ENABLE_SPLIT0r,
   4899             THDU_OUTPUT_PORT_RX_ENABLE_SPLIT1r
   4900         },
   4901         {
   4902             MMU_THDM_DB_PORT_RX_ENABLE_64_SPLIT0r,
   4903             MMU_THDM_DB_PORT_RX_ENABLE_64_SPLIT1r
   4904         },
   4905         {
   4906             MMU_THDM_MCQE_PORT_RX_ENABLE_64_SPLIT0r,
   4907             MMU_THDM_MCQE_PORT_RX_ENABLE_64_SPLIT1r
   4908         }
   4909     };
   4910 
   4911     SOC_IF_ERROR_RETURN(
   4912         soc_td3_mmu_bmp_reg_pos_get(unit, port, &pipe, &split, &pos));
   4913 
   4914     for (i = 0; i < 3; i++) {
   4915         COMPILER_64_ZERO(rval64);
   4916         COMPILER_64_ZERO(rval64_tmp);
   4917 
   4918         if (pos < 32) {
   4919             COMPILER_64_SET(rval64_tmp, 0, (1 << pos));
   4920         } else {
   4921             COMPILER_64_SET(rval64_tmp, (1 << (pos - 32)), 0);
   4922         }
   4923 
   4924         SOC_IF_ERROR_RETURN
   4925             (soc_trident3_xpe_reg_get(unit, reg[i][split],
   4926                                       -1, pipe, 0, &rval64));
   4927 
   4928         if (enable) {
   4929             COMPILER_64_OR(rval64, rval64_tmp);
   4930         } else {
   4931             COMPILER_64_NOT(rval64_tmp);
   4932             COMPILER_64_AND(rval64, rval64_tmp);
   4933         }
   4934 
   4935         SOC_IF_ERROR_RETURN
   4936             (soc_trident3_xpe_reg_set(unit, reg[i][split],
   4937                                       -1, pipe, 0, rval64));
   4938     }
   4939 
   4940     return SOC_E_NONE;
   4941 }
   4942 
   4943 STATIC int
   4944 _soc_helix5_mmu_init(int unit)
   4945 {
   4946     uint32 rval = 0;
   4947     int total_entries, clock_period, msbus_margin;
   4948     int refresh_time_val;
   4949     int val, time_refresh = 0;
   4950     int enable = 1;
   4951     int port;
   4952     int test_only;
   4953     soc_info_t *si;
   4954 #ifdef BCM_WARM_BOOT_SUPPORT
   4955     if (SOC_WARM_BOOT(unit)) {
   4956     } else
   4957 #endif
   4958     {
   4959 
   4960         test_only = (SAL_BOOT_XGSSIM) ? TRUE : FALSE;
   4961         SOC_IF_ERROR_RETURN(soc_hx5_mmu_config_init(unit, test_only));
   4962 
   4963 
   4964         PBMP_ALL_ITER(unit, port) {
   4965             _soc_hx5_thdo_hw_set(unit, port, enable);
   4966         }
   4967         si = &SOC_INFO(unit);
   4968 
   4969         total_entries = 1572;
   4970         clock_period = (1 * 10000) / si->frequency;
   4971         msbus_margin = (18 * 1000) / 16;
   4972 
   4973         refresh_time_val = clock_period * total_entries * msbus_margin;
   4974         val = refresh_time_val / (10000);
   4975 
   4976         if (val < 1000) {
   4977            time_refresh = 0;
   4978         } else if (val >= 1000 && val < 1500) {
   4979            time_refresh = 1;
   4980         } else if (val >= 1500 && val < 2000) {
   4981            time_refresh = 2;
   4982         } else if (val >= 2000 && val < 2500) {
   4983            time_refresh = 3;
   4984         } else if (val >= 2500 && val < 3000) {
   4985            time_refresh = 4;
   4986         } else if (val >= 3000 && val < 3500) {
   4987            time_refresh = 5;
   4988         } else if (val >= 3500 && val < 4000) {
   4989            time_refresh = 6;
   4990         } else if (val >= 4000 && val < 4500) {
   4991            time_refresh = 7;
   4992         } else if (val >= 4500 && val <= 5000) {
   4993            time_refresh = 8;
   4994         }
   4995 
   4996 
   4997         /* enable WRED refresh */
   4998         SOC_IF_ERROR_RETURN(READ_WRED_REFRESH_CONTROLr(unit, &rval));
   4999         soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval,
   5000                 REFRESH_DISABLEf, 0);
   5001         soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval,
   5002                 REFRESH_PERIODf, time_refresh);
   5003         SOC_IF_ERROR_RETURN(WRITE_WRED_REFRESH_CONTROLr(unit, rval));
   5004 
   5005 
   5006         SOC_IF_ERROR_RETURN
   5007             (soc_trident3_sc_reg32_get(unit, MMU_1DBG_Cr, 0, 0, 0, &rval));
   5008         soc_reg_field_set(unit, MMU_1DBG_Cr, &rval, FIELD_Af, 1);
   5009         SOC_IF_ERROR_RETURN
   5010             (soc_trident3_sc_reg32_set(unit, MMU_1DBG_Cr, -1, -1, 0, rval));
   5011         SOC_IF_ERROR_RETURN
   5012             (soc_trident3_sc_reg32_set(unit, MMU_2DBG_C_1r, -1, -1, 0, 0x4));
   5013     }
   5014     return SOC_E_NONE;
   5015 }
   5016 
   5017 STATIC int
   5018 _soc_hx5_mmu_config_shared_update_check(int val1, int val2, int flags)
   5019 {
   5020     int rv = 0;
   5021     if (flags == 1) {
   5022         if (val1 > val2) {
   5023             rv = 1;
   5024         }
   5025     } else {
   5026         if (val1 < val2) {
   5027             rv = 1;
   5028         }
   5029     }
   5030     return rv;
   5031 }
   5032 
   5033 #define HX5_MMU_SHARED_LIMIT_CHK(val1, val2, flags) \
   5034     _soc_hx5_mmu_config_shared_update_check((val1), (val2), (flags))
   5035 
   5036 int
   5037 soc_hx5_mmu_config_shared_buf_recalc(int unit, int res, int thdi_shd,
   5038                                     int thdo_db_shd, int thdo_qe_shd,
   5039                                     int post_update)
   5040 {
   5041     soc_info_t *si;
   5042     int pipe;
   5043     uint32 entry0[SOC_MAX_MEM_WORDS], cur_limit, rval = 0, rval2 = 0;
   5044     uint64 rval64;
   5045     thdi_port_pg_config_entry_t pg_config_mem;
   5046     mmu_thdo_config_qgroup_entry_t cfg_qgrp;
   5047     int port, base, numq, idx, midx;
   5048     soc_mem_t base_mem = INVALIDm, base_mem2 = INVALIDm;
   5049     soc_mem_t mem = INVALIDm, mem2 = INVALIDm;
   5050     soc_reg_t reg = INVALIDr;
   5051     soc_field_t field = INVALIDf;
   5052     int granularity, index1;
   5053 
   5054     si = &SOC_INFO(unit);
   5055     COMPILER_64_SET(rval64, 0, 0);
   5056 
   5057     /***********************************
   5058      * THDI
   5059  */
   5060     if (res & 0x1) { /* if (res & THDI) { */
   5061 
   5062         for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   5063             /* THDI SP entries */
   5064             rval = 0;
   5065             reg = THDI_BUFFER_CELL_LIMIT_SPr;
   5066             field = LIMITf;
   5067             granularity = 1;
   5068             SOC_IF_ERROR_RETURN
   5069                 (READ_THDI_BUFFER_CELL_LIMIT_SPr(unit, idx, &rval));
   5070             cur_limit = soc_reg_field_get(unit, reg, rval, field);
   5071             if ((cur_limit != 0) &&
   5072                 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdi_shd/granularity,
   5073                                         post_update)) {
   5074                 soc_reg_field_set(unit, reg, &rval, field, (thdi_shd/granularity));
   5075                 SOC_IF_ERROR_RETURN(
   5076                     soc_trident3_xpe_reg32_set(unit, reg,
   5077                                                -1, -1, idx, rval));
   5078             }
   5079         }
   5080 
   5081         /* Input per port settings */
   5082         base_mem = THDI_PORT_PG_CONFIGm;
   5083         PBMP_ALL_ITER(unit, port) {
   5084             pipe = si->port_pipe[port];
   5085             mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe];
   5086             field = PG_SHARED_LIMITf;
   5087             granularity = 1;
   5088             /* Input port per Port-PG settings */
   5089             for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) {
   5090                 midx = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
   5091                 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem));
   5092                 SOC_IF_ERROR_RETURN
   5093                     (soc_mem_read(unit, mem, MEM_BLOCK_ALL,
   5094                                   midx, &pg_config_mem));
   5095                 if (!soc_mem_field32_get(unit, mem, &pg_config_mem,
   5096                                          PG_SHARED_DYNAMICf)) {
   5097                     cur_limit = soc_mem_field32_get(unit, mem, &pg_config_mem,
   5098                                                     field);
   5099                     if ((cur_limit != 0) &&
   5100                         HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdi_shd/granularity,
   5101                                                 post_update)) {
   5102                         soc_mem_field32_set(unit, mem, &pg_config_mem,
   5103                                             field, thdi_shd/granularity);
   5104                     }
   5105                 }
   5106 
   5107                 SOC_IF_ERROR_RETURN
   5108                     (soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   5109                                    midx, &pg_config_mem));
   5110             }
   5111         }
   5112     }
   5113 
   5114     /***********************************
   5115      * THDO
   5116  */
   5117     if (res & 0x2) { /* if (res & THDO) { */
   5118         /* Per SP settings */
   5119         for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   5120             /* DB entries */
   5121             rval = 0;
   5122             reg = MMU_THDM_DB_POOL_SHARED_LIMITr;
   5123             field = SHARED_LIMITf;
   5124             granularity = 1;
   5125             SOC_IF_ERROR_RETURN
   5126                 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
   5127             cur_limit = soc_reg_field_get(unit, reg, rval, field);
   5128             if ((cur_limit != 0) &&
   5129                 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity,
   5130                                         post_update)) {
   5131                 soc_reg_field_set(unit, reg, &rval, field, (thdo_db_shd/granularity));
   5132                 SOC_IF_ERROR_RETURN
   5133                     (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
   5134             }
   5135 
   5136             rval = 0;
   5137             reg = MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr;
   5138             field = YELLOW_SHARED_LIMITf;
   5139             granularity = 8;
   5140             SOC_IF_ERROR_RETURN
   5141                 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
   5142             cur_limit = soc_reg_field_get(unit, reg, rval, field);
   5143             if ((cur_limit != 0) &&
   5144                 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, sal_ceil_func(thdo_db_shd, granularity),
   5145                                         post_update)) {
   5146                 soc_reg_field_set(unit, reg, &rval, field, sal_ceil_func(thdo_db_shd, granularity));
   5147                 SOC_IF_ERROR_RETURN
   5148                     (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
   5149             }
   5150 
   5151             rval = 0;
   5152             reg = MMU_THDM_DB_POOL_RED_SHARED_LIMITr;
   5153             field = RED_SHARED_LIMITf;
   5154             granularity = 8;
   5155             SOC_IF_ERROR_RETURN
   5156                 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
   5157             cur_limit = soc_reg_field_get(unit, reg, rval, field);
   5158             if ((cur_limit != 0) &&
   5159                 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, sal_ceil_func(thdo_db_shd, granularity),
   5160                                         post_update)) {
   5161                 soc_reg_field_set(unit, reg, &rval, field, sal_ceil_func(thdo_db_shd, granularity));
   5162                 SOC_IF_ERROR_RETURN
   5163                     (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
   5164             }
   5165 
   5166             /* MCQE */
   5167             rval = 0;
   5168             reg = MMU_THDM_MCQE_POOL_SHARED_LIMITr;
   5169             field = SHARED_LIMITf;
   5170             granularity = 1; /* Value retrieved from QE. Hence no further
   5171                               * granularity for Non-color Shd Limit */
   5172             SOC_IF_ERROR_RETURN
   5173                 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
   5174             cur_limit = soc_reg_field_get(unit, reg, rval, field);
   5175             if ((cur_limit != 0) &&
   5176                 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_qe_shd/granularity,
   5177                                         post_update)) {
   5178                 soc_reg_field_set(unit, reg, &rval, field,
   5179                                   (thdo_qe_shd/granularity));
   5180                 SOC_IF_ERROR_RETURN
   5181                     (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
   5182             }
   5183 
   5184             rval = 0;
   5185             reg = MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr;
   5186             field = YELLOW_SHARED_LIMITf;
   5187             granularity = 8;
   5188             SOC_IF_ERROR_RETURN
   5189                 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
   5190             cur_limit = soc_reg_field_get(unit, reg, rval, field);
   5191             if ((cur_limit != 0) &&
   5192                 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_qe_shd/granularity,
   5193                                         post_update)) {
   5194                 soc_reg_field_set(unit, reg, &rval, field,
   5195                                   (thdo_qe_shd/granularity));
   5196                 SOC_IF_ERROR_RETURN
   5197                     (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
   5198             }
   5199 
   5200             rval = 0;
   5201             reg = MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr;
   5202             field = RED_SHARED_LIMITf;
   5203             granularity = 8;
   5204             SOC_IF_ERROR_RETURN
   5205                 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
   5206             cur_limit = soc_reg_field_get(unit, reg, rval, field);
   5207             if ((cur_limit != 0) &&
   5208                 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_qe_shd/granularity,
   5209                                         post_update)) {
   5210                 soc_reg_field_set(unit, reg, &rval, field,
   5211                                   (thdo_qe_shd/granularity));
   5212                 SOC_IF_ERROR_RETURN
   5213                     (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
   5214             }
   5215         }
   5216 
   5217         /* configure Q-groups */
   5218         base_mem = MMU_THDU_CONFIG_QGROUPm;
   5219         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   5220             mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe];
   5221             for (idx = 0; idx < SOC_HX5_MMU_CFG_QGROUP_MAX; idx++) {
   5222                 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp));
   5223 
   5224                 SOC_IF_ERROR_RETURN
   5225                         (soc_mem_read(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp));
   5226 
   5227                 field = Q_SHARED_LIMIT_CELLf;
   5228                 granularity = 1;
   5229                 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, Q_LIMIT_DYNAMIC_CELLf)) {
   5230                     cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
   5231                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity,
   5232                                                 post_update)) {
   5233                         soc_mem_field32_set(unit, mem, &cfg_qgrp,
   5234                                             field, thdo_db_shd/granularity);
   5235                     }
   5236                 }
   5237 
   5238                 granularity = 8;
   5239                 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp,
   5240                                          Q_COLOR_LIMIT_DYNAMIC_CELLf)) {
   5241                     field = LIMIT_RED_CELLf;
   5242                     cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
   5243                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity,
   5244                                                 post_update)) {
   5245                         soc_mem_field32_set(unit, mem, &cfg_qgrp,
   5246                                             field, thdo_db_shd/granularity);
   5247                     }
   5248 
   5249                     field = LIMIT_YELLOW_CELLf;
   5250                     cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
   5251                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity,
   5252                                                 post_update)) {
   5253                         soc_mem_field32_set(unit, mem, &cfg_qgrp,
   5254                                             field, thdo_db_shd/granularity);
   5255                     }
   5256                 }
   5257 
   5258                 SOC_IF_ERROR_RETURN
   5259                         (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp));
   5260             }
   5261         }
   5262 
   5263         /* Output port per port per queue setting for UC queue */
   5264         PBMP_PORT_ITER(unit, port) {
   5265             base_mem = MMU_THDU_CONFIG_QUEUEm;
   5266             pipe = si->port_pipe[port];
   5267 
   5268             /* per port UC queue */
   5269             numq = si->port_num_uc_cosq[port];
   5270             base = si->port_uc_cosq_base[port];
   5271 
   5272             if (numq == 0) {
   5273                 continue;
   5274             }
   5275             mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe];
   5276             for (idx = 0; idx < numq; idx++) {
   5277                 sal_memset(entry0, 0, sizeof(mmu_thdu_config_queue_entry_t));
   5278 
   5279                 SOC_IF_ERROR_RETURN
   5280                     (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
   5281 
   5282                 field = Q_SHARED_LIMIT_CELLf;
   5283                 granularity = 1;
   5284                 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf)) {
   5285                     cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5286                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity,
   5287                                                 post_update)) {
   5288                         soc_mem_field32_set(unit, mem, entry0,
   5289                                             field, thdo_db_shd/granularity);
   5290                     }
   5291                 }
   5292 
   5293                 granularity = 8;
   5294                 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMIC_CELLf)) {
   5295                     field = LIMIT_YELLOW_CELLf;
   5296                     cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5297                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, sal_ceil_func(thdo_db_shd, granularity),
   5298                                                 post_update)) {
   5299                         soc_mem_field32_set(unit, mem, entry0,
   5300                                             field, sal_ceil_func(thdo_db_shd, granularity));
   5301                     }
   5302                     field = LIMIT_RED_CELLf;
   5303                     cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5304                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5305                                 sal_ceil_func(thdo_db_shd, granularity), post_update)) {
   5306                         soc_mem_field32_set(unit, mem, entry0,
   5307                                             field, sal_ceil_func(thdo_db_shd, granularity));
   5308                     }
   5309                 }
   5310                 SOC_IF_ERROR_RETURN
   5311                     (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
   5312             }
   5313 
   5314             /* Per port-SP unicast */
   5315             base_mem = MMU_THDU_CONFIG_PORTm;
   5316             mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe];
   5317             for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   5318                 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
   5319                 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t));
   5320 
   5321                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL,
   5322                                     index1, entry0));
   5323 
   5324                 field = SHARED_LIMITf;
   5325                 granularity = 1;
   5326                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5327                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5328                             thdo_db_shd/granularity, post_update)) {
   5329                     soc_mem_field32_set(unit, mem, entry0,
   5330                                         field, thdo_db_shd/granularity);
   5331                 }
   5332 
   5333                 granularity = 8;
   5334                 field = YELLOW_LIMITf;
   5335                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5336                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5337                             thdo_db_shd/granularity, post_update)) {
   5338                     soc_mem_field32_set(unit, mem, entry0,
   5339                                         field, thdo_db_shd/granularity);
   5340                 }
   5341                 field = RED_LIMITf;
   5342                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5343                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5344                             thdo_db_shd/granularity, post_update)) {
   5345                     soc_mem_field32_set(unit, mem, entry0,
   5346                                         field, thdo_db_shd/granularity);
   5347                 }
   5348 
   5349                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   5350                                                   index1, entry0));
   5351             }
   5352         }
   5353 
   5354         /* Output port per port per queue setting for MC queue */
   5355         PBMP_PORT_ITER(unit, port) {
   5356             base_mem = MMU_THDM_DB_PORTSP_CONFIGm;
   5357             base_mem2 = MMU_THDM_MCQE_PORTSP_CONFIGm;
   5358             pipe = si->port_pipe[port];
   5359 
   5360             /* Per Port-SP */
   5361             mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe];
   5362             mem2 = SOC_MEM_UNIQUE_ACC(unit, base_mem2)[pipe];
   5363             for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) {
   5364                 /* DB entries - Port-SP */
   5365                 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
   5366                 sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_entry_t));
   5367 
   5368                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL,
   5369                                     index1, entry0));
   5370 
   5371                 field = SHARED_LIMITf;
   5372                 granularity = 1;
   5373                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5374                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5375                             thdo_db_shd/granularity, post_update)) {
   5376                     soc_mem_field32_set(unit, mem, entry0,
   5377                                         field, thdo_db_shd/granularity);
   5378                 }
   5379 
   5380                 field = RED_SHARED_LIMITf;
   5381                 granularity = 8;
   5382                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5383                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5384                             thdo_db_shd/granularity, post_update)) {
   5385                     soc_mem_field32_set(unit, mem, entry0,
   5386                                         field, thdo_db_shd/granularity);
   5387                 }
   5388 
   5389                 field = YELLOW_SHARED_LIMITf;
   5390                 granularity = 8;
   5391                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5392                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5393                             thdo_db_shd/granularity, post_update)) {
   5394                     soc_mem_field32_set(unit, mem, entry0,
   5395                                         field, thdo_db_shd/granularity);
   5396                 }
   5397 
   5398                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   5399                                     index1, entry0));
   5400 
   5401                 /* MCQE - Port-SP*/
   5402                 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_entry_t));
   5403 
   5404                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem2, MEM_BLOCK_ALL,
   5405                                     index1, entry0));
   5406                 field = SHARED_LIMITf;
   5407                 granularity = 4;
   5408                 cur_limit = soc_mem_field32_get(unit, mem2, entry0, field);
   5409                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5410                             thdo_qe_shd/granularity, post_update)) {
   5411                     soc_mem_field32_set(unit, mem2, entry0,
   5412                                         field, thdo_qe_shd/granularity);
   5413                 }
   5414 
   5415                 field = RED_SHARED_LIMITf;
   5416                 granularity = 8;
   5417                 cur_limit = soc_mem_field32_get(unit, mem2, entry0, field);
   5418                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5419                             thdo_qe_shd/granularity, post_update)) {
   5420                     soc_mem_field32_set(unit, mem2, entry0,
   5421                                         field, thdo_qe_shd/granularity);
   5422                 }
   5423 
   5424                 field = YELLOW_SHARED_LIMITf;
   5425                 granularity = 8;
   5426                 cur_limit = soc_mem_field32_get(unit, mem2, entry0, field);
   5427                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5428                             thdo_qe_shd/granularity, post_update)) {
   5429                     soc_mem_field32_set(unit, mem2, entry0,
   5430                                         field, thdo_qe_shd/granularity);
   5431                 }
   5432                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL,
   5433                                     index1, entry0));
   5434 
   5435             }
   5436 
   5437             /* DB entries - Queue */
   5438             numq = si->port_num_cosq[port];
   5439             base = si->port_cosq_base[port];
   5440             if (numq == 0) {
   5441                 continue;
   5442             }
   5443 
   5444             base_mem = MMU_THDM_DB_QUEUE_CONFIGm;
   5445             mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe];
   5446 
   5447             for (idx = 0; idx < numq; idx++) {
   5448                 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_entry_t));
   5449 
   5450                 SOC_IF_ERROR_RETURN
   5451                     (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
   5452 
   5453                 field = Q_SHARED_LIMITf;
   5454                 granularity = 1;
   5455                 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) {
   5456                     cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5457                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5458                                 thdo_db_shd/granularity, post_update)) {
   5459                         soc_mem_field32_set(unit, mem, entry0,
   5460                                             field, thdo_db_shd/granularity);
   5461                     }
   5462                 }
   5463 
   5464                 granularity = 8;
   5465                 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) {
   5466                     field = YELLOW_SHARED_LIMITf;
   5467                     cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5468                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5469                                 thdo_db_shd/granularity, post_update)) {
   5470                         soc_mem_field32_set(unit, mem, entry0,
   5471                                             field, thdo_db_shd/granularity);
   5472                     }
   5473                     field = RED_SHARED_LIMITf;
   5474                     cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5475                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5476                                 thdo_db_shd/granularity, post_update)) {
   5477                         soc_mem_field32_set(unit, mem, entry0,
   5478                                             field, thdo_db_shd/granularity);
   5479                     }
   5480                 }
   5481                 SOC_IF_ERROR_RETURN
   5482                     (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx,
   5483                                    entry0));
   5484             }
   5485 
   5486             /* MCQE - Queue */
   5487             base_mem = MMU_THDM_MCQE_QUEUE_CONFIGm;
   5488             mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe];
   5489             for (idx = 0; idx < numq; idx++) {
   5490                 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_entry_t));
   5491 
   5492                 SOC_IF_ERROR_RETURN
   5493                     (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
   5494 
   5495                 field = Q_SHARED_LIMITf;
   5496                 granularity = 4;
   5497                 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) {
   5498                     cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5499                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5500                                 thdo_qe_shd/granularity, post_update)) {
   5501                         soc_mem_field32_set(unit, mem, entry0,
   5502                                             field, thdo_qe_shd/granularity);
   5503                     }
   5504                 }
   5505 
   5506                 granularity = 8;
   5507                 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) {
   5508                     field = YELLOW_SHARED_LIMITf;
   5509                     cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5510                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5511                                 thdo_qe_shd/granularity, post_update)) {
   5512                         soc_mem_field32_set(unit, mem, entry0,
   5513                                             field, thdo_qe_shd/granularity);
   5514                     }
   5515                     field = RED_SHARED_LIMITf;
   5516                     cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
   5517                     if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5518                                 thdo_qe_shd/granularity, post_update)) {
   5519                         soc_mem_field32_set(unit, mem, entry0,
   5520                                             field, thdo_qe_shd/granularity);
   5521                     }
   5522                 }
   5523                 SOC_IF_ERROR_RETURN
   5524                     (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx,
   5525                                    entry0));
   5526             }
   5527         }
   5528 
   5529         /* RQE */
   5530         for (idx = 0; idx < 11; idx++) {
   5531             rval = 0;
   5532             COMPILER_64_SET(rval64, 0, 0);
   5533 
   5534             SOC_IF_ERROR_RETURN
   5535                 (READ_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, &rval));
   5536 
   5537             reg = MMU_THDR_DB_CONFIG_PRIQr;
   5538             field = SHARED_LIMITf;
   5539             granularity = 1;
   5540             SOC_IF_ERROR_RETURN
   5541                 (soc_reg64_get(unit, reg, REG_PORT_ANY, idx, &rval64));
   5542             if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval,
   5543                                    DYNAMIC_ENABLEf)) {
   5544                 cur_limit = soc_reg64_field32_get(unit, reg, rval64, field);
   5545                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5546                             thdo_db_shd/granularity, post_update)) {
   5547                     soc_reg64_field32_set(unit, reg, &rval64, field,
   5548                                       (thdo_db_shd/granularity));
   5549                     SOC_IF_ERROR_RETURN
   5550                         (soc_reg64_set(unit, reg, REG_PORT_ANY, idx, rval64));
   5551                 }
   5552             }
   5553 
   5554             rval2 = 0;
   5555             reg = MMU_THDR_DB_LIMIT_COLOR_PRIQr;
   5556             granularity = 8;
   5557             SOC_IF_ERROR_RETURN
   5558                 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
   5559 
   5560             if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval,
   5561                                    COLOR_LIMIT_DYNAMICf)) {
   5562                 field = SHARED_RED_LIMITf;
   5563                 cur_limit = soc_reg_field_get(unit, reg, rval2, field);
   5564                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5565                             thdo_db_shd/granularity, post_update)) {
   5566                     soc_reg_field_set(unit, reg, &rval2, field, (thdo_db_shd/granularity));
   5567                 }
   5568 
   5569                 field = SHARED_YELLOW_LIMITf;
   5570                 cur_limit = soc_reg_field_get(unit, reg, rval2, field);
   5571                 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5572                             thdo_db_shd/granularity, post_update)) {
   5573                     soc_reg_field_set(unit, reg, &rval2, field, (thdo_db_shd/granularity));
   5574                 }
   5575                 SOC_IF_ERROR_RETURN
   5576                     (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
   5577             }
   5578 
   5579         }
   5580         /* per pool RQE settings */
   5581         for (idx = 0; idx < 4; idx++) {
   5582             reg = MMU_THDR_DB_CONFIG_SPr;
   5583             field = SHARED_LIMITf;
   5584             granularity = 1;
   5585 
   5586             SOC_IF_ERROR_RETURN
   5587                 (soc_reg64_get(unit, reg, REG_PORT_ANY, idx, &rval64));
   5588             cur_limit = soc_reg_field_get(unit, reg, rval, field);
   5589 
   5590             if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5591                         thdo_db_shd/granularity, post_update)) {
   5592                 soc_reg64_field32_set
   5593                     (unit, reg, &rval64, field, (thdo_db_shd/granularity));
   5594                 SOC_IF_ERROR_RETURN
   5595                     (soc_reg64_set(unit, reg, REG_PORT_ANY, idx, rval64));
   5596             }
   5597 
   5598             reg = MMU_THDR_DB_SP_SHARED_LIMITr;
   5599             granularity = 8;
   5600 
   5601             SOC_IF_ERROR_RETURN
   5602                 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
   5603 
   5604             field = SHARED_YELLOW_LIMITf;
   5605             cur_limit = soc_reg_field_get(unit, reg, rval, field);
   5606 
   5607             if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5608                         thdo_db_shd/granularity, post_update)) {
   5609                 soc_reg_field_set
   5610                     (unit, reg, &rval2, field, (thdo_db_shd/granularity));
   5611             }
   5612 
   5613             field = SHARED_RED_LIMITf;
   5614             cur_limit = soc_reg_field_get(unit, reg, rval, field);
   5615 
   5616             if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit,
   5617                         thdo_db_shd/granularity, post_update)) {
   5618                 soc_reg_field_set
   5619                     (unit, reg, &rval2, field, (thdo_db_shd/granularity));
   5620             }
   5621             SOC_IF_ERROR_RETURN
   5622                 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
   5623         }
   5624     }
   5625     return SOC_E_NONE;
   5626 }
   5627 
   5628 soc_pstats_tbl_desc_t
   5629 _soc_hx5_pstats_tbl_desc_all = {SOC_BLK_NONE, INVALIDm, FALSE, FALSE};
   5630 /* pstats support */
   5631 soc_pstats_tbl_desc_t _soc_hx5_pstats_tbl_desc[] = {
   5632     /* List all the potential memories */
   5633 #ifdef BCM_PSTATS_MEASURE
   5634     {
   5635         SOC_BLK_MMU_GLB,
   5636         INVALIDm,
   5637         FALSE, FALSE,
   5638         {
   5639             {MMU_INTFO_TIMESTAMPm},
   5640             {INVALIDm}
   5641         }
   5642     },
   5643 #endif
   5644     {
   5645         SOC_BLK_MMU_GLB,
   5646         INVALIDm,
   5647         FALSE, FALSE,
   5648         {
   5649             {MMU_INTFO_UTC_TIMESTAMPm},
   5650             {INVALIDm}
   5651         }
   5652     },
   5653     {
   5654         SOC_BLK_MMU_XPE,
   5655         MMU_THDU_UCQ_STATS_TABLEm,
   5656         TRUE, TRUE
   5657     },
   5658     {
   5659         SOC_BLK_MMU_XPE,
   5660         THDI_PKT_STAT_SP_SHARED_COUNTm,
   5661         FALSE, FALSE
   5662     },
   5663     {
   5664         SOC_BLK_MMU_XPE,
   5665         MMU_THDM_DB_POOL_MCUC_PKSTATm,
   5666         FALSE, FALSE
   5667 #ifdef BCM_PSTATS_MEASURE
   5668     },
   5669     {
   5670         SOC_BLK_MMU_GLB,
   5671         INVALIDm,
   5672         FALSE, FALSE,
   5673         {
   5674             {MMU_INTFO_TIMESTAMPm},
   5675             {INVALIDm}
   5676         }
   5677 #endif
   5678     }
   5679 };
   5680 
   5681 void
   5682 soc_helix5_mmu_pstats_tbl_config_all(int unit)
   5683 {
   5684     soc_control_t *soc = SOC_CONTROL(unit);
   5685     soc_pstats_mem_desc_t *desc, *desc_all;
   5686     int ti, mi, di = 0;
   5687 
   5688     desc_all = _soc_hx5_pstats_tbl_desc_all.desc;
   5689     /* Check and strip invalid memories */
   5690     for (ti = 0; ti < soc->pstats_tbl_desc_count; ti++) {
   5691         mi = 0;
   5692         desc = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].desc;
   5693         while (desc[mi].mem != INVALIDm) {
   5694             desc_all[di] = desc[mi];
   5695             di++;
   5696             mi++;
   5697         }
   5698     }
   5699     desc_all[di].mem = INVALIDm;
   5700 
   5701     soc->pstats_tbl_desc = &_soc_hx5_pstats_tbl_desc_all;
   5702     soc->pstats_tbl_desc_count = 1;
   5703 }
   5704 
   5705 void
   5706 soc_helix5_mmu_pstats_tbl_config(int unit)
   5707 {
   5708     soc_control_t *soc = SOC_CONTROL(unit);
   5709     soc_pstats_mem_desc_t *desc;
   5710     soc_mem_t bmem;
   5711     int pe, mor_dma;
   5712     int ti, mi, xpe, pipe;
   5713 
   5714     soc->pstats_tbl_desc = _soc_hx5_pstats_tbl_desc;
   5715     soc->pstats_tbl_desc_count = COUNTOF(_soc_hx5_pstats_tbl_desc);
   5716     soc->pstats_mode = PSTATS_MODE_NULL;
   5717 
   5718     /* Check and strip invalid memories */
   5719     for (ti = 0; ti < soc->pstats_tbl_desc_count; ti++) {
   5720         mi = 0;
   5721         desc = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].desc;
   5722         bmem = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].bmem;
   5723         if (bmem == INVALIDm) {
   5724             while (desc[mi].mem != INVALIDm) {
   5725                 desc[mi].width = soc_mem_entry_words(unit, desc[mi].mem);
   5726                 desc[mi].entries = soc_mem_index_count(unit, desc[mi].mem);
   5727                 mi++;
   5728             }
   5729             continue;
   5730         }
   5731         pe = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].pipe_enum;
   5732         mor_dma = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].mor_dma;
   5733         for (xpe = 0; xpe < NUM_XPE(unit); xpe++) {
   5734             for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   5735                 desc[mi].mem = pe ? SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, bmem, xpe, pipe) :
   5736                                     SOC_MEM_UNIQUE_ACC(unit, bmem)[xpe];
   5737                 if (desc[mi].mem == INVALIDm) {
   5738                     continue;
   5739                 }
   5740                 desc[mi].width = soc_mem_entry_words(unit, desc[mi].mem);
   5741                 desc[mi].entries = soc_mem_index_count(unit, desc[mi].mem);
   5742                 if (mor_dma) {
   5743                     desc[mi].mor_dma = TRUE;
   5744                 }
   5745                 mi++;
   5746                 if (!pe) {
   5747                     break;
   5748                 }
   5749             }
   5750         }
   5751         desc[mi].mem = INVALIDm;
   5752     }
   5753 
   5754     if (soc_property_get(unit, "pstats_desc_all", 1)) {
   5755         /* Use single desc chain */
   5756         soc_helix5_mmu_pstats_tbl_config_all(unit);
   5757     }
   5758 }
   5759 
   5760 int
   5761 soc_helix5_mmu_pstats_mode_set(int unit, uint32 flags)
   5762 {
   5763     soc_control_t *soc = SOC_CONTROL(unit);
   5764     int pf = 0;
   5765     uint32 rval = 0;
   5766     int rv;
   5767 
   5768     SOC_PSTATS_LOCK(unit);
   5769 
   5770     if (flags & _HX5_MMU_PSTATS_HWM_MOD) {
   5771         soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval,
   5772                           HWM_MODEf, 1);
   5773         pf |= _HX5_MMU_PSTATS_HWM_MOD;
   5774         if (flags & _HX5_MMU_PSTATS_RESET_ON_READ) {
   5775             soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval,
   5776                               HWM_RESET_ON_READf, 1);
   5777             pf |= _HX5_MMU_PSTATS_RESET_ON_READ;
   5778         }
   5779     }
   5780 
   5781     if (soc_feature(unit, soc_feature_mor_dma) &&
   5782             (flags & _HX5_MMU_PSTATS_MOR_EN)) {
   5783         soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval,
   5784                 MOR_ENf, 1);
   5785     }
   5786     if (flags & _HX5_MMU_PSTATS_MOR_EN) {
   5787         pf |= _HX5_MMU_PSTATS_MOR_EN;
   5788     }
   5789 
   5790     if (flags & _HX5_MMU_PSTATS_ENABLE) {
   5791         soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval,
   5792                 ENABLEf, 1);
   5793         pf |= _HX5_MMU_PSTATS_ENABLE;
   5794         if ((flags & _HX5_MMU_PSTATS_SYNC) ||
   5795                 (flags & _HX5_MMU_PSTATS_HWM_MOD &&
   5796                  flags & _HX5_MMU_PSTATS_RESET_ON_READ)) {
   5797             soc->pstats_mode = PSTATS_MODE_PKT_SYNC;
   5798             pf |= _HX5_MMU_PSTATS_SYNC;
   5799         } else {
   5800             soc->pstats_mode = PSTATS_MODE_PKT_BUFF;
   5801         }
   5802     } else {
   5803         soc->pstats_mode = PSTATS_MODE_NULL;
   5804     }
   5805 
   5806     soc->pstats_flags = pf;
   5807 
   5808     rv = WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval);
   5809 
   5810     SOC_PSTATS_UNLOCK(unit);
   5811 
   5812     return rv;
   5813 }
   5814 
   5815 int
   5816 soc_helix5_mmu_pstats_mode_get(int unit, uint32 *flags)
   5817 {
   5818     int pf = 0;
   5819     uint32 rval = 0;
   5820     int rv;
   5821     soc_reg_t reg = MMU_GCFG_PKTSTAT_OOBSTATr;
   5822 
   5823     SOC_PSTATS_LOCK(unit);
   5824 
   5825     rv = READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval);
   5826     if (SOC_FAILURE(rv)) {
   5827         SOC_PSTATS_UNLOCK(unit);
   5828         return rv;
   5829     }
   5830 
   5831     if (soc_reg_field_get(unit, reg, rval, ENABLEf)) {
   5832         pf |= _HX5_MMU_PSTATS_ENABLE;
   5833         pf |= _HX5_MMU_PSTATS_PKT_MOD;
   5834     }
   5835     if (soc_reg_field_get(unit, reg, rval, HWM_MODEf)) {
   5836         pf |= _HX5_MMU_PSTATS_HWM_MOD;
   5837         if (soc_reg_field_get(unit, reg, rval, HWM_RESET_ON_READf)) {
   5838             pf |= _HX5_MMU_PSTATS_RESET_ON_READ;
   5839         }
   5840     }
   5841 
   5842     SOC_PSTATS_UNLOCK(unit);
   5843 
   5844     *flags = pf;
   5845 
   5846     return SOC_E_NONE;
   5847 }
   5848 
   5849 int
   5850 soc_helix5_mmu_pstats_mor_enable(int unit)
   5851 {
   5852     soc_control_t *soc = SOC_CONTROL(unit);
   5853     uint32 rval;
   5854 
   5855 
   5856     if (soc->pstats_flags & _HX5_MMU_PSTATS_MOR_EN) {
   5857         SOC_IF_ERROR_RETURN(READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval));
   5858         if ( ! soc_reg_field_get(unit,
   5859                                  MMU_GCFG_PKTSTAT_OOBSTATr, rval, MOR_ENf)) {
   5860             soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, MOR_ENf, 1);
   5861             SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval));
   5862         }
   5863     }
   5864 
   5865     return SOC_E_NONE;
   5866 }
   5867 
   5868 int
   5869 soc_helix5_mmu_pstats_mor_disable(int unit)
   5870 {
   5871     soc_control_t *soc = SOC_CONTROL(unit);
   5872     uint32 rval;
   5873 
   5874     if (!soc_feature(unit, soc_feature_mor_dma) &&
   5875         (soc->pstats_flags & _HX5_MMU_PSTATS_MOR_EN)) {
   5876         SOC_IF_ERROR_RETURN(READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval));
   5877         soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, MOR_ENf, 0);
   5878         SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval));
   5879     }
   5880 
   5881     return SOC_E_NONE;
   5882 }
   5883 
   5884 /*
   5885  * Function:
   5886  *      soc_hx5_port_schedule_tdm_init
   5887  * Purpose:
   5888  *      Initialize TDM information in port_schedule_state that will be passed
   5889  *      to DV FlexPort API
   5890  * Parameters:
   5891  *      unit                 - (IN)  Unit number.
   5892  *      port_schedule_state  - (OUT) Port resource state.
   5893  * Returns:
   5894  *      BCM_E_xxx
   5895  * Notes:
   5896  *      If called during Scheduler Initialization, only below values need to be
   5897  *      properly set:
   5898  *        soc_tdm_schedule_pipe_t::num_slices
   5899  *        soc_tdm_schedule_t:: cal_len
   5900  *        soc_tdm_schedule_t:: num_ovs_groups
   5901  *        soc_tdm_schedule_t:: ovs_group_len
   5902  *        soc_tdm_schedule_t:: num_pkt_sch_or_ovs_space
   5903  *        soc_tdm_schedule_t:: pkt_sch_or_ovs_space_len
   5904  */
   5905 int
   5906 soc_hx5_port_schedule_tdm_init(int unit,
   5907                             soc_port_schedule_state_t *port_schedule_state)
   5908 {
   5909     soc_control_t *soc = SOC_CONTROL(unit);
   5910     _soc_helix5_tdm_temp_t *tdm = soc->tdm_info;
   5911     /*soc_info_t *si = &SOC_INFO(unit);*/
   5912     soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd;
   5913     soc_tdm_schedule_t *sched;
   5914     int pipe, hpipe, phy_port, is_flexport, group, slot;
   5915     int *port_p2PBLK_inst_mapping;
   5916 
   5917     if (tdm == NULL) {
   5918         return SOC_E_INIT;
   5919     }
   5920 
   5921     is_flexport = port_schedule_state->is_flexport;
   5922 	/*
   5923     port_schedule_state->calendar_type = si->fabric_port_enable ?
   5924                                         _HX5_TDM_CALENDAR_UNIVERSAL :
   5925                                         _HX5_TDM_CALENDAR_ETHERNET_OPTIMIZED;
   5926 	*/
   5927     /* Construct tdm_ingress_schedule_pipe and tdm_egress_schedule_pipe */
   5928     for (pipe = 0; pipe <  HELIX5_TDM_PIPES_PER_DEV; pipe++) {
   5929         tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe];
   5930         tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe];
   5931 
   5932         tdm_ischd->num_slices = HELIX5_OVS_HPIPE_COUNT_PER_PIPE;
   5933         tdm_eschd->num_slices = HELIX5_OVS_HPIPE_COUNT_PER_PIPE;
   5934 
   5935         if (is_flexport) {
   5936             /* TDM Calendar is always in slice 0 */
   5937             sal_memcpy(tdm_ischd->tdm_schedule_slice[0].linerate_schedule,
   5938                         tdm->tdm_pipe[pipe].idb_tdm,
   5939                         sizeof(int)*_HX5_TDM_LENGTH);
   5940             sal_memcpy(tdm_eschd->tdm_schedule_slice[0].linerate_schedule,
   5941                         tdm->tdm_pipe[pipe].mmu_tdm,
   5942                         sizeof(int)*_HX5_TDM_LENGTH);
   5943         }
   5944 
   5945         /* OVS */
   5946         for (hpipe = 0; hpipe < HELIX5_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) {
   5947             /* IDB OVERSUB*/
   5948             sched = &tdm_ischd->tdm_schedule_slice[hpipe];
   5949             sched->cal_len = _HX5_TDM_LENGTH;
   5950             sched->num_ovs_groups = HELIX5_TDM_OVS_GROUPS_PER_HPIPE;
   5951             sched->ovs_group_len = HELIX5_TDM_OVS_GROUP_LENGTH;
   5952             sched->num_pkt_sch_or_ovs_space = 1;
   5953             sched->pkt_sch_or_ovs_space_len = _HX5_PKT_SCH_LENGTH;
   5954 
   5955             if (is_flexport) {
   5956                 for (group = 0; group < HELIX5_TDM_OVS_GROUPS_PER_HPIPE; group++) {
   5957                     for (slot = 0; slot < HELIX5_TDM_OVS_GROUP_LENGTH; slot++) {
   5958                         sched->oversub_schedule[group][slot] =
   5959                             tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot];
   5960                     }
   5961                 }
   5962                 for (slot = 0; slot < _HX5_PKT_SCH_LENGTH; slot++) {
   5963                     sched->pkt_sch_or_ovs_space[0][slot] =
   5964                         tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot];
   5965                 }
   5966             }
   5967 
   5968             /* MMU OVERSUB */
   5969             sched = &tdm_eschd->tdm_schedule_slice[hpipe];
   5970             sched->cal_len = _HX5_TDM_LENGTH;
   5971             sched->num_ovs_groups = HELIX5_TDM_OVS_GROUPS_PER_HPIPE;
   5972             sched->ovs_group_len = HELIX5_TDM_OVS_GROUP_LENGTH;
   5973             sched->num_pkt_sch_or_ovs_space = 1;
   5974             sched->pkt_sch_or_ovs_space_len = _HX5_PKT_SCH_LENGTH;
   5975 
   5976             if (is_flexport) {
   5977                 for (group = 0; group < HELIX5_TDM_OVS_GROUPS_PER_HPIPE; group++) {
   5978                     for (slot = 0; slot < HELIX5_TDM_OVS_GROUP_LENGTH; slot++) {
   5979                         sched->oversub_schedule[group][slot] =
   5980                             tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot];
   5981                         }
   5982                     }
   5983                 for (slot = 0; slot < _HX5_PKT_SCH_LENGTH; slot++) {
   5984                     sched->pkt_sch_or_ovs_space[0][slot] =
   5985                         tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot];
   5986                 }
   5987             }
   5988         }
   5989     }
   5990 
   5991     if (is_flexport) {
   5992         port_p2PBLK_inst_mapping =
   5993             port_schedule_state->in_port_map.port_p2PBLK_inst_mapping;
   5994         /* pblk info for phy_port */
   5995         for (phy_port = 1; phy_port < HX5_NUM_EXT_PORTS; phy_port++) {
   5996             if (tdm->pblk_info[phy_port].pblk_cal_idx == -1) {
   5997                 continue;
   5998             }
   5999             port_p2PBLK_inst_mapping[phy_port] =
   6000                                         tdm->pblk_info[phy_port].pblk_cal_idx;
   6001         }
   6002     }
   6003     return SOC_E_NONE;
   6004 }
   6005 
   6006 /*
   6007  * Function:
   6008  *      soc_hx5_soc_tdm_update
   6009  * Purpose:
   6010  *      Update TDM information in SOC with TDM state return from DV FlexPort API
   6011  * Parameters:
   6012  *      unit                 - (IN)  Unit number.
   6013  *      port_schedule_state  - (OUT) Port resource state.
   6014  * Returns:
   6015  *      BCM_E_xxx
   6016  * Notes:
   6017  */
   6018 int
   6019 soc_hx5_soc_tdm_update(int unit,
   6020                             soc_port_schedule_state_t *port_schedule_state)
   6021 {
   6022     soc_control_t *soc = SOC_CONTROL(unit);
   6023     _soc_helix5_tdm_temp_t *tdm = soc->tdm_info;
   6024     soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd;
   6025     soc_tdm_schedule_t *sched;
   6026     int pipe, hpipe, phy_port, slot;
   6027     int index, group;
   6028 
   6029     if (tdm == NULL) {
   6030         return SOC_E_INIT;
   6031     }
   6032 
   6033     /* Copy info from soc_port_schedule_state_t to _soc_helix5_tdm_temp_t */
   6034     for (pipe = 0; pipe <  HELIX5_TDM_PIPES_PER_DEV; pipe++) {
   6035         tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe];
   6036         tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe];
   6037 
   6038         /* TDM Calendar is always in slice 0 */
   6039         sal_memcpy(tdm->tdm_pipe[pipe].idb_tdm,
   6040                     tdm_ischd->tdm_schedule_slice[0].linerate_schedule,
   6041                     sizeof(int)*_HX5_TDM_LENGTH);
   6042         sal_memcpy(tdm->tdm_pipe[pipe].mmu_tdm,
   6043                     tdm_eschd->tdm_schedule_slice[0].linerate_schedule,
   6044                     sizeof(int)*_HX5_TDM_LENGTH);
   6045 
   6046         for (hpipe = 0; hpipe < HELIX5_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) {
   6047             sched = &tdm_ischd->tdm_schedule_slice[hpipe];
   6048             for (group = 0; group < HELIX5_TDM_OVS_GROUPS_PER_HPIPE; group++) {
   6049                 for (slot = 0; slot < HELIX5_TDM_OVS_GROUP_LENGTH; slot++) {
   6050                     tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot] =
   6051                         sched->oversub_schedule[group][slot];
   6052                 }
   6053             }
   6054             for (slot = 0; slot < _HX5_PKT_SCH_LENGTH; slot++) {
   6055                 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot] =
   6056                     sched->pkt_sch_or_ovs_space[0][slot];
   6057 
   6058             }
   6059         }
   6060     }
   6061 
   6062     /* pblk info init  */
   6063     for (phy_port = 1; phy_port < HX5_NUM_EXT_PORTS; phy_port++) {
   6064         tdm->pblk_info[phy_port].pblk_cal_idx = -1;
   6065         tdm->pblk_info[phy_port].pblk_hpipe_num = -1;
   6066     }
   6067 
   6068     /* pblk info for phy_port */
   6069     for (pipe = 0; pipe < HELIX5_TDM_PIPES_PER_DEV; pipe++) {
   6070         tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe];
   6071         for (hpipe = 0; hpipe < HELIX5_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) {
   6072             for (group = 0; group < HELIX5_TDM_OVS_GROUPS_PER_HPIPE; group++) {
   6073                 for (index = 0; index < HELIX5_TDM_OVS_GROUP_LENGTH; index++) {
   6074                     phy_port =
   6075                         tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index];
   6076                     if (phy_port < HX5_NUM_EXT_PORTS) {
   6077                         tdm->pblk_info[phy_port].pblk_hpipe_num = hpipe;
   6078                         tdm->pblk_info[phy_port].pblk_cal_idx =
   6079                             port_schedule_state->out_port_map.port_p2PBLK_inst_mapping[phy_port];
   6080                     }
   6081                 }
   6082             }
   6083         }
   6084     }
   6085 
   6086     return SOC_E_NONE;
   6087 }
   6088 
   6089 void
   6090 soc_helix5_port_qsgmii_mode_get(int unit, soc_port_t port, int* qsgmii_mode)
   6091 {
   6092     soc_info_t *si;
   6093     int phy_port, base_port;
   6094 
   6095     si = &SOC_INFO(unit);
   6096 
   6097     phy_port = si->port_l2p_mapping[port];
   6098     base_port = HX5_PORT_BLOCK_BASE_PORT(port);
   6099 
   6100     if ((phy_port >= 1) && (phy_port <= 48)) {
   6101         *qsgmii_mode = soc_property_phys_port_get(unit, base_port,
   6102                                                   spn_PORT_GMII_MODE, 0);
   6103     } else {
   6104         *qsgmii_mode = 0;
   6105     }
   6106 
   6107     return;
   6108 }
   6109 
   6110 int
   6111 soc_hx5_mpls_hash_control_set(int *hash_entry)
   6112 {
   6113     int unit = 0;
   6114     int mpls_4k_banks = 0;
   6115     int index = 0;
   6116     int offset_base = 0, offset_multiplier = 0;
   6117     int hash_control_entry[2];
   6118     uint32 shared_4k_hash_control_entry[8];
   6119 
   6120     static const soc_field_t logical_to_physical_fields[] = {
   6121         LOGICAL_BANK_0_PHYSICAL_BANK_LOCATIONf,
   6122         LOGICAL_BANK_1_PHYSICAL_BANK_LOCATIONf,
   6123         LOGICAL_BANK_2_PHYSICAL_BANK_LOCATIONf,
   6124         LOGICAL_BANK_3_PHYSICAL_BANK_LOCATIONf,
   6125         LOGICAL_BANK_4_PHYSICAL_BANK_LOCATIONf,
   6126         LOGICAL_BANK_5_PHYSICAL_BANK_LOCATIONf,
   6127         LOGICAL_BANK_6_PHYSICAL_BANK_LOCATIONf,
   6128         LOGICAL_BANK_7_PHYSICAL_BANK_LOCATIONf,
   6129         LOGICAL_BANK_8_PHYSICAL_BANK_LOCATIONf,
   6130         LOGICAL_BANK_9_PHYSICAL_BANK_LOCATIONf
   6131     };
   6132 
   6133     static const soc_field_t shared_fields[] = {
   6134         B0_HASH_OFFSETf, B1_HASH_OFFSETf, B2_HASH_OFFSETf, B3_HASH_OFFSETf,
   6135         B4_HASH_OFFSETf, B5_HASH_OFFSETf, B6_HASH_OFFSETf, B7_HASH_OFFSETf
   6136     };
   6137 
   6138     sal_memset(hash_control_entry, 0,
   6139             sizeof(mpls_entry_hash_control_entry_t));
   6140     sal_memset(shared_4k_hash_control_entry, 0,
   6141             sizeof(ip_uat_shared_banks_control_entry_t));
   6142 
   6143     SOC_IF_ERROR_RETURN
   6144         (soc_helix5_hash_bank_count_get(unit, MPLS_ENTRY_SINGLEm,
   6145                                           &mpls_4k_banks));
   6146     SOC_IF_ERROR_RETURN
   6147         (READ_IP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   6148                                         shared_4k_hash_control_entry));
   6149     SOC_IF_ERROR_RETURN
   6150         (READ_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   6151                                        hash_control_entry));
   6152     sal_memcpy(hash_entry, hash_control_entry, sizeof(hash_control_entry));
   6153 
   6154     if (mpls_4k_banks) {
   6155         offset_base = 64 % (mpls_4k_banks);
   6156         offset_multiplier = 64 / (mpls_4k_banks);
   6157     }
   6158 
   6159     soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry,
   6160                         HASH_TABLE_BANK_CONFIGf, ((1 << mpls_4k_banks) - 1));
   6161     for(index = 0; index < mpls_4k_banks; index++) {
   6162         soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry,
   6163                             logical_to_physical_fields[index], index);
   6164         soc_mem_field32_set(unit, IP_UAT_SHARED_BANKS_CONTROLm,
   6165                             shared_4k_hash_control_entry, shared_fields[index],
   6166                             offset_base + ( index * offset_multiplier));
   6167     }
   6168 
   6169     SOC_IF_ERROR_RETURN
   6170         (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   6171                                         hash_control_entry));
   6172 
   6173     return SOC_E_NONE;
   6174 }
   6175 
   6176 
   6177 void
   6178 soc_helix5_temperature_intr(void *unit_vp, void *d1, void *d2,
   6179                               void *d3, void *d4)
   6180 {
   6181     uint32 rval, trval;
   6182     int i, rv, unit = PTR_TO_INT(unit_vp);
   6183 
   6184     if ((rv = READ_TOP_PVTMON_INTR_STATUSr(unit, &rval)) != SOC_E_NONE) {
   6185         LOG_ERROR(BSL_LS_SOC_COMMON,
   6186                   (BSL_META_U(unit,
   6187                               "TD3 Temp Intr, Reg access error.\n")));
   6188     }
   6189     LOG_ERROR(BSL_LS_SOC_COMMON,
   6190               (BSL_META_U(unit,
   6191                           "High temp interrupt: 0x%08x\n"), rval));
   6192     /* Raise event to app for it to take further graceful actions */
   6193     for (i = 0; i < 7; i++) {
   6194         if (i & _soc_hx5_temp_mon_mask[unit]) {
   6195             if ((rv = soc_reg32_get(unit, pvtmon_result_reg[i], REG_PORT_ANY, 0,
   6196                                     &trval)) != SOC_E_NONE) {
   6197                 LOG_ERROR(BSL_LS_SOC_COMMON,
   6198                           (BSL_META_U(unit,
   6199                                       "TD3 Temp Intr, Reg access error.\n")));
   6200             }
   6201             trval = soc_reg_field_get(unit, pvtmon_result_reg[i], trval,
   6202                                       PVT_DATAf);
   6203             /* Convert data to temperature.
   6204              * temp = 434.1-(data*0.5350) = (4341000-(trval*5350))/1000;
   6205              * Note: Since this is a high temp interrupt we can safely assume
   6206              * that this will end up being a +ive value.
   6207              */
   6208             trval = (4341000-(trval*5350))/1000;
   6209 
   6210             LOG_ERROR(BSL_LS_SOC_COMMON,
   6211                       (BSL_META_U(unit,
   6212                                   "TempMon %d: %d deg C.\n"), i, trval));
   6213             (void)soc_event_generate(unit, SOC_SWITCH_EVENT_ALARM,
   6214                                      SOC_SWITCH_EVENT_ALARM_HIGH_TEMP, i, trval);
   6215         }
   6216     }
   6217     /* Optionally hold system in reset.
   6218      * Note: The main intention is to stop the chip from getting fried and halt
   6219      *       all schan accesses as the h/w will not respond anymore.
   6220      *       We are not implementing a gracefull recovery, the unit needs to be
   6221      *       rebooted after this.
   6222      */
   6223     if (soc_property_get(unit, "temp_monitor_shutdown", 1)) {
   6224         if ((rv = WRITE_TOP_PVTMON_INTR_MASKr(unit, 0)) != SOC_E_NONE) {
   6225             LOG_ERROR(BSL_LS_SOC_COMMON,
   6226                       (BSL_META_U(unit,
   6227                                   "TH Temp Intr, Reg access error.\n")));
   6228         }
   6229         if ((rv = WRITE_TOP_SOFT_RESET_REGr(unit, 0)) != SOC_E_NONE) {
   6230             LOG_ERROR(BSL_LS_SOC_COMMON,
   6231                       (BSL_META_U(unit,
   6232                                   "TH Temp Intr, Reg access error.\n")));
   6233         }
   6234         if ((rv = READ_TOP_SOFT_RESET_REG_2r(unit, &rval)) != SOC_E_NONE) {
   6235             LOG_ERROR(BSL_LS_SOC_COMMON,
   6236                       (BSL_META_U(unit,
   6237                                   "TH Temp Intr, Reg access error.\n")));
   6238         }
   6239         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL0_RST_Lf,
   6240                           0);
   6241         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL1_RST_Lf,
   6242                           0);
   6243         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf,
   6244                           1);
   6245         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 1);
   6246         if ((rv = WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)) != SOC_E_NONE) {
   6247             LOG_ERROR(BSL_LS_SOC_COMMON,
   6248                       (BSL_META_U(unit,
   6249                                   "TH Temp Intr, Reg access error.\n")));
   6250         }
   6251         if ((rv = WRITE_TOP_SOFT_RESET_REG_3r(unit, 0)) != SOC_E_NONE) {
   6252             LOG_ERROR(BSL_LS_SOC_COMMON,
   6253                       (BSL_META_U(unit,
   6254                                   "TH Temp Intr, Reg access error.\n")));
   6255         }
   6256 
   6257         /* Stop all schan transactions on this unit */
   6258 #ifdef  INCLUDE_I2C
   6259         if ((rv = soc_i2c_detach(unit)) != SOC_E_NONE) {
   6260             LOG_ERROR(BSL_LS_SOC_COMMON,
   6261                       (BSL_META_U(unit,
   6262                                   "TH Temp Intr, i2c detach error.\n")));
   6263         }
   6264 #endif
   6265         if (!SOC_IS_RCPU_ONLY(unit)) {
   6266             /* Free up DMA memory */
   6267             if ((rv = soc_dma_detach(unit)) != SOC_E_NONE) {
   6268                 LOG_ERROR(BSL_LS_SOC_COMMON,
   6269                           (BSL_META_U(unit,
   6270                                       "TH Temp Intr, dma detach error.\n")));
   6271             }
   6272         }
   6273         if ((rv = soc_mem_scan_stop(unit)) != SOC_E_NONE) {
   6274             LOG_ERROR(BSL_LS_SOC_COMMON,
   6275                       (BSL_META_U(unit,
   6276                                   "TH Temp Intr, mem scan stop error.\n")));
   6277         }
   6278         /* Terminate counter module */
   6279         if ((rv = soc_counter_stop(unit)) != SOC_E_NONE) {
   6280             LOG_ERROR(BSL_LS_SOC_COMMON,
   6281                       (BSL_META_U(unit,
   6282                                   "TH Temp Intr, counter stop error.\n")));
   6283         }
   6284         if (SOC_SBUSDMA_DM_INFO(unit)) {
   6285             if ((rv = soc_sbusdma_desc_detach(unit)) != SOC_E_NONE) {
   6286                 LOG_ERROR(BSL_LS_SOC_COMMON,
   6287                           (BSL_META_U(unit,
   6288                                       "TH Temp Intr, sbusdma stop error.\n")));
   6289             }
   6290         }
   6291         if (soc_feature(unit, soc_feature_arl_hashed)) {
   6292             /* Stop L2X thread */
   6293             if ((rv = soc_l2x_stop(unit)) != SOC_E_NONE) {
   6294                 LOG_ERROR(BSL_LS_SOC_COMMON,
   6295                           (BSL_META_U(unit,
   6296                                       "TH Temp Intr, L2x stop error.\n")));
   6297             }
   6298 
   6299         }
   6300         if ((rv = soc_th_l2_bulk_age_stop(unit)) != SOC_E_NONE) {
   6301             LOG_ERROR(BSL_LS_SOC_COMMON,
   6302                       (BSL_META_U(unit,
   6303                                   "TH Temp Intr, L2 age stop error.\n")));
   6304         }
   6305         /* Disable all interrupts */
   6306 #ifdef BCM_CMICX_SUPPORT
   6307     if (soc_feature(unit, soc_feature_cmicx)) {
   6308         
   6309     }
   6310 #endif
   6311         SCHAN_LOCK(unit);
   6312         /* Clear all outstanding DPCs owned by this unit */
   6313         sal_dpc_cancel(INT_TO_PTR(unit));
   6314         LOG_ERROR(BSL_LS_SOC_COMMON,
   6315                   (BSL_META_U(unit,
   6316                               "\nReboot the system..")));
   6317     }
   6318 }
   6319 
   6320 int
   6321 soc_helix5_temperature_monitor_get(int unit, int temperature_max,
   6322     soc_switch_temperature_monitor_t *temperature_array, int *temperature_count)
   6323 {
   6324     soc_reg_t reg;
   6325     int index;
   6326     uint32 rval;
   6327     int fval, cur, peak;
   6328     int num_entries_out;
   6329     if (temperature_count) {
   6330         *temperature_count = 0;
   6331     }
   6332     if (COUNTOF(pvtmon_result_reg) > temperature_max) {
   6333         num_entries_out = temperature_max;
   6334     } else {
   6335         num_entries_out = COUNTOF(pvtmon_result_reg);
   6336     }
   6337     /* SDK-125480 temperature reading for VTMON 11
   6338      *  Assert TOP_AVS_RST_L.
   6339      */
   6340     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   6341     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6342                       TOP_AVS_RST_Lf, 0);
   6343     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   6344 
   6345     SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_3r(unit, &rval));
   6346     if ((soc_reg_field_get(unit, TOP_PVTMON_CTRL_3r, rval, PVTMON_RESET_Nf) == 0) ||
   6347         (soc_reg_field_get(unit, TOP_PVTMON_CTRL_3r, rval, PVTMON_SELECTf) != 0)) {
   6348         soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_RESET_Nf, 0);
   6349         SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_3r(unit, rval));
   6350         soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_RESET_Nf, 1);
   6351         soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_SELECTf, 0);
   6352         SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_3r(unit, rval));
   6353         sal_usleep(1000);
   6354     }
   6355 
   6356     for (index = 0; index < num_entries_out; index++) {
   6357         reg = pvtmon_result_reg[index];
   6358         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   6359 
   6360         fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf);
   6361         cur = (4341000-(fval*5350))/1000;
   6362 
   6363         fval = soc_reg_field_get(unit, reg, rval, MIN_PVT_DATAf);
   6364         peak = (4341000-(fval*5350))/1000;
   6365 
   6366         if (temperature_array) {
   6367             (temperature_array + index)->curr = cur;
   6368             (temperature_array + index)->peak = peak;
   6369         }
   6370     }
   6371 
   6372     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   6373     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6374                       TOP_PVT_MON_MIN_RST_Lf, 0);
   6375     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   6376     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6377                       TOP_PVT_MON_MIN_RST_Lf, 1);
   6378     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   6379 
   6380     if (temperature_count) {
   6381         *temperature_count=num_entries_out;
   6382     }
   6383     return SOC_E_NONE;
   6384 }
   6385 
   6386 void
   6387 soc_helix5_sbus_ring_map_config(int unit)
   6388 {
   6389     /*
   6390      * SBUS ring and block number:
   6391      * ring 0: IP(1), LBPORT0(54), LBPORT1(51), LBPORT2(52), LBPORT3(53)
   6392      * ring 1: EP(2)
   6393      * ring 2: MMU_XPE(3), MMU_SC(4), MMU_GLB(5)
   6394      * ring 3: PM7(22), PM6(21), PM5(20), PM4(19), PM3(18), PM2(17), PM1(16),
   6395      *         PM0(15), PM31(46), PM30(45), PM29(44), PM28(43), PM27(42),
   6396      *         PM26(41), PM25(40), PM24(39), CLPORT32(55)
   6397      * ring 4: PM32(11), PM8(23), PM9(24), PM10(25), PM11(26), PM12(27),
   6398      *         PM13(28), PM14(29), PM15(30), PM16(31), PM17(32), PM18(33),
   6399      *         PM19(34), PM20(35), PM21(36), PM22(37), PM23(38)
   6400      * ring 5: OTPC(6), AVS(59), TOP(7), SER(8)
   6401      */
   6402 
   6403 
   6404 #ifdef BCM_CMICX_SUPPORT
   6405     if (soc_feature(unit, soc_feature_cmicx)) {
   6406         soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_0_7_OFFSET,0x52222100);
   6407         soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_8_15_OFFSET,0x30050005);
   6408         soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_16_23_OFFSET,0x33333333);
   6409         soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_24_31_OFFSET,0x64444333);
   6410         soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_32_39_OFFSET,0x07500066);
   6411         soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_40_47_OFFSET,0x00000000);
   6412         soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_48_55_OFFSET,0x00000000);
   6413         soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_56_63_OFFSET,0x00000000);
   6414         soc_pci_write(unit, CMIC_TOP_SBUS_TIMEOUT_OFFSET,0x5000);
   6415     }
   6416 #endif
   6417 
   6418     return;
   6419 }
   6420 
   6421 /*
   6422  * Function:
   6423  *      soc_hx5_support_speeds
   6424  * Purpose:
   6425  *      Get the supported speed of port for specified lanes
   6426  * Parameters:
   6427  *      unit                 - (IN)  Unit number.
   6428  *      ports                - (IN)  Logical port number.
   6429  *      speed_mask           - (IN)  Bitmap for supported speed.
   6430  * Returns:
   6431  *      BCM_E_xxx
   6432  */
   6433 int
   6434 soc_hx5_support_speeds(int unit, int port, uint32 *speed_mask)
   6435 {
   6436     uint32 speed_valid;
   6437     int phy_port, lanes;
   6438     soc_info_t *si = &SOC_INFO(unit);
   6439 
   6440     phy_port = si->port_l2p_mapping[port];
   6441     lanes = si->port_num_lanes[port];
   6442 
   6443     switch(lanes) {
   6444     case 1:
   6445         /* Single Lane Port Speeds */
   6446         speed_valid = SOC_PA_SPEED_1000MB | SOC_PA_SPEED_10GB | SOC_PA_SPEED_11GB;
   6447         if (PORT_IS_FALCON(unit, phy_port)) {
   6448             speed_valid |= SOC_PA_SPEED_25GB | SOC_PA_SPEED_27GB;
   6449         } else {
   6450             speed_valid |=  SOC_PA_SPEED_10MB | SOC_PA_SPEED_100MB |
   6451                             SOC_PA_SPEED_2500MB | SOC_PA_SPEED_5000MB;
   6452         }
   6453         break;
   6454     case 2:
   6455         /* Dual Lane Port Speeds */
   6456         speed_valid = SOC_PA_SPEED_20GB | SOC_PA_SPEED_21GB;
   6457         if (PORT_IS_FALCON(unit, phy_port)) {
   6458             speed_valid |= SOC_PA_SPEED_40GB | SOC_PA_SPEED_42GB |
   6459                            SOC_PA_SPEED_50GB | SOC_PA_SPEED_53GB;
   6460         } else {
   6461             speed_valid |=  SOC_PA_SPEED_10GB | SOC_PA_SPEED_11GB;
   6462         }
   6463         break;
   6464     case 4:
   6465         /* Quad Lane Port Speeds */
   6466         speed_valid = SOC_PA_SPEED_40GB | SOC_PA_SPEED_42GB |
   6467                       SOC_PA_SPEED_100GB;
   6468         break;
   6469     default:
   6470         return SOC_E_PARAM;
   6471     }
   6472 
   6473     *speed_mask = speed_valid;
   6474 
   6475     return SOC_E_NONE;
   6476 }
   6477 
   6478 
   6479 #ifdef BCM_WARM_BOOT_SUPPORT
   6480 
   6481 #define SOC_FLEXPORT_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
   6482 #define SOC_FLEXPORT_WB_DEFAULT_VERSION            SOC_FLEXPORT_WB_VERSION_1_0
   6483 
   6484 int
   6485 soc_hx5_flexport_scache_allocate(int unit)
   6486 {
   6487     int rv = SOC_E_NONE;
   6488     uint8 *flexport_scache_ptr;
   6489     soc_scache_handle_t scache_handle;
   6490     uint32 alloc_get = 0;
   6491     uint32 alloc_size = 0;
   6492     int stable_size;
   6493     int default_ver = SOC_FLEXPORT_WB_DEFAULT_VERSION;
   6494 
   6495     alloc_size =  (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to logical*/
   6496                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to mmu */
   6497                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* logical to phy */
   6498                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* max port speed */
   6499                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* init port speed */
   6500                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* num of lanes */
   6501                   (sizeof(pbmp_t))                       + /* HG bitmap */
   6502                   (sizeof(pbmp_t));                        /* Disabled bitmap */
   6503 
   6504     alloc_get = alloc_size;
   6505 
   6506     SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0);
   6507     /* check to see if an scache table has been configured */
   6508     rv = soc_stable_size_get(unit, &stable_size);
   6509     if (SOC_FAILURE(rv) || stable_size <= 0) {
   6510         return rv;
   6511     }
   6512 
   6513     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
   6514                                           TRUE, &alloc_get,
   6515                                           &flexport_scache_ptr,
   6516                                           default_ver,
   6517                                           NULL);
   6518 
   6519     if (rv  == SOC_E_CONFIG) {
   6520         /* Probably Level1 */
   6521         return SOC_E_NONE;
   6522     }
   6523     /* NotRequired but just to confirm Get the pointer for the Level 2 cache */
   6524     if (alloc_get != alloc_size) {
   6525         /* Expected size doesn't match retrieved size */
   6526         LOG_ERROR(BSL_LS_SOC_COMMON,
   6527                 (BSL_META_U(unit,
   6528                  "ERROR: scache memory for flexport size mismatch"
   6529                  "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
   6530         return SOC_E_INTERNAL;
   6531     }
   6532 
   6533     if (NULL == flexport_scache_ptr) {
   6534         LOG_ERROR(BSL_LS_SOC_COMMON,
   6535                 (BSL_META_U(unit,
   6536                  "ERROR: scache memory not allocated for flexport"
   6537                  "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
   6538         return SOC_E_MEMORY;
   6539     }
   6540     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   6541                 (BSL_META_U(unit,
   6542                 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
   6543     return SOC_E_NONE;
   6544 
   6545 }
   6546 
   6547 /*
   6548  * Function:
   6549  *      soc_hx5_flexport_scache_sync
   6550  * Purpose:
   6551  *      Record Port info that maybe changed during flexport for Level 2 WB
   6552  *
   6553  * Warm Boot Version Map:
   6554  *
   6555  *  BCM_WB_VERSION_1_0
   6556  *    port_speed_max
   6557  *    port_init_speed
   6558  *    port_num_lanes
   6559  *    disabled_bitmap
   6560  *
   6561  * Parameters:
   6562  *      unit - StrataSwitch unit number.
   6563  * Returns:
   6564  *      SOC_E_XXX
   6565  */
   6566 int
   6567 soc_hx5_flexport_scache_sync(int unit)
   6568 {
   6569     uint8 *flexport_scache_ptr;
   6570     soc_scache_handle_t scache_handle;
   6571     uint32 alloc_get = 0;
   6572     uint32 alloc_size = 0;
   6573     uint32 var_size = 0;
   6574     soc_info_t *si = &SOC_INFO(unit);
   6575     uint32 scache_offset=0;
   6576     int rv = 0;
   6577 
   6578     alloc_size =  (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to logical*/
   6579                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to mmu */
   6580                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* logical to phy */
   6581                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* max port speed */
   6582                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* init port speed */
   6583                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* num of lanes */
   6584                   (sizeof(pbmp_t))                       + /* HG bitmap */
   6585                   (sizeof(pbmp_t));                        /* Disabled bitmap */
   6586 
   6587     alloc_get = alloc_size;
   6588 
   6589     SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0);
   6590     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
   6591                         FALSE, &alloc_get,
   6592                         &flexport_scache_ptr,
   6593                         SOC_FLEXPORT_WB_DEFAULT_VERSION,
   6594                         NULL);
   6595     if (rv == SOC_E_NOT_FOUND) {
   6596         /* Probably Level1 */
   6597         return SOC_E_NONE;
   6598     }
   6599     if (alloc_get != alloc_size) {
   6600         /* Expected size doesn't match retrieved size */
   6601         LOG_ERROR(BSL_LS_SOC_COMMON,
   6602                 (BSL_META_U(unit,
   6603                  "ERROR: scache memory for flexport size mismatch"
   6604                  "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
   6605         return SOC_E_INTERNAL;
   6606     }
   6607     if (NULL == flexport_scache_ptr) {
   6608         LOG_ERROR(BSL_LS_SOC_COMMON,
   6609                 (BSL_META_U(unit,
   6610                  "ERROR: scache memory not allocated for flexport"
   6611                  "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
   6612         return SOC_E_MEMORY;
   6613     }
   6614 
   6615     /* Physical to logical port mapping */
   6616     var_size = sizeof(int) * HELIX5_PHY_PORTS_PER_DEV;
   6617     sal_memcpy(&flexport_scache_ptr[scache_offset],
   6618                si->port_p2l_mapping, var_size);
   6619     scache_offset += var_size;
   6620 
   6621 
   6622     /* Physical to MMU port mapping */
   6623     var_size = sizeof(int) * HELIX5_PHY_PORTS_PER_DEV;
   6624     sal_memcpy(&flexport_scache_ptr[scache_offset],
   6625                si->port_p2m_mapping, var_size);
   6626     scache_offset += var_size;
   6627 
   6628     /* Logical to Physical port mapping */
   6629     var_size = sizeof(int) * HELIX5_PHY_PORTS_PER_DEV;
   6630     sal_memcpy(&flexport_scache_ptr[scache_offset],
   6631                si->port_l2p_mapping, var_size);
   6632     scache_offset += var_size;
   6633 
   6634     /* Max port speed */
   6635     var_size = sizeof(int) * HELIX5_PHY_PORTS_PER_DEV;
   6636 
   6637     sal_memcpy(&flexport_scache_ptr[scache_offset],
   6638                si->port_speed_max, var_size);
   6639     scache_offset += var_size;
   6640 
   6641     /* Init port speed */
   6642     sal_memcpy(&flexport_scache_ptr[scache_offset],
   6643                si->port_init_speed, var_size);
   6644     scache_offset += var_size;
   6645 
   6646     /* Num of lanes */
   6647     sal_memcpy(&flexport_scache_ptr[scache_offset],
   6648                si->port_num_lanes, var_size);
   6649     scache_offset += var_size;
   6650 
   6651     /* HG Bitmap */
   6652     sal_memcpy(&flexport_scache_ptr[scache_offset],
   6653                &si->hg.bitmap,
   6654                sizeof(pbmp_t));
   6655     scache_offset += sizeof(pbmp_t);
   6656 
   6657     /* Disabled Port Bitmap */
   6658     sal_memcpy(&flexport_scache_ptr[scache_offset],
   6659                &si->all.disabled_bitmap,
   6660                sizeof(pbmp_t));
   6661     scache_offset += sizeof(pbmp_t);
   6662 
   6663     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   6664                 (BSL_META_U(unit,
   6665                  "%s()[LINE:%d] \n"),FUNCTION_NAME(),  __LINE__));
   6666 
   6667     return SOC_E_NONE;
   6668 }
   6669 
   6670 /*
   6671  * Function:
   6672  *      soc_hx5_flexport_scache_recovery
   6673  * Purpose:
   6674  *      Recover Port info that maybe changed during flexport for Level 2 WB
   6675  *
   6676  * Warm Boot Version Map:
   6677  *
   6678  *  BCM_WB_VERSION_1_0
   6679  *    port_p2l_mapping
   6680  *    port_l2p_mapping
   6681  *    port_speed_max
   6682  *    port_init_speed
   6683  *    port_num_lanes
   6684  *    disabled_bitmap
   6685  *
   6686  * Parameters:
   6687  *      unit - StrataSwitch unit number.
   6688  * Returns:
   6689  *      SOC_E_XXX
   6690  */
   6691 int
   6692 soc_hx5_flexport_scache_recovery(int unit)
   6693 {
   6694     uint32 alloc_get = 0;
   6695     uint32 alloc_size = 0;
   6696     int rv = SOC_E_NONE, port, phy_port;
   6697     uint8 *flexport_scache_ptr = NULL;
   6698     soc_scache_handle_t scache_handle;
   6699     uint32 scache_offset=0;
   6700     uint32 var_size = 0;
   6701     uint16 recovered_ver = 0;
   6702     soc_info_t *si = &SOC_INFO(unit);
   6703 
   6704     alloc_size =  (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to logical*/
   6705                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to mmu */
   6706                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* logical to phy */
   6707                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* max port speed */
   6708                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* init port speed */
   6709                   (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* num of lanes */
   6710                   (sizeof(pbmp_t))                         + /* HG bitmap */
   6711                   (sizeof(pbmp_t));                          /* Disabled bitmap */
   6712 
   6713     alloc_get = alloc_size;
   6714 
   6715     SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0);
   6716     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
   6717                         FALSE, &alloc_get,
   6718                         &flexport_scache_ptr,
   6719                         SOC_FLEXPORT_WB_DEFAULT_VERSION,
   6720                         &recovered_ver);
   6721     if (SOC_FAILURE(rv)) {
   6722         if ((rv == SOC_E_CONFIG) ||
   6723             (rv == SOC_E_NOT_FOUND)) {
   6724             /* warmboot file does not contain this
   6725             * module, or the warmboot state does not exist.
   6726             * in this case return SOC_E_NOT_FOUND
   6727             */
   6728             return SOC_E_NOT_FOUND;
   6729         } else {
   6730             /* Only Level2 - flexport treat this as a error */
   6731             LOG_ERROR(BSL_LS_SOC_COMMON,
   6732                      (BSL_META_U(unit,
   6733                      "Failed to recover scache data - %s\n"),soc_errmsg(rv)));
   6734             return rv;
   6735         }
   6736     }
   6737     if (alloc_get != alloc_size) {
   6738         /* Expected size doesn't match retrieved size */
   6739         LOG_ERROR(BSL_LS_SOC_COMMON,
   6740                 (BSL_META_U(unit,
   6741                  "ERROR: scache recovery for flexport"
   6742                  "%s()[LINE:%d] DONE \n"),
   6743                   FUNCTION_NAME(),  __LINE__));
   6744         return SOC_E_INTERNAL;
   6745     }
   6746 
   6747     if (NULL == flexport_scache_ptr) {
   6748         LOG_ERROR(BSL_LS_SOC_COMMON,
   6749                 (BSL_META_U(unit,
   6750                  "ERROR: scache recovery for flexport"
   6751                  "%s()[LINE:%d] DONE \n"),
   6752                   FUNCTION_NAME(),  __LINE__));
   6753         return SOC_E_MEMORY;
   6754     }
   6755 
   6756     /*Physical to logical port mapping */
   6757     var_size = (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV);
   6758     sal_memcpy(si->port_p2l_mapping,
   6759                &flexport_scache_ptr[scache_offset],
   6760                var_size);
   6761     scache_offset += var_size;
   6762 
   6763     /*Physical to MMU port mapping */
   6764     var_size = (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV);
   6765     sal_memcpy(si->port_p2m_mapping,
   6766                &flexport_scache_ptr[scache_offset],
   6767                var_size);
   6768     scache_offset += var_size;
   6769 
   6770     /*Logical to Physical port mapping*/
   6771     var_size = (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV);
   6772     sal_memcpy(si->port_l2p_mapping,
   6773                &flexport_scache_ptr[scache_offset],
   6774                var_size);
   6775     scache_offset += var_size;
   6776 
   6777     /* Max port speed */
   6778     var_size = (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV);
   6779 
   6780     sal_memcpy(si->port_speed_max,
   6781                &flexport_scache_ptr[scache_offset],
   6782                var_size);
   6783     scache_offset += var_size;
   6784 
   6785     /* Init port speed */
   6786     sal_memcpy(si->port_init_speed,
   6787                &flexport_scache_ptr[scache_offset],
   6788                var_size);
   6789     scache_offset += var_size;
   6790 
   6791     /* Num of lanes */
   6792     sal_memcpy(si->port_num_lanes,
   6793                &flexport_scache_ptr[scache_offset],
   6794                var_size);
   6795     scache_offset += var_size;
   6796 
   6797     /* HG Bitmap */
   6798     sal_memcpy(&si->hg.bitmap,
   6799            &flexport_scache_ptr[scache_offset],
   6800            sizeof(pbmp_t));
   6801     scache_offset += sizeof(pbmp_t);
   6802 
   6803     /* Disabled Port Bitmap */
   6804     sal_memcpy(&si->all.disabled_bitmap,
   6805            &flexport_scache_ptr[scache_offset],
   6806            sizeof(pbmp_t));
   6807     scache_offset += sizeof(pbmp_t);
   6808 
   6809     SOC_PBMP_CLEAR(si->pipe_pbm[0]);
   6810 
   6811     for (port = 1; port < HX5_NUM_PORT; port++) {
   6812         phy_port = si->port_l2p_mapping[port];
   6813         if (phy_port == -1) {
   6814             SOC_PBMP_PORT_REMOVE(si->oversub_pbm, port);
   6815             si->port_l2i_mapping[port] = -1;
   6816             si->port_serdes[port] = -1;
   6817             si->port_pipe[port] = -1;
   6818             continue;
   6819         }
   6820         si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port];
   6821         if (phy_port <= 48) {
   6822             si->port_serdes[port] = (phy_port - 1) / _HX5_PORTS_PER_PMQ_PBLK;
   6823         } else {
   6824             si->port_serdes[port] = ((phy_port - 1) / _HX5_PORTS_PER_PBLK) - 9;
   6825         }
   6826         si->port_pipe[port] = 0;
   6827         SOC_PBMP_PORT_ADD(si->pipe_pbm[0], port);
   6828 
   6829         if (soc_hx5_port_oversub_get(unit, phy_port, port)) {
   6830             SOC_PBMP_PORT_ADD(si->oversub_pbm, port);
   6831         }
   6832     }
   6833 
   6834     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   6835                 (BSL_META_U(unit,
   6836                  "%s()[LINE:%d] \n"),FUNCTION_NAME(),  __LINE__));
   6837 
   6838     return SOC_E_NONE;
   6839 }
   6840 
   6841 #define SOC_TDM_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
   6842 #define SOC_TDM_WB_DEFAULT_VERSION            SOC_TDM_WB_VERSION_1_0
   6843 
   6844 /*
   6845  * Function:
   6846  *      soc_hx5_tdm_scache_allocate
   6847  * Purpose:
   6848  *      Calculate TDM info that maybe changed during flexport for Level 2 WB
   6849  *
   6850  * Warm Boot Version Map:
   6851  *
   6852  *  BCM_WB_VERSION_1_0
   6853  *    IDB TDM info on pipe0
   6854  *    MMU TDM info on pipe0
   6855  *    Oversub group info on pipe0
   6856  *    pkt shaper info on pipe0
   6857  *    pblk id of phy-port
   6858  *    port ratio
   6859  *    oversub ratio
   6860  *
   6861  * Parameters:
   6862  *      unit - StrataSwitch unit number.
   6863  * Returns:
   6864  *      SOC_E_XXX
   6865  */
   6866 int soc_hx5_tdm_scache_allocate(int unit)
   6867 {
   6868     int rv = SOC_E_NONE;
   6869     uint8 *tdm_scache_ptr;
   6870     soc_scache_handle_t scache_handle;
   6871     uint32 alloc_get = 0;
   6872     uint32 alloc_size = 0;
   6873     int stable_size;
   6874     int default_ver = SOC_TDM_WB_DEFAULT_VERSION;
   6875     int ilen, ovs_size, pkt_shp_size, hpipes;
   6876 
   6877     ilen = sizeof(int);
   6878     ovs_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE *
   6879                HELIX5_OVS_GROUP_COUNT_PER_HPIPE *
   6880                HELIX5_OVS_GROUP_TDM_LENGTH;
   6881     pkt_shp_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE *
   6882                    _HX5_PKT_SCH_LENGTH;
   6883     hpipes = HELIX5_PIPES_PER_DEV * HELIX5_OVS_HPIPE_COUNT_PER_PIPE;
   6884 
   6885     alloc_size = (ilen * HELIX5_TDM_LENGTH) + /* IDB TDM info on pipe0 */
   6886                  (ilen * HELIX5_TDM_LENGTH) + /* MMU TDM info on pipe0 */
   6887                  (ilen * ovs_size)     + /* Oversub group info on pipe0 */
   6888                  (ilen * pkt_shp_size)    + /* pkt shaper info on pipe0     */
   6889                  (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */
   6890                  (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */
   6891                  (ilen * HELIX5_PBLKS_PER_DEV)     + /* port ratio */
   6892                  (ilen * hpipes);                  /* oversub ratio */
   6893     alloc_get = alloc_size;
   6894 
   6895     SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0);
   6896     /* check to see if an scache table has been configured */
   6897     rv = soc_stable_size_get(unit, &stable_size);
   6898     if (SOC_FAILURE(rv) || stable_size <= 0) {
   6899         return rv;
   6900     }
   6901 
   6902     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
   6903                                       TRUE, &alloc_get,
   6904                                       &tdm_scache_ptr,
   6905                                       default_ver,
   6906                                       NULL);
   6907 
   6908     if (rv  == SOC_E_CONFIG) {
   6909         /* Probably Level1 */
   6910         return SOC_E_NONE;
   6911     }
   6912     /* NotRequired but just to confirm Get the pointer for the Level 2 cache */
   6913     if (alloc_get != alloc_size) {
   6914         /* Expected size doesn't match retrieved size */
   6915         LOG_ERROR(BSL_LS_SOC_COMMON,
   6916                   (BSL_META_U(unit,
   6917                   "ERROR: scache memory for tdm size mismatch"
   6918                   "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
   6919         return SOC_E_INTERNAL;
   6920     }
   6921 
   6922     if (NULL == tdm_scache_ptr) {
   6923         LOG_ERROR(BSL_LS_SOC_COMMON,
   6924                   (BSL_META_U(unit,
   6925                   "ERROR: scache memory not allocated for tdm"
   6926                   "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
   6927         return SOC_E_MEMORY;
   6928     }
   6929     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   6930                 (BSL_META_U(unit,
   6931                 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
   6932     return SOC_E_NONE;
   6933 }
   6934 
   6935 /*
   6936  * Function:
   6937  *      soc_hx5_tdm_scache_sync
   6938  * Purpose:
   6939  *      Record TDM info that maybe changed during flexport for Level 2 WB
   6940  *
   6941  * Warm Boot Version Map:
   6942  *
   6943  *  BCM_WB_VERSION_1_0
   6944  *    IDB TDM info on pipe0
   6945  *    MMU TDM info on pipe0
   6946  *    Oversub group info on pipe0
   6947  *    pkt shaper info on pipe0
   6948  *    pblk id of phy-port
   6949  *    port ratio
   6950  *    oversub ratio
   6951  *
   6952  * Parameters:
   6953  *      unit - StrataSwitch unit number.
   6954  * Returns:
   6955  *      SOC_E_XXX
   6956  */
   6957 int soc_hx5_tdm_scache_sync(int unit)
   6958 {
   6959     uint8 *tdm_scache_ptr;
   6960     soc_scache_handle_t scache_handle;
   6961     uint32 alloc_get = 0;
   6962     uint32 alloc_size = 0;
   6963     uint32 var_size = 0;
   6964     uint32 scache_offset=0;
   6965     int rv = 0;
   6966     int ilen, ovs_size, pkt_shp_size, hpipes, phy_port;
   6967     _soc_helix5_tdm_temp_t  *tdm = SOC_CONTROL(unit)->tdm_info;
   6968 
   6969     ilen = sizeof(int);
   6970     ovs_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE *
   6971                HELIX5_OVS_GROUP_COUNT_PER_HPIPE *
   6972                HELIX5_OVS_GROUP_TDM_LENGTH;
   6973     pkt_shp_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE *
   6974                    _HX5_PKT_SCH_LENGTH;
   6975     hpipes = HELIX5_PIPES_PER_DEV * HELIX5_OVS_HPIPE_COUNT_PER_PIPE;
   6976 
   6977     alloc_size = (ilen * HELIX5_TDM_LENGTH) + /* IDB TDM info on pipe0 */
   6978                  (ilen * HELIX5_TDM_LENGTH) + /* MMU TDM info on pipe0 */
   6979                  (ilen * ovs_size)     + /* Oversub group info on pipe0 */
   6980                  (ilen * pkt_shp_size)    + /* pkt shaper info on pipe0     */
   6981                  (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */
   6982                  (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */
   6983                  (ilen * HELIX5_PBLKS_PER_DEV)     + /* port ratio */
   6984                  (ilen * hpipes);                  /* oversub ratio */
   6985     alloc_get = alloc_size;
   6986 
   6987     SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0);
   6988     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
   6989                                       FALSE, &alloc_get,
   6990                                       &tdm_scache_ptr,
   6991                                       SOC_TDM_WB_DEFAULT_VERSION,
   6992                                       NULL);
   6993     if (rv == SOC_E_NOT_FOUND) {
   6994         /* Probably Level1 */
   6995         return SOC_E_NONE;
   6996     }
   6997     if (alloc_get != alloc_size) {
   6998         /* Expected size doesn't match retrieved size */
   6999         LOG_ERROR(BSL_LS_SOC_COMMON,
   7000                   (BSL_META_U(unit,
   7001                   "ERROR: scache memory for tdm size mismatch"
   7002                   "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
   7003         return SOC_E_INTERNAL;
   7004     }
   7005     if (NULL == tdm_scache_ptr) {
   7006         LOG_ERROR(BSL_LS_SOC_COMMON,
   7007                   (BSL_META_U(unit,
   7008                   "ERROR: scache memory not allocated for tdm"
   7009                   "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
   7010         return SOC_E_MEMORY;
   7011     }
   7012 
   7013     /* IDB TDM info on pipe0 */
   7014     var_size = ilen * HELIX5_TDM_LENGTH;
   7015     sal_memcpy(&tdm_scache_ptr[scache_offset],
   7016                tdm->tdm_pipe[0].idb_tdm,
   7017                var_size);
   7018     scache_offset += var_size;
   7019 
   7020     /* MMU TDM info on pipe0 */
   7021     var_size = ilen * HELIX5_TDM_LENGTH;
   7022     sal_memcpy(&tdm_scache_ptr[scache_offset],
   7023                tdm->tdm_pipe[0].mmu_tdm,
   7024                var_size);
   7025     scache_offset += var_size;
   7026 
   7027     /* Oversub group info on pipe0 */
   7028     var_size = ilen * ovs_size;
   7029     sal_memcpy(&tdm_scache_ptr[scache_offset],
   7030                tdm->tdm_pipe[0].ovs_tdm,
   7031                var_size);
   7032     scache_offset += var_size;
   7033 
   7034     /* pkt shaper info on pipe0 */
   7035     var_size = ilen * pkt_shp_size;
   7036     sal_memcpy(&tdm_scache_ptr[scache_offset],
   7037                tdm->tdm_pipe[0].pkt_shaper_tdm,
   7038                var_size);
   7039     scache_offset += var_size;
   7040 
   7041     /* hpipe id of phy-port */
   7042     for (phy_port = 0; phy_port < HELIX5_PHY_PORTS_PER_DEV; phy_port++) {
   7043         var_size = ilen;
   7044         sal_memcpy(&tdm_scache_ptr[scache_offset],
   7045                    &tdm->pblk_info[phy_port].pblk_hpipe_num,
   7046                    var_size);
   7047         scache_offset += var_size;
   7048     }
   7049 
   7050     /* pblk id of phy-port */
   7051     for (phy_port = 0; phy_port < HELIX5_PHY_PORTS_PER_DEV; phy_port++) {
   7052         var_size = ilen;
   7053         sal_memcpy(&tdm_scache_ptr[scache_offset],
   7054                    &tdm->pblk_info[phy_port].pblk_cal_idx,
   7055                    var_size);
   7056         scache_offset += var_size;
   7057     }
   7058 
   7059     /* port ratio */
   7060     var_size = ilen * HELIX5_PBLKS_PER_DEV;
   7061     sal_memcpy(&tdm_scache_ptr[scache_offset],
   7062                tdm->port_ratio,
   7063                var_size);
   7064     scache_offset += var_size;
   7065 
   7066     /* oversub ratio */
   7067     var_size = ilen * hpipes;
   7068     sal_memcpy(&tdm_scache_ptr[scache_offset],
   7069                tdm->ovs_ratio_x1000,
   7070                var_size);
   7071     scache_offset += var_size;
   7072 
   7073     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   7074                 (BSL_META_U(unit,
   7075                 "%s()[LINE:%d] \n"),FUNCTION_NAME(),  __LINE__));
   7076 
   7077     return SOC_E_NONE;
   7078 }
   7079 
   7080 /*
   7081  * Function:
   7082  *      soc_hx5_tdm_scache_recovery
   7083  * Purpose:
   7084  *      Recover TDM info that maybe changed during flexport for Level 2 WB
   7085  *
   7086  * Warm Boot Version Map:
   7087  *
   7088  *  BCM_WB_VERSION_1_0
   7089  *    IDB TDM info on pipe0
   7090  *    MMU TDM info on pipe0
   7091  *    Oversub group info on pipe0
   7092  *    pkt shaper info on pipe0
   7093  *    hpipe id of phy-port
   7094  *    pblk id of phy-port
   7095  *    port ratio
   7096  *    oversub ratio
   7097  *
   7098  * Parameters:
   7099  *      unit - StrataSwitch unit number.
   7100  * Returns:
   7101  *      SOC_E_XXX
   7102  */
   7103 int soc_hx5_tdm_scache_recovery(int unit)
   7104 {
   7105     uint32 alloc_get = 0;
   7106     uint32 alloc_size = 0;
   7107     int rv = SOC_E_NONE;
   7108     uint8 *tdm_scache_ptr = NULL;
   7109     soc_scache_handle_t scache_handle;
   7110     uint32 scache_offset=0;
   7111     uint32 var_size = 0;
   7112     uint16 recovered_ver = 0;
   7113     int ilen, ovs_size, pkt_shp_size, hpipes, phy_port;
   7114     _soc_helix5_tdm_temp_t *tdm = SOC_CONTROL(unit)->tdm_info;
   7115 
   7116     ilen = sizeof(int);
   7117     ovs_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE *
   7118                HELIX5_OVS_GROUP_COUNT_PER_HPIPE *
   7119                HELIX5_OVS_GROUP_TDM_LENGTH;
   7120     pkt_shp_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE *
   7121                    _HX5_PKT_SCH_LENGTH;
   7122     hpipes = HELIX5_PIPES_PER_DEV * HELIX5_OVS_HPIPE_COUNT_PER_PIPE;
   7123 
   7124     alloc_size = (ilen * HELIX5_TDM_LENGTH) + /* IDB TDM info on pipe0 */
   7125                  (ilen * HELIX5_TDM_LENGTH) + /* MMU TDM info on pipe0 */
   7126                  (ilen * ovs_size)     + /* Oversub group info on pipe0 */
   7127                  (ilen * pkt_shp_size)    + /* pkt shaper info on pipe0     */
   7128                  (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */
   7129                  (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */
   7130                  (ilen * HELIX5_PBLKS_PER_DEV)     + /* port ratio */
   7131                  (ilen * hpipes);                  /* oversub ratio */
   7132     alloc_get = alloc_size;
   7133 
   7134     SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0);
   7135     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
   7136                                       FALSE, &alloc_get,
   7137                                       &tdm_scache_ptr,
   7138                                       SOC_TDM_WB_DEFAULT_VERSION,
   7139                                       &recovered_ver);
   7140     if (SOC_FAILURE(rv)) {
   7141         if ((rv == SOC_E_CONFIG) ||
   7142             (rv == SOC_E_NOT_FOUND)) {
   7143             /* warmboot file does not contain this
   7144              * module, or the warmboot state does not exist.
   7145              * in this case return SOC_E_NOT_FOUND
   7146              */
   7147             return SOC_E_NOT_FOUND;
   7148         } else {
   7149             /* Only Level2 - flexport treat this as a error */
   7150             LOG_ERROR(BSL_LS_SOC_COMMON,
   7151                       (BSL_META_U(unit,
   7152                       "Failed to recover scache data - %s\n"),soc_errmsg(rv)));
   7153             return rv;
   7154         }
   7155     }
   7156     if (alloc_get != alloc_size) {
   7157         /* Expected size doesn't match retrieved size */
   7158         LOG_ERROR(BSL_LS_SOC_COMMON,
   7159                   (BSL_META_U(unit,
   7160                   "ERROR: scache recovery for tdm"
   7161                   "%s()[LINE:%d] DONE \n"),
   7162                   FUNCTION_NAME(),  __LINE__));
   7163         return SOC_E_INTERNAL;
   7164     }
   7165 
   7166     if (NULL == tdm_scache_ptr) {
   7167         LOG_ERROR(BSL_LS_SOC_COMMON,
   7168                   (BSL_META_U(unit,
   7169                   "ERROR: scache recovery for tdm"
   7170                   "%s()[LINE:%d] DONE \n"),
   7171                   FUNCTION_NAME(),  __LINE__));
   7172         return SOC_E_MEMORY;
   7173     }
   7174 
   7175     /* IDB TDM info on pipe0 */
   7176     var_size = ilen * HELIX5_TDM_LENGTH;
   7177     sal_memcpy(tdm->tdm_pipe[0].idb_tdm,
   7178                &tdm_scache_ptr[scache_offset],
   7179                var_size);
   7180     scache_offset += var_size;
   7181 
   7182     /* MMU TDM info on pipe0 */
   7183     var_size = ilen * HELIX5_TDM_LENGTH;
   7184     sal_memcpy(tdm->tdm_pipe[0].mmu_tdm,
   7185                &tdm_scache_ptr[scache_offset],
   7186                var_size);
   7187     scache_offset += var_size;
   7188 
   7189     /* Oversub group info on pipe0 */
   7190     var_size = ilen * ovs_size;
   7191     sal_memcpy(tdm->tdm_pipe[0].ovs_tdm,
   7192                &tdm_scache_ptr[scache_offset],
   7193                var_size);
   7194     scache_offset += var_size;
   7195 
   7196     /* pkt shaper info on pipe0 */
   7197     var_size = ilen * pkt_shp_size;
   7198     sal_memcpy(tdm->tdm_pipe[0].pkt_shaper_tdm,
   7199                &tdm_scache_ptr[scache_offset],
   7200                var_size);
   7201     scache_offset += var_size;
   7202 
   7203     /* hpipe id of phy-port */
   7204     for (phy_port = 0; phy_port < HELIX5_PHY_PORTS_PER_DEV; phy_port++) {
   7205         var_size = ilen;
   7206         sal_memcpy(&tdm->pblk_info[phy_port].pblk_hpipe_num,
   7207                    &tdm_scache_ptr[scache_offset],
   7208                    var_size);
   7209         scache_offset += var_size;
   7210     }
   7211 
   7212     /* pblk id of phy-port */
   7213     for (phy_port = 0; phy_port < HELIX5_PHY_PORTS_PER_DEV; phy_port++) {
   7214         var_size = ilen;
   7215         sal_memcpy(&tdm->pblk_info[phy_port].pblk_cal_idx,
   7216                    &tdm_scache_ptr[scache_offset],
   7217                    var_size);
   7218         scache_offset += var_size;
   7219     }
   7220 
   7221     /* port ratio */
   7222     var_size = ilen * HELIX5_PBLKS_PER_DEV;
   7223     sal_memcpy(tdm->port_ratio,
   7224                &tdm_scache_ptr[scache_offset],
   7225                var_size);
   7226     scache_offset += var_size;
   7227 
   7228     /* oversub ratio */
   7229     var_size = ilen * hpipes;
   7230     sal_memcpy(tdm->ovs_ratio_x1000,
   7231                &tdm_scache_ptr[scache_offset],
   7232                var_size);
   7233     scache_offset += var_size;
   7234 
   7235     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   7236                 (BSL_META_U(unit,
   7237                 "%s()[LINE:%d] \n"),FUNCTION_NAME(),  __LINE__));
   7238 
   7239     return SOC_E_NONE;
   7240 }
   7241 #endif /* BCM_WARM_BOOT_SUPPORT */
   7242 
   7243 
   7244 int
   7245 soc_helix5_show_voltage(int unit)
   7246 {
   7247     soc_reg_t reg;
   7248     int index;
   7249     uint32 rval = 0, fval = 0, avg = 0;
   7250 
   7251     SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_3r(unit, &rval));
   7252     if ((soc_reg_field_get(unit, TOP_PVTMON_CTRL_3r, rval, PVTMON_RESET_Nf) == 0) ||
   7253         (soc_reg_field_get(unit, TOP_PVTMON_CTRL_3r, rval, PVTMON_SELECTf) != 4)) {
   7254 
   7255         soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_RESET_Nf, 0);
   7256         SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_3r(unit, rval));
   7257         soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_RESET_Nf, 1);
   7258         SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_3r(unit, rval));
   7259 
   7260         rval = 0;
   7261         soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT0f, 4);
   7262         soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT1f, 4);
   7263         soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT2f, 4);
   7264         soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT3f, 4);
   7265         soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT4f, 4);
   7266         soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT5f, 4);
   7267         SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_2r(unit, rval));
   7268 
   7269         sal_usleep(1000);
   7270     }
   7271 
   7272     avg = 0;
   7273 
   7274     /* Read Voltages. */
   7275     for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) {
   7276         reg = pvtmon_result_reg[index];
   7277 
   7278         /* TOP_PVTMON_RESULT_6r is used for AVS, skip the same from
   7279            voltage calculation */
   7280         if (reg == TOP_PVTMON_RESULT_6r) {
   7281             continue;
   7282         }
   7283         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   7284         fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf);
   7285 #ifdef BCM_HELIX5_SUPPORT
   7286         if (SOC_IS_HELIX5(unit)) {
   7287             /* (PVT_DATA * 950) / (1024 * 0.8) */
   7288             fval = (fval * 950 * 10) / (1024 * 8);
   7289         } else
   7290 #endif /* BCM_HELIX5_SUPPORT */
   7291         {
   7292             LOG_CLI((BSL_META_U(unit,
   7293                                 "Voltage monitor fail: Need to add formula for current device.\n")));
   7294             return SOC_E_UNAVAIL;
   7295         }
   7296         avg += fval;
   7297         LOG_CLI((BSL_META_U(unit,
   7298                             "Voltage monitor %d: voltage = %d.%03dV\n"),
   7299                  index, (fval/1000), (fval %1000)));
   7300     }
   7301 
   7302     /* Get count and reduce 1 since TOP_PVTMON_RESULT_6r is not not applicable */
   7303     avg /= (COUNTOF(pvtmon_result_reg) - 1);
   7304     LOG_CLI((BSL_META_U(unit,
   7305                         "Average voltage is = %d.%03dV\n"),
   7306              (avg/1000), (avg %1000)));
   7307 
   7308     return SOC_E_NONE;
   7309 }
   7310 
   7311 /*
   7312  * Function:
   7313  *      soc_helix5_icid_get
   7314  * Purpose:
   7315  *      Get ICID
   7316  *
   7317  * Parameters:
   7318  *      unit             - (IN) StrataSwitch unit number.
   7319  *      max_size         - (IN) Max size of data_buf
   7320  *      data_buf         - (OUT) data buffer to be populated
   7321  *      actual_size      - (OUT) Actual size data in data buffer
   7322  *
   7323  * Return Value:
   7324  *      SOC_E_XXX
   7325  */
   7326 int
   7327 soc_helix5_icid_get(int unit, int max_size, uint8 *buffer, int *actual_size)
   7328 {
   7329     int w;
   7330 
   7331     if (SOC_BOND_INFO(unit)->ic_id == NULL) {
   7332         LOG_ERROR(BSL_LS_BCM_COMMON,
   7333                 (BSL_META_U(unit,
   7334                             "unit %d : Cannot read ICID data.\n"),
   7335                  unit));
   7336         return SOC_E_UNAVAIL;
   7337     }
   7338 
   7339     if (buffer == NULL) {
   7340         /* return required buffer size of 8 bytes (64 bits) */
   7341         *actual_size = HX5_ICID_LENGTH_BYTES;
   7342         return SOC_E_NONE;
   7343     }
   7344 
   7345     if (max_size != HX5_ICID_LENGTH_BYTES) {
   7346         LOG_VERBOSE(BSL_LS_BCM_COMMON,
   7347                 (BSL_META_U(unit,
   7348                             "unit %d : Incorrect buffer size.\n"),
   7349                  unit));
   7350         return SOC_E_PARAM;
   7351     }
   7352 
   7353     for (w = 0; w < (HX5_ICID_LENGTH_BYTES/4); w++) {
   7354         _SHR_PACK_U32(buffer, SOC_BOND_INFO(unit)->ic_id[w]);
   7355     }
   7356 
   7357     return SOC_E_NONE;
   7358 }
   7359 
   7360 /*
   7361  * Helix5 chip driver functions.
   7362  * Pls keep at the end of this file for easy access.
   7363  */
   7364 soc_functions_t soc_helix5_drv_funs = {
   7365     _soc_helix5_misc_init,
   7366     _soc_helix5_mmu_init,
   7367     soc_trident3_age_timer_get,
   7368     soc_trident3_age_timer_max_get,
   7369     soc_trident3_age_timer_set,
   7370     soc_trident3_tscx_firmware_set,
   7371     _soc_helix5_tscx_reg_read,
   7372     _soc_helix5_tscx_reg_write,
   7373     soc_helix5_bond_info_init
   7374 };
   7375 #endif /* BCM_HELIX5_SUPPORT */