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

cosq.c (70581B)


      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  * APACHE MMU/Cosq soc routines
      8  */
      9 
     10 #include <sal/core/libc.h>
     11 #include <shared/bsl.h>
     12 #include <soc/debug.h>
     13 #include <soc/util.h>
     14 #include <soc/mem.h>
     15 #include <soc/trident2.h>
     16 #include <soc/apache.h>
     17 
     18 #if defined(BCM_APACHE_SUPPORT)
     19 
     20 
     21 #define _AP_COSQ_CPU_RESERVED_L0_BASE 261
     22 #define _AP_COSQ_CPU_RESERVED_L0_NUM  4
     23 
     24 #define _AP_HSP_PORT_MAX_COS 8
     25 
     26 
     27 typedef struct soc_apache_fc_map_shadow_memory_s {
     28     soc_mem_t mem;
     29     uint32  *mem_shadow;
     30 }soc_apache_fc_map_shadow_memory_t;
     31 
     32 typedef struct soc_apache_fc_map_shadow_s {
     33     soc_apache_fc_map_shadow_memory_t* shadow_array;
     34     int mem_count;
     35 }soc_apache_fc_map_shadow_t;
     36 
     37 
     38 static soc_mem_t fc_map_mems[] = {
     39     MMU_INTFI_XPIPE_FC_MAP_TBL0m,
     40     MMU_INTFI_XPIPE_FC_MAP_TBL1m
     41     };
     42 
     43 static soc_apache_fc_map_shadow_t soc_apache_fc_map_shadow[SOC_MAX_NUM_DEVICES];
     44 
     45 static int _ap_invalid_ptr[SOC_MAX_NUM_DEVICES][SOC_APACHE_NODE_LVL_MAX];
     46 #define INVALID_PARENT(unit, level)   _soc_apache_invalid_parent_index((unit),(level))
     47 
     48 /* Programming all the entries with the Invalid Parent Pointer */
     49 STATIC int
     50 soc_apache_set_invalid_parent(int unit)
     51 {
     52     int level, index_max, index;
     53     soc_mem_t mem;
     54     uint32 entry[SOC_MAX_MEM_WORDS];
     55     for (level = SOC_APACHE_NODE_LVL_S1; level <= SOC_APACHE_NODE_LVL_L2;
     56             level++) {
     57         mem = _SOC_APACHE_NODE_PARENT_MEM(unit, -1, level);
     58         /* coverity[negative_returns : FALSE] */
     59         index_max = soc_mem_index_max(unit, mem);
     60         for (index = 0; index <= index_max; index++) { 
     61             SOC_IF_ERROR_RETURN
     62                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry));
     63             soc_mem_field32_set(unit, mem, entry, 
     64                    (level == SOC_APACHE_NODE_LVL_S1) ? 
     65                          P_PORTf: C_PARENTf, INVALID_PARENT(unit,level));
     66                
     67             SOC_IF_ERROR_RETURN
     68                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &entry));
     69         }
     70     }
     71     return SOC_E_NONE;
     72 }
     73 
     74 STATIC int
     75 soc_apache_init_invalid_parents(int unit)
     76 {
     77 
     78     
     79     _ap_invalid_ptr[unit][SOC_APACHE_NODE_LVL_ROOT] = -1;
     80     _ap_invalid_ptr[unit][SOC_APACHE_NODE_LVL_S1] = 0x7f ;
     81     _ap_invalid_ptr[unit][SOC_APACHE_NODE_LVL_L0] =
     82         soc_mem_index_max(unit, LLS_S1_PARENTm);
     83     _ap_invalid_ptr[unit][SOC_APACHE_NODE_LVL_L1] =
     84         soc_mem_index_max(unit, LLS_L0_PARENTm);
     85     _ap_invalid_ptr[unit][SOC_APACHE_NODE_LVL_L2] =
     86         soc_mem_index_max(unit, LLS_L1_PARENTm);
     87     return SOC_E_NONE;
     88 }
     89 
     90 int _soc_apache_invalid_parent_index(int unit, int level)
     91 {
     92     return _ap_invalid_ptr[unit][level];
     93 }
     94 
     95 #define _SOC_APACHE_DEF_SCHED_NODE_BASE(u,p,cfg,t)   \
     96             (cfg)[(t)].base_factor * (p)
     97 
     98 soc_apache_sched_type_t
     99 _soc_apache_port_sched_type_get(int unit, soc_port_t port)
    100 {
    101     soc_info_t *si;
    102 
    103     si = &SOC_INFO(unit);
    104     return SOC_PBMP_MEMBER(si->eq_pbm, port) ? 
    105         SOC_APACHE_SCHED_HSP : SOC_APACHE_SCHED_LLS;
    106 }
    107 
    108 int soc_apache_port_common_attributes_get(int unit, int port, int *pipe,
    109                                        int *mmu_port, int *phy_port)
    110 {
    111     int lphy_port, lmmu_port;
    112     soc_info_t *si;
    113 
    114     si = &SOC_INFO(unit);
    115 
    116     if (pipe) {
    117         *pipe = 0;
    118     }
    119 
    120     lphy_port = si->port_l2p_mapping[port];
    121     lmmu_port = si->port_p2m_mapping[lphy_port];
    122 
    123     if (phy_port) {
    124         *phy_port = lphy_port;
    125     }
    126 
    127     if (mmu_port) {
    128         *mmu_port = lmmu_port;
    129     }
    130     return 0;
    131 }
    132 
    133 int _soc_apache_root_scheduler_index(int unit, int port)
    134 {
    135     int mmu_port, in_pipe;
    136 
    137     SOC_IF_ERROR_RETURN(
    138         soc_apache_port_common_attributes_get(unit, port, &in_pipe, &mmu_port, NULL));
    139 
    140     return mmu_port;
    141 }
    142 
    143 int _soc_apache_s1_scheduler_index(int unit, int port, int level, int hw_index)
    144 {
    145     soc_mem_t mem;
    146     int c_parent;
    147     uint32 entry[SOC_MAX_MEM_WORDS];
    148     if(level == SOC_APACHE_NODE_LVL_S1) {
    149         return hw_index;
    150     } else if (level >= SOC_APACHE_NODE_LVL_L0) {
    151         mem = _SOC_APACHE_NODE_PARENT_MEM(unit, port, level);
    152         SOC_IF_ERROR_RETURN
    153             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, hw_index, &entry));
    154         c_parent = soc_mem_field32_get(unit, mem, entry, 
    155                 C_PARENTf);
    156         if(level == SOC_APACHE_NODE_LVL_L0) {
    157             return c_parent;
    158         }
    159         mem = _SOC_APACHE_NODE_PARENT_MEM(unit, port, level - 1);
    160         SOC_IF_ERROR_RETURN
    161             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, c_parent, &entry));
    162         c_parent = soc_mem_field32_get(unit, mem, entry, 
    163                 C_PARENTf);
    164         if(level == SOC_APACHE_NODE_LVL_L1) {
    165             return c_parent;
    166         }
    167         mem = _SOC_APACHE_NODE_PARENT_MEM(unit, port, level - 2);
    168         SOC_IF_ERROR_RETURN
    169             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, c_parent, &entry));
    170         c_parent = soc_mem_field32_get(unit, mem, entry, 
    171                 C_PARENTf);
    172         if(level == SOC_APACHE_NODE_LVL_L2) {
    173             return c_parent;
    174         }
    175 
    176     }
    177     return -1;
    178 }
    179 
    180 STATIC int
    181 _soc_apache_flush_queue(int unit, int port, int queue_hw_index)
    182 {
    183     return 0;
    184 }
    185 
    186 soc_error_t
    187 soc_apache_cosq_disable_hsp_sched(int unit, soc_port_t in_port)
    188 {
    189     int mmu_port;
    190     uint32 fval, rval;
    191 
    192     SOC_IF_ERROR_RETURN
    193         (soc_apache_port_common_attributes_get(unit, in_port, NULL, &mmu_port, NULL));
    194     SOC_IF_ERROR_RETURN(READ_HSP_SCHED_GLOBAL_CONFIGr(unit, &rval));
    195     fval = soc_reg_field_get(unit, HSP_SCHED_GLOBAL_CONFIGr, rval, IS_HSP_PORT_IN_XPIPEf);
    196     fval &= ~(1 << mmu_port);
    197     soc_reg_field_set(unit, HSP_SCHED_GLOBAL_CONFIGr, &rval, IS_HSP_PORT_IN_XPIPEf, fval);
    198     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_GLOBAL_CONFIGr(unit, rval));
    199     return SOC_E_NONE;
    200 }
    201 
    202 int
    203 soc_apache_cosq_enable_hsp_sched(int unit, soc_port_t in_port)
    204 {
    205     int mmu_port;
    206     uint32 fval, rval;
    207 
    208     SOC_IF_ERROR_RETURN(
    209         soc_apache_port_common_attributes_get(unit, in_port, NULL, &mmu_port, NULL));
    210     SOC_IF_ERROR_RETURN(READ_HSP_SCHED_GLOBAL_CONFIGr(unit, &rval));
    211     fval = soc_reg_field_get(unit, HSP_SCHED_GLOBAL_CONFIGr, rval, 
    212             IS_HSP_PORT_IN_XPIPEf);
    213     fval |= (1 << mmu_port);
    214     soc_reg_field_set(unit, HSP_SCHED_GLOBAL_CONFIGr, &rval, 
    215             IS_HSP_PORT_IN_XPIPEf, fval);
    216     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_GLOBAL_CONFIGr(unit, rval));
    217     return SOC_E_NONE;
    218 }
    219 
    220 
    221 int
    222 soc_apache_cosq_set_sched_parent(int unit, soc_port_t port,
    223                               int level, int hw_index,
    224                               int parent_hw_idx, int add)
    225 {
    226     soc_apache_sched_type_t sched_type;
    227     uint32 entry[SOC_MAX_MEM_WORDS], fval, rval;
    228     soc_mem_t mem;
    229     int l0off, l1off;
    230     uint32 *bmap = NULL;
    231     soc_port_t mmu_port;
    232     LOG_INFO(BSL_LS_SOC_COSQ,
    233              (BSL_META_U(unit,
    234                          "Port:%d L%d : %d parent:%d\n"),
    235                port, level - 1, hw_index, parent_hw_idx));
    236 
    237     sched_type = _soc_apache_port_sched_type_get(unit, port);
    238 
    239     if (sched_type == SOC_APACHE_SCHED_LLS) {
    240         mem = _SOC_APACHE_NODE_PARENT_MEM(unit, port, level);
    241         if (mem == INVALIDm) {
    242             return SOC_E_INTERNAL;
    243         }
    244 
    245         SOC_IF_ERROR_RETURN
    246             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, hw_index, &entry));
    247 #if 0
    248         /* disconnecting the queue , flush it */
    249         if ((parent_hw_idx == INVALID_PARENT(unit, level)) && 
    250                 (level == SOC_APACHE_NODE_LVL_L2)) {
    251             SOC_IF_ERROR_RETURN(_soc_apache_flush_queue(unit, port, hw_index));
    252         }
    253 #endif
    254 
    255         soc_mem_field32_set(unit, mem, entry,
    256                 level == SOC_APACHE_NODE_LVL_S1 ? P_PORTf : 
    257                 C_PARENTf, add ? parent_hw_idx: INVALID_PARENT(unit, level));
    258         SOC_IF_ERROR_RETURN
    259             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, hw_index, &entry));
    260     } else if (sched_type == SOC_APACHE_SCHED_HSP) {
    261         if (level == SOC_APACHE_NODE_LVL_L1) {
    262             l0off = parent_hw_idx % 5;
    263             l1off = hw_index % 10;
    264             SOC_IF_ERROR_RETURN(
    265                     soc_apache_port_common_attributes_get(unit, port, 
    266                         NULL, &mmu_port, NULL));
    267 
    268 
    269             if (parent_hw_idx == INVALID_PARENT(unit, level)) {
    270                 SOC_IF_ERROR_RETURN(_soc_apache_flush_queue(unit,mmu_port, hw_index));
    271             } 
    272             SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr(
    273                         unit, port, l0off, &rval));
    274 
    275             fval = soc_reg_field_get(unit, HSP_SCHED_L0_NODE_CONNECTION_CONFIGr, 
    276                     rval, CHILDREN_CONNECTION_MAPf);
    277 
    278             if (l1off >= 8) {
    279                 l1off -= 2;
    280             }
    281 
    282             if (!add) {
    283                 fval &= ~(1 << l1off);
    284             } else {
    285                 fval |= 1 << l1off;
    286             }
    287             soc_reg_field_set(unit, HSP_SCHED_L0_NODE_CONNECTION_CONFIGr, 
    288                     &rval, CHILDREN_CONNECTION_MAPf, fval);
    289 
    290             SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr(
    291                         unit, port, l0off, rval));
    292 
    293         }
    294     }
    295     if (level == SOC_APACHE_NODE_LVL_S1) {
    296         bmap = SOC_CONTROL(unit)->port_lls_s1_bmap[port];
    297     } else if (level == SOC_APACHE_NODE_LVL_L0) {
    298         bmap = SOC_CONTROL(unit)->port_lls_l0_bmap[port];
    299     } else if (level == SOC_APACHE_NODE_LVL_L1) {
    300         bmap = SOC_CONTROL(unit)->port_lls_l1_bmap[port];
    301     } else if (level == SOC_APACHE_NODE_LVL_L2) {
    302         bmap = SOC_CONTROL(unit)->port_lls_l2_bmap[port];
    303     } else {
    304         return SOC_E_PARAM;
    305     }
    306     
    307     SOC_LLS_SCHEDULER_LOCK(unit);
    308     if (!add) {
    309         SHR_BITCLR(bmap, hw_index);
    310     } else {
    311         SHR_BITSET(bmap, hw_index);
    312     }
    313     SOC_LLS_SCHEDULER_UNLOCK(unit);
    314 
    315     return SOC_E_NONE;
    316 }
    317 
    318 int 
    319 soc_apache_sched_weight_set(int unit, int port, int level,
    320                          int hw_index, int weight)
    321 {
    322     soc_apache_sched_type_t sched_type;
    323     uint32 entry[SOC_MAX_MEM_WORDS], rval;
    324     soc_mem_t mem = INVALIDm;
    325     soc_reg_t reg = INVALIDr;
    326 
    327     LOG_INFO(BSL_LS_SOC_COSQ,
    328              (BSL_META_U(unit,
    329                          "sched_weight_set L%d csch_index=%d wt=%d\n"),
    330                level, hw_index, weight));
    331 
    332     sched_type = _soc_apache_port_sched_type_get(unit, port);
    333 
    334     if (weight > 0x7f) {
    335         return SOC_E_PARAM;
    336     }
    337     if (sched_type == SOC_APACHE_SCHED_LLS) {
    338         mem = _SOC_APACHE_NODE_WIEGHT_MEM(unit, port, level);
    339         if (mem == INVALIDm) {
    340             return SOC_E_INTERNAL;
    341         }
    342         if ((mem == LLS_L2_CHILD_WEIGHT_CFG_CNTm) &&
    343                 (hw_index > soc_mem_index_max(unit, mem))) {
    344             hw_index -= (soc_mem_index_max(unit, mem) + 1);
    345             mem = LLS_L2_MC_CHILD_WEIGHT_CFG_CNTm;
    346         }
    347         if ((mem == LLS_S1_CHILD_WEIGHT_CFG_CNTm) && 
    348              (weight == 0)) {
    349             return SOC_E_PARAM;
    350         }
    351 
    352         SOC_IF_ERROR_RETURN
    353             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, hw_index, &entry));
    354         soc_mem_field32_set(unit, mem, &entry, C_WEIGHTf, weight);
    355         SOC_IF_ERROR_RETURN
    356             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, hw_index, &entry));
    357     } else if (sched_type == SOC_APACHE_SCHED_HSP) {
    358         if ((level == SOC_APACHE_NODE_LVL_L0) || (level == SOC_APACHE_NODE_LVL_L1)) {
    359             if (level == SOC_APACHE_NODE_LVL_L0) {
    360                 hw_index = hw_index % 5;
    361                 reg = HSP_SCHED_L0_NODE_WEIGHTr;
    362             } else if (level == SOC_APACHE_NODE_LVL_L1) {
    363                 hw_index = hw_index % 10;
    364                 reg = HSP_SCHED_L1_NODE_WEIGHTr;
    365             }
    366 
    367             rval = 0;
    368             soc_reg_field_set(unit, reg, &rval, WEIGHTf, weight);
    369             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, hw_index, rval));
    370         } else if (level == SOC_APACHE_NODE_LVL_L2) {
    371             if (hw_index < soc_mem_index_max(unit, LLS_L2_CHILD_WEIGHT_CFG_CNTm))
    372             {
    373                 reg = HSP_SCHED_L2_UC_QUEUE_WEIGHTr;
    374                 hw_index = hw_index % 10;
    375             } else {
    376                 reg = HSP_SCHED_L2_MC_QUEUE_WEIGHTr;
    377                 hw_index = (hw_index - 16384) % 10;
    378             }
    379 
    380             rval = 0;
    381             soc_reg_field_set(unit, reg, &rval, WEIGHTf, weight);
    382             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, hw_index, rval));
    383         }
    384     }
    385     return SOC_E_NONE;
    386 }
    387 
    388 int 
    389 soc_apache_sched_weight_get(int unit, int port, int level,
    390                          int hw_index, int *weight)
    391 {
    392     soc_apache_sched_type_t sched_type;
    393     uint32 entry[SOC_MAX_MEM_WORDS], rval;
    394     soc_mem_t mem = INVALIDm;
    395     soc_reg_t reg = INVALIDr;
    396 
    397     sched_type = _soc_apache_port_sched_type_get(unit, port);
    398 
    399     if (sched_type == SOC_APACHE_SCHED_LLS) {
    400         mem = _SOC_APACHE_NODE_WIEGHT_MEM(unit, port, level);
    401         if (mem == INVALIDm) {
    402             return SOC_E_INTERNAL;
    403         }
    404         if (mem == LLS_L2_CHILD_WEIGHT_CFG_CNTm &&
    405                 (hw_index > soc_mem_index_max(unit, mem))) {
    406             hw_index -= soc_mem_index_max(unit, mem) + 1;
    407             mem = LLS_L2_MC_CHILD_WEIGHT_CFG_CNTm;
    408         }
    409         SOC_IF_ERROR_RETURN
    410             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, hw_index, &entry));
    411         *weight = soc_mem_field32_get(unit, mem, &entry, C_WEIGHTf);
    412     } else if (sched_type == SOC_APACHE_SCHED_HSP) {
    413         if ((level == SOC_APACHE_NODE_LVL_L0) || (level == SOC_APACHE_NODE_LVL_L1)) {
    414             if (level == SOC_APACHE_NODE_LVL_L0) {
    415                 hw_index = hw_index % 5;
    416                 reg = HSP_SCHED_L0_NODE_WEIGHTr;
    417             } else if (level == SOC_APACHE_NODE_LVL_L1) {
    418                 hw_index = hw_index % 10;
    419                 reg = HSP_SCHED_L1_NODE_WEIGHTr;
    420             }
    421 
    422             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, hw_index, &rval));
    423             *weight = soc_reg_field_get(unit, reg, rval, WEIGHTf);
    424         } else if (level == SOC_APACHE_NODE_LVL_L2) {
    425             if (hw_index < 16384)
    426             {
    427                 reg = HSP_SCHED_L2_UC_QUEUE_WEIGHTr;
    428                 hw_index = hw_index % 10;
    429             } else {
    430                 reg = HSP_SCHED_L2_MC_QUEUE_WEIGHTr;
    431                 hw_index = (hw_index - 16384)% 10;
    432             }
    433 
    434             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, hw_index, &rval));
    435             *weight = soc_reg_field_get(unit, reg, rval, WEIGHTf);
    436         }
    437     }
    438 
    439     LOG_INFO(BSL_LS_SOC_COSQ,
    440              (BSL_META_U(unit,
    441                          "sched_weight_set L%d csch_index=%d wt=%d\n"),
    442                level, hw_index, *weight));
    443 
    444     return SOC_E_NONE;
    445 }
    446 
    447 int
    448 soc_apache_cosq_set_sched_child_config(int unit, soc_port_t port,
    449                               int level, int index,
    450                               int num_spri, int first_sp_child, 
    451                               int first_sp_mc_child, uint32 ucmap)
    452 {
    453     soc_apache_sched_type_t sched_type;
    454     uint32 entry[SOC_MAX_MEM_WORDS];
    455     soc_mem_t mem;
    456 
    457     LOG_INFO(BSL_LS_SOC_COSQ,
    458              (BSL_META_U(unit,
    459                          "Port:%d L%s%d config : index=%d FC=%d FMC=%d UMAP=0x%x\n"),
    460                port, (level == 0) ? "r" : "", level - 1, 
    461                index, first_sp_child, first_sp_mc_child, ucmap));
    462 
    463     mem = INVALIDm;
    464 
    465     sched_type = _soc_apache_port_sched_type_get(unit, port);
    466     if (sched_type == SOC_APACHE_SCHED_HSP) {
    467         return SOC_E_PARAM;
    468     }
    469     
    470     mem = _SOC_APACHE_NODE_CONFIG_MEM(unit, port, level);
    471     if (mem == INVALIDm) {
    472         return SOC_E_PARAM;
    473     }
    474     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry));
    475     soc_mem_field32_set(unit, mem, &entry, P_NUM_SPRIf, num_spri);
    476     if (mem == LLS_L1_CONFIGm) {  
    477         soc_mem_field32_set(unit, mem, &entry, P_START_UC_SPRIf, first_sp_child);
    478         soc_mem_field32_set(unit, mem, &entry, P_START_MC_SPRIf, 
    479                                                        first_sp_mc_child);
    480         soc_mem_field32_set(unit, mem, &entry, P_SPRI_SELECTf, 
    481                             (num_spri > 0) ? ucmap : 0);
    482     } else {
    483         soc_mem_field32_set(unit, mem, &entry, P_START_SPRIf, first_sp_child);
    484     }
    485 
    486     SOC_IF_ERROR_RETURN(soc_mem_write
    487                         (unit, mem, MEM_BLOCK_ANY, index, &entry));
    488 
    489     return SOC_E_NONE;
    490 }
    491 
    492 int
    493 soc_apache_cosq_set_sched_mode(int unit, soc_port_t port, int level, int index,
    494                                const soc_apache_sched_mode_e mode, int weight)
    495 {
    496     soc_apache_sched_type_t sched_type;
    497     uint32 entry[SOC_MAX_MEM_WORDS], mfval = 0, rval = 0, wrr_mask, pmap;
    498     soc_mem_t mem;
    499     soc_reg_t reg;
    500     soc_reg_t lls_per_port[] = { 
    501         LLS_PER_PORT_WRR_PKT_MODE_0r,
    502         LLS_PER_PORT_WRR_PKT_MODE_1r,
    503         LLS_PER_PORT_WRR_PKT_MODE_2r
    504 	};
    505     uint32 mc_group_mode;
    506     int fval, idx, parent_idx = -1;
    507 
    508     LOG_INFO(BSL_LS_SOC_COSQ,
    509              (BSL_META_U(unit,
    510                          "Port:%d L%s%d config : index=%d MODE=%d WT=%d\n"),
    511                port, (level == 0) ? "r" : "", level - 1, 
    512                index, mode, weight));
    513 
    514     reg = INVALIDr;
    515     mem = INVALIDm;
    516     sched_type = _soc_apache_port_sched_type_get(unit, port);
    517     if (sched_type == SOC_APACHE_SCHED_HSP) {
    518         /* get the port relative index / offset */
    519         if (level == SOC_APACHE_NODE_LVL_L0) {
    520             index = index % 5;
    521             reg = HSP_SCHED_PORT_CONFIGr;
    522             parent_idx = 0;
    523         } else if (level == SOC_APACHE_NODE_LVL_L1) {
    524             index = index % 10;
    525             reg = HSP_SCHED_L0_NODE_CONFIGr;
    526             /* Find the Parent index for the current child */
    527             for (idx = 1; idx < 5; idx++) {
    528                 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr(
    529                                                     unit, port, idx, &rval));
    530                 fval = soc_reg_field_get(unit,
    531                             HSP_SCHED_L0_NODE_CONNECTION_CONFIGr,
    532                             rval, CHILDREN_CONNECTION_MAPf);
    533                 if (idx == 4) {
    534                     if ((index >= 8) && (fval & (1 << (index - 2)))) {
    535                         parent_idx = idx;
    536                         break;
    537                     }
    538                 } else {
    539                     if (fval & (1 << index)) {
    540                         parent_idx = idx;
    541                         break;
    542                     }
    543                 }
    544             }
    545         } else if (level == SOC_APACHE_NODE_LVL_L2) {
    546             mc_group_mode = soc_reg_field_get( unit,
    547                     HSP_SCHED_PORT_CONFIGr, rval,
    548                     MC_GROUP_MODEf);
    549             reg = HSP_SCHED_L1_NODE_CONFIGr;
    550             if (mc_group_mode && (index >= 16384)) {
    551                 parent_idx = (index - 16384)  % 10;
    552                 if ( parent_idx  < _AP_HSP_PORT_MAX_COS) {
    553                     reg = HSP_SCHED_L0_NODE_CONFIGr;
    554                     parent_idx = 0;
    555                 }
    556             }else {
    557                 parent_idx = index  % 10;
    558             }  
    559         } else {
    560             return SOC_E_PARAM;
    561         }
    562 
    563         if (parent_idx == -1) {
    564             return SOC_E_INTERNAL;
    565         }
    566 
    567         if (mode == SOC_APACHE_SCHED_MODE_STRICT) {
    568             weight = 0;
    569         } else if (mode == SOC_APACHE_SCHED_MODE_WRR) {
    570             mfval = 1;
    571         } else if (mode == SOC_APACHE_SCHED_MODE_WDRR) {
    572             mfval = 0;
    573         } else {
    574             return SOC_E_PARAM;
    575         }
    576 
    577         /* selection between SP and WxRR is based on weight property. */
    578         SOC_IF_ERROR_RETURN(soc_apache_sched_weight_set(unit, port, 
    579                                                 level, index, weight));
    580 
    581         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
    582         wrr_mask = soc_reg_field_get(unit, reg, rval, ENABLE_WRRf);
    583         wrr_mask &= ~(1 << parent_idx);
    584         wrr_mask |= (mfval << parent_idx);
    585         soc_reg_field_set(unit, reg, &rval, ENABLE_WRRf, wrr_mask);
    586         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
    587  
    588     } else {
    589         if (mode == SOC_APACHE_SCHED_MODE_STRICT) {
    590             weight = 0;
    591         }
    592 
    593         SOC_IF_ERROR_RETURN(soc_apache_sched_weight_set(unit, port, 
    594                                                 level, index, weight));
    595 
    596         if (mode != SOC_APACHE_SCHED_MODE_STRICT) { 
    597             mem = _SOC_APACHE_NODE_CONFIG_MEM(unit, port, SOC_APACHE_NODE_LVL_S1);
    598             index = _soc_apache_s1_scheduler_index(unit, port,  level, index);
    599             if (index == -1) {
    600                 return SOC_E_INTERNAL;
    601             }
    602             SOC_IF_ERROR_RETURN(
    603                     soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry));
    604             soc_mem_field32_set(unit, mem, entry, 
    605                     PACKET_MODE_WRR_ACCOUNTING_ENABLEf, 
    606                     (mode == SOC_APACHE_SCHED_MODE_WRR) ? 1 : 0);
    607             SOC_IF_ERROR_RETURN(
    608                     soc_mem_write(unit, mem, MEM_BLOCK_ANY, index, &entry));
    609         }
    610     }
    611     if ((mode == SOC_APACHE_SCHED_MODE_WRR) && (!IS_CPU_PORT(unit, port)))  {
    612         reg = lls_per_port[port/32];
    613         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
    614         pmap = soc_reg_field_get(unit, reg, rval, WRR_PKT_MODEf);
    615         pmap = pmap | (1 << port); 
    616         soc_reg_field_set(unit, reg, &rval,WRR_PKT_MODEf, pmap);
    617         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 
    618     }
    619     return SOC_E_NONE;
    620 }
    621 
    622 /* number of registers in the set to support Dynamic Scheduling */
    623 #define _SOC_APACHE_DYN_REGISTER_SET    4  
    624 
    625 /* Structure to maintain the ports that are undergoing dyn sched*/
    626 typedef struct _soc_apache_port_dyn_sched_s {
    627     sal_mutex_t     lock;
    628     int             port[_SOC_APACHE_DYN_REGISTER_SET];
    629     int             _soc_apache_init_done[SOC_MAX_NUM_DEVICES];
    630 } _soc_apache_port_dyn_sched_t;
    631 
    632 static _soc_apache_port_dyn_sched_t _apache_dyn_sched_unit_data[SOC_MAX_NUM_DEVICES];
    633 
    634 /*
    635  * Function:
    636  *     _soc_apache_alloc_dyn_set
    637  * Purpose:
    638  *     This function allocates the register available from
    639  *     the set of SP_WERR_DYN_CHANGEnA/nB/nC (n=0,1,2,3) to the port and 
    640  *     updates the structure _apache_dyn_sched_unit_data to keep track 
    641  *     of the used registers from the set.
    642  * Parameters:
    643  *     unit       - (IN) unit number
    644  *     port       - (IN) local port number
    645  *     r_a        - (OUT) SP_WERR_DYN_CHANGEnA register
    646  *     r_b        - (OUT) SP_WERR_DYN_CHANGEnB register
    647  *     r_ctrl     - (OUT) SP_WERR_DYN_CHANGEnC register
    648  * Returns:
    649  *     SOC_E_XXX
    650  */
    651 STATIC int _soc_apache_alloc_dyn_set(int unit, int port, 
    652             soc_reg_t *r_a, soc_reg_t *r_b, soc_reg_t *r_ctrl)
    653 {
    654     _soc_apache_port_dyn_sched_t *pcb;
    655     int i, empty_at = -1, rv = SOC_E_NONE;
    656 
    657     soc_reg_t dyn_change_a_x[] = {
    658                                        LLS_SP_WERR_DYN_CHANGE_0Ar,
    659                                        LLS_SP_WERR_DYN_CHANGE_1Ar,
    660                                        LLS_SP_WERR_DYN_CHANGE_2Ar,
    661                                        LLS_SP_WERR_DYN_CHANGE_3Ar
    662                                  };
    663     soc_reg_t dyn_change_b_x[] = {
    664                                        LLS_SP_WERR_DYN_CHANGE_0Br,
    665                                        LLS_SP_WERR_DYN_CHANGE_1Br,
    666                                        LLS_SP_WERR_DYN_CHANGE_2Br,
    667                                        LLS_SP_WERR_DYN_CHANGE_3Br
    668                                  };
    669     
    670     soc_reg_t dyn_change_ctrl_x[] = {
    671                                        LLS_SP_WERR_DYN_CHANGE_0Cr,
    672                                        LLS_SP_WERR_DYN_CHANGE_1Cr,
    673                                        LLS_SP_WERR_DYN_CHANGE_2Cr,
    674                                        LLS_SP_WERR_DYN_CHANGE_3Cr
    675                                     };
    676 
    677     pcb = &_apache_dyn_sched_unit_data[unit];
    678     
    679     sal_mutex_take(pcb->lock, sal_sem_FOREVER);
    680     for (i = 0; i < _SOC_APACHE_DYN_REGISTER_SET; i++) {
    681         if (pcb->port[i] == -1) {
    682             empty_at = i;
    683             break;
    684         } else if (pcb->port[i] == port) {
    685             rv = SOC_E_BUSY;
    686             break;
    687         }
    688     }
    689 
    690     if (!rv && (empty_at >= 0)) {
    691         pcb->port[empty_at] = port;
    692     }
    693     
    694     sal_mutex_give(pcb->lock);
    695 
    696     if (rv) {
    697         return rv;
    698     }
    699 
    700     if (empty_at == -1) {
    701         return SOC_E_BUSY;
    702     }
    703     *r_a = dyn_change_a_x[empty_at];
    704     *r_b = dyn_change_b_x[empty_at];
    705     *r_ctrl = dyn_change_ctrl_x[empty_at];
    706     return SOC_E_NONE;
    707 }
    708 
    709 /*
    710  * Function:
    711  *     _soc_apache_free_dyn_set
    712  * Purpose:
    713  *     This function is called after the switchover is done 
    714  *     to update the structure _apache_dyn_sched_unit_data by  
    715  *     removing the port from it. This makes the register
    716  *     used for the request available for the next request.
    717  * Parameters:
    718  *     unit       - (IN) unit number
    719  *     port       - (IN) local port number
    720  * Returns:
    721  *     SOC_E_XXX
    722  */
    723 STATIC int _soc_apache_free_dyn_set(int unit, int port)
    724 {
    725     _soc_apache_port_dyn_sched_t *pcb;
    726     int i;
    727 
    728     pcb = &_apache_dyn_sched_unit_data[unit];
    729 
    730     sal_mutex_take(pcb->lock, sal_sem_FOREVER);
    731     for (i = 0; i < _SOC_APACHE_DYN_REGISTER_SET; i++) {
    732         if (pcb->port[i] == port) {
    733             pcb->port[i] = -1;
    734         }
    735     }
    736     sal_mutex_give(pcb->lock);
    737     
    738     return SOC_E_NONE;
    739 }
    740 
    741 /*
    742  * Function:
    743  *     soc_apache_cosq_set_sched_child_config_dynamic
    744  * Purpose:
    745  *     This function enables the spri_vect_mode by setting the 
    746  *     spri_vect_mode_enable field to 1 in the LLS_CONFIG0 reg, which changes 
    747  *     p_num_spri[3:0] to p_vect_spri[7:0]. It allocates the register from set
    748  *     of SP_WERR_DYN_CHNG_nA/nB/nC registers to the port. It then sets the 
    749  *     SP_WERR_DYN_CHNG_nB/nC reg with the new value for the node id's parent.
    750  *     It sets the fields in SP_WERR_DYN_CHNG_nA with the info about the node
    751  *     to be switched like node_id, node_level and parent_id along with in_use
    752  *     field to 1, which triggers the request in H/W. The H/W clears in_use
    753  *     field to 0 once the switchover is complete, so we keep polling its
    754  *     to know about the completion of the request. 
    755  * Parameters:
    756  *     unit       - (IN) unit number
    757  *     port       - (IN) local port number
    758  *     level      - (IN) level of the node
    759  *     index      - (IN) index of the node
    760  *     num_spri   - (IN) number of SPRI child nodes
    761  *     first_child - (IN) first child node
    762  *     first_mc_child - (IN) first multicast child node
    763  *     ucmap        - (IN) unicast map
    764  *     spmap        - (IN) spri map
    765  *     child_index     - (IN) index number of the child
    766  * Returns:
    767  *     SOC_E_XXX
    768  */
    769 int
    770 soc_apache_cosq_set_sched_child_config_dynamic(int unit, soc_port_t port,
    771                                             int level, int index, 
    772                                             int num_spri, int first_child,
    773                                             int first_mc_child, uint32 ucmap,
    774                                             uint32 spmap, int child_index)
    775 {
    776     uint32 entry[SOC_MAX_MEM_WORDS], rval, d32, timeout_val, old_spmap, f1, f2;
    777     soc_mem_t mem;
    778     int rv = SOC_E_NONE;
    779     soc_reg_t r_a = INVALIDr, r_b = INVALIDr, r_ctrl = INVALIDr;
    780     soc_timeout_t timeout;
    781 
    782     if (level == SOC_APACHE_NODE_LVL_ROOT) {
    783         return SOC_E_NONE;
    784     }
    785 
    786     SOC_IF_ERROR_RETURN(_soc_apache_alloc_dyn_set(unit, port, 
    787                                                &r_a, &r_b, &r_ctrl));
    788 
    789     mem = _SOC_APACHE_NODE_CONFIG_MEM(unit, port, level);
    790     if (mem == INVALIDm) {
    791         return SOC_E_INTERNAL;
    792     }
    793 
    794     level -= 1;
    795     /* Getting the old spmap */    
    796     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry));
    797     f1 = soc_mem_field32_get(unit, mem, &entry, P_NUM_SPRIf);
    798     f2 = soc_mem_field32_get(unit, mem, &entry, P_VECT_SPRI_7_4f);
    799     old_spmap = f1 | (f2 << 4);
    800 
    801     LOG_INFO(BSL_LS_SOC_COSQ,
    802             (BSL_META_U(unit,
    803             "Port:%d L%s%d config : index=%d FC=%d FMC=%d UMAP=0x%x NUMSP=%d\n"), 
    804              port, (level==0) ? "r" : "", level, 
    805              index, first_child, first_mc_child, ucmap, num_spri));
    806 
    807     /* Setting the memory fields based on the new spmap */
    808     soc_mem_field32_set(unit, mem, &entry, P_NUM_SPRIf, spmap & 0xf);
    809     soc_mem_field32_set(unit, mem, &entry, P_VECT_SPRI_7_4f, (spmap >> 4) & 0xf);
    810 
    811     if (mem == LLS_L1_CONFIGm) {
    812         soc_mem_field32_set(unit, mem, &entry, P_START_UC_SPRIf, first_child);
    813         soc_mem_field32_set(unit, mem, &entry, P_START_MC_SPRIf, first_mc_child);
    814         soc_mem_field32_set(unit, mem, &entry, P_SPRI_SELECTf, 
    815                             (num_spri > 0) ? ucmap : 0);
    816     } else {
    817         soc_mem_field32_set(unit, mem, &entry, P_START_SPRIf, first_child);
    818     }
    819 
    820     SOC_IF_ERROR_RETURN(
    821         soc_mem_write(unit, mem, MEM_BLOCK_ANY, index, &entry));
    822 
    823     rval = 0;
    824     soc_bits_get(entry, 0, 31, &d32);
    825     soc_reg_field_set(unit, r_ctrl, &rval, LLS_PARENT_CONFIGf, d32);
    826     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, r_ctrl, REG_PORT_ANY, 0, rval));
    827 
    828     rval = 0;
    829     soc_bits_get(entry, 32, 45, &d32);
    830     soc_reg_field_set(unit, r_b, &rval, LLS_PARENT_CONFIGf, d32);
    831     soc_reg_field_set(unit, r_b, &rval, LLS_PARENT_CONFIG_ORIGINAL_SP_VECTORf,
    832                                             old_spmap);
    833     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, r_b, REG_PORT_ANY, 0, rval));
    834 
    835     rval = 0;
    836     soc_reg_field_set(unit, r_a, &rval, NODE_LEVELf, level + 1);
    837     soc_reg_field_set(unit, r_a, &rval, NODE_IDf, child_index);
    838     soc_reg_field_set(unit, r_a, &rval, PARENT_IDf, index);
    839     soc_reg_field_set(unit, r_a, &rval, IN_USEf, 1);
    840     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, r_a, REG_PORT_ANY, 0, rval));
    841 
    842     if (!SAL_BOOT_SIMULATION) {
    843         timeout_val = soc_property_get(unit, spn_MMU_QUEUE_FLUSH_TIMEOUT, 2000000);
    844         soc_timeout_init(&timeout, timeout_val, 0);
    845 
    846         do {
    847             SOC_IF_ERROR_RETURN(
    848                 soc_reg32_get(unit, r_a, REG_PORT_ANY, 0, &rval));
    849                 
    850             if (soc_timeout_check(&timeout)) {
    851                 rv = SOC_E_TIMEOUT;
    852                 break;
    853             }
    854         } while (soc_reg_field_get(unit, r_a, rval, IN_USEf));
    855     }
    856 
    857     SOC_IF_ERROR_RETURN(_soc_apache_free_dyn_set(unit, port));
    858 
    859     return rv;
    860 }
    861 
    862 int
    863 soc_apache_cosq_set_sched_config(int unit, soc_port_t port,
    864                               int level, int index, int child_index,
    865                               int num_spri, int first_child, 
    866                               int first_mc_child, uint32 ucmap, uint32 spmap,
    867                               const soc_apache_sched_mode_e mode, int weight)
    868 {
    869     int child_level;
    870 
    871     if (level >= SOC_APACHE_NODE_LVL_L2) {
    872         return SOC_E_PARAM;
    873     }
    874 
    875     SOC_IF_ERROR_RETURN(
    876         soc_apache_cosq_set_sched_child_config_dynamic(unit, port,
    877                                 level, index, num_spri, first_child, 
    878                                 first_mc_child, ucmap, spmap, child_index));
    879     if (child_index >= 0) {
    880         soc_apache_get_child_type(unit, port, level, &child_level);
    881         SOC_IF_ERROR_RETURN(soc_apache_cosq_set_sched_mode(unit, port, 
    882                     child_level, 
    883                     child_index, mode, weight));
    884     }
    885 
    886     return SOC_E_NONE;
    887 }
    888 
    889 int
    890 soc_apache_cosq_get_sched_child_config(int unit, soc_port_t port,
    891                               int level, int index,
    892                               int *pnum_spri, int *pfirst_sp_child, 
    893                               int *pfirst_sp_mc_child, uint32 *pucmap, uint32 *pspmap)
    894 {
    895     soc_apache_sched_type_t sched_type;
    896     uint32 entry[SOC_MAX_MEM_WORDS];
    897     uint32 num_spri = 0, ucmap = 0, f1, f2;
    898     int first_sp_child = -1, first_sp_mc_child = -1,ii;
    899     soc_mem_t mem;
    900 
    901     sched_type = _soc_apache_port_sched_type_get(unit, port);
    902 
    903     mem = INVALIDm;
    904 
    905     if (sched_type == SOC_APACHE_SCHED_HSP) {
    906         return SOC_E_PARAM;
    907     }
    908 
    909     mem = _SOC_APACHE_NODE_CONFIG_MEM(unit, port, level);
    910     SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry));
    911     num_spri = soc_mem_field32_get(unit, mem, &entry, P_NUM_SPRIf);
    912 
    913     f1 = soc_mem_field32_get(unit, mem, &entry, P_NUM_SPRIf);
    914     f2 = soc_mem_field32_get(unit, mem, &entry, P_VECT_SPRI_7_4f);
    915     *pspmap = f1 | (f2 << 4);
    916     for (ii = 0; ii < 8; ii++) {
    917         if ((1 << ii) & *pspmap) {
    918             num_spri++;
    919         }
    920     }
    921     if (mem == LLS_L1_CONFIGm) { 
    922         first_sp_child = soc_mem_field32_get(unit, mem, &entry, P_START_UC_SPRIf);
    923         first_sp_mc_child = soc_mem_field32_get(unit, mem, 
    924                                          &entry, P_START_MC_SPRIf);
    925         ucmap = soc_mem_field32_get(unit, mem, &entry, P_SPRI_SELECTf);
    926     } else {
    927         first_sp_child = soc_mem_field32_get(unit, mem, &entry, P_START_SPRIf);
    928         first_sp_mc_child = 0;
    929     }
    930     
    931     if (num_spri == 0) {
    932         ucmap = 0;
    933     }
    934 
    935     if (pnum_spri) {
    936         *pnum_spri = num_spri;
    937     }
    938        
    939     if (pucmap) {
    940         *pucmap = ucmap;
    941     }
    942 
    943     if (pfirst_sp_child) {
    944         *pfirst_sp_child = first_sp_child;
    945     }
    946 
    947     if (pfirst_sp_mc_child) {
    948         *pfirst_sp_mc_child = first_sp_mc_child;
    949     }
    950 
    951     LOG_INFO(BSL_LS_SOC_COSQ,
    952              (BSL_META_U(unit,
    953                          "Port:%d L%s%d config : index=%d FC=%d FMC=%d UMAP=0x%x\n"),
    954                port, (level == 0) ? "r" : "", level - 1, 
    955                index, first_sp_child, first_sp_mc_child, ucmap));
    956 
    957     return SOC_E_NONE;
    958 }
    959 
    960 int
    961 soc_apache_cosq_get_sched_mode(int unit, soc_port_t port, int level, 
    962                             int index, soc_apache_sched_mode_e *pmode, int *weight)
    963 {
    964     soc_apache_sched_type_t sched_type;
    965     uint32 entry[SOC_MAX_MEM_WORDS], rval, wrr_mask;
    966     soc_apache_sched_mode_e mode = SOC_APACHE_SCHED_MODE_UNKNOWN;
    967     soc_mem_t mem;
    968     soc_reg_t reg;
    969     int parent_idx  = 0;
    970     int  idx, fval;   
    971     uint32 mc_group_mode = 0;
    972     reg = INVALIDr;
    973     mem = INVALIDm;
    974     sched_type = _soc_apache_port_sched_type_get(unit, port);
    975 
    976     if (sched_type == SOC_APACHE_SCHED_HSP) {
    977         /* get the port relative index / offset */
    978         if (level == SOC_APACHE_NODE_LVL_L0) {
    979             index = index % 5;
    980             reg = HSP_SCHED_PORT_CONFIGr;
    981             parent_idx = 0;
    982         } else if (level == SOC_APACHE_NODE_LVL_L1) {
    983             index = index % 10;
    984             reg = HSP_SCHED_L0_NODE_CONFIGr;
    985             /* Find the Parent index for the current child */
    986             for (idx = 1; idx < 5; idx++) {
    987                 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr(
    988                                                     unit, port, idx, &rval));
    989                 fval = soc_reg_field_get(unit,
    990                             HSP_SCHED_L0_NODE_CONNECTION_CONFIGr,
    991                             rval, CHILDREN_CONNECTION_MAPf);
    992                 if (idx == 4) {
    993                     if ((index >= 8) && (fval & (1 << (index - 2)))) {
    994                         parent_idx = idx;
    995                         break;
    996                     }
    997                 } else {
    998                     if (fval & (1 << index)) {
    999                         parent_idx = idx;
   1000                         break;
   1001                     }
   1002                 }
   1003             }
   1004         } else if (level == SOC_APACHE_NODE_LVL_L2) {
   1005             SOC_IF_ERROR_RETURN(
   1006                     READ_HSP_SCHED_PORT_CONFIGr( unit, port, &rval));
   1007             mc_group_mode = soc_reg_field_get( unit,
   1008                                                HSP_SCHED_PORT_CONFIGr, rval,
   1009                                                MC_GROUP_MODEf);
   1010             reg = HSP_SCHED_L1_NODE_CONFIGr;
   1011 
   1012             if (mc_group_mode && (index >= 16384)) {
   1013                 parent_idx = (index - 16384)  % 10;
   1014                 if ( parent_idx  < _AP_HSP_PORT_MAX_COS) {
   1015                     reg = HSP_SCHED_L0_NODE_CONFIGr;
   1016                     parent_idx = 0;
   1017                 }
   1018             }else {
   1019                 parent_idx = index  % 10;
   1020             }
   1021 
   1022         } else {
   1023             return SOC_E_PARAM;
   1024         }
   1025 
   1026         /* selection between SP and WxRR is based on weight property. */
   1027         SOC_IF_ERROR_RETURN(soc_apache_sched_weight_get(unit, port, 
   1028                                                 level, index, weight));
   1029         if (*weight == 0) {
   1030             mode = SOC_APACHE_SCHED_MODE_STRICT;
   1031         } else {
   1032             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
   1033             wrr_mask = soc_reg_field_get(unit, reg, rval, ENABLE_WRRf);
   1034             if (wrr_mask & (1 << parent_idx)) {
   1035                 mode = SOC_APACHE_SCHED_MODE_WRR;
   1036             } else {
   1037                 mode = SOC_APACHE_SCHED_MODE_WDRR;
   1038             }
   1039         }
   1040     } else {
   1041         SOC_IF_ERROR_RETURN(soc_apache_sched_weight_get(unit, port, 
   1042                         level, index, weight));
   1043         if (*weight == 0) {
   1044             mode = SOC_APACHE_SCHED_MODE_STRICT;
   1045         } else {
   1046             mem = _SOC_APACHE_NODE_CONFIG_MEM(unit, port, SOC_APACHE_NODE_LVL_S1);
   1047             index = _soc_apache_s1_scheduler_index(unit, port,  level, index);
   1048             if (index == -1) {
   1049                 return SOC_E_INTERNAL;
   1050             }
   1051             SOC_IF_ERROR_RETURN(
   1052                     soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry));
   1053             if (soc_mem_field32_get(unit, mem, 
   1054                                 entry, PACKET_MODE_WRR_ACCOUNTING_ENABLEf)) {
   1055                 mode = SOC_APACHE_SCHED_MODE_WRR;
   1056             } else {
   1057                 mode = SOC_APACHE_SCHED_MODE_WDRR;
   1058             }
   1059         }
   1060     }
   1061 
   1062     if (pmode) {
   1063         *pmode = mode;
   1064     }
   1065 
   1066     LOG_INFO(BSL_LS_SOC_COSQ,
   1067              (BSL_META_U(unit,
   1068                          "Port:%d L%s%d config : index=%d MODE=%d WT=%d\n"),
   1069                port, (level == 0) ? "r" : "", level - 1, index, mode, *weight));
   1070 
   1071     return SOC_E_NONE;
   1072 }
   1073 
   1074 int
   1075 soc_apache_cosq_get_sched_config(int unit, soc_port_t port,
   1076                               int level, int index, int child_index,
   1077                               int *pnum_spri, int *pfirst_child, 
   1078                               int *pfirst_mc_child, uint32 *pucmap, uint32 *pspmap,
   1079                               soc_apache_sched_mode_e *pmode, int *weight)
   1080 {
   1081     int child_level;
   1082 
   1083     if (level >= SOC_APACHE_NODE_LVL_L2) {
   1084         return SOC_E_PARAM;
   1085     }
   1086 
   1087     if (level != SOC_APACHE_NODE_LVL_ROOT) {
   1088         SOC_IF_ERROR_RETURN(soc_apache_cosq_get_sched_child_config(unit, port, level,
   1089                     index, pnum_spri, pfirst_child, pfirst_mc_child, pucmap, pspmap));
   1090     }
   1091 
   1092     if (child_index >= 0) {
   1093         soc_apache_get_child_type(unit, port, level, &child_level);
   1094         SOC_IF_ERROR_RETURN(
   1095                 soc_apache_cosq_get_sched_mode(unit, port, child_level, child_index,
   1096                                             pmode, weight));
   1097     }
   1098     
   1099     return SOC_E_NONE;
   1100 }
   1101 
   1102 int soc_apache_get_child_type(int unit, soc_port_t port, int level, 
   1103                                     int *child_type)
   1104 {
   1105     *child_type = -1;
   1106     if (level == SOC_APACHE_NODE_LVL_ROOT) {
   1107         *child_type = SOC_APACHE_NODE_LVL_S1;
   1108     } else if (level == SOC_APACHE_NODE_LVL_S1) {
   1109             *child_type = SOC_APACHE_NODE_LVL_L0;
   1110     } else if (level == SOC_APACHE_NODE_LVL_L0) {
   1111         *child_type = SOC_APACHE_NODE_LVL_L1;
   1112     } else if (level == SOC_APACHE_NODE_LVL_L1) {
   1113         *child_type = SOC_APACHE_NODE_LVL_L2;
   1114     }
   1115     return SOC_E_NONE;
   1116 }
   1117 int
   1118 soc_ap_is_skip_default_lls_creation(int unit) {
   1119     int skip = 0;
   1120     soc_pbmp_t skip_default_lls_pbmp;
   1121 
   1122     skip_default_lls_pbmp = soc_property_get_pbmp(unit, spn_PBMP_SKIP_DEFAULT_LLS, 0);
   1123     if (SOC_PBMP_NOT_NULL(skip_default_lls_pbmp)) {
   1124         skip = 1;
   1125     }
   1126 
   1127     return skip;
   1128 }
   1129 
   1130 STATIC int
   1131 _soc_apache_alloc_sched(int unit, soc_port_t in_port, soc_apache_node_lvl_e lvl, 
   1132                      int offset, int *hw_index)
   1133 {
   1134     int in_pipe, tlm = -1;
   1135     int mmu_port, max = -1;
   1136     soc_apache_sched_type_t stype;
   1137     uint32  sched_bmap[32];
   1138     
   1139     sal_memset(sched_bmap, 0, sizeof(uint32)*32);
   1140 
   1141     SOC_IF_ERROR_RETURN(
   1142         soc_apache_port_common_attributes_get(unit, in_port, &in_pipe, &mmu_port, NULL));
   1143 
   1144     stype = _soc_apache_port_sched_type_get(unit, in_port);
   1145 
   1146     if (lvl == SOC_APACHE_NODE_LVL_ROOT) {
   1147         tlm = 1;
   1148         max = 106;
   1149     } else if (lvl == SOC_APACHE_NODE_LVL_L0) {
   1150         tlm = 5; /* max 4 L0 under HSP */
   1151         max = 272;
   1152     } else if (lvl == SOC_APACHE_NODE_LVL_L1) {
   1153         tlm = 10;
   1154         max = 1024;
   1155     }
   1156 
   1157     if ((max < 0) || (tlm < 0)) {
   1158         return SOC_E_PARAM;
   1159     }
   1160         
   1161     if (stype == SOC_APACHE_SCHED_HSP) {
   1162         /* For HSP ports, the indexes of the scheduler and queues are fixed.*/
   1163         if (offset >= tlm) {
   1164             return SOC_E_PARAM;
   1165         }
   1166         mmu_port += (mmu_port >= 74) ? -74 : 0;
   1167         *hw_index = (mmu_port * tlm) + offset;
   1168         return SOC_E_NONE;
   1169     }  
   1170 
   1171     return SOC_E_RESOURCE;
   1172 }
   1173 
   1174 int soc_apache_l2_hw_index(int unit, int qnum, int uc)
   1175 {
   1176     if (uc) {
   1177         qnum -= (qnum >= 16384) ? 16384 : 0;
   1178     } else {
   1179         qnum -= (qnum >= 778) ? 778 : 0;
   1180         qnum += 16384;
   1181     }
   1182     return qnum;
   1183 }
   1184 
   1185 /*
   1186  * Function:
   1187  *     soc_apache_hw_index_logical_num
   1188  * Purpose:
   1189  *     Get the logical queue number according to hw index
   1190  * Parameters:
   1191  *     unit          - (IN) unit number
   1192  *     port          - (IN) local port number
   1193  *     index         -(IN) The index of Queue management related memory Tables
   1194  *     uc            - (IN) unicast indicator
   1195  * Returns:
   1196  *     logical queue number: queue number in logical view
   1197  *     In logical view,
   1198  *     the range of unicast queue number is:   [0,16384)
   1199  *     the range of multicast queue number is: [0,778)
   1200  */
   1201 int
   1202 soc_apache_hw_index_logical_num(int unit,int port,int index,int uc)
   1203 {
   1204     int qnum;
   1205     if (uc) {
   1206         qnum = index;
   1207     } else {
   1208         
   1209         qnum =  index - 16384;
   1210     }
   1211 
   1212     return qnum;
   1213 }
   1214 
   1215 
   1216 #define AP_DFL_HSP_SCHED_MODE  SOC_APACHE_SCHED_MODE_WDRR
   1217 
   1218 int
   1219 soc_apache_setup_hsp_port(int unit, int port)
   1220 {
   1221     uint32 rval, fval = 0, pbmf;
   1222     int mmu_port, pipe, l0_index, l1_index, l0_1, l0_4, hw_index, index;
   1223 
   1224    
   1225     SOC_IF_ERROR_RETURN(
   1226         soc_apache_port_common_attributes_get(unit, port, &pipe, &mmu_port, NULL));
   1227 
   1228     for (index = 0; index < 5; index++) {
   1229         SHR_BITSET(SOC_CONTROL(unit)->port_lls_l0_bmap[port],
   1230                 (mmu_port & 0x3f) * 5 + index);
   1231     }
   1232     for (index = 0; index < 10; index++) {
   1233         SHR_BITSET(SOC_CONTROL(unit)->port_lls_l1_bmap[port],
   1234                 (mmu_port & 0x3f) * 10 + index);
   1235     }
   1236     for (index = 0; index < 10; index++) {
   1237         SHR_BITSET(SOC_CONTROL(unit)->port_lls_l2_bmap[port],
   1238                 (mmu_port & 0x3f) * 10 + index);
   1239     }
   1240 
   1241     rval = 0;
   1242     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_PORT_CONFIGr(unit, port, rval));
   1243     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L0_NODE_CONFIGr(unit, port, rval));
   1244     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L1_NODE_CONFIGr(unit, port, rval));
   1245     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L2_UC_QUEUE_CONFIGr(unit, port, rval));
   1246 
   1247     l0_1 = 0;
   1248     l0_4 = 0;
   1249     for (l0_index = 0; l0_index < 5; l0_index++) {
   1250         SOC_IF_ERROR_RETURN(soc_apache_sched_hw_index_get(unit, port, 
   1251                                     SOC_APACHE_NODE_LVL_L0, l0_index, &hw_index));
   1252         SOC_IF_ERROR_RETURN(soc_apache_cosq_set_sched_parent(unit, port,
   1253                               SOC_APACHE_NODE_LVL_L0, hw_index, mmu_port, 1));
   1254 
   1255         if (l0_index == 1) {
   1256             l0_1 = hw_index;
   1257         } else if (l0_index == 4) {
   1258             l0_4 = hw_index;
   1259         }
   1260     }
   1261 
   1262     for (l1_index = 0; l1_index < 10; l1_index++) {
   1263         SOC_IF_ERROR_RETURN(soc_apache_sched_hw_index_get(unit, port, 
   1264                                     SOC_APACHE_NODE_LVL_L1, l1_index, &hw_index));
   1265 
   1266         SOC_IF_ERROR_RETURN(soc_apache_cosq_set_sched_parent(unit, port,
   1267                    SOC_APACHE_NODE_LVL_L1, hw_index, (l1_index < 8) ? l0_1 : l0_4, 1));
   1268 
   1269         SOC_IF_ERROR_RETURN(soc_apache_cosq_set_sched_mode(unit, port, 
   1270                  SOC_APACHE_NODE_LVL_L1, l1_index, SOC_APACHE_SCHED_MODE_WDRR, 1));
   1271     }
   1272 
   1273     pbmf = IS_HSP_PORT_IN_XPIPEf;
   1274     SOC_IF_ERROR_RETURN(READ_HSP_SCHED_GLOBAL_CONFIGr(unit, &rval));
   1275     fval = soc_reg_field_get(unit, HSP_SCHED_GLOBAL_CONFIGr, rval, pbmf);
   1276     fval |= (1 << mmu_port);
   1277     soc_reg_field_set(unit, HSP_SCHED_GLOBAL_CONFIGr, &rval, pbmf, fval);
   1278     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_GLOBAL_CONFIGr(unit, rval));
   1279     return SOC_E_NONE;
   1280 }
   1281 
   1282 int
   1283 soc_apache_delete_hsp_port(int unit, int port)
   1284 {
   1285     uint32 rval, fval = 0, pbmf;
   1286     int mmu_port, pipe, l0_index, index;
   1287 
   1288     SOC_IF_ERROR_RETURN(
   1289             soc_apache_port_common_attributes_get(unit, port, &pipe, &mmu_port, NULL));
   1290 
   1291     for (index = 0; index < 5; index++) {
   1292         SHR_BITCLR(SOC_CONTROL(unit)->port_lls_l0_bmap[port],
   1293                 (mmu_port & 0x3f) * 5 + index);
   1294     }
   1295     for (index = 0; index < 10; index++) {
   1296         SHR_BITCLR(SOC_CONTROL(unit)->port_lls_l1_bmap[port],
   1297                 (mmu_port & 0x3f) * 10 + index);
   1298     }
   1299     for (index = 0; index < 10; index++) {
   1300         SHR_BITCLR(SOC_CONTROL(unit)->port_lls_l2_bmap[port],
   1301                 (mmu_port & 0x3f) * 10 + index);
   1302     }
   1303   
   1304     rval = 0;
   1305     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_PORT_CONFIGr(unit, port, rval));
   1306     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L0_NODE_CONFIGr(unit, port, rval));
   1307     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L1_NODE_CONFIGr(unit, port, rval));
   1308     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L2_UC_QUEUE_CONFIGr(unit, port, rval));
   1309 
   1310     for (l0_index = 0; l0_index < 5; l0_index++) {
   1311         SOC_IF_ERROR_RETURN(
   1312                 WRITE_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr(unit, port,
   1313                     l0_index, rval));
   1314     }
   1315 
   1316     pbmf = IS_HSP_PORT_IN_XPIPEf;
   1317     SOC_IF_ERROR_RETURN(READ_HSP_SCHED_GLOBAL_CONFIGr(unit, &rval));
   1318     fval = soc_reg_field_get(unit, HSP_SCHED_GLOBAL_CONFIGr, rval, pbmf);
   1319     fval &= (~(1 << mmu_port));
   1320     soc_reg_field_set(unit, HSP_SCHED_GLOBAL_CONFIGr, &rval, pbmf, fval);
   1321     SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_GLOBAL_CONFIGr(unit, rval));
   1322     return SOC_E_NONE;
   1323 }
   1324 
   1325 /*
   1326  * Function:
   1327  *     _soc_apache_lls_init
   1328  * Purpose:
   1329  *     This function initialises the structure _apache_dyn_sched_unit_data, which is
   1330  *     used later to allocate the register available from  the set of 
   1331  *     SP_WERR_DYN_CHANGEnA/nB/nC (n=0,1,2,3) to the port and  to keep track 
   1332  *     of the used registers from the set for the port 
   1333  * Parameters:
   1334  *     unit       - (IN) unit number
   1335  * Returns:
   1336  *     SOC_E_XXX
   1337  */
   1338 STATIC int _soc_apache_lls_init(int unit)
   1339 {
   1340     _soc_apache_port_dyn_sched_t *pcb = NULL;
   1341     int i;
   1342     
   1343     if (soc_feature(unit, soc_feature_vector_based_spri)) {
   1344         pcb = &_apache_dyn_sched_unit_data[unit];
   1345         
   1346         if (pcb->_soc_apache_init_done[unit] == 1) {
   1347             return SOC_E_NONE;
   1348         }
   1349 
   1350         pcb->lock = sal_mutex_create("apache_dyn_lock");
   1351         for (i = 0; i < _SOC_APACHE_DYN_REGISTER_SET; i++) {
   1352             pcb->port[i] = -1;
   1353         }
   1354         pcb->_soc_apache_init_done[unit] = 1;
   1355     }
   1356 
   1357     return SOC_E_NONE;
   1358 }
   1359 
   1360 int soc_apache_lls_init(int unit)
   1361 {
   1362 
   1363     SOC_IF_ERROR_RETURN(_soc_apache_lls_init(unit));
   1364 
   1365 
   1366     SOC_IF_ERROR_RETURN(soc_apache_init_invalid_parents(unit));
   1367     
   1368     SOC_IF_ERROR_RETURN(soc_apache_set_invalid_parent(unit));
   1369 
   1370 
   1371     return SOC_E_NONE;
   1372 }
   1373 
   1374 int
   1375 soc_apache_sched_hw_index_get(int unit, int port, int lvl, int offset, 
   1376                             int *hw_index)
   1377 {
   1378     int rv;
   1379 
   1380     rv = _soc_apache_alloc_sched(unit, port, lvl, offset, hw_index);
   1381 
   1382     LOG_INFO(BSL_LS_SOC_COSQ,
   1383              (BSL_META_U(unit,
   1384                          "Alloced : port=%d lvl=%d ofst=%d Index=%d\n"),
   1385                                 port, lvl, offset, *hw_index));
   1386     return rv;
   1387 }
   1388 
   1389 int
   1390 soc_apache_qcn_counter_hw_index_get(int unit, soc_port_t port,
   1391                                  int index, int *qindex)
   1392 {
   1393     soc_mem_t mem;
   1394     mmu_qcn_enable_entry_t entry;
   1395     int resolved_index = -1;    
   1396     
   1397     if (qindex == NULL) {
   1398         return SOC_E_PARAM;
   1399     }
   1400 
   1401     mem = MMU_QCN_ENABLE_0m;
   1402 
   1403     resolved_index = soc_apache_l2_hw_index(unit, index, 1);
   1404     SOC_IF_ERROR_RETURN
   1405         (soc_mem_read(unit, mem, MEM_BLOCK_ANY, resolved_index, &entry));
   1406     if (soc_mem_field32_get(unit, mem, &entry, CPQ_ENf)) {
   1407         *qindex = soc_mem_field32_get(unit, mem, &entry, CPQ_IDf);
   1408     } else {
   1409         *qindex = -1;
   1410     }
   1411 
   1412     return SOC_E_NONE;
   1413 }
   1414 
   1415 
   1416 int 
   1417 soc_apache_get_def_qbase(int unit, soc_port_t inport, int qtype, 
   1418                        int *pbase, int *pnumq)
   1419 {
   1420     soc_info_t *si;
   1421     int base, numq;
   1422 
   1423     si = &SOC_INFO(unit);
   1424 
   1425     if (qtype == _SOC_TD2_INDEX_STYLE_UCAST_QUEUE) {
   1426         base = si->port_uc_cosq_base[inport];
   1427         numq = si->port_num_uc_cosq[inport];
   1428     } else if (qtype == _SOC_TD2_INDEX_STYLE_MCAST_QUEUE) {
   1429         base = si->port_cosq_base[inport];
   1430         numq = si->port_num_cosq[inport];
   1431     } else {
   1432         return SOC_E_INTERNAL;
   1433     }
   1434 
   1435     if (pbase) {
   1436         *pbase = base;
   1437     }
   1438     if (pnumq) {
   1439         *pnumq = numq;
   1440     }
   1441     return SOC_E_NONE;
   1442 }
   1443 
   1444 STATIC int
   1445 _soc_apache_dump_hsp_sched_at(int unit, int port, int level, int offset, int index)
   1446 {
   1447     uint32     rval = 0;
   1448     uint32     conn_map;
   1449     uint32     l0_index, l1_index;
   1450     uint32     mc_group_mode = 0;
   1451     char       *lvl_name[] = { "Root","S1","L0", "L1", "UC", "MC" };
   1452     char       *sched_modes[] = {"X", "SP", "WRR", "WERR"};
   1453     uint32     num_spri =0;
   1454     uint32     first_child =0;
   1455     uint32     first_mc_child =0;
   1456     uint32     ucmap =0;
   1457     uint32     sched_mode =0;
   1458     int        uc_cosq, mc_cosq;
   1459     int        uc_cosq_base, mc_cosq_base;
   1460     int        uc_hw_index, mc_hw_index;
   1461     int        hw_index;
   1462     int        wt =0;
   1463     int mmu_port;
   1464 
   1465 
   1466     SOC_IF_ERROR_RETURN(soc_apache_sched_hw_index_get(unit,
   1467                 port, SOC_APACHE_NODE_LVL_L1, 0, &uc_cosq_base));
   1468     mc_cosq_base = uc_cosq_base;
   1469 
   1470     uc_cosq = soc_apache_logical_qnum_hw_qnum(unit, port, uc_cosq_base, 1);
   1471     mc_cosq = soc_apache_logical_qnum_hw_qnum(unit, port, mc_cosq_base, 0);
   1472 
   1473     if (level != SOC_APACHE_NODE_LVL_ROOT) {
   1474         return SOC_E_PARAM;
   1475     }
   1476 
   1477     soc_apache_port_common_attributes_get(unit, port, NULL, &mmu_port, NULL);
   1478     /* Root Node */
   1479     LOG_CLI((BSL_META_U(unit,
   1480                         "  %s.%d : INDEX=%d NUM_SPRI=%d FC=%d MODE=%s Wt=%d\n"),
   1481                         lvl_name[level], offset, index, num_spri, first_child,
   1482                         sched_modes[sched_mode], wt));
   1483 
   1484     SOC_IF_ERROR_RETURN(READ_HSP_SCHED_PORT_CONFIGr(unit, port, &rval));
   1485     mc_group_mode = soc_reg_field_get(unit, HSP_SCHED_PORT_CONFIGr,
   1486                                       rval, MC_GROUP_MODEf);
   1487     /* L0 Node */
   1488     for (l0_index = 0; l0_index < 5; l0_index++) {
   1489         /* print the L0 Nodes*/
   1490         level = SOC_APACHE_NODE_LVL_L0;
   1491         SOC_IF_ERROR_RETURN(soc_apache_sched_hw_index_get(unit,
   1492                          port, level, l0_index, &hw_index));
   1493         soc_apache_cosq_get_sched_mode(unit, port, SOC_APACHE_NODE_LVL_L0,
   1494                                      hw_index, &sched_mode, &wt);
   1495         LOG_CLI((BSL_META_U(unit,
   1496                             "  %s.%d : INDEX=%d NUM_SPRI=%d FC=%d MODE=%s Wt=%d\n"),
   1497                             lvl_name[level], l0_index, hw_index, num_spri, first_child,
   1498                             sched_modes[sched_mode], wt));
   1499 
   1500         /* read Connection map for the  L0.1, L0.2, L0.3, L0.4, L0.5
   1501          * by default connection map should be set to all zeros for L0.0
   1502          */
   1503 
   1504         SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr(
   1505                                  unit, port, l0_index, &rval));
   1506         conn_map = soc_reg_field_get(unit,
   1507                             HSP_SCHED_L0_NODE_CONNECTION_CONFIGr,
   1508                             rval, CHILDREN_CONNECTION_MAPf);
   1509         if ((l0_index >= 1) && (l0_index <= 4)) {
   1510             for (l1_index = 0; l1_index < 8; l1_index++) {
   1511                 if (conn_map & (1U<<l1_index)) {
   1512                     if (l0_index == 4) {
   1513                         offset = l1_index + 2;
   1514                     } else {
   1515                         offset = l1_index;
   1516                     }
   1517                     /* print L1 node */
   1518                     level = SOC_APACHE_NODE_LVL_L1;
   1519                     SOC_IF_ERROR_RETURN(soc_apache_sched_hw_index_get(unit,
   1520                         port, level, offset, &hw_index));
   1521                     soc_apache_cosq_get_sched_mode(unit, port, SOC_APACHE_NODE_LVL_L1,
   1522                                                 hw_index, &sched_mode, &wt);
   1523                     LOG_CLI((BSL_META_U(unit,
   1524                                         "  %s.%d : INDEX=%d NUM_SP=%d FC=%d "
   1525                                         "FMC=%d UCMAP=0x%08x MODE=%s WT=%d\n"),
   1526                                         lvl_name[level], offset, hw_index, num_spri,
   1527                                         first_child, first_mc_child, ucmap,
   1528                                         sched_modes[sched_mode], wt));
   1529 
   1530                     /* print L2 UC node attached to L1 */
   1531                     uc_hw_index = soc_apache_l2_hw_index(unit, uc_cosq_base, 1);
   1532                     soc_apache_cosq_get_sched_mode(unit, port,
   1533                                                     SOC_APACHE_NODE_LVL_L2,
   1534                                                     uc_hw_index, &sched_mode, &wt);
   1535                     LOG_CLI((BSL_META_U(unit,
   1536                                         "    L2.uc : INDEX=%d Mode=%s WEIGHT=%d\n"),
   1537                                         uc_cosq, sched_modes[sched_mode], wt));
   1538                     uc_cosq_base++;
   1539                     uc_cosq++;
   1540 
   1541                     if (((mc_group_mode == 1) && (l0_index == 4)) ||
   1542                          (mc_group_mode == 0)) {
   1543                         /* print L2 MC node attached to L1 */
   1544                         /* MC_GROUP_MODE = 1 then  8 MC Cos queues are
   1545                          * grouped together and shared the parent (L0.0) bandwidth.
   1546                          * MC_QM and MC_SC queues are still paired with
   1547                          * UC_QM and UC_SC respectivly
   1548                          */
   1549                         mc_hw_index = soc_apache_l2_hw_index(unit, mc_cosq_base, 0);
   1550                         soc_apache_cosq_get_sched_mode(unit, port,
   1551                                                     SOC_APACHE_NODE_LVL_L2,
   1552                                                     mc_hw_index, &sched_mode, &wt);
   1553                         LOG_CLI((BSL_META_U(unit,
   1554                                             "    L2.mc : INDEX=%d Mode=%s WEIGHT=%d\n"),
   1555                                             mc_cosq, sched_modes[sched_mode], wt));
   1556                         mc_cosq_base++;
   1557                         mc_cosq++;
   1558                     }
   1559                 }
   1560             }
   1561         } else if (l0_index == 0) {
   1562             if (mc_group_mode) {
   1563                 for (l1_index = 0; l1_index < 8; l1_index++) {
   1564                     /* 8 MC Cos queues are grouped together and shared
   1565                      * the parent (L0.0) bandwidth.
   1566                      */
   1567                     mc_hw_index = soc_apache_l2_hw_index(unit, mc_cosq_base, 0);
   1568                     soc_apache_cosq_get_sched_mode(unit, port,
   1569                                                     SOC_APACHE_NODE_LVL_L2,
   1570                                                     mc_hw_index, &sched_mode, &wt);
   1571                     LOG_CLI((BSL_META_U(unit,
   1572                                         "    L2.mc : INDEX=%d Mode=%s WEIGHT=%d\n"),
   1573                                         mc_cosq, sched_modes[sched_mode], wt));
   1574                     mc_cosq_base++;
   1575                     mc_cosq++;
   1576                 }
   1577 
   1578             }
   1579         }
   1580     }
   1581 
   1582    return SOC_E_NONE;
   1583 }
   1584 
   1585 STATIC int
   1586 _soc_apache_child_num_get(int unit, int port, int level, int hw_index, int *count)
   1587 {
   1588     soc_mem_t mem;
   1589     int cindex, index_max, ii, child_level, num_child = 0;
   1590     uint32 entry[SOC_MAX_MEM_WORDS];
   1591 
   1592     soc_apache_get_child_type(unit, port, level, &child_level);
   1593     mem = _SOC_APACHE_NODE_PARENT_MEM(unit, port, child_level);
   1594 
   1595     if (mem == INVALIDm) {
   1596         return SOC_E_INTERNAL;
   1597     }
   1598     index_max = soc_mem_index_max(unit, mem);
   1599 
   1600     for (ii = 0; ii <= index_max; ii++) {
   1601         SOC_IF_ERROR_RETURN(
   1602                 soc_mem_read(unit, mem, MEM_BLOCK_ALL, ii, &entry));
   1603 
   1604         cindex = soc_mem_field32_get(unit, mem, entry, C_PARENTf);
   1605 
   1606         if (cindex == hw_index) {
   1607             num_child += 1;
   1608         }
   1609     }
   1610 
   1611     if (count != NULL) {
   1612         *count = num_child;
   1613     }
   1614 
   1615     return SOC_E_NONE;
   1616 }
   1617 
   1618 
   1619 STATIC int 
   1620 _soc_apache_dump_sched_at(int unit, int port, int level, int offset, int hw_index)
   1621 {
   1622     int num_spri = 0, first_child = 0, first_mc_child, rv, cindex;
   1623     uint32 ucmap, spmap;
   1624     soc_apache_sched_mode_e sched_mode;
   1625     soc_mem_t mem;
   1626     int index_max, ii, ci, child_level, wt = 0, num_child;
   1627     uint32 entry[SOC_MAX_MEM_WORDS];
   1628     char *lvl_name[] = { "Root", "S1",  "L0", "L1", "L2" };
   1629     char *sched_modes[] = {"X", "SP", "WRR", "WDRR"};
   1630     int num_s1_children = 0;
   1631 
   1632     if (level < SOC_APACHE_NODE_LVL_L2) {
   1633         soc_apache_get_child_type(unit, port, level, &child_level);
   1634         if (hw_index == INVALID_PARENT(unit, child_level)) {
   1635             /* 
   1636              * INVALID_PARENT(L0) may be zero. 
   1637              * When this condition occurs, 
   1638              * we need to do further check instead of returning.
   1639              */
   1640             if (!((child_level == SOC_APACHE_NODE_LVL_S1) &&
   1641                 (hw_index == 0))) {
   1642                 return SOC_E_NONE;
   1643             }
   1644         }
   1645     }
   1646 
   1647     if (level != SOC_APACHE_NODE_LVL_ROOT) { 
   1648         /* get sched config */
   1649         SOC_IF_ERROR_RETURN(
   1650                 soc_apache_cosq_get_sched_child_config(unit, port, level, hw_index, 
   1651                     &num_spri, &first_child, &first_mc_child, &ucmap, &spmap));
   1652     } 
   1653 
   1654     sched_mode = 0;
   1655     if (level != SOC_APACHE_NODE_LVL_ROOT) { 
   1656         SOC_IF_ERROR_RETURN(
   1657           soc_apache_cosq_get_sched_mode(unit, port, level, hw_index, &sched_mode, &wt));
   1658     }
   1659     
   1660     if (level == SOC_APACHE_NODE_LVL_L1) {
   1661         LOG_CLI((BSL_META_U(unit,
   1662                             "  %s.%d : INDEX=%d NUM_SP=%d FC=%d "
   1663                             "FMC=%d UCMAP=0x%08x MODE=%s WT=%d\n"),
   1664                             lvl_name[level], offset, hw_index, num_spri, 
   1665                             first_child, first_mc_child, ucmap, 
   1666                             sched_modes[sched_mode], wt));
   1667     } else {
   1668         if (soc_feature(unit, soc_feature_mmu_hqos_four_level))
   1669         {
   1670             LOG_CLI((BSL_META_U(unit,
   1671                                 "  %s.%d : INDEX=%d NUM_SPRI=%d FC=%d MODE=%s Wt=%d\n"),
   1672                                 lvl_name[level], offset, hw_index, num_spri, first_child,
   1673                                 sched_modes[sched_mode],
   1674                                 wt));
   1675         } else 
   1676         {    
   1677             if (level != SOC_APACHE_NODE_LVL_ROOT)  
   1678             {
   1679                 if (level == SOC_APACHE_NODE_LVL_S1) { 
   1680                     LOG_CLI((BSL_META_U(unit,
   1681                                      "  %s.%d : INDEX=%d NUM_SPRI=%d FC=%d MODE=%s Wt=%d\n"),
   1682                                      lvl_name[level-1 ], offset, hw_index, num_spri, first_child,
   1683                                      sched_modes[sched_mode],
   1684                                      wt));
   1685                 }
   1686                 else 
   1687                 {
   1688                     LOG_CLI((BSL_META_U(unit,
   1689                                      "  %s.%d : INDEX=%d NUM_SPRI=%d FC=%d MODE=%s Wt=%d\n"),
   1690                                      lvl_name[level], offset, hw_index, num_spri, first_child,
   1691                                      sched_modes[sched_mode],
   1692                                      wt));
   1693 
   1694                }
   1695             }             
   1696         }
   1697     }
   1698 
   1699     soc_apache_get_child_type(unit, port, level, &child_level);
   1700     mem = _SOC_APACHE_NODE_PARENT_MEM(unit, port, child_level);
   1701     
   1702     if(mem == INVALIDm) {
   1703         return SOC_E_INTERNAL;
   1704     }
   1705     index_max = soc_mem_index_max(unit, mem);
   1706 
   1707     num_child = 0;
   1708     for (ii = 0, ci = 0; ii <= index_max; ii++) {
   1709         rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, ii, &entry);
   1710         if (rv) {
   1711             LOG_CLI((BSL_META_U(unit,
   1712                                 "Failed to read memory at index: %d\n"), ii));
   1713             break;
   1714         }
   1715         
   1716         cindex = soc_mem_field32_get(unit, mem, entry,
   1717                 child_level == SOC_APACHE_NODE_LVL_S1 ? P_PORTf : 
   1718                 C_PARENTf);
   1719 
   1720         /*
   1721          * INVALID_PARENT(L0) may be zero.
   1722          * When this condition occurs,
   1723          * we should get the node`s child count to decide
   1724          * if it is a valid node or not.
   1725          */
   1726         if ((cindex == 0) && (child_level == SOC_APACHE_NODE_LVL_S1)) {
   1727             _soc_apache_child_num_get(unit, port, child_level,
   1728                                         ii, &num_s1_children);
   1729             if (num_s1_children == 0) {
   1730                 continue;
   1731             }
   1732         }
   1733 
   1734         if (cindex == hw_index) {
   1735             if (child_level == SOC_APACHE_NODE_LVL_L2) {
   1736                 SOC_IF_ERROR_RETURN(soc_apache_cosq_get_sched_mode(unit, port,
   1737                                     SOC_APACHE_NODE_LVL_L2, ii, &sched_mode, &wt));
   1738                 LOG_CLI((BSL_META_U(unit,
   1739                                     "     L2.%s INDEX=%d Mode=%s WEIGHT=%d\n"), 
   1740                                     ((ii < 16384) ? "uc" : "mc"),
   1741                                     ii, sched_modes[sched_mode], wt));
   1742             } else {
   1743                 _soc_apache_dump_sched_at(unit, port, child_level, ci, ii);
   1744                 ci += 1;
   1745             }
   1746             num_child += 1;
   1747         }
   1748     }
   1749     if (num_child == 0) {
   1750         LOG_CLI((BSL_META_U(unit,
   1751                             "*** No children \n")));
   1752     }
   1753     return SOC_E_NONE;
   1754 }
   1755 
   1756 int soc_apache_dump_port_lls(int unit, int port)
   1757 {
   1758     int mmu_port, index;
   1759 
   1760     if (_soc_apache_port_sched_type_get(unit, port) == SOC_APACHE_SCHED_HSP) {
   1761         return SOC_E_NONE;
   1762     }
   1763 
   1764     soc_apache_port_common_attributes_get(unit, port, NULL, &mmu_port, NULL);
   1765 
   1766     LOG_CLI((BSL_META_U(unit,
   1767                         "-------%s (LLS)------\n"), SOC_PORT_NAME(unit, (port))));
   1768     index = _soc_apache_root_scheduler_index(unit, port);
   1769     _soc_apache_dump_sched_at(unit, port, SOC_APACHE_NODE_LVL_ROOT, 0, index);
   1770     return SOC_E_NONE;
   1771 }
   1772 int soc_apache_dump_port_hsp(int unit, int port)
   1773 {
   1774     int mmu_port, index;
   1775 
   1776     if (_soc_apache_port_sched_type_get(unit, port) == SOC_APACHE_SCHED_LLS) {
   1777         return SOC_E_NONE;
   1778     }
   1779 
   1780     soc_apache_port_common_attributes_get(unit, port, NULL, &mmu_port, NULL);
   1781 
   1782     LOG_CLI((BSL_META_U(unit,
   1783                         "-------%s (HSP)------\n"), SOC_PORT_NAME(unit, (port))));
   1784     index = _soc_apache_root_scheduler_index(unit, port);
   1785     _soc_apache_dump_hsp_sched_at(unit, port, SOC_APACHE_NODE_LVL_ROOT, 0, index);
   1786     return SOC_E_NONE;
   1787 }
   1788 
   1789 int soc_apache_logical_qnum_hw_qnum(int unit, int port, int lqnum, int uc)
   1790 {
   1791     if (uc) {
   1792         return lqnum;
   1793     } else {
   1794         return lqnum + 16384;
   1795     }
   1796     return -1;
   1797 }
   1798 
   1799 int soc_apache_mmu_get_shared_size(int unit, int *shared_size)
   1800 {
   1801     uint32 entry0[SOC_MAX_MEM_WORDS];
   1802 
   1803     sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t));
   1804     SOC_IF_ERROR_RETURN
   1805         (soc_mem_read(unit, MMU_THDU_XPIPE_CONFIG_QUEUEm, MEM_BLOCK_ALL, 0, entry0));
   1806     *shared_size = soc_mem_field32_get(unit, MMU_THDU_XPIPE_CONFIG_QUEUEm, entry0, Q_SHARED_LIMIT_CELLf);
   1807     return 1;
   1808 }
   1809 
   1810 int soc_apache_mmu_config_res_limits_update(int unit, uint32 spid, 
   1811                                                       uint32 shared_size, int flags)
   1812 {
   1813     return soc_apache_mmu_config_shared_buf_recalc(unit, spid, shared_size, flags);
   1814 }
   1815 
   1816 void
   1817 soc_apache_fc_map_shadow_free(int unit)
   1818 {
   1819     int mem_idx;
   1820     soc_apache_fc_map_shadow_memory_t * shadow_info;
   1821     soc_apache_fc_map_shadow_t* shadow_ctrl = &soc_apache_fc_map_shadow[unit];
   1822     
   1823     if (shadow_ctrl->shadow_array != NULL) {
   1824         for (mem_idx = 0; mem_idx < shadow_ctrl->mem_count; mem_idx++){
   1825             shadow_info = &(shadow_ctrl->shadow_array[mem_idx]);
   1826             if (shadow_info->mem_shadow != NULL){
   1827                 sal_free(shadow_info->mem_shadow);
   1828             }
   1829         }
   1830     sal_free(shadow_ctrl->shadow_array);
   1831     shadow_ctrl->shadow_array = NULL;
   1832     shadow_ctrl->mem_count = 0;
   1833     }
   1834 }
   1835 
   1836 int
   1837 soc_apache_fc_map_shadow_create(int unit)
   1838 {
   1839 	  int mem_idx, alloc_size, num_entries, entry_size;
   1840 	  soc_apache_fc_map_shadow_memory_t* shadow_info = NULL;
   1841 	  uint32* shadow = NULL;
   1842     
   1843     if (soc_apache_fc_map_shadow[unit].shadow_array == NULL) {
   1844         alloc_size = sizeof(soc_apache_fc_map_shadow_memory_t) * 
   1845                      COUNTOF(fc_map_mems);
   1846         shadow_info = sal_alloc(alloc_size, "fc map shadow control");
   1847         if (shadow_info == NULL) {
   1848             return SOC_E_MEMORY;
   1849         }
   1850         
   1851         sal_memset(shadow_info, 0, alloc_size);
   1852         soc_apache_fc_map_shadow[unit].shadow_array = shadow_info;
   1853     
   1854         for (mem_idx = 0; mem_idx < COUNTOF(fc_map_mems); mem_idx++) {
   1855             num_entries = soc_mem_index_count(unit, fc_map_mems[mem_idx]);
   1856             entry_size = soc_mem_entry_words(unit, fc_map_mems[mem_idx]);
   1857             alloc_size = entry_size * num_entries * sizeof(uint32);
   1858             shadow = sal_alloc(alloc_size, "fc map shadow tbl");
   1859             if (shadow == NULL) {
   1860                 soc_apache_fc_map_shadow_free(unit);
   1861                 return SOC_E_MEMORY;
   1862             }
   1863             sal_memset(shadow, 0, alloc_size);
   1864             soc_apache_fc_map_shadow[unit].shadow_array[mem_idx].mem_shadow = shadow;
   1865             soc_apache_fc_map_shadow[unit].shadow_array[mem_idx].mem = fc_map_mems[mem_idx];
   1866             soc_apache_fc_map_shadow[unit].mem_count++;
   1867         }
   1868     }
   1869     return SOC_E_NONE; 
   1870 }
   1871 
   1872 int
   1873 soc_apache_fc_map_shadow_entry_get (int unit, soc_mem_t mem, int index, 
   1874                                       void* entry_data)
   1875 {
   1876     int mem_idx, entry_words;
   1877     uint32 * shadow = NULL;
   1878     
   1879     switch(mem){
   1880         case MMU_INTFI_XPIPE_FC_MAP_TBL0m:
   1881             mem_idx = 0;
   1882             break;
   1883         case MMU_INTFI_XPIPE_FC_MAP_TBL1m:
   1884             mem_idx = 1;
   1885             break;
   1886         default:
   1887             return SOC_E_NOT_FOUND;
   1888         
   1889     }
   1890     
   1891     shadow = soc_apache_fc_map_shadow[unit].shadow_array[mem_idx].mem_shadow;
   1892     entry_words = soc_mem_entry_words(unit, mem);
   1893     sal_memcpy(entry_data, shadow + index * entry_words, 
   1894                entry_words * sizeof(uint32));
   1895     return SOC_E_NONE;
   1896 }
   1897 
   1898 int
   1899 soc_apache_fc_map_shadow_entry_set (int unit, soc_mem_t mem, int index, 
   1900                                       void* entry_data)
   1901 {
   1902     int mem_idx, entry_words;
   1903     uint32 * shadow = NULL;
   1904     
   1905     switch(mem){
   1906         case MMU_INTFI_XPIPE_FC_MAP_TBL0m:
   1907             mem_idx = 0;
   1908             break;
   1909         case MMU_INTFI_XPIPE_FC_MAP_TBL1m:
   1910             mem_idx = 1;
   1911             break;
   1912         default:
   1913             return SOC_E_NOT_FOUND;
   1914         
   1915     }
   1916     shadow = soc_apache_fc_map_shadow[unit].shadow_array[mem_idx].mem_shadow;
   1917     entry_words = soc_mem_entry_words(unit, mem);
   1918     sal_memcpy(shadow + index * entry_words, entry_data, 
   1919                entry_words * sizeof(uint32));
   1920     return SOC_E_NONE;
   1921 }
   1922 
   1923 int 
   1924 soc_apache_fc_map_shadow_clear (int unit, soc_mem_t mem)
   1925 {
   1926     uint32 * shadow = NULL;
   1927     int entry_words, tbl_size, mem_idx, num_entries;
   1928     switch(mem){
   1929         case MMU_INTFI_XPIPE_FC_MAP_TBL0m:
   1930             mem_idx = 0;
   1931             break;
   1932         case MMU_INTFI_XPIPE_FC_MAP_TBL1m:
   1933             mem_idx = 1;
   1934             break;
   1935         default:
   1936             return SOC_E_NOT_FOUND;
   1937     }
   1938     entry_words = soc_mem_entry_words(unit, mem);
   1939     shadow = soc_apache_fc_map_shadow[unit].shadow_array[mem_idx].mem_shadow;
   1940     num_entries = soc_mem_index_count(unit, fc_map_mems[mem_idx]);
   1941     tbl_size = entry_words * num_entries;
   1942     if (shadow != NULL) {
   1943         sal_memset(shadow, 0, tbl_size * sizeof(uint32));
   1944     }
   1945     return SOC_E_NONE;
   1946 }
   1947 #ifdef BCM_WARM_BOOT_SUPPORT
   1948 int
   1949 soc_apache_fc_map_shadow_size_get (int unit, uint32 * size)
   1950 {
   1951     int alloc_size = 0, mem_idx, num_entries, entry_size;
   1952     for (mem_idx = 0; mem_idx < COUNTOF(fc_map_mems); mem_idx++) {
   1953         num_entries = soc_mem_index_count(unit, fc_map_mems[mem_idx]);
   1954         entry_size = soc_mem_entry_words(unit, fc_map_mems[mem_idx]);
   1955         alloc_size += entry_size * num_entries * sizeof(uint32);
   1956     }
   1957     *size = alloc_size;
   1958     return SOC_E_NONE;
   1959 }
   1960 
   1961 int
   1962 soc_apache_fc_map_shadow_sync (int unit, uint32 **sync_addr)
   1963 {
   1964     int mem_idx, num_entries, tbl_size, entry_size;
   1965 
   1966     for (mem_idx = 0; mem_idx < COUNTOF(fc_map_mems); mem_idx++) {
   1967         num_entries = soc_mem_index_count(unit, fc_map_mems[mem_idx]);
   1968         entry_size = soc_mem_entry_words(unit, fc_map_mems[mem_idx]);
   1969         tbl_size = entry_size * num_entries;
   1970         sal_memcpy(*sync_addr, soc_apache_fc_map_shadow[unit].shadow_array[mem_idx].mem_shadow, 
   1971                    tbl_size * sizeof(uint32));
   1972         *sync_addr += tbl_size;
   1973     }
   1974     return SOC_E_NONE;
   1975 }
   1976 
   1977 int
   1978 soc_apache_fc_map_shadow_load (int unit, uint32 **load_addr)
   1979 {
   1980     int blk, mem_idx, num_entries;
   1981     int tbl_size, entry_size, vmap_size;
   1982     uint32 *cache;
   1983     uint32 *shadow;
   1984     uint8 *vmap;
   1985     int index_min;
   1986     soc_mem_t mem;
   1987     
   1988     for (mem_idx = 0; mem_idx < COUNTOF(fc_map_mems); mem_idx++) {
   1989         mem = fc_map_mems[mem_idx];
   1990         num_entries = soc_mem_index_count(unit, mem);
   1991         entry_size = soc_mem_entry_words(unit, mem);
   1992         index_min = soc_mem_index_min(unit, mem);
   1993         tbl_size = entry_size * num_entries;
   1994         sal_memcpy(soc_apache_fc_map_shadow[unit].shadow_array[mem_idx].mem_shadow, *load_addr,
   1995                    tbl_size * sizeof(uint32));
   1996         *load_addr += tbl_size;
   1997         /* restore memory cache */
   1998         vmap_size = (num_entries + 7) / 8;
   1999         SOC_MEM_BLOCK_ITER(unit, mem, blk) {
   2000             if (SOC_MEM_STATE(unit, mem).cache[blk] == NULL) {
   2001                 continue;
   2002             }
   2003             cache = SOC_MEM_STATE(unit, mem).cache[blk];
   2004             vmap = SOC_MEM_STATE(unit, mem).vmap[blk];
   2005             shadow = soc_apache_fc_map_shadow[unit].shadow_array[mem_idx].mem_shadow;
   2006             sal_memcpy(cache, shadow, tbl_size * sizeof(uint32));
   2007         
   2008             sal_memset(&vmap[index_min / 8], 0xff, 
   2009                       (num_entries + 7 - index_min) / 8);
   2010                 
   2011             /* Clear invalid bits at the left and right ends */
   2012             vmap[index_min / 8] &= 0xff00 >> (8 - index_min % 8);
   2013             vmap[vmap_size - 1] &= 0x00ff >> ((8 - num_entries % 8) % 8);
   2014         }
   2015     }
   2016     return SOC_E_NONE;
   2017 }
   2018 #endif
   2019 
   2020 #undef _ERR_MSG_MODULE_NAME /* debug */
   2021 
   2022 #endif /* BCM_APACHE_SUPPORT */
   2023