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 (774658B)


      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  * COS Queue Management
      8  * Purpose: API to set different cosq, priorities, and scheduler registers.
      9  */
     10 #include <shared/bsl.h>
     11 #include <sal/core/libc.h>
     12 #include <soc/defs.h>
     13 #if defined(BCM_KATANA2_SUPPORT)
     14 #include <soc/drv.h>
     15 #include <soc/scache.h>
     16 #include <soc/katana.h>
     17 #include <soc/katana2.h>
     18 #include <soc/profile_mem.h>
     19 #include <soc/macutil.h>
     20 #ifdef BCM_CMICM_SUPPORT
     21 #include <soc/cmicm.h>
     22 #endif
     23 #include <soc/saber2.h>
     24 #if defined(BCM_METROLITE_SUPPORT)
     25 #include <soc/metrolite.h>
     26 #endif
     27     
     28 #include <bcm/error.h>
     29 #include <bcm/cosq.h>
     30 #include <bcm_int/esw/mbcm.h>
     31 #include <bcm_int/esw/firebolt.h>
     32 #include <bcm_int/esw/katana.h>
     33 #include <bcm_int/esw/katana2.h>
     34 #include <bcm_int/esw/stack.h>
     35 #include <bcm_int/esw/cosq.h>
     36 #include <bcm_int/esw_dispatch.h>
     37 #include <bcm_int/esw/subport.h>
     38 #include <bcm_int/esw/trx.h>
     39 #include <bcm_int/esw/oob.h>
     40 #include <bcm_int/esw/link.h>
     41 #include <bcm/types.h>
     42 
     43 #ifdef BCM_WARM_BOOT_SUPPORT
     44 #include <bcm_int/esw/switch.h>
     45 #endif /* BCM_WARM_BOOT_SUPPORT */
     46 
     47 #if defined(BCM_KATANA2_SUPPORT)
     48 #include <soc/katana2.h>
     49 #include <bcm_int/esw/multicast.h>
     50 #endif
     51 
     52 #define KT2_CELL_FIELD_MAX      (SOC_IS_SABER2(unit) ? \
     53                                 0xffff : 0x3ffff)
     54 
     55 /* MMU cell size in bytes */
     56 #define _BCM_KT2_COSQ_CELLSIZE   192
     57 #define _BCM_KT2_COSQ_EXT_CELLSIZE  (SOC_IS_SABER2(unit) ? \
     58         _BCM_KT2_COSQ_EXT_PACKING_CELLSIZE :_BCM_KT2_COSQ_CELLSIZE * 4)
     59 #define _BCM_KT2_COSQ_EXT_PACKING_CELLSIZE  _BCM_KT2_COSQ_CELLSIZE * 15 
     60 #define _BCM_KT2_MAX_PRIORITY_GROUPS 8
     61 
     62 #define _BCM_KT2_NUM_UCAST_QUEUE_GROUP            8
     63 #define _BCM_KT2_NUM_VLAN_UCAST_QUEUE_GROUP       16
     64 #define  _BCM_KT2_NUM_INTERNAL_PRI                16 
     65 #define  _BCM_KT2_NUM_PFC_CLASS                   8  
     66 #define _BCM_KT2_NUM_SAFC_CLASS                   16
     67 #define _SOC_KT2_COSQ_MAX_INDEX_S0                128
     68 #define _SOC_KT2_COSQ_MAX_INDEX_S1                256
     69 
     70 #if defined (BCM_SABER2_SUPPORT)
     71 #define _SOC_SB2_COSQ_MAX_INDEX_S0                16
     72 #endif
     73 
     74 #if defined (BCM_METROLITE_SUPPORT)
     75 #define _SOC_ML_COSQ_MAX_INDEX_S0                 24
     76 #endif
     77 
     78 extern kt2_port_to_mxqblock_subports_t *kt2_port_to_mxqblock_subports[SOC_MAX_NUM_DEVICES];
     79 
     80 #define _BCM_KT2_COSQ_LIST_NODE_INIT(list, node)        \
     81     list[node].in_use            = FALSE;               \
     82     list[node].wrr_in_use        = 0;                   \
     83     list[node].wrr_mode          = 0;                   \
     84     list[node].gport             = -1;                  \
     85     list[node].base_index        = -1;                  \
     86     list[node].mc_base_index     = -1;                  \
     87     list[node].numq              = 0;                   \
     88     list[node].hw_index          = -1;                  \
     89     list[node].level             = -1;                  \
     90     list[node].cosq_attached_to  = -1;                  \
     91     list[node].num_child         = 0;                   \
     92     list[node].first_child       = 4095;                \
     93     list[node].linkphy_enabled   = 0;                   \
     94     list[node].subport_enabled   = 0;                   \
     95     list[node].cosq_map          = NULL;                \
     96     list[node].parent            = NULL;                \
     97     list[node].sibling           = NULL;                \
     98     list[node].child             = NULL;                \
     99     list[node].local_port        = -1;                  \
    100     list[node].wred_disabled     = 0;                   \
    101     list[node].burst_calculation_enable     = 0;        \
    102     BCM_PBMP_CLEAR(list[node].fabric_pbmp);              \
    103     list[node].remote_modid      = -1;                  \
    104     list[node].fabric_modid      = -1;                  \
    105     list[node].remote_port      = -1;
    106 
    107 #define _BCM_KT2_COSQ_NODE_INIT(node)                   \
    108     node->in_use            = FALSE;                    \
    109     node->wrr_in_use        = 0;                        \
    110     node->wrr_mode          = 0;                        \
    111     node->gport             = -1;                       \
    112     node->base_index        = -1;                       \
    113     node->mc_base_index     = -1;                       \
    114     node->numq              = 0;                        \
    115     node->hw_index          = -1;                       \
    116     node->level             = -1;                       \
    117     node->cosq_attached_to  = -1;                       \
    118     node->num_child         = 0;                        \
    119     node->first_child       = 4095;                     \
    120     node->linkphy_enabled   = 0;                        \
    121     node->subport_enabled   = 0;                        \
    122     node->wred_disabled     = 0;                        \
    123     node->burst_calculation_enable = 0;                 \
    124     node->cosq_map          = NULL;                     \
    125     node->parent            = NULL;                     \
    126     node->sibling           = NULL;                     \
    127     node->child             = NULL;                     \
    128     BCM_PBMP_CLEAR(node->fabric_pbmp);                  \
    129     node->remote_modid      = -1;                       \
    130     node->fabric_modid      = -1;                       \
    131     node->remote_port       = -1;
    132  
    133 #define _BCM_KT2_LLS_DYN_CHG_REG_B 0x3FF
    134 #define _BCM_SB2_LLS_DYN_CHG_REG_B 0x3F
    135 #define _BCM_ML_LLS_DYN_CHG_REG_B  0xF
    136 #define _BCM_KT2_LLS_DYN_CHG_REG_C 0xFFFFFFFF
    137 
    138 #define _BCM_KT2_LB_BASE_QUEUE     0x40
    139 
    140 typedef enum {
    141     _BCM_KT2_COSQ_FC_PAUSE = 0,
    142     _BCM_KT2_COSQ_FC_PFC,
    143     _BCM_KT2_COSQ_FC_VOQFC,
    144     _BCM_KT2_COSQ_FC_E2ECC,
    145     _BCM_KT2_COSQ_FC_E2ECC_COE,
    146     _BCM_KT2_COSQ_FC_SAFC
    147 } _bcm_kt2_fc_type_t;
    148 
    149 typedef enum {
    150     _BCM_KT2_COSQ_DMVOQ = 0,
    151     _BCM_KT2_COSQ_DPVOQ,
    152     _BCM_KT2_COSQ_E2ECC_COE
    153 } _bcm_kt2_voq_type_t;
    154 
    155 
    156 typedef enum {
    157     _BCM_KT2_COSQ_STATE_NO_CHANGE,
    158     _BCM_KT2_COSQ_STATE_DISABLE,
    159     _BCM_KT2_COSQ_STATE_ENABLE,
    160     _BCM_KT2_COSQ_STATE_SPRI_TO_WRR,
    161     _BCM_KT2_COSQ_STATE_WRR_TO_SPRI,
    162     _BCM_KT2_COSQ_STATE_MAX
    163 }_bcm_kt2_cosq_state_t;
    164 
    165 typedef struct _bcm_kt2_cosq_list_s {
    166     int count;
    167     SHR_BITDCL *bits;
    168 }_bcm_kt2_cosq_list_t;
    169 
    170 typedef struct _bcm_kt2_cosq_port_info {
    171     int q_offset;
    172     int q_limit;
    173     int mcq_offset;
    174     int mcq_limit;
    175     int uc_vlan_base;
    176 }_bcm_kt2_cosq_port_info_t;
    177 
    178 typedef struct _bcm_kt2_mmu_info_s {
    179     int num_base_queues;   /* Number of classical queues */
    180     int num_ext_queues;    /* Number of extended queues */
    181     int qset_size;         /* subscriber queue set size */
    182     int num_dmvoq_queues;  /* Number of dmvoq queues */
    183     int base_dmvoq_queue;  /* Base DMVOQ queue */
    184     int num_sub_queues;    /* Number of subscriber queues */
    185     int base_sub_queue;    /* Base subscriber queue */
    186     uint32 num_queues;     /* total number of queues */
    187     uint32 num_nodes;      /* max number of sched nodes */
    188     uint32 max_nodes[_BCM_KT2_COSQ_NODE_LEVEL_MAX];/* max nodes in each level */
    189     bcm_gport_t *l1_gport_pair;        /* L1 gport mapping for dynamic update */
    190     _bcm_kt2_cosq_port_info_t *port;   /* port information */
    191     _bcm_kt2_cosq_list_t global_qlist;    /* list of extended queues */
    192     _bcm_kt2_cosq_list_t l2_global_qlist;    /* list of extended queues */
    193     _bcm_kt2_cosq_list_t dmvoq_qlist;    /* list of dmvoq queues */
    194     _bcm_kt2_cosq_list_t sched_list;   /* list of sched nodes */
    195     _bcm_kt2_cosq_list_t sub_qlist;    /* list of subscriber queues */
    196     _bcm_kt2_cosq_list_t sub_mcqlist;  /* list of multicast subscriber queues */
    197     _bcm_kt2_cosq_list_t sched_hw_list[_BCM_KT2_COSQ_NODE_LEVEL_MAX]; 
    198                                        /* list of sched hw list */
    199     _bcm_kt2_cosq_list_t l2_base_qlist;  
    200                            /* list of l2  base uc queue index list */
    201     _bcm_kt2_cosq_list_t l2_base_mcqlist;  
    202                            /* list of l2  base mc queue index list */ 
    203     _bcm_kt2_cosq_list_t l2_dmvoq_qlist;   
    204                            /* list of l2  dmvoq queue index list */
    205     _bcm_kt2_cosq_list_t l2_sub_qlist;
    206                            /* list of l2  subscriber queue index list */
    207     _bcm_kt2_cosq_list_t l2_sub_mcqlist;
    208                            /* list of l2 multicast subscriber queue index list */
    209     _bcm_kt2_cosq_node_t *sched_node;
    210                                          /* sched nodes */
    211     _bcm_kt2_cosq_node_t *queue_node;
    212                                          /* queue nodes */
    213     int     curr_merger_index[4];    
    214     uint32  intf_ref_cnt[BCM_MULTICAST_PORT_MAX]; /* Interface reference count
    215                                                      for queues */
    216 }_bcm_kt2_mmu_info_t;
    217 
    218 
    219 typedef struct  _pfc_port_support_s { 
    220     int                   supported;
    221     /* if PFC is supported for given port will be true*/
    222     int                   mmu_port; 
    223     int                   index1;/*index in to PFC_ST_TBL for given port*/
    224     int                   index2;/*index in to PFC_ST_TBL for given port*/
    225 }_pfc_port_support_t;
    226 _pfc_port_support_t kt2_pfc_support[KT2_MAX_LOGICAL_PORTS] = { 
    227    {0, -1, -1, -1},
    228    {1, 0, 0, 1},
    229    {0, -1, -1, -1},
    230    {0, -1, -1, -1},
    231    {0, -1, -1, -1},
    232    {1, 1, 2, 3},
    233    {0, -1, -1, -1},
    234    {0, -1, -1, -1},
    235    {0, -1, -1, -1},
    236    {1, 2, 4, 5},
    237    {0, -1, -1, -1},
    238    {0, -1, -1, -1},
    239    {0, -1, -1, -1},
    240    {1, 3, 6, 7},
    241    {0, -1, -1, -1},
    242    {0, -1, -1, -1},
    243    {0, -1, -1, -1},
    244    {1, 4, 8, 9},
    245    {0, -1, -1, -1},
    246    {0, -1, -1, -1},
    247    {0, -1, -1, -1},
    248    {1, 5, 10, 11},
    249    {0, -1, -1, -1},
    250    {0, -1, -1, -1},
    251    {0, -1, -1, -1},
    252    {1, 6, 12, 13},
    253    {1, 8, 16, 17},
    254    {1, 10, 20, 21},
    255    {1, 12, 24, 25},
    256    {0, -1, -1, -1},
    257    {1, 13, 26, 27},
    258    {0, -1, -1, -1},
    259    {0, -1, -1, -1},
    260    {1, 11, 22, 23},
    261    {0, -1, -1, -1},
    262    {0, -1, -1, -1},
    263    {1, 7, 14, 15},
    264    {0, -1, -1, -1},
    265    {0, -1, -1, -1},
    266    {1, 9, 18, 19},
    267    {0, -1, -1, -1},
    268    {0, -1, -1, -1}
    269  };
    270 
    271 #ifdef BCM_SABER2_SUPPORT
    272 _pfc_port_support_t sb2_pfc_support[SB2_MAX_LOGICAL_PORTS] =  {
    273    {0, -1, -1, -1},
    274    {1, 0, 0, 1,},
    275    {1, 1, 2, 3},
    276    {1, 2, 4, 5},
    277    {1, 3, 6, 7},
    278    {1, 4, 8, 9},
    279    {1, 5, 10, 11},
    280    {1, 6, 12, 13},
    281    {1, 7, 14, 15},
    282    {1, 8, 16, 17},
    283    {0, -1, -1, -1},
    284    {0, -1, -1, -1},
    285    {0, -1, -1, -1},
    286    {1, 9, 18, 19},
    287    {0, -1, -1, -1},
    288    {0, -1, -1, -1},
    289    {0, -1, -1, -1},
    290    {1, 10, 20, 21},
    291    {0, -1, -1, -1},
    292    {0, -1, -1, -1},
    293    {0, -1, -1, -1},
    294    {1, 11, 22, 23},
    295    {1, 12, 24, 25},
    296    {1, 13, 26, 27},
    297    {1, 14, 28, 29},
    298    {1, 15, 30, 31},
    299    {1, 16, 32, 33},
    300    {1, 17, 34, 35},
    301    {1, 18, 36, 37},
    302    {0, -1, -1, -1}
    303 };
    304 #endif 
    305 #ifdef BCM_METROLITE_SUPPORT
    306 _pfc_port_support_t ml_pfc_support[ML_MAX_LOGICAL_PORTS] =  {
    307    {0, -1, -1, -1},
    308    {1, 0, 0, 1,},
    309    {1, 1, 2, 3},
    310    {1, 2, 4, 5},
    311    {1, 3, 6, 7},
    312    {1, 4, 8, 9},
    313    {1, 5, 10, 11},
    314    {1, 6, 12, 13},
    315    {1, 7, 14, 15},
    316    {1, 8, 16, 17},
    317    {1, 9, 18, 19},
    318    {1, 10,20, 21},
    319    {1, 11,22, 23},
    320    {0, -1, -1, -1}
    321 };
    322 #endif
    323 
    324 STATIC _bcm_kt2_mmu_info_t *_bcm_kt2_mmu_info[BCM_MAX_NUM_UNITS];  
    325 
    326 STATIC soc_profile_mem_t *_bcm_kt2_cos_map_profile[BCM_MAX_NUM_UNITS];
    327 STATIC soc_profile_mem_t *_bcm_kt2_egr_cos_map_profile[BCM_MAX_NUM_UNITS];
    328 STATIC soc_profile_mem_t *_bcm_kt2_wred_profile[BCM_MAX_NUM_UNITS];
    329 STATIC soc_profile_mem_t *_bcm_kt2_ifp_cos_map_profile[BCM_MAX_NUM_UNITS];
    330 STATIC soc_profile_reg_t *_bcm_kt2_llfc_profile[BCM_MAX_NUM_UNITS];
    331 
    332 /* Number of COSQs configured for this device */
    333 STATIC int _bcm_kt2_num_cosq[SOC_MAX_NUM_DEVICES];
    334 
    335 STATIC int num_pp_ports[BCM_MAX_NUM_UNITS];
    336 STATIC int num_port_schedulers[BCM_MAX_NUM_UNITS];
    337 
    338 STATIC int num_s0_schedulers[BCM_MAX_NUM_UNITS];
    339 STATIC int num_s1_schedulers[BCM_MAX_NUM_UNITS];
    340 STATIC int num_l0_schedulers[BCM_MAX_NUM_UNITS];
    341 STATIC int num_l1_schedulers[BCM_MAX_NUM_UNITS];
    342 STATIC int num_total_schedulers[BCM_MAX_NUM_UNITS];
    343 
    344 STATIC int num_l2_queues[BCM_MAX_NUM_UNITS];
    345 STATIC int max_l1_shaper_bucket[BCM_MAX_NUM_UNITS];
    346 STATIC int max_l2_shaper_bucket[BCM_MAX_NUM_UNITS];
    347 STATIC soc_mem_t l2_shaper_memory[BCM_MAX_NUM_UNITS][4];
    348 STATIC uint8 pg_profile_refcount[BCM_MAX_NUM_UNITS][4];
    349 STATIC int soc_max_num_pp_ports[BCM_MAX_NUM_UNITS];
    350 
    351 STATIC int
    352 _bcm_kt2_cosq_packing_mode_get(int unit, int index, int *set);
    353 
    354 STATIC int
    355 _bcm_kt2_subport_cosq_config_set(int unit, int numq);
    356 int
    357 _bcm_kt2_cosq_subport_get(int unit, bcm_gport_t sched_gport,
    358                           int *pp_port);
    359 STATIC int
    360 _bcm_kt2_cosq_cpu_fc_set(int unit); 
    361 
    362 STATIC int
    363 _bcm_kt2_cosq_dynamic_thresh_enable_get(int unit, 
    364                         bcm_gport_t gport, bcm_cos_queue_t cosq, 
    365                         bcm_cosq_control_t type, int *arg);
    366 
    367 STATIC int
    368 _bcm_kt2_cosq_child_node_at_input(_bcm_kt2_cosq_node_t *node, int cosq,
    369                                   _bcm_kt2_cosq_node_t **child_node);
    370 
    371 STATIC int 
    372 _bcm_kt2_init_all_queue_counters(int unit);
    373 
    374 extern sal_mutex_t cosq_sync_lock[SOC_MAX_NUM_DEVICES];
    375 
    376 /* Function:
    377  *    _bcm_kt2_cosq_source_intf_set
    378  * Purpose:
    379  *    Function to set the SRC_INTF table and
    380  *    return the index
    381  * Parameters:
    382  *     unit       - (IN) unit number
    383  *     src_modid  - (IN) source module ID
    384  *     src_port_num - (IN) source port number
    385  * Returns:
    386  *     BCM_E_XXX
    387  */
    388 
    389 STATIC int
    390 _bcm_kt2_cosq_source_intf_set(int unit, bcm_port_t src_modid, 
    391         bcm_port_t src_port_num, _bcm_kt2_voq_type_t type)
    392 {
    393     int index, free_index = -1;
    394     uint32 rval, modid = 0, port_num = 0, valid;
    395 
    396     for (index = 0; index < SOC_REG_NUMELS(unit, SRC_INTFr); index++) {
    397         modid=0;
    398         port_num=0;
    399         BCM_IF_ERROR_RETURN(READ_SRC_INTFr(unit, index, &rval));
    400         valid = soc_reg_field_get(unit, SRC_INTFr, rval, SRC_MODID_VALIDf);
    401         if (1 == valid) {
    402             modid = soc_reg_field_get(unit, SRC_INTFr, rval, SOURCEf);
    403             if (src_modid == modid) {
    404                 return index;
    405             }
    406         } 
    407         valid = soc_reg_field_get(unit, SRC_INTFr, rval, SRC_PORT_NUM_VALIDf);
    408         if (1 == valid) {
    409             port_num = soc_reg_field_get(unit, SRC_INTFr, rval, SOURCEf);
    410             if (src_port_num == port_num) {
    411                 return index;
    412             }
    413         }
    414         if ((port_num == 0) && (modid == 0) &&
    415                 (free_index == -1)) {
    416             free_index = index;
    417         }
    418     }
    419     if (free_index == -1) {
    420         return BCM_E_RESOURCE;
    421     }
    422 
    423     rval = 0;
    424     if ((type == _BCM_KT2_COSQ_DMVOQ) || 
    425             (type == _BCM_KT2_COSQ_DPVOQ)) {
    426         soc_reg_field_set(unit, SRC_INTFr, &rval, SRC_MODID_VALIDf, 1);
    427         soc_reg_field_set(unit, SRC_INTFr, &rval, SOURCEf, src_modid);
    428         if (type != _BCM_KT2_COSQ_DPVOQ) {
    429             if (SOC_IS_SABER2(unit)) {
    430                 if (SOC_IS_METROLITE(unit)) {
    431                     soc_reg_field_set(unit, SRC_INTFr, &rval, IF_IDf, 0);
    432                 } else {
    433                     soc_reg_field_set(unit, SRC_INTFr, &rval, IF_IDf, 
    434                             free_index > 1 ? 0 :free_index);
    435                 }
    436             } else {
    437                 soc_reg_field_set(unit, SRC_INTFr, &rval, IF_IDf, 
    438                         free_index > 3 ? 0 :free_index);
    439             }
    440         }
    441     } else if (type == _BCM_KT2_COSQ_E2ECC_COE) {
    442         soc_reg_field_set(unit, SRC_INTFr, &rval, SRC_PORT_NUM_VALIDf, 1);
    443         soc_reg_field_set(unit, SRC_INTFr, &rval, SOURCEf, src_port_num);
    444     } else {
    445         return BCM_E_PARAM;
    446     }
    447 
    448     BCM_IF_ERROR_RETURN(WRITE_SRC_INTFr(unit, free_index, rval));
    449 
    450     return free_index;
    451 }
    452 
    453 /* Function:
    454  *    _bcm_kt2_cosq_source_intf_profile_get
    455  * Purpose:
    456  *    Function to get the SRC_INTF table and match with SOURCE field
    457  *    return the IF_ID 
    458  * Parameters:
    459  *     unit       - (IN) unit number
    460  *     src_modid  - (IN) source module ID 
    461  *     src_port_num - (IN) source port number
    462  *     type  - (IN) voq type
    463  * Returns:
    464  *     profile_index 
    465  */
    466 
    467 
    468 STATIC int
    469 _bcm_kt2_cosq_source_intf_profile_get(int unit, bcm_port_t src_modid, 
    470         bcm_port_t src_port_num, _bcm_kt2_voq_type_t type)
    471 {
    472     int index = -1;
    473     int profile_id = -1; 
    474     uint32 rval, modid = 0, port_num = 0, valid;
    475 
    476     for (index = 0; index < 16; index++) {
    477         modid=0;
    478         port_num=0;
    479         BCM_IF_ERROR_RETURN(READ_SRC_INTFr(unit, index, &rval));
    480         valid = soc_reg_field_get(unit, SRC_INTFr, rval, SRC_MODID_VALIDf);
    481         if (1 == valid) {
    482             modid = soc_reg_field_get(unit, SRC_INTFr, rval, SOURCEf);
    483             if (src_modid == modid) {
    484                 profile_id = soc_reg_field_get(unit, SRC_INTFr, rval, IF_IDf);
    485                 break;
    486             }
    487         } 
    488         valid = soc_reg_field_get(unit, SRC_INTFr, rval, SRC_PORT_NUM_VALIDf);
    489         if (1 == valid) {
    490             port_num = soc_reg_field_get(unit, SRC_INTFr, rval, SOURCEf);
    491             if (src_port_num == port_num) {
    492             profile_id = soc_reg_field_get(unit, SRC_INTFr, rval, IF_IDf);
    493             break;
    494             }
    495         }
    496     }
    497     return profile_id; 
    498 }
    499 
    500 /*
    501  * Function:
    502  *  _bcm_kt2_cosq_map_fc_status_to_node    
    503  * Purpose:
    504  *     Function will fill the appropriate indexes and SEL
    505  *     in MMU_INTFI_FC_MAP_TBL as per the table requirement
    506  * Parameters:
    507  *     unit      - (IN) unit number
    508  *     fct       - (IN) type is PFC/VOQ 
    509  *     hw_index  - (IN) hw_index of the queue 
    510  *     level     - (IN) Node level L2/L1/L0 
    511  * Returns:
    512  *     BCM_E_XXX
    513  */
    514 
    515 STATIC int
    516 _bcm_kt2_cosq_map_fc_status_to_node(int unit, _bcm_kt2_fc_type_t fct,
    517                               uint32 hw_index, int level, uint32 base_offset )
    518 {
    519     int map_entry_index, eindex, pfc;
    520     uint32 map_entry[SOC_MAX_MEM_WORDS];
    521     static const soc_field_t self[] = {
    522         SEL0f, SEL1f
    523     };
    524     static const soc_field_t indexf[] = {
    525         INDEX0f, INDEX1f
    526     };
    527     static const soc_mem_t mem[] = {
    528         INVALIDm,
    529         MMU_INTFI_FC_MAP_TBL0m,
    530         MMU_INTFI_FC_MAP_TBL1m,
    531         MMU_INTFI_FC_MAP_TBL2m
    532     };
    533     if ((fct == _BCM_KT2_COSQ_FC_PFC) || 
    534                   (fct == _BCM_KT2_COSQ_FC_SAFC)) { 
    535         pfc = 1; 
    536     }else { 
    537         pfc = 0; 
    538     }
    539 
    540     map_entry_index = hw_index / 16;
    541     eindex = (hw_index % 16) / 8;
    542     BCM_IF_ERROR_RETURN
    543         (soc_mem_read(unit, mem[level], MEM_BLOCK_ALL, map_entry_index, &map_entry));
    544     soc_mem_field32_set(unit, mem[level], &map_entry,
    545             indexf[eindex], base_offset);
    546     soc_mem_field32_set(unit, mem[level], &map_entry, self[eindex], pfc);
    547     BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem[level],
    548                 MEM_BLOCK_ALL, map_entry_index, &map_entry));
    549     return BCM_E_NONE;
    550 }
    551 
    552 /*
    553  * Function:
    554  *     _bcm_kt2_cosq_localport_resolve
    555  * Purpose:
    556  *     Resolve GRPOT if it is a local port
    557  * Parameters:
    558  *     unit       - (IN) unit number
    559  *     gport      - (IN) GPORT identifier
    560  *     local_port - (OUT) local port number
    561  * Returns:
    562  *     BCM_E_XXX
    563  */
    564 int
    565 _bcm_kt2_cosq_localport_resolve(int unit, bcm_gport_t gport,
    566                                bcm_port_t *local_port)
    567 {
    568     bcm_module_t module;
    569     bcm_port_t port;
    570     bcm_trunk_t trunk;
    571     int id/*, result*/;
    572 
    573     if (!BCM_GPORT_IS_SET(gport)) {
    574         if (!SOC_PORT_VALID_RANGE(unit, gport)) {
    575             return BCM_E_PORT;
    576         }
    577         *local_port = gport;
    578         return BCM_E_NONE;
    579     } else if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
    580         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
    581         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
    582         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
    583         BCM_GPORT_IS_SCHEDULER(gport)) {
    584         return BCM_E_PORT;
    585     }
    586 
    587     BCM_IF_ERROR_RETURN
    588         (_bcm_esw_gport_resolve(unit, gport, &module, &port, &trunk, &id));
    589 
    590     BCM_IF_ERROR_RETURN
    591         (_bcm_kt2_modport_to_pp_port_get(unit, module, port, &port));
    592 
    593     *local_port = port;
    594 
    595     return BCM_E_NONE;
    596 }
    597 
    598 /*
    599  * Function:
    600  *     _bcm_kt2_cosq_node_get
    601  * Purpose:
    602  *     Get internal information of queue group or scheduler type GPORT
    603  * Parameters:
    604  *     unit       - (IN) unit number
    605  *     gport      - (IN) queue group/scheduler GPORT identifier
    606  *     modid      - (OUT) module identifier
    607  *     port       - (OUT) port number
    608  *     id         - (OUT) queue group or scheduler identifier
    609  *     node       - (OUT) node structure for the specified GPORT
    610  * Returns:
    611  *     BCM_E_XXX
    612  */
    613 STATIC int
    614 _bcm_kt2_cosq_node_get(int unit, bcm_gport_t gport, bcm_module_t *modid,
    615                       bcm_port_t *port, int *id, _bcm_kt2_cosq_node_t **node)
    616 {
    617     _bcm_kt2_mmu_info_t *mmu_info;
    618     _bcm_kt2_cosq_node_t *node_base;
    619     bcm_module_t modid_out = 0;
    620     bcm_port_t port_out = 0;
    621     uint32 encap_id = 0;
    622     int index;
    623 
    624 
    625     if (_bcm_kt2_mmu_info[unit] == NULL) {
    626         return BCM_E_INIT;
    627     }
    628 
    629     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
    630         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid_out));
    631         port_out = BCM_GPORT_UCAST_QUEUE_GROUP_SYSPORTID_GET(gport);
    632     } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
    633         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid_out));
    634         port_out = BCM_GPORT_MCAST_QUEUE_GROUP_SYSPORTID_GET(gport);    
    635     } else if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport)) {
    636         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid_out));
    637         port_out = BCM_GPORT_DESTMOD_QUEUE_GROUP_SYSPORTID_GET(gport);
    638     } else if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
    639         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid_out));
    640         port_out = BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_SYSPORTID_GET(gport);
    641     } else if (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
    642         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid_out));
    643         port_out = BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_SYSPORTID_GET(gport);
    644     } else if (BCM_GPORT_IS_SCHEDULER(gport)) {
    645         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid_out));
    646         port_out = BCM_GPORT_SCHEDULER_GET(gport) & 0xff;
    647     } else if (BCM_GPORT_IS_LOCAL(gport)) {
    648         encap_id = BCM_GPORT_LOCAL_GET(gport);
    649         port_out = encap_id;
    650     } else if (BCM_GPORT_IS_MODPORT(gport)) {
    651         encap_id = BCM_GPORT_MODPORT_PORT_GET(gport);
    652         port_out = encap_id;
    653     } else if (BCM_GPORT_IS_SUBPORT_PORT(gport)) {
    654         encap_id = BCM_GPORT_SUBPORT_PORT_GET(gport);
    655         port_out = encap_id;
    656     } else {
    657         return BCM_E_PORT;
    658     }
    659 
    660     mmu_info = _bcm_kt2_mmu_info[unit];
    661 
    662     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) || 
    663         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
    664         encap_id = (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) ?
    665                    BCM_GPORT_UCAST_QUEUE_GROUP_QID_GET(gport) :
    666                    BCM_GPORT_MCAST_QUEUE_GROUP_QID_GET(gport);
    667         index = encap_id;
    668         node_base = mmu_info->queue_node;
    669     } else if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport)) {  
    670         encap_id = BCM_GPORT_DESTMOD_QUEUE_GROUP_QID_GET(gport); 
    671         index = encap_id;
    672         if (mmu_info->num_dmvoq_queues > 0) { 
    673             index += mmu_info->base_dmvoq_queue;
    674         }
    675         node_base = mmu_info->queue_node;
    676     } else if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
    677                BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
    678         encap_id = (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) ?
    679                     BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(gport):
    680                     BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(gport);
    681 
    682         index = encap_id;
    683         if (mmu_info->num_sub_queues > 0) {
    684             if (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
    685                 index += (mmu_info->base_sub_queue + mmu_info->num_queues/2);
    686             } else {
    687                 index += mmu_info->base_sub_queue;
    688             }
    689         }
    690         node_base = mmu_info->queue_node;
    691     }
    692     else {
    693         if (BCM_GPORT_IS_SCHEDULER(gport)) {
    694             /* scheduler */
    695             encap_id = (BCM_GPORT_SCHEDULER_GET(gport) >> 8) & 0x7ff;
    696             if (encap_id == 0) {
    697                 encap_id = (BCM_GPORT_SCHEDULER_GET(gport) & 0xff);
    698             }
    699         }
    700         index = encap_id;
    701         if (index >= num_total_schedulers[unit]) {
    702             return BCM_E_PORT;
    703         }
    704         node_base = mmu_info->sched_node;
    705     }
    706 
    707     if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
    708         /*
    709          * Get S1 node from extended sched list if pp_port is reused
    710          */
    711         if (BCM_GPORT_IS_SUBPORT_PORT(gport) &&
    712             _SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, index) &&
    713             (index <= num_port_schedulers[unit])) {
    714             index += SOC_INFO(unit).cpu_hg_pp_port_index;
    715         }
    716     }
    717 
    718     if (!(BCM_GPORT_IS_LOCAL(gport) || BCM_GPORT_IS_MODPORT(gport)) &&
    719             node_base[index].numq == 0) {
    720         return BCM_E_NOT_FOUND;
    721     }
    722 
    723     if (modid != NULL) {
    724         *modid = modid_out;
    725     }
    726     if (port != NULL) {
    727         *port = port_out;
    728     }
    729     if (id != NULL) {
    730         *id = encap_id;
    731     }
    732     if (node != NULL) {
    733         *node = &node_base[index];
    734     }
    735 
    736     return BCM_E_NONE;
    737 }
    738 
    739 STATIC int
    740 _bcm_kt2_voq_base_node_get(int unit, int modid, int fabric_modid,
    741                       _bcm_kt2_cosq_node_t **node)
    742 {
    743     _bcm_kt2_mmu_info_t *mmu_info;
    744     _bcm_kt2_cosq_node_t *node_base;
    745     int index;
    746     *node = NULL; 
    747     mmu_info = _bcm_kt2_mmu_info[unit];
    748     node_base = mmu_info->queue_node;
    749     mmu_info = _bcm_kt2_mmu_info[unit];
    750     for(index = 0 ; 
    751             index < mmu_info->num_queues ; index++) {
    752         if ((node_base[index].remote_modid == modid) &&
    753             (node_base[index].fabric_modid == fabric_modid)) { 
    754             *node = &node_base[index];
    755             break;
    756         }
    757     }
    758     return BCM_E_NONE;
    759 }
    760 /*
    761  * Function:
    762  *     _bcm_kt2_node_index_get
    763  * Purpose:
    764  *     Allocate free index from the given list
    765  * Parameters:
    766  *     unit       - (IN) unit number
    767  *     list       - (IN) bit list
    768  *     start      - (IN) start index
    769  *     end        - (IN) end index
    770  *     qset       - (IN) size of queue set
    771  *     range      - (IN) range bits
    772  *     id         - (OUT) start index
    773  * Returns:
    774  *     BCM_E_XXX
    775  */
    776 STATIC int
    777 _bcm_kt2_node_index_get(int unit, SHR_BITDCL *list, int start, int end,
    778                        int qset, int range, int *id)
    779 {
    780     int i, j, inc;
    781     _bcm_kt2_mmu_info_t *mmu_info;
    782 
    783     if (_bcm_kt2_mmu_info[unit] == NULL) {
    784         return BCM_E_INIT;
    785     }
    786     mmu_info = _bcm_kt2_mmu_info[unit];
    787     *id = -1;
    788 
    789     if (range != qset) {
    790         inc = 1;
    791         for (i = start; i < end; i = (i + inc)) {
    792              inc = 1;
    793             for (j = i; j < (i + range); j++, inc++) {
    794                 if (SHR_BITGET(list, j) != 0) {
    795                     break;
    796                 }
    797             }
    798 
    799             if ((j == (i + range)) && (mmu_info->intf_ref_cnt[i] == 0)) {
    800                 *id = i;
    801                 return BCM_E_NONE;
    802             }
    803         }
    804         if (i == end) {
    805             return BCM_E_RESOURCE;
    806          }
    807     }
    808 
    809     for (i = start; i < end;  i = i + range) {
    810         for (j = i; j < (i + range); j++) {
    811             if (SHR_BITGET(list, j) != 0) {
    812                 break;
    813             }
    814         }
    815 
    816         if ((j == (i + range)) && (mmu_info->intf_ref_cnt[i] == 0)) {
    817             *id  =  i;
    818             return BCM_E_NONE;
    819            }
    820     }
    821 
    822     if (i == end) {
    823         return BCM_E_RESOURCE;
    824       }
    825 
    826     return BCM_E_NONE;
    827 }
    828 
    829 /*
    830  * Function:
    831  *     _bcm_kt2_node_index_set
    832  * Purpose:
    833  *     Mark indices as allocated
    834  * Parameters:
    835  *     list       - (IN) bit list
    836  *     start      - (IN) start index
    837  *     range      - (IN) range bits
    838  * Returns:
    839  *     BCM_E_XXX
    840  */
    841 STATIC int
    842 _bcm_kt2_node_index_set(_bcm_kt2_cosq_list_t *list, int start, int range)
    843 {
    844     list->count += range;
    845     SHR_BITSET_RANGE(list->bits, start, range);
    846 
    847     return BCM_E_NONE;
    848 }
    849 
    850 /*
    851  * Function:
    852  *     _bcm_kt2_node_index_clear
    853  * Purpose:
    854  *     Mark indices as free
    855  * Parameters:
    856  *     list       - (IN) bit list
    857  *     start      - (IN) start index
    858  *     range      - (IN) range bits
    859  * Returns:
    860  *     BCM_E_XXX
    861  */
    862 STATIC int
    863 _bcm_kt2_node_index_clear(_bcm_kt2_cosq_list_t *list, int start, int range)
    864 {
    865     list->count -= range;
    866     SHR_BITCLR_RANGE(list->bits, start, range);
    867 
    868     return BCM_E_NONE;
    869 }
    870 
    871 /*
    872  * Function:
    873  *     _bcm_kt2_cosq_map_index_get
    874  * Purpose:
    875  *     Allocate free index from the given list
    876  * Parameters:
    877  *     list       - (IN) bit list
    878  *     start      - (IN) start index
    879  *     end        - (IN) end index
    880  *     id         - (OUT) start index
    881  * Returns:
    882  *     BCM_E_XXX
    883  */
    884 STATIC int
    885 _bcm_kt2_cosq_map_index_get(SHR_BITDCL *list, int start, int end, int *id)
    886 {
    887     int i;
    888 
    889     for (i = start; i < end; i++) {
    890         if (SHR_BITGET(list, i) != 0) {
    891             continue;
    892         }
    893         *id  =  i;
    894         return BCM_E_NONE;
    895     }
    896 
    897     return BCM_E_RESOURCE;
    898 }
    899 
    900 /*
    901  * Function:
    902  *     _bcm_kt2_cosq_map_index_set
    903  * Purpose:
    904  *     Mark indices as allocated
    905  * Parameters:
    906  *     list       - (IN) bit list
    907  *     start      - (IN) start index
    908  *     range      - (IN) range bits
    909  * Returns:
    910  *     BCM_E_XXX
    911  */
    912 STATIC int
    913 _bcm_kt2_cosq_map_index_set(SHR_BITDCL *list, int start, int range)
    914 {
    915     SHR_BITSET_RANGE(list, start, range);
    916     return BCM_E_NONE;
    917 }
    918 
    919 /*
    920  * Function:
    921  *     _bcm_kt2_cosq_map_index_clear
    922  * Purpose:
    923  *     Mark indices as free
    924  * Parameters:
    925  *     list       - (IN) bit list
    926  *     start      - (IN) start index
    927  *     range      - (IN) range bits
    928  * Returns:
    929  *     BCM_E_XXX
    930  */
    931 STATIC int
    932 _bcm_kt2_cosq_map_index_clear(SHR_BITDCL *list, int start, int range)
    933 {
    934     if (list != NULL) {
    935         SHR_BITCLR_RANGE(list, start, range);
    936     }
    937     return BCM_E_NONE;
    938 }
    939 
    940 /*
    941  * Function:
    942  *     _bcm_kt2_cosq_map_index_is_set
    943  * Purpose:
    944  *     Check index is allocated
    945  * Parameters:
    946  *     list       - (IN) bit list
    947  *     index      - (IN) index
    948  * Returns:
    949  *     BCM_E_XXX
    950  */
    951 STATIC int
    952 _bcm_kt2_cosq_map_index_is_set(SHR_BITDCL *list, int index)
    953 {
    954     if (SHR_BITGET(list, index) != 0) {
    955         return TRUE;
    956     }
    957 
    958     return FALSE;
    959 }
    960 
    961 STATIC int
    962 _bcm_kt2_cosq_max_nodes_get(int unit, _bcm_kt2_cosq_node_level_t level,
    963                            int *id)
    964 {
    965     _bcm_kt2_mmu_info_t *mmu_info;
    966 
    967     if (level < _BCM_KT2_COSQ_NODE_LEVEL_ROOT ||
    968         level >= _BCM_KT2_COSQ_NODE_LEVEL_MAX) {
    969         return BCM_E_PARAM;
    970     }
    971     mmu_info = _bcm_kt2_mmu_info[unit];
    972     *id = mmu_info->max_nodes[level];
    973 
    974     return BCM_E_NONE;
    975 }
    976 
    977 typedef struct _bcm_kt2_lls_info_s {
    978     int node_count[_BCM_KT2_COSQ_NODE_LEVEL_MAX];
    979     uint32 *min_entries[_BCM_KT2_COSQ_NODE_LEVEL_MAX];
    980     uint32 *max_entries[_BCM_KT2_COSQ_NODE_LEVEL_MAX];
    981     uint32 *max_burst_entries[_BCM_KT2_COSQ_NODE_LEVEL_MAX];
    982     uint32 *min_burst_entries[_BCM_KT2_COSQ_NODE_LEVEL_MAX];
    983 } _bcm_kt2_lls_info_t;
    984 
    985 /* Max 1G rate to expedite draining packets during congestion */
    986 #define _BCM_KT2_COSQ_MAX_FLUSH_RATE   1000000 
    987 
    988 STATIC int 
    989 _bcm_kt2_cosq_lls_shapers_remove(int unit, int port, 
    990                             _bcm_kt2_cosq_node_t *node,
    991                             _bcm_kt2_lls_info_t *lls_tree)
    992 {
    993     int alloc_size, speed;
    994     _bcm_kt2_cosq_node_t *cur_node, *parent;
    995     uint32 *min_entries, *max_entries, *min_burst_entries, *max_burst_entries;
    996     uint32 max_shaper, min, max, flags, burst_max, burst_min;
    997     uint32 burst, mode;
    998     int count = 0;
    999     int num_entries = 0;
   1000 
   1001     parent = node->parent;
   1002     if ((parent == NULL) && 
   1003         (node->level != _BCM_KT2_COSQ_NODE_LEVEL_ROOT)) {
   1004         return BCM_E_INTERNAL;
   1005     }
   1006 
   1007     num_entries = (node->level != _BCM_KT2_COSQ_NODE_LEVEL_ROOT) ?
   1008                   parent->num_child : 1;
   1009 
   1010     /* Allocate memory based on child nodes */
   1011     alloc_size = sizeof(uint32) * num_entries;
   1012     lls_tree->min_entries[node->level] = sal_alloc(alloc_size, "lls_war_buf");
   1013     lls_tree->max_entries[node->level] = sal_alloc(alloc_size, "lls_war_buf");
   1014     lls_tree->max_burst_entries[node->level] = sal_alloc(alloc_size, "lls_war_buf");
   1015     lls_tree->min_burst_entries[node->level] = sal_alloc(alloc_size, "lls_war_buf");
   1016 
   1017     min_entries = lls_tree->min_entries[node->level];
   1018     max_entries = lls_tree->max_entries[node->level];
   1019     min_burst_entries = lls_tree->min_burst_entries[node->level];
   1020     max_burst_entries = lls_tree->max_burst_entries[node->level];
   1021 
   1022     sal_memset(min_entries, 0, alloc_size);
   1023     sal_memset(max_entries, 0, alloc_size);
   1024     sal_memset(min_burst_entries, 0, alloc_size);
   1025     sal_memset(max_burst_entries, 0, alloc_size);
   1026     lls_tree->node_count[node->level] = num_entries; 
   1027 
   1028     /*
   1029      *  Reserve 10% for the node which is being flushes and 
   1030      *  distribute remaining bandwidth across other nodes
   1031      */
   1032     speed = _BCM_KT2_COSQ_MAX_FLUSH_RATE;
   1033     max_shaper = ((speed * 9)/10)/lls_tree->node_count[node->level];
   1034 
   1035     if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_ROOT) {
   1036         BCM_IF_ERROR_RETURN
   1037             (bcm_kt_port_rate_egress_get(unit, port, &max, &burst, &mode));
   1038         min_entries[count] = 0;
   1039         max_entries[count] = max;
   1040         BCM_IF_ERROR_RETURN
   1041             (bcm_kt_port_rate_egress_set(unit, port, speed, burst, mode));
   1042         return BCM_E_NONE;
   1043     }
   1044 
   1045     /* store configured bandwidth of all the nodes */
   1046     for (cur_node = parent->child; cur_node != NULL;
   1047          cur_node = cur_node->sibling) {
   1048          BCM_IF_ERROR_RETURN
   1049              (bcm_kt2_cosq_gport_bandwidth_get(unit, cur_node->gport, 0, 
   1050                                   &min, &max, &burst_min, &burst_max, &flags));
   1051          min_entries[count] = min;
   1052          max_entries[count] = max;
   1053          min_burst_entries[count] = burst_min;
   1054          max_burst_entries[count] = burst_max;
   1055          count++;
   1056          if (cur_node->hw_index == node->hw_index) {
   1057              BCM_IF_ERROR_RETURN
   1058                  (bcm_kt2_cosq_gport_bandwidth_set(unit, cur_node->gport, 0, 
   1059                                           (speed / 10), speed, flags));
   1060          } else {
   1061              BCM_IF_ERROR_RETURN
   1062                  (bcm_kt2_cosq_gport_bandwidth_set(unit, cur_node->gport, 0, 
   1063                                               0, max_shaper, flags));
   1064          }
   1065     }
   1066 
   1067     return BCM_E_NONE;
   1068 }
   1069 
   1070 STATIC int 
   1071 _bcm_kt2_cosq_lls_shapers_restore(int unit, int port,
   1072                             _bcm_kt2_cosq_node_t *node,
   1073                             _bcm_kt2_lls_info_t *lls_tree)
   1074 {
   1075     _bcm_kt2_cosq_node_t *cur_node, *parent;
   1076     uint32 *min_entries, *max_entries, *burst_max_entries, *burst_min_entries;
   1077     uint32 min, max, burst_max, burst_min;
   1078     uint32 burst, mode;
   1079     int count = 0;
   1080 
   1081     parent = node->parent;
   1082     if ((parent == NULL) && 
   1083         (node->level != _BCM_KT2_COSQ_NODE_LEVEL_ROOT)) {
   1084         return BCM_E_INTERNAL;
   1085     }
   1086 
   1087     min_entries = lls_tree->min_entries[node->level];
   1088     max_entries = lls_tree->max_entries[node->level];
   1089     burst_max_entries = lls_tree->max_burst_entries[node->level];
   1090     burst_min_entries = lls_tree->min_burst_entries[node->level];
   1091 
   1092     if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_ROOT) {
   1093         BCM_IF_ERROR_RETURN
   1094             (bcm_kt_port_rate_egress_get(unit, port, &max, &burst, &mode));
   1095         max = max_entries[count];    
   1096         BCM_IF_ERROR_RETURN
   1097             (bcm_kt_port_rate_egress_set(unit, port, max, burst, mode));
   1098         return BCM_E_NONE;
   1099     }
   1100 
   1101     /* restore bandwidth */
   1102     for (cur_node = parent->child; cur_node != NULL;
   1103          cur_node = cur_node->sibling) {
   1104         min = min_entries[count];
   1105         max = max_entries[count];
   1106         burst_max = burst_max_entries[count];
   1107         burst_min = burst_min_entries[count];
   1108         count++;
   1109 
   1110         BCM_IF_ERROR_RETURN
   1111             (bcm_kt2_cosq_gport_bandwidth_set(unit, cur_node->gport, 0, 
   1112                                          min, max, 0));
   1113         BCM_IF_ERROR_RETURN(bcm_kt2_cosq_gport_bandwidth_burst_set(unit,
   1114                     cur_node->gport, 0, burst_min, burst_max));
   1115     }
   1116 
   1117     return BCM_E_NONE;
   1118 }
   1119 
   1120 STATIC int
   1121 _bcm_kt2_cosq_poll_flush_active(int unit, bcm_port_t port, 
   1122                                 _bcm_kt2_cosq_node_t *node)
   1123 {
   1124     soc_timeout_t timeout;
   1125     int flush_active = 1;
   1126     uint32 timeout_val;
   1127     uint32 rval = 0;
   1128     int packing_mode = 0;
   1129 
   1130     if (soc_feature(unit, soc_feature_mmu_packing)) {
   1131         BCM_IF_ERROR_RETURN
   1132         (_bcm_kt2_cosq_packing_mode_get(unit, node->hw_index, &packing_mode));
   1133         
   1134     }
   1135     if (packing_mode == 1) {
   1136         timeout_val = soc_property_get(unit, spn_MMU_QUEUE_FLUSH_TIMEOUT, 
   1137                                 _BCM_COSQ_QUEUE_FLUSH_TIMEOUT_PACKING_DEFAULT);
   1138     } else {
   1139 
   1140         timeout_val = soc_property_get(unit, spn_MMU_QUEUE_FLUSH_TIMEOUT, 
   1141                                     _BCM_COSQ_QUEUE_FLUSH_TIMEOUT_DEFAULT);
   1142     }
   1143     soc_timeout_init(&timeout, timeout_val, 0);
   1144 
   1145     while (flush_active) {                              
   1146         BCM_IF_ERROR_RETURN(READ_TOQ_FLUSH0r(unit, &rval)); 
   1147         flush_active = soc_reg_field_get(unit, TOQ_FLUSH0r, 
   1148                                          rval, FLUSH_ACTIVEf);
   1149         if (soc_timeout_check(&timeout)) {
   1150             return (BCM_E_TIMEOUT);
   1151          }
   1152     }
   1153 
   1154     return BCM_E_NONE;
   1155 }
   1156 
   1157 STATIC int
   1158 _bcm_kt2_cosq_adjust_lls_bw(int unit, bcm_gport_t gport, 
   1159                             _bcm_kt2_cosq_node_t *node)
   1160 {
   1161     int rv = BCM_E_NONE;
   1162     _bcm_kt2_lls_info_t lls_tree;
   1163     _bcm_kt2_cosq_node_t *cur_node;
   1164     bcm_port_t port;
   1165     int count = 0, i;
   1166     uint32 map_entry[SOC_MAX_MEM_WORDS];
   1167     int index = 0 , eindex = 0;
   1168     static const soc_field_t indexf[] = {
   1169         INDEX0f, INDEX1f
   1170     };
   1171     int map_offset = 0;
   1172 
   1173     /* resolve the port */
   1174     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   1175         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
   1176         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
   1177         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) || 
   1178         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   1179         BCM_GPORT_IS_SCHEDULER(gport)) {
   1180         BCM_IF_ERROR_RETURN
   1181             (_bcm_kt2_cosq_node_get(unit, gport, NULL, &port, NULL,
   1182                                    NULL));
   1183         if (node->hw_index > 0) {
   1184             index = node->hw_index / 16 ;
   1185             eindex = (node->hw_index % 16) / 8;
   1186             BCM_IF_ERROR_RETURN
   1187                 (soc_mem_read(unit, MMU_INTFI_FC_MAP_TBL2m,
   1188                               MEM_BLOCK_ALL, index, &map_entry));
   1189             map_offset = soc_mem_field32_get(unit, MMU_INTFI_FC_MAP_TBL2m, &map_entry,
   1190                     indexf[eindex]);
   1191             if (map_offset) {
   1192                 soc_mem_field32_set(unit, MMU_INTFI_FC_MAP_TBL2m, &map_entry,
   1193                         indexf[eindex], 0);
   1194                 BCM_IF_ERROR_RETURN(soc_mem_write(unit, MMU_INTFI_FC_MAP_TBL2m,
   1195                             MEM_BLOCK_ALL, index, &map_entry));
   1196 
   1197             }
   1198         }
   1199     } else {
   1200         /* optionally validate port */
   1201         BCM_IF_ERROR_RETURN
   1202             (_bcm_kt2_cosq_localport_resolve(unit, gport, &port));
   1203         if (port < 0) {
   1204             return BCM_E_PORT;
   1205         }
   1206     }
   1207 
   1208     sal_memset(&lls_tree, 0, sizeof(_bcm_kt2_lls_info_t));
   1209     cur_node =  node;
   1210     while (cur_node != NULL) {
   1211         count++;
   1212         rv = _bcm_kt2_cosq_lls_shapers_remove(unit, port, cur_node, &lls_tree); 
   1213         if (rv != BCM_E_NONE) {
   1214             goto cleanup;
   1215         }
   1216 
   1217         rv = _bcm_kt2_cosq_poll_flush_active(unit, port, node);
   1218         if (rv == BCM_E_NONE) {
   1219             break;
   1220         } else {
   1221             cur_node = cur_node->parent;
   1222         }
   1223     }
   1224 
   1225 cleanup:
   1226     cur_node = node; 
   1227     for (i = 0; i < count; i++) {
   1228         rv = _bcm_kt2_cosq_lls_shapers_restore(unit, port, cur_node, &lls_tree);
   1229         if (rv != BCM_E_NONE) {
   1230             goto cleanup;
   1231         }
   1232         cur_node = cur_node->parent;
   1233     } 
   1234     if (map_offset) {
   1235         soc_mem_field32_set(unit, MMU_INTFI_FC_MAP_TBL2m, &map_entry,
   1236                 indexf[eindex], map_offset);
   1237         BCM_IF_ERROR_RETURN(soc_mem_write(unit, MMU_INTFI_FC_MAP_TBL2m,
   1238                     MEM_BLOCK_ALL, index, &map_entry));
   1239 
   1240     }
   1241     for (i = _BCM_KT2_COSQ_NODE_LEVEL_ROOT; i < _BCM_KT2_COSQ_NODE_LEVEL_MAX;
   1242          i++) {
   1243         if (lls_tree.min_entries[i]) {
   1244             sal_free(lls_tree.min_entries[i]);
   1245             lls_tree.min_entries[i] = NULL;
   1246         }
   1247         if (lls_tree.max_entries[i]) {
   1248             sal_free(lls_tree.max_entries[i]);
   1249             lls_tree.max_entries[i] = NULL;
   1250         }
   1251         if (lls_tree.max_burst_entries[i]) {
   1252             sal_free(lls_tree.max_burst_entries[i]);
   1253             lls_tree.max_burst_entries[i] = NULL;
   1254         }
   1255         if (lls_tree.min_burst_entries[i]) {
   1256             sal_free(lls_tree.min_burst_entries[i]);
   1257             lls_tree.min_burst_entries[i] = NULL;
   1258         }
   1259     }
   1260 
   1261     return rv;
   1262 }
   1263 
   1264 
   1265 /*
   1266  * Function:
   1267  *     _bcm_kt2_cosq_alloc_clear
   1268  * Purpose:
   1269  *     Allocate cosq memory and clear
   1270  * Parameters:
   1271  *     size       - (IN) size of memory required
   1272  *     description- (IN) description about the structure
   1273  * Returns:
   1274  *     BCM_E_XXX
   1275  */
   1276 STATIC void *
   1277 _bcm_kt2_cosq_alloc_clear(unsigned int size, char *description)
   1278 {
   1279     void *block_p;
   1280 
   1281     block_p = sal_alloc(size, description);
   1282 
   1283     if (block_p != NULL) {
   1284         sal_memset(block_p, 0, size);
   1285     }
   1286 
   1287     return block_p;
   1288 }
   1289 
   1290 /*
   1291  * Function:
   1292  *     _bcm_kt2_cosq_free_memory
   1293  * Purpose:
   1294  *     Free memory allocated for mmu info members
   1295  * Parameters:
   1296  *     mmu_info_p       - (IN) MMU info pointer
   1297  * Returns:
   1298  *     BCM_E_XXX
   1299  */
   1300 STATIC void
   1301 _bcm_kt2_cosq_free_memory(_bcm_kt2_mmu_info_t *mmu_info_p)
   1302 {
   1303     int i;
   1304 
   1305     if (mmu_info_p->port != NULL) {
   1306         sal_free(mmu_info_p->port);
   1307         mmu_info_p->port = NULL;
   1308     }
   1309     if (mmu_info_p->l1_gport_pair != NULL) {
   1310         sal_free(mmu_info_p->l1_gport_pair);
   1311         mmu_info_p->l1_gport_pair = NULL;
   1312     }
   1313     if (mmu_info_p->global_qlist.bits != NULL) {
   1314         sal_free(mmu_info_p->global_qlist.bits);
   1315         mmu_info_p->global_qlist.bits = NULL;
   1316     }
   1317     if (mmu_info_p->dmvoq_qlist.bits != NULL) {
   1318         sal_free(mmu_info_p->dmvoq_qlist.bits);
   1319         mmu_info_p->dmvoq_qlist.bits = NULL;
   1320     }
   1321     if (mmu_info_p->sched_list.bits != NULL) {
   1322         sal_free(mmu_info_p->sched_list.bits);
   1323         mmu_info_p->sched_list.bits = NULL;
   1324     }
   1325     if (mmu_info_p->sub_qlist.bits != NULL) {
   1326         sal_free(mmu_info_p->sub_qlist.bits);
   1327         mmu_info_p->sub_qlist.bits = NULL;
   1328     }
   1329     if (mmu_info_p->sub_mcqlist.bits != NULL) {
   1330         sal_free(mmu_info_p->sub_mcqlist.bits);
   1331         mmu_info_p->sub_mcqlist.bits = NULL;
   1332     }
   1333     if (mmu_info_p->l2_base_qlist.bits != NULL) {
   1334         sal_free(mmu_info_p->l2_base_qlist.bits);
   1335         mmu_info_p->l2_base_qlist.bits = NULL;
   1336     }
   1337     if (mmu_info_p->l2_base_mcqlist.bits != NULL) {
   1338         sal_free(mmu_info_p->l2_base_mcqlist.bits);
   1339         mmu_info_p->l2_base_mcqlist.bits = NULL;
   1340     }    
   1341     if (mmu_info_p->l2_global_qlist.bits != NULL) {
   1342         sal_free(mmu_info_p->l2_global_qlist.bits);
   1343         mmu_info_p->l2_global_qlist.bits = NULL;
   1344     }
   1345     if (mmu_info_p->l2_dmvoq_qlist.bits != NULL) {
   1346         sal_free(mmu_info_p->l2_dmvoq_qlist.bits);
   1347         mmu_info_p->l2_dmvoq_qlist.bits = NULL;
   1348     }
   1349     if (mmu_info_p->l2_sub_qlist.bits != NULL) {
   1350         sal_free(mmu_info_p->l2_sub_qlist.bits);
   1351         mmu_info_p->l2_sub_qlist.bits = NULL;
   1352     }
   1353     if (mmu_info_p->l2_sub_mcqlist.bits != NULL) {
   1354         sal_free(mmu_info_p->l2_sub_mcqlist.bits);
   1355         mmu_info_p->l2_sub_mcqlist.bits = NULL;
   1356     }
   1357     for (i = 0; i < _BCM_KT2_COSQ_NODE_LEVEL_L2; i++) { 
   1358         if (mmu_info_p->sched_hw_list[i].bits != NULL) {
   1359             sal_free(mmu_info_p->sched_hw_list[i].bits);
   1360             mmu_info_p->sched_hw_list[i].bits = NULL;
   1361         }
   1362     }
   1363     if (mmu_info_p->sched_node != NULL) {
   1364         for (i = 0; i < mmu_info_p->num_nodes; i++) {
   1365             if (((&mmu_info_p->sched_node[i]) != NULL) &&
   1366                 ((&mmu_info_p->sched_node[i])->cosq_map != NULL)) {
   1367                 sal_free((&mmu_info_p->sched_node[i])->cosq_map);
   1368                 (&mmu_info_p->sched_node[i])->cosq_map = NULL;
   1369             }
   1370         }
   1371         sal_free(mmu_info_p->sched_node);
   1372         mmu_info_p->sched_node = NULL;
   1373     }
   1374     if (mmu_info_p->queue_node != NULL) {
   1375         for (i = 0; i < mmu_info_p->num_queues; i++) {
   1376             if (((&mmu_info_p->queue_node[i]) != NULL) &&
   1377                 ((&mmu_info_p->queue_node[i])->cosq_map != NULL)) {
   1378                 sal_free((&mmu_info_p->queue_node[i])->cosq_map);
   1379                 (&mmu_info_p->queue_node[i])->cosq_map = NULL;
   1380             }
   1381         }
   1382         sal_free(mmu_info_p->queue_node);
   1383         mmu_info_p->queue_node = NULL;
   1384     }
   1385 }
   1386 STATIC int
   1387 _bcm_kt2_port_is_coe_linkphy(_bcm_kt2_cosq_node_t *node)
   1388 {
   1389    while(node != NULL) {
   1390          if ((node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) ||
   1391              (node->level == _BCM_KT2_COSQ_NODE_LEVEL_S1)) {
   1392              return TRUE;
   1393          }
   1394          node = node->parent;
   1395    }
   1396    return FALSE;
   1397 }
   1398 
   1399 /*
   1400  * _bcm_is_port_linkphy_subport(int unit, int port, int min_port_index) {
   1401  *
   1402  * IN:
   1403  * unit :
   1404  * port : pp_port or physical port
   1405  * min_port_index : Start of subport pp_port. This can be -1 in which case
   1406  *                  min_port_index will be automatically fetched.
   1407  * OUT:
   1408  * TRUE - if port is a subport/linkphy pp_port
   1409  * FALSE - if port is a physical port
   1410  */
   1411 
   1412 STATIC int
   1413 _bcm_is_port_linkphy_subport(int unit, bcm_gport_t gport, int min_port_index)
   1414 {
   1415     soc_info_t *si;
   1416     int port, encap_id, rv;
   1417     _bcm_kt2_cosq_node_t *node = NULL;
   1418 
   1419     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   1420         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
   1421         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
   1422         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) || 
   1423         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   1424         BCM_GPORT_IS_SCHEDULER(gport)) {
   1425         rv = _bcm_kt2_cosq_node_get(unit, gport, NULL, &port, &encap_id, &node);
   1426     } else {
   1427         rv = _bcm_kt2_cosq_localport_resolve(unit, gport, &port);
   1428         encap_id = port;
   1429     }
   1430 
   1431     if (rv != BCM_E_NONE) {
   1432         LOG_ERROR(BSL_LS_BCM_COMMON,
   1433                     (BSL_META_U(unit,
   1434                                 "Unable to retrieve port info.\n")));
   1435     }
   1436 
   1437 #if defined BCM_METROLITE_SUPPORT
   1438     if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
   1439         if ((node && (encap_id > num_port_schedulers[unit]) && (encap_id <= num_pp_ports[unit])) ||
   1440             _bcm_kt2_port_is_coe_linkphy(node) || 
   1441             (!node && (BCM_GPORT_IS_SUBPORT_PORT(gport) ||
   1442              _SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, port)))) {
   1443             return TRUE;
   1444         }
   1445     } else
   1446 #endif
   1447     {
   1448         if (min_port_index == -1) {
   1449             si = &SOC_INFO(unit);
   1450             min_port_index = si->pp_port_index_min;
   1451         }
   1452         if (port >= min_port_index) {
   1453             return TRUE;
   1454         }
   1455     }
   1456     return FALSE;
   1457 }
   1458 
   1459 int
   1460 _bcm_kt2_cosq_port_resolve(int unit, bcm_gport_t gport, bcm_module_t *modid,
   1461                           bcm_port_t *port, bcm_trunk_t *trunk_id, int *id,
   1462                           int *qnum)
   1463 {
   1464     _bcm_kt2_cosq_node_t *node;
   1465 
   1466     BCM_IF_ERROR_RETURN
   1467         (_bcm_kt2_cosq_node_get(unit, gport, modid, port, NULL, &node));
   1468     *trunk_id = -1;
   1469 
   1470     if (_bcm_is_port_linkphy_subport(unit, gport, num_port_schedulers[unit])) {
   1471         BCM_IF_ERROR_RETURN(
   1472         _bcm_kt2_pp_port_to_modport_get(unit,*port,
   1473                             modid, port));
   1474     }
   1475 
   1476     if (qnum) {
   1477         if (node->hw_index == -1) {
   1478             return BCM_E_PARAM;
   1479         }
   1480         *qnum = node->hw_index;
   1481     }
   1482 
   1483     return BCM_E_NONE;
   1484 }
   1485 
   1486 /*
   1487  * Function:
   1488  *     _bcm_kt2_cosq_gport_traverse
   1489  * Purpose:
   1490  *     Walks through the valid COSQ GPORTs and calls
   1491  *     the user supplied callback function for each entry.
   1492  * Parameters:
   1493  *     unit       - (IN) unit number
   1494  *     gport      - (IN)
   1495  *     cb         - (IN) Callback function.
   1496  *     user_data  - (IN) User data to be passed to callback function
   1497  * Returns:
   1498  *     BCM_E_NONE - Success.
   1499  *     BCM_E_XXX
   1500  */
   1501 int
   1502 _bcm_kt2_cosq_gport_traverse(int unit, bcm_gport_t gport,
   1503                             bcm_cosq_gport_traverse_cb cb,
   1504                             void *user_data)
   1505 {
   1506     _bcm_kt2_cosq_node_t *node;
   1507     bcm_port_t port, port_out;
   1508     uint32 flags = BCM_COSQ_GPORT_SCHEDULER;
   1509     int rv = BCM_E_NONE;
   1510     bcm_module_t modid, modid_out;
   1511     bcm_gport_t gport_out;
   1512 
   1513     BCM_IF_ERROR_RETURN
   1514         (_bcm_kt2_cosq_node_get(unit, gport, &modid, &port, NULL, &node));
   1515 
   1516     if (node != NULL) {
   1517        if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L2) {
   1518            if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport)) {
   1519                flags = BCM_COSQ_GPORT_UCAST_QUEUE_GROUP;
   1520            } else if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport)) {
   1521                flags = BCM_COSQ_GPORT_DESTMOD_UCAST_QUEUE_GROUP; 
   1522            } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport)) {
   1523                flags = BCM_COSQ_GPORT_MCAST_QUEUE_GROUP;
   1524            } else if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) {
   1525                flags = BCM_COSQ_GPORT_SUBSCRIBER;
   1526            } else if (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) {
   1527                flags = (BCM_COSQ_GPORT_SUBSCRIBER | BCM_COSQ_GPORT_MCAST_QUEUE_GROUP);;
   1528            }       
   1529        }
   1530        if (BCM_GPORT_IS_SCHEDULER(gport)) {
   1531            if (node->type == _BCM_KT2_NODE_SCHEDULER_WFQ) {
   1532                if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_ROOT) {
   1533                    flags = BCM_COSQ_GPORT_SCHEDULER_WFQ;
   1534                } else {
   1535                    flags = BCM_COSQ_GPORT_SCHEDULER_WFQ |
   1536                            BCM_COSQ_GPORT_SCHEDULER;
   1537                }
   1538            }
   1539        }
   1540        BCM_IF_ERROR_RETURN
   1541            (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, modid, port,
   1542                                     &modid_out, &port_out));
   1543        BCM_GPORT_MODPORT_SET(gport_out, modid_out, port_out);
   1544 
   1545        rv = cb(unit, gport_out, node->numq, flags,
   1546                   node->gport, user_data);
   1547        if (BCM_FAILURE(rv)) {
   1548 #ifdef BCM_CB_ABORT_ON_ERR
   1549            if (SOC_CB_ABORT_ON_ERR(unit)) {
   1550                return rv;
   1551            }
   1552 #endif
   1553        }
   1554     } else {
   1555             return BCM_E_NONE;
   1556     }
   1557 
   1558     if (node->sibling != NULL) {
   1559         _bcm_kt2_cosq_gport_traverse(unit, node->sibling->gport, cb, user_data);
   1560     }
   1561 
   1562     if (node->child != NULL) {
   1563         _bcm_kt2_cosq_gport_traverse(unit, node->child->gport, cb, user_data);
   1564     }
   1565 
   1566     return BCM_E_NONE;
   1567 }
   1568 
   1569 /*
   1570  * Function:
   1571  *     _bcm_kt2_cosq_index_resolve
   1572  * Purpose:
   1573  *     Find hardware index for the given port/cosq
   1574  * Parameters:
   1575  *     unit       - (IN) unit number
   1576  *     port       - (IN) port number or GPORT identifier
   1577  *     cosq       - (IN) COS queue number
   1578  *     style      - (IN) index style (_BCM_KA_COSQ_INDEX_STYLE_XXX)
   1579  *     local_port - (OUT) local port number
   1580  *     index      - (OUT) result index
   1581  *     count      - (OUT) number of index
   1582  * Returns:
   1583  *     BCM_E_XXX
   1584  */
   1585 int
   1586 _bcm_kt2_cosq_index_resolve(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   1587                            _bcm_kt2_cosq_index_style_t style,
   1588                            bcm_port_t *local_port, int *index, int *count)
   1589 {
   1590     _bcm_kt2_cosq_node_t *node = NULL;
   1591     _bcm_kt2_cosq_node_t   *cur_node = NULL;
   1592     bcm_port_t resolved_port;
   1593     int resolved_index;
   1594     int id, startq, numq = 0;
   1595     _bcm_kt2_mmu_info_t *mmu_info;
   1596 
   1597     if (cosq < -1) {
   1598         return BCM_E_PARAM;
   1599     } else if (cosq == -1) {
   1600         startq = 0;
   1601     } else {
   1602         startq = cosq;
   1603     }
   1604 
   1605     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(port) ||
   1606         BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
   1607         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) ||
   1608         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) || 
   1609         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   1610         BCM_GPORT_IS_SCHEDULER(port)) {
   1611         BCM_IF_ERROR_RETURN
   1612             (_bcm_kt2_cosq_node_get(unit, port, NULL, &resolved_port, &id,
   1613                                    &node));
   1614         if ((node->cosq_attached_to < 0) || (node->hw_index == -1)) { 
   1615             /* Not resolved yet */
   1616             return BCM_E_NOT_FOUND;
   1617         }
   1618         if (BCM_GPORT_IS_SCHEDULER(port) &&
   1619             (style != _BCM_KT2_COSQ_INDEX_STYLE_BUCKET)) {
   1620             numq = node->numq;
   1621             if (startq >= numq) {
   1622                 return BCM_E_PARAM;
   1623             }
   1624         } else {
   1625             numq = node->numq;
   1626         }    
   1627     } else {
   1628         /* optionally validate port */
   1629         BCM_IF_ERROR_RETURN
   1630             (_bcm_kt2_cosq_localport_resolve(unit, port, &resolved_port));
   1631         if (resolved_port < 0) {
   1632             return BCM_E_PORT;
   1633         }
   1634         node = NULL;
   1635         numq = 0;
   1636     }
   1637 
   1638     switch (style) {
   1639     case _BCM_KT2_COSQ_INDEX_STYLE_BUCKET:
   1640         if (node != NULL) {
   1641             if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(port) ||
   1642                 BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
   1643                 BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) ||
   1644                 BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   1645                 BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port)) {
   1646                 resolved_index = node->hw_index;
   1647             } else if (BCM_GPORT_IS_SCHEDULER(port)) {
   1648                 if (node->level > _BCM_KT2_COSQ_NODE_LEVEL_L1) {
   1649                     return BCM_E_PARAM;
   1650                 }
   1651                 resolved_index = node->hw_index;
   1652             } else {
   1653                     return BCM_E_PARAM;
   1654             }
   1655         } else { /* node == NULL */
   1656             mmu_info = _bcm_kt2_mmu_info[unit];
   1657             numq = mmu_info->port[resolved_port].q_limit - 
   1658                     mmu_info->port[resolved_port].q_offset;
   1659             
   1660             if (cosq >= numq) {
   1661                 return BCM_E_PARAM;
   1662             }
   1663             resolved_index = mmu_info->port[resolved_port].q_offset + startq;
   1664         }
   1665         break;
   1666 
   1667     case _BCM_KT2_COSQ_INDEX_STYLE_WRED:
   1668         if (node != NULL) {
   1669             if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(port) ||
   1670                 BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
   1671                 BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) ||
   1672                 BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   1673                 BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port)) {
   1674                 resolved_index = node->hw_index;
   1675             } else if (BCM_GPORT_IS_SCHEDULER(port)) {
   1676                 if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1 && 
   1677                     node->level !=_BCM_KT2_COSQ_NODE_LEVEL_L0) {
   1678                     return BCM_E_PARAM;
   1679                 }
   1680                 _bcm_kt2_cosq_child_node_at_input(node ,startq ,
   1681                                                   &cur_node); 
   1682                 resolved_index = cur_node->hw_index;
   1683             } else {
   1684                     return BCM_E_PARAM;
   1685             }
   1686         } else { /* node == NULL */
   1687             mmu_info = _bcm_kt2_mmu_info[unit];
   1688             numq = mmu_info->port[resolved_port].q_limit - 
   1689                    mmu_info->port[resolved_port].q_offset;
   1690 
   1691             if (cosq >= numq) {
   1692                 return BCM_E_PARAM;
   1693             }
   1694             resolved_index = mmu_info->port[resolved_port].q_offset + startq;
   1695         }
   1696         break;
   1697 
   1698     case _BCM_KT2_COSQ_INDEX_STYLE_SCHEDULER:
   1699         if (node != NULL) {
   1700             if (BCM_GPORT_IS_SCHEDULER(port)) {
   1701                 for (cur_node = node->child; cur_node != NULL;
   1702                     cur_node = cur_node->sibling) {
   1703                     if (cur_node->cosq_attached_to == startq) {
   1704                         break;
   1705                     }
   1706                 }
   1707 
   1708                 if (cur_node == NULL) {
   1709                     /* this cosq is not yet attached */
   1710                     return BCM_E_INTERNAL;
   1711                 }
   1712                 if ((cur_node->type == _BCM_KT2_NODE_VOQ_ID) ||
   1713                      (cur_node->type == _BCM_KT2_NODE_SUBSCRIBER_GPORT_ID)) {
   1714                     numq = node->num_child;
   1715                 }
   1716                 resolved_index = cur_node->hw_index;
   1717             } else { /* unicast queue group or multicast queue group */
   1718                 return BCM_E_PARAM;
   1719             }
   1720         } else { /* node == NULL */
   1721             mmu_info = _bcm_kt2_mmu_info[unit];
   1722             numq = mmu_info->port[resolved_port].q_limit -
   1723                    mmu_info->port[resolved_port].q_offset;
   1724 
   1725             if (cosq >= numq) {
   1726                 return BCM_E_PARAM;
   1727             }
   1728             resolved_index = mmu_info->port[resolved_port].q_offset + startq;
   1729         }
   1730         break;
   1731     case _BCM_KT2_COSQ_INDEX_STYLE_UCAST_QUEUE:
   1732         mmu_info = _bcm_kt2_mmu_info[unit];
   1733         if (node != NULL) {
   1734             if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(port) ||
   1735                 BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
   1736                 BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) ||
   1737                 BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   1738                 BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port)) {
   1739                 resolved_index = node->hw_index;
   1740             } else if (BCM_GPORT_IS_SCHEDULER(port)) {
   1741                 if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) {
   1742                     return BCM_E_PARAM;
   1743                 }
   1744                 resolved_index = node->base_index;
   1745             } else {
   1746                 return BCM_E_PARAM;
   1747             }
   1748             
   1749             if ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(port)) ||
   1750                  (!(soc_feature(unit, soc_feature_mmu_packing)) &&  
   1751                                 BCM_GPORT_IS_MCAST_QUEUE_GROUP(port))) {
   1752                 resolved_index -= mmu_info->port[resolved_port].q_offset;
   1753             }
   1754         } else { /* node == NULL */
   1755             mmu_info = _bcm_kt2_mmu_info[unit];
   1756             numq = mmu_info->port[resolved_port].q_limit -
   1757                    mmu_info->port[resolved_port].q_offset;
   1758 
   1759             if (startq >= numq) {
   1760                 return BCM_E_PARAM;
   1761             }
   1762             resolved_index = startq;        
   1763         }
   1764         break;
   1765 
   1766     case _BCM_KT2_COSQ_INDEX_STYLE_QUEUE_REPLICATION:
   1767         mmu_info = _bcm_kt2_mmu_info[unit];
   1768         if (node != NULL) {
   1769             if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(port) ||
   1770                 BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   1771                 BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port)) {
   1772                 resolved_index = node->hw_index;
   1773             } else {
   1774                 return BCM_E_PARAM;
   1775             }
   1776             
   1777         } else { /* node == NULL */
   1778             mmu_info = _bcm_kt2_mmu_info[unit];
   1779             numq = mmu_info->port[resolved_port].q_limit -
   1780                    mmu_info->port[resolved_port].q_offset;
   1781 
   1782             if (startq >= numq) {
   1783                 return BCM_E_PARAM;
   1784             }
   1785             resolved_index = startq + mmu_info->port
   1786                                      [resolved_port].q_offset;        
   1787         }
   1788         break;
   1789 
   1790     default:
   1791         return BCM_E_INTERNAL;
   1792     }
   1793 
   1794     if (local_port != NULL) {
   1795         *local_port = resolved_port;
   1796     }
   1797     if (index != NULL) {
   1798         if (resolved_index < 0) {
   1799             return BCM_E_INTERNAL;
   1800         }
   1801         *index = resolved_index;
   1802     }
   1803     if (count != NULL) {
   1804         *count = (cosq == -1) ? numq : 1;
   1805     }
   1806 
   1807     return BCM_E_NONE;
   1808 }
   1809 /*
   1810  * Function:
   1811  *     _bcm_kt2_cosq_get_dmvoq_index
   1812  * Purpose:
   1813  *  This logic is to make sure that the base index is always
   1814  *  multiple of 8
   1815  *     unit       - (IN) unit number
   1816  *     mmu_info       - (IN) MMU info structure 
   1817  *     list       - (IN)list from which index need to be selected 
   1818  *     numq       - (IN) number of queues
   1819  *     id       - (IN) START ID 
   1820  *     limit       - (IN) limit
   1821  * Returns:
   1822  *     BCM_E_XXX
   1823  */
   1824 
   1825 
   1826 STATIC int
   1827 _bcm_kt2_cosq_get_dmvoq_index(
   1828         int unit,
   1829         _bcm_kt2_mmu_info_t *mmu_info,
   1830         _bcm_kt2_cosq_list_t *list,
   1831         int numq, int *id , int limit ) 
   1832 {
   1833      while (((mmu_info->base_dmvoq_queue + *id) % 8) != 0) {
   1834               *id = (*id + 8 - ((mmu_info->base_dmvoq_queue + *id) % 8)); 
   1835                BCM_IF_ERROR_RETURN
   1836                   (_bcm_kt2_node_index_get(unit, list->bits, *id, limit,
   1837                                            mmu_info->qset_size, numq, id));
   1838            }
   1839      return BCM_E_NONE;
   1840 }
   1841 /*
   1842  * Function:
   1843  *     _bcm_kt2_cosq_node_resolve
   1844  * Purpose:
   1845  *     Resolve queue number in the specified scheduler tree and its subtree
   1846  * Parameters:
   1847  *     unit       - (IN) unit number
   1848  *     node       - (IN) node structure for the specified scheduler node
   1849  *     cosq       - (IN) COS queue to attach to
   1850  * Returns:
   1851  *     BCM_E_XXX
   1852  */
   1853 STATIC int
   1854 _bcm_kt2_cosq_node_resolve(int unit, _bcm_kt2_cosq_node_t *node,
   1855                           bcm_cos_queue_t cosq)
   1856 {
   1857     _bcm_kt2_cosq_node_t *parent;
   1858     _bcm_kt2_mmu_info_t *mmu_info;
   1859     _bcm_kt2_cosq_list_t *list;
   1860     bcm_port_t local_port;
   1861     int start_idx = 0, end_idx = 0;
   1862     int base_idx;
   1863     int alloc_size;
   1864     int numq, id = 0, rv = BCM_E_NONE;
   1865     int offset, limit;
   1866     _bcm_kt2_subport_info_t info;
   1867     bcm_gport_t pp_port;
   1868     int dev_int_stream_id = 0;
   1869     soc_pbmp_t pbmp_linkphy_one_stream_per_subport;
   1870 
   1871     parent = node->parent;
   1872     if (parent == NULL) {
   1873         /* Not attached, should never happen */
   1874         return BCM_E_NOT_FOUND;
   1875     }
   1876 
   1877     if (parent->numq == 0 || parent->numq < -1) {
   1878         return BCM_E_PARAM;
   1879     }
   1880    
   1881     if (parent->cosq_map == NULL) {
   1882         alloc_size = SHR_BITALLOCSIZE(parent->numq);
   1883         parent->cosq_map = _bcm_kt2_cosq_alloc_clear(alloc_size,
   1884                                            "parent->cosq_map");
   1885         if (parent->cosq_map == NULL) {
   1886             return BCM_E_MEMORY;
   1887         }
   1888     }
   1889  
   1890     if (cosq < 0) {
   1891         BCM_IF_ERROR_RETURN
   1892             (_bcm_kt2_cosq_map_index_get(parent->cosq_map,
   1893                                         0, parent->numq, &id));
   1894         BCM_IF_ERROR_RETURN
   1895             (_bcm_kt2_cosq_map_index_set(parent->cosq_map, id, 1));
   1896         node->cosq_attached_to = id;
   1897     } else {
   1898         if (_bcm_kt2_cosq_map_index_is_set(parent->cosq_map,
   1899                                   cosq) == TRUE) {
   1900             return BCM_E_EXISTS;
   1901         }
   1902         BCM_IF_ERROR_RETURN
   1903             (_bcm_kt2_cosq_map_index_set(parent->cosq_map, cosq, 1));
   1904         node->cosq_attached_to = cosq;
   1905     } 
   1906 
   1907     mmu_info = _bcm_kt2_mmu_info[unit];
   1908     numq = (parent->wrr_mode == 0) ? ((parent->numq > 8) ? 8 : parent->numq) : 1;
   1909 
   1910     switch (parent->level) {
   1911         case _BCM_KT2_COSQ_NODE_LEVEL_ROOT:
   1912         case _BCM_KT2_COSQ_NODE_LEVEL_S1:    
   1913         case _BCM_KT2_COSQ_NODE_LEVEL_L0:
   1914             list = &mmu_info->sched_hw_list[node->level];
   1915             if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
   1916                 BCM_IF_ERROR_RETURN
   1917                   (_bcm_kt2_cosq_subport_get(unit, node->gport, &pp_port));
   1918                 BCM_IF_ERROR_RETURN
   1919                    (bcm_kt2_subport_pp_port_subport_info_get(unit, pp_port,
   1920                                                 &info));
   1921                  node->hw_index = (BCM_GPORT_SCHEDULER_GET(node->gport) >> 8);
   1922                  node->hw_index &= 0x7FF;
   1923                  if (info.port_type == _BCM_SUBPORT_COE_TYPE_LINKPHY) {
   1924                    /* linkphy
   1925                     * s0 index = stream_id/num_streams
   1926                     */
   1927                     dev_int_stream_id = info.dev_int_stream_id[0];
   1928 
   1929                     SOC_PBMP_CLEAR(pbmp_linkphy_one_stream_per_subport);
   1930                     pbmp_linkphy_one_stream_per_subport =
   1931                     soc_property_get_pbmp(unit,
   1932                     spn_PBMP_LINKPHY_ONE_STREAM_PER_SUBPORT, 0);
   1933                     BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_node_get(
   1934                                         unit, parent->gport, NULL, &local_port,
   1935                                         NULL, NULL));
   1936                     if (SOC_IS_METROLITE(unit) || (SOC_IS_SABER2(unit) &&
   1937                         SOC_PBMP_MEMBER(pbmp_linkphy_one_stream_per_subport,
   1938                         local_port))) {
   1939                         node->hw_index = dev_int_stream_id;
   1940                     } else if (SOC_IS_SABER2(unit) && (info.num_streams == 1)) {
   1941 
   1942                         /* When num_streams is 1, only 4 subports are supported in SB2 */
   1943                         if ((dev_int_stream_id % 8) > 3) {
   1944                             return BCM_E_PARAM;
   1945                         }
   1946 
   1947                         /* The following is the mapping in S1 when num_streams = 1.
   1948                          *   S1          S0
   1949                          *   0 - 3       0 - 3
   1950                          *   8 - 11      4 - 7
   1951                          *   16 - 19     8 - 11
   1952                          *   24 - 27     12 - 15
   1953                          *
   1954                          * The formula used is (4 * (S1 / 8) + (S1 % 8)).
   1955                          */
   1956                         node->hw_index = (4 * (dev_int_stream_id / 8)) +
   1957                                             (dev_int_stream_id %4);
   1958 
   1959                     } else {
   1960                         node->hw_index = (dev_int_stream_id / info.num_streams);
   1961                     }
   1962                     /* S0 is always WRR */
   1963                     node->wrr_in_use = 1;
   1964 
   1965                 } else
   1966 #if defined BCM_METROLITE_SUPPORT
   1967                 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
   1968                     if (info.port_type == _BCM_SUBPORT_COE_TYPE_SUBTAG) {
   1969                         BCM_IF_ERROR_RETURN
   1970                             (bcm_kt2_subport_pp_port_s1_index_get(unit, pp_port, &node->hw_index));
   1971                         /* S0 is always WRR */
   1972                         node->wrr_in_use = 1;
   1973                     }
   1974                 } else 
   1975 #endif
   1976                 {
   1977                     node->hw_index -= num_port_schedulers[unit];
   1978                 }
   1979                 if (parent->base_index < 0) {
   1980                     parent->base_index = node->hw_index;
   1981                 }
   1982 
   1983                 /*for single stream cases in LINKPhy we donot need to configure S0 as 
   1984                    S1 gets scheduled */
   1985                 if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
   1986                     if (node->hw_index < 128){
   1987                         _bcm_kt2_node_index_set(list, node->hw_index, 1);
   1988                     }
   1989                 } else {
   1990                     _bcm_kt2_node_index_set(list, node->hw_index, 1);
   1991                 }
   1992                 break;
   1993             }
   1994             if (parent->level == _BCM_KT2_COSQ_NODE_LEVEL_S1 &&
   1995                 node->level == _BCM_KT2_COSQ_NODE_LEVEL_L0 &&
   1996                 parent->linkphy_enabled) {
   1997                 /* S1 == L0 incase of linkphy */
   1998                 parent->base_index = parent->hw_index;
   1999                 node->hw_index = parent->hw_index;
   2000                 break;
   2001             }
   2002 
   2003             /* Indexes from 0 to num_s1_schedulers[unit] is used for S1 nodes,
   2004                remaining num_s1_schedulers[unit]++ are used for L0 and S0 */
   2005             start_idx = (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L0) ? 
   2006                          num_s1_schedulers[unit] : 0;
   2007             if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
   2008                 start_idx = 0;
   2009             }
   2010             end_idx = mmu_info->max_nodes[node->level];
   2011             if (node->hw_index > 0) {
   2012             if (parent->base_index < 0) {
   2013                     parent->base_index = node->hw_index;
   2014                 }
   2015             } else {
   2016                 if ( (parent->base_index < 0) && (parent->wrr_mode == 0) ) {
   2017                     rv = _bcm_kt2_node_index_get(unit, list->bits, start_idx, end_idx,
   2018                                                  mmu_info->qset_size, numq, &id);
   2019                     if (BCM_FAILURE(rv)) {
   2020                         _bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2021                                                 node->cosq_attached_to, 1);
   2022                         node->cosq_attached_to = -1;
   2023                         return rv;
   2024                     }
   2025                     _bcm_kt2_node_index_set(list, id, numq);
   2026                     parent->base_index = id;
   2027                 } else if ((node->cosq_attached_to >= numq) || (parent->wrr_mode == 1)) {
   2028                     rv = _bcm_kt2_node_index_get(unit, list->bits, start_idx, end_idx,
   2029                                                  mmu_info->qset_size, 1, &id);
   2030                     if (BCM_FAILURE(rv)) {
   2031                         _bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2032                                                 node->cosq_attached_to, 1);
   2033                         node->cosq_attached_to = -1;
   2034                         return rv;
   2035                     }
   2036                     _bcm_kt2_node_index_set(list, id, 1);
   2037                     if (parent->wrr_mode == 1) {
   2038                         if (parent->base_index < 0 ) {
   2039                             parent->base_index = id;
   2040                         }
   2041                     }
   2042                 }   
   2043             }    
   2044             break;
   2045             
   2046         case _BCM_KT2_COSQ_NODE_LEVEL_S0:
   2047             list = &mmu_info->sched_hw_list[node->level];
   2048             if (parent->linkphy_enabled &&
   2049                         !soc_feature(unit, soc_feature_discontinuous_pp_port)) {
   2050                 BCM_IF_ERROR_RETURN
   2051                   (_bcm_kt2_cosq_subport_get(unit, parent->gport, &pp_port));
   2052                 BCM_IF_ERROR_RETURN
   2053                    (bcm_kt2_subport_pp_port_subport_info_get(unit, pp_port,
   2054                                                 &info));
   2055                 if (node->cosq_attached_to > 1) {
   2056                     return BCM_E_PARAM;
   2057                 }
   2058                 if ((info.num_streams == 1) &&
   2059                     (node->cosq_attached_to > 0)) {
   2060                     _bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2061                                             node->cosq_attached_to, 1);
   2062                     return BCM_E_PARAM;
   2063                 }
   2064                 if (SOC_IS_SABER2(unit) && (info.num_streams == 1)) {
   2065                     node->hw_index = info.dev_int_stream_id[0];
   2066                 } else {
   2067                     node->hw_index = (parent->hw_index * info.num_streams) +
   2068                                     node->cosq_attached_to;
   2069                 }
   2070                 if (parent->base_index < 0) {
   2071                     parent->base_index = node->hw_index;
   2072                 }
   2073                 node->linkphy_enabled = 1;
   2074                 _bcm_kt2_node_index_set(list, node->hw_index, 1);
   2075             } else {
   2076                 if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L0) {
   2077                     return BCM_E_PARAM;
   2078                 }
   2079                 start_idx = num_s1_schedulers[unit];
   2080                 end_idx = mmu_info->max_nodes[node->level];
   2081                 if (node->hw_index > 0) {
   2082                     if (parent->base_index < 0) {
   2083                         parent->base_index = node->hw_index;
   2084                     }
   2085                 } else {
   2086                     if ((parent->base_index < 0) && (parent->wrr_mode == 0)) {
   2087                         rv = _bcm_kt2_node_index_get(unit, list->bits, start_idx, end_idx,
   2088                                                      mmu_info->qset_size, numq, &id);
   2089                         if (BCM_FAILURE(rv)) {
   2090                             _bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2091                                                     node->cosq_attached_to, 1);
   2092                             node->cosq_attached_to = -1;
   2093                             return rv;
   2094                         }
   2095                         _bcm_kt2_node_index_set(list, id, numq);
   2096                         parent->base_index = id;
   2097                     } else if ((node->cosq_attached_to >= numq) || (parent->wrr_mode == 1)) {
   2098                         rv = _bcm_kt2_node_index_get(unit, list->bits, start_idx, end_idx,
   2099                                                      mmu_info->qset_size, 1, &id);
   2100                         if (BCM_FAILURE(rv)) {
   2101                             _bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2102                                                     node->cosq_attached_to, 1);
   2103                             node->cosq_attached_to = -1;
   2104                             return rv;
   2105                         }
   2106                         _bcm_kt2_node_index_set(list, id, 1);
   2107                         if (parent->wrr_mode == 1) {
   2108                             if (parent->base_index < 0 ) {
   2109                                 parent->base_index = id;
   2110                             }
   2111                         }
   2112                     }
   2113                 }
   2114             }
   2115             break;
   2116         
   2117         case _BCM_KT2_COSQ_NODE_LEVEL_L1:
   2118             if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport)) {
   2119                 list = &mmu_info->l2_base_qlist;
   2120                 local_port = BCM_GPORT_UCAST_QUEUE_GROUP_SYSPORTID_GET
   2121                                                          (node->gport);
   2122                 offset = mmu_info->port[local_port].q_offset;
   2123                 limit =  mmu_info->port[local_port].q_limit;
   2124             } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport)) {
   2125                 list = &mmu_info->l2_base_mcqlist;
   2126                 local_port = BCM_GPORT_MCAST_QUEUE_GROUP_SYSPORTID_GET
   2127                                                          (node->gport);
   2128                 if (soc_feature(unit, soc_feature_mmu_packing)) {
   2129                     offset = mmu_info->port[local_port].mcq_offset;
   2130                     limit =  mmu_info->port[local_port].mcq_limit;
   2131                 } 
   2132                 else { 
   2133                          offset = mmu_info->port[local_port].q_offset;
   2134                          limit =  mmu_info->port[local_port].q_limit;
   2135                 }     
   2136             } else if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(node->gport)) {
   2137                 local_port = BCM_GPORT_DESTMOD_QUEUE_GROUP_SYSPORTID_GET
   2138                                                          (node->gport);
   2139                 offset = 0;
   2140                 if (mmu_info->num_dmvoq_queues > 0) {
   2141                     list = &mmu_info->l2_dmvoq_qlist;
   2142                     limit = mmu_info->num_dmvoq_queues;
   2143                 } else {
   2144                     list = &mmu_info->l2_global_qlist;
   2145                     limit = mmu_info->num_queues;
   2146                 }
   2147             } else if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport) ||
   2148                        BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) {
   2149                 local_port =
   2150                    ((BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) ?
   2151                      BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_SYSPORTID_GET
   2152                       (node->gport):
   2153                      BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_SYSPORTID_GET
   2154                       (node->gport));
   2155                 offset = 0;
   2156                 if (mmu_info->num_sub_queues > 0) {
   2157                     if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) {
   2158                         list = &mmu_info->l2_sub_qlist;
   2159                     } else {
   2160                         list = &mmu_info->l2_sub_mcqlist;
   2161                     }
   2162                     limit = mmu_info->num_sub_queues;
   2163                 } else {
   2164                     list = &mmu_info->l2_global_qlist;
   2165                     limit = mmu_info->num_queues;
   2166                 }
   2167             } else {
   2168                 list = &mmu_info->l2_global_qlist;
   2169                 offset = 0;
   2170                 limit = mmu_info->num_queues;
   2171             }
   2172             if (node->hw_index < 0) {    
   2173                 if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport) && 
   2174                     parent->mc_base_index < 0 && 
   2175                     node->cosq_attached_to < 8) {
   2176                     rv = _bcm_kt2_node_index_get(unit, list->bits, offset, limit,
   2177                                             mmu_info->qset_size, numq, &id);
   2178                     if (BCM_FAILURE(rv)) {
   2179                         _bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2180                                                 node->cosq_attached_to, 1);
   2181                         node->cosq_attached_to = -1;
   2182                         return rv;
   2183                     }
   2184                     _bcm_kt2_node_index_set(list, id, numq);
   2185                     parent->mc_base_index = id;
   2186                     node->mc_base_index = parent->mc_base_index;  
   2187                 } else if ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport)) &&
   2188                        parent->base_index < 0 && 
   2189                        node->cosq_attached_to < 8) {
   2190                     rv = _bcm_kt2_node_index_get(unit, list->bits, offset, limit,
   2191                                             mmu_info->qset_size, numq, &id);
   2192                     if (BCM_FAILURE(rv)) {
   2193                         _bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2194                                                 node->cosq_attached_to, 1);
   2195                         node->cosq_attached_to = -1;
   2196                         return rv;
   2197                     }
   2198                     _bcm_kt2_node_index_set(list, id, numq);
   2199                     parent->base_index = id ;
   2200                     node->base_index = parent->base_index;  
   2201                 } else if ((BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) &&
   2202                            (((parent->base_index < 0) &&
   2203                            (node->cosq_attached_to < 8)) || parent->wrr_mode == 1)) {
   2204                     rv = _bcm_kt2_node_index_get(unit, list->bits, offset, limit,
   2205                                                  mmu_info->qset_size, numq, &id);
   2206                     if (BCM_FAILURE(rv)) {
   2207                         _bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2208                                                 node->cosq_attached_to, 1);
   2209                         node->cosq_attached_to = -1;
   2210                         return rv;
   2211                     }
   2212 
   2213                     _bcm_kt2_node_index_set(list, id, numq);
   2214                     if (mmu_info->num_sub_queues > 0) {
   2215                         parent->base_index = id + mmu_info->base_sub_queue ;
   2216                     } else {
   2217                         parent->base_index = id  ;
   2218                     }
   2219                     node->base_index = parent->base_index;
   2220                 } else if (
   2221                      (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) &&
   2222                      (((parent->mc_base_index < 0) &&
   2223                      (node->cosq_attached_to < 8)) || parent->wrr_mode == 1)) {
   2224                     rv = _bcm_kt2_node_index_get(unit, list->bits, offset, limit,
   2225                                                  mmu_info->qset_size, numq, &id);
   2226                     if (BCM_FAILURE(rv)) {
   2227                         _bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2228                                                 node->cosq_attached_to, 1);
   2229                         node->cosq_attached_to = -1;
   2230                         return rv;
   2231                     }
   2232 
   2233                     _bcm_kt2_node_index_set(list, id, numq);
   2234                     if (mmu_info->num_sub_queues > 0) {
   2235                         parent->mc_base_index = id + mmu_info->base_sub_queue ;
   2236                     } else {
   2237                         parent->mc_base_index = id; 
   2238                     }
   2239                     node->mc_base_index = parent->mc_base_index;
   2240                 } else if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(node->gport) && 
   2241                        (( parent->base_index < 0 && 
   2242                         node->cosq_attached_to < 8) || parent->wrr_mode == 1)) {
   2243                     rv = _bcm_kt2_node_index_get(unit, list->bits, offset, limit,
   2244                                                  mmu_info->qset_size, numq, &id);
   2245                     if (BCM_FAILURE(rv)) {
   2246                         _bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2247                                                 node->cosq_attached_to, 1);
   2248                         node->cosq_attached_to = -1;
   2249                         return rv;
   2250                     }
   2251                     if (((mmu_info->base_dmvoq_queue + id) % 8) != 0) {
   2252                         BCM_IF_ERROR_RETURN
   2253                             (_bcm_kt2_cosq_get_dmvoq_index(unit, mmu_info, list,
   2254                                                            numq, &id, limit)); 
   2255                     }
   2256                     _bcm_kt2_node_index_set(list, id, numq);
   2257                     if  (mmu_info->num_dmvoq_queues > 0) { 
   2258                         parent->base_index = id + mmu_info->base_dmvoq_queue ;
   2259                     } else {
   2260                         parent->base_index = id ;
   2261                     }
   2262                     node->base_index = parent->base_index;  
   2263                 } else if (node->cosq_attached_to >= 8) {
   2264                     rv = _bcm_kt2_node_index_get(unit, list->bits, offset, limit,
   2265                                            mmu_info->qset_size, 1, &id);
   2266                     if (BCM_FAILURE(rv)) {
   2267                         _bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2268                                                 node->cosq_attached_to, 1);
   2269                         node->cosq_attached_to = -1;
   2270                         return rv;
   2271                     }
   2272                     if (node->type == _BCM_KT2_NODE_VOQ) {
   2273                         return BCM_E_PARAM; 
   2274                     }
   2275                     _bcm_kt2_node_index_set(list, id, 1);                
   2276                 }
   2277                 if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport) ||
   2278                     BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) {
   2279                     if (mmu_info->num_sub_queues > 0 ) {
   2280                         id += mmu_info->base_sub_queue;
   2281                     } 
   2282                 }
   2283             } else {
   2284                 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport) ||
   2285                     BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport) ||
   2286                     BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(node->gport) ||
   2287                     BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport) ||
   2288                     BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) {
   2289                     /*input 0 should be atttached first to get the correct base*/
   2290                     if (node->cosq_attached_to < 8) {
   2291                         if ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport) ||
   2292                              BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(node->gport) ||
   2293                              BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) &&
   2294                              (parent->base_index < 0)) {
   2295                             parent->base_index = node->hw_index;
   2296                         }    
   2297                         if ((BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport)  ||
   2298                              BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) &&
   2299                              (parent->mc_base_index < 0)) {
   2300                             parent->mc_base_index = node->hw_index;
   2301                         }
   2302                     }
   2303                     
   2304                 } 
   2305             }
   2306             break;
   2307 
   2308         case _BCM_KT2_COSQ_NODE_LEVEL_L2:
   2309             /* passthru */
   2310         default:
   2311             return BCM_E_PARAM;
   2312 
   2313     }
   2314 
   2315     if (parent->numq <= 8) {
   2316         if (parent->level <= _BCM_KT2_COSQ_NODE_LEVEL_L1) {
   2317             if (node->hw_index < 0) {
   2318                 base_idx = 
   2319                       (BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport) ||
   2320                        BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) ?
   2321                             parent->mc_base_index : parent->base_index;
   2322                 node->hw_index = (parent->wrr_mode == 1) ? id : base_idx + node->cosq_attached_to;
   2323             }    
   2324         }
   2325 
   2326         parent->num_child++;
   2327         /* get the lowest cosq as a first child */
   2328         if (node->hw_index < parent->first_child) {
   2329             parent->first_child = node->hw_index;
   2330         }
   2331     } else {
   2332         if (parent->level <= _BCM_KT2_COSQ_NODE_LEVEL_L1) {
   2333             if (node->hw_index < 0) {
   2334                 base_idx = (BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport) ||
   2335                             BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) ?
   2336                             parent->mc_base_index : parent->base_index;
   2337                 node->hw_index = (node->cosq_attached_to < numq) ? 
   2338                     (base_idx + node->cosq_attached_to) : id;
   2339             }
   2340             if (node->cosq_attached_to >= numq) {
   2341                 node->wrr_in_use = 1;
   2342             }    
   2343         }
   2344         parent->num_child++;
   2345     }
   2346 
   2347     return BCM_E_NONE;
   2348 }
   2349 
   2350 /*
   2351  * Function:
   2352  *     _bcm_kt2_cosq_node_unresolve
   2353  * Purpose:
   2354  *     Unresolve queue number in the specified scheduler tree and its subtree
   2355  * Parameters:
   2356  *     unit       - (IN) unit number
   2357  *     node       - (IN) node structure for the specified scheduler node
   2358  *     cosq       - (IN) COS queue to attach to
   2359  * Returns:
   2360  *     BCM_E_XXX
   2361  */
   2362 STATIC int
   2363 _bcm_kt2_cosq_node_unresolve(int unit, _bcm_kt2_cosq_node_t *node, 
   2364                              bcm_cos_queue_t cosq)
   2365 {
   2366     _bcm_kt2_cosq_node_t *cur_node, *parent;
   2367     _bcm_kt2_mmu_info_t *mmu_info;
   2368     _bcm_kt2_cosq_list_t *list;
   2369     uint32 map;
   2370     int min_index;
   2371     int id, offset, numq;
   2372     int min_flag = 0;
   2373 
   2374     if (node->cosq_attached_to < 0) {
   2375         /* Has been unresolved already */
   2376         return BCM_E_NONE;
   2377     }
   2378 
   2379     parent = node->parent;
   2380 
   2381     if (parent->numq == 0 || parent->numq < -1) {
   2382         return BCM_E_PARAM;
   2383     }
   2384 
   2385     if (parent->numq <= 8) {
   2386          /* find the current cosq_attached_to usage */
   2387         map = 0;
   2388         if (parent->first_child == node->hw_index && node->wrr_in_use == 0) {
   2389             min_flag = 1;
   2390             min_index = (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L2) ? 4095 :
   2391                         ((node->level == _BCM_KT2_COSQ_NODE_LEVEL_L1) ? 1023 :
   2392                           255);
   2393         } else {
   2394             min_index = parent->first_child;
   2395         }
   2396 
   2397         for (cur_node = parent->child; cur_node != NULL;
   2398             cur_node = cur_node->sibling) {
   2399             if (cur_node->cosq_attached_to >= 0) {
   2400                 map |= 1 << cur_node->cosq_attached_to;
   2401                 /* dont update the min node is not this node */
   2402                 if (min_flag && cur_node->hw_index != node->hw_index) {
   2403                 if (cur_node->hw_index < min_index) {
   2404                     min_index = cur_node->hw_index;
   2405                 }
   2406                }
   2407             }
   2408         }
   2409 
   2410         if (!(map & (1 << node->cosq_attached_to))) {
   2411             return BCM_E_PARAM;
   2412         }
   2413 
   2414         BCM_IF_ERROR_RETURN
   2415             (_bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2416              node->cosq_attached_to, 1));
   2417         parent->first_child = min_index;
   2418 
   2419     } else {
   2420 
   2421         /* check whether the entry is available */
   2422         for (cur_node = parent->child; cur_node != NULL;
   2423             cur_node = cur_node->sibling) {
   2424             if (cur_node->gport == node->gport) {
   2425                 break;
   2426             }
   2427         }
   2428 
   2429         if (cur_node == NULL) {
   2430             return BCM_E_PARAM;
   2431         }
   2432         BCM_IF_ERROR_RETURN
   2433             (_bcm_kt2_cosq_map_index_clear(parent->cosq_map,
   2434              cur_node->cosq_attached_to, 1));
   2435     }
   2436 
   2437     mmu_info = _bcm_kt2_mmu_info[unit];
   2438     numq = (parent->wrr_mode == 0) ? ((parent->numq > 8) ? 8 : parent->numq) : 1;
   2439 
   2440     switch (parent->level) {
   2441         case _BCM_KT2_COSQ_NODE_LEVEL_ROOT:
   2442         case _BCM_KT2_COSQ_NODE_LEVEL_S0:
   2443         case _BCM_KT2_COSQ_NODE_LEVEL_S1:
   2444         case _BCM_KT2_COSQ_NODE_LEVEL_L0:    
   2445             list = &mmu_info->sched_hw_list[node->level];
   2446             parent->num_child--;
   2447             if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_S0) && 
   2448                 (parent->num_child >= 0)) {
   2449                 if (node->cosq_attached_to >= numq) {
   2450                     _bcm_kt2_node_index_clear(list, node->hw_index, 1);
   2451                 }
   2452                 if (parent->num_child == 0 &&
   2453                     parent->base_index >= 0) {
   2454                     /* release contiguous queue ids */
   2455                     _bcm_kt2_node_index_clear(list, parent->base_index, numq);
   2456                     parent->base_index = -1;
   2457                 }    
   2458             } 
   2459             if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
   2460                 if ( node->hw_index < 128) { 
   2461                     _bcm_kt2_node_index_clear(list, node->hw_index, 1);
   2462                 }
   2463             }
   2464             break;
   2465             
   2466         case _BCM_KT2_COSQ_NODE_LEVEL_L1:
   2467             if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport)) {
   2468                 list = &mmu_info->l2_base_qlist;
   2469                 offset = 0;
   2470             } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport)) {
   2471                 list = &mmu_info->l2_base_mcqlist;
   2472                 offset = 0;
   2473             } else if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(node->gport) 
   2474                     && (mmu_info->num_dmvoq_queues > 0)) {
   2475                 list = &mmu_info->l2_dmvoq_qlist;
   2476                 offset = mmu_info->base_dmvoq_queue;
   2477             } else if ((BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport) ||
   2478                         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport))
   2479                     && (mmu_info->num_sub_queues > 0)) {
   2480                 if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) {
   2481                     list = &mmu_info->l2_sub_qlist;
   2482                     offset = mmu_info->base_sub_queue;
   2483                 } else {
   2484                     list = &mmu_info->l2_sub_mcqlist;
   2485                     offset = mmu_info->base_sub_queue + mmu_info->num_queues/2;
   2486                 }
   2487             } else {
   2488                 list = &mmu_info->l2_global_qlist;
   2489                 offset = 0 ; 
   2490             }            
   2491 
   2492             parent->num_child--;
   2493             id = node->hw_index - offset;
   2494             if (parent->num_child >= 0) {
   2495                 if (node->cosq_attached_to >= 8) {
   2496                     _bcm_kt2_node_index_clear(list, id, 1);
   2497                 }
   2498                 if (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) {
   2499                     if (parent->num_child == 0 &&
   2500                         parent->mc_base_index >= 0) {
   2501                         /* release contiguous queue ids */
   2502                         id = parent->mc_base_index - offset;
   2503                         _bcm_kt2_node_index_clear(list, id, numq);
   2504                         parent->mc_base_index = -1;
   2505                     }
   2506                 } else {
   2507                     if (parent->num_child == 0 &&
   2508                         parent->base_index >= 0) {
   2509                         /* release contiguous queue ids */
   2510                         id = parent->base_index - offset;
   2511                         _bcm_kt2_node_index_clear(list, id, numq);
   2512                         parent->base_index = -1;
   2513                     }
   2514                 }
   2515             }
   2516             break;
   2517 
   2518         case _BCM_KT2_COSQ_NODE_LEVEL_L2:
   2519             /* passthru */
   2520         default:
   2521             return BCM_E_PARAM;
   2522 
   2523     }
   2524 
   2525     return BCM_E_NONE;
   2526 }
   2527 
   2528 /*
   2529  * Function:
   2530  *     _bcm_kt2_cosq_valid_dynamic_request
   2531  * Purpose:
   2532  *     Validate the new dynamic request
   2533  * Parameters:
   2534  *     unit       - (IN) unit number
   2535  *     port      - (IN) port
   2536  *     level      - (IN) scheduler level
   2537  *     node_id    - (IN) node index
   2538  *     parent_id  - (IN) parent index
   2539  *     rval        - (IN) dynamic reg value
   2540  * Returns:
   2541  *     BCM_E_XXX
   2542  */
   2543 
   2544 STATIC int
   2545 _bcm_kt2_cosq_valid_dynamic_request(int unit, bcm_port_t port, int node_level, 
   2546                                    int node_id, int parent_id, uint32 rval) 
   2547 {
   2548     soc_reg_t dyn_reg = LLS_SP_WERR_DYN_CHANGE_0Ar;
   2549     lls_l0_parent_entry_t l0_parent;
   2550     lls_l1_parent_entry_t l1_parent;
   2551     bcm_port_t req_port, req_parent;
   2552 
   2553     /* dont allow more than one req per parent  */
   2554     req_parent = soc_reg_field_get(unit, dyn_reg, rval, PARENT_IDf);
   2555     if ((node_level == soc_reg_field_get(unit, dyn_reg, rval, NODE_LEVELf)) &&
   2556         (parent_id == req_parent)) {
   2557         return FALSE;
   2558     }
   2559 
   2560     switch (node_level) {
   2561         case _BCM_KT2_COSQ_NODE_LEVEL_L0:
   2562             req_port = parent_id;
   2563             break;
   2564         case _BCM_KT2_COSQ_NODE_LEVEL_L1:
   2565             SOC_IF_ERROR_RETURN
   2566                 (READ_LLS_L0_PARENTm(unit, MEM_BLOCK_ALL, req_parent,
   2567                                      &l0_parent));
   2568             req_port = soc_mem_field32_get(unit, LLS_L0_PARENTm, &l0_parent, 
   2569                                            C_PARENTf); 
   2570             break;
   2571         case _BCM_KT2_COSQ_NODE_LEVEL_L2:
   2572             SOC_IF_ERROR_RETURN
   2573                 (READ_LLS_L1_PARENTm(unit, MEM_BLOCK_ALL, req_parent,
   2574                                      &l1_parent));
   2575             req_port = soc_mem_field32_get(unit, LLS_L1_PARENTm, &l1_parent, 
   2576                                            C_PARENTf); 
   2577             SOC_IF_ERROR_RETURN
   2578                 (READ_LLS_L0_PARENTm(unit, MEM_BLOCK_ALL, req_port,
   2579                                      &l0_parent));
   2580             req_port = soc_mem_field32_get(unit, LLS_L0_PARENTm, &l0_parent, 
   2581                                            C_PARENTf);    
   2582             break;
   2583         default:
   2584             return FALSE;
   2585     }
   2586 
   2587     /* dont allow more than one req per port */
   2588     if (port == req_port) {
   2589         return FALSE;
   2590     }    
   2591     return TRUE;
   2592 }
   2593 
   2594 /*
   2595  * Function:
   2596  *     _bcm_kt2_cosq_dynamic_sp_werr_change
   2597  * Purpose:
   2598  *     Set LLS dynamic scheduler registers based on level and hw index
   2599  * Parameters:
   2600  *     unit       - (IN) unit number
   2601  *     level      - (IN) scheduler level
   2602  *     node_id    - (IN) node index
   2603  *     parent_id  - (IN) parent index
   2604  *     config       - (IN) config details
   2605  * Returns:
   2606  *     BCM_E_XXX
   2607  */
   2608 STATIC int
   2609 _bcm_kt2_cosq_dynamic_sp_werr_change(int unit, bcm_port_t port, int node_level, 
   2610                                     int node_id, int parent_id, uint32 *config,
   2611                                     _bcm_kt2_cosq_state_t state)
   2612 {
   2613     soc_timeout_t timeout;
   2614     uint32 timeout_val, rval;
   2615     int i, in_use;
   2616     soc_reg_t dyn_reg_a, dyn_reg_b, dyn_reg_c;
   2617     uint32 entry_b, entry_c;
   2618     lls_l0_parent_entry_t l0_parent;
   2619     int packing_mode = 0, abort;
   2620     
   2621     soc_reg_t dyn_change_a[] = 
   2622         {
   2623         LLS_SP_WERR_DYN_CHANGE_0Ar,
   2624         LLS_SP_WERR_DYN_CHANGE_1Ar,
   2625         LLS_SP_WERR_DYN_CHANGE_2Ar,
   2626         LLS_SP_WERR_DYN_CHANGE_3Ar
   2627         };
   2628     soc_reg_t dyn_change_b[] = 
   2629         {
   2630         LLS_SP_WERR_DYN_CHANGE_0Br,
   2631         LLS_SP_WERR_DYN_CHANGE_1Br,
   2632         LLS_SP_WERR_DYN_CHANGE_2Br,
   2633         LLS_SP_WERR_DYN_CHANGE_3Br
   2634         };
   2635     soc_reg_t dyn_change_c[] = 
   2636         {
   2637         LLS_SP_WERR_DYN_CHANGE_0Cr,
   2638         LLS_SP_WERR_DYN_CHANGE_1Cr,
   2639         LLS_SP_WERR_DYN_CHANGE_2Cr,
   2640         LLS_SP_WERR_DYN_CHANGE_3Cr
   2641         };
   2642 
   2643 
   2644     /* New value for the node_ids parent config bits 41:32
   2645      * to be programmed into dynamic change register
   2646      * LLS_SP_WERR_DYN_CHANGE_XB
   2647      */
   2648     if (SOC_IS_METROLITE(unit)) {
   2649         entry_b = (config[1] & _BCM_ML_LLS_DYN_CHG_REG_B);
   2650     } else if (SOC_IS_SABER2(unit)) {
   2651         entry_b = (config[1] & _BCM_SB2_LLS_DYN_CHG_REG_B);
   2652     } else {
   2653         entry_b = (config[1] & _BCM_KT2_LLS_DYN_CHG_REG_B);
   2654     }
   2655 
   2656     /* New value for the node_ids parent config bits 31:0.
   2657      * to be programmed into dynamic change register 
   2658      * LLS_SP_WERR_DYN_CHANGE_XC
   2659      */
   2660     entry_c = (config[0] & _BCM_KT2_LLS_DYN_CHG_REG_C);
   2661 
   2662     /* Get one of the free register to place the request */    
   2663     for (i = 0; i < 4; i++) {
   2664         dyn_reg_a =  dyn_change_a[i];
   2665         dyn_reg_b =  dyn_change_b[i];
   2666         dyn_reg_c =  dyn_change_c[i];
   2667         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, dyn_reg_a, REG_PORT_ANY, 
   2668                                           0, &rval));
   2669         if (SAL_BOOT_SIMULATION) {
   2670             break;
   2671         }    
   2672         
   2673         if (soc_reg_field_get(unit, dyn_reg_a, rval, IN_USEf) == 0) {
   2674             break;
   2675         } else {
   2676         /* verify any other req pending from this port or same parent */
   2677             if (_bcm_kt2_cosq_valid_dynamic_request(unit, port, node_level, 
   2678                      node_id, parent_id, rval) == FALSE) {
   2679                 return BCM_E_UNAVAIL;     
   2680             }                                                     
   2681         }
   2682     }    
   2683 
   2684     if (i == 4) {
   2685         /* None of the registers are available */
   2686         return BCM_E_UNAVAIL;
   2687     }    
   2688 
   2689     rval = 0 ;
   2690     /* subtract 2 due to addional level of s0 and s1 */
   2691     soc_reg_field_set(unit, dyn_reg_a, &rval, NODE_LEVELf, (node_level - 2));
   2692     soc_reg_field_set(unit, dyn_reg_a, &rval, NODE_IDf, node_id);
   2693     soc_reg_field_set(unit, dyn_reg_a, &rval, IN_USEf, 1);
   2694     if (node_level == _BCM_KT2_COSQ_NODE_LEVEL_L0) {
   2695         SOC_IF_ERROR_RETURN
   2696             (READ_LLS_L0_PARENTm(unit, MEM_BLOCK_ALL, node_id,
   2697                                  &l0_parent));
   2698         if (soc_mem_field32_get(unit, LLS_L0_PARENTm,
   2699                                 &l0_parent, C_TYPEf) == 1) {
   2700             if (SOC_IS_METROLITE(unit)) {
   2701                 /*
   2702                  * For Ports, set parent_id[6:5] = 0x1,
   2703                  * set parent_id[5:0] = {1b0, port_id[3:0]}.
   2704                  */
   2705                 parent_id = ((0x1 << 5) | (parent_id & 0xF));
   2706             } else if (SOC_IS_SABER2(unit)) {
   2707                 /* 
   2708                    For Ports, set parent_id[7:6] = 0x1, 
   2709                    set parent_id[5:0] = {1b0, port_id[4:0]}.
   2710                  */
   2711                 parent_id = ((0x1 << 6) | (parent_id & 0x1F));
   2712             } else if (SOC_IS_KATANA2(unit)) {
   2713                 /* 
   2714                    For Ports, set parent_id[9:7] = 0x2, 
   2715                    set parent_id[6:0] = {1b0, port_id[5:0]}.
   2716                  */
   2717                 parent_id = ((0x2 << 7) | (parent_id & 0x3F));
   2718             }
   2719         }
   2720     }
   2721     soc_reg_field_set(unit, dyn_reg_a, &rval, PARENT_IDf, parent_id);
   2722 
   2723     /* Write DYN_CHANGE_XB register first */
   2724     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, dyn_reg_c, REG_PORT_ANY, 
   2725                                       0, entry_c));
   2726     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, dyn_reg_b, REG_PORT_ANY, 
   2727                                       0, entry_b));
   2728     /* Write DYN_CHANGE_XA register next. this triggers the request */
   2729     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, dyn_reg_a, REG_PORT_ANY, 
   2730                                       0, rval));
   2731     if (SAL_BOOT_SIMULATION) {
   2732         return BCM_E_NONE;
   2733     }
   2734     
   2735     in_use = 1;
   2736     if (soc_feature(unit, soc_feature_mmu_packing)) {
   2737         BCM_IF_ERROR_RETURN
   2738         (_bcm_kt2_cosq_packing_mode_get(unit, node_id, &packing_mode));
   2739         
   2740     }
   2741     if (packing_mode == 1) {
   2742         timeout_val = soc_property_get(unit, spn_MMU_QUEUE_FLUSH_TIMEOUT, 
   2743                                 _BCM_COSQ_QUEUE_FLUSH_TIMEOUT_PACKING_DEFAULT);
   2744     } else {
   2745 
   2746         timeout_val = soc_property_get(unit, spn_MMU_QUEUE_FLUSH_TIMEOUT, 
   2747                                     _BCM_COSQ_QUEUE_FLUSH_TIMEOUT_DEFAULT);
   2748     }
   2749     soc_timeout_init(&timeout, timeout_val, 0);
   2750 
   2751     while (in_use) {                              
   2752         SOC_IF_ERROR_RETURN
   2753             (soc_reg32_get(unit, dyn_reg_a, REG_PORT_ANY, 0, &rval)); 
   2754         in_use = soc_reg_field_get(unit, dyn_reg_a, rval, IN_USEf);
   2755         if (in_use && soc_timeout_check(&timeout)) {
   2756             LOG_ERROR(BSL_LS_BCM_COMMON,
   2757                       (BSL_META_U(unit,
   2758                                   "ERROR: dynamic sp <-> werr change operation failed \n")));
   2759             LOG_ERROR(BSL_LS_BCM_COMMON,
   2760                       (BSL_META_U(unit,
   2761                                   " node_level %d node_id %d parent_id %d \n"), 
   2762                        node_level, node_id, parent_id));
   2763             soc_reg_field_set(unit, dyn_reg_a, &rval, IN_USEf, 0);
   2764             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, dyn_reg_a, REG_PORT_ANY, 
   2765                                 0, rval));
   2766             abort = 0;
   2767             if (packing_mode == 1) {
   2768                 timeout_val = soc_property_get(unit, spn_MMU_QUEUE_FLUSH_TIMEOUT, 
   2769                                         _BCM_COSQ_QUEUE_FLUSH_TIMEOUT_PACKING_DEFAULT);
   2770             } else {
   2771 
   2772                 timeout_val = soc_property_get(unit, spn_MMU_QUEUE_FLUSH_TIMEOUT, 
   2773                                             _BCM_COSQ_QUEUE_FLUSH_TIMEOUT_DEFAULT);
   2774             }
   2775             soc_timeout_init(&timeout, timeout_val, 0);
   2776             while (!abort) {
   2777                 SOC_IF_ERROR_RETURN
   2778                     (soc_reg32_get(unit, dyn_reg_a, REG_PORT_ANY, 0, &rval)); 
   2779                 /* ABORT_BEFORE_COMPLETE would be set by hw if operation is aborted */
   2780                 abort = soc_reg_field_get(unit, dyn_reg_a, rval, ABORT_BEFORE_COMPLETEf);
   2781                 if (abort) {
   2782                     soc_reg_field_set(unit, dyn_reg_a, &rval, ABORT_BEFORE_COMPLETEf, 0);
   2783                     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, dyn_reg_a, REG_PORT_ANY, 
   2784                                         0, rval));
   2785                     break;
   2786                 }
   2787                 if (soc_timeout_check(&timeout)) { 
   2788                     return BCM_E_TIMEOUT;
   2789                 }
   2790             }
   2791             return BCM_E_TIMEOUT;
   2792          }
   2793     }
   2794 
   2795     return BCM_E_NONE;
   2796 }
   2797 
   2798 int
   2799 _bcm_kt2_cosq_subport_get(int unit, bcm_gport_t sched_gport,
   2800                           int *pp_port)
   2801 {
   2802     int rv = BCM_E_NOT_FOUND;
   2803     bcm_cos_queue_t cosq;
   2804     bcm_gport_t gport;
   2805     _bcm_kt2_cosq_node_t *node;
   2806     int encap_id = 0;
   2807     bcm_gport_t input_gport;
   2808 
   2809     gport = sched_gport; 
   2810     BCM_IF_ERROR_RETURN
   2811         (_bcm_kt2_cosq_node_get(unit, gport, NULL, NULL, NULL,
   2812                                &node));
   2813 
   2814     while (node->level != _BCM_KT2_COSQ_NODE_LEVEL_ROOT) {
   2815         BCM_IF_ERROR_RETURN
   2816         (bcm_kt2_cosq_gport_attach_get(unit, gport, &input_gport, &cosq));
   2817         gport = input_gport;
   2818         if (BCM_GPORT_IS_SCHEDULER(gport)) {
   2819             encap_id = (BCM_GPORT_SCHEDULER_GET(node->gport) >> 8) & 0x7ff;
   2820             if (node->subport_enabled == 1) {
   2821                 *pp_port = encap_id;
   2822                 /*BCM_GPORT_SUBPORT_PORT_SET(*input_gport, encap_id);*/
   2823                 rv = BCM_E_NONE;
   2824                 break;
   2825             }
   2826         }
   2827         BCM_IF_ERROR_RETURN
   2828         (_bcm_kt2_cosq_node_get(unit, gport, NULL, NULL, NULL,
   2829                                &node));
   2830     }
   2831 #if defined BCM_METROLITE_SUPPORT
   2832     if ((rv == BCM_E_NONE) && 
   2833                soc_feature(unit, soc_feature_discontinuous_pp_port)) {
   2834         if (*pp_port > SOC_INFO(unit).cpu_hg_pp_port_index) {
   2835             *pp_port -= SOC_INFO(unit).cpu_hg_pp_port_index;
   2836         }
   2837     }
   2838 #endif
   2839 
   2840     return rv;
   2841 }
   2842 
   2843 int
   2844 _bcm_kt2_cosq_packing_mode_get(int unit, int index, int *set)
   2845 {
   2846     mmu_toq_qpack_mode_entry_t qpack_entry;
   2847     uint32 mode = 0;
   2848     
   2849     /* MMU_TOQ_QPACK_MODE register not present on Saber_2 */
   2850     if (SOC_IS_SABER2(unit)) {
   2851         return BCM_E_NONE;
   2852     }
   2853     SOC_IF_ERROR_RETURN
   2854         (READ_MMU_TOQ_QPACK_MODEm(unit, MEM_BLOCK_ALL, 
   2855                                   index/16, &qpack_entry));
   2856     soc_mem_field_get(unit, MMU_TOQ_QPACK_MODEm,
   2857                       (uint32 *)&qpack_entry,
   2858                       QMODEf, &mode);
   2859 
   2860     *set = (mode & (1 << (index % 16))) ? 1 : 0;
   2861     return BCM_E_NONE;
   2862 }
   2863 
   2864 int
   2865 _bcm_kt2_cosq_packing_mode_set(int unit, int index, int set)
   2866 {
   2867     int rv = BCM_E_NONE;
   2868     mmu_toq_qpack_mode_entry_t qpack_entry;
   2869     uint32 mode = 0;
   2870     
   2871     /* MMU_TOQ_QPACK_MODE register not present on Saber_2 */ 
   2872     if (SOC_IS_SABER2(unit)) {
   2873         return BCM_E_NONE;
   2874     }
   2875     SOC_IF_ERROR_RETURN
   2876         (READ_MMU_TOQ_QPACK_MODEm(unit, MEM_BLOCK_ALL, 
   2877                                   index/16, &qpack_entry));
   2878     soc_mem_field_get(unit, MMU_TOQ_QPACK_MODEm,
   2879                       (uint32 *)&qpack_entry,
   2880                       QMODEf, &mode);
   2881     if (set) {
   2882         mode |= (1 << (index % 16));
   2883     } else {
   2884         mode &= ~(1 << (index % 16));
   2885     }
   2886 
   2887     soc_mem_field32_set(unit, MMU_TOQ_QPACK_MODEm, 
   2888                         &qpack_entry, QMODEf, mode);           
   2889     SOC_IF_ERROR_RETURN
   2890         (WRITE_MMU_TOQ_QPACK_MODEm(unit, MEM_BLOCK_ALL, 
   2891                                    index/16, &qpack_entry));
   2892 
   2893     return rv;
   2894 }
   2895 
   2896 STATIC 
   2897 int _bcm_kt2_cosq_flush_queues(int unit, 
   2898                                bcm_port_t port,
   2899                                _bcm_kt2_cosq_node_t *node, 
   2900                                bcm_gport_t gport)
   2901 {
   2902    int flush_active = 0;
   2903    uint32 rval = 0; 
   2904    uint32 timeout_val = 0;
   2905    soc_timeout_t timeout;
   2906 
   2907    /* flush the queue  */
   2908    if (!(SAL_BOOT_SIMULATION)) {
   2909        BCM_IF_ERROR_RETURN(READ_TOQ_FLUSH0r(unit, &rval)); 
   2910        flush_active = soc_reg_field_get(unit, TOQ_FLUSH0r, rval, FLUSH_ACTIVEf);
   2911        if (flush_active == 1) {
   2912            /* some other queue is in flush state, return failure */
   2913            LOG_ERROR(BSL_LS_BCM_COMMON,
   2914                      (BSL_META_U(unit,
   2915                                  "ERROR: Queue %d is already in flush state \n"),
   2916                       (soc_reg_field_get(unit, TOQ_FLUSH0r, rval, FLUSH_ID0f))));
   2917            return BCM_E_BUSY;  
   2918        }
   2919        soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_TYPEf, 0);
   2920        soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_ID0f, node->hw_index);
   2921        soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_NUMf, 1);
   2922        soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_ACTIVEf, 1);
   2923        if (IS_EXT_MEM_PORT(unit, port)) {
   2924            soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_EXTERNALf, 1);
   2925        } else {
   2926 	       if (soc_reg_field_valid(unit, TOQ_FLUSH0r, FLUSH_EXTERNALf)){
   2927 	           soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_EXTERNALf, 0);
   2928 	       }
   2929        }
   2930        BCM_IF_ERROR_RETURN(WRITE_TOQ_FLUSH0r(unit, rval)); 
   2931        flush_active = 1;
   2932        timeout_val = soc_property_get(unit, spn_MMU_QUEUE_FLUSH_TIMEOUT, 
   2933                                        20000);
   2934        soc_timeout_init(&timeout, timeout_val, 0);
   2935 
   2936        while (flush_active) {                              
   2937               BCM_IF_ERROR_RETURN (READ_TOQ_FLUSH0r(unit, &rval)); 
   2938               flush_active = soc_reg_field_get(unit, TOQ_FLUSH0r, rval, 
   2939                                                FLUSH_ACTIVEf);
   2940               if (soc_timeout_check(&timeout)) {
   2941                   BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_adjust_lls_bw(unit, gport, 
   2942                                                                   node));
   2943                   BCM_IF_ERROR_RETURN(READ_TOQ_FLUSH0r(unit, &rval)); 
   2944                   flush_active = soc_reg_field_get(unit, TOQ_FLUSH0r, 
   2945                                                    rval, FLUSH_ACTIVEf);
   2946                   if (flush_active) {
   2947                       LOG_ERROR(BSL_LS_BCM_COMMON,
   2948                                 (BSL_META_U(unit,
   2949                                             "ERROR: Queue %d flush operation failed \n"), 
   2950                                  node->hw_index));
   2951                       return (BCM_E_TIMEOUT);
   2952                   }
   2953               }
   2954        }
   2955    }
   2956    return BCM_E_NONE;
   2957 }
   2958 
   2959 STATIC int
   2960 _bcm_kt2_cosq_l2_max_bucket_set(int unit, int port,
   2961                                 _bcm_kt2_cosq_node_t *node)
   2962 {
   2963     int rv;
   2964 
   2965     if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2) {
   2966         for (node = node->child; node; node = node->sibling) {
   2967             rv = _bcm_kt2_cosq_l2_max_bucket_set(unit, port, node);
   2968             if (!BCM_SUCCESS(rv)) {
   2969                 return rv;
   2970             }
   2971         }
   2972         return BCM_E_NONE;
   2973     }
   2974 
   2975 #if defined(BCM_SABER2_SUPPORT)
   2976     if (SOC_IS_SABER2(unit)) {
   2977         rv = soc_sb2_cosq_max_bucket_set(unit, port, node->hw_index,
   2978                                     _BCM_KT2_COSQ_NODE_LEVEL_L2);
   2979     } else 
   2980 #endif
   2981     {
   2982         rv = soc_kt2_cosq_max_bucket_set(unit, port, node->hw_index,
   2983                                     _BCM_KT2_COSQ_NODE_LEVEL_L2);
   2984     }
   2985     return rv;
   2986 }
   2987 
   2988 /*
   2989  * Function:
   2990  *        _bcm_kt2_cosq_min_clear(unit, physical_port, node);
   2991  * Parameters:
   2992  *      unit -  (IN) unit number
   2993  *      port - (IN) physical port
   2994  *      node - (IN) node undergoing switchover
   2995  * Returns:
   2996  *      BCM_E_XXX
   2997  */
   2998 STATIC int 
   2999  _bcm_kt2_cosq_min_clear(int unit, int port, 
   3000                          _bcm_kt2_cosq_node_t *node) 
   3001 {
   3002     int rv = BCM_E_NONE;
   3003 #if defined(BCM_SABER2_SUPPORT) 
   3004     if (SOC_IS_SABER2(unit)) {
   3005         rv = soc_sb2_cosq_min_clear(unit, port, node->hw_index,
   3006                 node->level);
   3007     } else 
   3008 #endif
   3009     {
   3010         rv = soc_kt2_cosq_min_clear(unit, port, node->hw_index,
   3011                 node->level);
   3012     }
   3013     return rv;
   3014 }
   3015 
   3016 int
   3017 _bcm_egress_metering_freeze(int unit, bcm_gport_t gport, void **setting)
   3018 {
   3019     int rv = BCM_E_NONE;
   3020     soc_mem_t mem;
   3021     uint32 *bmap, *bmap_list[6];
   3022     int word_count, wdc[6], blk_size=0;
   3023     int lvl, j, index, word, bit, index_count, count;
   3024     int idx, upper_flag = 0;
   3025     int prev_idx, prev_upper_flag;
   3026     mem_entry_t *buffer;
   3027     uint32 mant = 0, cycle = 0 , f_idx;
   3028     uint32 entry[SOC_MAX_MEM_WORDS];
   3029     uint32 lvl_count = 0;
   3030     uint32 min = 0;
   3031     uint32 exp = 0;
   3032     uint32 sched_mode = 0;
   3033     int wt = 0;
   3034     uint32 burst_mant = 0;
   3035     uint32 burst_exp = 0;
   3036     uint32 *l2bmap = NULL;
   3037     int alloc_size;
   3038     bcm_port_t port;
   3039     soc_info_t *si;
   3040     _bcm_kt2_cosq_node_t *node = NULL;
   3041     _bcm_kt2_cosq_node_t *l1node = NULL;
   3042     _bcm_kt2_cosq_node_t *cur_node = NULL;
   3043 
   3044     static const soc_mem_t parent_mems[] = {
   3045         0,
   3046         LLS_L0_PARENTm,
   3047         LLS_L0_PARENTm,
   3048         LLS_L0_PARENTm,
   3049         LLS_L1_PARENTm,
   3050         LLS_L2_PARENTm
   3051     };
   3052 
   3053     static const soc_mem_t cfg_mems[][2] = {
   3054         { LLS_PORT_SHAPER_CONFIG_Cm, INVALIDm },
   3055         { LLS_S0_SHAPER_CONFIG_Cm, INVALIDm },
   3056         { LLS_S1_SHAPER_CONFIG_Cm, INVALIDm },
   3057         { LLS_L0_SHAPER_CONFIG_Cm, LLS_L0_MIN_CONFIG_Cm },
   3058         { LLS_L1_SHAPER_CONFIG_Cm, LLS_L1_MIN_CONFIG_Cm },
   3059         { LLS_L2_SHAPER_CONFIG_LOWERm, LLS_L2_MIN_CONFIG_LOWER_Cm },
   3060         { LLS_L2_SHAPER_CONFIG_UPPERm, LLS_L2_MIN_CONFIG_UPPER_Cm },
   3061     };
   3062 
   3063     static const soc_field_t rate_mant_fields[] = {
   3064         C_MAX_REF_RATE_MANT_0f, C_MAX_REF_RATE_MANT_1f,
   3065         C_MAX_REF_RATE_MANT_2f, C_MAX_REF_RATE_MANT_3f,
   3066         C_MIN_REF_RATE_MANT_0f, C_MIN_REF_RATE_MANT_1f,
   3067         C_MIN_REF_RATE_MANT_2f, C_MIN_REF_RATE_MANT_3f
   3068     };
   3069 
   3070     static const soc_field_t rate_exp_fields[] = {
   3071         C_MAX_REF_RATE_EXP_0f, C_MAX_REF_RATE_EXP_1f,
   3072         C_MAX_REF_RATE_EXP_2f, C_MAX_REF_RATE_EXP_3f,
   3073         C_MIN_REF_RATE_EXP_0f, C_MIN_REF_RATE_EXP_1f,
   3074         C_MIN_REF_RATE_EXP_2f, C_MIN_REF_RATE_EXP_3f
   3075     };
   3076     static const soc_field_t burst_exp_fields[] = {
   3077         C_MAX_THLD_EXP_0f, C_MAX_THLD_EXP_1f,
   3078         C_MAX_THLD_EXP_2f, C_MAX_THLD_EXP_3f,
   3079         C_MIN_THLD_EXP_0f, C_MIN_THLD_EXP_1f,
   3080         C_MIN_THLD_EXP_2f, C_MIN_THLD_EXP_3f
   3081     };
   3082     static const soc_field_t burst_mant_fields[] = {
   3083         C_MAX_THLD_MANT_0f, C_MAX_THLD_MANT_1f,
   3084         C_MAX_THLD_MANT_2f, C_MAX_THLD_MANT_3f,
   3085         C_MIN_THLD_MANT_0f, C_MIN_THLD_MANT_1f,
   3086         C_MIN_THLD_MANT_2f, C_MIN_THLD_MANT_3f
   3087     };
   3088 
   3089     static const soc_field_t cycle_sel_fields[] = {
   3090         C_MAX_CYCLE_SEL_0f, C_MAX_CYCLE_SEL_1f,
   3091         C_MAX_CYCLE_SEL_2f, C_MAX_CYCLE_SEL_3f,
   3092         C_MIN_CYCLE_SEL_0f, C_MIN_CYCLE_SEL_1f,
   3093         C_MIN_CYCLE_SEL_2f, C_MIN_CYCLE_SEL_3f
   3094     };
   3095 
   3096     SOC_EGRESS_METERING_LOCK(unit);
   3097 
   3098     alloc_size = SHR_BITALLOCSIZE(soc_mem_index_count(unit, LLS_L2_PARENTm));
   3099 
   3100     l2bmap = sal_alloc(alloc_size, "l2bmap");
   3101     if(l2bmap == NULL) {
   3102         rv = SOC_E_MEMORY;
   3103         goto _ka2_freeze_abort;
   3104     }
   3105 
   3106     sal_memset(l2bmap, 0, alloc_size);
   3107     rv = _bcm_kt2_cosq_node_get(unit, gport, NULL, &port, NULL, &node);
   3108     if (rv < 0) {
   3109         sal_free(l2bmap);
   3110         goto _ka2_freeze_abort;
   3111     }
   3112 
   3113     l1node = node->parent;
   3114     for (cur_node = l1node->child; cur_node != NULL ; cur_node = cur_node->sibling) {
   3115          SHR_BITSET(l2bmap, cur_node->hw_index);
   3116     }
   3117 
   3118     bmap_list[0] = NULL;
   3119     bmap_list[1] = SOC_CONTROL(unit)->port_lls_s0_bmap[port];
   3120     bmap_list[2] = SOC_CONTROL(unit)->port_lls_s1_bmap[port];
   3121     bmap_list[3] = SOC_CONTROL(unit)->port_lls_l0_bmap[port];
   3122     bmap_list[4] = SOC_CONTROL(unit)->port_lls_l1_bmap[port];
   3123     bmap_list[5] = l2bmap;
   3124 
   3125     si = &SOC_INFO(unit);
   3126     /*
   3127      * On KTX we can have both s0 and s1 node or only
   3128      * s1 node but can not have only s0 node
   3129      */
   3130     bmap = bmap_list[2];
   3131     index_count = _SOC_KT2_COSQ_MAX_INDEX_S1;
   3132     word_count = _SHR_BITDCLSIZE(index_count);
   3133     for (word = 0; word < word_count; word++) {
   3134         if (bmap[word] != 0) {
   3135             break;
   3136         }
   3137     }
   3138     if (word == word_count) {
   3139         /* s1 list is zero */
   3140         bmap =  bmap_list[1];
   3141         index_count = _SOC_KT2_COSQ_MAX_INDEX_S0;
   3142         word_count = _SHR_BITDCLSIZE(index_count);
   3143         for (word = 0; word < word_count; word++) {
   3144             if (bmap[word] != 0) {
   3145                 break;
   3146             }
   3147         }
   3148         if (word < word_count) {
   3149             /* s0 list is non zero */
   3150             /* swap  s0 ans s1 list */
   3151             bmap = bmap_list[2];
   3152             bmap_list[2] = bmap_list[1];
   3153             bmap_list[1] = bmap;
   3154         }
   3155     }
   3156     count = 0;
   3157     /* Count the number of the valid Root,S0,S1
   3158      * L0/L1/L2 entries per port.
   3159      * To allocate the buffer to store the Min, Max shaper
   3160      * entries for the valid indices
   3161      */
   3162     for (lvl = 0; lvl < _SOC_KT2_COSQ_NODE_LVL_MAX; lvl++) {
   3163         lvl_count = 0;
   3164         if (lvl == _SOC_KT2_COSQ_NODE_LVL_ROOT) {
   3165             /* Port entry */
   3166             lvl_count = 1;
   3167             wdc[lvl] = 0;
   3168         } else {
   3169             bmap = bmap_list[lvl];
   3170             mem = parent_mems[lvl];
   3171             index_count = soc_mem_index_count(unit, mem);
   3172 
   3173             if (lvl == _SOC_KT2_COSQ_NODE_LVL_S0) {
   3174                 index_count = _SOC_KT2_COSQ_MAX_INDEX_S0;
   3175             } else
   3176                 if (lvl == _SOC_KT2_COSQ_NODE_LVL_S1) {
   3177                     index_count =_SOC_KT2_COSQ_MAX_INDEX_S1;
   3178                 }
   3179             wdc[lvl] = _SHR_BITDCLSIZE(index_count);
   3180             word_count = wdc[lvl];
   3181 
   3182             for (word = 0; word < word_count; word++) {
   3183                 if (bmap[word] != 0) {
   3184                     lvl_count += _shr_popcount(bmap[word]);
   3185                 }
   3186             }
   3187             if (lvl >= _SOC_KT2_COSQ_NODE_LVL_L0) {
   3188                 /* for MIN/MAX  shaper config */
   3189                 /* count allocation is based on worst case
   3190                  * estimate that entries might fall into different
   3191                  * table entries
   3192                  */
   3193                 lvl_count = (lvl_count * 2);
   3194             }
   3195         }
   3196         count += lvl_count;
   3197     }
   3198     count = count + 1;
   3199 
   3200 
   3201     buffer = sal_alloc((count + 1) * sizeof(mem_entry_t),
   3202             "shaper buffer");
   3203 
   3204     if (buffer == NULL) {
   3205         rv = SOC_E_MEMORY;
   3206         sal_free(l2bmap);
   3207         goto _ka2_freeze_abort;
   3208     }
   3209     count = 0;
   3210     /* port */
   3211     mem = LLS_PORT_SHAPER_CONFIG_Cm;
   3212     index = port & 0x3f;
   3213 
   3214     /* Save the entry */
   3215     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index,
   3216             &buffer[count].entry);
   3217     if (BCM_FAILURE(rv)) {
   3218         sal_free(buffer);
   3219         sal_free(l2bmap);
   3220         goto _ka2_freeze_abort;
   3221     }
   3222     buffer[count].mem = mem;
   3223     buffer[count].index = index;
   3224     count++;
   3225 
   3226     /* Set the threshold for the port to max shaper rate */
   3227     rv = soc_kt2_cosq_max_bucket_set(unit, port, index,
   3228             _SOC_KT2_COSQ_NODE_LVL_ROOT);
   3229     if (BCM_FAILURE(rv)) {
   3230         sal_free(buffer);
   3231         sal_free(l2bmap);
   3232         goto _ka2_freeze_abort;
   3233     }
   3234 
   3235     /* S0, S1, L0, L1, L2 meter */
   3236     for (lvl = _SOC_KT2_COSQ_NODE_LVL_S0;
   3237             lvl < _SOC_KT2_COSQ_NODE_LVL_MAX; lvl++) {
   3238         idx = upper_flag = 0;
   3239         prev_idx = prev_upper_flag = -1;
   3240         blk_size = ((lvl == _SOC_KT2_COSQ_NODE_LVL_L2) ? 8:
   3241                 ((lvl == _SOC_KT2_COSQ_NODE_LVL_L1)? 4: 1));
   3242         bmap = bmap_list[lvl];
   3243         word_count = wdc[lvl];
   3244         for (word = 0; word < word_count; word++) {
   3245             if (bmap[word] == 0) {
   3246                 continue;
   3247             }
   3248             for (bit = 0; bit < SHR_BITWID; bit++) {
   3249                 if (!(bmap[word] & (1 << bit))) {
   3250                     continue;
   3251                 }
   3252                 index = word * SHR_BITWID + bit;
   3253                 idx = index / blk_size;
   3254 
   3255                 for (j = 0; j < 2; j++) {
   3256                     mem = cfg_mems[lvl][j];
   3257 
   3258                     if (mem == INVALIDm) {
   3259                         continue;
   3260                     }
   3261 
   3262                     if (lvl == _SOC_KT2_COSQ_NODE_LVL_L2) {
   3263                         if ((index % 8) >= 4) {
   3264                             mem = cfg_mems[lvl+1][j];
   3265                             upper_flag = 1;
   3266                         } else {
   3267                             upper_flag = 0;
   3268                         }
   3269                     }
   3270 
   3271                     /* Store the Threshold MIN/MAX table entries only
   3272                      * once per table index as for the
   3273                      * next consecutive L1/L2 indices falling on
   3274                      * to the same table index need not be stored
   3275                      */
   3276                     if ((prev_idx != idx) ||
   3277                             ((lvl == _SOC_KT2_COSQ_NODE_LVL_L2) &&
   3278                              (prev_upper_flag != upper_flag))) {
   3279                         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, idx,
   3280                                 &buffer[count].entry);
   3281                         if (BCM_FAILURE(rv)) {
   3282                             sal_free(buffer);
   3283                             sal_free(l2bmap);
   3284                             goto _ka2_freeze_abort;
   3285                         }
   3286                         buffer[count].mem = mem;
   3287                         buffer[count].index = idx;
   3288                         count++;
   3289                     }
   3290 
   3291                     if (lvl == _SOC_KT2_COSQ_NODE_LVL_L2){
   3292                         if (SOC_PBMP_MEMBER(si->linkphy_pbm, port)) {
   3293                             /* coverity[leaked_storage] */
   3294                             rv = soc_kt2_cosq_get_sched_mode(unit, port, lvl,
   3295                                     index, &sched_mode, &wt);
   3296                         } else {
   3297                             /* coverity[leaked_storage] */
   3298                             /* coverity[resource_leak : FALSE] */
   3299                             rv = soc_kt2_cosq_get_sched_mode(unit, port, lvl - 2,
   3300                                     index, &sched_mode, &wt);
   3301                         }
   3302                         if (BCM_FAILURE(rv)) {
   3303                             sal_free(buffer);
   3304                             sal_free(l2bmap);
   3305                             goto _ka2_freeze_abort;
   3306                         }
   3307 
   3308                         if ( sched_mode == BCM_COSQ_STRICT )
   3309                         {
   3310                             rv = _soc_kt2_cosq_min_bucket_get(unit, port,
   3311                                     index, lvl,
   3312                                     &min, &mant,
   3313                                     &exp, &cycle);
   3314                             if (BCM_FAILURE(rv)) {
   3315                                 sal_free(buffer);
   3316                                 sal_free(l2bmap);
   3317                                 goto _ka2_freeze_abort;
   3318                             }
   3319                             if (min) {
   3320                                 if (exp != 0) {
   3321                                     if (exp < 10) {
   3322                                         burst_exp = 5;
   3323                                         burst_mant = 0;
   3324                                     } else {
   3325                                         burst_exp = exp - 4;
   3326                                         burst_mant = (mant >> 3);
   3327                                     }
   3328                                 }
   3329                                 else {
   3330                                     burst_mant = 0;
   3331                                     burst_exp = 0;
   3332                                 }
   3333                             }
   3334                         }
   3335                         if (!min)
   3336                         {
   3337                             /* Set the  MIN/MAX thresholds for L2 node
   3338                              * to 2 Kbps
   3339                              */
   3340                             mant = 1;
   3341                             cycle = 4;
   3342                             exp = 0;
   3343                         }
   3344                         f_idx = (j * 4) + (index % 4);
   3345                         sal_memset(entry, 0, (sizeof(uint32) * SOC_MAX_MEM_WORDS));
   3346                         rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL,
   3347                                 idx, &entry);
   3348                         if (BCM_FAILURE(rv)) {
   3349                             sal_free(buffer);
   3350                             sal_free(l2bmap);
   3351                             goto _ka2_freeze_abort;
   3352                         }
   3353 
   3354                         soc_mem_field32_set(unit, mem, &entry,
   3355                                 rate_mant_fields[f_idx], mant);
   3356                         soc_mem_field32_set(unit, mem, &entry,
   3357                                 rate_exp_fields[f_idx], exp);
   3358                         soc_mem_field32_set(unit, mem, &entry,
   3359                                 burst_exp_fields[f_idx], burst_exp);
   3360                         soc_mem_field32_set(unit, mem, &entry,
   3361                                 burst_mant_fields[f_idx], burst_mant);
   3362                         soc_mem_field32_set(unit, mem, &entry,
   3363                                 cycle_sel_fields[f_idx], cycle);
   3364                         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY,
   3365                                 idx, &entry);
   3366                         min = 0;
   3367                         sched_mode = 0;
   3368                         cycle = 0;
   3369                         exp = 0;
   3370                         mant = 0;
   3371                         burst_exp = 0;
   3372                         burst_mant = 0;
   3373                     } else if (((lvl >= _SOC_KT2_COSQ_NODE_LVL_L0) && (j == 1)) ||
   3374                             (lvl < _SOC_KT2_COSQ_NODE_LVL_L0)) {
   3375                         /* Set the MIN/MAX thresholds for L0/L1 node
   3376                          * to max shaper rate
   3377                          */
   3378                         rv = soc_kt2_cosq_max_bucket_set(unit, port,
   3379                                 index, lvl);
   3380                     }
   3381                     if (BCM_FAILURE(rv)) {
   3382                         sal_free(buffer);
   3383                         sal_free(l2bmap);
   3384                         goto _ka2_freeze_abort;
   3385                     }
   3386                 }/*END of for j */
   3387                 prev_idx = idx;
   3388                 prev_upper_flag = upper_flag;
   3389             } /* END of the valid bit */
   3390         } /* END of the word */
   3391     } /* END of lvl */
   3392 
   3393     buffer[count].mem = INVALIDm;
   3394     *setting = buffer;
   3395 _ka2_freeze_abort:
   3396     if (BCM_FAILURE(rv)) {
   3397         /* UNLOCK if fail */
   3398         SOC_EGRESS_METERING_UNLOCK(unit);
   3399     }
   3400     return rv;
   3401 }
   3402 
   3403 int
   3404 _bcm_egress_metering_thaw(int unit, void *setting)
   3405 {
   3406     int  rv = BCM_E_NONE;
   3407     mem_entry_t *buffer;
   3408     int index;
   3409 
   3410     if (setting == NULL) {
   3411         SOC_EGRESS_METERING_UNLOCK(unit);
   3412         return SOC_E_NONE;
   3413     }
   3414     buffer = setting;
   3415     for (index = 0; buffer[index].mem != INVALIDm ;index++) {
   3416         rv = soc_mem_write(unit, buffer[index].mem, MEM_BLOCK_ANY,
   3417                 buffer[index].index, &buffer[index].entry);
   3418         if (BCM_FAILURE(rv)) {
   3419             break;
   3420         }
   3421     }
   3422     sal_free(setting);
   3423 
   3424     SOC_EGRESS_METERING_UNLOCK(unit);
   3425     return rv;
   3426 }
   3427 /*
   3428  * Function:
   3429  *     _bcm_kt2_cosq_sched_config_set
   3430  * Purpose:
   3431  *     Set LLS scheduler registers based on GPORT
   3432  * Parameters:
   3433  *     unit       - (IN) unit number
   3434  *     gport     - (IN) queue group/scheduler GPORT identifier
   3435  *     state     - (IN) sched state change
   3436  * Returns:
   3437  *     BCM_E_XXX
   3438  */
   3439 STATIC int
   3440 _bcm_kt2_cosq_sched_config_set(int unit, bcm_gport_t gport, 
   3441                                _bcm_kt2_cosq_state_t state)
   3442 {
   3443     int rv = BCM_E_NONE;
   3444     _bcm_kt2_mmu_info_t *mmu_info;
   3445     _bcm_kt2_cosq_node_t *node, *parent;
   3446     mmu_rqe_queue_op_node_map_entry_t rqe_op_node;
   3447     mmu_wred_queue_op_node_map_entry_t wred_op_node;
   3448     egr_queue_to_pp_port_map_entry_t pp_port_map;
   3449     _bcm_kt2_subport_info_t info;
   3450     bcm_gport_t pp_port;
   3451     lls_l2_child_state1_entry_t l2_child_state;
   3452     uint32 entry_c[SOC_MAX_MEM_WORDS];
   3453     uint32 entry_p[SOC_MAX_MEM_WORDS];
   3454     int port, physical_port, start_spri = 0;
   3455     int update_spri_vector = 0;
   3456     uint8 spri_vector = 0, spri_select = 0;
   3457     int parent_index, numq;
   3458     uint8 vec_3_0, vec_7_4;
   3459     uint32 spare, min_list, ef_list, not_empty;
   3460     soc_mem_t config_mem, parent_mem;
   3461     soc_field_t start_spri_field = P_START_UC_SPRIf;
   3462     bcm_port_t local_port;
   3463     uint32 *bmap = NULL;
   3464     void *setting = NULL;
   3465     int s1_index = -1, link_state = BCM_PORT_LINK_STATUS_UP;
   3466     _bcm_kt2_cosq_node_t *s1_node = NULL;
   3467     soc_mem_t mem_c[] = {
   3468                         LLS_PORT_CONFIGm,
   3469                         LLS_S1_CONFIGm,
   3470                         INVALIDm,
   3471                         LLS_L0_CONFIGm,
   3472                         LLS_L1_CONFIGm
   3473                       };
   3474     soc_mem_t mem_p[] = {
   3475                         LLS_L0_PARENTm,
   3476                         LLS_L0_PARENTm,
   3477                         INVALIDm,
   3478                         LLS_L1_PARENTm, 
   3479                         LLS_L2_PARENTm
   3480                       };
   3481     mmu_thdo_opnconfig_cell_entry_t     mmu_thdo_opnconfig_cell_entry={{0}};
   3482     mmu_thdo_opnconfig_qentry_entry_t   mmu_thdo_opnconfig_qentry_entry={{0}};
   3483     mmu_enq_src_ppp_to_s1_lookup_entry_t ppp_to_s1;
   3484 
   3485     memset(&ppp_to_s1, 0, sizeof(ppp_to_s1));
   3486     
   3487     BCM_IF_ERROR_RETURN
   3488         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &port, NULL,
   3489                                &node));
   3490 
   3491     /* MMU_ENQ_SRC_PPP_TO_S1_LOOKUP is programmed
   3492      * to map the PP ports to S1 node associated with
   3493      * COE port for E2ECC COE Flow Control
   3494      */
   3495     if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
   3496         rv = _bcm_kt2_cosq_subport_get(unit, gport, &pp_port);
   3497         if (rv == BCM_E_NONE) {
   3498             BCM_IF_ERROR_RETURN
   3499                (bcm_kt2_subport_pp_port_subport_info_get(unit, pp_port,
   3500                                                 &info));
   3501             if (info.port_type == _BCM_KT2_SUBPORT_TYPE_SUBTAG) {
   3502                 SOC_IF_ERROR_RETURN
   3503                      (READ_MMU_ENQ_SRC_PPP_TO_S1_LOOKUPm(unit, MEM_BLOCK_ALL,
   3504                    pp_port, &ppp_to_s1));
   3505                 if (state == _BCM_KT2_COSQ_STATE_ENABLE) {
   3506                     soc_mem_field32_set(unit, MMU_ENQ_SRC_PPP_TO_S1_LOOKUPm,
   3507                                         &ppp_to_s1, S1_VLDf, 1);
   3508                     soc_mem_field32_set(unit, MMU_ENQ_SRC_PPP_TO_S1_LOOKUPm,
   3509                                         &ppp_to_s1, S1f, node->hw_index);
   3510                     SOC_IF_ERROR_RETURN
   3511                       (WRITE_MMU_ENQ_SRC_PPP_TO_S1_LOOKUPm(unit,
   3512                              MEM_BLOCK_ALL,
   3513                              pp_port, &ppp_to_s1));
   3514 
   3515                 } else if (state == _BCM_KT2_COSQ_STATE_DISABLE) {
   3516                     SOC_IF_ERROR_RETURN
   3517                       (WRITE_MMU_ENQ_SRC_PPP_TO_S1_LOOKUPm(unit,
   3518                           MEM_BLOCK_ALL,
   3519                           pp_port,
   3520                           (soc_mem_entry_null(unit,
   3521                           MMU_ENQ_SRC_PPP_TO_S1_LOOKUPm))));
   3522                 }
   3523 
   3524             }
   3525         }
   3526     }
   3527     parent = node->parent;
   3528     /*
   3529      * Programming the LLS_L0_PARENT and LLS_S1_CONFIG so that
   3530      *  credits are exchanged between the TXLP and MMU is proper in case of LinkPHY
   3531      */
   3532     if (soc_feature(unit, soc_feature_discontinuous_pp_port) &&
   3533         parent->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
   3534         sal_memset(entry_p, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
   3535         parent_mem = LLS_L0_PARENTm;
   3536         soc_mem_field32_set(unit, parent_mem, &entry_p, C_PARENTf,
   3537                 parent->hw_index);
   3538         soc_mem_field32_set(unit, parent_mem, &entry_p, C_TYPEf, 0);
   3539         SOC_IF_ERROR_RETURN
   3540             (soc_mem_write(unit, parent_mem, MEM_BLOCK_ANY, 
   3541                            node->hw_index, &entry_p));
   3542         config_mem = LLS_S1_CONFIGm;
   3543         sal_memset(entry_c, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
   3544         /* Programming the L0 start node, since l0==s1,
   3545          * using parent->hw_index
   3546          */
   3547         soc_mem_field32_set(unit, config_mem, &entry_c, P_START_SPRIf, 
   3548                 node->hw_index);
   3549         soc_mem_field32_set(unit, config_mem, &entry_c, P_NUM_SPRIf, 
   3550                 1);
   3551         (soc_mem_write(unit, config_mem, MEM_BLOCK_ANY, 
   3552                                     parent->hw_index, 
   3553                                     &entry_c));
   3554     } else if ((node->level == _BCM_KT2_COSQ_NODE_LEVEL_L0) &&
   3555         (parent->level == _BCM_KT2_COSQ_NODE_LEVEL_S1)) {
   3556         sal_memset(entry_p, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
   3557         parent_mem = LLS_L0_PARENTm;
   3558         soc_mem_field32_set(unit, parent_mem, &entry_p, C_PARENTf,
   3559                 parent->hw_index);
   3560         soc_mem_field32_set(unit, parent_mem, &entry_p, C_TYPEf, 0);
   3561         SOC_IF_ERROR_RETURN
   3562             (soc_mem_write(unit, parent_mem, MEM_BLOCK_ANY, 
   3563                            parent->hw_index, &entry_p));
   3564         if ((parent->hw_index >= 0) && (parent->hw_index <=127)) {
   3565             config_mem = LLS_S1_CONFIGm;
   3566             sal_memset(entry_c, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
   3567             /* Programming the L0 start node, since l0==s1,
   3568              * using parent->hw_index
   3569              */
   3570             soc_mem_field32_set(unit, config_mem, &entry_c, P_START_SPRIf, 
   3571                     parent->hw_index);
   3572             soc_mem_field32_set(unit, config_mem, &entry_c, P_NUM_SPRIf, 
   3573                    1);
   3574             (soc_mem_write(unit, config_mem, MEM_BLOCK_ANY, 
   3575                                        parent->hw_index, 
   3576                                        &entry_c));
   3577         }
   3578 
   3579     }
   3580     
   3581     physical_port = port;
   3582     rv = _bcm_kt2_cosq_subport_get(unit, gport, &pp_port);
   3583     if (rv == BCM_E_NONE) {
   3584         BCM_IF_ERROR_RETURN
   3585             (bcm_kt2_subport_pp_port_subport_info_get(unit, pp_port,
   3586                                                       &info));
   3587         physical_port = info.port;
   3588         if (state == _BCM_KT2_COSQ_STATE_ENABLE) {
   3589             node->local_port = physical_port;
   3590         }
   3591     }
   3592  
   3593     if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
   3594         bmap = SOC_CONTROL(unit)->port_lls_s0_bmap[physical_port];
   3595     } else if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) {
   3596         bmap = SOC_CONTROL(unit)->port_lls_s1_bmap[physical_port];
   3597     } else if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L0) {
   3598         bmap = SOC_CONTROL(unit)->port_lls_l0_bmap[physical_port];
   3599     } else if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L1) {
   3600         bmap = SOC_CONTROL(unit)->port_lls_l1_bmap[physical_port];
   3601     } else if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L2) {
   3602         bmap = SOC_CONTROL(unit)->port_lls_l2_bmap[physical_port];
   3603     } else {
   3604         return BCM_E_PARAM;
   3605     }
   3606 
   3607     if ((node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0 ||
   3608         node->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) &&
   3609         (state == _BCM_KT2_COSQ_STATE_ENABLE ||
   3610          state == _BCM_KT2_COSQ_STATE_DISABLE) &&
   3611         (!SOC_IS_METROLITE(unit) || !node->linkphy_enabled)) {
   3612         if (state == _BCM_KT2_COSQ_STATE_ENABLE) { 
   3613             SHR_BITSET(bmap, node->hw_index);
   3614         } else if (state == _BCM_KT2_COSQ_STATE_DISABLE) {
   3615             SHR_BITCLR(bmap, node->hw_index);
   3616         }      
   3617         return BCM_E_NONE;
   3618     }
   3619 
   3620     if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0 &&
   3621         (state == _BCM_KT2_COSQ_STATE_WRR_TO_SPRI ||
   3622          state == _BCM_KT2_COSQ_STATE_SPRI_TO_WRR)) {
   3623          return BCM_E_NONE;
   3624     }
   3625     
   3626 
   3627     if (((parent->level == _BCM_KT2_COSQ_NODE_LEVEL_S1)  ||
   3628         (SOC_IS_METROLITE(unit) && parent->linkphy_enabled)) &&
   3629         node->level == _BCM_KT2_COSQ_NODE_LEVEL_L0) {
   3630         return BCM_E_NONE;
   3631     }
   3632 
   3633     numq = (parent->wrr_mode == 0) ? ((parent->numq > 8) ? 8 : parent->numq) : 1;
   3634     if ((node->cosq_attached_to < numq) && (parent->base_index < 0) && 
   3635         (parent->mc_base_index < 0)) {
   3636         return BCM_E_PARAM;
   3637     }
   3638 
   3639     config_mem = mem_c[parent->level];
   3640     if ((node->cosq_attached_to < numq) && (parent->hw_index != -1)) {
   3641         start_spri = (BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport) ||
   3642                       BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) ?
   3643                       parent->mc_base_index : parent->base_index; 
   3644         spri_vector = 1 << node->cosq_attached_to;
   3645         update_spri_vector =  1;
   3646 
   3647         sal_memset(entry_c, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);   
   3648 
   3649         if ((parent->level == _BCM_KT2_COSQ_NODE_LEVEL_S0)
   3650                 && (parent->hw_index >= 128)) {
   3651             config_mem = LLS_L0_CONFIGm; 
   3652         }
   3653         SOC_IF_ERROR_RETURN
   3654             (soc_mem_read(unit, config_mem, MEM_BLOCK_ALL, parent->hw_index, 
   3655                           &entry_c));
   3656         vec_3_0 = soc_mem_field32_get(unit, config_mem, &entry_c, 
   3657                                       P_NUM_SPRIf);
   3658         vec_7_4 = soc_mem_field32_get(unit, config_mem, &entry_c, 
   3659                                       P_VECT_SPRI_7_4f);
   3660         if (state == _BCM_KT2_COSQ_STATE_ENABLE || 
   3661             state == _BCM_KT2_COSQ_STATE_WRR_TO_SPRI) {
   3662             vec_3_0 |= (spri_vector & 0xF);
   3663             vec_7_4 |= (spri_vector >> 4); 
   3664         } else if ((state == _BCM_KT2_COSQ_STATE_SPRI_TO_WRR) ||
   3665                (state == _BCM_KT2_COSQ_STATE_DISABLE)) {
   3666             vec_3_0 &= ~(spri_vector & 0xF);
   3667             vec_7_4 &= ~(spri_vector >> 4);
   3668         } 
   3669 
   3670         /* update LLS_CONFIG with the updated vector */ 
   3671         if (config_mem == LLS_L1_CONFIGm) {
   3672             spri_select = soc_mem_field32_get(unit, config_mem, &entry_c,
   3673                                               P_SPRI_SELECTf);
   3674             if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport) ||
   3675                 BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) {
   3676                 start_spri_field = P_START_MC_SPRIf;
   3677                 spri_select |= spri_vector;    
   3678             } else {
   3679                 spri_select &= ~(spri_vector);
   3680             }
   3681             /* Valid if num_spri is not 0 */
   3682             if (vec_3_0 != 0) {
   3683                 soc_mem_field32_set(unit, config_mem, &entry_c, start_spri_field, start_spri);
   3684             }
   3685             soc_mem_field32_set(unit, config_mem, &entry_c, P_SPRI_SELECTf, 
   3686                                 spri_select);
   3687         } else {
   3688             /* Valid if num_spri is not 0 */
   3689             if (vec_3_0 != 0) {
   3690                 soc_mem_field32_set(unit, config_mem, &entry_c, P_START_SPRIf, start_spri);
   3691             }
   3692         }
   3693         soc_mem_field32_set(unit, config_mem, &entry_c, P_NUM_SPRIf, vec_3_0);
   3694         soc_mem_field32_set(unit, config_mem, &entry_c, P_VECT_SPRI_7_4f, vec_7_4); 
   3695     }
   3696 
   3697     parent_mem = mem_p[parent->level]; 
   3698     sal_memset(entry_p, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
   3699     sal_memset(&wred_op_node, 0, sizeof(mmu_wred_queue_op_node_map_entry_t));
   3700 
   3701     switch (state) {
   3702         case _BCM_KT2_COSQ_STATE_ENABLE:
   3703             if ((parent_mem == LLS_L0_PARENTm) &&
   3704                 (parent->level == _BCM_KT2_COSQ_NODE_LEVEL_ROOT) &&
   3705                 (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L0)) {
   3706                 soc_mem_field32_set(unit, parent_mem, &entry_p, C_TYPEf, 1); 
   3707             }
   3708             if (parent->level != _BCM_KT2_COSQ_NODE_LEVEL_S1) {
   3709                 soc_mem_field32_set(unit, parent_mem, &entry_p, C_PARENTf, 
   3710                                     parent->hw_index);
   3711                 if (parent->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
   3712                     soc_mem_field32_set(unit, parent_mem, &entry_p, C_TYPEf, 0);
   3713                 }
   3714                 SOC_IF_ERROR_RETURN
   3715                     (soc_mem_write(unit, parent_mem, MEM_BLOCK_ANY, 
   3716                                    node->hw_index, &entry_p));
   3717             }
   3718             if (update_spri_vector && parent->linkphy_enabled == 0) {
   3719                 SOC_IF_ERROR_RETURN
   3720                     (soc_mem_write(unit, config_mem, MEM_BLOCK_ANY, 
   3721                                    parent->hw_index, &entry_c));
   3722             }
   3723 
   3724             if (parent->level == _BCM_KT2_COSQ_NODE_LEVEL_L1) {
   3725                 /* Read the entry from the RQE map in order to preserve 
   3726                  * the E_TYPE field 
   3727                  */
   3728                 SOC_IF_ERROR_RETURN
   3729                     (READ_MMU_RQE_QUEUE_OP_NODE_MAPm(unit, MEM_BLOCK_ALL, 
   3730                                                      node->hw_index,
   3731                                                      &rqe_op_node));
   3732                 soc_mem_field32_set(unit, MMU_RQE_QUEUE_OP_NODE_MAPm, 
   3733                                     &rqe_op_node,
   3734                                     OP_NODEf, parent->hw_index);           
   3735                 soc_mem_field32_set(unit, MMU_WRED_QUEUE_OP_NODE_MAPm, 
   3736                                     &wred_op_node,
   3737                                     OP_NODEf, parent->hw_index);    
   3738                 SOC_IF_ERROR_RETURN
   3739                     (WRITE_MMU_RQE_QUEUE_OP_NODE_MAPm(unit, MEM_BLOCK_ALL, 
   3740                                                       node->hw_index,
   3741                                                       &rqe_op_node));
   3742                 SOC_IF_ERROR_RETURN
   3743                     (WRITE_MMU_WRED_QUEUE_OP_NODE_MAPm(unit, MEM_BLOCK_ALL, 
   3744                                                        node->hw_index,
   3745                                                        &wred_op_node)); 
   3746 
   3747                 if ((soc_feature(unit, soc_feature_mmu_packing) &&
   3748                     IS_EXT_MEM_PORT(unit, port)) &&
   3749                     (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   3750                      BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
   3751                      BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport))) {
   3752                     BCM_IF_ERROR_RETURN
   3753                         (_bcm_kt2_cosq_packing_mode_set(unit, node->hw_index, 1));
   3754                 }
   3755 
   3756                 /*
   3757                  * Enable queue only if link is up. If port is down then
   3758                  * queue will be enabaled during link up event.
   3759                  */
   3760                 BCM_IF_ERROR_RETURN
   3761                     (_bcm_kt2_cosq_node_get(unit, gport, NULL ,&local_port, NULL,
   3762                                             NULL));
   3763                 rv =  _bcm_esw_link_get(unit, local_port, &link_state);
   3764                 if (rv == BCM_E_NONE) {
   3765                     if (link_state == BCM_PORT_LINK_STATUS_UP) {
   3766                         _soc_kt2_cosq_end_port_flush(unit,node->hw_index);
   3767                     }
   3768                 } else {
   3769                     _soc_kt2_cosq_end_port_flush(unit,node->hw_index);
   3770                 }
   3771 
   3772                 if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   3773                     BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   3774                     BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport)) {
   3775                     SOC_IF_ERROR_RETURN
   3776                         (READ_EGR_QUEUE_TO_PP_PORT_MAPm(unit, MEM_BLOCK_ALL, 
   3777                                                         node->hw_index,
   3778                                                         &pp_port_map));
   3779                     BCM_IF_ERROR_RETURN
   3780                         (_bcm_kt2_cosq_node_get(unit, gport, NULL ,&local_port, NULL,
   3781                                                 NULL));
   3782 
   3783                     soc_mem_field32_set(unit, EGR_QUEUE_TO_PP_PORT_MAPm, 
   3784                             &pp_port_map, PP_PORTf, local_port);
   3785                     SOC_IF_ERROR_RETURN
   3786                         (WRITE_EGR_QUEUE_TO_PP_PORT_MAPm(unit, MEM_BLOCK_ALL, 
   3787                                                          node->hw_index, 
   3788                                                          &pp_port_map));    
   3789                 }              
   3790                 
   3791                 rv = _bcm_kt2_cosq_subport_get(unit, gport, &pp_port);
   3792                 if (rv == BCM_E_NONE) {
   3793                     BCM_IF_ERROR_RETURN
   3794                        (bcm_kt2_subport_pp_port_subport_info_get(unit, pp_port,
   3795                                                         &info));
   3796                     port = info.port;
   3797                     SOC_IF_ERROR_RETURN
   3798                     (READ_EGR_QUEUE_TO_PP_PORT_MAPm(unit, MEM_BLOCK_ALL,
   3799                                                     node->hw_index,
   3800                                                     &pp_port_map));
   3801                     soc_mem_field32_set(unit, EGR_QUEUE_TO_PP_PORT_MAPm,
   3802                                         &pp_port_map, PP_PORTf, pp_port);
   3803 
   3804                     if (info.port_type == _BCM_KT2_SUBPORT_TYPE_LINKPHY) {
   3805                         /* LinkPhy - two streams per S0 node
   3806                          * To understand the queue association with the streams
   3807                          * read the parent L1 and S1 associated with the queue
   3808                          * read the stream ID
   3809                          */
   3810                         if ((parent->parent) && (parent->parent->parent)) {
   3811                            s1_node = parent->parent->parent;
   3812                            if (SOC_IS_METROLITE(unit)) {
   3813                                /* Metrolite doesn't have an S0 node in hardware.
   3814                                 * However, SW treats the level as S0 so as to be
   3815                                 * consistant with subport APIs.
   3816                                 */
   3817                                if (s1_node->level != _BCM_KT2_COSQ_NODE_LEVEL_S0) {
   3818                                    return BCM_E_INTERNAL;
   3819                                }
   3820                            } else if (s1_node->level != _BCM_KT2_COSQ_NODE_LEVEL_S1) { 
   3821                                return BCM_E_INTERNAL;
   3822                            }
   3823                            s1_index = s1_node->hw_index;
   3824                            if (s1_index < 0) {
   3825                                return BCM_E_INTERNAL;
   3826                            }
   3827                         } else {
   3828                            return BCM_E_INTERNAL;
   3829                         }
   3830                         soc_mem_field32_set(unit, EGR_QUEUE_TO_PP_PORT_MAPm, 
   3831                                     &pp_port_map, DEVICE_STREAM_IDf,
   3832                                     s1_index);
   3833                     } else {
   3834                         soc_mem_field32_set(unit, EGR_QUEUE_TO_PP_PORT_MAPm,
   3835                                     &pp_port_map, SUBPORT_TAGf,
   3836                                     info.subtag);
   3837                     }
   3838                     SOC_IF_ERROR_RETURN
   3839                     (WRITE_EGR_QUEUE_TO_PP_PORT_MAPm(unit, MEM_BLOCK_ALL,
   3840                                                      node->hw_index,
   3841                                                      &pp_port_map));
   3842                 }
   3843                 SOC_IF_ERROR_RETURN(READ_MMU_THDO_OPNCONFIG_CELLm(unit,
   3844                                     MEM_BLOCK_ANY, parent->hw_index,     
   3845                                     &mmu_thdo_opnconfig_cell_entry));
   3846                 soc_mem_field32_set(unit, MMU_THDO_OPNCONFIG_CELLm,
   3847                                     &mmu_thdo_opnconfig_cell_entry, 
   3848                                     PIDf, port);
   3849                 SOC_IF_ERROR_RETURN(WRITE_MMU_THDO_OPNCONFIG_CELLm(unit,
   3850                                     MEM_BLOCK_ALL, parent->hw_index,     
   3851                                     &mmu_thdo_opnconfig_cell_entry));
   3852                 SOC_IF_ERROR_RETURN(READ_MMU_THDO_OPNCONFIG_QENTRYm(unit,
   3853                                     MEM_BLOCK_ANY, parent->hw_index ,        
   3854                                     &mmu_thdo_opnconfig_qentry_entry));
   3855                 soc_mem_field32_set(unit, MMU_THDO_OPNCONFIG_QENTRYm,
   3856                                     &mmu_thdo_opnconfig_qentry_entry,
   3857                                     PIDf, port);
   3858                 SOC_IF_ERROR_RETURN(WRITE_MMU_THDO_OPNCONFIG_QENTRYm(unit,
   3859                                     MEM_BLOCK_ALL, parent->hw_index ,        
   3860                                     &mmu_thdo_opnconfig_qentry_entry));
   3861             }
   3862             SHR_BITSET(bmap, node->hw_index);
   3863             break;
   3864         case _BCM_KT2_COSQ_STATE_DISABLE:
   3865             mmu_info = _bcm_kt2_mmu_info[unit];
   3866             if (parent->level == _BCM_KT2_COSQ_NODE_LEVEL_ROOT) {
   3867                 parent_index = (1 << soc_mem_field_length(unit, parent_mem, 
   3868                                                           C_PARENTf)) - 1;
   3869             } else {    
   3870                 parent_index = mmu_info->max_nodes[parent->level] - 1;
   3871             }    
   3872             soc_mem_field32_set(unit, parent_mem, &entry_p, C_PARENTf, 
   3873                                 parent_index); 
   3874                                         
   3875             if (parent->level == _BCM_KT2_COSQ_NODE_LEVEL_L1) {
   3876                 /* flush the queue  */
   3877                 BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_flush_queues(
   3878                                     unit, physical_port, node, gport));
   3879                 SOC_IF_ERROR_RETURN
   3880                     (READ_LLS_L2_CHILD_STATE1m(unit, MEM_BLOCK_ALL,
   3881                                                node->hw_index,
   3882                                                &l2_child_state));
   3883                 if (SOC_MEM_FIELD_VALID(unit, LLS_L2_CHILD_STATE1m, SPAREf)) {
   3884                     soc_mem_field_get(unit, LLS_L2_CHILD_STATE1m,
   3885                                       (uint32 *)&l2_child_state, SPAREf,
   3886                                       &spare);
   3887                 } else {
   3888                     soc_mem_field_get(unit, LLS_L2_CHILD_STATE1m,
   3889                                       (uint32 *)&l2_child_state, 
   3890                                       C_ON_WERR_LISTf, &spare);
   3891                 }
   3892                 soc_mem_field_get(unit, LLS_L2_CHILD_STATE1m,
   3893                                   (uint32 *)&l2_child_state,
   3894                                   C_ON_MIN_LIST_0f, &min_list);
   3895                 soc_mem_field_get(unit, LLS_L2_CHILD_STATE1m,
   3896                                   (uint32 *)&l2_child_state,
   3897                                   C_ON_EF_LIST_0f, &ef_list);
   3898                 soc_mem_field_get(unit, LLS_L2_CHILD_STATE1m,
   3899                                   (uint32 *)&l2_child_state,
   3900                                   C_NOT_EMPTY_0f, &not_empty);
   3901                 /* check LLS_L2_CHILD_STATE[7:4] == 4'b0000 to confirm
   3902                  * that the node is empty */
   3903                 if (spare || min_list || ef_list || not_empty) {
   3904                     return BCM_E_BUSY;
   3905                 }
   3906                 SOC_IF_ERROR_RETURN
   3907                     (READ_LLS_L2_CHILD_STATE1m(unit, MEM_BLOCK_ALL, 
   3908                                                node->hw_index,
   3909                                                &l2_child_state));
   3910                 if (SOC_MEM_FIELD_VALID(unit, LLS_L2_CHILD_STATE1m, SPAREf)) {
   3911                     soc_mem_field_get(unit, LLS_L2_CHILD_STATE1m,
   3912                                       (uint32 *)&l2_child_state, SPAREf,
   3913                                       &spare);
   3914                 } else {
   3915                     soc_mem_field_get(unit, LLS_L2_CHILD_STATE1m,
   3916                                       (uint32 *)&l2_child_state, 
   3917                                       C_ON_WERR_LISTf, &spare);
   3918                 }
   3919                 soc_mem_field_get(unit, LLS_L2_CHILD_STATE1m, 
   3920                                   (uint32 *)&l2_child_state, 
   3921                                   C_ON_MIN_LIST_0f, &min_list);
   3922                 soc_mem_field_get(unit, LLS_L2_CHILD_STATE1m, 
   3923                                   (uint32 *)&l2_child_state, 
   3924                                   C_ON_EF_LIST_0f, &ef_list);
   3925                 soc_mem_field_get(unit, LLS_L2_CHILD_STATE1m, 
   3926                                   (uint32 *)&l2_child_state, 
   3927                                   C_NOT_EMPTY_0f, &not_empty);
   3928                 /* check LLS_L2_CHILD_STATE[7:4] == 4'b0000 to confirm 
   3929                  * that the node is empty */
   3930                 if (spare || min_list || ef_list || not_empty) {
   3931                     return BCM_E_BUSY;  
   3932                 }    
   3933 
   3934                 if ((soc_feature(unit, soc_feature_mmu_packing) &&
   3935                     IS_EXT_MEM_PORT(unit, port)) &&
   3936                     (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   3937                      BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
   3938                      BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport))) {
   3939                     BCM_IF_ERROR_RETURN
   3940                         (_bcm_kt2_cosq_packing_mode_set(unit, node->hw_index, 0));
   3941                 }
   3942 
   3943                 SOC_IF_ERROR_RETURN
   3944                     (READ_MMU_RQE_QUEUE_OP_NODE_MAPm(unit, MEM_BLOCK_ALL, 
   3945                                                      node->hw_index,
   3946                                                      &rqe_op_node));
   3947                 soc_mem_field32_set(unit, MMU_RQE_QUEUE_OP_NODE_MAPm, 
   3948                                     &rqe_op_node,
   3949                                     OP_NODEf, parent_index);
   3950                 soc_mem_field32_set(unit, MMU_WRED_QUEUE_OP_NODE_MAPm, 
   3951                                     &wred_op_node,
   3952                                     OP_NODEf, parent_index);
   3953                 SOC_IF_ERROR_RETURN
   3954                     (soc_mem_write(unit, parent_mem, MEM_BLOCK_ANY, 
   3955                                    node->hw_index, &entry_p));
   3956                 SOC_IF_ERROR_RETURN
   3957                     (WRITE_MMU_RQE_QUEUE_OP_NODE_MAPm(unit, MEM_BLOCK_ALL, 
   3958                                                       node->hw_index,
   3959                                                       &rqe_op_node));
   3960                 SOC_IF_ERROR_RETURN
   3961                     (WRITE_MMU_WRED_QUEUE_OP_NODE_MAPm(unit, MEM_BLOCK_ALL, 
   3962                                                        node->hw_index,
   3963                                                        &wred_op_node)); 
   3964             }else {
   3965                 if (parent->level != _BCM_KT2_COSQ_NODE_LEVEL_S1) { 
   3966                     SOC_IF_ERROR_RETURN
   3967                         (soc_mem_write(unit, parent_mem, MEM_BLOCK_ANY, 
   3968                                        node->hw_index, 
   3969                                        &entry_p));
   3970                 }
   3971             }
   3972             if (update_spri_vector && parent->linkphy_enabled == 0) {
   3973                 SOC_IF_ERROR_RETURN
   3974                     (soc_mem_write(unit, config_mem, MEM_BLOCK_ANY, 
   3975                                    parent->hw_index, 
   3976                                    &entry_c));
   3977             }
   3978             SHR_BITCLR(bmap, node->hw_index);
   3979             break;
   3980         case _BCM_KT2_COSQ_STATE_WRR_TO_SPRI:
   3981         case _BCM_KT2_COSQ_STATE_SPRI_TO_WRR:
   3982             if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) {
   3983                 SOC_IF_ERROR_RETURN
   3984                     (soc_kt2_cosq_s0_sched_set(unit, parent->hw_index,
   3985                      (state == _BCM_KT2_COSQ_STATE_WRR_TO_SPRI) ? 1 : 0));
   3986                 return BCM_E_NONE;
   3987             }
   3988 
   3989             if (update_spri_vector) {
   3990 #ifdef BCM_KATANA2_SUPPORT
   3991                 if ( SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit) && !SOC_IS_METROLITE(unit) &&
   3992                      (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   3993                             BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) ) {
   3994                         SOC_IF_ERROR_RETURN(_bcm_egress_metering_freeze(unit,
   3995                                     gport, &setting));
   3996 
   3997                         rv = soc_kt2_cosq_max_bucket_set(unit, physical_port, node->parent->hw_index, _SOC_KT2_COSQ_NODE_LVL_L1);
   3998                         if (BCM_FAILURE(rv)) {
   3999                             SOC_IF_ERROR_RETURN(_bcm_egress_metering_thaw(unit, setting));
   4000                             return rv;
   4001                         }
   4002 
   4003                         rv = _bcm_kt2_cosq_l2_max_bucket_set(unit, physical_port, node);
   4004                         if (BCM_FAILURE(rv)) {
   4005                             SOC_IF_ERROR_RETURN(_bcm_egress_metering_thaw(unit, setting));
   4006                             return rv;
   4007                         }
   4008                         /*
   4009                          *  for WERR to SP it is possible to have the node in two list min and WERR which
   4010                          *  may lead to time out. To avoid this we need to configure the min as 0
   4011                          */
   4012                         rv = _bcm_kt2_cosq_min_clear(unit, physical_port, node);
   4013                         if (BCM_FAILURE(rv)) {
   4014                             SOC_IF_ERROR_RETURN(_bcm_egress_metering_thaw(unit, setting));
   4015                             return rv;
   4016                         }
   4017                         rv = _bcm_kt2_cosq_dynamic_sp_werr_change(unit, port,
   4018                                 node->level,
   4019                                 node->hw_index,
   4020                                 parent->hw_index, entry_c,
   4021                                 state);
   4022                         SOC_IF_ERROR_RETURN(_bcm_egress_metering_thaw(unit, setting));
   4023                         if (BCM_FAILURE(rv)) {
   4024                             return rv;
   4025                         }
   4026                 }else 
   4027 #endif                 
   4028                 {
   4029                     SOC_IF_ERROR_RETURN(_soc_egress_metering_freeze(unit,
   4030                                 physical_port, &setting));
   4031 
   4032                     rv = _bcm_kt2_cosq_l2_max_bucket_set(unit, physical_port, node);
   4033                     if (BCM_FAILURE(rv)) {
   4034                         SOC_IF_ERROR_RETURN(_soc_egress_metering_thaw(unit, physical_port, setting));
   4035                         return rv;
   4036                     }
   4037                     /*
   4038                      *  for WERR to SP it is possible to have the node in two list min and WERR which
   4039                      *  may lead to time out. To avoid this we need to configure the min as 0
   4040                      */
   4041                     rv = _bcm_kt2_cosq_min_clear(unit, physical_port, node);
   4042                     if (BCM_FAILURE(rv)) {
   4043                         SOC_IF_ERROR_RETURN(_soc_egress_metering_thaw(unit, physical_port, setting));
   4044                         return rv;
   4045                     }
   4046                     rv = _bcm_kt2_cosq_dynamic_sp_werr_change(unit, port,
   4047                             node->level,
   4048                             node->hw_index,
   4049                             parent->hw_index, entry_c,
   4050                             state);
   4051                     SOC_IF_ERROR_RETURN(_soc_egress_metering_thaw(unit, physical_port, setting));
   4052                     if (!BCM_SUCCESS(rv)) {
   4053                         return rv;
   4054                     }
   4055                 }
   4056             }
   4057             break;
   4058         default:
   4059             break;
   4060     }            
   4061     return BCM_E_NONE;
   4062 }
   4063 
   4064 /*
   4065  * Function:
   4066  *     _bcm_kt2_cosq_sched_node_set
   4067  * Purpose:
   4068  *     Set LLS scheduler registers based on GPORT
   4069  * Parameters:
   4070  *     unit       - (IN) unit number
   4071  *     gport      - (IN) queue group/scheduler GPORT identifier
   4072  * Returns:
   4073  *     BCM_E_XXX
   4074  */
   4075 STATIC int
   4076 _bcm_kt2_cosq_sched_node_set(int unit, bcm_gport_t gport, 
   4077                                     _bcm_kt2_cosq_state_t state)
   4078 {
   4079     if (soc_feature(unit, soc_feature_vector_based_spri)) {
   4080         return _bcm_kt2_cosq_sched_config_set(unit, gport, state);
   4081     }    
   4082     
   4083     return BCM_E_PARAM;
   4084 }
   4085 
   4086 /*
   4087  * Function:
   4088  *     _bcm_kt2_cosq_port_base_queue_get
   4089  * Purpose:
   4090  *     Get base queue node for a port given any gport
   4091  * Parameters:
   4092  *     unit                - (IN) unit number
   4093  *     port                - (IN) port number or GPORT identifier
   4094  *     cosq                - (IN) COS queue number
   4095  *     node                - (OUT) Base queue node 
   4096  * Returns:
   4097  *     BCM_E_XXX
   4098  */
   4099 STATIC int
   4100 _bcm_kt2_cosq_port_base_queue_get(int unit, bcm_port_t port, int cosq,
   4101                                   _bcm_kt2_cosq_node_t **node)
   4102 {
   4103     int queue_idx, numq, local_port;
   4104     _bcm_kt2_mmu_info_t *mmu_info;
   4105 
   4106     if (node == NULL) {
   4107         return BCM_E_PARAM;
   4108     }
   4109 
   4110     mmu_info = _bcm_kt2_mmu_info[unit];
   4111     BCM_IF_ERROR_RETURN
   4112         (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
   4113     numq = mmu_info->port[local_port].q_limit -
   4114                 mmu_info->port[local_port].q_offset;
   4115     if (cosq > numq) {
   4116         return BCM_E_PARAM;
   4117     }
   4118     queue_idx = mmu_info->port[local_port].q_offset + cosq;
   4119 
   4120     if (queue_idx > mmu_info->num_queues) {
   4121         return BCM_E_INTERNAL;
   4122     }
   4123     *node = &mmu_info->queue_node[queue_idx];
   4124     return BCM_E_NONE;
   4125 }
   4126 
   4127 /*
   4128  * Function:
   4129  *     _bcm_kt2_cosq_sched_set
   4130  * Purpose:
   4131  *     Set scheduling mode
   4132  * Parameters:
   4133  *     unit                - (IN) unit number
   4134  *     port                - (IN) port number or GPORT identifier
   4135  *     cosq                - (IN) COS queue number
   4136  *     mode                - (IN) scheduling mode (BCM_COSQ_XXX)
   4137  *     num_weights         - (IN) number of entries in weights array
   4138  *     weights             - (IN) weights array
   4139  * Returns:
   4140  *     BCM_E_XXX
   4141  */
   4142 STATIC int
   4143 _bcm_kt2_cosq_sched_set(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   4144                        int mode, int num_weights, const int weights[])
   4145 {
   4146     _bcm_kt2_mmu_info_t *mmu_info;
   4147     _bcm_kt2_cosq_node_t *node, *cur_node = NULL, *l0_node, *temp_node = NULL;
   4148     bcm_port_t local_port;
   4149     int index;
   4150     int i, default_weight = -1;
   4151     int max_weight;
   4152     uint32 fval;
   4153     lls_l0_child_weight_cfg_cnt_entry_t l0_weight_cfg;
   4154     lls_l1_child_weight_cfg_cnt_entry_t l1_weight_cfg; 
   4155     lls_l2_child_weight_cfg_cnt_entry_t l2_weight_cfg;
   4156     lls_l2_parent_entry_t l2_parent;
   4157     _bcm_kt2_cosq_state_t state = _BCM_KT2_COSQ_STATE_NO_CHANGE;
   4158     soc_mem_t mem;
   4159     uint32 entry[SOC_MAX_MEM_WORDS];
   4160     int rv;
   4161     int status = 0;
   4162     int physical_port;
   4163   
   4164     if (cosq < 0) {
   4165         if (cosq == -1) {
   4166             /* caller needs to resolve the wild card value (-1) */
   4167             return BCM_E_INTERNAL;
   4168         } else { /* reject all other negative value */
   4169             return BCM_E_PARAM;
   4170         }
   4171     }
   4172 
   4173     /* Validate weight values */
   4174     if (mode == BCM_COSQ_ROUND_ROBIN ||
   4175         mode == BCM_COSQ_WEIGHTED_ROUND_ROBIN ||
   4176         mode == BCM_COSQ_DEFICIT_ROUND_ROBIN ||
   4177         mode == BCM_COSQ_STRICT) {
   4178         max_weight =
   4179             (1 << soc_mem_field_length(unit, LLS_L0_CHILD_WEIGHT_CFG_CNTm, 
   4180                                        C_WEIGHTf)) - 1;
   4181         for (i = 0; i < num_weights; i++) {
   4182             if (weights[i] < 0 || weights[i] > max_weight) {
   4183                 return BCM_E_PARAM;
   4184             }
   4185         }
   4186     } else {
   4187         return BCM_E_PARAM;
   4188     }
   4189 
   4190     /* To support legacy device compatibility to configure STRICT
   4191        mode if weight is "0".
   4192      */
   4193     if ((num_weights == 1) && (weights[0] == BCM_COSQ_WEIGHT_STRICT)) {
   4194         mode =  BCM_COSQ_STRICT;
   4195     }
   4196 
   4197     mmu_info = _bcm_kt2_mmu_info[unit];
   4198 
   4199     if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
   4200         BCM_IF_ERROR_RETURN
   4201             (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
   4202         BCM_IF_ERROR_RETURN
   4203             (_bcm_kt2_cosq_port_base_queue_get(unit, port, cosq, &cur_node));
   4204         if (cur_node) {
   4205             node = cur_node->parent;
   4206         }
   4207     }
   4208     
   4209     if (BCM_GPORT_IS_SCHEDULER(port)) { /* ETS style scheduler */
   4210         BCM_IF_ERROR_RETURN
   4211             (_bcm_kt2_cosq_node_get(unit, port, NULL, &local_port, NULL,
   4212                                    &node));        
   4213         if ((node->wrr_mode == 1) && (mode == BCM_COSQ_STRICT)) {
   4214             return BCM_E_PARAM;
   4215         }
   4216     } else if (!BCM_GPORT_IS_SUBPORT_PORT(port)) {
   4217         BCM_IF_ERROR_RETURN
   4218             (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
   4219 
   4220         node = &mmu_info->sched_node[local_port];
   4221         
   4222         if (node->gport < 0) {
   4223             return BCM_E_PARAM;
   4224         }
   4225 
   4226         if ((node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) &&
   4227             ((node = node->child) == NULL)) {
   4228             return BCM_E_PARAM;
   4229         }
   4230 
   4231         if ((l0_node = node->child) == NULL) {
   4232             return BCM_E_PARAM;
   4233         }
   4234         if (((node = l0_node->child) == NULL) && !(IS_CPU_PORT(unit, local_port))) {
   4235             return BCM_E_PARAM;
   4236         }
   4237         /*
   4238          * Adding HG and LB port too. These two ports have 24 queues
   4239          * resulting in three L1 nodes. During scheduler configuration
   4240          * we need to find first L1 nodes which is last in sibling list.
   4241          */
   4242         if (IS_CPU_PORT(unit, local_port) ||
   4243             IS_HG_PORT(unit, local_port)  ||
   4244             IS_LB_PORT(unit, local_port)) { 
   4245             /*
   4246              * In case when number of cpu queues are not multiples of 8
   4247              * there is chance last siblings gets numq < 8,
   4248              * which may result in failure , So node is moved to the 
   4249              * first sibling, which guarantee to have numq = 8
   4250              */
   4251             for (cur_node = l0_node; cur_node->sibling != NULL;
   4252                  cur_node = cur_node->sibling);
   4253             for (cur_node = cur_node->child; cur_node->sibling != NULL;
   4254                  cur_node = cur_node->sibling);
   4255             node = cur_node;
   4256         }
   4257         if (soc_feature(unit, soc_feature_mmu_packing)) {
   4258             for (cur_node = node; cur_node != NULL;
   4259                     cur_node = cur_node->sibling) {
   4260                 if(cur_node->cosq_attached_to == cosq) {
   4261                     node = cur_node;
   4262                     break;
   4263                 }
   4264             }
   4265             if (cur_node == NULL) {
   4266                 /* this cosq is not yet attached */
   4267                 return BCM_E_INTERNAL;
   4268             }
   4269         }
   4270     }
   4271 
   4272     if (!BCM_GPORT_IS_SUBPORT_PORT(port)) {
   4273         if (!soc_feature(unit, soc_feature_mmu_packing)) {
   4274             if ((mode != BCM_COSQ_STRICT) && 
   4275                     (node->numq > 0 && (cosq + num_weights) > node->numq)) {
   4276                 return BCM_E_PARAM;
   4277             }
   4278 
   4279 
   4280             if (node->cosq_attached_to < 0) { /* Not resolved yet */
   4281                 return BCM_E_NOT_FOUND;
   4282             }
   4283 
   4284             for (cur_node = node->child; cur_node != NULL;
   4285                     cur_node = cur_node->sibling) {
   4286                 if (cur_node->cosq_attached_to == cosq) {
   4287                     break;
   4288                 }
   4289             }
   4290         } else {
   4291             for (cur_node = node->child; cur_node != NULL;
   4292                     cur_node = cur_node->sibling) {
   4293                 if (cur_node->cosq_attached_to == cosq) {
   4294                     break;
   4295                 }
   4296             }
   4297         }
   4298     }
   4299 
   4300     if (cur_node == NULL) {
   4301         /* this cosq is not yet attached */
   4302         return BCM_E_INTERNAL;
   4303     }
   4304 
   4305     if ((cur_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) &&
   4306         (mode == BCM_COSQ_STRICT)) {
   4307         /* S0 supports only RR. */
   4308         return BCM_E_PARAM;
   4309     }
   4310 
   4311     if (cur_node->wrr_in_use == 1 && mode == BCM_COSQ_STRICT) {
   4312         if (cur_node->cosq_attached_to >= 8) {
   4313             return BCM_E_PARAM;
   4314         }  
   4315         state = _BCM_KT2_COSQ_STATE_WRR_TO_SPRI;        
   4316     }    
   4317 
   4318     if (cur_node->wrr_in_use == 0 && mode != BCM_COSQ_STRICT) {
   4319         state = _BCM_KT2_COSQ_STATE_SPRI_TO_WRR;
   4320     }    
   4321 
   4322     if (state == _BCM_KT2_COSQ_STATE_SPRI_TO_WRR && 
   4323         cur_node->level == _BCM_KT2_COSQ_NODE_LEVEL_L2) {
   4324         SOC_IF_ERROR_RETURN
   4325             (READ_LLS_L2_PARENTm(unit, MEM_BLOCK_ALL, cur_node->hw_index, 
   4326                                  &l2_parent));
   4327         if (soc_mem_field32_get(unit, LLS_L2_PARENTm, 
   4328                                 &l2_parent, C_EFf) == 1) {
   4329             return BCM_E_PARAM;
   4330         }
   4331     }
   4332 
   4333     /* Protect LLS hierachy schedule mode change as
   4334      * port flush on link flap might be effected
   4335      * when there is a change in the LLS hierarchy
   4336      */
   4337     SOC_LLS_SCHEDULER_LOCK(unit);
   4338     soc_kt_port_flush_state_get(unit, local_port, &status);
   4339     if (status) {
   4340 
   4341         LOG_ERROR(BSL_LS_BCM_COSQ,
   4342              (BSL_META_U(unit,
   4343          "Unit %d Port %d is in flush state,"
   4344          "Cannot change LLS hierarchy scheduler mode for Cosq hw_cosq=%d.\n"),
   4345         unit, local_port, cur_node->cosq_attached_to));
   4346         SOC_LLS_SCHEDULER_UNLOCK(unit);
   4347         return BCM_E_RESOURCE;
   4348     }
   4349 
   4350     cur_node->wrr_in_use = (mode != BCM_COSQ_STRICT) ? 1 : 0;
   4351     if ((cur_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) &&
   4352         (node->num_child == 2)) {
   4353         if (cur_node->sibling != NULL) {
   4354             temp_node = cur_node->sibling;
   4355         } else if (node->child != NULL) {
   4356             temp_node = node->child;
   4357         }
   4358         if (temp_node) {
   4359             temp_node->wrr_in_use = (mode != BCM_COSQ_STRICT) ? 1 : 0;
   4360         }
   4361     }
   4362 
   4363     rv = _bcm_kt2_cosq_sched_node_set(unit, cur_node->gport, state);
   4364     SOC_LLS_SCHEDULER_UNLOCK(unit);
   4365     if (BCM_FAILURE(rv)) {
   4366         if (state == _BCM_KT2_COSQ_STATE_SPRI_TO_WRR) {
   4367             cur_node->wrr_in_use = 0;
   4368         } else if (state == _BCM_KT2_COSQ_STATE_WRR_TO_SPRI) {
   4369             cur_node->wrr_in_use = 1;
   4370         }
   4371         if ((cur_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) &&
   4372             (node->num_child == 2)) {
   4373             if (cur_node->sibling != NULL) {
   4374                 temp_node = cur_node->sibling;
   4375             } else if (node->child != NULL) {
   4376                 temp_node = node->child;
   4377             }
   4378             if (temp_node) {
   4379                 if (state == _BCM_KT2_COSQ_STATE_SPRI_TO_WRR) {
   4380                     temp_node->wrr_in_use = 0;
   4381                 } else if (state == _BCM_KT2_COSQ_STATE_WRR_TO_SPRI) {
   4382                     temp_node->wrr_in_use = 1;
   4383                 }
   4384             }
   4385         }
   4386         return rv;
   4387     }
   4388 
   4389     if ((mode != BCM_COSQ_STRICT))  {
   4390         if (_bcm_is_port_linkphy_subport(unit, port, -1)) {
   4391             BCM_IF_ERROR_RETURN(_bcm_subport_physical_port_get(unit, 
   4392                                             local_port, &physical_port));
   4393             local_port = physical_port;
   4394         }
   4395         mem = LLS_PORT_CONFIGm;
   4396         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL,
   4397                                          local_port, &entry));
   4398         fval = ((mode == BCM_COSQ_WEIGHTED_ROUND_ROBIN) ||
   4399                 (mode == BCM_COSQ_ROUND_ROBIN)) ? 1 : 0;
   4400         if (soc_mem_field32_get(unit, mem, entry,
   4401                                 PACKET_MODE_WRR_ACCOUNTING_ENABLEf) != fval) {
   4402             soc_mem_field32_set(unit, mem, entry,
   4403                                 PACKET_MODE_WRR_ACCOUNTING_ENABLEf, fval);
   4404             BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ANY,
   4405                                 local_port, &entry));
   4406         }
   4407     }
   4408 
   4409     /*
   4410      * Check mode and if it is BCM_COSQ_STRICT or BCM_COSQ_ROUND_ROBIN then 
   4411      * configure default_weight 0 or 1 respectively.
   4412      */
   4413     if (mode == BCM_COSQ_STRICT) {
   4414         default_weight = 0;
   4415     } else if ((node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) ||
   4416                (cur_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) ||
   4417                (mode == BCM_COSQ_ROUND_ROBIN)) {
   4418         default_weight = 1; 
   4419     }
   4420 
   4421     switch (node->level) {
   4422     case _BCM_KT2_COSQ_NODE_LEVEL_ROOT: /* port scheduler */
   4423     case _BCM_KT2_COSQ_NODE_LEVEL_S0: /* S0 scheduler */
   4424     case _BCM_KT2_COSQ_NODE_LEVEL_S1: /* S1 scheduler */
   4425         for (i = 0; i < num_weights; i++) {
   4426             BCM_IF_ERROR_RETURN
   4427                    (_bcm_kt2_cosq_index_resolve(unit, port, cosq + i,
   4428                                        _BCM_KT2_COSQ_INDEX_STYLE_SCHEDULER,
   4429                                        NULL, &index, NULL));
   4430             SOC_IF_ERROR_RETURN
   4431                    (READ_LLS_L0_CHILD_WEIGHT_CFG_CNTm(unit, MEM_BLOCK_ALL, 
   4432                                                       index, &l0_weight_cfg));
   4433             soc_mem_field32_set(unit, LLS_L0_CHILD_WEIGHT_CFG_CNTm, 
   4434                                 (uint32 *)&l0_weight_cfg, 
   4435                                 C_WEIGHTf, (default_weight == -1) ? weights[i] : default_weight); 
   4436             soc_mem_field32_set(unit, LLS_L0_CHILD_WEIGHT_CFG_CNTm, 
   4437                                 (uint32 *)&l0_weight_cfg, 
   4438                                 C_WEIGHT_SURPLUS_COUNTf, 0);
   4439             soc_mem_field32_set(unit, LLS_L0_CHILD_WEIGHT_CFG_CNTm, 
   4440                                 (uint32 *)&l0_weight_cfg, 
   4441                                 C_WEIGHT_COUNTf, 0);
   4442             SOC_IF_ERROR_RETURN
   4443                    (WRITE_LLS_L0_CHILD_WEIGHT_CFG_CNTm(unit, MEM_BLOCK_ALL, 
   4444                                                        index, &l0_weight_cfg));
   4445             if ((cur_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) &&
   4446                 (node->num_child == 2)) {
   4447                 if (cur_node->sibling != NULL) {
   4448                     index = cur_node->sibling->hw_index;
   4449                 } else if (node->child != NULL) {
   4450                     index = node->child->hw_index;
   4451                 }
   4452                 SOC_IF_ERROR_RETURN
   4453                     (READ_LLS_L0_CHILD_WEIGHT_CFG_CNTm(unit, MEM_BLOCK_ALL, 
   4454                                                         index, &l0_weight_cfg));
   4455                 soc_mem_field32_set(unit, LLS_L0_CHILD_WEIGHT_CFG_CNTm, 
   4456                                     (uint32 *)&l0_weight_cfg, 
   4457                                     C_WEIGHTf, (default_weight == -1) ? weights[i] : default_weight); 
   4458                 soc_mem_field32_set(unit, LLS_L0_CHILD_WEIGHT_CFG_CNTm, 
   4459                                     (uint32 *)&l0_weight_cfg, 
   4460                                     C_WEIGHT_SURPLUS_COUNTf, 0);
   4461                 soc_mem_field32_set(unit, LLS_L0_CHILD_WEIGHT_CFG_CNTm, 
   4462                                     (uint32 *)&l0_weight_cfg, 
   4463                                     C_WEIGHT_COUNTf, 0);
   4464                 SOC_IF_ERROR_RETURN
   4465                     (WRITE_LLS_L0_CHILD_WEIGHT_CFG_CNTm(unit, MEM_BLOCK_ALL, 
   4466                                                         index, &l0_weight_cfg));
   4467             }
   4468 
   4469         }
   4470         break;
   4471 
   4472     case _BCM_KT2_COSQ_NODE_LEVEL_L0: /* L0 scheduler */
   4473         for (i = 0; i < num_weights; i++) {
   4474             BCM_IF_ERROR_RETURN
   4475                    (_bcm_kt2_cosq_index_resolve(unit, port, cosq + i,
   4476                                        _BCM_KT2_COSQ_INDEX_STYLE_SCHEDULER,
   4477                                         NULL, &index, NULL));
   4478             SOC_IF_ERROR_RETURN
   4479                    (READ_LLS_L1_CHILD_WEIGHT_CFG_CNTm(unit, MEM_BLOCK_ALL, 
   4480                                                       index, &l1_weight_cfg));
   4481             soc_mem_field32_set(unit, LLS_L1_CHILD_WEIGHT_CFG_CNTm, 
   4482                                 (uint32 *)&l1_weight_cfg, 
   4483                                 C_WEIGHTf, (default_weight == -1) ? weights[i] : default_weight); 
   4484             soc_mem_field32_set(unit, LLS_L1_CHILD_WEIGHT_CFG_CNTm, 
   4485                                 (uint32 *)&l1_weight_cfg, 
   4486                                 C_WEIGHT_SURPLUS_COUNTf, 0);
   4487             soc_mem_field32_set(unit, LLS_L1_CHILD_WEIGHT_CFG_CNTm, 
   4488                                 (uint32 *)&l1_weight_cfg, 
   4489                                 C_WEIGHT_COUNTf, 0);
   4490             SOC_IF_ERROR_RETURN
   4491                    (WRITE_LLS_L1_CHILD_WEIGHT_CFG_CNTm(unit, MEM_BLOCK_ALL, 
   4492                                                        index, &l1_weight_cfg));
   4493 
   4494         }
   4495         break;
   4496 
   4497     case _BCM_KT2_COSQ_NODE_LEVEL_L1: /* L1 scheduler */
   4498         for (i = 0; i < num_weights; i++) {
   4499             BCM_IF_ERROR_RETURN
   4500                    (_bcm_kt2_cosq_index_resolve(unit, port, cosq + i,
   4501                                        _BCM_KT2_COSQ_INDEX_STYLE_SCHEDULER,
   4502                                         NULL, &index, NULL));
   4503             SOC_IF_ERROR_RETURN
   4504                    (READ_LLS_L2_CHILD_WEIGHT_CFG_CNTm(unit, MEM_BLOCK_ALL, 
   4505                                                       index, &l2_weight_cfg));
   4506             soc_mem_field32_set(unit, LLS_L2_CHILD_WEIGHT_CFG_CNTm, 
   4507                                 (uint32 *)&l2_weight_cfg, 
   4508                                 C_WEIGHTf, (default_weight == -1) ? weights[i] : default_weight); 
   4509             soc_mem_field32_set(unit, LLS_L2_CHILD_WEIGHT_CFG_CNTm, 
   4510                                 (uint32 *)&l2_weight_cfg, 
   4511                                 C_WEIGHT_SURPLUS_COUNTf, 0);
   4512             soc_mem_field32_set(unit, LLS_L2_CHILD_WEIGHT_CFG_CNTm, 
   4513                                 (uint32 *)&l2_weight_cfg, 
   4514                                 C_WEIGHT_COUNTf, 0);
   4515             SOC_IF_ERROR_RETURN
   4516                    (WRITE_LLS_L2_CHILD_WEIGHT_CFG_CNTm(unit, MEM_BLOCK_ALL, 
   4517                                                        index, &l2_weight_cfg));
   4518 
   4519         }
   4520         break;
   4521 
   4522     default:
   4523         return BCM_E_INTERNAL;
   4524     }
   4525 
   4526     return BCM_E_NONE;
   4527 }
   4528 
   4529 /*
   4530  * Function:
   4531  *     _bcm_kt2_cosq_sched_get
   4532  * Purpose:
   4533  *     Get scheduling mode setting
   4534  * Parameters:
   4535  *     unit                - (IN) unit number
   4536  *     port                - (IN) port number or GPORT identifier
   4537  *     cosq                - (IN) COS queue number
   4538  *     mode                - (OUT) scheduling mode (BCM_COSQ_XXX)
   4539  *     num_weights         - (IN) number of entries in weights array
   4540  *     weights             - (OUT) weights array
   4541  * Returns:
   4542  *     BCM_E_XXX
   4543  */
   4544 STATIC int
   4545 _bcm_kt2_cosq_sched_get(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   4546                        int *mode, int num_weights, int weights[])
   4547 {
   4548     _bcm_kt2_mmu_info_t *mmu_info; 
   4549     _bcm_kt2_cosq_node_t *node = NULL, *l0_node = NULL;
   4550     _bcm_kt2_cosq_node_t *cur_node = NULL;
   4551     bcm_port_t local_port;
   4552     int index;
   4553     int i;
   4554     lls_l0_child_weight_cfg_cnt_entry_t l0_weight_cfg;
   4555     lls_l1_child_weight_cfg_cnt_entry_t l1_weight_cfg;
   4556     lls_l2_child_weight_cfg_cnt_entry_t l2_weight_cfg;
   4557     soc_mem_t mem;
   4558     uint32 entry[SOC_MAX_MEM_WORDS];
   4559     int physical_port;
   4560 
   4561     if (cosq < 0) {
   4562         if (cosq == -1) {
   4563             /* caller needs to resolve the wild card value (-1) */
   4564             return BCM_E_INTERNAL;
   4565         } else { /* reject all other negative value */
   4566             return BCM_E_PARAM;
   4567         }
   4568     }
   4569 
   4570     if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
   4571         BCM_IF_ERROR_RETURN
   4572             (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
   4573         BCM_IF_ERROR_RETURN
   4574             (_bcm_kt2_cosq_port_base_queue_get(unit, port, cosq, &cur_node));
   4575         if (cur_node) {
   4576             node = cur_node->parent;
   4577         }
   4578     }
   4579 
   4580     if (BCM_GPORT_IS_SCHEDULER(port)) { /* ETS style scheduler */
   4581            BCM_IF_ERROR_RETURN
   4582                (_bcm_kt2_cosq_node_get(unit, port, NULL, &local_port, NULL,
   4583                                       &node));
   4584     } else if (!BCM_GPORT_IS_SUBPORT_PORT(port)) {
   4585         if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)) {
   4586             local_port = _BCM_KT2_SUBPORT_PORT_ID_GET(port);
   4587         } else {
   4588              BCM_IF_ERROR_RETURN
   4589                  (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
   4590         }  
   4591         mmu_info = _bcm_kt2_mmu_info[unit];
   4592 
   4593         node = &mmu_info->sched_node[local_port];
   4594         
   4595         if (node->gport < 0) {
   4596             return BCM_E_PARAM;
   4597         }
   4598 
   4599         if ((node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) &&
   4600             ((node = node->child) == NULL)) {
   4601             return BCM_E_PARAM;
   4602         }
   4603 
   4604         if ((l0_node = node->child) == NULL) {
   4605             return BCM_E_PARAM;
   4606         }
   4607         if (((node = l0_node->child) == NULL) && !(IS_CPU_PORT(unit, local_port))) {
   4608             return BCM_E_PARAM;
   4609         }
   4610         /*
   4611          * Adding HG and LB port too. These two ports have 24 queues
   4612          * resulting in three L1 nodes. During scheduler configuration
   4613          * we need to find first L1 nodes which is last in sibling list.
   4614          */
   4615         if (IS_CPU_PORT(unit, local_port) ||
   4616             IS_HG_PORT(unit, local_port)  ||
   4617             IS_LB_PORT(unit, local_port)) {
   4618             /*
   4619              * In case when number of cpu queues are not multiples of 8
   4620              * there is chance last siblings gets numq < 8,
   4621              * which may result in failure , So node is moved to the 
   4622              * first sibling, which guarantee to have numq = 8
   4623              */
   4624             for (cur_node = l0_node; cur_node->sibling != NULL;
   4625                  cur_node = cur_node->sibling);
   4626             for (cur_node = cur_node->child; cur_node->sibling != NULL;
   4627                  cur_node = cur_node->sibling);
   4628             node = cur_node;
   4629         }
   4630     }
   4631 
   4632     if (node == NULL) {
   4633         return BCM_E_INTERNAL;
   4634     }
   4635     if (node->numq > 0 && (cosq + num_weights) > node->numq) {
   4636         return BCM_E_PARAM;
   4637     }
   4638 
   4639     if (node->cosq_attached_to < 0) { /* Not resolved yet */
   4640         return BCM_E_NOT_FOUND;
   4641     }
   4642 
   4643     if (!BCM_GPORT_IS_SUBPORT_PORT(port)) {
   4644         for (cur_node = node->child; cur_node != NULL;
   4645             cur_node = cur_node->sibling) {
   4646             if (cur_node->cosq_attached_to == cosq) {
   4647                 break;
   4648             }
   4649         }
   4650     }
   4651 
   4652     if (cur_node == NULL) {
   4653         /* this cosq is not yet attached */
   4654         return BCM_E_INTERNAL;
   4655     }
   4656     
   4657     switch (node->level) {
   4658     case _BCM_KT2_COSQ_NODE_LEVEL_ROOT: /* port scheduler */
   4659     case _BCM_KT2_COSQ_NODE_LEVEL_S0: /* S0 scheduler */
   4660     case _BCM_KT2_COSQ_NODE_LEVEL_S1: /* S1 scheduler */
   4661         for (i = 0; i < num_weights; i++) {
   4662             BCM_IF_ERROR_RETURN
   4663                 (_bcm_kt2_cosq_index_resolve(unit, port, cosq + i,
   4664                                         _BCM_KT2_COSQ_INDEX_STYLE_SCHEDULER,
   4665                                         NULL, &index, NULL));
   4666             SOC_IF_ERROR_RETURN
   4667                 (READ_LLS_L0_CHILD_WEIGHT_CFG_CNTm(unit, MEM_BLOCK_ALL, 
   4668                                                 index, &l0_weight_cfg));
   4669             weights[i] = soc_mem_field32_get(unit, LLS_L0_CHILD_WEIGHT_CFG_CNTm,
   4670                                             (uint32 *)&l0_weight_cfg, 
   4671                                             C_WEIGHTf);
   4672         }
   4673         break;
   4674 
   4675     case _BCM_KT2_COSQ_NODE_LEVEL_L0: /* L0 scheduler */
   4676         for (i = 0; i < num_weights; i++) {
   4677             BCM_IF_ERROR_RETURN
   4678                 (_bcm_kt2_cosq_index_resolve(unit, port, cosq + i,
   4679                                         _BCM_KT2_COSQ_INDEX_STYLE_SCHEDULER,
   4680                                         NULL, &index, NULL));
   4681             SOC_IF_ERROR_RETURN
   4682                 (READ_LLS_L1_CHILD_WEIGHT_CFG_CNTm(unit, MEM_BLOCK_ALL,
   4683                                                    index, &l1_weight_cfg));
   4684             weights[i] = soc_mem_field32_get(unit, LLS_L1_CHILD_WEIGHT_CFG_CNTm,
   4685                                              (uint32 *)&l1_weight_cfg, 
   4686                                              C_WEIGHTf);
   4687 
   4688         }
   4689         break;
   4690 
   4691     case _BCM_KT2_COSQ_NODE_LEVEL_L1: /* L1 scheduler */
   4692         for (i = 0; i < num_weights; i++) {
   4693             BCM_IF_ERROR_RETURN
   4694                 (_bcm_kt2_cosq_index_resolve(unit, port, cosq + i,
   4695                                         _BCM_KT2_COSQ_INDEX_STYLE_SCHEDULER,
   4696                                         NULL, &index, NULL));
   4697             SOC_IF_ERROR_RETURN
   4698                 (READ_LLS_L2_CHILD_WEIGHT_CFG_CNTm(unit, MEM_BLOCK_ALL, 
   4699                                                    index, &l2_weight_cfg));
   4700             weights[i] = soc_mem_field32_get(unit, LLS_L2_CHILD_WEIGHT_CFG_CNTm,
   4701                                              (uint32 *)&l2_weight_cfg, 
   4702                                              C_WEIGHTf);
   4703 
   4704         }
   4705         break;
   4706     default:
   4707         return BCM_E_INTERNAL;
   4708     }
   4709 
   4710     if (cur_node->wrr_in_use == 0) {
   4711         *mode = BCM_COSQ_STRICT;   
   4712     } else {
   4713         if (_bcm_is_port_linkphy_subport(unit, port, -1)) {
   4714             BCM_IF_ERROR_RETURN(_bcm_subport_physical_port_get(unit, 
   4715                                             local_port, &physical_port));
   4716             local_port = physical_port;
   4717         }
   4718         mem = LLS_PORT_CONFIGm;
   4719         BCM_IF_ERROR_RETURN(
   4720                 soc_mem_read(unit, mem, MEM_BLOCK_ALL, local_port, &entry));
   4721         if (soc_mem_field32_get(unit, mem, entry,
   4722                    PACKET_MODE_WRR_ACCOUNTING_ENABLEf)) {
   4723             *mode = BCM_COSQ_WEIGHTED_ROUND_ROBIN;
   4724         } else {
   4725             *mode = BCM_COSQ_DEFICIT_ROUND_ROBIN;
   4726         }
   4727     }
   4728     
   4729     return BCM_E_NONE;
   4730 }
   4731 
   4732 /*
   4733  * Function:
   4734  *     _bcm_kt2_cosq_port_sched_set
   4735  * Purpose:
   4736  *     Set scheduling mode setting for a port
   4737  * Parameters:
   4738  *     unit                - (IN) unit number
   4739  *     port                - (IN) port number or GPORT identifier
   4740  *     cosq                - (IN) COS queue number
   4741  *     mode                - (IN) scheduling mode (BCM_COSQ_XXX)
   4742  *     num_weights         - (IN) number of entries in weights array
   4743  *     weights             - (IN) weights array
   4744  * Returns:
   4745  *     BCM_E_XXX
   4746  */
   4747 STATIC int
   4748 _bcm_kt2_cosq_port_sched_set(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   4749                              int mode, int num_weights, int *weights)
   4750 {
   4751     int i;
   4752 
   4753     for (i = 0; i < num_weights; i++) {
   4754         BCM_IF_ERROR_RETURN
   4755             (_bcm_kt2_cosq_sched_set(unit, port, (cosq + i), 
   4756                                      mode, 1, &weights[i])); 
   4757                                      
   4758     }
   4759 
   4760     return BCM_E_NONE;
   4761 }
   4762 
   4763 /*
   4764  * Function:
   4765  *     _bcm_kt2_cosq_port_sched_get
   4766  * Purpose:
   4767  *     Set scheduling mode setting for a port
   4768  * Parameters:
   4769  *     unit                - (IN) unit number
   4770  *     port                - (IN) port number or GPORT identifier
   4771  *     cosq                - (IN) COS queue number
   4772  *     mode                - (OUT) scheduling mode (BCM_COSQ_XXX)
   4773  *     num_weights         - (IN) number of entries in weights array
   4774  *     weights             - (OUT) weights array
   4775  * Returns:
   4776  *     BCM_E_XXX
   4777  */
   4778 STATIC int
   4779 _bcm_kt2_cosq_port_sched_get(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   4780                              int *mode, int num_weights, int *weights)
   4781 {
   4782     int i;
   4783 
   4784     for (i = 0; i < num_weights; i++) {
   4785         BCM_IF_ERROR_RETURN
   4786             (_bcm_kt2_cosq_sched_get(unit, port, (cosq + i), 
   4787                                      mode, 1, &weights[i])); 
   4788                                      
   4789     }
   4790     
   4791     return BCM_E_NONE;
   4792 }
   4793 
   4794 /*
   4795  * Function:
   4796  *     _bcm_kt2_cosq_gport_egress_mapping_set_regular
   4797  * Purpose:
   4798  *     Determine which COS queue a given priority currently maps to.
   4799  * Parameters:
   4800  *     unit     - (IN) unit number
   4801  *     gport    - (IN) queue group GPORT identifier
   4802  *     priority - (IN) priority value to map
   4803  *     cosq     - (IN) COS queue to map to
   4804  * Returns:
   4805  *     BCM_E_XXX
   4806  */
   4807 STATIC int
   4808 _bcm_kt2_cosq_gport_egress_mapping_set_regular(int unit, bcm_port_t gport, 
   4809                                   bcm_cos_t priority,
   4810                                   bcm_cos_queue_t cosq , int flags)
   4811 {
   4812     bcm_port_t port;
   4813     soc_field_t field = REDIRECT_COSf;
   4814     egr_port_entry_t egr_port_entry;
   4815     egr_cos_map_entry_t cos_map_entries[16];
   4816     void *entries[1];     
   4817     uint32 old_index, new_index;
   4818     int rv;
   4819     
   4820     if (priority < 0 || priority >= 16) {
   4821         return BCM_E_PARAM;
   4822     }
   4823 
   4824     if (BCM_GPORT_IS_SET(gport)) {
   4825         BCM_IF_ERROR_RETURN(
   4826                 bcm_esw_port_local_get(unit, gport, &port));
   4827     } else {
   4828         port = gport;
   4829     }
   4830 
   4831     if (cosq < 0 || cosq > 7) {
   4832         return BCM_E_PARAM;
   4833     }
   4834     
   4835     if (!SOC_PORT_VALID(unit, port) || !IS_ALL_PORT(unit, port)) {
   4836         return BCM_E_PORT;
   4837     }
   4838 
   4839 
   4840     entries[0] = &cos_map_entries;
   4841 
   4842     BCM_IF_ERROR_RETURN
   4843         (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port_entry));
   4844     old_index = soc_mem_field32_get(unit, EGR_PORTm, &egr_port_entry,
   4845                                     EGR_COS_MAP_SELf);
   4846     old_index *= 16;
   4847 
   4848     soc_mem_lock(unit, EGR_PORTm);
   4849 
   4850     rv = soc_profile_mem_get(unit, _bcm_kt2_egr_cos_map_profile[unit],
   4851                              old_index, 16, entries);
   4852     if (BCM_SUCCESS(rv)) {
   4853         soc_mem_field32_set(unit, EGR_COS_MAPm, &cos_map_entries[priority], field,
   4854                             cosq);
   4855 
   4856         rv = soc_profile_mem_delete(unit, _bcm_kt2_egr_cos_map_profile[unit],
   4857                                     old_index);
   4858         if (BCM_FAILURE(rv)) {
   4859             soc_mem_unlock(unit, EGR_PORTm);
   4860             return rv;
   4861         }
   4862 
   4863         rv = soc_profile_mem_add(unit, _bcm_kt2_egr_cos_map_profile[unit], entries,
   4864                                 16, &new_index);
   4865         if (rv == SOC_E_RESOURCE) {
   4866             (void)soc_profile_mem_reference(unit, _bcm_kt2_egr_cos_map_profile[unit],
   4867                                             old_index, 16);
   4868         }
   4869     } else {
   4870         rv = soc_profile_mem_add(unit, _bcm_kt2_egr_cos_map_profile[unit], entries,
   4871                 16, &new_index);
   4872     }
   4873 
   4874     soc_mem_unlock(unit, EGR_PORTm);
   4875 
   4876     if (BCM_FAILURE(rv)) {
   4877         return rv;
   4878     }
   4879 
   4880     soc_mem_field32_set(unit, EGR_PORTm, &egr_port_entry, EGR_COS_MAP_SELf, 
   4881                         new_index / 16);
   4882     BCM_IF_ERROR_RETURN
   4883         (WRITE_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port_entry));
   4884 
   4885     return BCM_E_NONE;
   4886 }
   4887 /*
   4888  * Function:
   4889  *     _bcm_kt2_cosq_mapping_set_regular
   4890  * Purpose:
   4891  *     Determine which COS queue a given priority currently maps to.
   4892  * Parameters:
   4893  *     unit           - (IN) unit number
   4894  *     gport          - (IN) queue group GPORT identifier
   4895  *     count          - (IN) number of entries to be configured
   4896  *     priority_array - (IN) priority array value to map
   4897  *     cosq_array     - (IN) COS queue array to map to
   4898  * Returns:
   4899  *     BCM_E_XXX
   4900  */
   4901 STATIC int
   4902 _bcm_kt2_cosq_mapping_set_regular(int unit, bcm_port_t gport,
   4903                                   int count, 
   4904                                   bcm_cos_t *priority_array,
   4905                                   bcm_cos_queue_t *cosq_array)
   4906 {
   4907     _bcm_kt2_mmu_info_t *mmu_info;
   4908     bcm_port_t port;
   4909     int numq;
   4910     bcm_cos_queue_t hw_cosq[16];
   4911     soc_field_t field = COSf;
   4912     cos_map_sel_entry_t cos_map_sel_entry;
   4913     port_cos_map_entry_t cos_map_entries[16];
   4914     void *entries[1];     
   4915     uint32 old_index, new_index;
   4916     int count_index= 0;
   4917     int rv;
   4918 #ifndef BCM_COSQ_HIGIG_MAP_DISABLE
   4919     int cpu_hg_index = 0;
   4920 #endif
   4921     
   4922     if (count < 1 || count > 16) {
   4923         return BCM_E_PARAM;
   4924     }
   4925 
   4926     if (priority_array == NULL || cosq_array == NULL){
   4927         return BCM_E_PARAM;
   4928     }
   4929 
   4930     for (count_index = 0; count_index < count; count_index++) {
   4931         if (priority_array[count_index] < 0 || priority_array[count_index] >= 16) {
   4932             return BCM_E_PARAM;
   4933         }
   4934 
   4935         hw_cosq[count_index] = cosq_array[count_index];
   4936     }
   4937  
   4938     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   4939         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   4940         for (count_index = 0; count_index < count; count_index++) {
   4941             BCM_IF_ERROR_RETURN
   4942                 (_bcm_kt2_cosq_index_resolve
   4943                  (unit, gport, cosq_array[count_index], _BCM_KT2_COSQ_INDEX_STYLE_UCAST_QUEUE,
   4944                   &port, &(hw_cosq[count_index]), NULL));
   4945         }
   4946     } else if(_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT (unit, gport)) {
   4947         port = _BCM_KT2_SUBPORT_PORT_ID_GET(gport);
   4948     } else { 
   4949         if (BCM_GPORT_IS_SET(gport)) {
   4950             BCM_IF_ERROR_RETURN(
   4951                 bcm_esw_port_local_get(unit, gport, &port));
   4952         } else {
   4953             port = gport;
   4954         }
   4955 
   4956         if (!SOC_PORT_VALID(unit, port) || !IS_ALL_PORT(unit, port)) {
   4957             return BCM_E_PORT;
   4958         }
   4959 
   4960     }
   4961 
   4962     mmu_info = _bcm_kt2_mmu_info[unit];
   4963     numq = mmu_info->port[port].q_limit - 
   4964         mmu_info->port[port].q_offset;
   4965    
   4966     for (count_index = 0; count_index < count; count_index++) {
   4967         if (cosq_array[count_index] >= numq) {
   4968             return BCM_E_PARAM;
   4969         }
   4970 
   4971     }
   4972     
   4973     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   4974         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   4975         field = (numq <= 8) ? COSf : HG_COSf;
   4976     }
   4977 
   4978     entries[0] = &cos_map_entries;
   4979 
   4980     BCM_IF_ERROR_RETURN
   4981         (READ_COS_MAP_SELm(unit, MEM_BLOCK_ANY, port, &cos_map_sel_entry));
   4982     old_index = soc_mem_field32_get(unit, COS_MAP_SELm, &cos_map_sel_entry,
   4983                                     SELECTf);
   4984     old_index *= 16;
   4985 
   4986     soc_mem_lock(unit, PORT_COS_MAPm);
   4987 
   4988     rv = soc_profile_mem_get(unit, _bcm_kt2_cos_map_profile[unit],
   4989                              old_index, 16, entries);
   4990     if (BCM_SUCCESS(rv)) {
   4991         for (count_index = 0; count_index < count; count_index++) {
   4992             soc_mem_field32_set(unit, PORT_COS_MAPm, &cos_map_entries[priority_array[count_index]], field,
   4993                     hw_cosq[count_index]);
   4994         }
   4995 
   4996 
   4997         rv = soc_profile_mem_delete(unit, _bcm_kt2_cos_map_profile[unit],
   4998                                     old_index);
   4999 #ifndef BCM_COSQ_HIGIG_MAP_DISABLE
   5000         if (BCM_SUCCESS(rv) && IS_CPU_PORT(unit, port)) {
   5001             rv = soc_profile_mem_delete(unit, _bcm_kt2_cos_map_profile[unit],
   5002                                         old_index);
   5003         }
   5004 #endif /* BCM_COSQ_HIGIG_MAP_DISABLE */
   5005         if (BCM_FAILURE(rv)) {
   5006             soc_mem_unlock(unit, PORT_COS_MAPm);
   5007             return rv;
   5008         }
   5009 
   5010         rv = soc_profile_mem_add(unit, _bcm_kt2_cos_map_profile[unit], entries,
   5011                                 16, &new_index);
   5012 #ifndef BCM_COSQ_HIGIG_MAP_DISABLE
   5013         if (BCM_SUCCESS(rv) && IS_CPU_PORT(unit, port)) {
   5014             rv = soc_profile_mem_reference(unit, _bcm_kt2_cos_map_profile[unit],
   5015                                         new_index, 16);
   5016         }
   5017 #endif /* BCM_COSQ_HIGIG_MAP_DISABLE */
   5018 
   5019         if (rv == SOC_E_RESOURCE) {
   5020             (void)soc_profile_mem_reference(unit, _bcm_kt2_cos_map_profile[unit],
   5021                                             old_index, 16);
   5022 #ifndef BCM_COSQ_HIGIG_MAP_DISABLE
   5023             if (IS_CPU_PORT(unit, port)) {
   5024                 (void)soc_profile_mem_reference(unit,
   5025                                                 _bcm_kt2_cos_map_profile[unit],
   5026                                                 old_index, 16);
   5027             }
   5028 #endif /* BCM_COSQ_HIGIG_MAP_DISABLE */
   5029         }
   5030     } else {
   5031         rv = soc_profile_mem_add(unit, _bcm_kt2_cos_map_profile[unit], entries,
   5032                 16, &new_index);
   5033 #ifndef BCM_COSQ_HIGIG_MAP_DISABLE
   5034         if (BCM_SUCCESS(rv) && IS_CPU_PORT(unit, port)) {
   5035             rv = soc_profile_mem_reference(unit, _bcm_kt2_cos_map_profile[unit],
   5036                     new_index, 16);
   5037         }
   5038 #endif /* BCM_COSQ_HIGIG_MAP_DISABLE */
   5039     }
   5040 
   5041     soc_mem_unlock(unit, PORT_COS_MAPm);
   5042 
   5043     if (BCM_FAILURE(rv)) {
   5044         return rv;
   5045     }
   5046 
   5047     soc_mem_field32_set(unit, COS_MAP_SELm, &cos_map_sel_entry, SELECTf,
   5048                         new_index / 16);
   5049     BCM_IF_ERROR_RETURN
   5050         (WRITE_COS_MAP_SELm(unit, MEM_BLOCK_ANY, port, &cos_map_sel_entry));
   5051 
   5052 #ifndef BCM_COSQ_HIGIG_MAP_DISABLE
   5053     if (IS_CPU_PORT(unit, port)) {
   5054         cpu_hg_index = SOC_INFO(unit).cpu_hg_pp_port_index;
   5055         BCM_IF_ERROR_RETURN
   5056             (soc_mem_field32_modify(unit, COS_MAP_SELm,
   5057                                     cpu_hg_index, SELECTf,
   5058                                     new_index / 16));
   5059     }
   5060 #endif /* BCM_COSQ_HIGIG_MAP_DISABLE */
   5061 
   5062     return BCM_E_NONE;
   5063 }
   5064 
   5065 /*
   5066  * Function:
   5067  *     _bcm_kt2_cosq_bucket_set
   5068  * Purpose:
   5069  *     Configure COS queue bandwidth control bucket
   5070  * Parameters:
   5071  *     unit          - (IN) unit number
   5072  *     port          - (IN) port number or GPORT identifier
   5073  *     cosq          - (IN) COS queue number
   5074  *     min_quantum   - (IN) kbps or packet/second
   5075  *     max_quantum   - (IN) kbps or packet/second
   5076  *     burst_quantum - (IN) kbps or packet/second
   5077  *     flags         - (IN)
   5078  * Returns:
   5079  *     BCM_E_XXX
   5080  * Notes:
   5081  *     If port is any form of local port, cosq is the hardware queue index.
   5082  */
   5083 STATIC int
   5084 _bcm_kt2_cosq_bucket_set(int unit, bcm_gport_t port, bcm_cos_queue_t cosq,
   5085                         uint32 min_quantum, uint32 max_quantum,
   5086                         uint32 burst_min_quantum, uint32 burst_max_quantum,
   5087                         uint32 flags)
   5088 {
   5089     int rv;
   5090     _bcm_kt2_cosq_node_t *node;
   5091     bcm_port_t local_port;
   5092     int index;
   5093     soc_mem_t config_mem[2];
   5094     lls_port_shaper_config_c_entry_t port_entry;
   5095     lls_l0_shaper_config_c_entry_t  l0_entry;
   5096     lls_l1_shaper_config_c_entry_t  l1_entry;
   5097     lls_l2_shaper_config_lower_entry_t l2_entry;
   5098     lls_s0_shaper_config_c_entry_t s0_entry;
   5099     uint32 rate_exp[2], rate_mantissa[2];
   5100     uint32 burst_exp[2], burst_mantissa[2];
   5101     uint32 cycle_sel[2];
   5102     uint32 burst_min, burst_max;
   5103     int i, idx, status;
   5104     int level = _BCM_KT2_COSQ_NODE_LEVEL_L2;
   5105     soc_field_t rate_exp_f[] = {
   5106         C_MAX_REF_RATE_EXPf, C_MIN_REF_RATE_EXPf
   5107     };
   5108     soc_field_t rate_mant_f[] = {
   5109         C_MAX_REF_RATE_MANTf, C_MIN_REF_RATE_MANTf
   5110     };
   5111     soc_field_t burst_exp_f[] = {
   5112         C_MAX_THLD_EXPf, C_MIN_THLD_EXPf
   5113     };
   5114     soc_field_t burst_mant_f[] = {
   5115         C_MAX_THLD_MANTf, C_MIN_THLD_MANTf
   5116     };
   5117     soc_field_t cycle_sel_f[] = {
   5118         C_MAX_CYCLE_SELf, C_MIN_CYCLE_SELf
   5119     };
   5120     soc_field_t rate_exp_fields[] = {
   5121        C_MAX_REF_RATE_EXP_0f, C_MAX_REF_RATE_EXP_1f,
   5122        C_MAX_REF_RATE_EXP_2f, C_MAX_REF_RATE_EXP_3f,
   5123        C_MIN_REF_RATE_EXP_0f, C_MIN_REF_RATE_EXP_1f,
   5124        C_MIN_REF_RATE_EXP_2f, C_MIN_REF_RATE_EXP_3f
   5125     };
   5126     soc_field_t rate_mant_fields[] = {
   5127        C_MAX_REF_RATE_MANT_0f, C_MAX_REF_RATE_MANT_1f,
   5128        C_MAX_REF_RATE_MANT_2f, C_MAX_REF_RATE_MANT_3f,
   5129        C_MIN_REF_RATE_MANT_0f, C_MIN_REF_RATE_MANT_1f,
   5130        C_MIN_REF_RATE_MANT_2f, C_MIN_REF_RATE_MANT_3f
   5131     };
   5132     soc_field_t burst_exp_fields[] = {
   5133        C_MAX_THLD_EXP_0f, C_MAX_THLD_EXP_1f,
   5134        C_MAX_THLD_EXP_2f, C_MAX_THLD_EXP_3f,
   5135        C_MIN_THLD_EXP_0f, C_MIN_THLD_EXP_1f,
   5136        C_MIN_THLD_EXP_2f, C_MIN_THLD_EXP_3f
   5137     };
   5138     soc_field_t burst_mant_fields[] = {
   5139        C_MAX_THLD_MANT_0f, C_MAX_THLD_MANT_1f,
   5140        C_MAX_THLD_MANT_2f, C_MAX_THLD_MANT_3f,
   5141        C_MIN_THLD_MANT_0f, C_MIN_THLD_MANT_1f,
   5142        C_MIN_THLD_MANT_2f, C_MIN_THLD_MANT_3f
   5143     };
   5144     soc_field_t cycle_sel_fields[] = {
   5145         C_MAX_CYCLE_SEL_0f, C_MAX_CYCLE_SEL_1f,
   5146         C_MAX_CYCLE_SEL_2f, C_MAX_CYCLE_SEL_3f,    
   5147         C_MIN_CYCLE_SEL_0f, C_MIN_CYCLE_SEL_1f,
   5148         C_MIN_CYCLE_SEL_2f, C_MIN_CYCLE_SEL_3f
   5149     };
   5150     int shaper_bucket_index = 0;
   5151 
   5152     if (cosq < 0) {
   5153         if (cosq == -1) {
   5154             /* caller needs to resolve the wild card value (-1) */
   5155             return BCM_E_INTERNAL;
   5156         } else { /* reject all other negative value */
   5157             return BCM_E_PARAM;
   5158         }
   5159     }
   5160 
   5161 
   5162     BCM_IF_ERROR_RETURN
   5163         (_bcm_kt2_cosq_index_resolve(unit, port, cosq,
   5164                                     _BCM_KT2_COSQ_INDEX_STYLE_BUCKET,
   5165                                     &local_port, &index, NULL));
   5166     
   5167     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(port) ||
   5168         BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
   5169         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   5170         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   5171         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) || 
   5172         BCM_GPORT_IS_SCHEDULER(port)) {
   5173         BCM_IF_ERROR_RETURN
   5174             (_bcm_kt2_cosq_node_get(unit, port, NULL, NULL, NULL, &node));
   5175         level = node->level;    
   5176 
   5177         if ((level == _BCM_KT2_COSQ_NODE_LEVEL_S0 || 
   5178             level == _BCM_KT2_COSQ_NODE_LEVEL_S1  || 
   5179             level== _BCM_KT2_COSQ_NODE_LEVEL_ROOT) && 
   5180             (min_quantum > 0)) {
   5181             /* min shaper is not supported */
   5182             return BCM_E_PARAM;
   5183         }
   5184     }
   5185 
   5186     for (i=0; i<2; i++) {
   5187        sal_memset(&rate_mantissa[i], 0, sizeof(rate_mantissa[i]));
   5188        sal_memset(&rate_exp[i], 0, sizeof(rate_exp[i]));
   5189        sal_memset(&burst_mantissa[i] , 0, sizeof(burst_mantissa[i]));
   5190        sal_memset(&burst_exp[i], 0, sizeof(burst_exp[i]));
   5191        sal_memset(&cycle_sel[i], 0, sizeof(cycle_sel[i]));
   5192     }
   5193     if (!(flags & _BCM_XGS_METER_FLAG_RESET)) {
   5194 
   5195         /* compute exp and mantissa and program the registers */
   5196         rv = soc_katana_get_shaper_rate_info(unit, max_quantum,
   5197                                              &rate_mantissa[0], &rate_exp[0]);
   5198         if (BCM_FAILURE(rv)) {
   5199             return(rv);
   5200         }
   5201 
   5202         rv = soc_katana_get_shaper_rate_info(unit, min_quantum,
   5203                                              &rate_mantissa[1], &rate_exp[1]);
   5204         if (BCM_FAILURE(rv)) {
   5205             return(rv);
   5206         }
   5207 
   5208         burst_max = burst_max_quantum;
   5209         burst_min = burst_min_quantum;
   5210         rv = soc_katana_get_shaper_burst_info(unit, burst_max,
   5211                                               &burst_mantissa[0],
   5212                                               &burst_exp[0], flags);
   5213         if (BCM_FAILURE(rv)) {
   5214             return(rv);
   5215         }
   5216 
   5217         rv = soc_katana_get_shaper_burst_info(unit, burst_min,
   5218                                               &burst_mantissa[1],
   5219                                               &burst_exp[1], flags);
   5220         if (BCM_FAILURE(rv)) {
   5221             return(rv);
   5222         }
   5223 
   5224         if (!(flags & _BCM_XGS_METER_FLAG_NON_BURST_CORRECTION)) {
   5225             /* set recommended burst settings */
   5226             for (i = 0; i < 2; i++) {
   5227                 if (rate_exp[i] != 0) {
   5228                     if (rate_exp[i] < 10) {
   5229                         burst_exp[i] = 5;
   5230                         burst_mantissa[i] = 0;
   5231                     } else {
   5232                         burst_exp[i] = rate_exp[i] - 4;
   5233                         burst_mantissa[i] = (rate_mantissa[i] >> 3);
   5234                     }
   5235                 }
   5236             }
   5237             /* set recommended refresh rate/cycle_sel settings */
   5238             for (i = 0; i < 2; i++) {
   5239                 if (rate_exp[i] > 4) {
   5240                     cycle_sel[i] = 0;
   5241                 } else if (rate_exp[i] > 1) {
   5242                     cycle_sel[i] = 5 - rate_exp[i];
   5243                 } else {
   5244                     cycle_sel[i] = 4;
   5245                 }
   5246             }
   5247         } else {
   5248             for (i = 0; i < 2; i++) {
   5249                 if ((burst_exp[i] >= 14) && (burst_mantissa[i] >= 124)) {
   5250                     /* maximum supported is 2064384 byte */
   5251                     burst_exp[i] = 14;
   5252                     burst_mantissa[i] = 124;
   5253                 } 
   5254                 rv =  soc_katana_compute_refresh_rate(unit, rate_exp[i],
   5255                                                       rate_mantissa[i], burst_exp[i],
   5256                                                       burst_mantissa[i], &cycle_sel[i]);
   5257                 if (BCM_FAILURE(rv)) {
   5258                     return(rv);
   5259                 }
   5260             }
   5261         }
   5262     }
   5263     
   5264     /* 
   5265      * At this point, port might be in flush state.
   5266      * If so, return.
   5267      */
   5268     SOC_EGRESS_METERING_LOCK(unit);
   5269     soc_kt_port_flush_state_get(unit, local_port, &status);
   5270     if (status) {
   5271 
   5272         LOG_INFO(BSL_LS_BCM_COSQ,
   5273                 (BSL_META_U(unit,
   5274                 "Unit %d Port %d is in flush state.\n"), unit, local_port));
   5275 
   5276         SOC_EGRESS_METERING_UNLOCK(unit);
   5277         return BCM_E_RESOURCE;
   5278     }
   5279 
   5280     switch (level) {
   5281         case _BCM_KT2_COSQ_NODE_LEVEL_ROOT:
   5282             config_mem[0] = LLS_PORT_SHAPER_CONFIG_Cm;            
   5283             rv = soc_mem_read(unit, config_mem[0], MEM_BLOCK_ALL,
   5284                              index, &port_entry);
   5285             if (BCM_FAILURE(rv)) {
   5286                 SOC_EGRESS_METERING_UNLOCK(unit);
   5287                 return(rv);
   5288             }
   5289             soc_mem_field32_set(unit, config_mem[0], &port_entry,
   5290                                 rate_exp_f[0], rate_exp[0]);
   5291             soc_mem_field32_set(unit, config_mem[0], &port_entry,
   5292                                 rate_mant_f[0], rate_mantissa[0]);
   5293             soc_mem_field32_set(unit, config_mem[0], &port_entry,
   5294                                 burst_exp_f[0], burst_exp[0]);
   5295             soc_mem_field32_set(unit, config_mem[0], &port_entry,
   5296                                 burst_mant_f[0], burst_mantissa[0]);
   5297             soc_mem_field32_set(unit, config_mem[0], &port_entry,
   5298                                 cycle_sel_f[0], cycle_sel[0]); 
   5299             rv = soc_mem_write(unit, config_mem[0],
   5300                               MEM_BLOCK_ALL, index, &port_entry);
   5301             if (BCM_FAILURE(rv)) {
   5302                 SOC_EGRESS_METERING_UNLOCK(unit);
   5303                 return(rv);
   5304             }
   5305 
   5306             break;
   5307 
   5308         case _BCM_KT2_COSQ_NODE_LEVEL_L0:
   5309             config_mem[0] = LLS_L0_SHAPER_CONFIG_Cm;
   5310             config_mem[1] = LLS_L0_MIN_CONFIG_Cm;            
   5311             for (i = 0; i < 2; i++) {
   5312             rv = soc_mem_read(unit, config_mem[i], MEM_BLOCK_ALL,
   5313                              index, &l0_entry);
   5314             if (BCM_FAILURE(rv)) {
   5315                 SOC_EGRESS_METERING_UNLOCK(unit);
   5316                 return(rv);
   5317             }
   5318 
   5319                 soc_mem_field32_set(unit, config_mem[i], &l0_entry,
   5320                                     rate_exp_f[i], rate_exp[i]);
   5321                 soc_mem_field32_set(unit, config_mem[i], &l0_entry,
   5322                                     rate_mant_f[i], rate_mantissa[i]);
   5323                 soc_mem_field32_set(unit, config_mem[i], &l0_entry,
   5324                                     burst_exp_f[i], burst_exp[i]);
   5325                 soc_mem_field32_set(unit, config_mem[i], &l0_entry,
   5326                                     burst_mant_f[i], burst_mantissa[i]);
   5327                 soc_mem_field32_set(unit, config_mem[i], &l0_entry,
   5328                                     cycle_sel_f[i], cycle_sel[i]);   
   5329                 rv = soc_mem_write(unit, config_mem[i],
   5330                                   MEM_BLOCK_ALL, index, &l0_entry);
   5331                 if (BCM_FAILURE(rv)) {
   5332                     SOC_EGRESS_METERING_UNLOCK(unit);
   5333                     return(rv);
   5334                 }
   5335              }
   5336             break;
   5337 
   5338         case _BCM_KT2_COSQ_NODE_LEVEL_L1:
   5339             config_mem[0] = LLS_L1_SHAPER_CONFIG_Cm;
   5340             config_mem[1] = LLS_L1_MIN_CONFIG_Cm;            
   5341             if (SOC_IS_SABER2(unit)) {
   5342                 rate_exp_fields[0] = C_MAX_REF_RATE_EXPf;
   5343                 rate_exp_fields[1] = INVALIDf;
   5344                 rate_exp_fields[2] = INVALIDf;
   5345                 rate_exp_fields[3] = INVALIDf;
   5346                 rate_exp_fields[4] = C_MIN_REF_RATE_EXPf;
   5347 
   5348                 rate_mant_fields[0] = C_MAX_REF_RATE_MANTf;
   5349                 rate_mant_fields[1] = INVALIDf;
   5350                 rate_mant_fields[2] = INVALIDf;
   5351                 rate_mant_fields[3] = INVALIDf;
   5352                 rate_mant_fields[4] = C_MIN_REF_RATE_MANTf;
   5353 
   5354                 burst_exp_fields[0] = C_MAX_THLD_EXPf;
   5355                 burst_exp_fields[1] = INVALIDf;
   5356                 burst_exp_fields[2] = INVALIDf;
   5357                 burst_exp_fields[3] = INVALIDf;
   5358                 burst_exp_fields[4] = C_MIN_THLD_EXPf;
   5359 
   5360                 burst_mant_fields[0] = C_MAX_THLD_MANTf;
   5361                 burst_mant_fields[1] = INVALIDf;
   5362                 burst_mant_fields[2] = INVALIDf;
   5363                 burst_mant_fields[3] = INVALIDf;
   5364                 burst_mant_fields[4] = C_MIN_THLD_MANTf;
   5365 
   5366                 cycle_sel_fields[0] = C_MAX_CYCLE_SELf;
   5367                 cycle_sel_fields[1] = INVALIDf;
   5368                 cycle_sel_fields[2] = INVALIDf;
   5369                 cycle_sel_fields[3] = INVALIDf;
   5370                 cycle_sel_fields[4] = C_MIN_CYCLE_SELf;
   5371 
   5372                 shaper_bucket_index = 0;
   5373             } else {
   5374                 shaper_bucket_index = index % max_l1_shaper_bucket[unit];
   5375             }
   5376             for (i = 0; i < 2; i++) {
   5377                  idx = (i * 4) + shaper_bucket_index;
   5378                 rv = soc_mem_read(unit, config_mem[i], MEM_BLOCK_ALL,
   5379                                      index / max_l1_shaper_bucket[unit], &l1_entry);
   5380                 if (BCM_FAILURE(rv)) {
   5381                     SOC_EGRESS_METERING_UNLOCK(unit);
   5382                     return(rv);
   5383                 }
   5384 
   5385                 soc_mem_field32_set(unit, config_mem[i], &l1_entry,
   5386                                     rate_exp_fields[idx], rate_exp[i]);
   5387                 soc_mem_field32_set(unit, config_mem[i], &l1_entry,
   5388                                     rate_mant_fields[idx], rate_mantissa[i]);
   5389                 soc_mem_field32_set(unit, config_mem[i], &l1_entry,
   5390                                     burst_exp_fields[idx], burst_exp[i]);
   5391                 soc_mem_field32_set(unit, config_mem[i], &l1_entry,
   5392                                     burst_mant_fields[idx], burst_mantissa[i]);
   5393                 soc_mem_field32_set(unit, config_mem[i], &l1_entry,
   5394                                     cycle_sel_fields[idx], cycle_sel[i]); 
   5395                 rv = soc_mem_write(unit, config_mem[i], MEM_BLOCK_ALL, 
   5396                                      index / max_l1_shaper_bucket[unit], &l1_entry);
   5397                 if (BCM_FAILURE(rv)) {
   5398                     SOC_EGRESS_METERING_UNLOCK(unit);
   5399                     return(rv);
   5400                 }
   5401             }
   5402             break;
   5403 
   5404         case _BCM_KT2_COSQ_NODE_LEVEL_L2:
   5405             if ((index % max_l2_shaper_bucket[unit]) < 4) {
   5406                  config_mem[0] = l2_shaper_memory[unit][0];
   5407                  config_mem[1] = l2_shaper_memory[unit][1];
   5408             } else {
   5409                  config_mem[0] = l2_shaper_memory[unit][2];
   5410                  config_mem[1] = l2_shaper_memory[unit][3];
   5411             }
   5412             for (i = 0; i < 2; i++) {
   5413                 idx = (i * 4) + (index % 4);
   5414                 rv = soc_mem_read(unit, config_mem[i], MEM_BLOCK_ALL,
   5415                                  index/max_l2_shaper_bucket[unit], &l2_entry);
   5416                 if (BCM_FAILURE(rv)) {
   5417                     SOC_EGRESS_METERING_UNLOCK(unit);
   5418                     return(rv);
   5419                 }
   5420                 soc_mem_field32_set(unit, config_mem[i], &l2_entry,
   5421                                     rate_exp_fields[idx], rate_exp[i]);
   5422                 soc_mem_field32_set(unit, config_mem[i], &l2_entry,
   5423                                     rate_mant_fields[idx], rate_mantissa[i]);
   5424                 soc_mem_field32_set(unit, config_mem[i], &l2_entry,
   5425                                     burst_exp_fields[idx], burst_exp[i]);
   5426                 soc_mem_field32_set(unit, config_mem[i], &l2_entry,
   5427                                     burst_mant_fields[idx], burst_mantissa[i]);
   5428                 soc_mem_field32_set(unit, config_mem[i], &l2_entry,
   5429                                     cycle_sel_fields[idx], cycle_sel[i]);       
   5430                 rv = soc_mem_write(unit, config_mem[i], MEM_BLOCK_ALL, 
   5431                                   index/max_l2_shaper_bucket[unit], &l2_entry);
   5432                 if (BCM_FAILURE(rv)) {
   5433                     SOC_EGRESS_METERING_UNLOCK(unit);
   5434                     return(rv);
   5435                 }
   5436             }
   5437             break;
   5438 
   5439         case _BCM_KT2_COSQ_NODE_LEVEL_S0:
   5440         case _BCM_KT2_COSQ_NODE_LEVEL_S1:
   5441             config_mem[0] = (level == _BCM_KT2_COSQ_NODE_LEVEL_S0 &&
   5442                              (node->linkphy_enabled) && !SOC_IS_METROLITE(unit)) ?
   5443                             LLS_S0_SHAPER_CONFIG_Cm :
   5444                             LLS_S1_SHAPER_CONFIG_Cm;
   5445 
   5446             if ((level == _BCM_KT2_COSQ_NODE_LEVEL_S1) 
   5447                  && (node->hw_index > 127 && node->hw_index < 256)){
   5448                config_mem[0] = LLS_L0_SHAPER_CONFIG_Cm;
   5449             } else {
   5450 #if defined (BCM_SABER2_SUPPORT)
   5451                 if (SOC_IS_SABER2(unit)) {
   5452 #if defined (BCM_METROLITE_SUPPORT)
   5453                     if (SOC_IS_METROLITE(unit)) {
   5454                         if (level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
   5455                             if ((node->hw_index >= _SOC_ML_COSQ_MAX_INDEX_S0) &&
   5456                                 node->linkphy_enabled) {
   5457                                 SOC_EGRESS_METERING_UNLOCK(unit);
   5458                                 return BCM_E_PARAM;
   5459                             }
   5460                         }
   5461                     } else
   5462 #endif /* BCM_METROLITE_SUPPORT */
   5463                     {
   5464                         if (level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
   5465                             if ((node->hw_index >= _SOC_SB2_COSQ_MAX_INDEX_S0) &&
   5466                                 node->linkphy_enabled) {
   5467                                 SOC_EGRESS_METERING_UNLOCK(unit);
   5468                                 return BCM_E_PARAM;
   5469                             }
   5470                         }
   5471                     }
   5472                 } else
   5473 #endif /* BCM_SABER2_SUPPORT */
   5474                 if ((level == _BCM_KT2_COSQ_NODE_LEVEL_S0) &&
   5475                     (node->hw_index >= _SOC_KT2_COSQ_MAX_INDEX_S0)) {
   5476                     SOC_EGRESS_METERING_UNLOCK(unit);
   5477                     return BCM_E_NONE;
   5478                 }
   5479             }
   5480 
   5481             rv = soc_mem_read(unit, config_mem[0], MEM_BLOCK_ALL,
   5482                              index, &s0_entry);
   5483             if (BCM_FAILURE(rv)) {
   5484                 SOC_EGRESS_METERING_UNLOCK(unit);
   5485                 return(rv);
   5486             }
   5487             soc_mem_field32_set(unit, config_mem[0], &s0_entry,
   5488                                 rate_exp_f[0], rate_exp[0]);
   5489             soc_mem_field32_set(unit, config_mem[0], &s0_entry,
   5490                                 rate_mant_f[0], rate_mantissa[0]);
   5491             soc_mem_field32_set(unit, config_mem[0], &s0_entry,
   5492                                 burst_exp_f[0], burst_exp[0]);
   5493             soc_mem_field32_set(unit, config_mem[0], &s0_entry,
   5494                                 burst_mant_f[0], burst_mantissa[0]);
   5495             soc_mem_field32_set(unit, config_mem[0], &s0_entry,
   5496                                 cycle_sel_f[0], cycle_sel[0]);
   5497             rv = soc_mem_write(unit, config_mem[0],
   5498                                MEM_BLOCK_ALL, index, &s0_entry);
   5499             if (BCM_FAILURE(rv)) {
   5500                 SOC_EGRESS_METERING_UNLOCK(unit);
   5501                 return(rv);
   5502             }
   5503             break;
   5504             
   5505         default:
   5506             SOC_EGRESS_METERING_UNLOCK(unit);
   5507             return BCM_E_PARAM;
   5508     }
   5509 
   5510     SOC_EGRESS_METERING_UNLOCK(unit);
   5511     return BCM_E_NONE;
   5512 }
   5513 
   5514 /*
   5515  * Function:
   5516  *     _bcm_kt2_cosq_bucket_get
   5517  * Purpose:
   5518  *     Get COS queue bandwidth control bucket setting
   5519  * Parameters:
   5520  *     unit          - (IN) unit number
   5521  *     port          - (IN) port number or GPORT identifier
   5522  *     cosq          - (IN) COS queue number
   5523  *     min_quantum   - (OUT) kbps or packet/second
   5524  *     max_quantum   - (OUT) kbps or packet/second
   5525  *     burst_quantum - (OUT) kbps or packet/second
   5526  *     flags         - (IN)
   5527  * Returns:
   5528  *     BCM_E_XXX
   5529  * Notes:
   5530  *     If port is any form of local port, cosq is the hardware queue index.
   5531  */
   5532 STATIC int
   5533 _bcm_kt2_cosq_bucket_get(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   5534                         uint32 *min_quantum, uint32 *max_quantum,
   5535                         uint32 *burst_min_quantum, uint32 *burst_max_quantum,
   5536                         uint32 flags)
   5537 {
   5538     int rv;
   5539     _bcm_kt2_cosq_node_t *node;
   5540     bcm_port_t local_port;
   5541     int index;
   5542     soc_mem_t config_mem[2];
   5543     lls_port_shaper_config_c_entry_t port_entry;
   5544     lls_l0_shaper_config_c_entry_t  l0_entry;
   5545     lls_l1_shaper_config_c_entry_t  l1_entry;
   5546     lls_l2_shaper_config_lower_entry_t l2_entry;
   5547     lls_s0_shaper_config_c_entry_t s0_entry;
   5548     uint32 rate_exp[2], rate_mantissa[2];
   5549     uint32 burst_exp[2], burst_mantissa[2];
   5550     int i, idx, status;
   5551     int level = _BCM_KT2_COSQ_NODE_LEVEL_L2;
   5552     soc_field_t rate_exp_f[] = {
   5553         C_MAX_REF_RATE_EXPf, C_MIN_REF_RATE_EXPf
   5554     };
   5555     soc_field_t rate_mant_f[] = {
   5556         C_MAX_REF_RATE_MANTf, C_MIN_REF_RATE_MANTf
   5557     };
   5558     soc_field_t burst_exp_f[] = {
   5559         C_MAX_THLD_EXPf, C_MIN_THLD_EXPf
   5560     };
   5561     soc_field_t burst_mant_f[] = {
   5562         C_MAX_THLD_MANTf, C_MIN_THLD_MANTf
   5563     };
   5564     soc_field_t rate_exp_fields[] = {
   5565        C_MAX_REF_RATE_EXP_0f, C_MAX_REF_RATE_EXP_1f,
   5566        C_MAX_REF_RATE_EXP_2f, C_MAX_REF_RATE_EXP_3f,
   5567        C_MIN_REF_RATE_EXP_0f, C_MIN_REF_RATE_EXP_1f,
   5568        C_MIN_REF_RATE_EXP_2f, C_MIN_REF_RATE_EXP_3f
   5569     };
   5570     soc_field_t rate_mant_fields[] = {
   5571        C_MAX_REF_RATE_MANT_0f, C_MAX_REF_RATE_MANT_1f,
   5572        C_MAX_REF_RATE_MANT_2f, C_MAX_REF_RATE_MANT_3f,
   5573        C_MIN_REF_RATE_MANT_0f, C_MIN_REF_RATE_MANT_1f,
   5574        C_MIN_REF_RATE_MANT_2f, C_MIN_REF_RATE_MANT_3f
   5575     };
   5576     soc_field_t burst_exp_fields[] = {
   5577        C_MAX_THLD_EXP_0f, C_MAX_THLD_EXP_1f,
   5578        C_MAX_THLD_EXP_2f, C_MAX_THLD_EXP_3f,
   5579        C_MIN_THLD_EXP_0f, C_MIN_THLD_EXP_1f,
   5580        C_MIN_THLD_EXP_2f, C_MIN_THLD_EXP_3f       
   5581     };
   5582     soc_field_t burst_mant_fields[] = {
   5583        C_MAX_THLD_MANT_0f, C_MAX_THLD_MANT_1f,
   5584        C_MAX_THLD_MANT_2f, C_MAX_THLD_MANT_3f,
   5585        C_MIN_THLD_MANT_0f, C_MIN_THLD_MANT_1f,
   5586        C_MIN_THLD_MANT_2f, C_MIN_THLD_MANT_3f
   5587     };
   5588     int shaper_bucket_index = 0;
   5589 
   5590     if (cosq < 0) {
   5591         if (cosq == -1) {
   5592             /* caller needs to resolve the wild card value (-1) */
   5593             return BCM_E_INTERNAL;
   5594         } else { /* reject all other negative value */
   5595             return BCM_E_PARAM;
   5596         }
   5597     }
   5598 
   5599     if (min_quantum == NULL || max_quantum == NULL || 
   5600         burst_min_quantum == NULL || burst_max_quantum == NULL) {
   5601         return BCM_E_PARAM;
   5602     }
   5603 
   5604     BCM_IF_ERROR_RETURN
   5605         (_bcm_kt2_cosq_index_resolve(unit, port, cosq,
   5606                                     _BCM_KT2_COSQ_INDEX_STYLE_BUCKET,
   5607                                     &local_port, &index, NULL));
   5608     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(port) ||
   5609         BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
   5610         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   5611         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   5612         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) || 
   5613         BCM_GPORT_IS_SCHEDULER(port)) {
   5614         BCM_IF_ERROR_RETURN
   5615             (_bcm_kt2_cosq_node_get(unit, port, NULL, NULL, NULL, &node));
   5616         level = node->level;    
   5617     } 
   5618 
   5619     /*
   5620      * At this point, port might be in flush state.
   5621      * If so, the max shaper might have been set to a large
   5622      * value temporarily which must not be returned.
   5623      */
   5624     SOC_EGRESS_METERING_LOCK(unit);
   5625     soc_kt_port_flush_state_get(unit, local_port, &status);
   5626     if (status) {
   5627 
   5628         LOG_INFO(BSL_LS_BCM_COSQ,
   5629                 (BSL_META_U(unit,
   5630                 "Unit %d Port %d is in flush state.\n"), unit, local_port));
   5631 
   5632         SOC_EGRESS_METERING_UNLOCK(unit);
   5633         return BCM_E_RESOURCE;
   5634     }
   5635 
   5636     switch (level) {
   5637         case _BCM_KT2_COSQ_NODE_LEVEL_ROOT:
   5638             config_mem[0] = LLS_PORT_SHAPER_CONFIG_Cm;
   5639             rv = (soc_mem_read(unit, config_mem[0], MEM_BLOCK_ALL,
   5640                              index, &port_entry));
   5641             if (BCM_FAILURE(rv)) {
   5642                 SOC_EGRESS_METERING_UNLOCK(unit);
   5643                 return rv;
   5644             }
   5645             rate_exp[0] = soc_mem_field32_get(unit, config_mem[0], &port_entry,
   5646                                 rate_exp_f[0]);
   5647             rate_mantissa[0] = soc_mem_field32_get(unit, config_mem[0], 
   5648                                                    &port_entry,
   5649                                                    rate_mant_f[0]);
   5650             rate_exp[1] = rate_exp[0];
   5651             rate_mantissa[1] = rate_mantissa[0];
   5652             burst_exp[0] = soc_mem_field32_get(unit, config_mem[0], &port_entry,
   5653                                 burst_exp_f[0]);
   5654             burst_mantissa[0] = soc_mem_field32_get(unit, config_mem[0],
   5655                                                     &port_entry,
   5656                                                     burst_mant_f[0]);
   5657             burst_exp[1] = burst_exp[0];
   5658             burst_mantissa[1] = burst_mantissa[0];
   5659             break;
   5660 
   5661         case _BCM_KT2_COSQ_NODE_LEVEL_L0:
   5662             config_mem[0] = LLS_L0_SHAPER_CONFIG_Cm;
   5663             config_mem[1] = LLS_L0_MIN_CONFIG_Cm;
   5664 
   5665             for (i = 0; i < 2; i++) {
   5666                 rv = soc_mem_read(unit, config_mem[i], MEM_BLOCK_ALL,
   5667                                  index, &l0_entry);
   5668                 if (BCM_FAILURE(rv)) {
   5669                     SOC_EGRESS_METERING_UNLOCK(unit);
   5670                     return rv;
   5671                 }
   5672 
   5673                 rate_exp[i] = soc_mem_field32_get(unit, config_mem[i], 
   5674                                                   &l0_entry,
   5675                                                   rate_exp_f[i]);
   5676                 rate_mantissa[i] = soc_mem_field32_get(unit, config_mem[i], 
   5677                                                        &l0_entry,
   5678                                                        rate_mant_f[i]);
   5679                 burst_exp[i] = soc_mem_field32_get(unit, config_mem[i], 
   5680                                                    &l0_entry,
   5681                                                    burst_exp_f[i]);
   5682                 burst_mantissa[i] = soc_mem_field32_get(unit, config_mem[i], 
   5683                                                         &l0_entry,
   5684                                                         burst_mant_f[i]);
   5685             }
   5686             break;
   5687 
   5688         case _BCM_KT2_COSQ_NODE_LEVEL_L1:
   5689             config_mem[0] = LLS_L1_SHAPER_CONFIG_Cm;
   5690             config_mem[1] = LLS_L1_MIN_CONFIG_Cm;
   5691             if (SOC_IS_SABER2(unit)) {
   5692                 rate_exp_fields[0] = C_MAX_REF_RATE_EXPf;
   5693                 rate_exp_fields[1] = INVALIDf;
   5694                 rate_exp_fields[2] = INVALIDf;
   5695                 rate_exp_fields[3] = INVALIDf;
   5696                 rate_exp_fields[4] = C_MIN_REF_RATE_EXPf;
   5697 
   5698                 rate_mant_fields[0] = C_MAX_REF_RATE_MANTf;
   5699                 rate_mant_fields[1] = INVALIDf;
   5700                 rate_mant_fields[2] = INVALIDf;
   5701                 rate_mant_fields[3] = INVALIDf;
   5702                 rate_mant_fields[4] = C_MIN_REF_RATE_MANTf;
   5703 
   5704                 burst_exp_fields[0] = C_MAX_THLD_EXPf;
   5705                 burst_exp_fields[1] = INVALIDf;
   5706                 burst_exp_fields[2] = INVALIDf;
   5707                 burst_exp_fields[3] = INVALIDf;
   5708                 burst_exp_fields[4] = C_MIN_THLD_EXPf;
   5709 
   5710                 burst_mant_fields[0] = C_MAX_THLD_MANTf;
   5711                 burst_mant_fields[1] = INVALIDf;
   5712                 burst_mant_fields[2] = INVALIDf;
   5713                 burst_mant_fields[3] = INVALIDf;
   5714                 burst_mant_fields[4] = C_MIN_THLD_MANTf;
   5715 
   5716                 shaper_bucket_index = 0;
   5717             } else {
   5718                 shaper_bucket_index = index % max_l1_shaper_bucket[unit];
   5719             }
   5720             for (i = 0; i < 2; i++) {
   5721                 idx = (i * 4) + shaper_bucket_index;
   5722                 rv = soc_mem_read(unit, config_mem[i], MEM_BLOCK_ALL,
   5723                                      index / max_l1_shaper_bucket[unit], &l1_entry);
   5724                 if (BCM_FAILURE(rv)) {
   5725                     SOC_EGRESS_METERING_UNLOCK(unit);
   5726                     return rv;
   5727                 }
   5728                 rate_exp[i] = soc_mem_field32_get(unit, config_mem[i], 
   5729                                                   &l1_entry,
   5730                                                   rate_exp_fields[idx]);
   5731                 rate_mantissa[i] = soc_mem_field32_get(unit, config_mem[i], 
   5732                                                        &l1_entry,
   5733                                                        rate_mant_fields[idx]);
   5734                 burst_exp[i] = soc_mem_field32_get(unit, config_mem[i], 
   5735                                                    &l1_entry,
   5736                                                    burst_exp_fields[idx]);
   5737                 burst_mantissa[i] = soc_mem_field32_get(unit, config_mem[i], 
   5738                                                         &l1_entry,
   5739                                                         burst_mant_fields[idx]);
   5740              }
   5741             break;
   5742 
   5743         case _BCM_KT2_COSQ_NODE_LEVEL_L2:
   5744             if ((index % max_l2_shaper_bucket[unit]) < 4) {
   5745                  config_mem[0] = l2_shaper_memory[unit][0];
   5746                  config_mem[1] = l2_shaper_memory[unit][1];
   5747             } else {
   5748                  config_mem[0] = l2_shaper_memory[unit][2];
   5749                  config_mem[1] = l2_shaper_memory[unit][3];
   5750             }
   5751 
   5752             for (i = 0; i < 2; i++) {
   5753                 idx = (i * 4) + (index % 4);
   5754                 rv = soc_mem_read(unit, config_mem[i], MEM_BLOCK_ALL,
   5755                                  index/max_l2_shaper_bucket[unit], &l2_entry);
   5756                 if (BCM_FAILURE(rv)) {
   5757                     SOC_EGRESS_METERING_UNLOCK(unit);
   5758                     return rv;
   5759                 }
   5760                 rate_exp[i] = soc_mem_field32_get(unit, config_mem[i], 
   5761                                                   &l2_entry,
   5762                                                   rate_exp_fields[idx]);
   5763                 rate_mantissa[i] = soc_mem_field32_get(unit, config_mem[i], 
   5764                                                        &l2_entry,
   5765                                                        rate_mant_fields[idx]);
   5766                 burst_exp[i] = soc_mem_field32_get(unit, config_mem[i], 
   5767                                                    &l2_entry,
   5768                                                    burst_exp_fields[idx]);
   5769                 burst_mantissa[i] = soc_mem_field32_get(unit, config_mem[i], 
   5770                                                         &l2_entry,
   5771                                                         burst_mant_fields[idx]);
   5772             }
   5773             break;
   5774 
   5775         case _BCM_KT2_COSQ_NODE_LEVEL_S0:
   5776         case _BCM_KT2_COSQ_NODE_LEVEL_S1:
   5777 #if defined (BCM_SABER2_SUPPORT)
   5778             if (SOC_IS_SABER2(unit) && (level == _BCM_KT2_COSQ_NODE_LEVEL_S0)) {
   5779                 if ((node->hw_index >= _SOC_SB2_COSQ_MAX_INDEX_S0) &&
   5780                     node->linkphy_enabled) {
   5781                     SOC_EGRESS_METERING_UNLOCK(unit);
   5782                     return BCM_E_PARAM;
   5783                 }
   5784             } else
   5785 #endif
   5786             if ((level == _BCM_KT2_COSQ_NODE_LEVEL_S0) &&
   5787                 (node->hw_index >= _SOC_KT2_COSQ_MAX_INDEX_S0)) {
   5788                 SOC_EGRESS_METERING_UNLOCK(unit);
   5789                 return BCM_E_NONE;
   5790             }
   5791             config_mem[0] = (level == _BCM_KT2_COSQ_NODE_LEVEL_S0 &&
   5792                              (node->linkphy_enabled) && !SOC_IS_METROLITE(unit)) ?
   5793                             LLS_S0_SHAPER_CONFIG_Cm :
   5794                             LLS_S1_SHAPER_CONFIG_Cm;
   5795             rv = soc_mem_read(unit, config_mem[0], MEM_BLOCK_ALL,
   5796                              index, &s0_entry);
   5797             if (BCM_FAILURE(rv)) {
   5798                 SOC_EGRESS_METERING_UNLOCK(unit);
   5799                 return rv;
   5800             }
   5801             rate_exp[0] = soc_mem_field32_get(unit, config_mem[0], &s0_entry,
   5802                                               rate_exp_f[0]);
   5803             rate_mantissa[0] = soc_mem_field32_get(unit, config_mem[0], 
   5804                                                    &s0_entry,
   5805                                                    rate_mant_f[0]);
   5806             burst_exp[0] = soc_mem_field32_get(unit, config_mem[0], &s0_entry,
   5807                                                burst_exp_f[0]);
   5808             burst_mantissa[0] = soc_mem_field32_get(unit, config_mem[0], 
   5809                                                     &s0_entry,
   5810                                                     burst_mant_f[0]);
   5811             break;
   5812 
   5813         default:
   5814             SOC_EGRESS_METERING_UNLOCK(unit);
   5815             return BCM_E_PARAM;
   5816     }
   5817     SOC_EGRESS_METERING_UNLOCK(unit);
   5818 
   5819     /* convert exp and mantissa to bps */
   5820     rv = soc_katana_compute_shaper_rate(unit, rate_mantissa[0], rate_exp[0],
   5821                                         max_quantum);
   5822     if (BCM_FAILURE(rv)) {
   5823         return(rv);
   5824     }
   5825 
   5826     rv = soc_katana_compute_shaper_rate(unit, rate_mantissa[1], rate_exp[1],
   5827                                         min_quantum);
   5828     if (BCM_FAILURE(rv)) {
   5829         return(rv);
   5830     }
   5831     if((level == _BCM_KT2_COSQ_NODE_LEVEL_ROOT) ||
   5832        (level == _BCM_KT2_COSQ_NODE_LEVEL_S0)  ||
   5833        (level == _BCM_KT2_COSQ_NODE_LEVEL_S1)) 
   5834     {
   5835         *min_quantum=0; 
   5836     }  
   5837     rv = soc_katana_compute_shaper_burst(unit, burst_mantissa[0], burst_exp[0],
   5838                                          burst_max_quantum);
   5839     if (BCM_FAILURE(rv)) {
   5840         return(rv);
   5841     }
   5842 
   5843     rv = soc_katana_compute_shaper_burst(unit, burst_mantissa[1], burst_exp[1],
   5844                                          burst_min_quantum);
   5845     if (BCM_FAILURE(rv)) {
   5846         return(rv);
   5847     }    
   5848     
   5849     return BCM_E_NONE;
   5850 }
   5851 
   5852 /*
   5853  *  Convert HW drop probability to percent value
   5854  */
   5855 STATIC int
   5856 _bcm_kt2_hw_drop_prob_to_percent[] = {
   5857     0,     /* 0  */
   5858     1,     /* 1  */
   5859     2,     /* 2  */
   5860     3,     /* 3  */
   5861     4,     /* 4  */
   5862     5,     /* 5  */
   5863     6,     /* 6  */
   5864     7,     /* 7  */
   5865     8,     /* 8  */
   5866     9,     /* 9  */
   5867     10,    /* 10 */
   5868     25,    /* 11 */
   5869     50,    /* 12 */
   5870     75,    /* 13 */
   5871     100,   /* 14 */
   5872     -1     /* 15 */
   5873 };
   5874 
   5875 STATIC int
   5876 _bcm_kt2_percent_to_drop_prob(int percent)
   5877 {
   5878    int i;
   5879 
   5880    for (i = 14; i > 0 ; i--) {
   5881       if (percent >= _bcm_kt2_hw_drop_prob_to_percent[i]) {
   5882           break;
   5883       }
   5884    }
   5885    return i;
   5886 }
   5887 
   5888 STATIC int
   5889 _bcm_kt2_drop_prob_to_percent(int drop_prob) {
   5890    return (_bcm_kt2_hw_drop_prob_to_percent[drop_prob]);
   5891 }
   5892 
   5893 /*
   5894  * Function:
   5895  *     _bcm_kt2_cosq_wred_set
   5896  * Purpose:
   5897  *     Configure unicast queue WRED setting
   5898  * Parameters:
   5899  *     unit                - (IN) unit number
   5900  *     port                - (IN) port number or GPORT identifier
   5901  *     cosq                - (IN) COS queue number
   5902  *     flags               - (IN) BCM_COSQ_DISCARD_XXX
   5903  *     min_thresh          - (IN)
   5904  *     max_thresh          - (IN)
   5905  *     drop_probablity     - (IN)
   5906  *     gain                - (IN)
   5907  *     ignore_enable_flags - (IN)
   5908  * Returns:
   5909  *     BCM_E_XXX
   5910  * Notes:
   5911  *     If port is any form of local port, cosq is the hardware queue index.
   5912  */
   5913 STATIC int
   5914 _bcm_kt2_cosq_wred_set(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   5915                       uint32 flags, uint32 min_thresh, uint32 max_thresh,
   5916                       int drop_probability, int gain, int ignore_enable_flags)
   5917 {
   5918     soc_reg_t reg = 0;
   5919     soc_field_t field;
   5920     uint32 rval = 0;
   5921     bcm_port_t local_port;
   5922     int index;
   5923     uint32 profile_index, old_profile_index, partner_index;
   5924     mmu_wred_drop_curve_profile_0_entry_t entry_tcp_green;
   5925     mmu_wred_drop_curve_profile_1_entry_t entry_tcp_yellow;
   5926     mmu_wred_drop_curve_profile_2_entry_t entry_tcp_red;
   5927     mmu_wred_drop_curve_profile_3_entry_t entry_nontcp_green;
   5928     mmu_wred_drop_curve_profile_4_entry_t entry_nontcp_yellow;
   5929     mmu_wred_drop_curve_profile_5_entry_t entry_nontcp_red;
   5930     void *entries[6];
   5931     soc_mem_t mems[6];
   5932     _bcm_kt2_cosq_node_t *node;
   5933     soc_mem_t wred_mem = MMU_WRED_QUEUE_CONFIG_BUFFERm;
   5934     soc_mem_t partner_mem = MMU_WRED_QUEUE_CONFIG_QENTRYm;
   5935     mmu_wred_queue_config_buffer_entry_t qentry, entry;
   5936     int rate, i;
   5937     int wred_enabled = 0;
   5938     int ext_mem_port_count = 0;
   5939     int wred_disable_request = 0;
   5940     _bcm_kt2_mmu_info_t *mmu_info;
   5941 
   5942     reg = WRED_CONFIGr;
   5943     if (flags & BCM_COSQ_DISCARD_DEVICE) {
   5944 /* For port -1 , set global wred discard profile for all ports */
   5945         if ((port == -1) || (flags & BCM_COSQ_DISCARD_PACKETS)) {
   5946             reg = GLOBAL_WRED_CONFIG_QENTRYr;
   5947             field = WRED_ENABLEf;
   5948             local_port = 0;
   5949             index = 0; /* mmu init code uses service pool 0 only */
   5950         } else {
   5951             return BCM_E_PARAM;
   5952         }
   5953     } else {
   5954         if (cosq == -1) {
   5955            return BCM_E_PARAM;
   5956         }
   5957         wred_disable_request = (!ignore_enable_flags) &&
   5958                            (!(flags & BCM_COSQ_DISCARD_ENABLE));
   5959         BCM_IF_ERROR_RETURN
   5960             (_bcm_kt2_cosq_index_resolve(unit, port, cosq,
   5961                                         _BCM_KT2_COSQ_INDEX_STYLE_WRED,
   5962                                         &local_port, &index, NULL));
   5963         /* WRED doesn't work on CPU/LB Ports */
   5964         if (IS_LB_PORT(unit, local_port) || IS_CPU_PORT(unit, local_port)) {
   5965             return BCM_E_PORT;
   5966         }
   5967 
   5968         if (flags & BCM_COSQ_DISCARD_PACKETS) {
   5969             wred_mem = MMU_WRED_QUEUE_CONFIG_QENTRYm;
   5970             partner_mem = MMU_WRED_QUEUE_CONFIG_BUFFERm;
   5971         }
   5972         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(port) ||
   5973             BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
   5974             BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   5975             BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   5976             BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) || 
   5977             BCM_GPORT_IS_SCHEDULER(port)) {
   5978                 BCM_IF_ERROR_RETURN
   5979                     (_bcm_kt2_cosq_node_get(unit, port, NULL, &local_port, NULL,
   5980                                        &node));
   5981                 node->wred_disabled = wred_disable_request;
   5982                 if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L0) {
   5983                     wred_mem = (flags & BCM_COSQ_DISCARD_PACKETS) ? 
   5984                                 MMU_WRED_OPN_CONFIG_QENTRYm : 
   5985                                 MMU_WRED_OPN_CONFIG_BUFFERm;
   5986                     partner_mem = (flags & BCM_COSQ_DISCARD_PACKETS) ? 
   5987                                 MMU_WRED_OPN_CONFIG_BUFFERm : 
   5988                                 MMU_WRED_OPN_CONFIG_QENTRYm; 
   5989                 }
   5990         } else {
   5991             mmu_info = _bcm_kt2_mmu_info[unit];
   5992             if (cosq >= (mmu_info->port[local_port].q_limit -
   5993                 mmu_info->port[local_port].q_offset)) {
   5994                 return BCM_E_PARAM;
   5995             }
   5996             node = &mmu_info->queue_node[mmu_info->port[local_port].q_offset + cosq];
   5997             node->wred_disabled = wred_disable_request;
   5998         }
   5999         field = WRED_ENf;
   6000     }
   6001 
   6002     old_profile_index = 0xffffffff;
   6003     profile_index = 0xffffffff;
   6004     if (reg == GLOBAL_WRED_CONFIG_QENTRYr) {
   6005         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, local_port, index, &rval));
   6006     } else {
   6007         SOC_IF_ERROR_RETURN
   6008            (soc_mem_read(unit, wred_mem, MEM_BLOCK_ALL,
   6009                          index, &qentry));
   6010     }
   6011     /*
   6012      * Note that there is issue with dynamic disable of WRED
   6013      * if low rate shaper is configured. There will be huge
   6014      * queue build up and average queue size calculated will
   6015      * be high resulting in WRED entering into tail drop. At
   6016      * this time if WRED gets disabled then re-claculation of
   6017      * average queue size will not be done by WRED and it will
   6018      * remain in tail drop state even if queue is emptied. So
   6019      * instead of diabling WRED attach default WRED profile
   6020      * which have very high min and max threshold and zero
   6021      * dropping rate.
   6022      */
   6023     if (wred_disable_request && (reg != GLOBAL_WRED_CONFIG_QENTRYr)) {
   6024             old_profile_index = soc_mem_field32_get(unit, wred_mem,
   6025                                                     &qentry, PROFILE_INDEXf);
   6026             soc_mem_field32_set(unit, wred_mem, &qentry, PROFILE_INDEXf, 0);
   6027             soc_mem_field32_set(unit, wred_mem, &qentry, WEIGHTf, 0);
   6028     } else
   6029     if (flags & (BCM_COSQ_DISCARD_NONTCP | BCM_COSQ_DISCARD_COLOR_ALL)) {
   6030         if (reg == GLOBAL_WRED_CONFIG_QENTRYr) {
   6031             old_profile_index = soc_reg_field_get(unit, reg, rval, 
   6032                                                   PROFILE_INDEXf);
   6033         } else {
   6034             old_profile_index = soc_mem_field32_get(unit, wred_mem,
   6035                                                     &qentry, PROFILE_INDEXf);
   6036         } 
   6037         entries[0] = &entry_tcp_green;
   6038         entries[1] = &entry_tcp_yellow;
   6039         entries[2] = &entry_tcp_red;
   6040         entries[3] = &entry_nontcp_green;
   6041         entries[4] = &entry_nontcp_yellow;
   6042         entries[5] = &entry_nontcp_red;
   6043         BCM_IF_ERROR_RETURN
   6044             (soc_profile_mem_get(unit, _bcm_kt2_wred_profile[unit],
   6045                                  old_profile_index, 1, entries));
   6046         for (i = 0; i < 6; i++) {
   6047             mems[i] = INVALIDm;
   6048         }
   6049         if (!(flags & BCM_COSQ_DISCARD_NONTCP)) {
   6050             if (flags & BCM_COSQ_DISCARD_COLOR_GREEN) {
   6051                 mems[0] = MMU_WRED_DROP_CURVE_PROFILE_0m;
   6052             }
   6053             if (flags & BCM_COSQ_DISCARD_COLOR_YELLOW) {
   6054                 mems[1] = MMU_WRED_DROP_CURVE_PROFILE_1m;
   6055             }
   6056             if (flags & BCM_COSQ_DISCARD_COLOR_RED) {
   6057                 mems[2] = MMU_WRED_DROP_CURVE_PROFILE_2m;
   6058             }
   6059         } else if (!(flags & (BCM_COSQ_DISCARD_COLOR_GREEN |
   6060                               BCM_COSQ_DISCARD_COLOR_YELLOW |
   6061                               BCM_COSQ_DISCARD_COLOR_RED))) {
   6062             mems[3] = MMU_WRED_DROP_CURVE_PROFILE_3m;
   6063             mems[4] = MMU_WRED_DROP_CURVE_PROFILE_4m;
   6064             mems[5] = MMU_WRED_DROP_CURVE_PROFILE_5m;
   6065 
   6066         } else {
   6067             if (flags & BCM_COSQ_DISCARD_COLOR_GREEN) {
   6068                 mems[3] = MMU_WRED_DROP_CURVE_PROFILE_3m;
   6069             }
   6070             if (flags & BCM_COSQ_DISCARD_COLOR_YELLOW) {
   6071                 mems[4] = MMU_WRED_DROP_CURVE_PROFILE_4m;
   6072             }
   6073             if (flags & BCM_COSQ_DISCARD_COLOR_RED) {
   6074                 mems[5] = MMU_WRED_DROP_CURVE_PROFILE_5m;
   6075             }
   6076         }
   6077         rate = _bcm_kt2_percent_to_drop_prob(drop_probability);
   6078         for (i = 0; i < 6; i++) {
   6079             if (mems[i] == INVALIDm) {
   6080                 continue;
   6081             }
   6082             soc_mem_field32_set(unit, mems[i], entries[i], MIN_THDf,
   6083                                 min_thresh);
   6084             soc_mem_field32_set(unit, mems[i], entries[i], MAX_THDf,
   6085                                 max_thresh);
   6086             soc_mem_field32_set(unit, mems[i], entries[i], MAX_DROP_RATEf,
   6087                                 rate);
   6088         }
   6089         BCM_IF_ERROR_RETURN
   6090             (soc_profile_mem_add(unit, _bcm_kt2_wred_profile[unit], entries, 1,
   6091                                  &profile_index));
   6092         if (reg == GLOBAL_WRED_CONFIG_QENTRYr) {
   6093             soc_reg_field_set(unit, reg, &rval, PROFILE_INDEXf, profile_index);
   6094             soc_reg_field_set(unit, reg, &rval, WEIGHTf, gain);
   6095         } else {
   6096             soc_mem_field32_set(unit, wred_mem, &qentry, PROFILE_INDEXf, 
   6097                                 profile_index);
   6098             soc_mem_field32_set(unit, wred_mem, &qentry, WEIGHTf, gain);
   6099         }
   6100     }
   6101 
   6102     /* Some APIs only modify profiles */
   6103     if (!ignore_enable_flags) {
   6104         if ( reg == GLOBAL_WRED_CONFIG_QENTRYr) {
   6105             soc_reg_field_set(unit, reg, &rval, CAP_AVERAGEf,
   6106                               flags & BCM_COSQ_DISCARD_CAP_AVERAGE ? 1 : 0);
   6107             soc_reg_field_set(unit, reg, &rval, field,
   6108                               flags & BCM_COSQ_DISCARD_ENABLE ? 1 : 0);
   6109         } else {
   6110             soc_mem_field32_set(unit, wred_mem, &qentry, CAP_AVERAGEf,
   6111                               flags & BCM_COSQ_DISCARD_CAP_AVERAGE ? 1 : 0);
   6112             if (flags & BCM_COSQ_DISCARD_ENABLE) {
   6113                 soc_mem_field32_set(unit, wred_mem, &qentry, field, 1);
   6114             }
   6115             if (wred_mem == MMU_WRED_QUEUE_CONFIG_BUFFERm || 
   6116                 wred_mem == MMU_WRED_QUEUE_CONFIG_QENTRYm) {
   6117                 /* ECN marking is applicable only for queues */
   6118                 soc_mem_field32_set(unit, wred_mem, &qentry, ECN_MARKING_ENf,
   6119                                   flags & BCM_COSQ_DISCARD_MARK_CONGESTION ?
   6120                                   1 : 0);
   6121                 if (wred_mem == MMU_WRED_QUEUE_CONFIG_QENTRYm) {
   6122                     /* ECN marking needs to be enabled in BUFFER entry */
   6123                     SOC_IF_ERROR_RETURN
   6124                            (soc_mem_read(unit, MMU_WRED_QUEUE_CONFIG_BUFFERm, 
   6125                                          MEM_BLOCK_ALL, index, &entry));
   6126                     soc_mem_field32_set(unit, MMU_WRED_QUEUE_CONFIG_BUFFERm, 
   6127                                      &entry, ECN_MARKING_ENf,
   6128                                      flags & BCM_COSQ_DISCARD_MARK_CONGESTION ?
   6129                                      1 : 0);
   6130                     SOC_IF_ERROR_RETURN
   6131                         (soc_mem_write(unit, MMU_WRED_QUEUE_CONFIG_BUFFERm, 
   6132                                        MEM_BLOCK_ALL, index, &entry));
   6133                 }    
   6134             }
   6135         }
   6136     }
   6137 
   6138     partner_index = 0xffffffff;
   6139     if (reg == GLOBAL_WRED_CONFIG_QENTRYr) {
   6140         BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, local_port, index, rval));
   6141 
   6142         /* update interna/external buffer entries based on port configuration */
   6143         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, GLOBAL_WRED_CONFIG_BUFFERIr,
   6144                                           local_port, index, &rval));
   6145         soc_reg_field_set(unit, GLOBAL_WRED_CONFIG_BUFFERIr, &rval, field,
   6146                           flags & BCM_COSQ_DISCARD_ENABLE ? 1 : 0);
   6147         soc_reg_field_set(unit, GLOBAL_WRED_CONFIG_BUFFERIr, &rval,
   6148                           PROFILE_INDEXf, 0);
   6149         BCM_IF_ERROR_RETURN(soc_reg32_set(unit, GLOBAL_WRED_CONFIG_BUFFERIr,
   6150                             local_port, index, rval));
   6151         BCM_PBMP_COUNT(PBMP_EXT_MEM (unit), ext_mem_port_count);
   6152         if (ext_mem_port_count > 0) {
   6153             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, GLOBAL_WRED_CONFIG_BUFFERE_POOL0r,
   6154                                               local_port, index, &rval));
   6155             soc_reg_field_set(unit, GLOBAL_WRED_CONFIG_BUFFERE_POOL0r, &rval, field,
   6156                               flags & BCM_COSQ_DISCARD_ENABLE ? 1 : 0);
   6157             soc_reg_field_set(unit, GLOBAL_WRED_CONFIG_BUFFERE_POOL0r, &rval,
   6158                               PROFILE_INDEXf, 0);
   6159             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, GLOBAL_WRED_CONFIG_BUFFERE_POOL0r,
   6160                                 local_port, index, rval));
   6161         }
   6162     } else {
   6163         SOC_IF_ERROR_RETURN
   6164             (soc_mem_write(unit, wred_mem, MEM_BLOCK_ALL,
   6165                            index, &qentry));
   6166         SOC_IF_ERROR_RETURN
   6167             (soc_mem_read(unit, partner_mem, MEM_BLOCK_ALL,
   6168                               index, &qentry));
   6169         wred_enabled = soc_mem_field32_get(unit, partner_mem,
   6170                                            &qentry, WRED_ENf);
   6171         
   6172         /* if buffer/qentry_mem WRED enabled, make sure the partner_mem 
   6173          * (qentry/buffer_mem) also WRED enabled.
   6174          * if buffer/qentry_mem WRED disabled, make sure the partner_mem
   6175          *  (qentry/buffer_mem) also WRED disabled. 
   6176          */
   6177         if (((flags & BCM_COSQ_DISCARD_ENABLE) && (wred_enabled == 0)) ||
   6178             (!(flags & BCM_COSQ_DISCARD_ENABLE) && (wred_enabled == 1))) {
   6179             partner_index = soc_mem_field32_get(unit, partner_mem,
   6180                                                 &qentry, PROFILE_INDEXf); 
   6181             soc_mem_field32_set(unit, partner_mem, &qentry, PROFILE_INDEXf, 0);
   6182             if (flags & BCM_COSQ_DISCARD_ENABLE) {
   6183                 soc_mem_field32_set(unit, partner_mem, &qentry, WRED_ENf, 1);
   6184             }
   6185             SOC_IF_ERROR_RETURN
   6186                 (soc_mem_write(unit, partner_mem, MEM_BLOCK_ALL,
   6187                                index, &qentry));    
   6188         }    
   6189     }
   6190 
   6191 /* Replacing old profiles with new global profiles when wred discard 
   6192       profile is set for all ports */
   6193 
   6194     if ((port== -1) && (flags & BCM_COSQ_DISCARD_DEVICE) &&
   6195                        (profile_index != 0xffffffff)) {
   6196         for(i = 1; i < SOC_REG_NUMELS(unit, reg); i++) {
   6197             BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit, 
   6198                         _bcm_kt2_wred_profile[unit], entries, 1, 
   6199                         &profile_index));
   6200             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, local_port, i, rval));
   6201         }
   6202      }
   6203     
   6204     if (old_profile_index != 0xffffffff && old_profile_index > 0) {
   6205         BCM_IF_ERROR_RETURN
   6206             (soc_profile_mem_delete(unit, _bcm_kt2_wred_profile[unit],
   6207                                     old_profile_index));
   6208         if ((port==-1) && (flags & BCM_COSQ_DISCARD_DEVICE)) {
   6209             for (i = 1; i < SOC_REG_NUMELS(unit, reg);  i++) {
   6210                 BCM_IF_ERROR_RETURN(soc_profile_mem_delete(unit, 
   6211                             _bcm_kt2_wred_profile[unit],old_profile_index));
   6212             }
   6213         }
   6214     }
   6215     
   6216     if (partner_index != 0xffffffff && partner_index > 0) {
   6217         BCM_IF_ERROR_RETURN
   6218             (soc_profile_mem_delete(unit, _bcm_kt2_wred_profile[unit],
   6219                                     partner_index));
   6220     }    
   6221 
   6222     return BCM_E_NONE;
   6223 }
   6224 
   6225 /*
   6226  * Function:
   6227  *     _bcm_kt2_cosq_wred_get
   6228  * Purpose:
   6229  *     Get unicast queue WRED setting
   6230  * Parameters:
   6231  *     unit                - (IN) unit number
   6232  *     port                - (IN) port number or GPORT identifier
   6233  *     cosq                - (IN) COS queue number
   6234  *     flags               - (IN/OUT) BCM_COSQ_DISCARD_XXX
   6235  *     min_thresh          - (OUT)
   6236  *     max_thresh          - (OUT)
   6237  *     drop_probablity     - (OUT)
   6238  *     gain                - (OUT)
   6239  * Returns:
   6240  *     BCM_E_XXX
   6241  * Notes:
   6242  *     If port is any form of local port, cosq is the hardware queue index.
   6243  */
   6244 STATIC int
   6245 _bcm_kt2_cosq_wred_get(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   6246                       uint32 *flags, uint32 *min_thresh, uint32 *max_thresh,
   6247                       int *drop_probability, int *gain)
   6248 {
   6249     soc_reg_t reg = 0;
   6250     soc_field_t field;
   6251     uint32 rval;
   6252     bcm_port_t local_port;
   6253     int index, profile_index;
   6254     mmu_wred_drop_curve_profile_0_entry_t entry_tcp_green;
   6255     mmu_wred_drop_curve_profile_1_entry_t entry_tcp_yellow;
   6256     mmu_wred_drop_curve_profile_2_entry_t entry_tcp_red;
   6257     mmu_wred_drop_curve_profile_3_entry_t entry_nontcp_green;
   6258     mmu_wred_drop_curve_profile_4_entry_t entry_nontcp_yellow;
   6259     mmu_wred_drop_curve_profile_5_entry_t entry_nontcp_red;
   6260     void *entries[6];
   6261     void *entry_p;
   6262     soc_mem_t mem;
   6263     _bcm_kt2_cosq_node_t *node;
   6264     soc_mem_t wred_mem = MMU_WRED_QUEUE_CONFIG_BUFFERm;
   6265     mmu_wred_queue_config_buffer_entry_t qentry;
   6266     int rate;
   6267     int wred_disabled = 0;
   6268     _bcm_kt2_mmu_info_t *mmu_info;
   6269 
   6270     if (*flags & BCM_COSQ_DISCARD_DEVICE) {
   6271         if ((port == -1) || (*flags & BCM_COSQ_DISCARD_PACKETS)) {
   6272             reg = GLOBAL_WRED_CONFIG_QENTRYr;
   6273             field = WRED_ENABLEf;
   6274             local_port = 0;
   6275             index = 0; /* mmu init code uses service pool 0 only */
   6276             wred_mem = 0;
   6277         } else {
   6278             return BCM_E_PARAM;
   6279         }
   6280     } else {
   6281         if (cosq == -1) {
   6282            return BCM_E_PARAM;
   6283         }
   6284         BCM_IF_ERROR_RETURN
   6285             (_bcm_kt2_cosq_index_resolve(unit, port, cosq,
   6286                                         _BCM_KT2_COSQ_INDEX_STYLE_WRED,
   6287                                         &local_port, &index, NULL));
   6288         /* WRED doesn't work on CPU/LB Ports */
   6289         if (IS_LB_PORT(unit, local_port) || IS_CPU_PORT(unit, local_port)) {
   6290             return BCM_E_PORT;
   6291         }
   6292         if (*flags & BCM_COSQ_DISCARD_PACKETS) {
   6293             wred_mem = MMU_WRED_QUEUE_CONFIG_QENTRYm;
   6294         }
   6295         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(port) ||
   6296             BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
   6297             BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   6298             BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   6299             BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) || 
   6300             BCM_GPORT_IS_SCHEDULER(port)) {        
   6301                 BCM_IF_ERROR_RETURN
   6302                     (_bcm_kt2_cosq_node_get(unit, port, NULL, &local_port, NULL,
   6303                                        &node));
   6304                 if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L1) {
   6305                     wred_mem = (*flags & BCM_COSQ_DISCARD_PACKETS) ? 
   6306                                 MMU_WRED_OPN_CONFIG_QENTRYm : 
   6307                                 MMU_WRED_OPN_CONFIG_BUFFERm;
   6308                 } else {
   6309                     wred_disabled = node->wred_disabled;
   6310                 }
   6311         } else {
   6312             mmu_info = _bcm_kt2_mmu_info[unit];
   6313             if (cosq >= (mmu_info->port[local_port].q_limit -
   6314                 mmu_info->port[local_port].q_offset)) {
   6315                 return BCM_E_PARAM;
   6316             }
   6317             node = &mmu_info->queue_node[mmu_info->port[local_port].q_offset + cosq];
   6318             wred_disabled = node->wred_disabled;
   6319         }
   6320         field = WRED_ENf;
   6321     }
   6322 
   6323     if (reg == GLOBAL_WRED_CONFIG_QENTRYr) {
   6324         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, local_port, index, &rval));
   6325         profile_index = soc_reg_field_get(unit, reg, rval, PROFILE_INDEXf);
   6326     } else {
   6327             SOC_IF_ERROR_RETURN
   6328                (soc_mem_read(unit, wred_mem, MEM_BLOCK_ALL,
   6329                              index, &qentry));
   6330             profile_index = soc_mem_field32_get(unit, wred_mem,
   6331                                                 &qentry, PROFILE_INDEXf);
   6332     }
   6333 
   6334     if (!(*flags & BCM_COSQ_DISCARD_NONTCP)) {
   6335         if (*flags & BCM_COSQ_DISCARD_COLOR_GREEN) {
   6336             mem = MMU_WRED_DROP_CURVE_PROFILE_0m;
   6337             entry_p = &entry_tcp_green;
   6338         } else if (*flags & BCM_COSQ_DISCARD_COLOR_YELLOW) {
   6339             mem = MMU_WRED_DROP_CURVE_PROFILE_1m;
   6340             entry_p = &entry_tcp_yellow;
   6341         } else if (*flags & BCM_COSQ_DISCARD_COLOR_RED) {
   6342             mem = MMU_WRED_DROP_CURVE_PROFILE_2m;
   6343             entry_p = &entry_tcp_red;
   6344         } else {
   6345            mem = MMU_WRED_DROP_CURVE_PROFILE_0m;
   6346            entry_p = &entry_tcp_green;
   6347         }
   6348     } else {
   6349         if (*flags & BCM_COSQ_DISCARD_COLOR_GREEN) {
   6350             mem = MMU_WRED_DROP_CURVE_PROFILE_3m;
   6351             entry_p = &entry_nontcp_green;
   6352         } else if (*flags & BCM_COSQ_DISCARD_COLOR_YELLOW) {
   6353             mem = MMU_WRED_DROP_CURVE_PROFILE_4m;
   6354             entry_p = &entry_nontcp_yellow;
   6355         } else if (*flags & BCM_COSQ_DISCARD_COLOR_RED) {
   6356             mem = MMU_WRED_DROP_CURVE_PROFILE_5m;
   6357             entry_p = &entry_nontcp_red;
   6358         } else {
   6359            mem = MMU_WRED_DROP_CURVE_PROFILE_3m;
   6360            entry_p = &entry_nontcp_green;
   6361         }
   6362     }
   6363     entries[0] = &entry_tcp_green;
   6364     entries[1] = &entry_tcp_yellow;
   6365     entries[2] = &entry_tcp_red;
   6366     entries[3] = &entry_nontcp_green;
   6367     entries[4] = &entry_nontcp_yellow;
   6368     entries[5] = &entry_nontcp_red;
   6369     BCM_IF_ERROR_RETURN
   6370         (soc_profile_mem_get(unit, _bcm_kt2_wred_profile[unit],
   6371                              profile_index, 1, entries));
   6372     if (min_thresh != NULL) {
   6373         *min_thresh = soc_mem_field32_get(unit, mem, entry_p, MIN_THDf);
   6374     }
   6375     if (max_thresh != NULL) {
   6376         *max_thresh = soc_mem_field32_get(unit, mem, entry_p, MAX_THDf);
   6377     }
   6378     if (drop_probability != NULL) {
   6379         rate = soc_mem_field32_get(unit, mem, entry_p, MAX_DROP_RATEf);
   6380         *drop_probability = _bcm_kt2_drop_prob_to_percent(rate);
   6381     }
   6382 
   6383     if (gain != NULL && reg == GLOBAL_WRED_CONFIG_QENTRYr) {
   6384         *gain = soc_reg_field_get(unit, reg, rval, WEIGHTf);
   6385     }
   6386     if (gain != NULL && wred_mem != 0) {
   6387         *gain = soc_mem_field32_get(unit, wred_mem, &qentry, WEIGHTf);
   6388     }
   6389 
   6390     *flags &= ~(BCM_COSQ_DISCARD_CAP_AVERAGE | BCM_COSQ_DISCARD_ENABLE);
   6391     if ((reg == GLOBAL_WRED_CONFIG_QENTRYr) &&
   6392         soc_reg_field_get(unit, reg, rval, CAP_AVERAGEf)) {
   6393         *flags |= BCM_COSQ_DISCARD_CAP_AVERAGE;
   6394     }
   6395     if ((wred_mem != 0) &&
   6396          soc_mem_field32_get(unit, wred_mem, &qentry, CAP_AVERAGEf)) {
   6397         *flags |= BCM_COSQ_DISCARD_CAP_AVERAGE;
   6398     }
   6399 
   6400     if ((reg == GLOBAL_WRED_CONFIG_QENTRYr) &&
   6401         soc_reg_field_get(unit, reg, rval, field)) {
   6402         *flags |= BCM_COSQ_DISCARD_ENABLE;
   6403     }
   6404     if ((wred_mem != 0) && (wred_disabled == 0) &&
   6405          soc_mem_field32_get(unit, wred_mem, &qentry, field)) {
   6406         *flags |= BCM_COSQ_DISCARD_ENABLE;
   6407     }
   6408 
   6409     if (wred_mem == MMU_WRED_QUEUE_CONFIG_BUFFERm || 
   6410         wred_mem == MMU_WRED_QUEUE_CONFIG_QENTRYm) {
   6411         if (soc_mem_field32_get(unit, wred_mem, &qentry, ECN_MARKING_ENf)) {
   6412             *flags |= BCM_COSQ_DISCARD_MARK_CONGESTION;
   6413         }
   6414     }
   6415 
   6416     return BCM_E_NONE;
   6417 }
   6418 STATIC int
   6419 bcm_kt2_handle_queue_min_accounting(int unit,
   6420                                     bcm_port_t port,
   6421                                     int queue_id,
   6422                                     int active)
   6423 {
   6424     int shared_size, conf_size, recalc_type;
   6425     _bcm_kt2_mmu_info_t *mmu_info_p;
   6426     mmu_thdo_qconfig_cell_entry_t     mmu_thdo_qconfig_cell_entry={{0}};
   6427 
   6428     /* Currently it is handled only for Saber2 */
   6429 #ifdef BCM_SABER2_SUPPORT
   6430     if (SOC_IS_SABER2(unit)) {
   6431 #ifdef BCM_METROLITE_SUPPORT
   6432         if (SOC_IS_METROLITE(unit)) {
   6433             return BCM_E_NONE;
   6434         }
   6435 #endif
   6436     } else
   6437 #endif
   6438     {
   6439         return BCM_E_NONE;
   6440     }
   6441     /* Do run time accounting only for front panel port */
   6442     if ((port <= 0) || (port >= LB_PORT(unit))) {
   6443         return BCM_E_NONE;
   6444     }
   6445     /* Check if queue is classical queue then return */
   6446     mmu_info_p = _bcm_kt2_mmu_info[unit];
   6447     if ((queue_id >= mmu_info_p->port[port].q_offset) &&
   6448         (queue_id < mmu_info_p->port[port].q_limit)) {
   6449         return BCM_E_NONE;
   6450     }
   6451     if ((queue_id >= mmu_info_p->port[port].mcq_offset) &&
   6452         (queue_id < mmu_info_p->port[port].mcq_limit)) {
   6453         return BCM_E_NONE;
   6454     }
   6455     if ((queue_id <= 0) || (queue_id >= soc_mem_index_count(
   6456         unit, MMU_THDO_QCONFIG_CELLm))) {
   6457         return BCM_E_NONE;
   6458     }
   6459     if (active) {
   6460         /* queue is going to be used */
   6461         if (IS_EXT_MEM_PORT(unit, port)) {
   6462             soc_kt2_mmu_get_shared_size(unit, NULL, &shared_size);
   6463             soc_sb2_get_queue_min_size(unit, NULL, &conf_size);
   6464             recalc_type = BCM_KT2_RECALC_SHARED_EXT_DECREMENT;
   6465             if (shared_size < conf_size) {
   6466                     LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\nGlobal external"
   6467                                                              " shared buffer exhausted")));
   6468                     return BCM_E_RESOURCE;
   6469             }
   6470             BCM_IF_ERROR_RETURN(
   6471                 soc_sb2_mmu_config_shared_buf_recalc(unit,
   6472                                                      shared_size - conf_size,
   6473                                                      recalc_type));
   6474         } else {
   6475             soc_kt2_mmu_get_shared_size(unit, &shared_size, NULL);
   6476             soc_sb2_get_queue_min_size(unit, &conf_size, NULL);
   6477             recalc_type = BCM_KT2_RECALC_SHARED_INT_DECREMENT;
   6478             if (shared_size < conf_size) {
   6479                     LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\nGlobal internal"
   6480                                                              " shared buffer exhausted")));
   6481                     return BCM_E_RESOURCE;
   6482             }
   6483             BCM_IF_ERROR_RETURN(
   6484                 soc_sb2_mmu_config_shared_buf_recalc(unit,
   6485                                                      shared_size - conf_size,
   6486                                                      recalc_type));
   6487         }
   6488         BCM_IF_ERROR_RETURN(
   6489             READ_MMU_THDO_QCONFIG_CELLm(unit,
   6490                                         MEM_BLOCK_ANY, queue_id,
   6491                                         &mmu_thdo_qconfig_cell_entry));
   6492         soc_mem_field32_set(unit, MMU_THDO_QCONFIG_CELLm,
   6493                             &mmu_thdo_qconfig_cell_entry, Q_MIN_CELLf,
   6494                             conf_size);
   6495         BCM_IF_ERROR_RETURN(WRITE_MMU_THDO_QCONFIG_CELLm(unit,
   6496                             MEM_BLOCK_ANY, queue_id,
   6497                             &mmu_thdo_qconfig_cell_entry));
   6498     } else {
   6499         /* queue is going to be freed */
   6500         BCM_IF_ERROR_RETURN(
   6501             READ_MMU_THDO_QCONFIG_CELLm(unit,
   6502                                         MEM_BLOCK_ANY, queue_id,
   6503                                         &mmu_thdo_qconfig_cell_entry));
   6504         conf_size = soc_mem_field32_get(unit, MMU_THDO_QCONFIG_CELLm,
   6505                                         &mmu_thdo_qconfig_cell_entry, Q_MIN_CELLf);
   6506         if (IS_EXT_MEM_PORT(unit, port)) {
   6507             soc_kt2_mmu_get_shared_size(unit, NULL, &shared_size);
   6508             recalc_type = BCM_KT2_RECALC_SHARED_EXT_INCREMENT;
   6509             BCM_IF_ERROR_RETURN(
   6510                 soc_sb2_mmu_config_shared_buf_recalc(unit,
   6511                                                      shared_size + conf_size,
   6512                                                      recalc_type));
   6513         } else {
   6514             soc_kt2_mmu_get_shared_size(unit, &shared_size, NULL);
   6515             recalc_type = BCM_KT2_RECALC_SHARED_INT_INCREMENT;
   6516             BCM_IF_ERROR_RETURN(
   6517                 soc_sb2_mmu_config_shared_buf_recalc(unit,
   6518                                                      shared_size + conf_size,
   6519                                                      recalc_type));
   6520         }
   6521     }
   6522     return BCM_E_NONE;
   6523 }
   6524 STATIC int
   6525 _bcm_kt2_cosq_gport_delete_node(int unit, bcm_gport_t gport)
   6526 {
   6527     _bcm_kt2_cosq_node_t *node;
   6528     _bcm_kt2_mmu_info_t *mmu_info;
   6529     int encap_id;    
   6530 
   6531     BCM_IF_ERROR_RETURN
   6532         (_bcm_kt2_cosq_node_get(unit, gport, NULL, NULL, NULL, &node));
   6533 
   6534     /* reset the shaper configuration for the
   6535      * node
   6536      */
   6537     if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_ROOT && node->cosq_attached_to >= 0) {
   6538         BCM_IF_ERROR_RETURN (bcm_kt2_cosq_gport_bandwidth_set(unit,
   6539                              node->gport, 0, 0, 0, _BCM_XGS_METER_FLAG_RESET));
   6540     }
   6541 
   6542     if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_ROOT && 
   6543             node->cosq_attached_to >= 0) {
   6544         BCM_IF_ERROR_RETURN (bcm_kt2_cosq_gport_detach(unit, node->gport,
   6545                     node->parent->gport, 
   6546                     node->cosq_attached_to));
   6547     }
   6548 
   6549     mmu_info = _bcm_kt2_mmu_info[unit];
   6550 
   6551     if (BCM_GPORT_IS_SCHEDULER(gport)) {
   6552         /* scheduler node */
   6553         encap_id = (BCM_GPORT_SCHEDULER_GET(gport) >> 8) & 0x7ff;
   6554 
   6555         if (encap_id == 0) {
   6556             encap_id = (BCM_GPORT_SCHEDULER_GET(gport) & 0xff);
   6557         }
   6558     } else if (BCM_GPORT_IS_LOCAL(gport)) {    
   6559         encap_id = BCM_GPORT_LOCAL_GET(gport);
   6560     } else if (BCM_GPORT_IS_MODPORT(gport)) {
   6561         encap_id = BCM_GPORT_MODPORT_PORT_GET(gport);
   6562     } else if (BCM_GPORT_IS_SUBPORT_PORT(gport)) {
   6563         encap_id = BCM_GPORT_SUBPORT_PORT_GET(gport);
   6564     } else {
   6565         return BCM_E_PARAM;
   6566     }
   6567 
   6568     _bcm_kt2_node_index_clear(&mmu_info->sched_list, encap_id, 1);
   6569 
   6570     if (node->cosq_map != NULL) {
   6571         sal_free(node->cosq_map);
   6572         node->cosq_map = NULL;
   6573     }
   6574 
   6575     _BCM_KT2_COSQ_NODE_INIT(node);
   6576 
   6577     return BCM_E_NONE;
   6578 }
   6579 
   6580 
   6581 STATIC int
   6582 _bcm_kt2_cosq_gport_delete_all(int unit, bcm_gport_t gport, int *rv)
   6583 {
   6584     _bcm_kt2_cosq_node_t *node;
   6585     _bcm_kt2_mmu_info_t *mmu_info;
   6586     _bcm_kt2_cosq_port_info_t *port_info;
   6587     int vlan_queue_present = 1;
   6588     bcm_port_t local_port;
   6589     uint32 rval = 0;
   6590     int encap_id;    
   6591     
   6592     BCM_IF_ERROR_RETURN
   6593         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL, &node));
   6594 
   6595     if (node->child != NULL) {
   6596         _bcm_kt2_cosq_gport_delete_all(unit, node->child->gport, rv);
   6597         BCM_IF_ERROR_RETURN(*rv);
   6598     }
   6599 
   6600     if (node->sibling != NULL) {
   6601         _bcm_kt2_cosq_gport_delete_all(unit, node->sibling->gport, rv);
   6602         BCM_IF_ERROR_RETURN(*rv);
   6603     }
   6604 
   6605     /* reset the shaper configuration for the
   6606      * node
   6607      */
   6608     if (node->cosq_attached_to >= 0) {
   6609        BCM_IF_ERROR_RETURN (bcm_kt2_cosq_gport_bandwidth_set(unit,
   6610                             node->gport, 0, 0, 0, _BCM_XGS_METER_FLAG_RESET));
   6611     }
   6612 
   6613     if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_ROOT && 
   6614         node->cosq_attached_to >= 0) {
   6615 
   6616         *rv = bcm_kt2_cosq_gport_detach(unit, node->gport, node->parent->gport, 
   6617                                        node->cosq_attached_to);
   6618         BCM_IF_ERROR_RETURN(*rv);
   6619     }
   6620 
   6621     mmu_info = _bcm_kt2_mmu_info[unit];
   6622 
   6623     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { /* unicast queue group */
   6624         encap_id = BCM_GPORT_UCAST_QUEUE_GROUP_QID_GET(gport);
   6625     } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 
   6626         /* multicast queue group */
   6627         encap_id = BCM_GPORT_MCAST_QUEUE_GROUP_QID_GET(gport); 
   6628     } else if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport)) {
   6629         encap_id = BCM_GPORT_DESTMOD_QUEUE_GROUP_QID_GET(gport); 
   6630         if (mmu_info->num_dmvoq_queues > 0) {
   6631             _bcm_kt2_node_index_clear(&mmu_info->dmvoq_qlist,
   6632                     encap_id , 1);
   6633             encap_id += mmu_info->base_dmvoq_queue;
   6634         } else {
   6635             _bcm_kt2_node_index_clear(&mmu_info->global_qlist,
   6636                     encap_id , 1);
   6637         }
   6638     } else if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
   6639         /* subscriber queue group */
   6640         encap_id = BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(gport);
   6641         if (mmu_info->num_sub_queues > 0) {
   6642             _bcm_kt2_node_index_clear(&mmu_info->sub_qlist,
   6643                     encap_id , 1);
   6644             encap_id += mmu_info->base_sub_queue;
   6645         } else {
   6646 
   6647             _bcm_kt2_node_index_clear(&mmu_info->global_qlist,
   6648                                 encap_id, 1);
   6649         }
   6650         /* Check if all unicast vlan queues of this port are deleted */
   6651         BCM_IF_ERROR_RETURN(
   6652             bcm_kt2_cosq_is_attached(unit, local_port, 1,
   6653                                      &vlan_queue_present));
   6654         port_info = &mmu_info->port[local_port];
   6655         if (!vlan_queue_present) {
   6656             port_info->uc_vlan_base = mmu_info->num_queues - 1;
   6657             SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, local_port, &rval));
   6658             soc_reg_field_set(unit, ING_COS_MODEr, &rval,
   6659                               SERVICE_BASE_QUEUE_NUMf, port_info->uc_vlan_base);
   6660             SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, local_port, rval));
   6661         }
   6662     } else if (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
   6663         /* subscriber queue group */
   6664         encap_id = BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(gport);
   6665         if (mmu_info->num_sub_queues > 0) {
   6666             _bcm_kt2_node_index_clear(&mmu_info->sub_mcqlist,
   6667                     encap_id , 1);
   6668             encap_id += mmu_info->base_sub_queue;
   6669         } else {
   6670 
   6671             _bcm_kt2_node_index_clear(&mmu_info->global_qlist,
   6672                                 encap_id, 1);
   6673         }
   6674     } else {
   6675         if (BCM_GPORT_IS_SCHEDULER(gport)) {
   6676            /* scheduler node */
   6677            encap_id = (BCM_GPORT_SCHEDULER_GET(gport) >> 8) & 0x7ff;
   6678         
   6679            if (encap_id == 0) {
   6680                encap_id = (BCM_GPORT_SCHEDULER_GET(gport) & 0xff);
   6681            }
   6682         } else if (BCM_GPORT_IS_LOCAL(gport)) {    
   6683            encap_id = BCM_GPORT_LOCAL_GET(gport);
   6684         } else if (BCM_GPORT_IS_MODPORT(gport)) {
   6685            encap_id = BCM_GPORT_MODPORT_PORT_GET(gport);
   6686         } else if (BCM_GPORT_IS_SUBPORT_PORT(gport)) {
   6687            encap_id = BCM_GPORT_SUBPORT_PORT_GET(gport);
   6688         } else {
   6689             return BCM_E_PARAM;
   6690         }
   6691 
   6692         _bcm_kt2_node_index_clear(&mmu_info->sched_list, encap_id, 1);
   6693    }
   6694 
   6695    if (node->cosq_map != NULL) {
   6696        sal_free(node->cosq_map);
   6697        node->cosq_map = NULL;
   6698    }
   6699    if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   6700        BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
   6701        BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
   6702        BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   6703        BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
   6704        BCM_IF_ERROR_RETURN(
   6705            bcm_kt2_handle_queue_min_accounting(unit, local_port,
   6706                                                encap_id, 0));
   6707    }
   6708     _BCM_KT2_COSQ_NODE_INIT(node);
   6709 
   6710     return BCM_E_NONE;
   6711 }
   6712 
   6713 STATIC int
   6714 _bcm_kt2_cosq_queue_map_set(int unit, _bcm_kt2_cosq_node_t *node,
   6715                             bcm_port_t port)
   6716 {
   6717     _bcm_kt2_cosq_node_t *cur_node, *l1_node;
   6718     egr_queue_to_pp_port_map_entry_t    pp_port_map;
   6719     mmu_thdo_opnconfig_cell_entry_t     opnconfig_cell;
   6720     mmu_thdo_opnconfig_qentry_entry_t   opnconfig_qentry;
   6721     int update_opn = 0;
   6722 
   6723     switch(node->level) {
   6724         case _BCM_KT2_COSQ_NODE_LEVEL_L0:
   6725             for (l1_node = node->child; l1_node != NULL;
   6726                  l1_node = l1_node->sibling) {
   6727                  update_opn = 0;
   6728                  for (cur_node = l1_node->child; cur_node != NULL;
   6729                       cur_node = cur_node->sibling) {
   6730                      if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP
   6731                          (cur_node->gport) ||
   6732                          BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP
   6733                          (cur_node->gport) ) {
   6734                          SOC_IF_ERROR_RETURN
   6735                              (READ_EGR_QUEUE_TO_PP_PORT_MAPm(unit, MEM_BLOCK_ALL,
   6736                                      cur_node->hw_index, &pp_port_map));
   6737                          soc_mem_field32_set(unit, EGR_QUEUE_TO_PP_PORT_MAPm,
   6738                                      &pp_port_map, PP_PORTf, port);
   6739                          SOC_IF_ERROR_RETURN
   6740                              (WRITE_EGR_QUEUE_TO_PP_PORT_MAPm(unit, MEM_BLOCK_ALL,
   6741                                                          cur_node->hw_index,
   6742                                                          &pp_port_map));
   6743                          update_opn = 1;
   6744                      }
   6745                 }
   6746                 if (update_opn) {
   6747                     SOC_IF_ERROR_RETURN
   6748                         (READ_MMU_THDO_OPNCONFIG_CELLm(unit, MEM_BLOCK_ANY,
   6749                                     l1_node->hw_index, &opnconfig_cell));
   6750                     soc_mem_field32_set(unit, MMU_THDO_OPNCONFIG_CELLm,
   6751                                         &opnconfig_cell, PIDf, port);
   6752                     SOC_IF_ERROR_RETURN
   6753                         (WRITE_MMU_THDO_OPNCONFIG_CELLm(unit, MEM_BLOCK_ALL,
   6754                                     l1_node->hw_index, &opnconfig_cell));
   6755                     SOC_IF_ERROR_RETURN
   6756                         (READ_MMU_THDO_OPNCONFIG_QENTRYm(unit, MEM_BLOCK_ANY,
   6757                                     l1_node->hw_index, &opnconfig_qentry));
   6758                     soc_mem_field32_set(unit, MMU_THDO_OPNCONFIG_QENTRYm,
   6759                                     &opnconfig_qentry, PIDf, port);
   6760                     SOC_IF_ERROR_RETURN
   6761                         (WRITE_MMU_THDO_OPNCONFIG_QENTRYm(unit, MEM_BLOCK_ALL,
   6762                                     l1_node->hw_index, &opnconfig_qentry));
   6763                 }
   6764             }
   6765             break;
   6766         case _BCM_KT2_COSQ_NODE_LEVEL_L1:
   6767             for (cur_node = node->child; cur_node != NULL;
   6768                  cur_node = cur_node->sibling) {
   6769                  if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(cur_node->gport) ||
   6770                      BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(cur_node->gport)) {
   6771                      SOC_IF_ERROR_RETURN
   6772                         (READ_EGR_QUEUE_TO_PP_PORT_MAPm(unit, MEM_BLOCK_ALL,
   6773                                      cur_node->hw_index, &pp_port_map));
   6774                      soc_mem_field32_set(unit, EGR_QUEUE_TO_PP_PORT_MAPm,
   6775                                      &pp_port_map, PP_PORTf, port);
   6776                      SOC_IF_ERROR_RETURN
   6777                         (WRITE_EGR_QUEUE_TO_PP_PORT_MAPm(unit, MEM_BLOCK_ALL,
   6778                                                          cur_node->hw_index,
   6779                                                          &pp_port_map));
   6780                      update_opn = 1;
   6781                  }
   6782             }
   6783             if (update_opn) {
   6784                 SOC_IF_ERROR_RETURN
   6785                     (READ_MMU_THDO_OPNCONFIG_CELLm(unit, MEM_BLOCK_ANY,
   6786                                     node->hw_index, &opnconfig_cell));
   6787                 soc_mem_field32_set(unit, MMU_THDO_OPNCONFIG_CELLm,
   6788                                     &opnconfig_cell, PIDf, port);
   6789                 SOC_IF_ERROR_RETURN
   6790                     (WRITE_MMU_THDO_OPNCONFIG_CELLm(unit, MEM_BLOCK_ALL,
   6791                                     node->hw_index, &opnconfig_cell));
   6792                 SOC_IF_ERROR_RETURN
   6793                     (READ_MMU_THDO_OPNCONFIG_QENTRYm(unit, MEM_BLOCK_ANY,
   6794                                     node->hw_index, &opnconfig_qentry));
   6795                 soc_mem_field32_set(unit, MMU_THDO_OPNCONFIG_QENTRYm,
   6796                                     &opnconfig_qentry, PIDf, port);
   6797                 SOC_IF_ERROR_RETURN
   6798                     (WRITE_MMU_THDO_OPNCONFIG_QENTRYm(unit, MEM_BLOCK_ALL,
   6799                                     node->hw_index, &opnconfig_qentry));
   6800             }
   6801             break;
   6802         default:
   6803             return BCM_E_PARAM;
   6804     }
   6805 
   6806     return BCM_E_NONE;
   6807 }
   6808 
   6809 STATIC int
   6810 _bcm_kt_cosq_bucket_start(int unit,
   6811            int index, int level, int cycle_sel, int rate_exp, int thld_exp,
   6812            int max_bucket)
   6813 {
   6814     lls_l0_shaper_config_c_entry_t  l0_entry;
   6815     lls_l0_shaper_bucket_c_entry_t  l0_bucket;
   6816     lls_l1_shaper_config_c_entry_t  l1_entry;
   6817     lls_l1_shaper_bucket_c_entry_t  l1_bucket;
   6818     soc_field_t cycle_sel_f[] = {
   6819         C_MAX_CYCLE_SEL_0f, C_MAX_CYCLE_SEL_1f,
   6820         C_MAX_CYCLE_SEL_2f, C_MAX_CYCLE_SEL_3f
   6821     };
   6822     soc_field_t rate_exp_f[] = {
   6823         C_MAX_REF_RATE_EXP_0f, C_MAX_REF_RATE_EXP_1f,
   6824         C_MAX_REF_RATE_EXP_2f, C_MAX_REF_RATE_EXP_3f
   6825     };
   6826     soc_field_t thld_exp_f[] = {
   6827         C_MAX_THLD_EXP_0f, C_MAX_THLD_EXP_1f,
   6828         C_MAX_THLD_EXP_2f, C_MAX_THLD_EXP_3f
   6829     };
   6830     soc_field_t active_in_lls_f[] = {
   6831         NOT_ACTIVE_IN_LLS_0f, NOT_ACTIVE_IN_LLS_1f,
   6832         NOT_ACTIVE_IN_LLS_2f, NOT_ACTIVE_IN_LLS_3f
   6833     };
   6834     soc_field_t max_bucket_f[] = {
   6835         C_MAX_BUCKET_0f, C_MAX_BUCKET_1f,
   6836         C_MAX_BUCKET_2f, C_MAX_BUCKET_3f
   6837     };
   6838     soc_field_t not_empty_f[] = {
   6839         NOT_EMPTY_0f, NOT_EMPTY_1f,
   6840         NOT_EMPTY_2f, NOT_EMPTY_3f
   6841     };
   6842 
   6843     switch(level) {
   6844         case _BCM_KT2_COSQ_NODE_LEVEL_L0:
   6845             SOC_IF_ERROR_RETURN
   6846                 (soc_mem_read(unit, LLS_L0_SHAPER_CONFIG_Cm, MEM_BLOCK_ALL,
   6847                               index, &l0_entry));
   6848             soc_mem_field32_set(unit, LLS_L0_SHAPER_CONFIG_Cm, &l0_entry,
   6849                                 C_MAX_CYCLE_SELf, cycle_sel);
   6850             soc_mem_field32_set(unit, LLS_L0_SHAPER_CONFIG_Cm, &l0_entry,
   6851                                 C_MAX_REF_RATE_EXPf, rate_exp?rate_exp:0xe);
   6852             soc_mem_field32_set(unit, LLS_L0_SHAPER_CONFIG_Cm, &l0_entry,
   6853                                 C_MAX_THLD_EXPf, thld_exp);
   6854             SOC_IF_ERROR_RETURN
   6855                  (soc_mem_write(unit, LLS_L0_SHAPER_CONFIG_Cm, MEM_BLOCK_ALL,
   6856                                 index, &l0_entry));
   6857 
   6858             sal_memset(&l0_bucket, 0, sizeof(lls_l0_shaper_bucket_c_entry_t));
   6859             soc_mem_field32_set(unit, LLS_L0_SHAPER_BUCKET_Cm, &l0_bucket,
   6860                                 NOT_ACTIVE_IN_LLSf, 1);
   6861             soc_mem_field32_set(unit, LLS_L0_SHAPER_BUCKET_Cm, &l0_bucket,
   6862                                 C_MAX_BUCKETf, max_bucket);
   6863             soc_mem_field32_set(unit, LLS_L0_SHAPER_BUCKET_Cm, &l0_bucket,
   6864                                 NOT_EMPTYf, 0);
   6865             SOC_IF_ERROR_RETURN
   6866                 (soc_mem_write(unit, LLS_L0_SHAPER_BUCKET_Cm,
   6867                                MEM_BLOCK_ALL, index, &l0_bucket));
   6868             break;
   6869         case _BCM_KT2_COSQ_NODE_LEVEL_L1:
   6870             SOC_IF_ERROR_RETURN
   6871                 (soc_mem_read(unit, LLS_L1_SHAPER_CONFIG_Cm, MEM_BLOCK_ALL,
   6872                               (index / 4), &l1_entry));
   6873             soc_mem_field32_set(unit, LLS_L1_SHAPER_CONFIG_Cm, &l1_entry,
   6874                                 cycle_sel_f[index % 4], cycle_sel);
   6875             soc_mem_field32_set(unit, LLS_L1_SHAPER_CONFIG_Cm, &l1_entry,
   6876                                 rate_exp_f[index % 4], rate_exp);
   6877             soc_mem_field32_set(unit, LLS_L1_SHAPER_CONFIG_Cm, &l1_entry,
   6878                                 thld_exp_f[index % 4], thld_exp);
   6879             SOC_IF_ERROR_RETURN
   6880                  (soc_mem_write(unit, LLS_L1_SHAPER_CONFIG_Cm, MEM_BLOCK_ALL,
   6881                                 (index / 4), &l1_entry));
   6882 
   6883             sal_memset(&l1_bucket, 0, sizeof(lls_l1_shaper_bucket_c_entry_t));
   6884             soc_mem_field32_set(unit, LLS_L1_SHAPER_BUCKET_Cm, &l1_bucket,
   6885                                 active_in_lls_f[index % 4], 1);
   6886             soc_mem_field32_set(unit, LLS_L1_SHAPER_BUCKET_Cm, &l1_bucket,
   6887                                 max_bucket_f[index % 4], max_bucket);
   6888             soc_mem_field32_set(unit, LLS_L1_SHAPER_BUCKET_Cm, &l1_bucket,
   6889                                 not_empty_f[index % 4], 0);
   6890             SOC_IF_ERROR_RETURN
   6891                 (soc_mem_write(unit, LLS_L1_SHAPER_BUCKET_Cm,
   6892                                MEM_BLOCK_ALL, (index / 4), &l1_bucket));
   6893             break;
   6894         default:
   6895             return BCM_E_PARAM;
   6896      }
   6897 
   6898     return BCM_E_NONE;
   6899 }
   6900 
   6901 STATIC int
   6902 _bcm_kt_cosq_bucket_stop(int unit,
   6903             int index, int level, int *cycle_sel, int *rate_exp, int *thld_exp,
   6904             int *max_bucket)
   6905 {
   6906     lls_l0_shaper_config_c_entry_t  l0_entry;
   6907     lls_l0_child_state1_entry_t     l0_state;
   6908     lls_l0_shaper_bucket_c_entry_t  l0_bucket;
   6909     lls_l1_shaper_config_c_entry_t  l1_entry;
   6910     lls_l1_child_state1_entry_t     l1_state;
   6911     lls_l1_shaper_bucket_c_entry_t  l1_bucket;
   6912 #if defined(BROADCOM_DEBUG)
   6913     int cycle_sel1, rate_exp1, thld_exp1, max_bucket1;
   6914 #endif
   6915     int werr_list, min_list, ef_list, i;
   6916     int count = 0;
   6917     soc_field_t cycle_sel_f[] = {
   6918         C_MAX_CYCLE_SEL_0f, C_MAX_CYCLE_SEL_1f,
   6919         C_MAX_CYCLE_SEL_2f, C_MAX_CYCLE_SEL_3f
   6920     };
   6921     soc_field_t rate_exp_f[] = {
   6922         C_MAX_REF_RATE_EXP_0f, C_MAX_REF_RATE_EXP_1f,
   6923         C_MAX_REF_RATE_EXP_2f, C_MAX_REF_RATE_EXP_3f
   6924     };
   6925     soc_field_t thld_exp_f[] = {
   6926         C_MAX_THLD_EXP_0f, C_MAX_THLD_EXP_1f,
   6927         C_MAX_THLD_EXP_2f, C_MAX_THLD_EXP_3f
   6928     };
   6929     soc_field_t active_in_lls_f[] = {
   6930         NOT_ACTIVE_IN_LLS_0f, NOT_ACTIVE_IN_LLS_1f,
   6931         NOT_ACTIVE_IN_LLS_2f, NOT_ACTIVE_IN_LLS_3f
   6932     };
   6933     soc_field_t max_bucket_f[] = {
   6934         C_MAX_BUCKET_0f, C_MAX_BUCKET_1f,
   6935         C_MAX_BUCKET_2f, C_MAX_BUCKET_3f
   6936     };
   6937     soc_field_t not_empty_f[] = {
   6938         NOT_EMPTY_0f, NOT_EMPTY_1f,
   6939         NOT_EMPTY_2f, NOT_EMPTY_3f
   6940     };
   6941 
   6942     switch(level) {
   6943         case _BCM_KT2_COSQ_NODE_LEVEL_L0:
   6944             SOC_IF_ERROR_RETURN
   6945                 (soc_mem_read(unit, LLS_L0_SHAPER_CONFIG_Cm, MEM_BLOCK_ALL,
   6946                               index, &l0_entry));
   6947             *cycle_sel = soc_mem_field32_get(unit, LLS_L0_SHAPER_CONFIG_Cm,
   6948                                              &l0_entry, C_MAX_CYCLE_SELf);
   6949             *rate_exp = soc_mem_field32_get(unit, LLS_L0_SHAPER_CONFIG_Cm,
   6950                                              &l0_entry, C_MAX_REF_RATE_EXPf);
   6951             *thld_exp = soc_mem_field32_get(unit, LLS_L0_SHAPER_CONFIG_Cm,
   6952                                              &l0_entry, C_MAX_THLD_EXPf);
   6953             soc_mem_field32_set(unit, LLS_L0_SHAPER_CONFIG_Cm, &l0_entry,
   6954                                 C_MAX_CYCLE_SELf, 0xF);
   6955             soc_mem_field32_set(unit, LLS_L0_SHAPER_CONFIG_Cm, &l0_entry,
   6956                                 C_MAX_REF_RATE_EXPf, 0xE);
   6957             soc_mem_field32_set(unit, LLS_L0_SHAPER_CONFIG_Cm, &l0_entry,
   6958                                 C_MAX_THLD_EXPf, 9);
   6959             SOC_IF_ERROR_RETURN
   6960                 (soc_mem_write(unit, LLS_L0_SHAPER_CONFIG_Cm, MEM_BLOCK_ALL,
   6961                                index, &l0_entry));
   6962             sal_usleep(10);
   6963 
   6964             sal_memset(&l0_bucket, 0, sizeof(lls_l0_shaper_bucket_c_entry_t));
   6965              SOC_IF_ERROR_RETURN
   6966                 (soc_mem_read(unit, LLS_L0_SHAPER_BUCKET_Cm, MEM_BLOCK_ALL,
   6967                               index, &l0_bucket));
   6968             *max_bucket = soc_mem_field32_get(unit, LLS_L0_SHAPER_BUCKET_Cm,
   6969                                              &l0_bucket, C_MAX_BUCKETf);
   6970             soc_mem_field32_set(unit, LLS_L0_SHAPER_BUCKET_Cm, &l0_bucket,
   6971                                 NOT_ACTIVE_IN_LLSf, 0);
   6972             soc_mem_field32_set(unit, LLS_L0_SHAPER_BUCKET_Cm, &l0_bucket,
   6973                                 C_MAX_BUCKETf, 0);
   6974             soc_mem_field32_set(unit, LLS_L0_SHAPER_BUCKET_Cm, &l0_bucket,
   6975                                 NOT_EMPTYf, 0);
   6976             SOC_IF_ERROR_RETURN
   6977                 (soc_mem_write(unit, LLS_L0_SHAPER_BUCKET_Cm,
   6978                                MEM_BLOCK_ALL, index, &l0_bucket));
   6979 
   6980             sal_usleep(1000000);
   6981             count = 0;
   6982 
   6983             /* check twice to avoid any transient states */
   6984             for (i = 0; i < 20; i++) {
   6985                 SOC_IF_ERROR_RETURN
   6986                     (READ_LLS_L0_CHILD_STATE1m(unit, MEM_BLOCK_ALL,
   6987                                                index, &l0_state));
   6988                 werr_list = soc_mem_field32_get(unit, LLS_L0_CHILD_STATE1m,
   6989                                                 &l0_state, C_ON_WERR_LISTf);
   6990                 min_list = soc_mem_field32_get(unit, LLS_L0_CHILD_STATE1m,
   6991                                                &l0_state, C_ON_MIN_LISTf);
   6992                 ef_list = soc_mem_field32_get(unit, LLS_L0_CHILD_STATE1m,
   6993                                               &l0_state, C_ON_EF_LISTf);
   6994                 SOC_IF_ERROR_RETURN
   6995                     (soc_mem_read(unit, LLS_L0_SHAPER_CONFIG_Cm, MEM_BLOCK_ALL,
   6996                                   index, &l0_entry));
   6997 #if defined(BROADCOM_DEBUG)
   6998                 cycle_sel1 = soc_mem_field32_get(unit, LLS_L0_SHAPER_CONFIG_Cm,
   6999                         &l0_entry, C_MAX_CYCLE_SELf);
   7000                 rate_exp1 = soc_mem_field32_get(unit, LLS_L0_SHAPER_CONFIG_Cm,
   7001                         &l0_entry, C_MAX_REF_RATE_EXPf);
   7002                 thld_exp1 = soc_mem_field32_get(unit, LLS_L0_SHAPER_CONFIG_Cm,
   7003                         &l0_entry, C_MAX_THLD_EXPf);
   7004                 SOC_IF_ERROR_RETURN
   7005                     (soc_mem_read(unit, LLS_L0_SHAPER_BUCKET_Cm, MEM_BLOCK_ALL,
   7006                                   index, &l0_bucket));
   7007                 max_bucket1 = soc_mem_field32_get(unit, LLS_L0_SHAPER_BUCKET_Cm,
   7008                         &l0_bucket, C_MAX_BUCKETf);
   7009 
   7010 
   7011                 LOG_INFO(BSL_LS_BCM_COSQ,
   7012                         (BSL_META_U(unit,
   7013                                     "Iteration No :%d \n"
   7014                         "LLS_L0_SHAPER_CONFIG_C.C_MAX_CYCLE_SELf = %d \n"
   7015                         "LLS_L0_SHAPER_CONFIG_C.C_MAX_REF_RATE_EXPf = %d \n"
   7016                         "LLS_L0_SHAPER_CONFIG_C.C_MAX_THLD_EXPf = %d \n"
   7017                         "LLS_L0_SHAPER_BUCKET_C.C_MAX_BUCKET =%d \n"
   7018                         "LLS_L0_CHILD_STATE1.C_ON_WERR_LIST= %d \n"
   7019                         "LLS_L0_CHILD_STATE1.C_ON_MIN_LIST= %d \n"
   7020                         "LLS_L0_CHILD_STATE1.C_ON_EF_LISTf = %d \n"),
   7021                         i, cycle_sel1, rate_exp1, thld_exp1,max_bucket1,
   7022                         werr_list, min_list, ef_list));
   7023 #endif
   7024 
   7025 
   7026                 if ((i < 19) && (werr_list || min_list || ef_list)) {
   7027                     /* If any of the above states are set during first read then
   7028                     * wait for 1 second and read again.*/
   7029                     sal_usleep(1000000);
   7030                     count = 0;
   7031                 }
   7032                 if ((i == 19) && (werr_list || min_list || ef_list)) {
   7033                     /* If any of the above states are set during second read then
   7034                     * return appropriate error */
   7035                     return BCM_E_BUSY;
   7036                 }
   7037                 if (count < 4) {
   7038                     /* forcefully iterating for four times,
   7039                        so that transient state is ignored */
   7040                     sal_usleep(1000000);
   7041                     count++ ;
   7042                 }
   7043                 if ( count == 4) {
   7044                     break;
   7045                 }
   7046             }
   7047             break;
   7048 
   7049         case _BCM_KT2_COSQ_NODE_LEVEL_L1:
   7050             SOC_IF_ERROR_RETURN
   7051                 (soc_mem_read(unit, LLS_L1_SHAPER_CONFIG_Cm, MEM_BLOCK_ALL,
   7052                               (index / 4), &l1_entry));
   7053             *cycle_sel = soc_mem_field32_get(unit, LLS_L1_SHAPER_CONFIG_Cm,
   7054                                              &l1_entry, cycle_sel_f[index % 4]);
   7055             *rate_exp = soc_mem_field32_get(unit, LLS_L1_SHAPER_CONFIG_Cm,
   7056                                              &l1_entry, rate_exp_f[index % 4]);
   7057             *thld_exp = soc_mem_field32_get(unit, LLS_L1_SHAPER_CONFIG_Cm,
   7058                                              &l1_entry, thld_exp_f[index % 4]);
   7059             soc_mem_field32_set(unit, LLS_L1_SHAPER_CONFIG_Cm, &l1_entry,
   7060                                 cycle_sel_f[index % 4], 0xF);
   7061             soc_mem_field32_set(unit, LLS_L1_SHAPER_CONFIG_Cm, &l1_entry,
   7062                                 rate_exp_f[index % 4], 0xE);
   7063             soc_mem_field32_set(unit, LLS_L1_SHAPER_CONFIG_Cm, &l1_entry,
   7064                                 thld_exp_f[index % 4], 9);
   7065             SOC_IF_ERROR_RETURN
   7066                 (soc_mem_write(unit, LLS_L1_SHAPER_CONFIG_Cm, MEM_BLOCK_ALL,
   7067                                (index / 4), &l1_entry));
   7068             sal_usleep(10);
   7069 
   7070             sal_memset(&l1_bucket, 0, sizeof(lls_l1_shaper_bucket_c_entry_t));
   7071             SOC_IF_ERROR_RETURN
   7072                 (soc_mem_read(unit, LLS_L1_SHAPER_BUCKET_Cm, MEM_BLOCK_ALL,
   7073                               (index / 4), &l1_bucket));
   7074             *max_bucket = soc_mem_field32_get(unit, LLS_L1_SHAPER_BUCKET_Cm,
   7075                                          &l1_bucket, max_bucket_f[index % 4]);
   7076             soc_mem_field32_set(unit, LLS_L1_SHAPER_BUCKET_Cm, &l1_bucket,
   7077                                 active_in_lls_f[index % 4], 0);
   7078             soc_mem_field32_set(unit, LLS_L1_SHAPER_BUCKET_Cm, &l1_bucket,
   7079                                 max_bucket_f[index % 4], 0);
   7080             soc_mem_field32_set(unit, LLS_L1_SHAPER_BUCKET_Cm, &l1_bucket,
   7081                                 not_empty_f[index % 4], 0);
   7082             SOC_IF_ERROR_RETURN
   7083                 (soc_mem_write(unit, LLS_L1_SHAPER_BUCKET_Cm,
   7084                                MEM_BLOCK_ALL, (index / 4), &l1_bucket));
   7085 
   7086             sal_usleep(10);
   7087 
   7088             /* check twice to avoid any transient states */
   7089             for (i = 0; i < 2; i++) {
   7090                 SOC_IF_ERROR_RETURN
   7091                     (READ_LLS_L1_CHILD_STATE1m(unit, MEM_BLOCK_ALL,
   7092                                                index, &l1_state));
   7093                 werr_list = soc_mem_field32_get(unit, LLS_L1_CHILD_STATE1m,
   7094                                                 &l1_state, C_ON_WERR_LISTf);
   7095                 min_list = soc_mem_field32_get(unit, LLS_L1_CHILD_STATE1m,
   7096                                                &l1_state, C_ON_MIN_LIST_0f);
   7097                 ef_list = soc_mem_field32_get(unit, LLS_L1_CHILD_STATE1m,
   7098                                               &l1_state, C_ON_EF_LIST_0f);
   7099                 if ((i == 0) && (werr_list || min_list || ef_list)) {
   7100                     /* If any of the above states are set during first read then
   7101                     * wait for 1 second and read again.*/
   7102                     sal_usleep(1000000);
   7103                 }
   7104                 if ((i == 1) && (werr_list || min_list || ef_list)) {
   7105                     /* If any of the above states are set during second read then
   7106                     * return appropriate error */
   7107                     return BCM_E_BUSY;
   7108                 }
   7109             }
   7110             break;
   7111 
   7112         default:
   7113             return BCM_E_PARAM;
   7114      }
   7115 
   7116      return BCM_E_NONE;
   7117 }
   7118 
   7119 STATIC int
   7120 _bcm_kt2_cosq_child_node_at_input(_bcm_kt2_cosq_node_t *node, int cosq,
   7121                                   _bcm_kt2_cosq_node_t **child_node)
   7122 {
   7123     _bcm_kt2_cosq_node_t *cur_node;
   7124 
   7125     for (cur_node = node->child; cur_node; cur_node = cur_node->sibling) {
   7126         if (cur_node->cosq_attached_to == cosq) {
   7127             break;
   7128         }
   7129     }
   7130     if (!cur_node) {
   7131         return BCM_E_NOT_FOUND;
   7132     }
   7133 
   7134     *child_node = cur_node;
   7135 
   7136     return BCM_E_NONE;
   7137 }
   7138 
   7139 int 
   7140 bcm_kt2_sw_hw_queue(int unit, int *queue_array)
   7141 {
   7142     _bcm_kt2_mmu_info_t *mmu_info;
   7143     int index = 0;
   7144     mmu_info = _bcm_kt2_mmu_info[unit];
   7145 
   7146     for (index = 0; index <  mmu_info->num_queues; index++){
   7147         if( mmu_info->queue_node[index].hw_index == *queue_array){
   7148             *queue_array = index;
   7149             return BCM_E_NONE;
   7150         }  
   7151     }
   7152     *queue_array = -1;
   7153     return BCM_E_PARAM;
   7154 }
   7155 
   7156 int
   7157 bcm_kt2_is_uc_queue(int unit,int queue_id,int *is_ucq)
   7158 {
   7159     _bcm_kt2_mmu_info_t *mmu_info;
   7160     _bcm_kt2_cosq_list_t *list; 
   7161    
   7162     mmu_info = _bcm_kt2_mmu_info[unit];
   7163     
   7164     list = &mmu_info->l2_base_qlist;
   7165 
   7166     if(SHR_BITGET(list->bits, queue_id))
   7167     {
   7168       *is_ucq = TRUE;
   7169     }
   7170     else 
   7171     {
   7172       *is_ucq = FALSE  ;
   7173     }
   7174     return BCM_E_NONE;
   7175 }
   7176 /*
   7177  * Function:
   7178  *      bcm_kt2_cosq_subscriber_qid_set
   7179  * Purpose:
   7180  *      Setting a relative queue id as per the configured value  
   7181  * Parameters:
   7182  *     unit  - (IN) unit number
   7183  *     gport - (IN) GPORT identifier
   7184  *     queue_id  - (IN) QUEUE identifier 
   7185  * Returns:
   7186  *     BCM_E_XXX
   7187  */
   7188 
   7189 int
   7190 bcm_kt2_cosq_subscriber_qid_set(int unit,
   7191     bcm_gport_t *gport,
   7192     int queue_id) 
   7193 {
   7194     _bcm_kt2_mmu_info_t *mmu_info;
   7195     _bcm_kt2_cosq_node_t *node = NULL;
   7196     mmu_info = _bcm_kt2_mmu_info[unit];
   7197     if (mmu_info == NULL) {
   7198         return BCM_E_INIT;
   7199     }
   7200 
   7201     node = &mmu_info->queue_node[queue_id];
   7202     if (node->cosq_attached_to < 0) {
   7203         return BCM_E_PARAM;
   7204     }
   7205     if (mmu_info->num_sub_queues) {
   7206         queue_id -= mmu_info->base_sub_queue;
   7207     }
   7208     if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) {
   7209         BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_QID_SET(*gport, queue_id);
   7210     } else if (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)) {
   7211         BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_QID_SET(*gport, queue_id);
   7212     } else {
   7213         return BCM_E_INIT;
   7214     }
   7215 
   7216     return BCM_E_NONE;
   7217 }
   7218 
   7219 /*
   7220  * Function:
   7221  *      _bcm_kt2_subscriber_sw_qid_set
   7222  * Purpose:
   7223  *      Set queue id for the subscriber software queue index
   7224  * Parameters:
   7225  *     unit  - (IN) unit number
   7226  *     gport - (OUT) GPORT identifier
   7227  *     queue_id  - (IN) QUEUE identifier
   7228  * Returns:
   7229  *     BCM_E_XXX
   7230  */
   7231 
   7232 int
   7233 _bcm_kt2_subscriber_sw_qid_set(int unit,
   7234                                bcm_gport_t *gport,
   7235                                int queue_id)
   7236 {
   7237     _bcm_kt2_mmu_info_t *mmu_info;
   7238     mmu_info = _bcm_kt2_mmu_info[unit];
   7239     if (mmu_info == NULL) {
   7240         return BCM_E_INIT;
   7241     }
   7242     if (mmu_info->num_sub_queues) {
   7243         queue_id -= mmu_info->base_sub_queue;
   7244     }
   7245     BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_QID_SET(*gport, queue_id);
   7246 
   7247     return BCM_E_NONE;
   7248 }
   7249 
   7250 /*
   7251  * Function:
   7252  *     _bcm_kt2_intf_ref_cnt_increment
   7253  * Purpose:
   7254  *     Increase interface reference count for queue id
   7255  * Parameters:
   7256  *     unit  - (IN) unit number
   7257  *     queue_id - (IN) HW queue id
   7258  *     count  - (IN) Interface count
   7259  * Returns:
   7260  *     BCM_E_XXX
   7261  */
   7262 
   7263 int
   7264 _bcm_kt2_intf_ref_cnt_increment(int unit, uint32 queue_id, int count)
   7265 {
   7266     _bcm_kt2_mmu_info_t *mmu_info;
   7267 
   7268     if (_bcm_kt2_mmu_info[unit] == NULL) {
   7269         return BCM_E_INIT;
   7270     }
   7271 
   7272     mmu_info = _bcm_kt2_mmu_info[unit];
   7273     mmu_info->intf_ref_cnt[queue_id] = mmu_info->intf_ref_cnt[queue_id]
   7274                                        + count;
   7275     return BCM_E_NONE;
   7276 }
   7277 
   7278 /*
   7279  * Function:
   7280  *     _bcm_kt2_intf_ref_cnt_decrement
   7281  * Purpose:
   7282  *     Decrease interface reference count for queue id
   7283  * Parameters:
   7284  *     unit  - (IN) unit number
   7285  *     queue_id - (IN) HW queue id
   7286  *     count  - (IN) Interface count
   7287  * Returns:
   7288  *     BCM_E_XXX
   7289  */
   7290 
   7291 int
   7292 _bcm_kt2_intf_ref_cnt_decrement(int unit, uint32 queue_id, int count)
   7293 {
   7294     _bcm_kt2_mmu_info_t *mmu_info;
   7295 
   7296     if (_bcm_kt2_mmu_info[unit] == NULL) {
   7297         return BCM_E_INIT;
   7298     }
   7299 
   7300     mmu_info = _bcm_kt2_mmu_info[unit];
   7301     if (mmu_info->intf_ref_cnt[queue_id] > 0) {
   7302         mmu_info->intf_ref_cnt[queue_id] = mmu_info->intf_ref_cnt[queue_id]
   7303                                            - count;
   7304     } else {
   7305         return BCM_E_PARAM;
   7306     }
   7307     return BCM_E_NONE;
   7308 }
   7309 
   7310 /*
   7311  * Function:
   7312  *     bcm_kt2_cosq_gport_add
   7313  * Purpose:
   7314  *     Create a cosq gport structure
   7315  * Parameters:
   7316  *     unit  - (IN) unit number
   7317  *     port  - (IN) port number
   7318  *     numq  - (IN) number of COS queues
   7319  *     flags - (IN) flags (BCM_COSQ_GPORT_XXX)
   7320  *     gport - (OUT) GPORT identifier
   7321  * Returns:
   7322  *     BCM_E_XXX
   7323  */
   7324 int
   7325 bcm_kt2_cosq_gport_add(int unit, bcm_gport_t port, int numq, uint32 flags,
   7326                       bcm_gport_t *gport)
   7327 {
   7328     _bcm_kt2_mmu_info_t *mmu_info;
   7329     _bcm_kt2_cosq_port_info_t *port_info;
   7330     _bcm_kt2_cosq_node_t *node = NULL;
   7331     bcm_module_t local_modid, modid_out;
   7332     bcm_port_t local_port, port_out;
   7333     int id, max_nodes;
   7334     uint32 sched_encap;
   7335     _bcm_kt2_cosq_list_t *list;
   7336     int max_queues;
   7337 
   7338     LOG_INFO(BSL_LS_BCM_COSQ,
   7339              (BSL_META_U(unit,
   7340                          "bcm_kt2_cosq_gport_add: unit=%d port=0x%x numq=%d flags=0x%x\n"),
   7341               unit, port, numq, flags));
   7342 
   7343     if (gport == NULL) {
   7344         return BCM_E_PARAM;
   7345     }
   7346 
   7347     if (_bcm_kt2_mmu_info[unit] == NULL) {
   7348         return BCM_E_INIT;
   7349     }
   7350 
   7351     BCM_IF_ERROR_RETURN
   7352         (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
   7353 
   7354     if (local_port < 0) {
   7355         return BCM_E_PORT;
   7356     }
   7357 
   7358     mmu_info = _bcm_kt2_mmu_info[unit];
   7359     port_info = &mmu_info->port[local_port];
   7360     switch (flags) {
   7361     case BCM_COSQ_GPORT_UCAST_QUEUE_GROUP:
   7362         if (numq != 1) {
   7363             return BCM_E_PARAM;
   7364         }
   7365         
   7366         for (id = port_info->q_offset; id < port_info->q_limit; id++) {
   7367             if (mmu_info->queue_node[id].numq == 0) {
   7368                 break;
   7369             }
   7370         }
   7371         
   7372         if (id == port_info->q_limit) {
   7373             return BCM_E_RESOURCE;
   7374         }            
   7375 
   7376         BCM_GPORT_UCAST_QUEUE_GROUP_SYSQID_SET(*gport, local_port, id);
   7377         list = &mmu_info->l2_base_qlist;
   7378         _bcm_kt2_node_index_set(&mmu_info->l2_base_qlist, id, 1);
   7379         node = &mmu_info->queue_node[id];
   7380         node->gport = *gport;
   7381         node->numq = numq;
   7382         node->hw_index = id;
   7383         break;
   7384 
   7385     case BCM_COSQ_GPORT_MCAST_QUEUE_GROUP:
   7386         if ((numq != 1) ||
   7387             (!soc_feature(unit, soc_feature_mmu_packing))) {
   7388             return BCM_E_PARAM;
   7389         }
   7390         for (id = port_info->mcq_offset; id < port_info->mcq_limit; id++) {
   7391             if (mmu_info->queue_node[id].numq == 0) {
   7392                 break;
   7393             }
   7394         }
   7395         
   7396         if (id == port_info->mcq_limit) {
   7397             return BCM_E_RESOURCE;
   7398         }            
   7399 
   7400         BCM_GPORT_MCAST_QUEUE_GROUP_SYSQID_SET(*gport, local_port, id);
   7401         node = &mmu_info->queue_node[id];
   7402         node->gport = *gport;
   7403         node->numq = numq;
   7404         node->hw_index = id;
   7405         break;        
   7406 
   7407     case BCM_COSQ_GPORT_VLAN_UCAST_QUEUE_GROUP:
   7408     case BCM_COSQ_GPORT_SUBSCRIBER:
   7409     case (BCM_COSQ_GPORT_SUBSCRIBER | BCM_COSQ_GPORT_MCAST_QUEUE_GROUP):
   7410         if (numq != 1) {
   7411             return BCM_E_PARAM;
   7412         }
   7413 
   7414         if ((flags & BCM_COSQ_GPORT_MCAST_QUEUE_GROUP) &&
   7415             (!soc_feature(unit, soc_feature_mmu_packing))) {
   7416             return BCM_E_PARAM;
   7417         }
   7418 
   7419         if (flags & BCM_COSQ_GPORT_MCAST_QUEUE_GROUP) {
   7420             /* check for pre allocated subscriber queues */
   7421             if (mmu_info->num_sub_queues == 0) {
   7422                 list = &mmu_info->global_qlist;
   7423                 max_queues = mmu_info->num_queues;
   7424                 BCM_IF_ERROR_RETURN
   7425                     (_bcm_kt2_node_index_get(unit, list->bits, mmu_info->num_queues/2,
   7426                                              max_queues, mmu_info->qset_size, 1, &id));
   7427                 _bcm_kt2_node_index_set(list, id, 1);
   7428                 BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_SYSQID_SET(*gport,
   7429                                                                   local_port, id);
   7430             } else {
   7431                 list = &mmu_info->sub_mcqlist;
   7432                 max_queues = mmu_info->num_sub_queues;
   7433                 BCM_IF_ERROR_RETURN
   7434                     (_bcm_kt2_node_index_get(unit, list->bits, 0, max_queues,
   7435                                              mmu_info->qset_size, 1, &id));
   7436                 _bcm_kt2_node_index_set(list, id, 1);
   7437                 BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_SYSQID_SET(*gport,
   7438                                                                   local_port, id);
   7439                 id += (mmu_info->base_sub_queue + mmu_info->num_queues / 2);
   7440             }
   7441         } else {
   7442             /* check for pre allocated subscriber queues */
   7443             if (mmu_info->num_sub_queues == 0) {
   7444                 list = &mmu_info->global_qlist;
   7445                 max_queues = (soc_feature(unit, soc_feature_mmu_packing) ?
   7446                               mmu_info->num_queues / 2 : mmu_info->num_queues);
   7447                 BCM_IF_ERROR_RETURN
   7448                     (_bcm_kt2_node_index_get(unit, list->bits, 0, max_queues,
   7449                                              mmu_info->qset_size, 1, &id));
   7450                 _bcm_kt2_node_index_set(list, id, 1);
   7451                 BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_SYSQID_SET(*gport,
   7452                                                                   local_port, id);
   7453             } else {
   7454                 list = &mmu_info->sub_qlist;
   7455                 max_queues = mmu_info->num_sub_queues;
   7456                 BCM_IF_ERROR_RETURN
   7457                     (_bcm_kt2_node_index_get(unit, list->bits, 0, max_queues,
   7458                                              mmu_info->qset_size, 1, &id));
   7459                 _bcm_kt2_node_index_set(list, id, 1);
   7460                 BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_SYSQID_SET(*gport,
   7461                                                                   local_port, id);
   7462                 id += mmu_info->base_sub_queue;
   7463             }
   7464         }
   7465         node = &mmu_info->queue_node[id];
   7466         node->gport = *gport;
   7467         node->numq = numq;
   7468         if (flags & BCM_COSQ_GPORT_SUBSCRIBER) {
   7469             node->hw_index = id;
   7470         }
   7471         if (flags == BCM_COSQ_GPORT_VLAN_UCAST_QUEUE_GROUP) {
   7472             node->type = _BCM_KT2_NODE_VLAN_UCAST;
   7473         }
   7474         if (id < port_info->uc_vlan_base) {
   7475             port_info->uc_vlan_base = id;
   7476         }
   7477         break;
   7478 
   7479     case (BCM_COSQ_GPORT_WITH_ID |  BCM_COSQ_GPORT_SUBSCRIBER):
   7480         if (numq != 1) {
   7481             return BCM_E_PARAM;
   7482         }
   7483 
   7484         if (BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_SYSPORTID_GET(*gport)
   7485               != local_port) {
   7486             return BCM_E_PARAM;
   7487         }
   7488 
   7489         id = BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(*gport);
   7490         if ((id >= mmu_info->num_sub_queues) ||
   7491              (mmu_info->num_sub_queues == 0) ||
   7492              (mmu_info->intf_ref_cnt[id] != 0)) {
   7493             return BCM_E_PARAM;
   7494         }
   7495         max_queues = mmu_info->num_sub_queues;
   7496 
   7497         node = &mmu_info->queue_node[id + mmu_info->base_sub_queue];
   7498         if(node->numq != 0) {
   7499             return BCM_E_EXISTS;
   7500         }
   7501         _bcm_kt2_node_index_set(&mmu_info->sub_qlist, id, 1);
   7502         _bcm_kt2_node_index_set(&mmu_info->l2_sub_qlist, id, 1);
   7503 
   7504         id += mmu_info->base_sub_queue;
   7505         node->hw_index  = id;
   7506         node->gport = *gport;
   7507         node->numq = numq;
   7508         node->type = _BCM_KT2_NODE_SUBSCRIBER_GPORT_ID;
   7509         node->level = _BCM_KT2_COSQ_NODE_LEVEL_L2;
   7510         if (id < port_info->uc_vlan_base) {
   7511             port_info->uc_vlan_base = id;
   7512         }
   7513         break;
   7514 
   7515     case (BCM_COSQ_GPORT_WITH_ID |  BCM_COSQ_GPORT_SUBSCRIBER |
   7516           BCM_COSQ_GPORT_MCAST_QUEUE_GROUP):
   7517 
   7518         if (numq != 1) {
   7519             return BCM_E_PARAM;
   7520         }
   7521 
   7522         if ((flags & BCM_COSQ_GPORT_MCAST_QUEUE_GROUP) &&
   7523             (!soc_feature(unit, soc_feature_mmu_packing))) {
   7524             return BCM_E_PARAM;
   7525         }
   7526 
   7527         if (BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_SYSPORTID_GET(*gport)
   7528               != local_port) {
   7529             return BCM_E_PARAM;
   7530         }
   7531 
   7532         id = BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(*gport);
   7533         if ((id >= mmu_info->num_sub_queues) ||
   7534              (mmu_info->num_sub_queues == 0) ||
   7535              (mmu_info->intf_ref_cnt[id] != 0)) {
   7536             return BCM_E_PARAM;
   7537         }
   7538         max_queues = mmu_info->num_sub_queues;
   7539 
   7540         node = &mmu_info->queue_node[id + mmu_info->base_sub_queue + mmu_info->num_queues/2];
   7541         if(node->numq != 0) {
   7542             return BCM_E_EXISTS;
   7543         }
   7544         _bcm_kt2_node_index_set(&mmu_info->sub_mcqlist, id, 1);
   7545         _bcm_kt2_node_index_set(&mmu_info->l2_sub_mcqlist, id, 1);
   7546 
   7547         id += (mmu_info->base_sub_queue + mmu_info->num_queues/2);
   7548         node->hw_index  = id;
   7549         node->gport = *gport;
   7550         node->numq = numq;
   7551         node->type = _BCM_KT2_NODE_SUBSCRIBER_GPORT_ID;
   7552         node->level = _BCM_KT2_COSQ_NODE_LEVEL_L2;
   7553         break;
   7554 
   7555     case BCM_COSQ_GPORT_DESTMOD_UCAST_QUEUE_GROUP:
   7556         if (numq != 1) {
   7557             return BCM_E_PARAM;
   7558         }
   7559 
   7560         if (!IS_HG_PORT(unit, local_port)) {
   7561             return BCM_E_PORT;
   7562         }
   7563         if (mmu_info->num_dmvoq_queues == 0) { 
   7564             list = &mmu_info->global_qlist;
   7565             max_queues = mmu_info->num_queues;
   7566         } else {
   7567             list = &mmu_info->dmvoq_qlist;
   7568             max_queues = mmu_info->num_dmvoq_queues;
   7569         }
   7570 
   7571         BCM_IF_ERROR_RETURN
   7572             (_bcm_kt2_node_index_get(unit, list->bits, 0, max_queues,
   7573                                      mmu_info->qset_size, 1, &id));
   7574         _bcm_kt2_node_index_set(list, id, 1);
   7575         BCM_GPORT_DESTMOD_QUEUE_GROUP_SYSQID_SET(*gport, local_port, id);
   7576         if (mmu_info->num_dmvoq_queues == 1) {
   7577             id  +=  mmu_info->base_dmvoq_queue;  
   7578         }
   7579         node = &mmu_info->queue_node[id];
   7580         node->gport = *gport;
   7581         node->numq = numq;
   7582         node->level = _BCM_KT2_COSQ_NODE_LEVEL_L2;
   7583         node->type = _BCM_KT2_NODE_VOQ;
   7584         break;
   7585 
   7586     case (BCM_COSQ_GPORT_WITH_ID | BCM_COSQ_GPORT_DESTMOD_UCAST_QUEUE_GROUP):
   7587         if (numq != 1) {
   7588             return BCM_E_PARAM;
   7589         }
   7590 
   7591         if (!IS_HG_PORT(unit, local_port)) {
   7592             return BCM_E_PORT;
   7593         }
   7594 
   7595         if (BCM_GPORT_DESTMOD_QUEUE_GROUP_SYSPORTID_GET(*gport) 
   7596                 != local_port) {
   7597             return BCM_E_PARAM;
   7598         }    
   7599 
   7600         id = BCM_GPORT_DESTMOD_QUEUE_GROUP_QID_GET(*gport);
   7601         if ((id >= mmu_info->num_dmvoq_queues) ||
   7602              (mmu_info->num_dmvoq_queues == 0)) {
   7603             return BCM_E_PARAM;
   7604         }
   7605         max_queues = mmu_info->num_dmvoq_queues;
   7606         node = &mmu_info->queue_node[id + mmu_info->base_dmvoq_queue];
   7607         if(node->numq != 0) {
   7608             return BCM_E_EXISTS;
   7609         }
   7610         _bcm_kt2_node_index_set(&mmu_info->dmvoq_qlist, id, 1);
   7611         _bcm_kt2_node_index_set(&mmu_info->l2_dmvoq_qlist, id, 1);
   7612         id += mmu_info->base_dmvoq_queue;
   7613         node->hw_index  = id;  
   7614         node->gport = *gport;
   7615         node->numq = numq;          
   7616         node->level = _BCM_KT2_COSQ_NODE_LEVEL_L2;
   7617         node->type = _BCM_KT2_NODE_VOQ_ID;
   7618         break;
   7619        
   7620     case BCM_COSQ_GPORT_SCHEDULER_WFQ:
   7621     case BCM_COSQ_GPORT_SCHEDULER:
   7622     case (BCM_COSQ_GPORT_SCHEDULER | BCM_COSQ_GPORT_SCHEDULER_WFQ):
   7623         /* passthru */
   7624     case 0:  
   7625 
   7626         if (numq == 0 || numq < -1) {
   7627             return BCM_E_PARAM;
   7628         }
   7629 
   7630         if (flags & BCM_COSQ_GPORT_SCHEDULER) {
   7631             BCM_IF_ERROR_RETURN
   7632                 (_bcm_kt2_cosq_max_nodes_get(unit, _BCM_KT2_COSQ_NODE_LEVEL_L2,
   7633                                             &max_nodes));
   7634         } else {
   7635             BCM_IF_ERROR_RETURN
   7636                 (_bcm_kt2_cosq_max_nodes_get(unit, _BCM_KT2_COSQ_NODE_LEVEL_L0,
   7637                                             &max_nodes));
   7638         }
   7639         if (numq > max_nodes) {
   7640             return BCM_E_PARAM;
   7641         }
   7642 
   7643         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &local_modid));
   7644         BCM_IF_ERROR_RETURN
   7645             (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, local_modid,
   7646                                      local_port, &modid_out, &port_out));
   7647 
   7648         if ((flags == 0) || (flags == BCM_COSQ_GPORT_SCHEDULER_WFQ)) {
   7649             /* this is a port level scheduler */
   7650             id = port_out;
   7651 
   7652             if ( id < 0 || id >= num_port_schedulers[unit]) {
   7653                 return BCM_E_PARAM;
   7654             }
   7655 
   7656             _bcm_kt2_node_index_set(&mmu_info->sched_list, id, 1);
   7657             node = &mmu_info->sched_node[id];
   7658             sched_encap = (id << 8) | port_out;
   7659             BCM_GPORT_SCHEDULER_SET(*gport, sched_encap);
   7660             node->gport = *gport;
   7661             node->level = _BCM_KT2_COSQ_NODE_LEVEL_ROOT;
   7662             node->hw_index = id;
   7663             node->numq = numq;
   7664             node->cosq_attached_to = 0;
   7665             if (flags == BCM_COSQ_GPORT_SCHEDULER_WFQ) {
   7666                 node->wrr_mode = 1;
   7667                 node->type = _BCM_KT2_NODE_SCHEDULER_WFQ;
   7668             }
   7669         } else {
   7670             if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
   7671                 id = BCM_GPORT_SUBPORT_PORT_GET(port);
   7672 #if defined BCM_METROLITE_SUPPORT
   7673                 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
   7674                     /*
   7675                      * Allocate S1 node from extended sched list if pp_port
   7676                      * is reused
   7677                      */
   7678                     if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, id) &&
   7679                         (id <= num_port_schedulers[unit])) {
   7680                         id += SOC_INFO(unit).cpu_hg_pp_port_index;
   7681                     }
   7682                 }
   7683 #endif
   7684             } else {
   7685                 BCM_IF_ERROR_RETURN
   7686                     (_bcm_kt2_node_index_get(unit, mmu_info->sched_list.bits,
   7687                                             soc_max_num_pp_ports[unit] + 1,
   7688                                             mmu_info->num_nodes, 1, 1, &id));
   7689             }    
   7690             _bcm_kt2_node_index_set(&mmu_info->sched_list, id, 1);
   7691             node = &mmu_info->sched_node[id];
   7692             sched_encap = (id << 8) | port_out;
   7693             BCM_GPORT_SCHEDULER_SET(*gport, sched_encap);
   7694             node->gport = *gport;
   7695             node->numq = numq;
   7696             node->cosq_attached_to = -1;
   7697             if (flags & BCM_COSQ_GPORT_SCHEDULER_WFQ) {
   7698                 node->wrr_mode = 1;
   7699                 node->type = _BCM_KT2_NODE_SCHEDULER_WFQ;
   7700             }
   7701             if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
   7702                 node->subport_enabled = 1;
   7703             }
   7704        }
   7705        break;
   7706         
   7707     case BCM_COSQ_GPORT_WITH_ID:
   7708         if (BCM_GPORT_IS_SCHEDULER(*gport)) {
   7709             if (numq == 0 || numq < -1 || numq > 8) {
   7710                 return BCM_E_PARAM;
   7711             }
   7712             id = BCM_GPORT_SCHEDULER_GET(*gport);
   7713 
   7714             if (id != local_port) {
   7715                 return BCM_E_PARAM;
   7716             }    
   7717             
   7718             /* allow only port or subport level scheduler with id */
   7719             if ( id < 0 || id >= soc_max_num_pp_ports[unit]) {
   7720                 return BCM_E_PARAM;
   7721             }
   7722 
   7723             _bcm_kt2_node_index_set(&mmu_info->sched_list, id, 1);
   7724             node = &mmu_info->sched_node[id];
   7725             node->gport = *gport;
   7726             node->level = _BCM_KT2_COSQ_NODE_LEVEL_ROOT;
   7727             node->hw_index = id;
   7728             node->numq = numq;
   7729             node->cosq_attached_to = 0;
   7730         } else if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(*gport)) {
   7731             if (numq != 1) {
   7732                 return BCM_E_PARAM;
   7733             }
   7734 
   7735             if (BCM_GPORT_UCAST_QUEUE_GROUP_SYSPORTID_GET(*gport) 
   7736                                                    != local_port) {
   7737                 return BCM_E_PARAM;
   7738             }    
   7739             
   7740             id = BCM_GPORT_UCAST_QUEUE_GROUP_QID_GET(*gport);
   7741             port_info = &mmu_info->port[local_port];
   7742             /* allow only base queues */
   7743             if (id < port_info->q_offset || id >= port_info->q_limit) {
   7744                 return BCM_E_PARAM;
   7745             }
   7746 
   7747             list = &mmu_info->l2_base_qlist; 
   7748             if (SHR_BITGET(list->bits, id) != 0) {
   7749                 return BCM_E_RESOURCE;
   7750             }    
   7751 
   7752             node = &mmu_info->queue_node[id];
   7753             if (node->numq != 0) {
   7754                 return BCM_E_EXISTS;
   7755             }
   7756             
   7757             _bcm_kt2_node_index_set(&mmu_info->l2_base_qlist, id, 1);
   7758             node->hw_index  = id;  
   7759             node->gport = *gport;
   7760             node->numq = numq;          
   7761         } else {
   7762             return BCM_E_PARAM;
   7763         }
   7764         break;
   7765         
   7766     default:
   7767         return BCM_E_PARAM;
   7768     }
   7769     if ((flags == BCM_COSQ_GPORT_UCAST_QUEUE_GROUP) ||
   7770         (flags == BCM_COSQ_GPORT_MCAST_QUEUE_GROUP) ||
   7771         (flags == BCM_COSQ_GPORT_VLAN_UCAST_QUEUE_GROUP) ||
   7772         (flags == BCM_COSQ_GPORT_SUBSCRIBER) ||
   7773         (flags == (BCM_COSQ_GPORT_SUBSCRIBER | BCM_COSQ_GPORT_MCAST_QUEUE_GROUP)) ||
   7774         (flags == (BCM_COSQ_GPORT_WITH_ID |  BCM_COSQ_GPORT_SUBSCRIBER)) ||
   7775         (flags == (BCM_COSQ_GPORT_WITH_ID |  BCM_COSQ_GPORT_SUBSCRIBER |
   7776                    BCM_COSQ_GPORT_MCAST_QUEUE_GROUP)) ||
   7777         (flags == BCM_COSQ_GPORT_DESTMOD_UCAST_QUEUE_GROUP) ||
   7778         (flags == (BCM_COSQ_GPORT_WITH_ID | BCM_COSQ_GPORT_DESTMOD_UCAST_QUEUE_GROUP))) {
   7779         BCM_IF_ERROR_RETURN(
   7780             bcm_kt2_handle_queue_min_accounting(unit, local_port,
   7781                                                 node->hw_index, 1));
   7782     }
   7783     LOG_INFO(BSL_LS_BCM_COSQ,
   7784              (BSL_META_U(unit,
   7785                          "                       gport=0x%x\n"),
   7786               *gport));
   7787 
   7788     return BCM_E_NONE;
   7789 }
   7790 /*
   7791  * Function:
   7792  *     bcm_kt2_cosq_is_attached
   7793  * Purpose:
   7794  *     To check if any queue is attached to port
   7795  * Parameters:
   7796  *     unit  - (IN) unit number
   7797  *     port  - (IN) Physical port number
   7798  *     exclude_default - (IN) if set skip default queues
   7799  *     vlan_queue_present - (OUT) Set TRUE if queue is attached
   7800  * Returns:
   7801  *     BCM_E_XXX
   7802  */
   7803 int
   7804 bcm_kt2_cosq_is_attached(int unit,
   7805                          bcm_port_t port,
   7806                          int exclude_default,
   7807                          int *vlan_queue_present)
   7808 {
   7809     _bcm_kt2_mmu_info_t *mmu_info;
   7810     _bcm_kt2_cosq_port_info_t *port_info;
   7811     uint32 *bmap = NULL;
   7812     int max_word_count, word, index, bit;
   7813 
   7814     /* Parameter sanity check */
   7815     if (port < 0) {
   7816         return BCM_E_PORT;
   7817     }
   7818     if (vlan_queue_present == NULL) {
   7819         return BCM_E_PARAM;
   7820     }
   7821     max_word_count = _SHR_BITDCLSIZE(soc_mem_index_count(unit,
   7822                                               LLS_L2_PARENTm));
   7823     bmap = SOC_CONTROL(unit)->port_lls_l2_bmap[port];
   7824 
   7825     /*
   7826      * Caller of this routine may invoke it with logical
   7827      * port number for coe, linkphy or mpls applications.
   7828      * In these cases bmap will be null. If it is NULL then
   7829      * return BCM_E_NONE without changing vlan_queue_present.
   7830      */
   7831     if (bmap == NULL) {
   7832         return BCM_E_NONE;
   7833     }
   7834 
   7835     for (word = 0; word < max_word_count; word++) {
   7836          if (bmap[word] == 0) {
   7837              continue;
   7838          }
   7839          for (bit = 0; bit < SHR_BITWID; bit++) {
   7840               if (!(bmap[word] & (1 << bit))) {
   7841                     continue;
   7842               }
   7843               index = word * SHR_BITWID + bit;
   7844               /* check if index is for default queue */
   7845               mmu_info = _bcm_kt2_mmu_info[unit];
   7846               port_info = &mmu_info->port[port];
   7847               if (exclude_default &&
   7848                   ((index >= port_info->q_offset &&
   7849                    index < port_info->q_limit) ||
   7850                   (index >= port_info->mcq_offset &&
   7851                    index < port_info->mcq_limit))) {
   7852                    continue;
   7853               }
   7854               *vlan_queue_present = 1;
   7855               return BCM_E_NONE;
   7856          }
   7857     }
   7858     *vlan_queue_present = 0;
   7859     return BCM_E_NONE;
   7860 }
   7861 /*
   7862  * Function:
   7863  *     bcm_kt2_cosq_gport_delete
   7864  * Purpose:
   7865  *     Destroy a cosq gport structure
   7866  * Parameters:
   7867  *     unit  - (IN) unit number
   7868  *     gport - (IN) GPORT identifier
   7869  * Returns:
   7870  *     BCM_E_XXX
   7871  */
   7872 int
   7873 bcm_kt2_cosq_gport_delete(int unit, bcm_gport_t gport)
   7874 {
   7875     _bcm_kt2_cosq_node_t *node;
   7876     _bcm_kt2_mmu_info_t *mmu_info;
   7877     _bcm_kt2_cosq_port_info_t *port_info;
   7878     int vlan_queue_present = 1;
   7879     bcm_port_t local_port;
   7880     uint32 rval = 0;
   7881     int encap_id = 0;
   7882     int rv = BCM_E_NONE;
   7883 
   7884     LOG_INFO(BSL_LS_BCM_COSQ,
   7885              (BSL_META_U(unit,
   7886                          "bcm_kt2_cosq_gport_delete: unit=%d gport=0x%x\n"),
   7887               unit, gport));
   7888 
   7889     if (_bcm_kt2_mmu_info[unit] == NULL) {
   7890         return BCM_E_INIT;
   7891     }
   7892     mmu_info = _bcm_kt2_mmu_info[unit];
   7893     
   7894     BCM_IF_ERROR_RETURN
   7895         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL, &node));
   7896 
   7897     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   7898         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
   7899         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
   7900         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   7901         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
   7902         if (node->cosq_attached_to >= 0) {
   7903             /* reset the shaper configuration for the
   7904              * node
   7905              */
   7906 
   7907             BCM_IF_ERROR_RETURN (bcm_kt2_cosq_gport_bandwidth_set(unit,
   7908                          node->gport, 0, 0, 0, _BCM_XGS_METER_FLAG_RESET));
   7909             BCM_IF_ERROR_RETURN
   7910                 (bcm_kt2_cosq_gport_detach(unit, gport, node->parent->gport, 
   7911                                           node->cosq_attached_to));
   7912         }
   7913         if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
   7914             encap_id = BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(gport);
   7915             if (mmu_info->num_sub_queues > 0) {
   7916                 _bcm_kt2_node_index_clear(&mmu_info->sub_qlist,
   7917                         encap_id, 1);
   7918                 encap_id += mmu_info->base_sub_queue;
   7919             } else {
   7920                 _bcm_kt2_node_index_clear(&mmu_info->global_qlist,
   7921                                   encap_id, 1);
   7922             }
   7923             /* Check if all unicast vlan queues of this port are deleted */
   7924             BCM_IF_ERROR_RETURN(
   7925                 bcm_kt2_cosq_is_attached(unit, local_port, 1,
   7926                                          &vlan_queue_present));
   7927             port_info = &mmu_info->port[local_port];
   7928             if (!vlan_queue_present) {
   7929                 port_info->uc_vlan_base = mmu_info->num_queues - 1;
   7930                 SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, local_port, &rval));
   7931                 soc_reg_field_set(unit, ING_COS_MODEr, &rval,
   7932                                   SERVICE_BASE_QUEUE_NUMf, port_info->uc_vlan_base);
   7933                 SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, local_port, rval));
   7934             }
   7935         }
   7936         if (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
   7937             encap_id = BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(gport);
   7938             if (mmu_info->num_sub_queues > 0) {
   7939                 _bcm_kt2_node_index_clear(&mmu_info->sub_mcqlist,
   7940                         encap_id - mmu_info->num_queues/2, 1);
   7941                 encap_id += mmu_info->base_sub_queue;
   7942             } else {
   7943                 _bcm_kt2_node_index_clear(&mmu_info->global_qlist,
   7944                                   encap_id, 1);
   7945             }
   7946         }
   7947 
   7948         if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport)) {
   7949             encap_id = BCM_GPORT_DESTMOD_QUEUE_GROUP_QID_GET(gport);
   7950             if (mmu_info->num_dmvoq_queues > 0) {
   7951                 _bcm_kt2_node_index_clear(&mmu_info->dmvoq_qlist,
   7952                         encap_id, 1);
   7953                 encap_id += mmu_info->base_dmvoq_queue;
   7954             } else {
   7955                 _bcm_kt2_node_index_clear(&mmu_info->global_qlist,
   7956                         encap_id, 1);
   7957             }
   7958         }
   7959         BCM_IF_ERROR_RETURN(
   7960             bcm_kt2_handle_queue_min_accounting(unit, local_port,
   7961                                                 encap_id, 0));
   7962         _BCM_KT2_COSQ_NODE_INIT(node);
   7963     } else {
   7964         /* 
   7965          *  Deleting the SUB-Tree 
   7966          */
   7967         if (node->child != NULL) {
   7968             BCM_IF_ERROR_RETURN
   7969                 (_bcm_kt2_cosq_gport_delete_all(unit, node->child->gport, &rv));
   7970         }
   7971         /* 
   7972          *  Deleting the parent Node 
   7973          */
   7974         BCM_IF_ERROR_RETURN
   7975             (_bcm_kt2_cosq_gport_delete_node(unit, gport));
   7976     }
   7977 
   7978     return rv;
   7979 }
   7980 
   7981 /*
   7982  * Function:
   7983  *     bcm_kt2_cosq_gport_get
   7984  * Purpose:
   7985  *     Get a cosq gport structure
   7986  * Parameters:
   7987  *     unit  - (IN) unit number
   7988  *     gport - (IN) GPORT identifier
   7989  *     port  - (OUT) port number
   7990  *     numq  - (OUT) number of COS queues
   7991  *     flags - (OUT) flags (BCM_COSQ_GPORT_XXX)
   7992  * Returns:
   7993  *     BCM_E_XXX
   7994  */
   7995 int
   7996 bcm_kt2_cosq_gport_get(int unit, bcm_gport_t gport, bcm_gport_t *port,
   7997                       int *numq, uint32 *flags)
   7998 {
   7999     _bcm_kt2_cosq_node_t *node;
   8000     bcm_module_t modid;
   8001     bcm_port_t local_port;
   8002     int id;
   8003     _bcm_gport_dest_t dest;
   8004 
   8005     if (port == NULL || numq == NULL || flags == NULL) {
   8006         return BCM_E_PARAM;
   8007     }
   8008 
   8009     LOG_INFO(BSL_LS_BCM_COSQ,
   8010              (BSL_META_U(unit,
   8011                          "bcm_kt2_cosq_gport_get: unit=%d gport=0x%x\n"),
   8012               unit, gport));
   8013 
   8014     BCM_IF_ERROR_RETURN
   8015         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, &id, &node));
   8016 
   8017     if (SOC_USE_GPORT(unit)) {
   8018         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid));
   8019         dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
   8020         dest.modid = modid;
   8021         dest.port = local_port;
   8022         BCM_IF_ERROR_RETURN(_bcm_esw_gport_construct(unit, &dest, port));
   8023     } else {
   8024         *port = local_port;
   8025     }
   8026 
   8027     *numq = node->numq;
   8028 
   8029     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   8030         *flags = BCM_COSQ_GPORT_UCAST_QUEUE_GROUP;
   8031     } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   8032         *flags = BCM_COSQ_GPORT_MCAST_QUEUE_GROUP; 
   8033     } else if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport)) {
   8034         *flags = BCM_COSQ_GPORT_DESTMOD_UCAST_QUEUE_GROUP; 
   8035     } else if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
   8036         *flags = BCM_COSQ_GPORT_SUBSCRIBER;
   8037         if (node->type == _BCM_KT2_NODE_VLAN_UCAST) {
   8038             *flags = BCM_COSQ_GPORT_VLAN_UCAST_QUEUE_GROUP;
   8039         }
   8040     } else if (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
   8041         *flags = (BCM_COSQ_GPORT_SUBSCRIBER |
   8042                   BCM_COSQ_GPORT_MCAST_QUEUE_GROUP);
   8043     } else if (BCM_GPORT_IS_SCHEDULER(gport)) {
   8044         *flags = BCM_COSQ_GPORT_SCHEDULER;
   8045         if (node->type == _BCM_KT2_NODE_SCHEDULER_WFQ) {
   8046             if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_ROOT) {
   8047                 *flags = BCM_COSQ_GPORT_SCHEDULER_WFQ;
   8048             } else {
   8049                 *flags = BCM_COSQ_GPORT_SCHEDULER_WFQ |
   8050                          BCM_COSQ_GPORT_SCHEDULER;
   8051             }
   8052         }
   8053     } else {
   8054         *flags = 0;
   8055     }
   8056 
   8057     LOG_INFO(BSL_LS_BCM_COSQ,
   8058              (BSL_META_U(unit,
   8059                          "                       port=0x%x numq=%d flags=0x%x\n"),
   8060               *port, *numq, *flags));
   8061 
   8062     return BCM_E_NONE;
   8063 }
   8064 
   8065 /*
   8066  * Function:
   8067  *     bcm_kt2_cosq_gport_traverse
   8068  * Purpose:
   8069  *     Walks through the valid COSQ GPORTs and calls
   8070  *     the user supplied callback function for each entry.
   8071  * Parameters:
   8072  *     unit       - (IN) unit number
   8073  *     trav_fn    - (IN) Callback function.
   8074  *     user_data  - (IN) User data to be passed to callback function
   8075  * Returns:
   8076  *     BCM_E_NONE - Success.
   8077  *     BCM_E_XXX
   8078  */
   8079 int
   8080 bcm_kt2_cosq_gport_traverse(int unit, bcm_cosq_gport_traverse_cb cb,
   8081                            void *user_data)
   8082 {
   8083     _bcm_kt2_cosq_node_t *port_info;
   8084     _bcm_kt2_mmu_info_t *mmu_info;
   8085     bcm_module_t my_modid, modid_out;
   8086     bcm_port_t port, port_out;
   8087 
   8088     if (_bcm_kt2_mmu_info[unit] == NULL) {
   8089         return BCM_E_INIT;
   8090     }
   8091     mmu_info = _bcm_kt2_mmu_info[unit];
   8092 
   8093     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
   8094     PBMP_ALL_ITER(unit, port) {
   8095         BCM_IF_ERROR_RETURN
   8096             (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
   8097                                     my_modid, port, &modid_out, &port_out));
   8098         /* root node */
   8099         port_info = &mmu_info->sched_node[port_out];
   8100 
   8101         if (port_info->gport >= 0) {
   8102             _bcm_kt2_cosq_gport_traverse(unit, port_info->gport, cb, user_data);
   8103         }
   8104       }
   8105 
   8106     return BCM_E_NONE;
   8107 }
   8108 
   8109 /*
   8110  * Function:
   8111  *     bcm_kt2_cosq_gport_egress_mapping_set
   8112  * Purpose:
   8113  *     Determine which COS queue a given priority currently maps to.
   8114  * Parameters:
   8115  *     unit     - (IN) unit number
   8116  *     gport    - (IN) queue group GPORT identifier
   8117  *     priority - (IN) priority value to map
   8118  *     cosq     - (IN) COS queue to map to
   8119  * Returns:
   8120  *     BCM_E_XXX
   8121  */
   8122 int
   8123 bcm_kt2_cosq_gport_egress_mapping_set(int unit, bcm_port_t gport, bcm_cos_t priority,
   8124                         bcm_cos_t cosq, uint32 flags)
   8125 { 
   8126     bcm_pbmp_t ports;
   8127     bcm_port_t local_port;
   8128     BCM_PBMP_CLEAR(ports);
   8129 
   8130     if (gport == -1) {    /* all ports */
   8131         BCM_PBMP_ASSIGN(ports, PBMP_ALL(unit));
   8132         if ( soc_feature(unit, soc_feature_flex_port)) {
   8133             BCM_IF_ERROR_RETURN(
   8134                     _bcm_kt2_flexio_pbmp_update(unit,
   8135                         &ports));
   8136         }
   8137     } else {
   8138         return _bcm_kt2_cosq_gport_egress_mapping_set_regular(unit, gport, priority, cosq, flags);
   8139     }
   8140 
   8141     PBMP_ITER(ports, local_port) {
   8142         BCM_IF_ERROR_RETURN
   8143             (_bcm_kt2_cosq_gport_egress_mapping_set_regular(unit, local_port, priority, 
   8144                                                cosq, flags));
   8145 
   8146     }    
   8147 
   8148     return BCM_E_NONE;
   8149 }
   8150 
   8151 
   8152 /*
   8153  * Function:
   8154  *     bcm_kt2_cosq_mapping_get
   8155  * Purpose:
   8156  *     Determine which COS queue a given priority currently maps to.
   8157  * Parameters:
   8158  *     unit     - (IN) unit number
   8159  *     gport    - (IN) queue group GPORT identifier
   8160  *     priority - (IN) priority value to map
   8161  *     cosq     - (OUT) COS queue to map to
   8162  * Returns:
   8163  *     BCM_E_XXX
   8164  */
   8165 int
   8166 bcm_kt2_cosq_gport_egress_mapping_get(int unit, bcm_port_t gport, bcm_cos_t *priority,
   8167                         bcm_cos_queue_t *cosq, uint32 flags)
   8168 {
   8169     bcm_port_t port;
   8170     soc_field_t field = REDIRECT_COSf;
   8171     int index;
   8172     egr_port_entry_t egr_port_entry;
   8173     void *entry_p;
   8174 
   8175     if (BCM_GPORT_IS_SET(gport)) {
   8176         BCM_IF_ERROR_RETURN(
   8177                 bcm_esw_port_local_get(unit, gport, &port));
   8178     } else {
   8179         port = gport;
   8180     }
   8181 
   8182     if (!SOC_PORT_VALID(unit, port) || !IS_ALL_PORT(unit, port)) {
   8183         return BCM_E_PORT;
   8184     }
   8185 
   8186     BCM_IF_ERROR_RETURN
   8187         (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port_entry));
   8188     index = soc_mem_field32_get(unit, EGR_PORTm, &egr_port_entry,
   8189                                 EGR_COS_MAP_SELf);
   8190     index *= 16;
   8191 
   8192     entry_p = SOC_PROFILE_MEM_ENTRY(unit, _bcm_kt2_egr_cos_map_profile[unit],
   8193                                     egr_cos_map_entry_t *,
   8194                                     index + *priority);
   8195     *cosq = soc_mem_field32_get(unit, EGR_COS_MAPm, entry_p, field);
   8196 
   8197 
   8198     return BCM_E_NONE;
   8199 }
   8200 /*
   8201  * Function:
   8202  *     bcm_kt2_cosq_mapping_set
   8203  * Purpose:
   8204  *     Determine which COS queue a given priority currently maps to.
   8205  * Parameters:
   8206  *     unit     - (IN) unit number
   8207  *     gport    - (IN) queue group GPORT identifier
   8208  *     priority - (IN) priority value to map
   8209  *     cosq     - (IN) COS queue to map to
   8210  * Returns:
   8211  *     BCM_E_XXX
   8212  */
   8213 int
   8214 bcm_kt2_cosq_mapping_set(int unit, bcm_port_t gport, bcm_cos_t priority,
   8215                         bcm_cos_queue_t cosq)
   8216 { 
   8217     bcm_pbmp_t ports;
   8218     bcm_port_t local_port;
   8219     BCM_PBMP_CLEAR(ports);
   8220 
   8221     if (gport == -1) {    /* all ports */
   8222         BCM_PBMP_ASSIGN(ports, PBMP_ALL(unit));
   8223         if ( soc_feature(unit, soc_feature_flex_port)) {
   8224             BCM_IF_ERROR_RETURN(
   8225                     _bcm_kt2_flexio_pbmp_update(unit,
   8226                         &ports));
   8227         }
   8228     } else {
   8229         return _bcm_kt2_cosq_mapping_set_regular(unit, gport, 1, &priority, &cosq);
   8230     }
   8231 
   8232     PBMP_ITER(ports, local_port) {
   8233         BCM_IF_ERROR_RETURN
   8234             (_bcm_kt2_cosq_mapping_set_regular(unit, local_port, 1, &priority, 
   8235                                                &cosq));
   8236 
   8237     }    
   8238 
   8239     return BCM_E_NONE;
   8240 }
   8241 
   8242 /*
   8243  * Function:
   8244  *     bcm_kt2_cosq_port_mapping_multi_set
   8245  * Purpose:
   8246  *     Determine which COS queue a given priority currently maps to.
   8247  * Parameters:
   8248  *     unit           - (IN) unit number
   8249  *     gport          - (IN) queue group GPORT identifier
   8250  *     count          - (IN) number of entries to be configured (or retrieved)
   8251  *     priority_array - (IN) array of priority value to map
   8252  *     cosq_array     - (IN) array of COS queue to map to
   8253  * Returns:
   8254  *     BCM_E_XXX
   8255  */
   8256 int
   8257 bcm_kt2_cosq_port_mapping_multi_set(int unit, bcm_port_t gport,int count,
   8258                         bcm_cos_t *priority_array, bcm_cos_queue_t *cosq_array)
   8259 {
   8260     bcm_pbmp_t ports;
   8261     bcm_port_t local_port;
   8262     BCM_PBMP_CLEAR(ports);
   8263 
   8264     if (gport == -1) {    /* all ports */
   8265         BCM_PBMP_ASSIGN(ports, PBMP_ALL(unit));
   8266         if ( soc_feature(unit, soc_feature_flex_port)) {
   8267             BCM_IF_ERROR_RETURN(
   8268                     _bcm_kt2_flexio_pbmp_update(unit,
   8269                         &ports));
   8270         }
   8271     } else {
   8272         return _bcm_kt2_cosq_mapping_set_regular(unit, gport, count,
   8273                                             priority_array, cosq_array);
   8274     }
   8275 
   8276     PBMP_ITER(ports, local_port) {
   8277         BCM_IF_ERROR_RETURN
   8278             (_bcm_kt2_cosq_mapping_set_regular(unit, local_port, count,
   8279                                     priority_array, cosq_array));
   8280     }
   8281     return BCM_E_NONE;
   8282 }
   8283 
   8284 /*
   8285  * Function:
   8286  *     _bcm_kt2_cosq_mapping_get_regular
   8287  * Purpose:
   8288  *     Determine which COS queue a given priority currently maps to.
   8289  * Parameters:
   8290  *     unit           - (IN) unit number
   8291  *     gport          - (IN) queue group GPORT identifier
   8292  *     count          - (IN) number of entries to be retrieved
   8293  *     priority_array - (IN) priority array values 
   8294  *     cosq_array     - (OUT) COS queue values mapped to priority 
   8295  * Returns:
   8296  *     BCM_E_XXX
   8297  */
   8298 
   8299 STATIC
   8300 int _bcm_kt2_cosq_mapping_get_regular (int unit, bcm_port_t gport,int count,
   8301                     bcm_cos_t *priority_array, bcm_cos_queue_t *cosq_array)
   8302 {
   8303     _bcm_kt2_mmu_info_t *mmu_info;
   8304     bcm_port_t port;
   8305     int numq;
   8306     bcm_cos_queue_t hw_cosq;
   8307     soc_field_t field = COSf;
   8308     int index;
   8309     int count_index = 0;
   8310     cos_map_sel_entry_t cos_map_sel_entry;
   8311     void *entry_p;
   8312     bcm_pbmp_t ports;
   8313 
   8314 
   8315     if (count < 1 || count > 16){
   8316         return BCM_E_PARAM;
   8317     }
   8318 
   8319     if ((NULL == priority_array) || (NULL == cosq_array)){
   8320         return BCM_E_PARAM;
   8321     }
   8322 
   8323     for (count_index = 0; count_index < count; count_index++) { 
   8324         if (priority_array[count_index] < 0 || priority_array[count_index] >= 16) {
   8325             return BCM_E_PARAM;
   8326         }
   8327     }
   8328 
   8329     if (gport == -1) {
   8330         BCM_PBMP_ASSIGN(ports, PBMP_ALL(unit));
   8331         PBMP_ITER(ports, port) {
   8332             BCM_IF_ERROR_RETURN
   8333                 (READ_COS_MAP_SELm(unit, MEM_BLOCK_ANY, port, 
   8334                                    &cos_map_sel_entry));
   8335             index = soc_mem_field32_get(unit, COS_MAP_SELm, 
   8336                                         &cos_map_sel_entry,
   8337                                         SELECTf);
   8338             index *= 16;
   8339 
   8340             entry_p = SOC_PROFILE_MEM_ENTRY(unit, _bcm_kt2_cos_map_profile[unit],
   8341                     port_cos_map_entry_t *,
   8342                     index + priority_array[0]); /*only return for first priority*/
   8343             cosq_array[0] = soc_mem_field32_get(unit, PORT_COS_MAPm, entry_p, field);
   8344             return BCM_E_NONE;
   8345         }
   8346     }
   8347     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   8348         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   8349         BCM_IF_ERROR_RETURN
   8350             (_bcm_kt2_cosq_index_resolve
   8351             (unit, gport, -1, _BCM_KT2_COSQ_INDEX_STYLE_UCAST_QUEUE,
   8352              &port, NULL, NULL));
   8353     } else if(_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT (unit, gport)) {
   8354         port = _BCM_KT2_SUBPORT_PORT_ID_GET(gport);
   8355     } else { 
   8356         if (BCM_GPORT_IS_SET(gport)) {
   8357             BCM_IF_ERROR_RETURN(
   8358                 bcm_esw_port_local_get(unit, gport, &port));
   8359         } else {
   8360             port = gport;
   8361         }
   8362 
   8363         if (!SOC_PORT_VALID(unit, port) || !IS_ALL_PORT(unit, port)) {
   8364             return BCM_E_PORT;
   8365         }
   8366     } 
   8367 
   8368     mmu_info = _bcm_kt2_mmu_info[unit];
   8369     numq = mmu_info->port[port].q_limit - 
   8370            mmu_info->port[port].q_offset;
   8371     
   8372     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   8373         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   8374         field = (numq <= 8) ? COSf : HG_COSf;
   8375     }
   8376 
   8377     BCM_IF_ERROR_RETURN
   8378         (READ_COS_MAP_SELm(unit, MEM_BLOCK_ANY, port, &cos_map_sel_entry));
   8379     index = soc_mem_field32_get(unit, COS_MAP_SELm, &cos_map_sel_entry,
   8380                                 SELECTf);
   8381     index *= 16;
   8382 
   8383     for (count_index = 0; count_index < count; count_index++) {
   8384         entry_p = SOC_PROFILE_MEM_ENTRY(unit, _bcm_kt2_cos_map_profile[unit],
   8385                 port_cos_map_entry_t *,
   8386                 index + priority_array[count_index]);
   8387         hw_cosq = soc_mem_field32_get(unit, PORT_COS_MAPm, entry_p, field);
   8388 
   8389         if (hw_cosq >= numq) {
   8390             return BCM_E_NOT_FOUND;
   8391         }
   8392         cosq_array[count_index] = hw_cosq;
   8393     }
   8394     return BCM_E_NONE;
   8395 }
   8396 
   8397 /*
   8398  * Function:
   8399  *     bcm_kt2_cosq_port_mapping_multi_get
   8400  * Purpose:
   8401  *     Determine which COS queue a given priority currently maps to.
   8402  * Parameters:
   8403  *     unit           - (IN) unit number
   8404  *     gport          - (IN) queue group GPORT identifier
   8405  *     count          - (IN) number of entries to be retrieved
   8406  *     priority_array - (IN) priority array values 
   8407  *     cosq_array     - (OUT) COS queue values mapped to priority 
   8408  * Returns:
   8409  *     BCM_E_XXX
   8410  */
   8411 int
   8412 bcm_kt2_cosq_port_mapping_multi_get(int unit, bcm_port_t gport, int count,
   8413                     bcm_cos_t *priority_array, bcm_cos_queue_t *cosq_array)
   8414 {
   8415     return _bcm_kt2_cosq_mapping_get_regular (unit, gport,count,
   8416                         priority_array, cosq_array);
   8417 }
   8418 
   8419 /*
   8420  * Function:
   8421  *     bcm_kt2_cosq_mapping_get
   8422  * Purpose:
   8423  *     Determine which COS queue a given priority currently maps to.
   8424  * Parameters:
   8425  *     unit     - (IN) unit number
   8426  *     gport    - (IN) queue group GPORT identifier
   8427  *     priority - (IN) priority value to map
   8428  *     cosq     - (OUT) COS queue to map to
   8429  * Returns:
   8430  *     BCM_E_XXX
   8431  */
   8432 int
   8433 bcm_kt2_cosq_mapping_get(int unit, bcm_port_t gport, bcm_cos_t priority,
   8434                         bcm_cos_queue_t *cosq)
   8435 {
   8436     return _bcm_kt2_cosq_mapping_get_regular (unit, gport, 1,
   8437                         &priority, cosq);
   8438 
   8439 }
   8440 
   8441 /*
   8442  * Function:
   8443  *     bcm_kt2_cosq_port_sched_set
   8444  * Purpose:
   8445  *     Set up class-of-service policy and corresponding weights and delay
   8446  * Parameters:
   8447  *     unit    - (IN) unit number
   8448  *     pbm     - (IN) port bitmap
   8449  *     mode    - (IN) Scheduling mode (BCM_COSQ_xxx)
   8450  *     weights - (IN) Weights for each COS queue
   8451  *     delay   - This parameter is not used
   8452  * Returns:
   8453  *     BCM_E_XXX
   8454  * Notes:
   8455  *     For non-ETS style scheduler (CPU port) only.
   8456  */
   8457 int
   8458 bcm_kt2_cosq_port_sched_set(int unit, bcm_pbmp_t pbm,
   8459                            int mode, const int *weights, int delay)
   8460 {
   8461     bcm_port_t port;
   8462     int num_cos=0;
   8463     int num_weights;
   8464 
   8465     bcm_kt2_cosq_config_get(unit, &num_cos);  
   8466     BCM_PBMP_ITER(pbm, port) {
   8467         num_weights = IS_CPU_PORT(unit, port) ? BCM_COS_COUNT : num_cos;
   8468             
   8469         BCM_IF_ERROR_RETURN
   8470             (_bcm_kt2_cosq_port_sched_set(unit, port, 0, mode, num_weights,
   8471                                          (int *)weights));
   8472     }
   8473 
   8474     return BCM_E_NONE;
   8475 }
   8476 
   8477 /*
   8478  * Function:
   8479  *     bcm_kt2_cosq_port_sched_get
   8480  * Purpose:
   8481  *     Retrieve class-of-service policy and corresponding weights and delay
   8482  * Parameters:
   8483  *     unit     - (IN) unit number
   8484  *     pbm      - (IN) port bitmap
   8485  *     mode     - (OUT) Scheduling mode (BCM_COSQ_XXX)
   8486  *     weights  - (OUT) Weights for each COS queue
   8487  *     delay    - This parameter is not used
   8488  * Returns:
   8489  *     BCM_E_XXX
   8490  * Notes:
   8491  *     For non-ETS style scheduler (CPU port) only.
   8492  */
   8493 int
   8494 bcm_kt2_cosq_port_sched_get(int unit, bcm_pbmp_t pbm,
   8495                            int *mode, int *weights, int *delay)
   8496 {
   8497     bcm_port_t port;
   8498     int num_cos=0;
   8499     int num_weights;
   8500     
   8501     
   8502     bcm_kt2_cosq_config_get(unit, &num_cos);  
   8503     BCM_PBMP_ITER(pbm, port) {
   8504         num_weights = IS_CPU_PORT(unit, port) ? BCM_COS_COUNT : num_cos;
   8505         
   8506         BCM_IF_ERROR_RETURN
   8507             (_bcm_kt2_cosq_port_sched_get(unit, port, 0, mode, num_weights, 
   8508                                          weights));        
   8509     }
   8510 
   8511     return BCM_E_NONE;
   8512 }
   8513 
   8514 /*
   8515  * Function:
   8516  *     bcm_kt2_cosq_sched_weight_max_get
   8517  * Purpose:
   8518  *     Retrieve maximum weights for given COS policy
   8519  * Parameters:
   8520  *     unit    - (IN) unit number
   8521  *     mode    - (IN) Scheduling mode (BCM_COSQ_xxx)
   8522  *     weight_max - (OUT) Maximum weight for COS queue.
   8523  * Returns:
   8524  *     BCM_E_XXX
   8525  */
   8526 int
   8527 bcm_kt2_cosq_sched_weight_max_get(int unit, int mode, int *weight_max)
   8528 {
   8529     switch (mode) {
   8530     case BCM_COSQ_STRICT:
   8531         *weight_max = BCM_COSQ_WEIGHT_STRICT;
   8532         break;
   8533     case BCM_COSQ_ROUND_ROBIN:
   8534         *weight_max = BCM_COSQ_WEIGHT_MIN;
   8535         break;
   8536     case BCM_COSQ_WEIGHTED_ROUND_ROBIN:
   8537     case BCM_COSQ_DEFICIT_ROUND_ROBIN:
   8538         *weight_max =
   8539             (1 << soc_mem_field_length(unit, LLS_L0_CHILD_WEIGHT_CFG_CNTm, 
   8540                                        C_WEIGHTf)) - 1;
   8541         break;
   8542     default:
   8543         return BCM_E_PARAM;
   8544     }
   8545 
   8546     return BCM_E_NONE;
   8547 }
   8548 
   8549 /*
   8550  * Function:
   8551  *     bcm_kt2_cosq_bandwidth_set
   8552  * Purpose:
   8553  *     Configure COS queue bandwidth control
   8554  * Parameters:
   8555  *     unit          - (IN) unit number
   8556  *     port          - (IN) port number or GPORT identifier
   8557  *     cosq          - (IN) COS queue number
   8558  *     min_quantum   - (IN)
   8559  *     max_quantum   - (IN)
   8560  *     burst_quantum - (IN)
   8561  *     flags         - (IN)
   8562  * Returns:
   8563  *     BCM_E_XXX
   8564  * Notes:
   8565  *     If port is any form of local port, cosq is the hardware queue index.
   8566  */
   8567 int
   8568 bcm_kt2_cosq_port_bandwidth_set(int unit, bcm_port_t port,
   8569                                bcm_cos_queue_t cosq,
   8570                                uint32 min_quantum, uint32 max_quantum,
   8571                                uint32 burst_quantum, uint32 flags)
   8572 {
   8573     if (cosq < 0) {
   8574         return BCM_E_PARAM;
   8575     }
   8576 
   8577     return _bcm_kt2_cosq_bucket_set(unit, port, cosq, min_quantum,
   8578                                    max_quantum, min_quantum, 
   8579                                    burst_quantum, flags);
   8580 }
   8581 
   8582 /*
   8583  * Function:
   8584  *     bcm_kt2_cosq_bandwidth_get
   8585  * Purpose:
   8586  *     Get COS queue bandwidth control configuration
   8587  * Parameters:
   8588  *     unit          - (IN) unit number
   8589  *     port          - (IN) port number or GPORT identifier
   8590  *     cosq          - (IN) COS queue number
   8591  *     min_quantum   - (OUT)
   8592  *     max_quantum   - (OUT)
   8593  *     burst_quantum - (OUT)
   8594  *     flags         - (OUT)
   8595  * Returns:
   8596  *     BCM_E_XXX
   8597  * Notes:
   8598  *     If port is any form of local port, cosq is the hardware queue index.
   8599  */
   8600 int
   8601 bcm_kt2_cosq_port_bandwidth_get(int unit, bcm_port_t port,
   8602                                bcm_cos_queue_t cosq,
   8603                                uint32 *min_quantum, uint32 *max_quantum,
   8604                                uint32 *burst_quantum, uint32 *flags)
   8605 {
   8606 
   8607     if (cosq < 0) {
   8608         return BCM_E_PARAM;
   8609     }
   8610 
   8611     BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_bucket_get(unit, port, cosq, min_quantum,
   8612                                                 max_quantum, burst_quantum,
   8613                                                 burst_quantum, *flags));
   8614     *flags = 0;
   8615 
   8616     return BCM_E_NONE;
   8617 }
   8618 
   8619 int
   8620 bcm_kt2_cosq_port_pps_set(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   8621                          int pps)
   8622 {
   8623     uint32 min, max, burst_min, burst_max;
   8624 
   8625     if (!IS_CPU_PORT(unit, port)) {
   8626         return BCM_E_PORT;
   8627     } else if (cosq < 0 || cosq >= NUM_CPU_COSQ(unit)) {
   8628         return BCM_E_PARAM;
   8629     }
   8630 
   8631     BCM_IF_ERROR_RETURN
   8632         (_bcm_kt2_cosq_bucket_get(unit, port, cosq, &min, &max, &burst_min,
   8633                                  &burst_max, _BCM_XGS_METER_FLAG_PACKET_MODE));
   8634 
   8635     return _bcm_kt2_cosq_bucket_set(unit, port, cosq, min, pps, burst_min,
   8636                                    burst_max, _BCM_XGS_METER_FLAG_PACKET_MODE);
   8637 }
   8638 
   8639 int
   8640 bcm_kt2_cosq_port_pps_get(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   8641                          int *pps)
   8642 {
   8643     uint32 min, max, burst_min, burst_max;
   8644 
   8645     if (!IS_CPU_PORT(unit, port)) {
   8646         return BCM_E_PORT;
   8647     } else if (cosq < 0 || cosq >= NUM_CPU_COSQ(unit)) {
   8648         return BCM_E_PARAM;
   8649     }
   8650 
   8651     BCM_IF_ERROR_RETURN
   8652         (_bcm_kt2_cosq_bucket_get(unit, port, cosq, &min, &max, &burst_min,
   8653                                  &burst_max, _BCM_XGS_METER_FLAG_PACKET_MODE));
   8654     *pps = max;
   8655 
   8656     return BCM_E_NONE;
   8657 }
   8658 
   8659 int
   8660 bcm_kt2_cosq_port_burst_set(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   8661                            int burst)
   8662 {
   8663     uint32 min, max, cur_burst_min, cur_burst_max;
   8664 
   8665     if (!IS_CPU_PORT(unit, port)) {
   8666         return BCM_E_PORT;
   8667     } else if (cosq < 0 || cosq >= NUM_CPU_COSQ(unit)) {
   8668         return BCM_E_PARAM;
   8669     }
   8670 
   8671     /* Get the current PPS and BURST settings */
   8672     BCM_IF_ERROR_RETURN
   8673         (_bcm_kt2_cosq_bucket_get(unit, port, cosq, &min, &max, &cur_burst_min,
   8674                              &cur_burst_max, _BCM_XGS_METER_FLAG_PACKET_MODE));
   8675 
   8676     /* Replace the current BURST setting, keep PPS the same */
   8677     return _bcm_kt2_cosq_bucket_set(unit, port, cosq, min, max, cur_burst_min,
   8678                                burst, _BCM_XGS_METER_FLAG_PACKET_MODE);
   8679 }
   8680 
   8681 int
   8682 bcm_kt2_cosq_port_burst_get(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   8683                            int *burst)
   8684 {
   8685     uint32 min, max, cur_burst_min, cur_burst_max;
   8686 
   8687     if (!IS_CPU_PORT(unit, port)) {
   8688         return BCM_E_PORT;
   8689     } else if (cosq < 0 || cosq >= NUM_CPU_COSQ(unit)) {
   8690         return BCM_E_PARAM;
   8691     }
   8692 
   8693     BCM_IF_ERROR_RETURN
   8694         (_bcm_kt2_cosq_bucket_get(unit, port, cosq, &min, &max, &cur_burst_min,
   8695                               &cur_burst_max, _BCM_XGS_METER_FLAG_PACKET_MODE));
   8696     *burst = cur_burst_max;
   8697 
   8698     return BCM_E_NONE;
   8699 }
   8700 
   8701 /*
   8702  * Function:
   8703  *     bcm_kt2_cosq_gport_sched_set
   8704  * Purpose:
   8705  *     Configure COS queue scheduler setting
   8706  * Parameters:
   8707  *      unit   - (IN) unit number
   8708  *      gport  - (IN) GPORT identifier
   8709  *      cosq   - (IN) COS queue to configure, -1 for all COS queues
   8710  *      mode   - (IN) Scheduling mode, one of BCM_COSQ_xxx
   8711  *      weight - (IN) queue weight
   8712  * Returns:
   8713  *      BCM_E_XXX
   8714  */
   8715 int
   8716 bcm_kt2_cosq_gport_sched_set(int unit, bcm_gport_t gport,
   8717                             bcm_cos_queue_t cosq, int mode, int weight)
   8718 {
   8719     int rv, numq, i, count;
   8720 
   8721     if (cosq == -1) {
   8722         BCM_IF_ERROR_RETURN
   8723             (_bcm_kt2_cosq_index_resolve(unit, gport, cosq,
   8724                                         _BCM_KT2_COSQ_INDEX_STYLE_SCHEDULER,
   8725                                         NULL, NULL, &numq));
   8726         cosq = 0;
   8727     } else {
   8728         numq = 1;
   8729     }
   8730 
   8731     count = 0;
   8732     for (i = 0; i < numq; i++) {
   8733         rv = _bcm_kt2_cosq_sched_set(unit, gport, cosq + i, mode, 1, &weight);
   8734         if (rv == BCM_E_NOT_FOUND) {
   8735             continue;
   8736         } else if (BCM_FAILURE(rv)) {
   8737             return rv;
   8738         } else {
   8739             count++;
   8740         }
   8741     }
   8742 
   8743     return count > 0 ? BCM_E_NONE : BCM_E_NOT_FOUND;
   8744 }
   8745 
   8746 /*
   8747  * Function:
   8748  *     bcm_kt2_cosq_gport_sched_get
   8749  * Purpose:
   8750  *     Get COS queue scheduler setting
   8751  * Parameters:
   8752  *     unit   - (IN) unit number
   8753  *     gport  - (IN) GPORT identifier
   8754  *     cosq   - (IN) COS queue to get, -1 for any queue
   8755  *     mode   - (OUT) Scheduling mode, one of BCM_COSQ_xxx
   8756  *     weight - (OUT) queue weight
   8757  * Returns:
   8758  *     BCM_E_XXX
   8759  */
   8760 int
   8761 bcm_kt2_cosq_gport_sched_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
   8762                             int *mode, int *weight)
   8763 {
   8764     int rv, numq, i;
   8765 
   8766     if (cosq == -1) {
   8767         BCM_IF_ERROR_RETURN
   8768             (_bcm_kt2_cosq_index_resolve(unit, gport, cosq,
   8769                                         _BCM_KT2_COSQ_INDEX_STYLE_SCHEDULER,
   8770                                         NULL, NULL, &numq));
   8771         cosq = 0;
   8772     } else {
   8773         numq = 1;
   8774     }
   8775 
   8776     for (i = 0; i < numq; i++) {
   8777         rv = _bcm_kt2_cosq_sched_get(unit, gport, cosq + i, mode, 1, weight);
   8778         if (rv == BCM_E_NOT_FOUND) {
   8779             continue;
   8780         } else {
   8781             return rv;
   8782         }
   8783     }
   8784 
   8785     return BCM_E_NOT_FOUND;
   8786 }
   8787 
   8788 /*
   8789  * Function:
   8790  *     bcm_kt2_cosq_gport_child_node_bandwidth_set
   8791  * Purpose:
   8792  *     Configure COS queue bandwidth control
   8793  * Parameters:
   8794  *     unit   - (IN) unit number
   8795  *     gport  - (IN) GPORT identifier
   8796  *     cosq   - (IN) COS queue to configure, -1 for all COS queues
   8797  *     kbits_sec_min - (IN) minimum bandwidth, kbits/sec
   8798  *     kbits_sec_max - (IN) maximum bandwidth, kbits/sec
   8799  *     flags  - (IN) BCM_COSQ_BW_*
   8800  * Returns:
   8801  *     BCM_E_XXX
   8802  */
   8803 int
   8804 bcm_kt2_cosq_gport_child_node_bandwidth_set(int unit,
   8805                                 bcm_gport_t gport, bcm_cos_queue_t cosq,
   8806                                 uint32 kbits_sec_min, uint32 kbits_sec_max,
   8807                                 uint32 flags)
   8808 {
   8809     _bcm_kt2_cosq_node_t *node = NULL;
   8810     _bcm_kt2_cosq_node_t *cur_node = NULL;
   8811     bcm_gport_t cur_gport;
   8812     int start_cos;
   8813     int end_cos;
   8814     int numq, i;
   8815     uint32 temp_kbits_sec_min = 0;
   8816     uint32 temp_kbits_sec_max = 0;
   8817     uint32 kbits_sec_burst_min = 0;
   8818     uint32 kbits_sec_burst_max = 0;
   8819     uint32 child_found_flag=0;
   8820     bcm_port_t local_port;
   8821     _bcm_kt2_mmu_info_t *mmu_info;
   8822 
   8823     cur_gport = gport;
   8824 
   8825     BCM_IF_ERROR_RETURN
   8826             (_bcm_kt2_cosq_index_resolve(unit, gport, cosq,
   8827                                          _BCM_KT2_COSQ_INDEX_STYLE_BUCKET,
   8828                                          &local_port, NULL, &numq));
   8829     if (cosq == -1) {
   8830         start_cos = 0;
   8831         end_cos = numq - 1;
   8832 
   8833     } else {
   8834         start_cos = end_cos = cosq;
   8835     }
   8836 
   8837     if ((BCM_GPORT_IS_SET(gport)) &&
   8838         (BCM_GPORT_IS_SCHEDULER(gport))) {
   8839         BCM_IF_ERROR_RETURN
   8840             (_bcm_kt2_cosq_node_get(unit, gport, NULL, NULL, NULL, &node));
   8841     }
   8842 
   8843     if (node) {
   8844         /* For Port gport, L0, L1 scheduler nodes */
   8845         if (cosq >= node->numq) {
   8846             return BCM_E_PARAM;
   8847         }
   8848         child_found_flag = 0;
   8849         for (i = 0, cur_node = node->child; cur_node; 
   8850                     cur_node = cur_node->sibling, i++) {
   8851             
   8852             /* get the child node at cosq */
   8853             if ((cosq != -1) && (cur_node->cosq_attached_to != cosq)) {
   8854                 continue;
   8855             }
   8856             child_found_flag = 1;
   8857             cur_gport = cur_node->gport;
   8858 
   8859             BCM_IF_ERROR_RETURN
   8860                 (_bcm_kt2_cosq_bucket_get(unit, cur_gport
   8861                                      ,cur_node->cosq_attached_to,
   8862                                      &temp_kbits_sec_min,
   8863                                      &temp_kbits_sec_max,
   8864                                      &kbits_sec_burst_min,
   8865                                      &kbits_sec_burst_max, 0));
   8866             if ((kbits_sec_burst_min || kbits_sec_burst_max) &&
   8867                 (!(flags & BCM_COSQ_BW_BURST_CALCULATE)))
   8868             {
   8869                 flags = _BCM_XGS_METER_FLAG_NON_BURST_CORRECTION;
   8870             }
   8871 
   8872             BCM_IF_ERROR_RETURN
   8873                 (_bcm_kt2_cosq_bucket_set(unit, cur_gport,
   8874                                     cur_node->cosq_attached_to,  kbits_sec_min,
   8875                                     kbits_sec_max, kbits_sec_burst_min,
   8876                                     kbits_sec_burst_max, flags));
   8877             if (flags & BCM_COSQ_BW_BURST_CALCULATE) {
   8878                 cur_node->burst_calculation_enable = 1;
   8879             } else {
   8880                 cur_node->burst_calculation_enable = 0;
   8881             }
   8882         }
   8883         if (child_found_flag == 0) {
   8884             return BCM_E_NOT_FOUND;
   8885         }
   8886     } else {
   8887         /* For Port and L2 queues */
   8888         for (i = start_cos; i <= end_cos; i++) {
   8889             BCM_IF_ERROR_RETURN
   8890                 (_bcm_kt2_cosq_bucket_get(unit, cur_gport, i,
   8891                                      &temp_kbits_sec_min,
   8892                                      &temp_kbits_sec_max,
   8893                                      &kbits_sec_burst_min,
   8894                                      &kbits_sec_burst_max, 0));
   8895 
   8896             if ((kbits_sec_burst_min || kbits_sec_burst_max) &&
   8897                 (!(flags & BCM_COSQ_BW_BURST_CALCULATE)))
   8898             {
   8899                 flags = _BCM_XGS_METER_FLAG_NON_BURST_CORRECTION;
   8900             }
   8901             BCM_IF_ERROR_RETURN
   8902                 (_bcm_kt2_cosq_bucket_set(unit, cur_gport,
   8903                                           i, kbits_sec_min,
   8904                                           kbits_sec_max,
   8905                                           kbits_sec_burst_min,
   8906                                           kbits_sec_burst_max, flags));
   8907             mmu_info = _bcm_kt2_mmu_info[unit];
   8908             cur_node = &mmu_info->queue_node[mmu_info->port[
   8909                                              local_port].q_offset + i];
   8910             if (flags & BCM_COSQ_BW_BURST_CALCULATE) {
   8911                 cur_node->burst_calculation_enable = 1;
   8912             } else {
   8913                 cur_node->burst_calculation_enable = 0;
   8914             }
   8915         }
   8916     }
   8917 
   8918     return BCM_E_NONE;
   8919 }
   8920 
   8921 /*
   8922  * Function:
   8923  *     bcm_kt2_cosq_gport_child_node_bandwidth_get
   8924  * Purpose:
   8925  *     Get COS queue bandwidth control configuration
   8926  * Parameters:
   8927  *     unit   - (IN) unit number
   8928  *     gport  - (IN) GPORT identifier
   8929  *     cosq   - (IN) COS queue to get, -1 for any COS queue
   8930  *     kbits_sec_min - (OUT) minimum bandwidth, kbits/sec
   8931  *     kbits_sec_max - (OUT) maximum bandwidth, kbits/sec
   8932  *     flags  - (OUT) BCM_COSQ_BW_*
   8933  * Returns:
   8934  *     BCM_E_XXX
   8935  */
   8936 int
   8937 bcm_kt2_cosq_gport_child_node_bandwidth_get(int unit, bcm_gport_t gport,
   8938                                 bcm_cos_queue_t cosq, uint32 *kbits_sec_min,
   8939                                 uint32 *kbits_sec_max, uint32 *flags)
   8940 {
   8941     uint32 burst_min, burst_max;
   8942     _bcm_kt2_cosq_node_t *node = NULL;
   8943     _bcm_kt2_cosq_node_t *cur_node = NULL;
   8944     bcm_gport_t cur_gport;
   8945     int i;
   8946     bcm_port_t local_port;
   8947     _bcm_kt2_mmu_info_t *mmu_info;
   8948 
   8949     i = (cosq == -1) ? 0 : cosq;
   8950 
   8951     cur_gport = gport;
   8952     if ((BCM_GPORT_IS_SET(gport)) &&
   8953         (BCM_GPORT_IS_SCHEDULER(gport))) {
   8954        /* get the child node at cosq
   8955         */
   8956         BCM_IF_ERROR_RETURN
   8957             (_bcm_kt2_cosq_node_get(unit, gport, NULL, NULL, NULL, &node));
   8958         if (node != NULL) {
   8959             if (cosq >= node->numq) { 
   8960                 return BCM_E_PARAM; 
   8961             }
   8962             /* resolve the child attached to input cosq */
   8963             BCM_IF_ERROR_RETURN(
   8964                _bcm_kt2_cosq_child_node_at_input(node, i, &cur_node));
   8965             cur_gport = cur_node->gport;
   8966 
   8967         } else {
   8968             return BCM_E_PARAM;
   8969         }
   8970 
   8971     } else {
   8972         BCM_IF_ERROR_RETURN
   8973             (_bcm_kt2_cosq_index_resolve(unit, gport, i,
   8974                                          _BCM_KT2_COSQ_INDEX_STYLE_BUCKET,
   8975                                          &local_port, NULL, NULL));
   8976         mmu_info = _bcm_kt2_mmu_info[unit];
   8977         cur_node = &mmu_info->queue_node[mmu_info->port[
   8978                                          local_port].q_offset + i];
   8979     }
   8980 
   8981     BCM_IF_ERROR_RETURN
   8982         (_bcm_kt2_cosq_bucket_get(unit, cur_gport, i,
   8983                                   kbits_sec_min, kbits_sec_max,
   8984                                   &burst_min, &burst_max, *flags));
   8985 
   8986     *flags = 0;
   8987     if (cur_node->burst_calculation_enable == 1) {
   8988         *flags |= BCM_COSQ_BW_BURST_CALCULATE;
   8989     }
   8990     return BCM_E_NONE;
   8991 }
   8992 
   8993 /*
   8994  * Function:
   8995  *     bcm_kt2_cosq_gport_bandwidth_set
   8996  * Purpose:
   8997  *     Configure COS queue bandwidth control
   8998  * Parameters:
   8999  *     unit   - (IN) unit number
   9000  *     gport  - (IN) GPORT identifier
   9001  *     cosq   - (IN) COS queue to configure, -1 for all COS queues
   9002  *     kbits_sec_min - (IN) minimum bandwidth, kbits/sec
   9003  *     kbits_sec_max - (IN) maximum bandwidth, kbits/sec
   9004  *     flags  - (IN) BCM_COSQ_BW_*
   9005  * Returns:
   9006  *     BCM_E_XXX
   9007  */
   9008 int
   9009 bcm_kt2_cosq_gport_bandwidth_set(int unit, bcm_gport_t gport,
   9010                                 bcm_cos_queue_t cosq, uint32 kbits_sec_min,
   9011                                 uint32 kbits_sec_max, uint32 flags)
   9012 {
   9013     int numq, i;
   9014     if (cosq == -1) {
   9015         BCM_IF_ERROR_RETURN
   9016             (_bcm_kt2_cosq_index_resolve(unit, gport, cosq,
   9017                                         _BCM_KT2_COSQ_INDEX_STYLE_BUCKET,
   9018                                         NULL, NULL, &numq));
   9019         cosq = 0;
   9020     } else {
   9021         numq = 1;
   9022     }
   9023     for (i = 0; i < numq; i++) {
   9024         BCM_IF_ERROR_RETURN
   9025             (_bcm_kt2_cosq_bucket_set(unit, gport, cosq + i, kbits_sec_min,
   9026                                       kbits_sec_max, kbits_sec_min,
   9027                                       kbits_sec_max, flags));
   9028     }
   9029 
   9030     return BCM_E_NONE;
   9031 }
   9032 
   9033 /*
   9034  * Function:
   9035  *     bcm_kt2_cosq_gport_bandwidth_get
   9036  * Purpose:
   9037  *     Get COS queue bandwidth control configuration
   9038  * Parameters:
   9039  *     unit   - (IN) unit number
   9040  *     gport  - (IN) GPORT identifier
   9041  *     cosq   - (IN) COS queue to get, -1 for any COS queue
   9042  *     kbits_sec_min - (OUT) minimum bandwidth, kbits/sec
   9043  *     kbits_sec_max - (OUT) maximum bandwidth, kbits/sec
   9044  *     burst_min - (OUT) minimum burst rate
   9045  *     burst_max - (OUT) maximum burst rate
   9046  *     flags  - (OUT) BCM_COSQ_BW_*
   9047  * Returns:
   9048  *     BCM_E_XXX
   9049  */
   9050 int
   9051 bcm_kt2_cosq_gport_bandwidth_get(int unit, bcm_gport_t gport,
   9052                                 bcm_cos_queue_t cosq, uint32 *kbits_sec_min,
   9053                                 uint32 *kbits_sec_max, uint32 *burst_min,
   9054                                 uint32 *burst_max, uint32 *flags)
   9055 {
   9056     BCM_IF_ERROR_RETURN
   9057         (_bcm_kt2_cosq_bucket_get(unit, gport, 
   9058                                   cosq == -1 ? 0 : cosq,
   9059                                   kbits_sec_min, kbits_sec_max,
   9060                                   burst_min, burst_max, *flags));
   9061     
   9062     *flags = 0;
   9063 
   9064     return BCM_E_NONE;
   9065 }
   9066 
   9067 /*
   9068  * Function:
   9069  *     bcm_kt2_cosq_gport_bandwidth_burst_set
   9070  * Purpose:
   9071  *     Configure COS queue bandwidth burst setting
   9072  * Parameters:
   9073  *      unit        - (IN) unit number
   9074  *      gport       - (IN) GPORT identifier
   9075  *      cosq        - (IN) COS queue to configure, -1 for all COS queues
   9076  *      kbits_burst - (IN) maximum burst, kbits
   9077  * Returns:
   9078  *      BCM_E_XXX
   9079  */
   9080 int
   9081 bcm_kt2_cosq_gport_bandwidth_burst_set(int unit, bcm_gport_t gport,
   9082                                       bcm_cos_queue_t cosq,
   9083                                       uint32 kbits_burst_min,
   9084                                       uint32 kbits_burst_max)
   9085 {
   9086     int numq, i;
   9087     uint32 kbits_sec_min, kbits_sec_max;
   9088     uint32 kbits_sec_burst_min, kbits_sec_burst_max;
   9089     _bcm_kt2_cosq_node_t *node = NULL;
   9090     _bcm_kt2_cosq_node_t *cur_node = NULL;
   9091     bcm_gport_t cur_gport;
   9092     uint8 child_node_found = 0;
   9093 
   9094     if (cosq == -1) {
   9095         BCM_IF_ERROR_RETURN
   9096             (_bcm_kt2_cosq_index_resolve(unit, gport, cosq,
   9097                                         _BCM_KT2_COSQ_INDEX_STYLE_BUCKET,
   9098                                         NULL, NULL, &numq));
   9099         cosq = 0;
   9100     } else {
   9101         numq = 1;
   9102     }
   9103 
   9104     if ((soc_property_get(unit,
   9105         spn_COSQ_CONTROL_BURST_NODE_SELECT, 0)) &&
   9106         (BCM_GPORT_IS_SET(gport)) &&
   9107         (BCM_GPORT_IS_SCHEDULER(gport))) {
   9108         BCM_IF_ERROR_RETURN
   9109             (_bcm_kt2_cosq_node_get(unit, gport, NULL, NULL, NULL, &node));
   9110         if (node) {
   9111             /* For Port gport, L0, L1 scheduler nodes */
   9112             if (cosq >= node->numq) {
   9113                 return BCM_E_PARAM;
   9114             }
   9115             for (cur_node = node->child; cur_node; cur_node = cur_node->sibling) {
   9116                  /* get the child node at cosq */
   9117                  if ((cosq != -1) && (cur_node->cosq_attached_to != cosq)) {
   9118                      continue;
   9119                  }
   9120                  child_node_found = 1;
   9121                  cur_gport = cur_node->gport;
   9122 
   9123                  BCM_IF_ERROR_RETURN
   9124                     (_bcm_kt2_cosq_bucket_get(unit,
   9125                                               cur_gport,
   9126                                               cur_node->cosq_attached_to,
   9127                                               &kbits_sec_min,
   9128                                               &kbits_sec_max,
   9129                                               &kbits_sec_burst_min,
   9130                                               &kbits_sec_burst_max,
   9131                                               0));
   9132                  BCM_IF_ERROR_RETURN
   9133                     (_bcm_kt2_cosq_bucket_set(unit,
   9134                                               cur_gport,
   9135                                               cur_node->cosq_attached_to,
   9136                                               kbits_sec_min,
   9137                                               kbits_sec_max,
   9138                                               kbits_burst_min,
   9139                                               kbits_burst_max,
   9140                                               _BCM_XGS_METER_FLAG_NON_BURST_CORRECTION));
   9141                  if (cosq != -1) {
   9142                      break;
   9143                  }
   9144             }
   9145             if (child_node_found == 0) {
   9146                 return BCM_E_NOT_FOUND;
   9147             }
   9148         } else {
   9149             /* It should never come here */
   9150             return BCM_E_INTERNAL;
   9151         }
   9152     } else {
   9153         for (i = 0; i < numq; i++) {
   9154              BCM_IF_ERROR_RETURN
   9155                  (_bcm_kt2_cosq_bucket_get(unit, gport, cosq + i, &kbits_sec_min,
   9156                                            &kbits_sec_max, &kbits_sec_burst_min,
   9157                                            &kbits_sec_burst_max, 0));
   9158              BCM_IF_ERROR_RETURN
   9159                  (_bcm_kt2_cosq_bucket_set(unit, gport, cosq + i, kbits_sec_min,
   9160                                            kbits_sec_max, kbits_burst_min,
   9161                                            kbits_burst_max,
   9162                                            _BCM_XGS_METER_FLAG_NON_BURST_CORRECTION));
   9163        }
   9164     }
   9165     return BCM_E_NONE;
   9166 }
   9167 
   9168 /*
   9169  * Function:
   9170  *     bcm_kt2_cosq_gport_bandwidth_burst_get
   9171  * Purpose:
   9172  *     Get COS queue bandwidth burst setting
   9173  * Parameters:
   9174  *     unit        - (IN) unit number
   9175  *     gport       - (IN) GPORT identifier
   9176  *     cosq        - (IN) COS queue to get, -1 for any queue
   9177  *     kbits_burst - (OUT) maximum burst, kbits
   9178  * Returns:
   9179  *     BCM_E_XXX
   9180  */
   9181 int
   9182 bcm_kt2_cosq_gport_bandwidth_burst_get(int unit, bcm_gport_t gport,
   9183                                        bcm_cos_queue_t cosq,
   9184                                        uint32 *kbits_burst_min,
   9185                                        uint32 *kbits_burst_max)
   9186 {
   9187     uint32 kbits_sec_min, kbits_sec_max;
   9188     _bcm_kt2_cosq_node_t *node = NULL;
   9189     _bcm_kt2_cosq_node_t *cur_node = NULL;
   9190     bcm_gport_t cur_gport;
   9191     uint8 child_node_found = 0;
   9192 
   9193     if ((soc_property_get(unit,
   9194         spn_COSQ_CONTROL_BURST_NODE_SELECT, 0)) &&
   9195         (BCM_GPORT_IS_SET(gport)) &&
   9196         (BCM_GPORT_IS_SCHEDULER(gport))) {
   9197         BCM_IF_ERROR_RETURN
   9198             (_bcm_kt2_cosq_node_get(unit, gport, NULL, NULL, NULL, &node));
   9199         if (node) {
   9200 
   9201             /* For Port gport, L0, L1 scheduler nodes */
   9202             if (cosq >= node->numq) {
   9203                 return BCM_E_PARAM;
   9204             }
   9205             for (cur_node = node->child; cur_node; cur_node = cur_node->sibling) {
   9206                  /* get the child node at cosq */
   9207                  if ((cosq != -1) && (cur_node->cosq_attached_to != cosq)) {
   9208                      continue;
   9209                  }
   9210                  cur_gport = cur_node->gport;
   9211                  child_node_found = 1;
   9212                  BCM_IF_ERROR_RETURN
   9213                     (_bcm_kt2_cosq_bucket_get(unit,
   9214                                               cur_gport,
   9215                                               cur_node->cosq_attached_to,
   9216                                               &kbits_sec_min,
   9217                                               &kbits_sec_max,
   9218                                               kbits_burst_min,
   9219                                               kbits_burst_max,
   9220                                               0));
   9221                  break;
   9222             }
   9223             if (child_node_found == 0) {
   9224                 return BCM_E_NOT_FOUND;
   9225             }
   9226         } else {
   9227             /* It should never come here */
   9228             return BCM_E_INTERNAL;
   9229         }
   9230     } else {
   9231         BCM_IF_ERROR_RETURN
   9232             (_bcm_kt2_cosq_bucket_get(unit, gport, cosq == -1 ? 0 : cosq,
   9233                                       &kbits_sec_min, &kbits_sec_max,
   9234                                       kbits_burst_min, kbits_burst_max, 0));
   9235     }
   9236     return BCM_E_NONE;
   9237 }
   9238 
   9239 /*
   9240  * Function:
   9241  *     bcm_kt2_cosq_gport_discard_set
   9242  * Purpose:
   9243  *     Configure gport WRED setting
   9244  * Parameters:
   9245  *     unit    - (IN) unit number
   9246  *     port    - (IN) GPORT identifier
   9247  *     cosq    - (IN) COS queue to configure, -1 for all COS queues
   9248  *     discard - (IN) discard settings
   9249  * Returns:
   9250  *     BCM_E_XXX
   9251  */
   9252 int
   9253 bcm_kt2_cosq_gport_discard_set(int unit, bcm_gport_t gport,
   9254                                bcm_cos_queue_t cosq,
   9255                                bcm_cosq_gport_discard_t *discard)
   9256 {
   9257     int numq, i;
   9258     uint32 min_thresh, max_thresh;
   9259     int cell_size, cell_field_max;
   9260     int local_port;
   9261 
   9262     if (discard == NULL ||
   9263         discard->gain < 0 || discard->gain > 15 ||
   9264         discard->drop_probability < 0 || discard->drop_probability > 100) {
   9265         return BCM_E_PARAM;
   9266     }
   9267 
   9268     if (cosq < -1) {
   9269         return BCM_E_PARAM;
   9270     }
   9271     cell_size = _BCM_KT2_COSQ_CELLSIZE;
   9272     cell_field_max = KT2_CELL_FIELD_MAX;
   9273 
   9274     if (gport != -1) {
   9275         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   9276             BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   9277             BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   9278             BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) || 
   9279             BCM_GPORT_IS_SCHEDULER(gport)) {
   9280                 BCM_IF_ERROR_RETURN
   9281                 (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
   9282                                         NULL));
   9283         } else {
   9284             BCM_IF_ERROR_RETURN
   9285                 (_bcm_kt2_cosq_localport_resolve(unit, gport, &local_port));
   9286         }
   9287         if (IS_EXT_MEM_PORT(unit, local_port)) {
   9288             cell_size = _BCM_KT2_COSQ_EXT_CELLSIZE;
   9289             if (soc_feature(unit, soc_feature_mmu_packing)) {
   9290                 cell_size = _BCM_KT2_COSQ_EXT_PACKING_CELLSIZE;
   9291             }
   9292             cell_field_max = soc_kt2_get_max_buffer_size(unit, 1, cell_field_max);
   9293         } else {
   9294             cell_field_max = soc_kt2_get_max_buffer_size(unit, 0, cell_field_max);
   9295         }
   9296     }
   9297 
   9298     min_thresh = discard->min_thresh;
   9299     max_thresh = discard->max_thresh;
   9300     if (discard->flags & BCM_COSQ_DISCARD_BYTES) {
   9301         /* Convert bytes to cells */
   9302         min_thresh += (cell_size - 1);
   9303         min_thresh /= cell_size;
   9304 
   9305         max_thresh += (cell_size - 1);
   9306         max_thresh /= cell_size;
   9307 
   9308         if ((min_thresh > cell_field_max) ||
   9309             (max_thresh > cell_field_max)) {
   9310             return BCM_E_PARAM;
   9311         }
   9312     } else { /* BCM_COSQ_DISCARD_PACKETS */
   9313         if ((min_thresh > KT2_CELL_FIELD_MAX) ||
   9314             (max_thresh > KT2_CELL_FIELD_MAX)) {
   9315             return BCM_E_PARAM;
   9316         }
   9317     }
   9318 
   9319     if (cosq == -1) {
   9320         BCM_IF_ERROR_RETURN
   9321             (_bcm_kt2_cosq_index_resolve(unit, gport, cosq,
   9322                                         _BCM_KT2_COSQ_INDEX_STYLE_WRED,
   9323                                         NULL, NULL, &numq));
   9324         cosq = 0;
   9325     } else {
   9326         numq = 1;
   9327     }
   9328 
   9329     for (i = 0; i < numq; i++) {
   9330         BCM_IF_ERROR_RETURN
   9331             (_bcm_kt2_cosq_wred_set(unit, gport, cosq + i, discard->flags,
   9332                                    min_thresh, max_thresh,
   9333                                    discard->drop_probability, discard->gain,
   9334                                    FALSE));
   9335     }
   9336 
   9337     return BCM_E_NONE;
   9338 }
   9339 
   9340 /*
   9341  * Function:
   9342  *     bcm_kt2_cosq_gport_discard_get
   9343  * Purpose:
   9344  *     Get port WRED setting
   9345  * Parameters:
   9346  *     unit    - (IN) unit number
   9347  *     port    - (IN) GPORT identifier
   9348  *     cosq    - (IN) COS queue to get, -1 for any queue
   9349  *     discard - (OUT) discard settings
   9350  * Returns:
   9351  *     BCM_E_XXX
   9352  */
   9353 int
   9354 bcm_kt2_cosq_gport_discard_get(int unit, bcm_gport_t gport,
   9355                               bcm_cos_queue_t cosq,
   9356                               bcm_cosq_gport_discard_t *discard)
   9357 {
   9358     uint32 min_thresh, max_thresh;
   9359     int cell_size, cell_field_max;
   9360     int local_port;
   9361 
   9362 
   9363     if (discard == NULL) {
   9364         return BCM_E_PARAM;
   9365     }
   9366 
   9367     if (cosq < -1) {
   9368         return BCM_E_PARAM;
   9369     }
   9370     cell_size = _BCM_KT2_COSQ_CELLSIZE;
   9371     cell_field_max = KT2_CELL_FIELD_MAX;
   9372 
   9373     if (gport != -1) {
   9374         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   9375             BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   9376             BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   9377             BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) || 
   9378             BCM_GPORT_IS_SCHEDULER(gport)) {
   9379                 BCM_IF_ERROR_RETURN
   9380                 (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
   9381                                         NULL));
   9382         } else {
   9383             BCM_IF_ERROR_RETURN
   9384                 (_bcm_kt2_cosq_localport_resolve(unit, gport, &local_port));
   9385         }
   9386         if (IS_EXT_MEM_PORT(unit, local_port)) {
   9387             cell_size = _BCM_KT2_COSQ_EXT_CELLSIZE;
   9388             if (soc_feature(unit, soc_feature_mmu_packing)) {
   9389                 cell_size = _BCM_KT2_COSQ_EXT_PACKING_CELLSIZE;
   9390             }
   9391             cell_field_max = soc_kt2_get_max_buffer_size(unit, 1, cell_field_max);
   9392         } else {
   9393             cell_field_max = soc_kt2_get_max_buffer_size(unit, 0, cell_field_max);
   9394         }
   9395     }
   9396 
   9397     BCM_IF_ERROR_RETURN
   9398         (_bcm_kt2_cosq_wred_get(unit, gport, cosq == -1 ? 0 : cosq,
   9399                                &discard->flags, &min_thresh, &max_thresh,
   9400                                &discard->drop_probability, &discard->gain));
   9401 
   9402     /*
   9403      *  During cosq init we associated same wred profile for all (internal memory and
   9404      *  external memory) port. So need to cap get threshold for external memory port.
   9405      */
   9406     if (min_thresh > cell_field_max) {
   9407         min_thresh = cell_field_max;
   9408     }
   9409     if (max_thresh > cell_field_max) {
   9410         max_thresh = cell_field_max;
   9411     }
   9412     /* Convert number of cells to number of bytes */
   9413     if (discard->flags & BCM_COSQ_DISCARD_BYTES) {
   9414         discard->min_thresh = min_thresh * cell_size;
   9415         discard->max_thresh = max_thresh * cell_size;
   9416     } else {
   9417         discard->min_thresh = min_thresh;
   9418         discard->max_thresh = max_thresh;
   9419     }
   9420 
   9421     return BCM_E_NONE;
   9422 }
   9423 
   9424 /*
   9425  * Function:
   9426  *     bcm_kt2_cosq_discard_set
   9427  * Purpose:
   9428  *     Get port WRED setting
   9429  * Parameters:
   9430  *     unit    - (IN) unit number
   9431  *     flags   - (IN) flags
   9432  * Returns:
   9433  *     BCM_E_XXX
   9434  */
   9435 int
   9436 bcm_kt2_cosq_discard_set(int unit, uint32 flags)
   9437 {
   9438     bcm_port_t port;
   9439     bcm_cos_queue_t cosq;
   9440     int numq;
   9441 
   9442     if (flags & ~(BCM_COSQ_DISCARD_DEVICE |
   9443                   BCM_COSQ_DISCARD_NONTCP |
   9444                   BCM_COSQ_DISCARD_COLOR_ALL |
   9445                   BCM_COSQ_DISCARD_PACKETS |
   9446                   BCM_COSQ_DISCARD_CAP_AVERAGE |
   9447                   BCM_COSQ_DISCARD_ENABLE |
   9448                   BCM_COSQ_DISCARD_MARK_CONGESTION)) {
   9449         return BCM_E_PARAM;
   9450     }
   9451 
   9452     flags &= ~(BCM_COSQ_DISCARD_NONTCP | BCM_COSQ_DISCARD_COLOR_ALL);
   9453 
   9454     PBMP_PORT_ITER(unit, port) {
   9455         BCM_IF_ERROR_RETURN
   9456             (_bcm_kt2_cosq_index_resolve(unit, port, -1,
   9457                                         _BCM_KT2_COSQ_INDEX_STYLE_WRED, NULL,
   9458                                         NULL, &numq));
   9459         for (cosq = 0; cosq < numq; cosq++) {
   9460             BCM_IF_ERROR_RETURN
   9461                 (_bcm_kt2_cosq_wred_set(unit, port, cosq, flags, 0, 0, 0, 0,
   9462                                        FALSE));
   9463         }
   9464     }
   9465 
   9466     return BCM_E_NONE;
   9467 
   9468 }
   9469 
   9470 /*
   9471  * Function:
   9472  *     bcm_kt2_cosq_discard_get
   9473  * Purpose:
   9474  *     Get port WRED setting
   9475  * Parameters:
   9476  *     unit    - (IN) unit number
   9477  *     flags   - (OUT) flags
   9478  * Returns:
   9479  *     BCM_E_XXX
   9480  */
   9481 int
   9482 bcm_kt2_cosq_discard_get(int unit, uint32 *flags)
   9483 {
   9484     bcm_port_t port;
   9485 
   9486     PBMP_PORT_ITER(unit, port) {
   9487         *flags = 0;
   9488         /* use setting from hardware cosq index 0 of the first port */
   9489         return _bcm_kt2_cosq_wred_get(unit, port, 0, flags, NULL, NULL, NULL,
   9490                                      NULL);
   9491     }
   9492 
   9493     return BCM_E_NOT_FOUND;
   9494 
   9495 }
   9496 
   9497 /*
   9498  * Function:
   9499  *     bcm_kt2_cosq_discard_port_set
   9500  * Purpose:
   9501  *     Configure port WRED setting
   9502  * Parameters:
   9503  *     unit          - (IN) unit number
   9504  *     port          - (IN) port number or GPORT identifier
   9505  *     cosq          - (IN) COS queue number
   9506  *     color         - (IN)
   9507  *     drop_start    - (IN)
   9508  *     drop_slot     - (IN)
   9509  *     average_time  - (IN)
   9510  * Returns:
   9511  *     BCM_E_XXX
   9512  * Notes:
   9513  *     If port is any form of local port, cosq is the hardware queue index.
   9514  */
   9515 int
   9516 bcm_kt2_cosq_discard_port_set(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   9517                              uint32 color, int drop_start, int drop_slope,
   9518                              int average_time)
   9519 {
   9520     return SOC_E_UNAVAIL;
   9521 }
   9522 
   9523 /*
   9524  * Function:
   9525  *     bcm_kt2_cosq_discard_port_get
   9526  * Purpose:
   9527  *     Get port WRED setting
   9528  * Parameters:
   9529  *     unit          - (IN) unit number
   9530  *     port          - (IN) port number or GPORT identifier
   9531  *     cosq          - (IN) COS queue number
   9532  *     color         - (OUT)
   9533  *     drop_start    - (OUT)
   9534  *     drop_slot     - (OUT)
   9535  *     average_time  - (OUT)
   9536  * Returns:
   9537  *     BCM_E_XXX
   9538  * Notes:
   9539  *     If port is any form of local port, cosq is the hardware queue index.
   9540  */
   9541 int
   9542 bcm_kt2_cosq_discard_port_get(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
   9543                              uint32 color, int *drop_start, int *drop_slope,
   9544                              int *average_time)
   9545 {
   9546     return SOC_E_UNAVAIL;
   9547 
   9548 }
   9549 STATIC int
   9550 _bcm_kt2_cosq_current_stat_set_get(int unit,
   9551                                    bcm_gport_t gport,
   9552                                    bcm_cos_queue_t cosq,
   9553                                    bcm_cosq_stat_t stat,
   9554                                    int set,
   9555                                    uint64 *value)
   9556 {
   9557     bcm_port_t local_port;
   9558     uint32 entry[SOC_MAX_MEM_WORDS];
   9559     uint32 sw_val, hw_val;
   9560     soc_mem_t mem = INVALIDm;
   9561     soc_field_t field;
   9562     _bcm_kt2_cosq_node_t *node;
   9563     _bcm_kt2_mmu_info_t *mmu_info = _bcm_kt2_mmu_info[unit];
   9564     int startq, numq, cell_size = _BCM_KT2_COSQ_CELLSIZE;
   9565     int rv = BCM_E_NONE;
   9566 
   9567 
   9568     rv = _bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
   9569                                 &node);
   9570     if ((rv != BCM_E_NONE) && (rv != BCM_E_PORT)) {
   9571          return BCM_E_PARAM;
   9572     }
   9573     if (rv == BCM_E_PORT) {
   9574         if ((gport <= CMIC_PORT(unit)) || (gport >= LB_PORT(unit))) {
   9575             return BCM_E_PARAM;
   9576         } else {
   9577             local_port = gport;
   9578         }
   9579     }
   9580     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   9581         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
   9582         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
   9583         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   9584         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
   9585         BCM_GPORT_IS_SCHEDULER(gport)) {
   9586         if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) &&
   9587             (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2)) {
   9588             return BCM_E_PARAM;
   9589         }
   9590         if (BCM_GPORT_IS_SCHEDULER(gport)) {
   9591             BCM_IF_ERROR_RETURN(
   9592                 _bcm_kt2_cosq_child_node_at_input(node, cosq,
   9593                                               &node));
   9594         }
   9595 
   9596         startq = node->hw_index;
   9597     } else {
   9598         mmu_info = _bcm_kt2_mmu_info[unit];
   9599         numq = mmu_info->port[local_port].q_limit -
   9600                 mmu_info->port[local_port].q_offset;
   9601 
   9602         if (cosq < 0 || cosq >= numq) {
   9603             return BCM_E_PARAM;
   9604         }
   9605         startq = mmu_info->port[local_port].q_offset + cosq;
   9606     }
   9607 
   9608     if (IS_EXT_MEM_PORT(unit, local_port)) {
   9609         cell_size = _BCM_KT2_COSQ_EXT_CELLSIZE;
   9610         if (soc_feature(unit, soc_feature_mmu_packing)) {
   9611             cell_size = _BCM_KT2_COSQ_EXT_PACKING_CELLSIZE;
   9612         }
   9613     }
   9614 
   9615     switch (stat) {
   9616     case bcmCosqStatEgressUCQueueBytesCurrent:
   9617         mem = MMU_THDO_QCOUNT_CELLm;
   9618         field = TOTAL_COUNTf;
   9619         break;
   9620     default:
   9621         return BCM_E_PARAM;
   9622     }
   9623     BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   9624     if (set) {
   9625         COMPILER_64_TO_32_LO(sw_val, *value);
   9626         hw_val = (sw_val + cell_size - 1) / cell_size;
   9627         soc_mem_field32_set(unit, mem, entry, field, hw_val);
   9628         BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   9629     } else {
   9630         hw_val = soc_mem_field32_get(unit, mem, entry, field);
   9631         sw_val = hw_val * cell_size;
   9632         COMPILER_64_SET(*value, 0, sw_val);
   9633     }
   9634     return BCM_E_NONE;
   9635 }
   9636 
   9637 int
   9638 bcm_kt2_cosq_stat_set(int unit, bcm_gport_t port, bcm_cos_queue_t cosq,
   9639                      bcm_cosq_stat_t stat, uint64 value)
   9640 {
   9641     bcm_port_t local_port;
   9642     int startq, numq, i;
   9643     soc_counter_non_dma_id_t dma_id;
   9644     _bcm_kt2_cosq_node_t *node = NULL;
   9645     _bcm_kt2_cosq_node_t *child_node = NULL;
   9646     int first_child = 1; 
   9647     uint64  value64;
   9648     uint64  zero;
   9649 #ifdef BCM_SABER2_SUPPORT
   9650     uint32 drop_type, total_drop_mask, wred_drop_mask;
   9651     uint32 rval;
   9652 #endif
   9653 
   9654     if (stat == bcmCosqStatEgressUCQueueBytesCurrent) {
   9655         return _bcm_kt2_cosq_current_stat_set_get(unit, port,
   9656                                                   cosq, stat,
   9657                                                   1, &value);
   9658     }
   9659     BCM_IF_ERROR_RETURN
   9660         (_bcm_kt2_cosq_index_resolve
   9661         (unit, port, cosq, _BCM_KT2_COSQ_INDEX_STYLE_UCAST_QUEUE,
   9662          &local_port, &startq, &numq));
   9663     if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
   9664         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   9665         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) ||
   9666         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port)) {
   9667         /* pass port as queue number */
   9668         local_port = startq;
   9669         startq = 0;
   9670     }
   9671 
   9672 #ifdef BCM_SABER2_SUPPORT
   9673     if(SOC_IS_SABER2(unit)) {
   9674 #ifdef BCM_METROLITE_SUPPORT
   9675         if(SOC_IS_METROLITE(unit)) {
   9676            total_drop_mask = BCM_ML_COSQ_TOTAL_DROP_MASK;
   9677            wred_drop_mask = BCM_ML_COSQ_WRED_DROP_MASK;
   9678         } else 
   9679 #endif
   9680         {
   9681            total_drop_mask = BCM_SB2_COSQ_TOTAL_DROP_MASK;
   9682            wred_drop_mask = BCM_SB2_COSQ_WRED_DROP_MASK;
   9683         }  
   9684         SOC_IF_ERROR_RETURN(READ_THDO_DROP_CTR_CONFIGr(unit, &rval));
   9685         drop_type = soc_reg_field_get(unit, THDO_DROP_CTR_CONFIGr, rval, OP_DROP_MASKf); 
   9686 
   9687         if (drop_type == total_drop_mask) {
   9688             if (!((stat == bcmCosqStatDroppedPackets)||
   9689                   (stat == bcmCosqStatDroppedBytes)||
   9690                   (stat == bcmCosqStatRedCongestionDroppedPackets)||
   9691                   (stat == bcmCosqStatRedCongestionDroppedBytes)||
   9692                   (stat == bcmCosqStatYellowCongestionDroppedPackets)||
   9693                   (stat == bcmCosqStatYellowCongestionDroppedBytes)||
   9694                   (stat == bcmCosqStatOutPackets)||(stat == bcmCosqStatOutBytes))){
   9695                 return BCM_E_PARAM;
   9696             }
   9697 
   9698         }
   9699         else if (drop_type == wred_drop_mask) {
   9700             if (!((stat == bcmCosqStatDiscardDroppedPackets)||
   9701                   (stat == bcmCosqStatDiscardDroppedBytes)||
   9702                   (stat == bcmCosqStatRedDiscardDroppedPackets)||
   9703                   (stat == bcmCosqStatRedDiscardDroppedBytes)||
   9704                   (stat == bcmCosqStatYellowDiscardDroppedPackets)||
   9705                   (stat == bcmCosqStatYellowDiscardDroppedBytes)||
   9706                   (stat == bcmCosqStatGreenDiscardDroppedBytes)||
   9707                   (stat == bcmCosqStatGreenDiscardDroppedPackets)||
   9708                   (stat == bcmCosqStatOutPackets)||(stat == bcmCosqStatOutBytes))){
   9709                 return BCM_E_PARAM;
   9710             }
   9711         }
   9712     }
   9713 #endif
   9714 
   9715     switch (stat) {
   9716         case bcmCosqStatDroppedPackets:
   9717         case bcmCosqStatDiscardDroppedPackets:
   9718             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT;
   9719             break;
   9720 
   9721         case bcmCosqStatDroppedBytes:
   9722         case bcmCosqStatDiscardDroppedBytes:
   9723             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE;
   9724             break;
   9725 
   9726 
   9727         case bcmCosqStatRedCongestionDroppedPackets:
   9728         case bcmCosqStatRedDiscardDroppedPackets:
   9729             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED;
   9730             break;
   9731 
   9732         case bcmCosqStatRedCongestionDroppedBytes:
   9733         case bcmCosqStatRedDiscardDroppedBytes:
   9734             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_RED;
   9735             break;
   9736     
   9737         case bcmCosqStatYellowCongestionDroppedPackets:
   9738         case bcmCosqStatYellowDiscardDroppedPackets :
   9739             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW;
   9740             break;
   9741 
   9742         case bcmCosqStatYellowCongestionDroppedBytes:
   9743         case bcmCosqStatYellowDiscardDroppedBytes:
   9744             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_YELLOW;
   9745             break;
   9746 
   9747         case bcmCosqStatGreenDiscardDroppedPackets:
   9748             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN;
   9749             break;
   9750 
   9751         case bcmCosqStatGreenDiscardDroppedBytes:
   9752             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_GREEN;
   9753             break;
   9754  
   9755         case bcmCosqStatOutPackets:
   9756             dma_id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT;
   9757             break;
   9758         case bcmCosqStatOutBytes:
   9759             dma_id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE;
   9760             break;
   9761         default:
   9762             return BCM_E_PARAM;
   9763     }
   9764 
   9765     if (!BCM_GPORT_IS_SCHEDULER(port)) {  
   9766         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(port) ||
   9767             BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   9768             BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
   9769             BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   9770             BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) ||
   9771             (cosq != BCM_COS_INVALID)) {
   9772             BCM_IF_ERROR_RETURN
   9773                 (soc_counter_set(unit, local_port, dma_id, startq, value));
   9774         } else {
   9775             numq = soc_property_get(unit, spn_BCM_NUM_COS, BCM_COS_DEFAULT);
   9776             if (numq < 1) {
   9777                 numq = 1;
   9778             } else if (numq > 8) {
   9779                 numq = 8;
   9780             }
   9781             for (i = 0; i < numq; i++) {
   9782                 COMPILER_64_ZERO(zero);
   9783                 BCM_IF_ERROR_RETURN
   9784                     (soc_counter_set(unit, local_port, dma_id, i, i == 0 ? value : zero ));
   9785             }
   9786         }
   9787     } else {
   9788          
   9789       BCM_IF_ERROR_RETURN
   9790        (_bcm_kt2_cosq_node_get(unit, port, 0, 
   9791                   &local_port, NULL, &node));
   9792        if (cosq == -1) {  
   9793             for (i = 0; i < node->numq; i++) {
   9794                  if ((_bcm_kt2_cosq_child_node_at_input(node, i, &child_node))
   9795                                                         == BCM_E_NOT_FOUND) {
   9796                        continue;
   9797                  }
   9798                               
   9799                  port = child_node->gport;
   9800                          
   9801                  BCM_IF_ERROR_RETURN
   9802                  (_bcm_kt2_cosq_index_resolve
   9803                  (unit, port, 0, _BCM_KT2_COSQ_INDEX_STYLE_UCAST_QUEUE,
   9804                   &local_port, &startq, &numq));
   9805 
   9806                  if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   9807                      BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   9808                      BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port)) {
   9809                     /* pass port as queue number */
   9810                     local_port = startq;
   9811                     startq = 0;
   9812                  }
   9813                  if(first_child) { 
   9814                    /*
   9815                     *According to api guide only first child should be set with given value
   9816                     *all other are set to 0
   9817                     */ 
   9818                     BCM_IF_ERROR_RETURN
   9819                     (soc_counter_set(unit, local_port, dma_id,
   9820                                startq , value));
   9821                      first_child = 0; 
   9822                 }
   9823                 else { 
   9824                     COMPILER_64_ZERO(value64);
   9825                     BCM_IF_ERROR_RETURN
   9826                     (soc_counter_set(unit, local_port, dma_id,
   9827                                startq , value64));
   9828                 }
   9829            }
   9830        } 
   9831        else {  
   9832 
   9833             if ((_bcm_kt2_cosq_child_node_at_input(node, cosq, &child_node))
   9834                                                      == BCM_E_NOT_FOUND) {
   9835                  return BCM_E_NOT_FOUND; 
   9836             }
   9837                              
   9838             port = child_node->gport;
   9839                        
   9840             BCM_IF_ERROR_RETURN
   9841             (_bcm_kt2_cosq_index_resolve
   9842               (unit, port, 0, _BCM_KT2_COSQ_INDEX_STYLE_UCAST_QUEUE,
   9843                &local_port, &startq, &numq));
   9844 
   9845             if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   9846                 BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
   9847                 BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port)) {
   9848                     /* pass port as queue number */
   9849                     local_port = startq;
   9850                     startq = 0;
   9851             }
   9852             BCM_IF_ERROR_RETURN
   9853             (soc_counter_set(unit, local_port, dma_id,
   9854              startq , value));
   9855        }
   9856     }
   9857 
   9858 
   9859     return BCM_E_NONE;
   9860 }
   9861 
   9862 int
   9863 _bcm_kt2_cosq_pfc_class_resolve(bcm_switch_control_t sctype, int *type,
   9864                                int *class)
   9865 {
   9866     switch (sctype) {
   9867     case bcmSwitchPFCClass7Queue:
   9868     case bcmSwitchPFCClass6Queue:
   9869     case bcmSwitchPFCClass5Queue:
   9870     case bcmSwitchPFCClass4Queue:
   9871     case bcmSwitchPFCClass3Queue:
   9872     case bcmSwitchPFCClass2Queue:
   9873     case bcmSwitchPFCClass1Queue:
   9874     case bcmSwitchPFCClass0Queue:
   9875         *type = _BCM_KT2_NODE_UCAST;
   9876         break;
   9877     case bcmSwitchPFCClass7McastQueue:
   9878     case bcmSwitchPFCClass6McastQueue:
   9879     case bcmSwitchPFCClass5McastQueue:
   9880     case bcmSwitchPFCClass4McastQueue:
   9881     case bcmSwitchPFCClass3McastQueue:
   9882     case bcmSwitchPFCClass2McastQueue:
   9883     case bcmSwitchPFCClass1McastQueue:
   9884     case bcmSwitchPFCClass0McastQueue:
   9885         *type = _BCM_KT2_NODE_MCAST;
   9886         break;
   9887 /*    case bcmSwitchPFCClass7DestmodQueue:
   9888     case bcmSwitchPFCClass6DestmodQueue:
   9889     case bcmSwitchPFCClass5DestmodQueue:
   9890     case bcmSwitchPFCClass4DestmodQueue:
   9891     case bcmSwitchPFCClass3DestmodQueue:
   9892     case bcmSwitchPFCClass2DestmodQueue:
   9893     case bcmSwitchPFCClass1DestmodQueue:
   9894     case bcmSwitchPFCClass0DestmodQueue:
   9895         *type = _BCM_KT2_COSQ_TYPE_EXT_UCAST;
   9896         break;
   9897 */
   9898     default:
   9899         return BCM_E_PARAM;
   9900     }
   9901 
   9902     switch (sctype) {
   9903     case bcmSwitchPFCClass7Queue:
   9904     case bcmSwitchPFCClass7McastQueue:
   9905     case bcmSwitchPFCClass7DestmodQueue:
   9906         *class = 7;
   9907         break;
   9908     case bcmSwitchPFCClass6Queue:
   9909     case bcmSwitchPFCClass6McastQueue:
   9910     case bcmSwitchPFCClass6DestmodQueue:
   9911         *class = 6;
   9912         break;
   9913     case bcmSwitchPFCClass5Queue:
   9914     case bcmSwitchPFCClass5McastQueue:
   9915     case bcmSwitchPFCClass5DestmodQueue:
   9916         *class = 5;
   9917         break;
   9918     case bcmSwitchPFCClass4Queue:
   9919     case bcmSwitchPFCClass4McastQueue:
   9920     case bcmSwitchPFCClass4DestmodQueue:
   9921         *class = 4;
   9922         break;
   9923     case bcmSwitchPFCClass3Queue:
   9924     case bcmSwitchPFCClass3McastQueue:
   9925     case bcmSwitchPFCClass3DestmodQueue:
   9926         *class = 3;
   9927         break;
   9928     case bcmSwitchPFCClass2Queue:
   9929     case bcmSwitchPFCClass2McastQueue:
   9930     case bcmSwitchPFCClass2DestmodQueue:
   9931         *class = 2;
   9932         break;
   9933     case bcmSwitchPFCClass1Queue:
   9934     case bcmSwitchPFCClass1McastQueue:
   9935     case bcmSwitchPFCClass1DestmodQueue:
   9936         *class = 1;
   9937         break;
   9938     case bcmSwitchPFCClass0Queue:
   9939     case bcmSwitchPFCClass0McastQueue:
   9940     case bcmSwitchPFCClass0DestmodQueue:
   9941         *class = 0;
   9942         break;
   9943     /*
   9944      * COVERITY
   9945      *
   9946      * This default is unreachable but needed for some compiler. 
   9947      */ 
   9948     /* coverity[dead_error_begin] */
   9949     default:
   9950         return BCM_E_INTERNAL;
   9951     }
   9952     return BCM_E_NONE;
   9953 }
   9954 #ifdef BCM_SABER2_SUPPORT
   9955 /*
   9956  * Function:
   9957  *    _bcm_kt2_port_pfc_supported
   9958  * Purpose:
   9959  *     To check if given port support 8 PGs or not.
   9960  * Parameters:
   9961  *     unit       - (IN) unit number
   9962  *     port       - (IN) port number
   9963  * Returns:
   9964  *     1 if port support 8 PGs else 0
   9965  */
   9966 STATIC int
   9967 _bcm_kt2_port_pfc_supported(int unit, bcm_port_t local_port)
   9968 {
   9969 
   9970 #ifdef BCM_METROLITE_SUPPORT
   9971     if(SOC_IS_METROLITE(unit) && (local_port < ML_MAX_LOGICAL_PORTS))  {
   9972        return ml_pfc_support[local_port].supported ;
   9973     } else
   9974 #endif
   9975     if(SOC_IS_SABER2(unit) && (local_port < SB2_MAX_LOGICAL_PORTS))  {
   9976        return sb2_pfc_support[local_port].supported ;
   9977     }
   9978     return BCM_E_NONE;
   9979 }
   9980 STATIC int
   9981 bcm_kt2_pg_profile_refcount_init(int unit)
   9982 {
   9983     uint64 rval64;
   9984     int    i;
   9985     uint32 low, high, temp;
   9986 
   9987     pg_profile_refcount[unit][0] = 0;
   9988     pg_profile_refcount[unit][1] = 0;
   9989     pg_profile_refcount[unit][2] = 0;
   9990     pg_profile_refcount[unit][3] = 0;
   9991     if(SOC_IS_SABER2(unit))  {
   9992        SOC_IF_ERROR_RETURN(
   9993            READ_MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r(unit, &rval64));
   9994        low = COMPILER_64_LO(rval64);
   9995        high = COMPILER_64_HI(rval64);
   9996        for(i = 0; i < 40; i = i + 2) {
   9997            if (i < 32) {
   9998                temp = 0x3 & (low >> i);
   9999            } else {
  10000                temp = 0x3 & (high >> (i -32));
  10001            }
  10002            pg_profile_refcount[unit][temp] = pg_profile_refcount[unit][temp] + 1;
  10003        }
  10004     }
  10005     return BCM_E_NONE;
  10006 }
  10007 #endif
  10008 
  10009 /*
  10010  * Function:
  10011  *     _bcm_kt2_fc_status_map_gport
  10012  * Purpose:
  10013  *     Set mapping in FC_MAP_TBL for gport, and update cos_bmp with gport cosq.
  10014  * Parameters:
  10015  *     unit       - (IN) unit number
  10016  *     port       - (IN) port number
  10017  *     gport      - (IN) gport to be mapped
  10018  *     fct        - (IN) FC type 
  10019  *     cos_map    - (OUT) hw_cosq of gport
  10020  * Returns:
  10021  *     BCM_E_XXX
  10022  */
  10023 STATIC int
  10024 _bcm_kt2_fc_status_map_gport(int unit, int port, 
  10025                 bcm_gport_t gport, _bcm_kt2_fc_type_t fct, 
  10026                 uint32 *cos_bmp)
  10027 {
  10028     int hw_index, hw_index1;
  10029     int base_index = 0;
  10030     int hw_cosq, hw_cosq1;
  10031     int id, lvl;
  10032     bcm_port_t local_port, resolved_port;
  10033     _bcm_kt2_cosq_node_t *node;
  10034     _bcm_kt2_cosq_port_info_t *port_info;
  10035     _bcm_kt2_mmu_info_t *mmu_info;
  10036     int supported = 0 ;
  10037 
  10038     
  10039     BCM_IF_ERROR_RETURN
  10040         (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
  10041 #ifdef BCM_METROLITE_SUPPORT
  10042     if(SOC_IS_METROLITE(unit))  {
  10043        supported = ml_pfc_support[local_port].supported ;
  10044     } else
  10045 #endif
  10046 #ifdef BCM_SABER2_SUPPORT
  10047     if(SOC_IS_SABER2(unit))  {
  10048        supported = sb2_pfc_support[local_port].supported ; 
  10049     } else 
  10050 #endif 
  10051     {
  10052        supported = kt2_pfc_support[local_port].supported ; 
  10053     }
  10054     if (!supported) { 
  10055         return BCM_E_PARAM;  
  10056     }
  10057     mmu_info = _bcm_kt2_mmu_info[unit];
  10058     port_info = &mmu_info->port[local_port];
  10059     
  10060     hw_index = hw_index1 = -1;
  10061     hw_cosq = hw_cosq1 = -1;
  10062     if (BCM_GPORT_IS_SET(gport)) {
  10063         BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_node_get(unit, gport, 
  10064                             0,  &resolved_port, &id, &node));
  10065     /* hardware supports pfc at l0 and l1 level but  the index needs to be 
  10066      * assigned in multiple of 8 for pfc to work.Since we are not doing it 
  10067      * returning E_PARAM for scheduler node as of now can be corrected if 
  10068      * index allocation is changed .Rest of the code programmed to handle
  10069      * schedulers  
  10070      */ 
  10071         if (!(BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  10072             BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)||
  10073             BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)
  10074             )) {
  10075             return BCM_E_PARAM; 
  10076         }
  10077         hw_index = node->hw_index;
  10078         if (!IS_HG_PORT(unit,local_port)) {
  10079             hw_cosq =  node->hw_index % NUM_COS(unit);
  10080         }
  10081         else { 
  10082                 hw_cosq =  node->hw_index - port_info->q_offset ;
  10083         }
  10084 
  10085         lvl = node->level;
  10086     } else {
  10087             hw_cosq = gport;
  10088             node = &mmu_info->queue_node[port_info->q_offset + hw_cosq];
  10089             if ((node->cosq_attached_to == -1)) {
  10090                 return BCM_E_PARAM;
  10091             }
  10092             hw_index = node->hw_index;
  10093         if (soc_feature(unit, soc_feature_mmu_packing)) {
  10094             node = &mmu_info->queue_node[port_info->mcq_offset + hw_cosq];
  10095             if (!(node->cosq_attached_to == -1)) {
  10096                 hw_index1 = node->hw_index;
  10097                 hw_cosq1 = hw_cosq ;
  10098             }
  10099         }
  10100         lvl = _BCM_KT2_COSQ_NODE_LEVEL_L2;
  10101     }
  10102     if ((hw_cosq < 0) || (hw_cosq >= _BCM_KT2_NUM_INTERNAL_PRI)) {
  10103         return BCM_E_PARAM;
  10104     }
  10105 #ifdef BCM_METROLITE_SUPPORT
  10106     if(SOC_IS_METROLITE(unit))  {
  10107        base_index = ml_pfc_support[local_port].index1 + hw_cosq / 8 ;
  10108     } else
  10109 #endif
  10110 #ifdef BCM_SABER2_SUPPORT
  10111     if(SOC_IS_SABER2(unit))  {
  10112        base_index = sb2_pfc_support[local_port].index1 + hw_cosq / 8 ; 
  10113     } else 
  10114 #endif 
  10115     {
  10116        base_index = kt2_pfc_support[local_port].index1 + hw_cosq / 8 ; 
  10117     }
  10118     BCM_IF_ERROR_RETURN(
  10119          _bcm_kt2_cosq_map_fc_status_to_node(unit, fct,
  10120                                         hw_index, lvl - 2, base_index ));
  10121     if (cos_bmp != NULL) {
  10122         *cos_bmp |= 1 << hw_cosq;
  10123     }
  10124     if (hw_cosq1 >= 0) {
  10125         BCM_IF_ERROR_RETURN(
  10126             _bcm_kt2_cosq_map_fc_status_to_node(unit, fct,
  10127                                            hw_index1, lvl - 2, base_index));
  10128         if (cos_bmp != NULL) {
  10129             *cos_bmp |= 1 << hw_cosq1;
  10130         }
  10131     }
  10132 
  10133     return BCM_E_NONE;
  10134 }
  10135 
  10136 /*
  10137  * Function:
  10138  *     _bcm_kt2_port_pfc_profile_set
  10139  * Purpose:
  10140  *     Set PFC mapping profile for port. Updates PRIO2COS_PROFILE & PORT_PFC_CFG.
  10141  * Parameters:
  10142  *     unit       - (IN) unit number
  10143  *     port       - (IN) port number
  10144  *     op         - (IN) operation type
  10145  *     entry_cnt  - (IN) count of bmp 
  10146  *     pfc_class  - (IN) class list
  10147  *     cos_bmp    - (IN) bmp list
  10148  * Returns:
  10149  *     BCM_E_XXX
  10150  */
  10151 STATIC int
  10152 _bcm_kt2_port_pfc_profile_set(int unit, int port, _bcm_cosq_op_t op,
  10153                               int entry_cnt, int *pfc_class, uint32 *cos_bmp)
  10154 {
  10155     soc_reg_t   reg;
  10156     bcm_port_t local_port;
  10157     int rv, entry, cur_class;
  10158     int mmu_port;
  10159     uint32 profile_index, old_profile_index;
  10160     uint32 fval, tmp32, cur_bmp;
  10161     uint64 rval64[16], tmp, *rval64s[1], rval, index_map;
  10162 #ifdef BCM_METROLITE_SUPPORT
  10163     uint32 rval32, index_map32;
  10164 #endif
  10165     if (pfc_class == NULL) {
  10166         return BCM_E_PARAM;
  10167     }
  10168     if (cos_bmp == NULL) {
  10169         return BCM_E_PARAM;
  10170     }
  10171     if ((entry_cnt < 0 ) ) {
  10172         return BCM_E_PARAM;
  10173     }
  10174     
  10175     BCM_IF_ERROR_RETURN(
  10176         _bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
  10177 #ifdef BCM_METROLITE_SUPPORT
  10178     if(SOC_IS_METROLITE(unit)) {
  10179        mmu_port = ml_pfc_support[local_port].mmu_port;
  10180     } else
  10181 #endif
  10182 #ifdef BCM_SABER2_SUPPORT 
  10183     if(SOC_IS_SABER2(unit)) { 
  10184        mmu_port = sb2_pfc_support[local_port].mmu_port;
  10185     } else 
  10186 #endif 
  10187    {
  10188        mmu_port = kt2_pfc_support[local_port].mmu_port;
  10189    }
  10190    if (mmu_port == -1) { 
  10191        return BCM_E_PARAM;
  10192    } 
  10193     reg = PORT_PFC_CFG0r;
  10194     rval64s[0] = rval64;
  10195 #ifdef BCM_METROLITE_SUPPORT
  10196     if(SOC_IS_METROLITE(unit)) {
  10197        BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval32));
  10198        index_map32 = soc_reg_field_get(unit, reg, rval32, PROFILE_INDEXf);
  10199        index_map32 = index_map32 >> (mmu_port * 2);
  10200        old_profile_index = (index_map32 & 3) * 16;
  10201     } else
  10202 #endif
  10203     { 
  10204     BCM_IF_ERROR_RETURN(soc_reg64_get(unit, reg, 0, 0, &rval));
  10205     
  10206     index_map = soc_reg64_field_get(unit, reg, rval, PROFILE_INDEXf);
  10207     COMPILER_64_SHR(index_map, ((mmu_port % 32) * 2));
  10208     COMPILER_64_TO_32_LO(tmp32, index_map);
  10209     old_profile_index = (tmp32 & 3)*16;
  10210     }
  10211     BCM_IF_ERROR_RETURN
  10212         (soc_profile_reg_get(unit, _bcm_kt2_llfc_profile[unit],
  10213                              old_profile_index, 16, rval64s));
  10214 
  10215     for (entry = 0; entry < entry_cnt; entry++) {
  10216         cur_class = pfc_class[entry];
  10217         cur_bmp = cos_bmp[entry];
  10218         if (op == _BCM_COSQ_OP_SET) {
  10219             soc_reg64_field32_set(unit, PRIO2COS_PROFILEr, &rval64[cur_class],
  10220                                   COS_BMPf, cur_bmp);
  10221         } else {
  10222             if (cur_bmp != 0) {
  10223                 fval = soc_reg64_field32_get(unit, PRIO2COS_PROFILEr,
  10224                                              rval64[cur_class], COS_BMPf);
  10225                 if (op == _BCM_COSQ_OP_ADD) {
  10226                     fval |= cur_bmp;
  10227                 } else { /* _BCM_COSQ_OP_DELETE */
  10228                     fval &= ~cur_bmp;
  10229                 }
  10230                 soc_reg64_field32_set(unit, PRIO2COS_PROFILEr,
  10231                                       &rval64[cur_class], COS_BMPf, fval);
  10232             }
  10233         }
  10234     }
  10235     
  10236     BCM_IF_ERROR_RETURN
  10237         (soc_profile_reg_delete(unit, _bcm_kt2_llfc_profile[unit],
  10238                                 old_profile_index));
  10239 
  10240     rv = soc_profile_reg_add(unit, _bcm_kt2_llfc_profile[unit], rval64s,
  10241                              16, &profile_index);
  10242     if (SOC_FAILURE(rv)) {
  10243         BCM_IF_ERROR_RETURN
  10244             (soc_profile_reg_reference(unit, _bcm_kt2_llfc_profile[unit],
  10245                                        old_profile_index, 16));
  10246         return rv;
  10247     }
  10248 
  10249 #ifdef BCM_METROLITE_SUPPORT
  10250     if(SOC_IS_METROLITE(unit)) {
  10251        index_map32 = soc_reg_field_get(unit, reg, rval32, PROFILE_INDEXf);
  10252        tmp32 = 3 << (mmu_port * 2);
  10253        tmp32 = ~tmp32;
  10254        index_map32 = index_map32 & tmp32;
  10255        tmp32 = (profile_index / 16) << (mmu_port * 2);
  10256        index_map32 = index_map32 | tmp32;
  10257        soc_reg_field_set(unit, reg, &rval32, PROFILE_INDEXf,
  10258                         index_map32);
  10259        BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, 0, 0, rval32));
  10260     } else
  10261 #endif
  10262     {
  10263     index_map = soc_reg64_field_get(unit, reg, rval, PROFILE_INDEXf);
  10264 
  10265     COMPILER_64_SET(tmp, 0, 3);
  10266     COMPILER_64_SHL(tmp, (mmu_port % 32) * 2);
  10267     COMPILER_64_NOT(tmp);
  10268     COMPILER_64_AND(index_map, tmp);
  10269     COMPILER_64_SET(tmp, 0, profile_index/16);
  10270     COMPILER_64_SHL(tmp, (mmu_port % 32) * 2);
  10271     COMPILER_64_OR(index_map, tmp);
  10272     
  10273     soc_reg64_field_set(unit, reg, &rval, PROFILE_INDEXf,
  10274                         index_map);
  10275 
  10276     BCM_IF_ERROR_RETURN(soc_reg64_set(unit, reg, 0, 0, rval));
  10277     }
  10278     return BCM_E_NONE;
  10279 }
  10280 
  10281 int
  10282 bcm_kt2_cosq_port_pfc_op(int unit, bcm_port_t port,
  10283                          bcm_switch_control_t sctype, _bcm_cosq_op_t op,
  10284                          bcm_gport_t *gport, int gport_count)
  10285 {
  10286     int type, class = -1, index;
  10287     uint32 cos_bmp;
  10288     _bcm_kt2_fc_type_t fct;
  10289 
  10290     if (gport_count < 0) {
  10291         return BCM_E_PARAM;
  10292     }
  10293     if (!SOC_IS_SABER2(unit) && !IS_XE_PORT(unit,port)) {
  10294         return BCM_E_PARAM; 
  10295     }
  10296     BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_pfc_class_resolve(sctype, &type, &class));
  10297 
  10298     cos_bmp = 0;
  10299     fct = (op == _BCM_COSQ_OP_CLEAR)? 0 : _BCM_KT2_COSQ_FC_PFC;
  10300     for (index = 0; index < gport_count; index++) {
  10301         BCM_IF_ERROR_RETURN(
  10302             _bcm_kt2_fc_status_map_gport(unit, port, gport[index],
  10303                                          fct, &cos_bmp));
  10304     }
  10305 
  10306     if (op == _BCM_COSQ_OP_CLEAR) {
  10307         cos_bmp = (1 << _BCM_KT2_NUM_INTERNAL_PRI) - 1;
  10308     }
  10309 
  10310     BCM_IF_ERROR_RETURN(_bcm_kt2_port_pfc_profile_set(unit, port, op,
  10311                                                       1, &class, &cos_bmp));
  10312     
  10313     return BCM_E_NONE;
  10314 }
  10315 
  10316 int
  10317 bcm_kt2_cosq_port_pfc_get(int unit, bcm_port_t port,
  10318                          bcm_switch_control_t sctype,
  10319                          bcm_gport_t *gport, int gport_count,
  10320                          int *actual_gport_count)
  10321 {
  10322     _bcm_kt2_cosq_node_t *node;
  10323     bcm_port_t local_port;
  10324     int type = -1, class = -1, hw_cosq, count = 0;
  10325     uint32 profile_index;
  10326     uint64 rval64[16], *rval64s[1], rval, index_map;
  10327     uint32 tmp32, bmp;
  10328     _bcm_kt2_mmu_info_t *mmu_info;
  10329     int  mmu_port;
  10330     soc_reg_t   reg;
  10331     int node_port = 0 ;
  10332     _bcm_kt2_cosq_port_info_t *port_info;
  10333     static const soc_field_t self[] = {
  10334         SEL0f, SEL1f, 
  10335     };
  10336     int j, hw_index, eindex;
  10337     soc_mem_t mem;
  10338     uint32 map_entry[SOC_MAX_MEM_WORDS];
  10339 #ifdef BCM_METROLITE_SUPPORT
  10340     uint32 rval32, index_map32;
  10341 #endif
  10342     if (IS_CPU_PORT(unit, port)) {
  10343         return BCM_E_PORT;
  10344     }
  10345 
  10346     if ((gport == NULL) && (gport_count > 0)) {
  10347         return BCM_E_PARAM;
  10348     }
  10349     
  10350     if (actual_gport_count == NULL) {
  10351         return BCM_E_PARAM;
  10352     }
  10353 
  10354     BCM_IF_ERROR_RETURN
  10355         (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
  10356 
  10357     BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_pfc_class_resolve(sctype, &type, &class));
  10358 
  10359     mmu_info = _bcm_kt2_mmu_info[unit];
  10360 #ifdef BCM_METROLITE_SUPPORT
  10361     if(SOC_IS_METROLITE(unit)) {
  10362        mmu_port = ml_pfc_support[local_port].mmu_port;
  10363     } else
  10364 #endif
  10365 #ifdef BCM_SABER2_SUPPORT 
  10366     if(SOC_IS_SABER2(unit)) { 
  10367        mmu_port = sb2_pfc_support[local_port].mmu_port;
  10368     } else 
  10369 #endif 
  10370    {
  10371     mmu_port = kt2_pfc_support[local_port].mmu_port;
  10372    }
  10373     if (mmu_port == -1) { 
  10374         return BCM_E_PARAM; 
  10375     }
  10376     port_info = &mmu_info->port[local_port];
  10377 
  10378     rval64s[0] = rval64;
  10379     reg = PORT_PFC_CFG0r;
  10380 #ifdef BCM_METROLITE_SUPPORT
  10381     if(SOC_IS_METROLITE(unit)) {
  10382        BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval32));
  10383        index_map32 = soc_reg_field_get(unit, reg, rval32, PROFILE_INDEXf); 
  10384        index_map32 = index_map32 >> (mmu_port * 2);
  10385        profile_index = (index_map32 & 3) * 16;
  10386     } else
  10387 #endif
  10388     {
  10389     BCM_IF_ERROR_RETURN(soc_reg64_get(unit, reg, REG_PORT_ANY, 0, &rval));
  10390 
  10391     index_map = soc_reg64_field_get(unit, reg, rval, PROFILE_INDEXf);
  10392     COMPILER_64_SHR(index_map, ((mmu_port % 32) * 2));
  10393     COMPILER_64_TO_32_LO(tmp32, index_map);
  10394     profile_index = (tmp32 & 3)*16;
  10395     }
  10396     BCM_IF_ERROR_RETURN
  10397         (soc_profile_reg_get(unit, _bcm_kt2_llfc_profile[unit],
  10398                              profile_index, 16, rval64s));
  10399 
  10400     bmp = soc_reg64_field32_get(unit, PRIO2COS_PROFILEr, rval64[class],
  10401                                 COS_BMPf);
  10402      
  10403     for (hw_cosq = 0; hw_cosq < 8; hw_cosq++) {
  10404         if (!(bmp & (1 << hw_cosq))) {
  10405             continue;
  10406         }
  10407             for (j = num_pp_ports[unit] ;
  10408                  j < num_total_schedulers[unit]; j++) {
  10409                 node = &mmu_info->sched_node[j];
  10410                 if (node->cosq_attached_to == -1) { 
  10411                     continue ;
  10412                 } 
  10413                 BCM_IF_ERROR_RETURN
  10414                   (_bcm_kt2_cosq_node_get(unit, node->gport, NULL 
  10415                      ,&node_port, NULL, NULL));
  10416                 if ( (node_port != local_port) ||
  10417                     ((node->hw_index % NUM_COS(unit)) != hw_cosq)) {
  10418                     continue;
  10419                 }
  10420 
  10421                 hw_index = (node->hw_index / 16);
  10422                 eindex = (node->hw_index % 16)/8;
  10423                 if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L0) {
  10424                     mem = MMU_INTFI_FC_MAP_TBL0m ; 
  10425                 } else if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L1) {
  10426                     mem = MMU_INTFI_FC_MAP_TBL1m; 
  10427                 } else {
  10428                     continue;
  10429                 }
  10430 
  10431                 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, 
  10432                         MEM_BLOCK_ALL, hw_index, &map_entry));
  10433 
  10434                 if (soc_mem_field32_get(unit, mem, &map_entry, self[eindex])) {
  10435                     if (gport_count > 0 && count < gport_count) {
  10436                         gport[count] = node->gport;
  10437                     }
  10438                     count++;
  10439                     break;
  10440                 }
  10441             }
  10442             for (j = port_info->q_offset; 
  10443                  (j < port_info->q_limit); j++) {
  10444                 node = &mmu_info->queue_node[j];
  10445                 if (node->cosq_attached_to == -1) { 
  10446                     continue ;
  10447                 } 
  10448                 BCM_IF_ERROR_RETURN
  10449                   (_bcm_kt2_cosq_node_get(unit, node->gport, NULL ,&node_port, 
  10450                                NULL, NULL));
  10451                 if ((node_port != local_port)) {
  10452                     continue;
  10453                 }
  10454                 if ((node->hw_index % NUM_COS(unit)) != hw_cosq) {
  10455                     continue;
  10456                 }
  10457                 mem = MMU_INTFI_FC_MAP_TBL2m ;
  10458                 hw_index = (node->hw_index / 16);
  10459                 eindex = (node->hw_index % 16) / 8; 
  10460 
  10461                 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, 
  10462                         MEM_BLOCK_ALL, hw_index, &map_entry));
  10463 
  10464                 if (soc_mem_field32_get(unit, mem, &map_entry, self[eindex])) {
  10465                       
  10466                     if (gport_count > 0 && count < gport_count) {
  10467                          
  10468                         gport[count] = node->gport;
  10469                     }
  10470                     count++;
  10471                     break;
  10472                 }
  10473             }
  10474             if(soc_feature(unit, soc_feature_mmu_packing)) {   
  10475                for (j = port_info->mcq_offset; 
  10476                     (j < port_info->mcq_limit); j++) {
  10477                     node = &mmu_info->queue_node[j];
  10478                     if (node->cosq_attached_to == -1) { 
  10479                         continue ;
  10480                     } 
  10481                     BCM_IF_ERROR_RETURN
  10482                      (_bcm_kt2_cosq_node_get(unit, node->gport, NULL ,&node_port, 
  10483                                    NULL, NULL));
  10484                     if ((node_port != local_port)) {
  10485                         continue;
  10486                     }
  10487                     if ((node->hw_index % NUM_COS(unit)) != hw_cosq) {
  10488                         continue;
  10489                     }
  10490                     mem = MMU_INTFI_FC_MAP_TBL2m ;
  10491                     hw_index = (node->hw_index / 16);
  10492                     eindex = (node->hw_index % 16) / 8; 
  10493 
  10494                     BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, 
  10495                             MEM_BLOCK_ALL, hw_index, &map_entry));
  10496 
  10497                     if (soc_mem_field32_get(unit, mem, &map_entry, self[eindex])) {
  10498                         if (gport_count > 0 && count < gport_count ) {
  10499                             gport[count] = node->gport;
  10500                     }
  10501                     count++;
  10502                     break;
  10503                     }
  10504                }
  10505             }
  10506             if (mmu_info->num_sub_queues) {
  10507                 for (j=mmu_info->base_sub_queue; 
  10508                         j < (mmu_info->base_sub_queue+mmu_info->num_sub_queues); j++) {
  10509 
  10510                     node = &mmu_info->queue_node[j];
  10511                     if (node->cosq_attached_to == -1) {
  10512                         continue;
  10513                     }
  10514                     BCM_IF_ERROR_RETURN
  10515                         (_bcm_kt2_cosq_node_get(unit, node->gport, NULL ,&node_port,
  10516                                                 NULL, NULL));
  10517                     if (node_port != local_port) {
  10518                         continue;
  10519                     }
  10520                     if ((node->hw_index % NUM_COS(unit)) != hw_cosq) {
  10521                         continue;
  10522                     }
  10523                     mem = MMU_INTFI_FC_MAP_TBL2m ;
  10524                     hw_index = (node->hw_index / 16);
  10525                     eindex = (node->hw_index % 16) / 8;  
  10526 
  10527                     BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem,  
  10528                                 MEM_BLOCK_ALL, hw_index, &map_entry));
  10529 
  10530                     if (soc_mem_field32_get(unit, mem, &map_entry, self[eindex])) {
  10531                         if (gport_count > 0 && count < gport_count ) {
  10532                             gport[count] = node->gport;
  10533                         }
  10534                         count++;
  10535                         break;
  10536                     }
  10537 
  10538 
  10539                 } 
  10540 
  10541             }  
  10542             if ((count == gport_count) && (gport_count > 0)) {
  10543                  break;
  10544             }
  10545     }
  10546 
  10547     if (count == 0) {
  10548         return BCM_E_NOT_FOUND;
  10549     }
  10550     *actual_gport_count = count;
  10551     return BCM_E_NONE;
  10552 }
  10553 
  10554 /*
  10555  * Function:
  10556  *     bcm_kt2_cosq_pfc_class_mapping_set
  10557  * Purpose:
  10558  *     Set PFC mapping for port. PFC class is mapped to cosq or scheduler node gports.
  10559  * Parameters:
  10560  *     unit             - (IN) unit number
  10561  *     port             - (IN) port number
  10562  *     array_count      - (IN) count of mapping
  10563  *     mapping_array    - (IN) mappings 
  10564  * Returns:
  10565  *     BCM_E_XXX
  10566  */
  10567 int
  10568 bcm_kt2_cosq_safc_class_mapping_set(int unit,
  10569     bcm_gport_t port,
  10570     int array_count,
  10571     bcm_cosq_safc_class_mapping_t *mapping_array)
  10572 {
  10573     int index, count;
  10574     int cur_class = 0, pfc_class[_BCM_KT2_NUM_SAFC_CLASS];
  10575     bcm_gport_t cur_gport = 0;
  10576     int local_port = 0;
  10577     uint32 cos_bmp[_BCM_KT2_NUM_SAFC_CLASS];
  10578 
  10579     BCM_IF_ERROR_RETURN
  10580         (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
  10581     /*safc is supported only on higig interfaces */ 
  10582     if (!IS_HG_PORT(unit, local_port)) {
  10583          return BCM_E_PARAM;  
  10584     }
  10585     if ((array_count < 0) || (array_count > _BCM_KT2_NUM_SAFC_CLASS)) {
  10586         return BCM_E_PARAM;
  10587     }
  10588     if (mapping_array == NULL) {
  10589         return BCM_E_PARAM;
  10590     }
  10591 
  10592     for (count = 0; count < array_count; count++) {
  10593         cur_class = mapping_array[count].class_id;
  10594         if ((cur_class < 0) || (cur_class >= _BCM_KT2_NUM_SAFC_CLASS)) {
  10595             return BCM_E_PARAM;
  10596         } else {
  10597             cos_bmp[cur_class] = 0;
  10598         }
  10599         
  10600         for (index = 0; index < BCM_COSQ_SAFC_GPORT_COUNT; index++) {
  10601             cur_gport = mapping_array[count].gport_list[index];
  10602             if (cur_gport == BCM_GPORT_INVALID) {
  10603                 break;
  10604             }
  10605             
  10606             BCM_IF_ERROR_RETURN(_bcm_kt2_fc_status_map_gport(unit, port, 
  10607                 cur_gport, _BCM_KT2_COSQ_FC_SAFC, &cos_bmp[cur_class]));
  10608         }
  10609     }
  10610 
  10611     for (index = 0; index < _BCM_KT2_NUM_SAFC_CLASS; index++) {
  10612          pfc_class[index] = index;
  10613     }
  10614     BCM_IF_ERROR_RETURN(_bcm_kt2_port_pfc_profile_set(unit, port,
  10615         _BCM_COSQ_OP_SET, _BCM_KT2_NUM_SAFC_CLASS, pfc_class, cos_bmp));
  10616     
  10617     return BCM_E_NONE;
  10618 }
  10619 
  10620 int
  10621 bcm_kt2_cosq_port_safc_get(int unit, bcm_port_t port,
  10622                         int cur_class,
  10623                          bcm_gport_t *gport, int gport_count,
  10624                          int *actual_gport_count)
  10625 {
  10626     _bcm_kt2_cosq_node_t *node;
  10627     bcm_port_t local_port;
  10628     int hw_cosq, count = 0;
  10629     uint32 profile_index;
  10630     uint64 rval64[16], *rval64s[1], rval, index_map;
  10631     uint32 tmp32, bmp;
  10632     _bcm_kt2_mmu_info_t *mmu_info;
  10633     int  mmu_port;
  10634     soc_info_t *si;
  10635     soc_reg_t   reg;
  10636     int node_port = 0 ;
  10637     int supported = 0 ;
  10638     _bcm_kt2_cosq_port_info_t *port_info;
  10639     static const soc_reg_t llfc_cfgr[] = {
  10640         PORT_PFC_CFG0r,
  10641     };
  10642     static const soc_field_t self[] = {
  10643         SEL0f, SEL1f, 
  10644     };
  10645     int j, hw_index, eindex;
  10646     soc_mem_t mem;
  10647     uint32 map_entry[SOC_MAX_MEM_WORDS];
  10648 
  10649     if (IS_CPU_PORT(unit, port)) {
  10650         return BCM_E_PORT;
  10651     }
  10652 
  10653     if ((gport == NULL) && (gport_count > 0)) {
  10654         return BCM_E_PARAM;
  10655     }
  10656     
  10657     if (actual_gport_count == NULL) {
  10658         return BCM_E_PARAM;
  10659     }
  10660 
  10661     BCM_IF_ERROR_RETURN
  10662         (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
  10663      
  10664     si = &SOC_INFO(unit);
  10665     mmu_info = _bcm_kt2_mmu_info[unit];
  10666 #ifdef BCM_METROLITE_SUPPORT
  10667     if(SOC_IS_METROLITE(unit)) {
  10668        mmu_port = ml_pfc_support[local_port].mmu_port;
  10669        supported = ml_pfc_support[local_port].supported;
  10670     } else
  10671 #endif
  10672 #ifdef BCM_SABER2_SUPPORT 
  10673     if(SOC_IS_SABER2(unit)) { 
  10674        mmu_port = sb2_pfc_support[local_port].mmu_port;
  10675        supported = sb2_pfc_support[local_port].supported;
  10676     } else 
  10677 #endif 
  10678    {
  10679     mmu_port = kt2_pfc_support[local_port].mmu_port;
  10680     supported = kt2_pfc_support[local_port].supported; 
  10681    }
  10682    if (!supported) {
  10683        return BCM_E_PARAM; 
  10684 
  10685    }
  10686     port_info = &mmu_info->port[local_port];
  10687 
  10688     rval64s[0] = rval64;
  10689     reg = llfc_cfgr[mmu_port/32];
  10690     BCM_IF_ERROR_RETURN(soc_reg64_get(unit, reg, REG_PORT_ANY, 0, &rval));
  10691 
  10692     index_map = soc_reg64_field_get(unit, reg, rval, PROFILE_INDEXf);
  10693     COMPILER_64_SHR(index_map, ((mmu_port % 32) * 2));
  10694     COMPILER_64_TO_32_LO(tmp32, index_map);
  10695     profile_index = (tmp32 & 3)*16;
  10696 
  10697     BCM_IF_ERROR_RETURN
  10698         (soc_profile_reg_get(unit, _bcm_kt2_llfc_profile[unit],
  10699                              profile_index, 16, rval64s));
  10700 
  10701     bmp = soc_reg64_field32_get(unit, PRIO2COS_PROFILEr, rval64[cur_class],
  10702                                 COS_BMPf);
  10703      
  10704     num_port_schedulers[unit] = si->cpu_hg_index;
  10705 
  10706     for (hw_cosq = 0; hw_cosq < 8; hw_cosq++) {
  10707         if (!(bmp & (1 << hw_cosq))) {
  10708             continue;
  10709         }
  10710             for (j = num_pp_ports[unit] ;
  10711                  j < num_total_schedulers[unit] ; j++) {
  10712                 node = &mmu_info->sched_node[j];
  10713                 if (node->cosq_attached_to == -1) { 
  10714                     continue ;
  10715                 } 
  10716                 BCM_IF_ERROR_RETURN
  10717                   (_bcm_kt2_cosq_node_get(unit, node->gport, NULL 
  10718                      ,&node_port, NULL, NULL));
  10719                 if ( (node_port != local_port) ||
  10720                     ((node->hw_index - port_info->q_offset) != hw_cosq)) {
  10721                     continue;
  10722                 }
  10723 
  10724                 hw_index = (node->hw_index / 16);
  10725                 eindex = (node->hw_index % 16)/8;
  10726                 if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L0) {
  10727                     mem = MMU_INTFI_FC_MAP_TBL0m ; 
  10728                 } else if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L1) {
  10729                     mem = MMU_INTFI_FC_MAP_TBL1m; 
  10730                 } else {
  10731                     continue;
  10732                 }
  10733 
  10734                 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, 
  10735                         MEM_BLOCK_ALL, hw_index, &map_entry));
  10736 
  10737                 if (soc_mem_field32_get(unit, mem, &map_entry, self[eindex])) {
  10738                     if (gport_count > 0 && count < gport_count) {
  10739                         gport[count] = node->gport;
  10740                     }
  10741                     count++;
  10742                     break;
  10743                 }
  10744             }
  10745             for (j = port_info->q_offset; 
  10746                  (j < port_info->q_limit); j++) {
  10747                 node = &mmu_info->queue_node[j];
  10748                 if (node->cosq_attached_to == -1) { 
  10749                     continue ;
  10750                 } 
  10751                 BCM_IF_ERROR_RETURN
  10752                   (_bcm_kt2_cosq_node_get(unit, node->gport, NULL ,&node_port, 
  10753                                NULL, NULL));
  10754                 if ((node_port != local_port)) {
  10755                     continue;
  10756                 }
  10757                 if ((node->hw_index - port_info->q_offset) != hw_cosq) {
  10758                     continue;
  10759                 }
  10760                 mem = MMU_INTFI_FC_MAP_TBL2m ;
  10761                 hw_index = (node->hw_index / 16);
  10762                 eindex = (node->hw_index % 16) / 8; 
  10763 
  10764                 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, 
  10765                         MEM_BLOCK_ALL, hw_index, &map_entry));
  10766 
  10767                 if (soc_mem_field32_get(unit, mem, &map_entry, self[eindex])) {
  10768                       
  10769                     if (gport_count > 0 && count < gport_count) {
  10770                          
  10771                         gport[count] = node->gport;
  10772                     }
  10773                     count++;
  10774                     break;
  10775                 }
  10776             }
  10777             if(soc_feature(unit, soc_feature_mmu_packing)) {   
  10778                for (j = port_info->mcq_offset; 
  10779                     (j < port_info->mcq_limit); j++) {
  10780                     node = &mmu_info->queue_node[j];
  10781                     if (node->cosq_attached_to == -1) { 
  10782                         continue ;
  10783                     } 
  10784                     BCM_IF_ERROR_RETURN
  10785                      (_bcm_kt2_cosq_node_get(unit, node->gport, NULL ,&node_port, 
  10786                                    NULL, NULL));
  10787                     if ((node_port != local_port)) {
  10788                         continue;
  10789                     }
  10790                     if ((node->hw_index % NUM_COS(unit)) != hw_cosq) {
  10791                         continue;
  10792                     }
  10793                     mem = MMU_INTFI_FC_MAP_TBL2m ;
  10794                     hw_index = (node->hw_index / 16);
  10795                     eindex = (node->hw_index % 16) / 8; 
  10796 
  10797                     BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, 
  10798                             MEM_BLOCK_ALL, hw_index, &map_entry));
  10799 
  10800                     if (soc_mem_field32_get(unit, mem, &map_entry, self[eindex])) {
  10801                         if (gport_count > 0 && count < gport_count ) {
  10802                             gport[count] = node->gport;
  10803                     }
  10804                     count++;
  10805                     break;
  10806                     }
  10807                }
  10808         }  
  10809         if ((count == gport_count) && (gport_count > 0)) {
  10810             break;
  10811         }
  10812     }
  10813 
  10814     if (count == 0) {
  10815         return BCM_E_NOT_FOUND;
  10816     }
  10817     *actual_gport_count = count;
  10818     return BCM_E_NONE;
  10819 }
  10820 
  10821                     
  10822 int
  10823 bcm_kt2_cosq_safc_class_mapping_get(int unit,
  10824     bcm_gport_t port,
  10825     int array_max,
  10826     int *array_count,
  10827     bcm_cosq_safc_class_mapping_t *mapping_array)
  10828 {
  10829     int rv = 0;
  10830     int cur_class = 0;
  10831     int actual_gport_count, class_count = 0;
  10832     int local_port = 0 ;
  10833 
  10834     BCM_IF_ERROR_RETURN
  10835         (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
  10836     if (!IS_HG_PORT(unit,local_port)) {
  10837         return BCM_E_PARAM; 
  10838     }
  10839     if ((mapping_array == NULL) && (array_max > 0)) {
  10840         return BCM_E_PARAM;
  10841     }
  10842     if (array_count == NULL) {
  10843         return BCM_E_PARAM;
  10844     }
  10845 
  10846     for (cur_class = 0; cur_class < _BCM_KT2_NUM_SAFC_CLASS; cur_class++) {
  10847         actual_gport_count = 0;
  10848         if (array_max > 0) {
  10849             rv = bcm_kt2_cosq_port_safc_get(unit, local_port, cur_class, 
  10850                         mapping_array[class_count].gport_list,
  10851                         BCM_COSQ_PFC_GPORT_COUNT, &actual_gport_count);
  10852         } else {
  10853             rv = bcm_kt2_cosq_port_safc_get(unit, local_port, cur_class,
  10854                          NULL, -1, &actual_gport_count);
  10855         }
  10856         if (rv == BCM_E_NONE) {
  10857             if (array_max > 0) {
  10858                 mapping_array[class_count].class_id = cur_class;
  10859                 if (actual_gport_count < BCM_COSQ_PFC_GPORT_COUNT) {
  10860                     mapping_array[class_count].gport_list[actual_gport_count] = 
  10861                                                              BCM_GPORT_INVALID;
  10862                 }
  10863             }
  10864             class_count++;
  10865         } else if (rv != BCM_E_NOT_FOUND) {
  10866             return rv;
  10867         }
  10868 
  10869         if ((class_count == array_max) && (array_max > 0)) {
  10870             break;
  10871         }
  10872     }
  10873 
  10874     *array_count = class_count;
  10875     if (class_count == 0) {
  10876         return BCM_E_NOT_FOUND;
  10877     }
  10878     
  10879     return BCM_E_NONE;
  10880 }
  10881 
  10882 /*
  10883  * Function:
  10884  *     bcm_kt2_cosq_pfc_class_mapping_set
  10885  * Purpose:
  10886  *     Set PFC mapping for port. PFC class is mapped to cosq or scheduler node gports.
  10887  * Parameters:
  10888  *     unit             - (IN) unit number
  10889  *     port             - (IN) port number
  10890  *     array_count      - (IN) count of mapping
  10891  *     mapping_array    - (IN) mappings 
  10892  * Returns:
  10893  *     BCM_E_XXX
  10894  */
  10895 int
  10896 bcm_kt2_cosq_pfc_class_mapping_set(int unit,
  10897     bcm_gport_t port,
  10898     int array_count,
  10899     bcm_cosq_pfc_class_mapping_t *mapping_array)
  10900 {
  10901     int index, count;
  10902     int cur_class = 0, pfc_class[_BCM_KT2_NUM_PFC_CLASS];
  10903     bcm_gport_t cur_gport = 0;
  10904     int local_port = 0;
  10905     uint32 cos_bmp[_BCM_KT2_NUM_PFC_CLASS];
  10906 
  10907     BCM_IF_ERROR_RETURN
  10908         (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
  10909     if (!SOC_IS_SABER2(unit) && !IS_XE_PORT(unit,local_port)) {
  10910         return BCM_E_PARAM; 
  10911     }
  10912     if ((array_count < 0) || (array_count > _BCM_KT2_NUM_PFC_CLASS)) {
  10913         return BCM_E_PARAM;
  10914     }
  10915     if (mapping_array == NULL) {
  10916         return BCM_E_PARAM;
  10917     }
  10918 
  10919     for (count = 0; count < array_count; count++) {
  10920         cur_class = mapping_array[count].class_id;
  10921         if ((cur_class < 0) || (cur_class >= _BCM_KT2_NUM_PFC_CLASS)) {
  10922             return BCM_E_PARAM;
  10923         } else {
  10924             cos_bmp[cur_class] = 0;
  10925         }
  10926         
  10927         for (index = 0; index < BCM_COSQ_PFC_GPORT_COUNT; index++) {
  10928             cur_gport = mapping_array[count].gport_list[index];
  10929             if (cur_gport == BCM_GPORT_INVALID) {
  10930                 break;
  10931             }
  10932             
  10933             BCM_IF_ERROR_RETURN(_bcm_kt2_fc_status_map_gport(unit, port, 
  10934                 cur_gport, _BCM_KT2_COSQ_FC_PFC, &cos_bmp[cur_class]));
  10935         }
  10936     }
  10937 
  10938     for (index = 0; index < _BCM_KT2_NUM_PFC_CLASS; index++) {
  10939          pfc_class[index] = index;
  10940     }
  10941     BCM_IF_ERROR_RETURN(_bcm_kt2_port_pfc_profile_set(unit, port,
  10942         _BCM_COSQ_OP_SET, _BCM_KT2_NUM_PFC_CLASS, pfc_class, cos_bmp));
  10943     
  10944     return BCM_E_NONE;
  10945 }
  10946 
  10947 int
  10948 bcm_kt2_cosq_pfc_class_mapping_get(int unit,
  10949     bcm_gport_t port,
  10950     int array_max,
  10951     int *array_count,
  10952     bcm_cosq_pfc_class_mapping_t *mapping_array)
  10953 {
  10954     int rv = 0;
  10955     int cur_class = 0;
  10956     int actual_gport_count, class_count = 0;
  10957     int local_port = 0 ;
  10958     bcm_switch_control_t sc[] = { bcmSwitchPFCClass0Queue,
  10959                                   bcmSwitchPFCClass1Queue,
  10960                                   bcmSwitchPFCClass2Queue,
  10961                                   bcmSwitchPFCClass3Queue,
  10962                                   bcmSwitchPFCClass4Queue,
  10963                                   bcmSwitchPFCClass5Queue,
  10964                                   bcmSwitchPFCClass6Queue,
  10965                                   bcmSwitchPFCClass7Queue
  10966                                 };
  10967 
  10968     BCM_IF_ERROR_RETURN
  10969         (_bcm_kt2_cosq_localport_resolve(unit, port, &local_port));
  10970     if (!SOC_IS_SABER2(unit) && !IS_XE_PORT(unit,local_port)) {
  10971         return BCM_E_PARAM; 
  10972     }
  10973     if ((mapping_array == NULL) && (array_max > 0)) {
  10974         return BCM_E_PARAM;
  10975     }
  10976     if (array_count == NULL) {
  10977         return BCM_E_PARAM;
  10978     }
  10979 
  10980     for (cur_class = 0; cur_class < _BCM_KT2_NUM_PFC_CLASS; cur_class++) {
  10981         actual_gport_count = 0;
  10982         if (array_max > 0) {
  10983             rv = bcm_kt2_cosq_port_pfc_get(unit, local_port, sc[cur_class], 
  10984                         mapping_array[class_count].gport_list,
  10985                         BCM_COSQ_PFC_GPORT_COUNT, &actual_gport_count);
  10986         } else {
  10987             rv = bcm_kt2_cosq_port_pfc_get(unit, local_port, sc[cur_class],
  10988                          NULL, -1, &actual_gport_count);
  10989         }
  10990         if (rv == BCM_E_NONE) {
  10991             if (array_max > 0) {
  10992                 mapping_array[class_count].class_id = cur_class;
  10993                 if (actual_gport_count < BCM_COSQ_PFC_GPORT_COUNT) {
  10994                     mapping_array[class_count].gport_list[actual_gport_count] = 
  10995                                                              BCM_GPORT_INVALID;
  10996                 }
  10997             }
  10998             class_count++;
  10999         } else if (rv != BCM_E_NOT_FOUND) {
  11000             return rv;
  11001         }
  11002 
  11003         if ((class_count == array_max) && (array_max > 0)) {
  11004             break;
  11005         }
  11006     }
  11007 
  11008     *array_count = class_count;
  11009     if (class_count == 0) {
  11010         return BCM_E_NOT_FOUND;
  11011     }
  11012     
  11013     return BCM_E_NONE;
  11014 }
  11015 
  11016 int
  11017 bcm_kt2_cosq_stat_get(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
  11018                      bcm_cosq_stat_t stat, int sync_mode, uint64 *value)
  11019 {
  11020     bcm_port_t local_port;
  11021     int startq, numq, i;
  11022     uint64 sum, value64;
  11023     soc_counter_non_dma_id_t dma_id;
  11024     _bcm_kt2_cosq_node_t *node = NULL;
  11025     _bcm_kt2_cosq_node_t *child_node = NULL;
  11026 #ifdef BCM_SABER2_SUPPORT
  11027     uint32 drop_type, total_drop_mask, wred_drop_mask;
  11028     uint32 rval;
  11029 #endif
  11030     int (*counter_get) (int , soc_port_t , soc_reg_t , int , uint64 *);
  11031 
  11032     if (value == NULL) {
  11033         return BCM_E_PARAM;
  11034     }
  11035     if (stat == bcmCosqStatEgressUCQueueBytesCurrent) {
  11036         return _bcm_kt2_cosq_current_stat_set_get(unit, port,
  11037                                                   cosq, stat,
  11038                                                   0, value);
  11039     }
  11040 
  11041     /*
  11042      * if sync-mode is set, update the software cached counter value, 
  11043      * with the hardware count and then retrieve the count.
  11044      * else return the software cache counter value.
  11045      */
  11046     counter_get = (sync_mode == 1)? soc_counter_sync_get: soc_counter_get;
  11047 
  11048     BCM_IF_ERROR_RETURN
  11049         (_bcm_kt2_cosq_index_resolve
  11050         (unit, port, cosq, _BCM_KT2_COSQ_INDEX_STYLE_UCAST_QUEUE,
  11051          &local_port, &startq, &numq));
  11052 
  11053     if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
  11054         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
  11055         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) ||
  11056         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port)) {
  11057         /* pass port as queue number */
  11058         local_port = startq;
  11059         startq = 0;
  11060     }
  11061 
  11062 #ifdef BCM_SABER2_SUPPORT
  11063     if(SOC_IS_SABER2(unit)) {
  11064 #ifdef BCM_METROLITE_SUPPORT
  11065         if(SOC_IS_METROLITE(unit)) {
  11066            total_drop_mask = BCM_ML_COSQ_TOTAL_DROP_MASK;
  11067            wred_drop_mask = BCM_ML_COSQ_WRED_DROP_MASK;
  11068         } else
  11069 #endif
  11070         {
  11071            total_drop_mask = BCM_SB2_COSQ_TOTAL_DROP_MASK;
  11072            wred_drop_mask = BCM_SB2_COSQ_WRED_DROP_MASK;
  11073         }
  11074         SOC_IF_ERROR_RETURN(READ_THDO_DROP_CTR_CONFIGr(unit, &rval));
  11075         drop_type = soc_reg_field_get(unit, THDO_DROP_CTR_CONFIGr, rval, OP_DROP_MASKf); 
  11076 
  11077         if (drop_type == total_drop_mask) {
  11078             if (!((stat == bcmCosqStatDroppedPackets)||
  11079                  (stat == bcmCosqStatDroppedBytes)||
  11080                  (stat == bcmCosqStatRedCongestionDroppedPackets)||
  11081                  (stat == bcmCosqStatRedCongestionDroppedBytes)||
  11082                  (stat == bcmCosqStatYellowCongestionDroppedPackets)||
  11083                  (stat == bcmCosqStatYellowCongestionDroppedBytes)||
  11084                  (stat == bcmCosqStatOutPackets)||(stat == bcmCosqStatOutBytes))){
  11085                 return BCM_E_PARAM;
  11086             }   
  11087 
  11088         }
  11089         else if (drop_type == wred_drop_mask) {
  11090             if (!((stat == bcmCosqStatDiscardDroppedPackets)||
  11091                   (stat == bcmCosqStatDiscardDroppedBytes)||
  11092                   (stat == bcmCosqStatRedDiscardDroppedPackets)||
  11093                   (stat == bcmCosqStatRedDiscardDroppedBytes)||
  11094                   (stat == bcmCosqStatYellowDiscardDroppedPackets)||
  11095                   (stat == bcmCosqStatYellowDiscardDroppedBytes)||
  11096                   (stat == bcmCosqStatGreenDiscardDroppedBytes)||
  11097                   (stat == bcmCosqStatGreenDiscardDroppedPackets)||
  11098                   (stat == bcmCosqStatOutPackets)||(stat == bcmCosqStatOutBytes))){
  11099                 return BCM_E_PARAM;
  11100             }
  11101         }
  11102     }
  11103 #endif
  11104     switch (stat) {
  11105         case bcmCosqStatDroppedPackets:
  11106         case bcmCosqStatDiscardDroppedPackets:
  11107             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT;
  11108             break;
  11109 
  11110         case bcmCosqStatDroppedBytes:
  11111         case bcmCosqStatDiscardDroppedBytes:
  11112             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE;
  11113             break;
  11114 
  11115         case bcmCosqStatRedCongestionDroppedPackets:
  11116         case bcmCosqStatRedDiscardDroppedPackets:
  11117             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED;
  11118             break;
  11119 
  11120         case bcmCosqStatRedCongestionDroppedBytes:
  11121         case bcmCosqStatRedDiscardDroppedBytes:
  11122             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_RED;
  11123             break;
  11124 
  11125         case bcmCosqStatYellowCongestionDroppedPackets:
  11126         case bcmCosqStatYellowDiscardDroppedPackets :
  11127             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW;
  11128             break;
  11129 
  11130         case bcmCosqStatYellowCongestionDroppedBytes:
  11131         case bcmCosqStatYellowDiscardDroppedBytes:
  11132             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_YELLOW;
  11133             break;
  11134 
  11135         case bcmCosqStatGreenDiscardDroppedPackets:
  11136             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN;
  11137             break;
  11138 
  11139         case bcmCosqStatGreenDiscardDroppedBytes:
  11140             dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_GREEN;
  11141             break;
  11142  
  11143         case bcmCosqStatOutPackets:
  11144             dma_id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT;
  11145             break;
  11146         
  11147         case bcmCosqStatOutBytes:
  11148             dma_id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE;
  11149             break;
  11150         default:
  11151             return BCM_E_PARAM;
  11152     }
  11153 
  11154     if (!BCM_GPORT_IS_SCHEDULER(port)) { 
  11155         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(port) ||
  11156             BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
  11157             BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
  11158             BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
  11159             BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) ||
  11160             (cosq != BCM_COS_INVALID)) {
  11161             BCM_IF_ERROR_RETURN
  11162                 (counter_get(unit, local_port, dma_id, startq, value));
  11163         } else {
  11164             numq = soc_property_get(unit, spn_BCM_NUM_COS, BCM_COS_DEFAULT);
  11165             if (numq < 1) {
  11166                 numq = 1;
  11167             } else if (numq > 8) {
  11168                 numq = 8;
  11169             }
  11170             COMPILER_64_ZERO(sum);
  11171             COMPILER_64_ZERO(value64);
  11172             for (i = 0; i < numq; i++) {
  11173                 BCM_IF_ERROR_RETURN
  11174                     (counter_get(unit, local_port, dma_id, i, &value64));
  11175                 COMPILER_64_ADD_64(sum, value64);
  11176             }
  11177             *value = sum;
  11178         }
  11179     } else {
  11180            BCM_IF_ERROR_RETURN
  11181            (_bcm_kt2_cosq_node_get(unit, port, 0, 
  11182                             &local_port, NULL, &node));
  11183            COMPILER_64_ZERO(sum);
  11184            if (cosq == -1) { 
  11185                for (i = 0; i < node->numq; i++) {
  11186                     if ((_bcm_kt2_cosq_child_node_at_input(node, i, &child_node))
  11187                                                       == BCM_E_NOT_FOUND) {
  11188                          continue;
  11189                     }
  11190                      port = child_node->gport;
  11191                          
  11192                     BCM_IF_ERROR_RETURN
  11193                     (_bcm_kt2_cosq_index_resolve
  11194                     (unit, port, 0, _BCM_KT2_COSQ_INDEX_STYLE_UCAST_QUEUE,
  11195                     &local_port, &startq, &numq));
  11196 
  11197                     if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
  11198                         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
  11199                         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port)) {
  11200                         /* pass port as queue number */
  11201                         local_port = startq;
  11202                         startq = 0;
  11203                    }
  11204                    BCM_IF_ERROR_RETURN
  11205                    (counter_get(unit, local_port, dma_id,
  11206                              startq , &value64));
  11207                    COMPILER_64_ADD_64(sum, value64);
  11208                } 
  11209          } 
  11210          else { 
  11211 
  11212                if ((_bcm_kt2_cosq_child_node_at_input(node, cosq, &child_node))
  11213                                                   == BCM_E_NOT_FOUND) {
  11214                     return BCM_E_NOT_FOUND;  
  11215                }
  11216                port = child_node->gport;
  11217                      
  11218                BCM_IF_ERROR_RETURN
  11219                (_bcm_kt2_cosq_index_resolve
  11220                 (unit, port, 0, _BCM_KT2_COSQ_INDEX_STYLE_UCAST_QUEUE,
  11221                  &local_port, &startq, &numq));
  11222 
  11223                if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
  11224                    BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
  11225                    BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port)) {
  11226                    /* pass port as queue number */
  11227                    local_port = startq;
  11228                    startq = 0;
  11229                }
  11230                BCM_IF_ERROR_RETURN
  11231                (counter_get(unit, local_port, dma_id,
  11232                              startq , &value64));
  11233                    COMPILER_64_ADD_64(sum, value64);
  11234          }
  11235          *value = sum;
  11236     }
  11237 
  11238     return BCM_E_NONE;
  11239 }
  11240 
  11241 int
  11242 bcm_kt2_cosq_gport_stat_set(int unit, bcm_gport_t port, bcm_cos_queue_t cosq,
  11243                                  bcm_cosq_gport_stats_t stat, uint64 value)
  11244 {
  11245     bcm_port_t local_port;
  11246     int startq, numq, i;
  11247     uint64 value64;
  11248     soc_counter_non_dma_id_t dma_id;
  11249 
  11250     if (BCM_GPORT_IS_SCHEDULER(port) && cosq != BCM_COS_INVALID) {
  11251         return BCM_E_PARAM;
  11252     }
  11253 
  11254     BCM_IF_ERROR_RETURN
  11255         (_bcm_kt2_cosq_index_resolve
  11256         (unit, port, cosq, _BCM_KT2_COSQ_INDEX_STYLE_UCAST_QUEUE,
  11257          &local_port, &startq, &numq));
  11258     if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
  11259         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
  11260         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) ||
  11261         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port)) {
  11262         /* pass port as queue number */
  11263         local_port = startq;
  11264         startq = 0;
  11265     }
  11266 
  11267     switch (stat) {
  11268     case bcmCosqGportGreenAcceptedPkts:
  11269         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_GREEN;
  11270         break;
  11271     case bcmCosqGportGreenAcceptedBytes:
  11272         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_BYTE_GREEN;
  11273         break;
  11274     case bcmCosqGportYellowAcceptedPkts:
  11275         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_YELLOW;
  11276         break;
  11277     case bcmCosqGportYellowAcceptedBytes:
  11278         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_BYTE_YELLOW;
  11279         break;    
  11280     case bcmCosqGportRedAcceptedPkts:
  11281         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_RED;
  11282         break;
  11283     case bcmCosqGportRedAcceptedBytes:
  11284         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_BYTE_RED;
  11285         break;        
  11286     case bcmCosqGportReceivedPkts:
  11287         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT;
  11288         break;
  11289     case bcmCosqGportReceivedBytes:
  11290         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_BYTE;
  11291         break;
  11292     case bcmCosqGportGreenDroppedPkts:
  11293         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN;
  11294         break;
  11295     case bcmCosqGportGreenDroppedBytes:
  11296         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_GREEN;
  11297         break;    
  11298     case bcmCosqGportYellowDroppedPkts:
  11299         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW;
  11300         break;
  11301     case bcmCosqGportYellowDroppedBytes:
  11302         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_YELLOW;
  11303         break;    
  11304     case bcmCosqGportRedDroppedPkts:
  11305         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED;
  11306         break;
  11307     case bcmCosqGportRedDroppedBytes:
  11308         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_RED;
  11309         break;    
  11310     case bcmCosqGportDroppedPkts:
  11311         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT;
  11312         break;
  11313     case bcmCosqGportDroppedBytes:
  11314         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE;
  11315         break;
  11316     case bcmCosqGportOutPkts:
  11317         dma_id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT;
  11318         break;
  11319     case bcmCosqGportOutBytes:
  11320         dma_id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE;
  11321         break;    
  11322     default:
  11323         return BCM_E_PARAM;
  11324     }
  11325 
  11326     if (!BCM_GPORT_IS_SCHEDULER(port)) {      
  11327         BCM_IF_ERROR_RETURN
  11328              (soc_counter_set(unit, local_port, dma_id, startq, value));
  11329     } else {
  11330          
  11331         COMPILER_64_ZERO(value64);
  11332         for (i = 0; i < numq; i++) {
  11333             BCM_IF_ERROR_RETURN
  11334                 (soc_counter_set(unit, local_port, dma_id, startq + i, 
  11335                                  value64));
  11336         }
  11337     }    
  11338 
  11339     return BCM_E_NONE;
  11340 }
  11341 
  11342 int
  11343 bcm_kt2_cosq_gport_stat_get(int unit, bcm_port_t port, bcm_cos_queue_t cosq,
  11344                                  bcm_cosq_gport_stats_t stat, uint64 *value)
  11345 {
  11346     bcm_port_t local_port;
  11347     int startq, numq, i;
  11348     uint64 sum, value64;
  11349     soc_counter_non_dma_id_t dma_id;
  11350     
  11351     if (value == NULL) {
  11352         return BCM_E_PARAM;
  11353     }
  11354 
  11355     if (BCM_GPORT_IS_SCHEDULER(port) && cosq != BCM_COS_INVALID) {
  11356         return BCM_E_PARAM;
  11357     }    
  11358 
  11359     BCM_IF_ERROR_RETURN
  11360         (_bcm_kt2_cosq_index_resolve
  11361         (unit, port, cosq, _BCM_KT2_COSQ_INDEX_STYLE_UCAST_QUEUE,
  11362          &local_port, &startq, &numq));
  11363 
  11364     if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(port) ||
  11365         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port) ||
  11366         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(port) ||
  11367         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port)) {
  11368         /* pass port as queue number */
  11369         local_port = startq;
  11370         startq = 0;
  11371     }
  11372 
  11373     switch (stat) {
  11374     case bcmCosqGportGreenAcceptedPkts:
  11375         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_GREEN;
  11376         break;
  11377     case bcmCosqGportGreenAcceptedBytes:
  11378         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_BYTE_GREEN;
  11379         break;
  11380     case bcmCosqGportYellowAcceptedPkts:
  11381         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_YELLOW;
  11382         break;
  11383     case bcmCosqGportYellowAcceptedBytes:
  11384         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_BYTE_YELLOW;
  11385         break;    
  11386     case bcmCosqGportRedAcceptedPkts:
  11387         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_RED;
  11388         break;
  11389     case bcmCosqGportRedAcceptedBytes:
  11390         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_BYTE_RED;
  11391         break;        
  11392     case bcmCosqGportReceivedPkts:
  11393         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT;
  11394         break;
  11395     case bcmCosqGportReceivedBytes:
  11396         dma_id = SOC_COUNTER_NON_DMA_COSQ_ACCEPT_BYTE;
  11397         break;
  11398     case bcmCosqGportGreenDroppedPkts:
  11399         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN;
  11400         break;
  11401     case bcmCosqGportGreenDroppedBytes:
  11402         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_GREEN;
  11403         break;    
  11404     case bcmCosqGportYellowDroppedPkts:
  11405         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW;
  11406         break;
  11407     case bcmCosqGportYellowDroppedBytes:
  11408         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_YELLOW;
  11409         break;    
  11410     case bcmCosqGportRedDroppedPkts:
  11411         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED;
  11412         break;
  11413     case bcmCosqGportRedDroppedBytes:
  11414         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_RED;
  11415         break;    
  11416     case bcmCosqGportDroppedPkts:
  11417         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT;
  11418         break;
  11419     case bcmCosqGportDroppedBytes:
  11420         dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE;
  11421         break;
  11422     case bcmCosqGportOutPkts:
  11423         dma_id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT;
  11424         break;
  11425     case bcmCosqGportOutBytes:
  11426         dma_id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE;
  11427         break;    
  11428     default:
  11429         return BCM_E_PARAM;
  11430     }
  11431 
  11432     if (!BCM_GPORT_IS_SCHEDULER(port)) { 
  11433         BCM_IF_ERROR_RETURN
  11434              (soc_counter_get(unit, local_port, dma_id, startq, value)); 
  11435     } else {
  11436         COMPILER_64_ZERO(sum);
  11437         for (i = 0; i < numq; i++) {
  11438             BCM_IF_ERROR_RETURN
  11439                 (soc_counter_get(unit, local_port, dma_id, startq + i, 
  11440                                  &value64));
  11441             COMPILER_64_ADD_64(sum, value64);
  11442         }
  11443         *value = sum;
  11444     }
  11445 
  11446     return BCM_E_NONE;
  11447 }
  11448 
  11449 #ifdef BCM_KATANA2_SUPPORT
  11450 STATIC
  11451 void _bcm_kt2_flex_config_set (int unit, bcm_cosq_stat_t *stat_array,
  11452                                int stat_count)
  11453 {
  11454     _sb2_cosq_counter_mem_map_t *mem_map;
  11455     int num_elem = 0, elem_size = 4;
  11456     int index = 0;
  11457     int i = 0;
  11458     char *cname_pkt = NULL;
  11459     char *cname_byte = NULL;
  11460     soc_counter_non_dma_id_t non_dma_id = 0;
  11461     uint16 dev_id;
  11462     uint8 rev_id;
  11463 
  11464     soc_sb2_cosq_counter_mem_map_get(unit, &num_elem, &mem_map);
  11465     if (SOC_IS_SABER2(unit)) {
  11466        elem_size = 2;
  11467     }
  11468     soc_cm_get_id(unit, &dev_id, &rev_id);
  11469     if ((dev_id == BCM56233_DEVICE_ID) ||
  11470         (SOC_IS_METROLITE(unit))) {
  11471         elem_size = 1;
  11472     }
  11473 
  11474     /*updating the mem map for cosq counters*/ 
  11475     for (index = 0; index < stat_count; index++) {
  11476         switch (stat_array[index]) {
  11477             case bcmCosqStatDroppedPackets:
  11478                 non_dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT;
  11479                 cname_pkt = "DROP_PKT"; 
  11480                 cname_byte = "DROP_BYTE"; 
  11481                 break;
  11482             case bcmCosqStatDiscardDroppedPackets:
  11483                 non_dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT;
  11484                 cname_pkt = "WRED_DROP_PKT"; 
  11485                 cname_byte = "WRED_DROP_BYTE"; 
  11486                 break;
  11487             case bcmCosqStatYellowCongestionDroppedPackets:
  11488                 non_dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW;
  11489                 cname_pkt = "DROP_PKT_Y"; 
  11490                 cname_byte = "DROP_BYTE_Y"; 
  11491                 break;
  11492             case bcmCosqStatYellowDiscardDroppedPackets:
  11493                 non_dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW;
  11494                 cname_pkt = "WRED_DROP_PKT_Y"; 
  11495                 cname_byte = "WRED_DROP_BYTE_Y"; 
  11496                 break;
  11497 
  11498             case bcmCosqStatRedCongestionDroppedPackets:
  11499                 non_dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED;
  11500                 cname_pkt = "DROP_PKT_R"; 
  11501                 cname_byte = "DROP_BYTE_R"; 
  11502                 break;
  11503             case bcmCosqStatRedDiscardDroppedPackets:
  11504                 non_dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED;
  11505                 cname_pkt = "WRED_DROP_PKT_R"; 
  11506                 cname_byte = "WRED_DROP_BYTE_R"; 
  11507                 break;
  11508 
  11509             case bcmCosqStatGreenDiscardDroppedPackets: 
  11510                 non_dma_id = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN; 
  11511                 cname_pkt = "WRED_DROP_PKT_G"; 
  11512                 cname_byte = "WRED_DROP_BYTE_G"; 
  11513                 break;
  11514 
  11515             case bcmCosqStatOutPackets :
  11516                 non_dma_id = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT;
  11517                 cname_pkt = "PERQ_PKT"; 
  11518                 cname_byte ="PERQ_BYTE"; 
  11519                 break;
  11520             default:
  11521                 break;
  11522         }
  11523         for ( i = 0; i < elem_size; i++) {
  11524             mem_map[index*elem_size + i].non_dma_id = non_dma_id;
  11525             mem_map[index*elem_size + i].cname_pkt = cname_pkt;
  11526             mem_map[index*elem_size + i].cname_byte = cname_byte;
  11527         }
  11528     } 
  11529 }
  11530 
  11531 int 
  11532 bcm_kt2_cosq_stat_config_set(int unit, int stat_count, 
  11533                     bcm_cosq_stat_t  *stat_array)
  11534 {
  11535     int index = 0;
  11536     uint32 drop_type; 
  11537     uint32 type = 0;
  11538     int rv;
  11539     pbmp_t      pbmp;
  11540     sal_usecs_t     interval;
  11541     uint32      flags;
  11542     soc_port_t port;
  11543 #ifdef BCM_KATANA2_SUPPORT
  11544     uint32 total_drop_mask, wred_drop_mask, default_drop_mask;
  11545 #endif
  11546 
  11547 #ifdef BCM_METROLITE_SUPPORT
  11548     if(SOC_IS_METROLITE(unit)) {
  11549        total_drop_mask = BCM_ML_COSQ_TOTAL_DROP_MASK;
  11550        wred_drop_mask = BCM_ML_COSQ_WRED_DROP_MASK;
  11551        default_drop_mask = BCM_ML_COSQ_DEFAULT_DROP_MASK;
  11552        drop_type = BCM_ML_COSQ_DEFAULT_DROP_MASK;
  11553    } else
  11554 #endif
  11555    {
  11556        total_drop_mask = BCM_SB2_COSQ_TOTAL_DROP_MASK;
  11557        wred_drop_mask = BCM_SB2_COSQ_WRED_DROP_MASK;
  11558        default_drop_mask = BCM_SB2_COSQ_DEFAULT_DROP_MASK;
  11559        drop_type = BCM_SB2_COSQ_DEFAULT_DROP_MASK; 
  11560     }
  11561 
  11562     if ((stat_count != BCM_SB2_COSQ_FLEX_COUNT_SUPPORTED) || 
  11563             (stat_array == NULL)) {
  11564         return BCM_E_PARAM;
  11565     }
  11566 
  11567     /*validating the stat_types, aligning the stats order generating the type*/
  11568     for ( index = 0; index < stat_count; index++) {
  11569         switch(stat_array[index]) {
  11570             case bcmCosqStatDroppedPackets:
  11571                 /*swap with position 0*/
  11572                 stat_array[index] = stat_array[0];
  11573                 stat_array[0] = bcmCosqStatDroppedPackets;
  11574                 /*fall through*/
  11575             case bcmCosqStatYellowCongestionDroppedPackets:
  11576             case bcmCosqStatRedCongestionDroppedPackets:
  11577                 type = total_drop_mask;
  11578                 break;
  11579 
  11580             case bcmCosqStatDiscardDroppedPackets:
  11581                 /*swap with position 0*/
  11582                 stat_array[index] = stat_array[0];
  11583                 stat_array[0] = bcmCosqStatDiscardDroppedPackets; 
  11584                 /*fall through*/
  11585             case bcmCosqStatGreenDiscardDroppedPackets: 
  11586             case bcmCosqStatYellowDiscardDroppedPackets:
  11587             case bcmCosqStatRedDiscardDroppedPackets:
  11588                 type = wred_drop_mask; 
  11589                 break;
  11590             case bcmCosqStatOutPackets :
  11591                 break;
  11592             default:
  11593                 return BCM_E_PARAM;
  11594         }
  11595         if (stat_array[index] != bcmCosqStatOutPackets) {
  11596             if (drop_type != default_drop_mask) {
  11597                 if (BCM_SB2_COSQ_CHECK_STAT_TYPE(drop_type,type)) {
  11598                     return BCM_E_PARAM;
  11599                 }
  11600             }
  11601             else {
  11602                 drop_type = type;
  11603             }
  11604         }
  11605 
  11606     }
  11607     /* 
  11608      * populate the configuration variable. 
  11609      * we need to configure super set first
  11610      */
  11611     _bcm_kt2_flex_config_set (unit, stat_array, stat_count);
  11612 
  11613     /*detaching and disabling the counter threads*/
  11614     rv = soc_counter_detach(unit);
  11615     BCM_IF_ERROR_RETURN(rv); 
  11616     
  11617     rv = soc_counter_attach(unit);
  11618     BCM_IF_ERROR_RETURN(rv);
  11619     if (SOC_IS_SABER2(unit)) {
  11620         SOC_IF_ERROR_RETURN(soc_saber2_perq_flex_counters_init(unit,drop_type));
  11621     } else {
  11622         SOC_IF_ERROR_RETURN(_soc_katana2_perq_flex_counters_init(unit,drop_type));
  11623     }
  11624 
  11625     /*starting  the counter thread*/
  11626     SOC_PBMP_CLEAR(pbmp);
  11627     for (port =  SOC_INFO(unit).cmic_port;
  11628                  port <= SOC_INFO(unit).lb_port;
  11629                  port++) {
  11630         if (SOC_IS_SABER2(unit) && (!SOC_IS_METROLITE(unit)) &&
  11631             soc_saber2_port_is_unused(unit, port)) {
  11632             continue;
  11633         }
  11634         if (SOC_INFO(unit).block_valid[SOC_PORT_BLOCK(unit,port)]) {
  11635             LOG_VERBOSE(BSL_LS_APPL_SHELL,
  11636                     (BSL_META_U(unit,
  11637                                 "BlockName:%s \n"),
  11638                      SOC_BLOCK_NAME(unit, SOC_PORT_BLOCK(unit,port))));
  11639             SOC_PBMP_PORT_ADD(pbmp, port);
  11640         }
  11641     }
  11642     interval = (SAL_BOOT_BCMSIM) ?
  11643                SOC_COUNTER_INTERVAL_SIM_DEFAULT : SOC_COUNTER_INTERVAL_DEFAULT;
  11644     interval = soc_property_get(unit, spn_BCM_STAT_INTERVAL, interval);
  11645     flags =
  11646         soc_property_get(unit, spn_BCM_STAT_FLAGS, SOC_COUNTER_F_DMA);
  11647 
  11648     rv = soc_counter_start(unit, flags, interval,pbmp); 
  11649     BCM_IF_ERROR_RETURN(rv); 
  11650     
  11651     /*reset all the previous configured counters*/
  11652     BCM_IF_ERROR_RETURN(_bcm_kt2_init_all_queue_counters(unit));
  11653     return BCM_E_NONE;
  11654 }
  11655 
  11656 
  11657 int bcm_kt2_cosq_stat_config_get (int unit, int stat_count,
  11658                                 bcm_cosq_stat_t  *stat_array)
  11659 {
  11660     _sb2_cosq_counter_mem_map_t *mem_map;
  11661     int num_elem, index = 0, elem_size = 4;
  11662     uint32 rval;
  11663     uint32 drop_type;
  11664     uint16 dev_id;
  11665     uint8 rev_id;
  11666 #ifdef BCM_KATANA2_SUPPORT
  11667     uint32 wred_drop_mask, default_drop_mask;
  11668 #endif
  11669     if (SOC_IS_SABER2(unit)) {
  11670         elem_size = 2;
  11671     }
  11672     soc_cm_get_id(unit, &dev_id, &rev_id);
  11673     if ((dev_id == BCM56233_DEVICE_ID) ||
  11674         (SOC_IS_METROLITE(unit))) {
  11675         elem_size = 1;
  11676     }
  11677 
  11678 #ifdef BCM_METROLITE_SUPPORT
  11679     if (SOC_IS_METROLITE(unit)) {
  11680         wred_drop_mask = BCM_ML_COSQ_WRED_DROP_MASK;
  11681         default_drop_mask = BCM_ML_COSQ_DEFAULT_DROP_MASK;
  11682     } else
  11683 #endif
  11684     {
  11685         wred_drop_mask = BCM_SB2_COSQ_WRED_DROP_MASK;
  11686         default_drop_mask = BCM_SB2_COSQ_DEFAULT_DROP_MASK;
  11687     }
  11688     if ((stat_array == NULL)|| (stat_count != BCM_SB2_COSQ_FLEX_COUNT_SUPPORTED)) {
  11689         return BCM_E_PARAM;
  11690     }
  11691     soc_sb2_cosq_counter_mem_map_get(unit, &num_elem, &mem_map);
  11692     
  11693     /*get the type of THDO counters configured */  
  11694     
  11695     SOC_IF_ERROR_RETURN(READ_THDO_DROP_CTR_CONFIGr(unit, &rval));
  11696     drop_type = soc_reg_field_get(unit, THDO_DROP_CTR_CONFIGr, rval, OP_DROP_MASKf); 
  11697 
  11698     for (index = 0; index < num_elem; index+= elem_size) {
  11699         switch (mem_map[index].non_dma_id) {
  11700             case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT:
  11701                 if ((drop_type & default_drop_mask) == wred_drop_mask ) {
  11702                     stat_array[index/elem_size] = bcmCosqStatDiscardDroppedPackets;
  11703                 } else {
  11704                     stat_array[index/elem_size] = bcmCosqStatDroppedPackets;
  11705                 }
  11706                 break;
  11707 
  11708             case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW:
  11709                 if ((drop_type & default_drop_mask) == wred_drop_mask) {
  11710                     stat_array[index/elem_size] = bcmCosqStatYellowDiscardDroppedPackets;
  11711                 } else {
  11712                     stat_array[index/elem_size] = bcmCosqStatYellowCongestionDroppedPackets;
  11713                 }
  11714                 break;
  11715 
  11716             case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED:
  11717                 if ((drop_type & default_drop_mask) == wred_drop_mask) {
  11718                     stat_array[index/elem_size] = bcmCosqStatRedDiscardDroppedPackets;
  11719                 } else {
  11720                     stat_array[index/elem_size] = bcmCosqStatRedCongestionDroppedPackets;
  11721                 }
  11722                 break;
  11723 
  11724             case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN:
  11725                 if ((drop_type & default_drop_mask) == wred_drop_mask) {
  11726                     stat_array[index/elem_size] = bcmCosqStatGreenDiscardDroppedPackets;
  11727                 }
  11728                 break;
  11729 
  11730             case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT:
  11731                 stat_array[index/elem_size] = bcmCosqStatOutPackets;
  11732                 break;
  11733             default:
  11734                 break;
  11735         }
  11736     }
  11737     return BCM_E_NONE;
  11738 }
  11739 
  11740 #endif
  11741 
  11742 int bcm_kt2_cosq_port_get(int unit, int queue_id, bcm_port_t *port) 
  11743 {
  11744     _bcm_kt2_mmu_info_t *mmu_info;
  11745     lls_l0_parent_entry_t l0_parent;
  11746     lls_l1_parent_entry_t l1_parent;
  11747     lls_l2_parent_entry_t l2_parent;
  11748     egr_queue_to_pp_port_map_entry_t pp_port_map;
  11749     int index;
  11750     int ctype;
  11751     int rv = BCM_E_NONE;
  11752 
  11753     if (_bcm_kt2_mmu_info[unit] == NULL) {
  11754         return BCM_E_INIT;
  11755     }
  11756 
  11757     mmu_info = _bcm_kt2_mmu_info[unit];
  11758     
  11759     if (queue_id >= mmu_info->num_queues) {
  11760         return BCM_E_PARAM;
  11761     }    
  11762 
  11763     SOC_IF_ERROR_RETURN
  11764         (READ_LLS_L2_PARENTm(unit, MEM_BLOCK_ALL, queue_id, &l2_parent));
  11765     index = soc_mem_field32_get(unit, LLS_L2_PARENTm, &l2_parent, C_PARENTf);
  11766 
  11767     SOC_IF_ERROR_RETURN
  11768             (READ_LLS_L1_PARENTm(unit, MEM_BLOCK_ALL, index, &l1_parent));
  11769     index = soc_mem_field32_get(unit, LLS_L1_PARENTm, &l1_parent, C_PARENTf);
  11770 
  11771     SOC_IF_ERROR_RETURN
  11772             (READ_LLS_L0_PARENTm(unit, MEM_BLOCK_ALL, index, &l0_parent));
  11773 
  11774     /*
  11775      * Ctype 1 indicates parent is a port, 0 indicates parent is an s1.
  11776      */
  11777     ctype  = soc_mem_field32_get(unit, LLS_L0_PARENTm, &l0_parent, C_TYPEf);;
  11778     if (ctype) {
  11779         *port = soc_mem_field32_get(unit, LLS_L0_PARENTm,
  11780                 &l0_parent, C_PARENTf);
  11781     } else {
  11782         /*
  11783          * Get the subport that this queue is associated with.
  11784          */
  11785         SOC_IF_ERROR_RETURN
  11786             (READ_EGR_QUEUE_TO_PP_PORT_MAPm(unit, MEM_BLOCK_ALL,
  11787                                             queue_id, &pp_port_map));
  11788         *port = soc_mem_field32_get(unit, EGR_QUEUE_TO_PP_PORT_MAPm,
  11789                 &pp_port_map, PP_PORTf);
  11790     }
  11791 
  11792     return rv;
  11793 }
  11794 
  11795 #ifdef BCM_WARM_BOOT_SUPPORT
  11796 
  11797 #define BCM_WB_VERSION_1_0                     SOC_SCACHE_VERSION(1,0)
  11798 #define BCM_WB_VERSION_1_1                     SOC_SCACHE_VERSION(1,1)
  11799 #define BCM_WB_VERSION_1_2                     SOC_SCACHE_VERSION(1,2)
  11800 #define BCM_WB_VERSION_1_3                     SOC_SCACHE_VERSION(1,3)
  11801 #define BCM_WB_VERSION_1_4                     SOC_SCACHE_VERSION(1,4)
  11802 #define BCM_WB_VERSION_1_5                     SOC_SCACHE_VERSION(1,5)
  11803 #define BCM_WB_VERSION_1_6                     SOC_SCACHE_VERSION(1,6)
  11804 #define BCM_WB_VERSION_1_7                     SOC_SCACHE_VERSION(1,7)
  11805 #define BCM_WB_VERSION_1_8                     SOC_SCACHE_VERSION(1,8)
  11806 #define BCM_WB_DEFAULT_VERSION                 BCM_WB_VERSION_1_8
  11807 
  11808 #define _BCM_KT2_COSQ_WB_END_NODE_VALUE         0xffffffff
  11809 
  11810 #define _BCM_KT2_COSQ_WB_NODE_COSQ_MASK         0x3f    /* LW-1 [5:0] */
  11811 #define _BCM_KT2_COSQ_WB_NODE_COSQ_SHIFT        0
  11812 #define _BCM_KT2_COSQ_WB_NODE_NUMQ_MASK         0x3f    /* LW-1 [11:6] */
  11813 #define _BCM_KT2_COSQ_WB_NODE_NUMQ_SHIFT        6
  11814 #define _BCM_KT2_COSQ_WB_NODE_HW_INDEX_MASK     0xfff   /* LW-1 [23:12] */
  11815 #define _BCM_KT2_COSQ_WB_NODE_HW_INDEX_SHIFT    12
  11816 #define _BCM_KT2_COSQ_WB_NODE_LEVEL_MASK        0x7     /* LW-1 [26:24] */
  11817 #define _BCM_KT2_COSQ_WB_NODE_LEVEL_SHIFT       24
  11818 #define _BCM_KT2_COSQ_WB_NODE_WRR_MASK          0x1     /* LW-1 [27] */
  11819 #define _BCM_KT2_COSQ_WB_NODE_WRR_SHIFT         27
  11820 #define _BCM_KT2_COSQ_WB_NODE_SUBPORT_MASK      0x1     /* LW-1 [28] */
  11821 #define _BCM_KT2_COSQ_WB_NODE_SUBPORT_SHIFT     28
  11822 #define _BCM_KT2_COSQ_WB_NODE_LINKPHY_MASK      0x1     /* LW-1 [29] */
  11823 #define _BCM_KT2_COSQ_WB_NODE_LINKPHY_SHIFT     29
  11824 #define _BCM_KT2_COSQ_WB_NODE_IDBASED_MASK      0x1     /* LW-1 [30] */
  11825 #define _BCM_KT2_COSQ_WB_NODE_IDBASED_SHIFT     30 
  11826 #define _BCM_KT2_COSQ_WB_NODE_NUMQ_MAX_MASK     0x1     /* LW-1 [31] */
  11827 #define _BCM_KT2_COSQ_WB_NODE_NUMQ_MAX_SHIFT    31
  11828 
  11829 #define _BCM_KT2_COSQ_WB_NUM_COS_MASK         0xf    /* [3:0] */
  11830 #define _BCM_KT2_COSQ_WB_NUM_COS_SHIFT        0
  11831 
  11832 #define _BCM_KT2_COSQ_WB_NODE_TYPE_MASK       0xf
  11833 #define _BCM_KT2_COSQ_WB_NODE_TYPE_SHIFT        0     /*[0:3] 8*/
  11834 #define _BCM_KT2_COSQ_WB_NODE_WRR_MODE_MASK   0x1
  11835 #define _BCM_KT2_COSQ_WB_NODE_WRR_MODE_SHIFT    4     /*[4]*/
  11836 #define _BCM_KT2_COSQ_WB_NODE_WRED_DISABLE_MASK   0x1
  11837 #define _BCM_KT2_COSQ_WB_NODE_WRED_DISABLE_SHIFT    5 /*[5]*/
  11838 #define _BCM_KT2_COSQ_WB_NODE_BW_BURST_CAL_MASK   0x1
  11839 #define _BCM_KT2_COSQ_WB_NODE_BW_BURST_CAL_SHIFT    6 /*[6]*/
  11840 
  11841 #define SET_FIELD(_field, _value)                       \
  11842     (((_value) & _BCM_KT2_COSQ_WB_## _field## _MASK) <<  \
  11843      _BCM_KT2_COSQ_WB_## _field## _SHIFT)
  11844 #define GET_FIELD(_field, _byte)                        \
  11845     (((_byte) >> _BCM_KT2_COSQ_WB_## _field## _SHIFT) &  \
  11846      _BCM_KT2_COSQ_WB_## _field## _MASK)
  11847 
  11848 #define _BCM_KT2_NODE_TYPE_WRR_SET(ptr, node)  \
  11849     do {*((uint8 *)ptr) = node->type; \
  11850      *((uint8 *)ptr) |= (node->wrr_mode << _BCM_KT2_COSQ_WB_NODE_WRR_MODE_SHIFT);\
  11851     }while(0);
  11852 
  11853 #define _BCM_KT2_NODE_WRED_DISABLE_SET(ptr, node)  \
  11854     do {\
  11855      *((uint8 *)ptr) |= ((node->wred_disabled & _BCM_KT2_COSQ_WB_NODE_WRED_DISABLE_MASK)\
  11856       << _BCM_KT2_COSQ_WB_NODE_WRED_DISABLE_SHIFT);\
  11857     }while(0);
  11858 
  11859 #define _BCM_KT2_NODE_BW_BURST_CAL_SET(ptr, node)  \
  11860     do {\
  11861      *((uint8 *)ptr) |= ((node->burst_calculation_enable & _BCM_KT2_COSQ_WB_NODE_BW_BURST_CAL_MASK)\
  11862       << _BCM_KT2_COSQ_WB_NODE_BW_BURST_CAL_SHIFT);\
  11863     }while(0);
  11864 
  11865 #define _BCM_KT2_NODE_TYPE_WRR_GET(ptr, node)   \
  11866     do { node->type = ((*(uint8 *)ptr) & _BCM_KT2_COSQ_WB_NODE_TYPE_MASK); \
  11867       node->wrr_mode = ((*(uint8 *)ptr) >>  _BCM_KT2_COSQ_WB_NODE_WRR_MODE_SHIFT);\
  11868     }while(0); 
  11869 
  11870 #define _BCM_KT2_NODE_WRED_DISABLE_GET(ptr, node)   \
  11871     do {\
  11872       node->wred_disabled  = (((*(uint8 *)ptr) >>  _BCM_KT2_COSQ_WB_NODE_WRED_DISABLE_SHIFT) \
  11873                               & _BCM_KT2_COSQ_WB_NODE_WRED_DISABLE_MASK);\
  11874     }while(0);
  11875 
  11876 #define _BCM_KT2_NODE_BW_BURST_CAL_GET(ptr, node)   \
  11877     do {\
  11878       node->burst_calculation_enable  = (((*(uint8 *)ptr) >>  _BCM_KT2_COSQ_WB_NODE_BW_BURST_CAL_SHIFT) \
  11879                               & _BCM_KT2_COSQ_WB_NODE_BW_BURST_CAL_MASK);\
  11880     }while(0);
  11881 
  11882 /*
  11883  * This funtion encodes the 1 byte of the common  data to be written in to
  11884  * scache.Currently only last 4 bits of the byte are used for storing
  11885  * num_cos value rest can be used if necessary later.
  11886  */
  11887 STATIC void
  11888 _bcm_kt2_cosq_wb_encode_data(int unit, uint8 *scache_ptr)
  11889  {
  11890      uint8 data = 0;
  11891      int numq = 0;
  11892      bcm_kt2_cosq_config_get(unit,&numq);
  11893      data  = SET_FIELD(NUM_COS, numq);
  11894      *scache_ptr = data;
  11895 }
  11896 
  11897 STATIC int
  11898 _bcm_kt2_cosq_wb_alloc(int unit)
  11899 {
  11900     soc_scache_handle_t scache_handle;
  11901     uint8 *scache_ptr;
  11902     _bcm_kt2_mmu_info_t *mmu_info;
  11903     int rv, alloc_size;
  11904 
  11905     mmu_info = _bcm_kt2_mmu_info[unit];
  11906 
  11907     alloc_size = 0;
  11908     alloc_size += sizeof(mmu_info->num_base_queues);
  11909     alloc_size += sizeof(mmu_info->num_ext_queues);
  11910     alloc_size += sizeof(mmu_info->qset_size);
  11911     alloc_size += sizeof(mmu_info->num_queues);
  11912     alloc_size += sizeof(mmu_info->num_nodes);
  11913     alloc_size += sizeof(mmu_info->max_nodes);
  11914     alloc_size += (num_total_schedulers[unit] * sizeof(uint32) * 3);
  11915     alloc_size += (num_l2_queues[unit] * sizeof(uint32) * 2);
  11916     alloc_size += sizeof(uint32);
  11917 
  11918     /* Following is the addition memory for Version 1_1 */
  11919 
  11920     /* Allocating memory for storing fabric_pbmp and we require
  11921      fabric_pbmp only for l2 nodes*/ 
  11922     alloc_size += (num_l2_queues[unit] * sizeof(bcm_pbmp_t));
  11923     /* Allocating memory for storing remote_modid and we require
  11924      remote_modid only for l2 nodes*/ 
  11925     alloc_size += (num_l2_queues[unit] * sizeof(uint32));
  11926     /* Allocating memory for storing fabric_modid and we require
  11927        fabric_modid only for l2 nodes*/ 
  11928     alloc_size += (num_l2_queues[unit] * sizeof(uint32));
  11929     /* Allocating memory for storing curr_merger_index */
  11930     alloc_size += (4 * sizeof(int));
  11931     /* Storing the _BCM_KT2_COSQ_WB_END_NODE_VALUE */
  11932     alloc_size += sizeof(uint32);
  11933     /* Storing NUM_COS */
  11934     alloc_size += sizeof(uint8);
  11935 
  11936     /* Allocating memory for storing the multicast mc base index
  11937        for the L1 nodes*/
  11938     alloc_size += (num_l1_schedulers[unit] * sizeof(uint32));
  11939     /* Storing the _BCM_KT2_COSQ_WB_END_NODE_VALUE */
  11940     alloc_size += sizeof(uint32);
  11941    /* Allocating memory for storing the IFP_COS_MAP refcount */
  11942     alloc_size += (4 * sizeof(uint32));
  11943     /* Storing the _BCM_KT2_COSQ_WB_END_NODE_VALUE */
  11944     alloc_size += sizeof(uint32);
  11945    
  11946     /*Storing the COSQ_STAT_CONFIG*/ 
  11947     alloc_size += (sizeof(bcm_cosq_stat_t)* 3);
  11948 
  11949     /*Storing the node data*/
  11950     alloc_size += sizeof(uint8)*(num_total_schedulers[unit] + num_l2_queues[unit]);
  11951     
  11952     /* Storing interface reference count for all queues */
  11953     alloc_size += (BCM_MULTICAST_PORT_MAX * sizeof(uint32));
  11954 
  11955     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COSQ, 0);
  11956     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, alloc_size,
  11957                                  &scache_ptr, BCM_WB_DEFAULT_VERSION, NULL);
  11958     if (rv == BCM_E_NOT_FOUND) {
  11959         rv = BCM_E_NONE;
  11960     }
  11961 
  11962     return rv;
  11963 }
  11964 
  11965 STATIC uint32
  11966 _bcm_kt2_cosq_wb_encode_node(int unit, _bcm_kt2_cosq_node_t *node)
  11967 {
  11968     uint32 data = 0;
  11969     int max_numq;
  11970 
  11971     data  = SET_FIELD(NODE_COSQ, node->cosq_attached_to);
  11972     data |= SET_FIELD(NODE_NUMQ, node->numq);
  11973     max_numq = ((1 << _BCM_KT2_COSQ_WB_NODE_NUMQ_SHIFT) - 1);
  11974     if (node->numq > max_numq) {
  11975         data |= SET_FIELD(NODE_NUMQ_MAX, 1);
  11976     }
  11977     data |= SET_FIELD(NODE_LEVEL, node->level);
  11978     data |= SET_FIELD(NODE_HW_INDEX, node->hw_index);
  11979     data |= SET_FIELD(NODE_WRR, node->wrr_in_use);
  11980     data |= SET_FIELD(NODE_SUBPORT, node->subport_enabled);
  11981     data |= SET_FIELD(NODE_LINKPHY, node->linkphy_enabled);
  11982     if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L2) {
  11983         if ((node->type == _BCM_KT2_NODE_VOQ_ID) ||
  11984             (node->type == _BCM_KT2_NODE_SUBSCRIBER_GPORT_ID)) {
  11985             data |= SET_FIELD(NODE_IDBASED, 1);
  11986         }
  11987     }
  11988     
  11989     return data;
  11990 }
  11991 
  11992 STATIC int
  11993 _bcm_kt2_cosq_update_scache(int unit, uint8 *scache_ptr, 
  11994                             _bcm_kt2_cosq_node_t *node, int *length)
  11995 {
  11996     uint8 *ptr;
  11997     uint32 node_data;
  11998     bcm_gport_t sub_gport = 0;
  11999     int id;
  12000     int port = 0;
  12001     _bcm_kt2_mmu_info_t *mmu_info;
  12002 
  12003     ptr = scache_ptr;
  12004     mmu_info = _bcm_kt2_mmu_info[unit];
  12005 
  12006     if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)){
  12007         id = BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(node->gport);
  12008         if(mmu_info->num_sub_queues) {
  12009             id += mmu_info->base_sub_queue;
  12010         }
  12011         port = BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_SYSPORTID_GET(node->gport);
  12012         BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_SYSQID_SET(sub_gport, port, id);
  12013         *(((uint32 *)ptr)) = sub_gport;
  12014         ptr += sizeof(uint32);
  12015     } else if (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport)){
  12016         id = BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(node->gport);
  12017         if(mmu_info->num_sub_queues) {
  12018             id += mmu_info->base_sub_queue;
  12019         }
  12020         port =
  12021         BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_SYSPORTID_GET(node->gport);
  12022         BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_SYSQID_SET(sub_gport, port, id);
  12023         *(((uint32 *)ptr)) = sub_gport;
  12024         ptr += sizeof(uint32);
  12025     } else {
  12026         *(((uint32 *)ptr)) = node->gport;
  12027         ptr += sizeof(uint32);
  12028     }
  12029             
  12030     node_data = _bcm_kt2_cosq_wb_encode_node(unit, node);
  12031     *(((uint32 *)ptr)) = node_data;
  12032     ptr += sizeof(uint32);
  12033 
  12034     if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2) {
  12035         *(((uint32 *)ptr)) = node->base_index;
  12036         ptr += sizeof(uint32);
  12037     }
  12038 
  12039     *length = ptr - scache_ptr;
  12040     return BCM_E_NONE;
  12041 }
  12042 
  12043 STATIC int
  12044 _bcm_kt2_cosq_update_l0_tree(int unit, uint8 *scache_ptr, 
  12045                               _bcm_kt2_cosq_node_t *node, 
  12046                              int *length)
  12047 {
  12048     uint8 *ptr;
  12049     _bcm_kt2_cosq_node_t *l0_node, *l1_node, *l2_node;
  12050     int inc;
  12051 
  12052     ptr = scache_ptr;
  12053 
  12054     for (l0_node = node; l0_node != NULL;
  12055          l0_node = l0_node->sibling) {
  12056         BCM_IF_ERROR_RETURN
  12057             (_bcm_kt2_cosq_update_scache(unit, ptr, l0_node, &inc));
  12058         ptr += inc;
  12059 
  12060         for (l1_node = l0_node->child; l1_node != NULL;
  12061              l1_node = l1_node->sibling) {
  12062             BCM_IF_ERROR_RETURN
  12063                 (_bcm_kt2_cosq_update_scache(unit, ptr, l1_node, &inc));
  12064             ptr += inc;
  12065                 
  12066             for (l2_node = l1_node->child; l2_node != NULL;
  12067                  l2_node = l2_node->sibling) {
  12068                 BCM_IF_ERROR_RETURN
  12069                     (_bcm_kt2_cosq_update_scache(unit, ptr, l2_node, &inc));
  12070                 ptr += inc;
  12071             }
  12072         }
  12073     }
  12074 
  12075     *length = ptr - scache_ptr;
  12076     return BCM_E_NONE;
  12077 }
  12078 
  12079 
  12080 int
  12081 bcm_kt2_cosq_sync(int unit)
  12082 {
  12083     soc_scache_handle_t scache_handle;
  12084     uint8 *scache_ptr, *ptr;
  12085     _bcm_kt2_mmu_info_t *mmu_info;
  12086     _bcm_kt2_cosq_node_t *port_node, *l0_node;
  12087     _bcm_kt2_cosq_node_t *s0_node, *s1_node;
  12088     bcm_port_t port;
  12089     int i, inc;
  12090     _bcm_kt2_cosq_node_t *l1_node, *l2_node;
  12091     soc_info_t *si;
  12092     uint32 profile_index;
  12093     int ref_count;
  12094 
  12095 #ifdef BCM_KATANA2_SUPPORT      
  12096     bcm_cosq_stat_t stat_array[BCM_SB2_COSQ_FLEX_COUNT_SUPPORTED];
  12097 #endif
  12098     si = &SOC_INFO(unit);
  12099     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COSQ, 0);
  12100     BCM_IF_ERROR_RETURN
  12101         (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 0,
  12102                                  &scache_ptr, BCM_WB_DEFAULT_VERSION, NULL));
  12103 
  12104     if (_bcm_kt2_mmu_info[unit] == NULL) {
  12105         return BCM_E_INIT;
  12106     }
  12107 
  12108     mmu_info = _bcm_kt2_mmu_info[unit];
  12109 
  12110     ptr = scache_ptr;
  12111 
  12112     *(((uint32 *)ptr)) = mmu_info->num_base_queues;
  12113     ptr += sizeof(uint32);
  12114 
  12115 
  12116     *(((uint32 *)ptr)) = mmu_info->num_ext_queues;
  12117     ptr += sizeof(uint32);
  12118 
  12119     *(((uint32 *)ptr)) = mmu_info->qset_size;
  12120     ptr += sizeof(uint32);
  12121 
  12122     *(((uint32 *)ptr)) = mmu_info->num_queues;
  12123     ptr += sizeof(uint32);
  12124 
  12125     *(((uint32 *)ptr)) = mmu_info->num_nodes;
  12126     ptr += sizeof(uint32);
  12127 
  12128     for (i = 0; i < _BCM_KT2_COSQ_NODE_LEVEL_MAX; i++) {
  12129         *(((uint32 *)ptr)) = mmu_info->max_nodes[i];
  12130         ptr += sizeof(uint32);
  12131     }
  12132 
  12133     for (port = 0; port < (si->lb_port + 1) ; port++) {
  12134         if (SOC_IS_SABER2(unit) && (!SOC_IS_METROLITE(unit)) &&
  12135             soc_saber2_port_is_unused(unit, port)) {
  12136             continue;
  12137         }
  12138         port_node = &mmu_info->sched_node[port];
  12139 
  12140         if (port_node->cosq_attached_to < 0) {
  12141             continue;
  12142         }
  12143 
  12144         if (port_node->child != NULL) {
  12145             BCM_IF_ERROR_RETURN
  12146                 (_bcm_kt2_cosq_update_scache(unit, ptr, port_node, &inc));
  12147             ptr += inc;
  12148         }
  12149 
  12150         s0_node = port_node->child;
  12151         if (s0_node != NULL && 
  12152                 s0_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
  12153             for (s0_node = port_node->child; s0_node != NULL;
  12154                     s0_node = s0_node->sibling) {
  12155                 BCM_IF_ERROR_RETURN
  12156                     (_bcm_kt2_cosq_update_scache(unit, ptr, s0_node, &inc));
  12157                 ptr += inc;
  12158 
  12159                 s1_node = s0_node->child;
  12160                 if (s1_node != NULL && 
  12161                         s1_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) {
  12162                     for (s1_node = s0_node->child; s1_node != NULL;
  12163                             s1_node = s1_node->sibling) {
  12164                         BCM_IF_ERROR_RETURN
  12165                             (_bcm_kt2_cosq_update_scache(unit, ptr, s1_node, &inc));
  12166                         ptr += inc;
  12167                         for (l0_node = s1_node->child; l0_node != NULL;
  12168                                 l0_node = l0_node->sibling) {
  12169                             BCM_IF_ERROR_RETURN
  12170                                 (_bcm_kt2_cosq_update_l0_tree(unit, ptr, l0_node, &inc));
  12171                             ptr += inc;
  12172                         }
  12173                     }
  12174                 } else {
  12175                     l0_node = s1_node;
  12176                     BCM_IF_ERROR_RETURN
  12177                         (_bcm_kt2_cosq_update_l0_tree(unit, ptr, l0_node, &inc));
  12178                     ptr += inc;
  12179                 }
  12180             }
  12181         } else {
  12182             l0_node = port_node->child;
  12183             BCM_IF_ERROR_RETURN
  12184                 (_bcm_kt2_cosq_update_l0_tree(unit, ptr, l0_node, &inc));
  12185             ptr += inc;
  12186         }
  12187     }
  12188 
  12189     *(((uint32 *)ptr)) = _BCM_KT2_COSQ_WB_END_NODE_VALUE;
  12190 
  12191     ptr += sizeof(uint32) ;
  12192 
  12193     for (i = 0; i < 4; i++) {
  12194         *(((uint32 *)ptr)) = mmu_info->curr_merger_index[i];
  12195         ptr += sizeof(uint32);
  12196     }
  12197 
  12198     PBMP_ALL_ITER(unit, port) {
  12199         if (!(IS_HG_PORT(unit, port)|| IS_HL_PORT(unit, port))) {
  12200             continue;
  12201         }
  12202         port_node = &mmu_info->sched_node[port];
  12203 
  12204         if (port_node->cosq_attached_to < 0) {
  12205             continue;
  12206         }
  12207 
  12208         s0_node = port_node->child;
  12209         if (s0_node != NULL && 
  12210                 s0_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
  12211             continue;
  12212         } else {
  12213             l0_node = port_node->child;
  12214             for (; l0_node != NULL;
  12215                     l0_node = l0_node->sibling) {
  12216                 for (l1_node = l0_node->child; l1_node != NULL;
  12217                         l1_node = l1_node->sibling) {
  12218                     for (l2_node = l1_node->child; l2_node != NULL;
  12219                             l2_node = l2_node->sibling) {
  12220                         sal_memcpy(ptr, &l2_node->fabric_pbmp, sizeof(bcm_pbmp_t));
  12221                         ptr += sizeof(bcm_pbmp_t);
  12222                         *(((uint32 *)ptr)) = l2_node->remote_modid;
  12223                         ptr += sizeof(uint32);
  12224                         *(((uint32 *)ptr)) = l2_node->fabric_modid;
  12225                         ptr += sizeof(uint32);
  12226                     }
  12227                 }
  12228             }
  12229         }
  12230     }
  12231     *(((uint32 *)ptr)) = _BCM_KT2_COSQ_WB_END_NODE_VALUE;
  12232     ptr += sizeof(uint32);
  12233 
  12234     /* add NUM_COS to the scache */
  12235     _bcm_kt2_cosq_wb_encode_data( unit, (uint8 *)ptr);
  12236     ptr += sizeof(uint8);
  12237 
  12238     /* Store the mc base index for L1 node */
  12239     PBMP_ALL_ITER(unit, port) {
  12240 #ifdef BCM_METROLITE_SUPPORT
  12241         if (SOC_IS_METROLITE(unit)) {
  12242             if((soc_property_get(unit, spn_SAT_ENABLE, 0) != 0) &&
  12243                (port == SOC_SB2_SAT_OAMP_PHY_PORT_NUMBER)) {
  12244                /* no need to store SAT port*/
  12245                continue;
  12246             }
  12247         }
  12248 #endif
  12249         port_node = &mmu_info->sched_node[port];
  12250 
  12251         if (port_node->cosq_attached_to < 0) {
  12252             continue;
  12253         }
  12254         if (!port_node->child) {
  12255             continue;
  12256         }
  12257         s0_node = (port_node->child->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) ?
  12258             port_node->child : port_node;
  12259 
  12260         do {
  12261             s1_node = (s0_node->child->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) ?
  12262                 s0_node->child : s0_node;
  12263             do {
  12264                 for (l0_node = s1_node->child;
  12265                         l0_node != NULL;
  12266                         l0_node = l0_node->sibling) {
  12267                     for (l1_node = l0_node->child;
  12268                             l1_node != NULL;
  12269                             l1_node = l1_node->sibling) {
  12270                         *(((uint32 *)ptr)) =  l1_node->mc_base_index;
  12271                         ptr += sizeof(uint32);
  12272 
  12273                     }
  12274                 }
  12275                 if (s1_node == s0_node) {
  12276                     break;
  12277                 }
  12278                 /* It comes here
  12279                    only in case s1 is valid */
  12280                 s1_node = s1_node->sibling;
  12281             } while (s1_node != NULL);
  12282             if (s0_node == port_node) {
  12283                 break;
  12284             }
  12285             /* It comes here
  12286                only in case s0 is valid */
  12287             s0_node = s0_node->sibling;
  12288         } while (s0_node != NULL);
  12289 
  12290     }
  12291 
  12292     *(((uint32 *)ptr)) = _BCM_KT2_COSQ_WB_END_NODE_VALUE;
  12293 
  12294     ptr += sizeof(uint32);
  12295     for (profile_index = 0 ; profile_index < 4 ; profile_index++) {
  12296         BCM_IF_ERROR_RETURN (soc_profile_mem_ref_count_get(unit,
  12297                     _bcm_kt2_ifp_cos_map_profile[unit],
  12298                     (profile_index * 16), &ref_count));
  12299         *(((uint32 *)ptr)) = ref_count;
  12300         ptr += sizeof(uint32);
  12301     }
  12302 
  12303     *(((uint32 *)ptr)) = _BCM_KT2_COSQ_WB_END_NODE_VALUE;
  12304 
  12305     /*saving the counter values*/
  12306 #ifdef BCM_KATANA2_SUPPORT 
  12307     if (SOC_IS_KATANA2(unit)) {
  12308         bcm_kt2_cosq_stat_config_get(unit, BCM_SB2_COSQ_FLEX_COUNT_SUPPORTED, stat_array);
  12309         for (profile_index = 0; profile_index < 3; profile_index++) {
  12310             *(((uint32 *)ptr)) = stat_array[profile_index];
  12311             ptr += sizeof(uint32);
  12312         }
  12313     }
  12314     else {
  12315         ptr += (sizeof(uint32) * 3);
  12316     }
  12317 #else
  12318     ptr += (sizeof(uint32) * 3);
  12319 #endif
  12320 
  12321     PBMP_ALL_ITER(unit, port) {
  12322         port_node = &mmu_info->sched_node[port];
  12323         if (port_node->cosq_attached_to < 0) {
  12324             continue;
  12325         }
  12326         _BCM_KT2_NODE_TYPE_WRR_SET(ptr, port_node);
  12327         _BCM_KT2_NODE_BW_BURST_CAL_SET(ptr, port_node);
  12328         ptr += sizeof(uint8);
  12329         s0_node = port_node->child;
  12330         if (s0_node != NULL && 
  12331                 s0_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
  12332             continue;
  12333         } else {
  12334             /*copy the node type to the node*/
  12335             for (l0_node = port_node->child;l0_node != NULL;
  12336                     l0_node = l0_node->sibling) {
  12337                 /*copy the node type to the node*/
  12338                 _BCM_KT2_NODE_TYPE_WRR_SET(ptr, l0_node);
  12339                 _BCM_KT2_NODE_BW_BURST_CAL_SET(ptr, port_node);
  12340                 ptr += sizeof(uint8);
  12341                 for (l1_node = l0_node->child; l1_node != NULL;
  12342                         l1_node = l1_node->sibling) {
  12343                     /*copy the node type to the node*/
  12344                     _BCM_KT2_NODE_TYPE_WRR_SET(ptr, l1_node);
  12345                     _BCM_KT2_NODE_BW_BURST_CAL_SET(ptr, port_node);
  12346                     ptr += sizeof(uint8);
  12347                     for (l2_node = l1_node->child; l2_node != NULL;
  12348                             l2_node = l2_node->sibling) {
  12349                         /*copy the node type to the node*/
  12350                         _BCM_KT2_NODE_TYPE_WRR_SET(ptr,l2_node);
  12351                         _BCM_KT2_NODE_BW_BURST_CAL_SET(ptr, port_node);
  12352                         _BCM_KT2_NODE_WRED_DISABLE_SET(ptr,l2_node);
  12353                         ptr += sizeof(uint8);
  12354                     }
  12355                 }
  12356             }
  12357         }    
  12358     }
  12359 
  12360     /* copy interface reference count values for all queues into scache ptr */
  12361     sal_memcpy(ptr, mmu_info->intf_ref_cnt,
  12362                (sizeof(uint32) * BCM_MULTICAST_PORT_MAX));
  12363     ptr += (sizeof(uint32) * BCM_MULTICAST_PORT_MAX);
  12364     return BCM_E_NONE; 
  12365 }
  12366 
  12367 /*
  12368  * Function:
  12369  *     _bcm_kt2_cosq_map_alloc_set
  12370  * Purpose:
  12371  *     Allocate the cosq_map bitmap and 
  12372  *     restore  
  12373  * Parameters:
  12374  *     node       - (IN) cosq_node 
  12375  * Returns:
  12376  *     BCM_E_XXX
  12377  */
  12378 STATIC int
  12379 _bcm_kt2_cosq_map_alloc_set(_bcm_kt2_cosq_node_t *node)
  12380 {
  12381     _bcm_kt2_cosq_node_t *child;
  12382     int alloc_size;
  12383     if (node->cosq_map == NULL) {
  12384         alloc_size = SHR_BITALLOCSIZE(node->numq);
  12385         node->cosq_map = _bcm_kt2_cosq_alloc_clear(alloc_size,
  12386                                            "node->cosq_map");
  12387         if (node->cosq_map == NULL) {
  12388             return BCM_E_MEMORY;
  12389         }
  12390     }
  12391     child = node->child;
  12392     while (child != NULL) {
  12393         BCM_IF_ERROR_RETURN
  12394             (_bcm_kt2_cosq_map_index_set(node->cosq_map, 
  12395                                          child->cosq_attached_to, 1));
  12396         child = child->sibling;
  12397     }
  12398 
  12399     return BCM_E_NONE;
  12400 }
  12401 
  12402 /*
  12403  * Function:
  12404  *     _bcm_kt2_cosq_map_recover_next_level_node  
  12405  * Purpose:
  12406  *     Used to recover cos_map for S0,S1,L0,L1 levels   
  12407  * Parameters:
  12408  *     node       - (IN) cosq_node 
  12409  * Returns:
  12410  *     BCM_E_XXX
  12411  */
  12412 
  12413 STATIC int
  12414 _bcm_kt2_cosq_map_recover_next_level_node(_bcm_kt2_cosq_node_t *node) 
  12415 {
  12416     if (!node) {
  12417         return BCM_E_NONE;
  12418     }
  12419     if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L2) {
  12420         return BCM_E_NONE;
  12421     }
  12422     BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_map_alloc_set(node));
  12423     BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_map_recover_next_level_node(node->sibling));
  12424     BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_map_recover_next_level_node(node->child));
  12425     return BCM_E_NONE;
  12426 }
  12427 
  12428 int
  12429 bcm_kt2_cosq_reinit(int unit)
  12430 {
  12431     soc_scache_handle_t scache_handle;
  12432     uint8 *scache_ptr, *ptr;
  12433     _bcm_kt2_cosq_node_t *port_info;
  12434     _bcm_kt2_mmu_info_t *mmu_info;
  12435     _bcm_kt2_cosq_node_t *port_node = NULL;
  12436     _bcm_kt2_cosq_node_t *queue_node = NULL;
  12437     _bcm_kt2_cosq_node_t *node = NULL;
  12438     _bcm_kt2_cosq_node_t *temp_node = NULL;
  12439     _bcm_kt2_cosq_node_t *s0_node = NULL;
  12440     _bcm_kt2_cosq_node_t *s1_node = NULL;
  12441     _bcm_kt2_cosq_node_t *l0_node = NULL;
  12442     _bcm_kt2_cosq_node_t *l1_node = NULL;
  12443     _bcm_kt2_cosq_node_t *tmp_node = NULL;
  12444     uint32 *s0_bmap = NULL;
  12445     uint32 *s1_bmap = NULL;
  12446     uint32 *l0_bmap = NULL;
  12447     uint32 *l1_bmap = NULL;
  12448     uint32 *l2_bmap = NULL;
  12449     int additional_scache_size = 0;
  12450     int rv, stable_size = 0;
  12451     bcm_port_t port = 0;
  12452     bcm_gport_t gport;
  12453     int i, index, numq;
  12454     uint32 node_data;
  12455     uint32 encap_id;
  12456     int set_index, cosq;
  12457     uint32 entry[SOC_MAX_MEM_WORDS];
  12458     soc_profile_mem_t *profile_mem;
  12459     _bcm_kt2_cosq_list_t *list;
  12460     _bcm_kt2_cosq_node_t *l2_node;
  12461     soc_mem_t mem;
  12462     mmu_wred_queue_config_buffer_entry_t qentry;
  12463     mmu_wred_queue_config_qentry_entry_t qentry1;
  12464     int cpu_hg_index = 0;
  12465     bcm_pbmp_t all_pbmp;
  12466     bcm_port_t tmp_port = 0;
  12467     bcm_gport_t tmp_gport = 0;
  12468     uint16 recovered_ver = 0;
  12469     int offset = 0;
  12470     int node_id_based = 0;
  12471     uint8 data;
  12472     int num_cos = 0;
  12473     soc_profile_reg_t *profile_reg;
  12474     soc_reg_t reg;
  12475     uint64 rval,index_map; 
  12476     int mmu_port = 0 ;
  12477     uint32  tmp32;
  12478     int max_numq;
  12479     uint32 refcount = 0, profile_index;
  12480 #ifdef BCM_KATANA2_SUPPORT
  12481     bcm_cosq_stat_t stat_array[BCM_SB2_COSQ_FLEX_COUNT_SUPPORTED];
  12482 #endif
  12483 #ifdef BCM_METROLITE_SUPPORT
  12484     uint32 rval32, index_map32;
  12485 #endif
  12486     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
  12487     if ((stable_size == 0) || (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) {
  12488         /* COSQ warmboot requires extended scache support i.e. level2 warmboot*/
  12489         return BCM_E_NONE;
  12490     }
  12491 
  12492     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COSQ, 0);
  12493     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 0, &scache_ptr,
  12494             BCM_WB_DEFAULT_VERSION,  &recovered_ver);
  12495     if (BCM_FAILURE(rv)) {
  12496         return rv;
  12497     }
  12498 
  12499     if (_bcm_kt2_mmu_info[unit] == NULL) {
  12500         return BCM_E_INIT;
  12501     }
  12502 
  12503     mmu_info = _bcm_kt2_mmu_info[unit];
  12504 
  12505     ptr = scache_ptr;
  12506 
  12507     mmu_info->num_base_queues = *(((uint32 *)ptr));
  12508     ptr += sizeof(uint32);
  12509 
  12510 
  12511     mmu_info->num_ext_queues = *(((uint32 *)ptr));
  12512     ptr += sizeof(uint32);
  12513 
  12514     mmu_info->qset_size = *(((uint32 *)ptr));
  12515     ptr += sizeof(uint32);
  12516 
  12517     mmu_info->num_queues = *(((uint32 *)ptr));
  12518     ptr += sizeof(uint32);
  12519 
  12520     mmu_info->num_nodes = *(((uint32 *)ptr));
  12521     ptr += sizeof(uint32);
  12522 
  12523     for (i = 0; i < _BCM_KT2_COSQ_NODE_LEVEL_MAX; i++) {
  12524         mmu_info->max_nodes[i] = *(((uint32 *)ptr));
  12525         ptr += sizeof(uint32);
  12526     }
  12527 
  12528     while (*(((uint32 *)ptr)) != _BCM_KT2_COSQ_WB_END_NODE_VALUE) {
  12529         gport = *(((uint32 *)ptr));
  12530         ptr += sizeof(uint32);
  12531         node_data = *(((uint32 *)ptr));
  12532         ptr += sizeof(uint32);
  12533 
  12534         if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  12535             tmp_port = 0;
  12536             tmp_gport = 0;
  12537 
  12538             if (mmu_info->num_sub_queues ==0)  {
  12539                 list = &mmu_info->global_qlist;
  12540             } else {
  12541                 list = &mmu_info->sub_qlist;
  12542             }
  12543             encap_id = BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(gport);
  12544             node = &mmu_info->queue_node[encap_id];
  12545 
  12546             if (mmu_info->num_sub_queues)  {
  12547                 encap_id -= mmu_info->base_sub_queue;
  12548             }
  12549             tmp_port = BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_SYSPORTID_GET(gport);
  12550             BCM_GPORT_UCAST_SUBSCRIBER_QUEUE_GROUP_SYSQID_SET(tmp_gport, tmp_port, encap_id);
  12551             gport = tmp_gport;
  12552          } else if (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  12553             tmp_port = 0;
  12554             tmp_gport = 0;
  12555             if (mmu_info->num_sub_queues ==0)  {
  12556                 list = &mmu_info->global_qlist;
  12557             } else {
  12558                 list = &mmu_info->sub_mcqlist;
  12559             }
  12560             encap_id = BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_QID_GET(gport);
  12561             node = &mmu_info->queue_node[encap_id];
  12562 
  12563             if (mmu_info->num_sub_queues)  {
  12564                 encap_id = encap_id - mmu_info->base_sub_queue - mmu_info->num_queues/2;
  12565             }
  12566             tmp_port =
  12567             BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_SYSPORTID_GET(gport);
  12568             BCM_GPORT_MCAST_SUBSCRIBER_QUEUE_GROUP_SYSQID_SET(tmp_gport,
  12569                                                      tmp_port, encap_id);
  12570             gport = tmp_gport;
  12571             _bcm_kt2_node_index_set(list, encap_id, 1);
  12572         } else if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
  12573             encap_id = BCM_GPORT_UCAST_QUEUE_GROUP_QID_GET(gport);
  12574             node = &mmu_info->queue_node[encap_id]; 
  12575         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
  12576             encap_id = BCM_GPORT_MCAST_QUEUE_GROUP_QID_GET(gport);
  12577             node = &mmu_info->queue_node[encap_id];        
  12578         } else if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport)) {
  12579             encap_id = BCM_GPORT_DESTMOD_QUEUE_GROUP_QID_GET(gport);
  12580             if (mmu_info->num_dmvoq_queues ==0)  { 
  12581                 list = &mmu_info->global_qlist;
  12582             } else {
  12583                 list = &mmu_info->dmvoq_qlist;
  12584             }
  12585             if (mmu_info->num_dmvoq_queues == 1)  {
  12586                 encap_id += mmu_info->base_dmvoq_queue;
  12587             }
  12588             node = &mmu_info->queue_node[encap_id];
  12589         } else {
  12590             encap_id = (BCM_GPORT_SCHEDULER_GET(gport) >> 8) & 0x7ff;
  12591             if (encap_id == 0) {
  12592                 encap_id = (BCM_GPORT_SCHEDULER_GET(gport) & 0xff);
  12593             }
  12594             list = &mmu_info->sched_list;
  12595             _bcm_kt2_node_index_set(list, encap_id, 1);
  12596             node = &mmu_info->sched_node[encap_id]; 
  12597             node->first_child = 4095;
  12598             node->base_index = *(((uint32 *)ptr));
  12599             ptr += sizeof(uint32);
  12600         }
  12601 
  12602         node->gport = gport;
  12603         node->numq  = GET_FIELD(NODE_NUMQ, node_data);
  12604         node->cosq_attached_to = GET_FIELD(NODE_COSQ, node_data);
  12605         node->level = GET_FIELD(NODE_LEVEL, node_data);
  12606         node->hw_index = GET_FIELD(NODE_HW_INDEX, node_data);
  12607         node->wrr_in_use = GET_FIELD(NODE_WRR, node_data);
  12608         node->subport_enabled = GET_FIELD(NODE_SUBPORT, node_data);
  12609         node->linkphy_enabled = GET_FIELD(NODE_LINKPHY, node_data);
  12610         node_id_based = GET_FIELD(NODE_IDBASED, node_data);
  12611 
  12612         switch (node->level) {
  12613             case _BCM_KT2_COSQ_NODE_LEVEL_ROOT:
  12614                 port_node = node;
  12615                 if (port_node != NULL) {
  12616                     port_node->parent = NULL;
  12617                     port_node->sibling = NULL;
  12618                     port_node->child = NULL;
  12619                     s1_node = NULL;
  12620                     s0_node = NULL;
  12621                 }
  12622                 break;
  12623 
  12624             case _BCM_KT2_COSQ_NODE_LEVEL_S0:
  12625                 s0_node = node;
  12626                 list = &mmu_info->sched_hw_list[_BCM_KT2_COSQ_NODE_LEVEL_S0];
  12627 
  12628                 if (port_node != NULL && s0_node != NULL) {
  12629                     s0_node->parent = port_node;
  12630                     tmp_node = port_node;
  12631                     if (tmp_node->child == NULL) {
  12632                         tmp_node->child = s0_node;
  12633                         s0_node->sibling = NULL;
  12634                     } else {
  12635                         temp_node = tmp_node->child;
  12636                         while (temp_node->sibling != NULL) {
  12637                             temp_node = temp_node->sibling;
  12638                         }
  12639                         temp_node->sibling = s0_node;
  12640                     }
  12641                     port_node->num_child++;
  12642                     if ((port_node->numq > 0) &&
  12643                         (port_node->numq != mmu_info->max_nodes[s0_node->level])) {
  12644                         if (s0_node->hw_index < port_node->first_child) {
  12645                             port_node->first_child = s0_node->hw_index;
  12646                         }
  12647                         if (port_node->num_child == 1) {
  12648                             if ((port_node->base_index + port_node->numq - 1)
  12649                                         < soc_mem_index_count(unit, LLS_S1_CONFIGm)) {
  12650                                 _bcm_kt2_node_index_set(list, port_node->base_index,
  12651                                     port_node->numq);
  12652                             }
  12653                         }
  12654                     } else if (s0_node->hw_index < 128) {
  12655                         _bcm_kt2_node_index_set(list, s0_node->hw_index, 1);
  12656                     }
  12657                     if (port_node->numq == -1) {
  12658                         BCM_IF_ERROR_RETURN
  12659                             (_bcm_kt2_cosq_max_nodes_get(unit, s0_node->level, 
  12660                                                             &max_numq));
  12661                         port_node->numq = max_numq;
  12662                     }
  12663                 }
  12664                 break;
  12665 
  12666             case _BCM_KT2_COSQ_NODE_LEVEL_S1:
  12667                 s1_node = node;
  12668                 list = &mmu_info->sched_hw_list[_BCM_KT2_COSQ_NODE_LEVEL_S1];
  12669 
  12670                 if (s0_node != NULL && s1_node != NULL) {
  12671                     s1_node->parent = s0_node;
  12672                     tmp_node = s0_node;
  12673                     if (tmp_node->child == NULL) {
  12674                         tmp_node->child = s1_node;
  12675                         s1_node->sibling = NULL;
  12676                     } else {
  12677                         temp_node = tmp_node->child;
  12678                         while (temp_node->sibling != NULL) {
  12679                             temp_node = temp_node->sibling;
  12680                         }
  12681                         temp_node->sibling = s1_node;
  12682                     }
  12683                     s0_node->num_child++;
  12684 
  12685                     if ((s0_node->numq > 0) &&
  12686                         (s0_node->numq != mmu_info->max_nodes[node->level])) {
  12687                         if (s1_node->hw_index < s0_node->first_child) {
  12688                             s0_node->first_child = s1_node->hw_index;
  12689                         }
  12690                         if (s0_node->num_child == 1) {
  12691                             _bcm_kt2_node_index_set(list, s0_node->base_index, 
  12692                                     s0_node->numq);
  12693                         }
  12694                     } else {
  12695                         _bcm_kt2_node_index_set(list, s1_node->hw_index, 1);
  12696                     }
  12697                     if (s0_node->numq == -1) {
  12698                         BCM_IF_ERROR_RETURN
  12699                             (_bcm_kt2_cosq_max_nodes_get(unit, s1_node->level, 
  12700                                                             &max_numq));
  12701                         s0_node->numq = max_numq;
  12702                     }
  12703                 }
  12704                 break;
  12705 
  12706             case _BCM_KT2_COSQ_NODE_LEVEL_L0:
  12707                 l0_node = node;
  12708                 list = &mmu_info->sched_hw_list[_BCM_KT2_COSQ_NODE_LEVEL_L0];
  12709 
  12710                 tmp_node = (s1_node != NULL) ? 
  12711                     s1_node : ((s0_node != NULL) ? s0_node : port_node);
  12712                 if (tmp_node != NULL && l0_node != NULL) {
  12713                     l0_node->parent = tmp_node;
  12714                     if (tmp_node->child == NULL) {
  12715                         tmp_node->child = l0_node;
  12716                         l0_node->sibling = NULL;
  12717                     } else {
  12718                         temp_node = tmp_node->child;
  12719                         while (temp_node->sibling != NULL) {
  12720                             temp_node = temp_node->sibling;
  12721                         }
  12722                         temp_node->sibling = l0_node;
  12723                     }
  12724                     tmp_node->num_child++;
  12725                     if ((tmp_node->numq > 0) &&
  12726                         (tmp_node->numq != mmu_info->max_nodes[node->level])) {
  12727                         if (l0_node->hw_index < tmp_node->first_child) {
  12728                             tmp_node->first_child = l0_node->hw_index;
  12729                         }
  12730                         if (tmp_node->num_child == 1) {
  12731                             _bcm_kt2_node_index_set(list, tmp_node->base_index, 
  12732                                     tmp_node->numq);
  12733                         }
  12734                     } else {
  12735                         _bcm_kt2_node_index_set(list, l0_node->hw_index, 1);
  12736                     }
  12737                     if (tmp_node->numq == -1) {
  12738                         BCM_IF_ERROR_RETURN
  12739                             (_bcm_kt2_cosq_max_nodes_get(unit, l0_node->level, 
  12740                                                             &max_numq));
  12741                         tmp_node->numq = max_numq;
  12742                     }
  12743                 }
  12744                 break;
  12745 
  12746             case _BCM_KT2_COSQ_NODE_LEVEL_L1:
  12747                 l1_node = node;
  12748                 list = &mmu_info->sched_hw_list[_BCM_KT2_COSQ_NODE_LEVEL_L1];
  12749                 if (l0_node != NULL && l1_node != NULL) {
  12750                     l1_node->parent = l0_node;
  12751                     if (l0_node->child == NULL) {
  12752                         l0_node->child = l1_node;
  12753                         l1_node->sibling = NULL;
  12754                     } else {
  12755                         temp_node = l0_node->child;
  12756                         while (temp_node->sibling != NULL) {
  12757                             temp_node = temp_node->sibling;
  12758                         }
  12759                         temp_node->sibling = l1_node;
  12760                     }
  12761                     l0_node->num_child++;
  12762 
  12763                     if ((l0_node->numq > 0) &&
  12764                         (l0_node->numq != mmu_info->max_nodes[node->level])) {
  12765                         if (l1_node->hw_index < l0_node->first_child) {
  12766                             l0_node->first_child = l1_node->hw_index;
  12767                         }
  12768                         if (l0_node->num_child == 1) {
  12769                             _bcm_kt2_node_index_set(list, l0_node->base_index, 
  12770                                     l0_node->numq);
  12771                         }
  12772                     } else {
  12773                         _bcm_kt2_node_index_set(list, l1_node->hw_index, 1);
  12774                     }
  12775                     if (l0_node->numq == -1) {
  12776                         BCM_IF_ERROR_RETURN
  12777                             (_bcm_kt2_cosq_max_nodes_get(unit, l1_node->level, 
  12778                                                             &max_numq));
  12779                         l0_node->numq = max_numq;
  12780                     }
  12781                 }
  12782                 break;
  12783 
  12784             case _BCM_KT2_COSQ_NODE_LEVEL_L2:
  12785                 queue_node = node;
  12786                 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
  12787                     list = &mmu_info->l2_base_qlist;
  12788                 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
  12789                     list = &mmu_info->l2_base_mcqlist;
  12790                 } else if (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  12791 
  12792                     if (mmu_info->num_sub_queues == 0)  {
  12793                         list = &mmu_info->l2_global_qlist;
  12794                     } else {
  12795                         list = &mmu_info->l2_sub_qlist;
  12796                     }
  12797                     if (node_id_based) {
  12798                         queue_node->type = _BCM_KT2_NODE_SUBSCRIBER_GPORT_ID;
  12799                     }
  12800                 } else if (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  12801                     if (mmu_info->num_sub_queues == 0)  {
  12802                         list = &mmu_info->l2_global_qlist;
  12803                     } else {
  12804                         list = &mmu_info->l2_sub_mcqlist;
  12805                     }
  12806                     if (node_id_based) {
  12807                         queue_node->type = _BCM_KT2_NODE_SUBSCRIBER_GPORT_ID;
  12808                     }
  12809                 } else if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport)) {
  12810                     if (mmu_info->num_dmvoq_queues ==0)  { 
  12811 
  12812                         list = &mmu_info->l2_global_qlist;
  12813                         offset = 0 ; 
  12814                     } else {
  12815                         list = &mmu_info->l2_dmvoq_qlist;
  12816                         offset = mmu_info->base_dmvoq_queue;
  12817                     }
  12818                     if (node_id_based) {
  12819                         queue_node->type = _BCM_KT2_NODE_VOQ_ID; 
  12820                     } else {
  12821                         queue_node->type = _BCM_KT2_NODE_VOQ; 
  12822                     }
  12823                 } else {
  12824                     list = &mmu_info->l2_global_qlist;
  12825                 }
  12826                 if (l1_node != NULL && queue_node != NULL) {
  12827                     queue_node->parent = l1_node;
  12828                     queue_node->hw_index = GET_FIELD(NODE_HW_INDEX, node_data);
  12829                     /* Creating LLS tree how it is created */
  12830                     if (l1_node->child == NULL) {
  12831                         l1_node->child = queue_node;
  12832                         queue_node->sibling = NULL;
  12833                     } else {
  12834                         temp_node = l1_node->child;
  12835                         while (temp_node->sibling != NULL) {
  12836                             temp_node = temp_node->sibling;
  12837                         }
  12838                         temp_node->sibling = queue_node;
  12839                     }
  12840                     l1_node->num_child++;
  12841 
  12842                     if ((l1_node->numq > 0) &&
  12843                         (l1_node->numq != mmu_info->max_nodes[node->level])) {
  12844                         if (queue_node->hw_index < l1_node->first_child) {
  12845                             l1_node->first_child = queue_node->hw_index;
  12846                         }
  12847                         if (BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport)) {
  12848                             if (node_id_based) {
  12849                                 _bcm_kt2_node_index_set(list, encap_id - offset , 1);
  12850                             } else if (encap_id % 8 == 0) {
  12851                                 _bcm_kt2_node_index_set(list, encap_id - offset , l1_node->numq);
  12852                             }
  12853                         } else if (l1_node->num_child == 1) {
  12854                             if (
  12855                              BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  12856                              BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  12857                                 if(node_id_based) {
  12858                                     _bcm_kt2_node_index_set(list,
  12859                                             encap_id,
  12860                                             1);
  12861                                 } else {
  12862                                     _bcm_kt2_node_index_set(list,
  12863                                             encap_id,
  12864                                             l1_node->numq);
  12865                                 }
  12866                             } else {
  12867                                 _bcm_kt2_node_index_set(list, l1_node->base_index,
  12868                                         l1_node->numq);
  12869                             }
  12870                         }    
  12871                     } else {
  12872                         _bcm_kt2_node_index_set(list, queue_node->hw_index, 1);
  12873                     }
  12874                     if (l1_node->numq == -1) {
  12875                         BCM_IF_ERROR_RETURN
  12876                             (_bcm_kt2_cosq_max_nodes_get(unit, queue_node->level, 
  12877                                                             &max_numq));
  12878                         l1_node->numq = max_numq;
  12879                     }
  12880                 }
  12881                 break;
  12882 
  12883             default:
  12884                 break;
  12885         }
  12886         if (GET_FIELD(NODE_NUMQ_MAX, node_data)) {
  12887             node->numq  = -1;
  12888         }
  12889     }
  12890     /* Update reference counts for DSCP_TABLE profile*/
  12891     BCM_PBMP_CLEAR(all_pbmp);
  12892     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  12893 #ifdef BCM_KATANA2_SUPPORT
  12894     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  12895         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  12896     }
  12897     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  12898             soc_feature(unit, soc_feature_subtag_coe)) {
  12899         _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  12900     }
  12901 #endif
  12902 
  12903 
  12904     /* Update PORT_COS_MAP memory profile reference counter */
  12905     profile_mem = _bcm_kt2_cos_map_profile[unit];
  12906     PBMP_ITER(all_pbmp, port) {
  12907         SOC_IF_ERROR_RETURN
  12908             (soc_mem_read(unit, COS_MAP_SELm, MEM_BLOCK_ALL, port, &entry));
  12909         set_index = soc_mem_field32_get(unit, COS_MAP_SELm, &entry, SELECTf);
  12910         SOC_IF_ERROR_RETURN
  12911             (soc_profile_mem_reference(unit, profile_mem, set_index * 16, 16));
  12912     }
  12913     /* Update EGR_COS_MAP memory profile reference counter */
  12914     profile_mem = _bcm_kt2_egr_cos_map_profile[unit];
  12915     PBMP_ITER(all_pbmp, port) {
  12916         SOC_IF_ERROR_RETURN
  12917             (soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ALL, port, &entry));
  12918         set_index = soc_mem_field32_get(unit, EGR_PORTm, &entry, EGR_COS_MAP_SELf);
  12919         SOC_IF_ERROR_RETURN
  12920             (soc_profile_mem_reference(unit, profile_mem, set_index * 16, 16));
  12921     }
  12922 
  12923     /* Update ING_QUEUE_OFFSET_MAPPING_TABLE memory profile reference counter */
  12924     for (i = 0; i < soc_mem_index_count(unit, SERVICE_COS_MAPm); i++) {
  12925          SOC_IF_ERROR_RETURN
  12926             (soc_mem_read(unit, SERVICE_COS_MAPm, MEM_BLOCK_ALL, i, &entry));
  12927         if (!soc_mem_field32_get(unit, SERVICE_COS_MAPm, &entry, VALIDf)) {
  12928             continue;
  12929         }
  12930         set_index = soc_mem_field32_get(unit, SERVICE_COS_MAPm,
  12931                                         &entry, QUEUE_OFFSET_PROFILE_INDEXf);
  12932         SOC_IF_ERROR_RETURN
  12933             (_bcm_offset_map_table_entry_reference(unit, set_index * 16, 16));
  12934     }
  12935 
  12936     cpu_hg_index = SOC_INFO(unit).cpu_hg_pp_port_index;
  12937     profile_mem = _bcm_kt2_cos_map_profile[unit];
  12938     if (cpu_hg_index != -1) {
  12939         SOC_IF_ERROR_RETURN(soc_mem_read(unit, COS_MAP_SELm, MEM_BLOCK_ALL,
  12940                     cpu_hg_index, &entry));
  12941         set_index = soc_mem_field32_get(unit, COS_MAP_SELm, &entry, SELECTf);
  12942         SOC_IF_ERROR_RETURN
  12943             (soc_profile_mem_reference(unit, profile_mem, set_index * 16, 16));
  12944     }
  12945 
  12946     PBMP_ITER(all_pbmp, port) {
  12947         if (IS_LB_PORT(unit, port)) {
  12948             /* Loopback port base starts from 64 */
  12949             continue;
  12950         }
  12951         SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ALL,
  12952                     port, &entry));
  12953         index = soc_mem_field32_get(unit, PORT_TABm, &entry, TRUST_DSCP_PTRf);
  12954 
  12955         SOC_IF_ERROR_RETURN(_bcm_dscp_table_entry_reference(unit, index * 64,
  12956                     64));
  12957     }
  12958 
  12959     /* Update MMU_WRED_DROP_CURVE_PROFILE_x memory profile reference counter */
  12960     profile_mem = _bcm_kt2_wred_profile[unit];
  12961     PBMP_PORT_ITER(unit, port) {
  12962 
  12963         /*
  12964          * Wred data can be in two tables depending on packet based or byte based
  12965          * we scan both and update the software profile
  12966          */
  12967         BCM_IF_ERROR_RETURN
  12968             (_bcm_kt2_cosq_index_resolve(unit, port, -1,
  12969                                          _BCM_KT2_COSQ_INDEX_STYLE_WRED, NULL,
  12970                                          NULL, &numq));
  12971         for (cosq = 0; cosq < numq; cosq++) {
  12972             BCM_IF_ERROR_RETURN
  12973                 (_bcm_kt2_cosq_index_resolve(unit, port, cosq,
  12974                                              _BCM_KT2_COSQ_INDEX_STYLE_WRED,
  12975                                              NULL, &index, NULL));
  12976             /* scan byte based wred table */
  12977             mem = MMU_WRED_QUEUE_CONFIG_BUFFERm;
  12978             SOC_IF_ERROR_RETURN
  12979                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &qentry));
  12980             set_index = soc_mem_field32_get(unit, mem, &qentry, PROFILE_INDEXf);
  12981             SOC_IF_ERROR_RETURN
  12982                 (soc_profile_mem_reference(unit, profile_mem, set_index, 1));
  12983 
  12984             /* scan packet based wred table */
  12985             mem=MMU_WRED_QUEUE_CONFIG_QENTRYm; 
  12986             set_index = 0;
  12987             memset(&qentry1, 0, sizeof(mmu_wred_queue_config_qentry_entry_t));
  12988 
  12989             SOC_IF_ERROR_RETURN
  12990                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &qentry1));
  12991             set_index = soc_mem_field32_get(unit, mem, &qentry1, PROFILE_INDEXf);
  12992             SOC_IF_ERROR_RETURN
  12993                 (soc_profile_mem_reference(unit, profile_mem, set_index, 1));
  12994         }
  12995     }
  12996 
  12997     /* Restoring the cosq_map */
  12998     PBMP_ITER(all_pbmp, port) {
  12999         if (IS_LB_PORT(unit, port)) {
  13000             continue;
  13001         }
  13002         node = NULL;
  13003 
  13004         /* root node */
  13005         port_info = &mmu_info->sched_node[port];
  13006         if (port_info->gport >= 0) {
  13007             /* Should not be checking for return value, as we are check for node not NULL */
  13008             /* coverity[unchecked_value] */
  13009             (void)_bcm_kt2_cosq_node_get(unit, port_info->gport, NULL, NULL, NULL, &node);
  13010             if (node != NULL) {
  13011                 SOC_IF_ERROR_RETURN (
  13012                         _bcm_kt2_cosq_map_recover_next_level_node(node));
  13013             }
  13014         }
  13015     }
  13016 
  13017     if (recovered_ver >= BCM_WB_VERSION_1_1) {
  13018         ptr += sizeof(uint32);
  13019         for (i = 0; i < 4; i++) {
  13020             mmu_info->curr_merger_index[i] = *(((uint32 *)ptr));
  13021             ptr += sizeof(uint32);
  13022         }
  13023         PBMP_ALL_ITER(unit, port) {
  13024             if (!(IS_HG_PORT(unit, port)|| IS_HL_PORT(unit, port))) {
  13025                 continue;
  13026             }
  13027             port_node = &mmu_info->sched_node[port];
  13028 
  13029             if (port_node->cosq_attached_to < 0) {
  13030                 continue;
  13031             }
  13032 
  13033             s0_node = port_node->child;
  13034             if (s0_node != NULL && 
  13035                     s0_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
  13036                 continue;
  13037             } else {
  13038                 for (l0_node = port_node->child; l0_node != NULL;
  13039                         l0_node = l0_node->sibling) {
  13040                     for (l1_node = l0_node->child; l1_node != NULL;
  13041                             l1_node = l1_node->sibling) {
  13042                         for (l2_node = l1_node->child; l2_node != NULL;
  13043                                 l2_node = l2_node->sibling) {
  13044                             sal_memcpy(&l2_node->fabric_pbmp, ptr, sizeof(bcm_pbmp_t));
  13045                             ptr += sizeof(bcm_pbmp_t);
  13046                             l2_node->remote_modid = *(((uint32 *)ptr));
  13047                             ptr += sizeof(uint32);
  13048                             l2_node->fabric_modid = *(((uint32 *)ptr));
  13049                             ptr += sizeof(uint32);
  13050                         }
  13051                     }
  13052                 }
  13053             }
  13054 
  13055         }
  13056     } else {
  13057         /* Extra memory for storing fabric_pbmp and we require
  13058            fabric_pbmp only for l2 nodes*/ 
  13059         additional_scache_size += (num_l2_queues[unit] * sizeof(bcm_pbmp_t));
  13060         /* Extra memory for storing remote_modid and we require
  13061            remote_modid only for l2 nodes*/ 
  13062         additional_scache_size += (num_l2_queues[unit] * sizeof(uint32));
  13063         /* Extra memory for storing fabric_modid and we require
  13064            fabric_modid only for l2 nodes*/ 
  13065         additional_scache_size += (num_l2_queues[unit] * sizeof(uint32));
  13066         /* Extra memory for storing curr_merger_index */
  13067         additional_scache_size += (sizeof(int) * 4);
  13068         /* Extra memory forStoring the _BCM_KT2_COSQ_WB_END_NODE_VALUE */
  13069         additional_scache_size += sizeof(uint32);
  13070     }
  13071     if (recovered_ver >= BCM_WB_VERSION_1_2) {
  13072         ptr += sizeof(uint32);
  13073         data = *((uint8 *) ptr);
  13074         num_cos = GET_FIELD(NUM_COS, data);
  13075         if (_bcm_kt2_num_cosq[unit] == 0) {
  13076             return BCM_E_INIT;
  13077         }
  13078         _bcm_kt2_num_cosq[unit] = num_cos;
  13079     } else {
  13080         additional_scache_size += sizeof(uint8);
  13081     }
  13082 
  13083     if (recovered_ver >= BCM_WB_VERSION_1_3) {
  13084         ptr += sizeof(uint8);
  13085         PBMP_ALL_ITER(unit, port) {
  13086             port_node = &mmu_info->sched_node[port];
  13087             if (port_node->cosq_attached_to < 0) {
  13088                 continue;
  13089             }
  13090 
  13091             if (port_node->child == NULL) { 
  13092                 continue;  
  13093             } 
  13094             s0_node = (port_node->child->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) ?
  13095                 port_node->child : port_node;
  13096 
  13097             do {
  13098                if (s0_node->child) {
  13099                    s1_node = (s0_node->child->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) ?
  13100                    s0_node->child : s0_node;
  13101                    do {
  13102                       for (l0_node = s1_node->child;
  13103                                l0_node != NULL;
  13104                                l0_node = l0_node->sibling) {
  13105                            for (l1_node = l0_node->child;
  13106                                       l1_node != NULL;
  13107                                       l1_node = l1_node->sibling) {
  13108                                 l1_node->mc_base_index = *(((uint32 *)ptr));
  13109                                 ptr += sizeof(uint32);
  13110 
  13111                            }
  13112                       }
  13113                       if (s1_node == s0_node) {
  13114                           break;
  13115                       }
  13116                       /* It comes here
  13117                          only in case s1 is valid */
  13118                       s1_node = s1_node->sibling;
  13119                    } while (s1_node != NULL);
  13120                 }
  13121                 if (s0_node == port_node) {
  13122                     break;
  13123                 }
  13124                 /* It comes here
  13125                    only in case s0 is valid */
  13126                 s0_node = s0_node->sibling;
  13127             } while (s0_node != NULL);
  13128         }
  13129     } else {
  13130         /* Extra memory for storing mc base index for L1 nodes*/
  13131         additional_scache_size += (num_l1_schedulers[unit] * sizeof(uint32));
  13132         /* Extra memory forStoring the _BCM_KT2_COSQ_WB_END_NODE_VALUE */
  13133         additional_scache_size += sizeof(uint32);
  13134     }
  13135     if (recovered_ver >= BCM_WB_VERSION_1_4) {
  13136         /* Update PORT_COS_MAP memory profile reference counter */
  13137         profile_mem = _bcm_kt2_ifp_cos_map_profile[unit];
  13138         ptr += sizeof(uint32);
  13139         for (profile_index = 0; profile_index < 4 ; profile_index++) {
  13140             refcount = *(((uint32 *)ptr));
  13141             while (refcount) {
  13142                 SOC_IF_ERROR_RETURN
  13143                     (soc_profile_mem_reference(unit, profile_mem, profile_index * 16, 16));
  13144                 refcount--;
  13145             }
  13146             ptr += sizeof(uint32);
  13147         }
  13148     } else {
  13149         /* Extra memory for storing IFP_COS_MAP refcount*/
  13150         additional_scache_size += (4 * sizeof(uint32));
  13151         /* Extra memory forStoring the _BCM_KT2_COSQ_WB_END_NODE_VALUE */
  13152         additional_scache_size += sizeof(uint32);
  13153     }
  13154     if (recovered_ver >= BCM_WB_VERSION_1_5) {
  13155 #ifdef BCM_KATANA2_SUPPORT
  13156         /* flex counter warm boot support for saber2*/ 
  13157         if (SOC_IS_KATANA2(unit)) {
  13158             for (index =0 ; index < BCM_SB2_COSQ_FLEX_COUNT_SUPPORTED; index++) {
  13159                 stat_array[index] = *(((uint32 *)ptr));
  13160                 ptr += sizeof(uint32);
  13161             }
  13162             bcm_kt2_cosq_stat_config_set(unit, BCM_SB2_COSQ_FLEX_COUNT_SUPPORTED,
  13163                     stat_array);
  13164         } 
  13165         else {
  13166             ptr += (sizeof(uint32) *3);
  13167         }
  13168 #else
  13169         ptr += (sizeof(uint32) *3);
  13170 #endif
  13171     }
  13172     else {
  13173         /*Extra memory for cosq stat config*/
  13174         additional_scache_size += (sizeof(bcm_cosq_stat_t)* 3);        
  13175     } 
  13176 
  13177     /*populating node type and wrr mode to the node from scache*/
  13178     if (recovered_ver >= BCM_WB_VERSION_1_6) {
  13179         PBMP_ALL_ITER(unit, port) {
  13180             port_node = &mmu_info->sched_node[port];
  13181             if (port_node->cosq_attached_to < 0) {
  13182                 continue;
  13183             }
  13184             /*copy the node type to the node*/
  13185             _BCM_KT2_NODE_TYPE_WRR_GET(ptr, port_node);
  13186             if (recovered_ver >= BCM_WB_VERSION_1_8) {
  13187                 _BCM_KT2_NODE_BW_BURST_CAL_GET(ptr, port_node);
  13188             }
  13189             ptr += sizeof(uint8);
  13190             s0_node = port_node->child;
  13191             if (s0_node != NULL && 
  13192                     s0_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
  13193                 continue;
  13194             } else {
  13195                 for ( l0_node = port_node->child; l0_node != NULL;
  13196                         l0_node = l0_node->sibling) {
  13197                     /*copy the node type to the node*/
  13198                     _BCM_KT2_NODE_TYPE_WRR_GET(ptr, l0_node);
  13199                     if (recovered_ver >= BCM_WB_VERSION_1_8) {
  13200                         _BCM_KT2_NODE_BW_BURST_CAL_GET(ptr, port_node);
  13201                     }
  13202                     ptr += sizeof(uint8);
  13203                     for (l1_node = l0_node->child; l1_node != NULL;
  13204                             l1_node = l1_node->sibling) {
  13205                         /*copy the node type to the node*/
  13206                         _BCM_KT2_NODE_TYPE_WRR_GET(ptr, l1_node);
  13207                         if (recovered_ver >= BCM_WB_VERSION_1_8) {
  13208                             _BCM_KT2_NODE_BW_BURST_CAL_GET(ptr, port_node);
  13209                         }
  13210                         ptr += sizeof(uint8);
  13211                         for (l2_node = l1_node->child; l2_node != NULL;
  13212                                 l2_node = l2_node->sibling) {
  13213                             /*copy the node type to the node*/
  13214                             _BCM_KT2_NODE_TYPE_WRR_GET(ptr,l2_node);
  13215                             if (recovered_ver >= BCM_WB_VERSION_1_8) {
  13216                                 _BCM_KT2_NODE_WRED_DISABLE_GET(ptr,l2_node);
  13217                                 _BCM_KT2_NODE_BW_BURST_CAL_GET(ptr, port_node);
  13218                             }
  13219                             ptr += sizeof(uint8);
  13220                         }
  13221                     }
  13222                 }
  13223             }    
  13224         }
  13225     } else {
  13226         /* Extra memory for storing mc base index for L1 nodes*/
  13227         additional_scache_size += ((num_total_schedulers[unit] + num_l2_queues[unit])  * sizeof(uint8));
  13228     }
  13229 
  13230     if (recovered_ver >= BCM_WB_VERSION_1_7) {
  13231         /* Update interface reference count values for all queues */
  13232         sal_memcpy(mmu_info->intf_ref_cnt, ptr,
  13233                    (sizeof(uint32) * BCM_MULTICAST_PORT_MAX));
  13234         ptr += (sizeof(uint32) * BCM_MULTICAST_PORT_MAX);
  13235     } else {
  13236         /* Extra memory to store interface ref count of queues */
  13237         additional_scache_size += (sizeof(uint32) * BCM_MULTICAST_PORT_MAX);
  13238     }
  13239 
  13240     if (additional_scache_size > 0) {
  13241         BCM_IF_ERROR_RETURN(
  13242                 soc_scache_realloc(unit, scache_handle, additional_scache_size));
  13243     }
  13244 
  13245     /* Iterating through all the ports to update the bmaps */
  13246     for (port = CMIC_PORT(unit); port < (LB_PORT(unit)+1); port++) {
  13247         port_node = &mmu_info->sched_node[port];
  13248         s0_bmap = SOC_CONTROL(unit)->port_lls_s0_bmap[port];
  13249         s1_bmap = SOC_CONTROL(unit)->port_lls_s1_bmap[port];
  13250         l0_bmap = SOC_CONTROL(unit)->port_lls_l0_bmap[port];
  13251         l1_bmap = SOC_CONTROL(unit)->port_lls_l1_bmap[port];
  13252         l2_bmap = SOC_CONTROL(unit)->port_lls_l2_bmap[port];
  13253 
  13254         if (port_node->cosq_attached_to < 0) {
  13255             continue;
  13256         }
  13257         if (port_node->child == NULL) { 
  13258             continue;  
  13259         }  
  13260         s0_node = (port_node->child->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) ?
  13261             port_node->child : port_node;
  13262 
  13263         do {
  13264             if (s0_node->child) {
  13265                 s1_node = (s0_node->child->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) ?
  13266                   s0_node->child : s0_node;
  13267                 do {
  13268                    for (l0_node = s1_node->child;
  13269                              l0_node != NULL;
  13270                              l0_node = l0_node->sibling) {
  13271                         SHR_BITSET(l0_bmap, l0_node->hw_index);
  13272                         for (l1_node = l0_node->child;
  13273                             l1_node != NULL;
  13274                             l1_node = l1_node->sibling) {
  13275                             SHR_BITSET(l1_bmap, l1_node->hw_index);
  13276                             for (l2_node = l1_node->child;
  13277                                 l2_node != NULL;
  13278                                 l2_node = l2_node->sibling) {
  13279                                 SHR_BITSET(l2_bmap, l2_node->hw_index);
  13280                             }
  13281                         }
  13282                    }
  13283                    if (s1_node == s0_node) {
  13284                        break;
  13285                    }
  13286                    /* It comes here
  13287                       only in case s1 is valid */
  13288                       SHR_BITSET(s1_bmap, s1_node->hw_index);
  13289                       s1_node = s1_node->sibling;
  13290                 } while (s1_node != NULL);
  13291             }       
  13292             if (s0_node == port_node) {
  13293                 break;
  13294             }
  13295             /* It comes here
  13296                only in case s0 is valid */
  13297             SHR_BITSET(s0_bmap, s0_node->hw_index);
  13298             s0_node = s0_node->sibling;
  13299         } while (s0_node != NULL);
  13300 
  13301     }
  13302     /* Update PRIO2COS_LLFC register profile reference counter */
  13303     profile_reg = _bcm_kt2_llfc_profile[unit];
  13304     PBMP_PORT_ITER(unit, port) {
  13305 #ifdef BCM_METROLITE_SUPPORT
  13306         if (SOC_IS_METROLITE(unit)) {
  13307             mmu_port = ml_pfc_support[port].mmu_port;
  13308         } else
  13309 #endif
  13310 #ifdef BCM_SABER2_SUPPORT 
  13311         if (SOC_IS_SABER2(unit)) { 
  13312             mmu_port = sb2_pfc_support[port].mmu_port;
  13313         } else 
  13314 #endif 
  13315         {
  13316             mmu_port = kt2_pfc_support[port].mmu_port;
  13317         }
  13318         if (mmu_port == -1) {
  13319             continue; 
  13320         }
  13321         reg = PORT_PFC_CFG0r;
  13322 #ifdef BCM_METROLITE_SUPPORT
  13323         if(SOC_IS_METROLITE(unit)) {
  13324             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg,
  13325                                  REG_PORT_ANY, 0, &rval32));
  13326             index_map32 = soc_reg_field_get(unit, reg,
  13327                                               rval32, PROFILE_INDEXf);
  13328             index_map32 = index_map32 >> (mmu_port * 2);
  13329             set_index = (index_map32 & 3);
  13330         } else
  13331 #endif
  13332         {
  13333              BCM_IF_ERROR_RETURN(soc_reg64_get(unit, reg, 0, 0, &rval));
  13334 
  13335              index_map = soc_reg64_field_get(unit, reg, rval, PROFILE_INDEXf);
  13336              COMPILER_64_SHR(index_map, ((mmu_port % 32) * 2));
  13337              COMPILER_64_TO_32_LO(tmp32, index_map);
  13338              set_index = (tmp32 & 3);
  13339         }
  13340         SOC_IF_ERROR_RETURN
  13341                 (soc_profile_reg_reference(unit, profile_reg,
  13342                                              set_index * 16, 16));
  13343     }
  13344     return BCM_E_NONE;
  13345 }
  13346 #endif /* BCM_WARM_BOOT_SUPPORT */
  13347 
  13348 int
  13349 _bcm_kt2_subport_config_set(int unit)
  13350 {
  13351     soc_info_t *si;
  13352     bcm_port_t port;
  13353     bcm_port_t lp_ports = 0;
  13354     int start = 0, end = 0;
  13355     int min_subport_index;
  13356     int num_max_stream = 0;
  13357     soc_pbmp_t pbmp_linkphy_one_stream_per_subport;
  13358 
  13359     si = &SOC_INFO(unit);
  13360     min_subport_index = si->pp_port_index_min;
  13361 
  13362     num_max_stream = si->lp_streams_per_subport;
  13363 
  13364     SOC_PBMP_CLEAR(pbmp_linkphy_one_stream_per_subport);
  13365     if (SOC_IS_SABER2(unit)) {
  13366         pbmp_linkphy_one_stream_per_subport =
  13367         soc_property_get_pbmp(unit, spn_PBMP_LINKPHY_ONE_STREAM_PER_SUBPORT, 0);
  13368     }
  13369 
  13370     SOC_PBMP_ITER(si->linkphy_pbm, port) {
  13371         /* coverity[dead_error_condition] */
  13372         if (port >= si->lb_port) {
  13373             /* coverity[dead_error_begin] */
  13374             break;
  13375         }
  13376         start = si->port_linkphy_s1_base[port];
  13377         end = start +
  13378           si->port_num_subport[port] *
  13379           (SOC_PBMP_MEMBER(pbmp_linkphy_one_stream_per_subport, port) ?
  13380            1 : num_max_stream) - 1;
  13381         SOC_IF_ERROR_RETURN
  13382             (soc_kt2_cosq_s1_range_set(unit, port, start, end, 1)); 
  13383         SOC_IF_ERROR_RETURN
  13384             (soc_kt2_cosq_port_coe_linkphy_status_set(unit, port, 1));
  13385         lp_ports++;
  13386     }
  13387 
  13388     /*
  13389      * setup linkphy destination stream mapping if
  13390      * linkphy is enabled on the ports OR
  13391      * the linkphy_allowed_pbmp is not NULL, meaning
  13392      * there are ports on which linkphy could be
  13393      * enabled in future.
  13394      */
  13395     if ((lp_ports > 0) ||
  13396         (SOC_PBMP_NOT_NULL(si->linkphy_allowed_pbm))) {
  13397         SOC_IF_ERROR_RETURN
  13398             (soc_kt2_cosq_stream_mapping_set(unit));
  13399     }
  13400 
  13401     SOC_PBMP_ITER(si->subtag_pbm, port) {
  13402         /* coverity[dead_error_condition] */
  13403         if (port >= si->lb_port) {
  13404             /* coverity[dead_error_begin] */
  13405             break;
  13406         }
  13407         start = si->port_subport_base[port] - min_subport_index;
  13408         end = start + si->port_num_subport[port] - 1;
  13409         SOC_IF_ERROR_RETURN
  13410             (soc_kt2_cosq_s1_range_set(unit, port, start, end, 0)); 
  13411         SOC_IF_ERROR_RETURN
  13412             (soc_kt2_cosq_port_coe_linkphy_status_set(unit, port, 1));
  13413     }
  13414 
  13415     return BCM_E_NONE;
  13416 }
  13417 
  13418 int
  13419 _bcm_kt2_packing_config_set(int unit, bcm_port_t port, int numq)
  13420 {
  13421     bcm_gport_t port_sched, l0_sched;
  13422     bcm_gport_t l1_sched;
  13423     bcm_gport_t cosq;
  13424     int cos, i;
  13425     uint32 type;
  13426     BCM_IF_ERROR_RETURN
  13427         (bcm_kt2_cosq_gport_add(unit, port, 1, 0, &port_sched));
  13428 
  13429     /*    coverity[uninit_use_in_call : FALSE]    */
  13430     BCM_IF_ERROR_RETURN
  13431         (bcm_kt2_cosq_gport_add(unit, port, numq, 
  13432                                  BCM_COSQ_GPORT_SCHEDULER, 
  13433                                  &l0_sched));
  13434      BCM_IF_ERROR_RETURN
  13435         (bcm_kt2_cosq_gport_attach(unit, l0_sched, port_sched, 0)); 
  13436 
  13437     for (cos = 0; cos < numq; cos++) {
  13438         BCM_IF_ERROR_RETURN
  13439             (bcm_kt2_cosq_gport_add(unit, port, 2, BCM_COSQ_GPORT_SCHEDULER, 
  13440                                     &l1_sched));
  13441         BCM_IF_ERROR_RETURN
  13442             (bcm_kt2_cosq_gport_attach(unit, l1_sched, l0_sched, cos));
  13443         for (i = 0; i < 2; i++) {
  13444             type = (i == 0) ? BCM_COSQ_GPORT_UCAST_QUEUE_GROUP :
  13445                     BCM_COSQ_GPORT_MCAST_QUEUE_GROUP;
  13446             BCM_IF_ERROR_RETURN
  13447                 (bcm_kt2_cosq_gport_add(unit, port, 1, type, &cosq));
  13448             BCM_IF_ERROR_RETURN
  13449                 (bcm_kt2_cosq_gport_attach(unit, cosq, l1_sched, i)); 
  13450             BCM_IF_ERROR_RETURN
  13451                 (bcm_kt2_cosq_gport_sched_set(unit, l1_sched, i, 
  13452                                           BCM_COSQ_WEIGHTED_ROUND_ROBIN, 1));
  13453         }        
  13454     }
  13455 
  13456     return BCM_E_NONE;
  13457 } 
  13458     
  13459 int
  13460 _bcm_kt2_port_lls_config_set(int unit, 
  13461                              bcm_port_t port, 
  13462                              int startq, 
  13463                              int total_queues, 
  13464                              int numq)
  13465 {
  13466     bcm_gport_t port_sched, l0_sched;
  13467     bcm_gport_t l1_sched;
  13468     bcm_gport_t cosq;
  13469     int cos, i;
  13470     uint32 type;
  13471     uint32 total_opnodes = (total_queues + 7)/8; 
  13472 
  13473     BCM_IF_ERROR_RETURN
  13474         (bcm_kt2_cosq_gport_add(unit, port, 1, 0, &port_sched));
  13475  
  13476     /*    coverity[uninit_use_in_call : FALSE]    */
  13477     BCM_IF_ERROR_RETURN
  13478         (bcm_kt2_cosq_gport_add(unit, port, total_opnodes,
  13479                                  BCM_COSQ_GPORT_SCHEDULER, 
  13480                                  &l0_sched));
  13481      BCM_IF_ERROR_RETURN
  13482         (bcm_kt2_cosq_gport_attach(unit, l0_sched, port_sched, 0)); 
  13483 
  13484     for (i = 0; i < total_opnodes; i++) {
  13485          if (IS_HG_PORT(unit, port) && soc_feature(unit, soc_feature_mmu_packing))  { 
  13486              BCM_IF_ERROR_RETURN
  13487              (bcm_kt2_cosq_gport_add(unit, port, numq * 2 , BCM_COSQ_GPORT_SCHEDULER, 
  13488                                     &l1_sched));
  13489          }
  13490          else { 
  13491 
  13492              BCM_IF_ERROR_RETURN
  13493              (bcm_kt2_cosq_gport_add(unit, port, numq, BCM_COSQ_GPORT_SCHEDULER, 
  13494                                     &l1_sched));
  13495          }
  13496 
  13497         BCM_IF_ERROR_RETURN
  13498             (bcm_kt2_cosq_gport_attach(unit, l1_sched, l0_sched, i));
  13499         for (cos = 0; cos < numq; cos++) {
  13500             type = BCM_COSQ_GPORT_WITH_ID;
  13501             BCM_GPORT_UCAST_QUEUE_GROUP_SYSQID_SET(cosq, port, (startq + cos)); 
  13502             BCM_IF_ERROR_RETURN
  13503                 (bcm_kt2_cosq_gport_add(unit, port, 1, type, &cosq));
  13504             BCM_IF_ERROR_RETURN
  13505                 (bcm_kt2_cosq_gport_attach(unit, cosq, l1_sched, cos)); 
  13506             BCM_IF_ERROR_RETURN
  13507                 (bcm_kt2_cosq_gport_sched_set(unit, l1_sched, cos, 
  13508                                           BCM_COSQ_WEIGHTED_ROUND_ROBIN, 1));
  13509          if (IS_HG_PORT(unit, port) && soc_feature(unit, soc_feature_mmu_packing))  { 
  13510              BCM_IF_ERROR_RETURN
  13511                 (bcm_kt2_cosq_gport_add(unit, port, 1, 
  13512                          BCM_COSQ_GPORT_MCAST_QUEUE_GROUP, &cosq));
  13513              BCM_IF_ERROR_RETURN
  13514                 (bcm_kt2_cosq_gport_attach(unit, cosq, l1_sched, cos + numq)); 
  13515              BCM_IF_ERROR_RETURN
  13516                 (bcm_kt2_cosq_gport_sched_set(unit, l1_sched, (cos + numq)  , 
  13517                                           BCM_COSQ_WEIGHTED_ROUND_ROBIN, 1));
  13518          }
  13519         }
  13520         startq += 8;
  13521     }
  13522 
  13523     return BCM_E_NONE;
  13524 } 
  13525 
  13526 int 
  13527 _bcm_kt2_create_default_lls_tree(int unit, bcm_port_t port) 
  13528 {
  13529     soc_info_t *si;
  13530     int numq = 0, cosq;
  13531     bcm_gport_t port_sched, l0_sched, l1_sched, queue;
  13532 
  13533     si = &SOC_INFO(unit);
  13534     bcm_kt2_cosq_config_get(unit, &numq);
  13535     if (numq < 1) {
  13536         numq = 1;
  13537     } else if (numq > 8) {
  13538         numq = 8;
  13539     }
  13540     if (IS_HG_PORT(unit, port)) {
  13541         BCM_IF_ERROR_RETURN
  13542             (_bcm_kt2_port_lls_config_set(unit, port, 
  13543                                           si->port_uc_cosq_base[port], 
  13544                                           si->port_num_uc_cosq[port], 
  13545                                           numq));
  13546     } else {
  13547         if (!soc_feature(unit, soc_feature_mmu_packing)) {
  13548             BCM_IF_ERROR_RETURN
  13549                 (bcm_kt2_cosq_gport_add(unit, port, 1, 0, &port_sched));
  13550 
  13551             /*    coverity[uninit_use_in_call : FALSE]    */
  13552             BCM_IF_ERROR_RETURN
  13553                 (bcm_kt2_cosq_gport_add(unit, port, 1, 
  13554                                         BCM_COSQ_GPORT_SCHEDULER, 
  13555                                         &l0_sched));
  13556             BCM_IF_ERROR_RETURN
  13557                 (bcm_kt2_cosq_gport_attach(unit, l0_sched, port_sched, 0)); 
  13558             BCM_IF_ERROR_RETURN
  13559                 (bcm_kt2_cosq_gport_add(unit, port, numq, 
  13560                                         BCM_COSQ_GPORT_SCHEDULER, 
  13561                                         &l1_sched));
  13562             BCM_IF_ERROR_RETURN
  13563                 (bcm_kt2_cosq_gport_attach(unit, l1_sched, l0_sched, 0));  
  13564             for (cosq = 0; cosq < numq; cosq++) {
  13565                 BCM_IF_ERROR_RETURN
  13566                     (bcm_kt2_cosq_gport_add(unit, port, 1,
  13567                                             BCM_COSQ_GPORT_UCAST_QUEUE_GROUP, &queue));
  13568                 BCM_IF_ERROR_RETURN
  13569                     (bcm_kt2_cosq_gport_attach(unit, queue, l1_sched, 
  13570                                                cosq)); 
  13571                 BCM_IF_ERROR_RETURN
  13572                     (bcm_kt2_cosq_gport_sched_set(unit, l1_sched, cosq,
  13573                                                   BCM_COSQ_STRICT, 0)); 
  13574             }
  13575         }else {
  13576             BCM_IF_ERROR_RETURN
  13577                 (_bcm_kt2_packing_config_set(unit, port, numq));
  13578         }
  13579     }
  13580 
  13581     return BCM_E_NONE;
  13582 
  13583 }
  13584 
  13585 int 
  13586 bcm_katana2_cosq_reconfigure_flexio(int unit, bcm_port_t port, int lanes)
  13587 {
  13588    bcm_gport_t gport; 
  13589    int i;
  13590    BCM_IF_ERROR_RETURN
  13591    (bcm_esw_port_gport_get(unit, port , &gport));
  13592 
  13593     /* Deleting the LLS tree */
  13594     BCM_IF_ERROR_RETURN
  13595         ( bcm_kt2_cosq_gport_delete(unit, gport));
  13596    /* Creating the default LLS tree */
  13597    BCM_IF_ERROR_RETURN
  13598        ( _bcm_kt2_create_default_lls_tree(unit, port));
  13599    for (i = 1; i < lanes; i++) {
  13600         BCM_IF_ERROR_RETURN
  13601         (bcm_esw_port_gport_get(unit, port + i , &gport));
  13602         /* Deleting the LLS tree */
  13603         BCM_IF_ERROR_RETURN
  13604         ( bcm_kt2_cosq_gport_delete(unit, gport));
  13605    }
  13606    return BCM_E_NONE;
  13607 }
  13608 
  13609 STATIC int 
  13610 _bcm_kt2_init_all_queue_counters(int unit)
  13611 {  
  13612     uint32 max_queue = soc_mem_index_count(unit, LLS_L2_PARENTm);
  13613     uint32 queue_index;
  13614     uint64 val;
  13615 #ifdef BCM_KATANA2_SUPPORT
  13616     int num_elem = 0;
  13617     int index = 0, increment = 4;
  13618     _sb2_cosq_counter_mem_map_t *mem_map;
  13619     soc_reg_t non_dma_id_1 = 0, non_dma_id_2 = 0;   
  13620     if (SOC_IS_SABER2(unit)) {
  13621         uint16 dev_id;
  13622         uint8 rev_id;
  13623         increment = 2;
  13624         soc_cm_get_id(unit, &dev_id, &rev_id);
  13625         if (dev_id == BCM56233_DEVICE_ID) {
  13626             increment = 1;
  13627         }
  13628     }
  13629 #ifdef BCM_METROLITE_SUPPORT
  13630     if(SOC_IS_METROLITE(unit))  {
  13631        increment = 1;
  13632     }
  13633 #endif 
  13634     soc_sb2_cosq_counter_mem_map_get(unit, &num_elem, &mem_map);
  13635     COMPILER_64_ZERO(val);
  13636     /* This API is mainly for clearing the extended queues only,
  13637        So Looping only for queue_id > SOC_MAX_NUM_PP_PORTS */
  13638 
  13639     for ( index = 0; index < num_elem; index += increment ) {
  13640         switch (mem_map[index].non_dma_id) {
  13641             case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT:
  13642                 non_dma_id_1 = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT;
  13643                 non_dma_id_2 = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE;
  13644                 break;
  13645             case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW:
  13646                 non_dma_id_1 = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW;
  13647                 non_dma_id_2 = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_YELLOW;
  13648                 break;
  13649             case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED:
  13650                 non_dma_id_1 = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED;
  13651                 non_dma_id_2 = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_RED;
  13652                 break;
  13653             case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN:
  13654                 non_dma_id_1 = SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN;
  13655                 non_dma_id_2 = SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_GREEN;
  13656                 break;
  13657             case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT:
  13658                 non_dma_id_1 = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT;
  13659                 non_dma_id_2 = SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE;
  13660                 break;
  13661             default:
  13662                 break;
  13663         }
  13664         for (queue_index = soc_max_num_pp_ports[unit] + 1;
  13665                 queue_index < max_queue; queue_index++) {
  13666             BCM_IF_ERROR_RETURN(soc_counter_set(unit, queue_index, 
  13667                         non_dma_id_1, 0, val));
  13668             BCM_IF_ERROR_RETURN(soc_counter_set(unit, queue_index, 
  13669                         non_dma_id_2, 0, val));
  13670         }
  13671     }
  13672 #else
  13673      COMPILER_64_ZERO(val);
  13674     /* This API is mainly for clearing the extended queues only,
  13675        So Looping only for queue_id > SOC_MAX_NUM_PP_PORTS */
  13676     for (queue_index = SOC_MAX_NUM_PP_PORTS + 1;
  13677             queue_index < max_queue; queue_index++) {
  13678         BCM_IF_ERROR_RETURN(soc_counter_set(unit, queue_index, 
  13679                     SOC_COUNTER_NON_DMA_COSQ_DROP_PKT, 0, val));
  13680         BCM_IF_ERROR_RETURN(soc_counter_set(unit, queue_index, 
  13681                     SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE, 0, val));
  13682         BCM_IF_ERROR_RETURN(soc_counter_set(unit, queue_index, 
  13683                     SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED, 0, val));
  13684         BCM_IF_ERROR_RETURN(soc_counter_set(unit, queue_index, 
  13685                     SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_RED, 0, val));
  13686         BCM_IF_ERROR_RETURN(soc_counter_set(unit, queue_index, 
  13687                     SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT, 0, val));
  13688         BCM_IF_ERROR_RETURN(soc_counter_set(unit, queue_index, 
  13689                     SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE, 0, val));
  13690     }     
  13691 
  13692 #endif
  13693     return BCM_E_NONE;
  13694 }
  13695 int
  13696 bcm_kt2_init_fc_map_tbl(int unit)
  13697 {
  13698     int max_index;
  13699     int max_nodes;
  13700     uint32 map_entry[SOC_MAX_MEM_WORDS];
  13701     int mem;
  13702     int index;
  13703     int field ;
  13704     static const soc_field_t indexf[] = {
  13705         INDEX0f, INDEX1f 
  13706     };
  13707     static const soc_mem_t memx[] = {
  13708         MMU_INTFI_FC_MAP_TBL0m,
  13709         MMU_INTFI_FC_MAP_TBL1m,
  13710         MMU_INTFI_FC_MAP_TBL2m
  13711     };
  13712     static const soc_mem_t memy[] = {
  13713         MMU_INTFI_FC_ST_TBL0m,
  13714         MMU_INTFI_FC_ST_TBL1m,
  13715         MMU_INTFI_FC_ST_TBL2m,
  13716     };
  13717 
  13718     for ( mem = 0 ; mem < 3 ; mem++)
  13719     {
  13720        max_index = soc_mem_index_count(unit, memy[mem]) - 1;
  13721        max_nodes = soc_mem_index_count(unit,memx[mem]);
  13722        for ( index = 0 ; index < max_nodes ; index++)
  13723        {
  13724          SOC_IF_ERROR_RETURN(soc_mem_read(unit, memx[mem],
  13725                 MEM_BLOCK_ALL, index, &map_entry));
  13726          for (field = 0; field  <  COUNTOF(indexf); field++)
  13727          {
  13728               soc_mem_field32_set(unit, memx[mem],
  13729                                    &map_entry, indexf[field], max_index);
  13730          }
  13731          SOC_IF_ERROR_RETURN(soc_mem_write(unit, memx[mem],
  13732                         MEM_BLOCK_ALL, index, &map_entry));
  13733        }
  13734      }
  13735      return BCM_E_NONE;
  13736 }
  13737 
  13738 /*
  13739  * Function:
  13740  *     bcm_kt2_cosq_init
  13741  * Purpose:
  13742  *     Initialize (clear) all COS schedule/mapping state.
  13743  * Parameters:
  13744  *     unit - unit number
  13745  * Returns:
  13746  *     BCM_E_XXX
  13747  */
  13748 int
  13749 bcm_kt2_cosq_init(int unit)
  13750 {
  13751     soc_info_t *si;
  13752     STATIC int _kt2_max_cosq = -1;
  13753     int cosq, numq, alloc_size, ext_pbmp_count;
  13754     bcm_port_t port;
  13755     soc_reg_t mem;
  13756     soc_pbmp_t pbmp_linkphy, ext_pbmp;
  13757     STATIC soc_mem_t wred_mems[6] = {
  13758         MMU_WRED_DROP_CURVE_PROFILE_0m, MMU_WRED_DROP_CURVE_PROFILE_1m,
  13759         MMU_WRED_DROP_CURVE_PROFILE_2m, MMU_WRED_DROP_CURVE_PROFILE_3m,
  13760         MMU_WRED_DROP_CURVE_PROFILE_4m, MMU_WRED_DROP_CURVE_PROFILE_5m
  13761     };
  13762     int entry_words[6];
  13763     mmu_wred_drop_curve_profile_0_entry_t entry_tcp_green;
  13764     mmu_wred_drop_curve_profile_1_entry_t entry_tcp_yellow;
  13765     mmu_wred_drop_curve_profile_2_entry_t entry_tcp_red;
  13766     mmu_wred_drop_curve_profile_3_entry_t entry_nontcp_green;
  13767     mmu_wred_drop_curve_profile_4_entry_t entry_nontcp_yellow;
  13768     mmu_wred_drop_curve_profile_5_entry_t entry_nontcp_red;
  13769     void *entries[6];
  13770     uint64 rval64s[16], *prval64s[1];
  13771     uint32 profile_index,rval;
  13772     _bcm_kt2_mmu_info_t *mmu_info_p;
  13773     int i, cmc;
  13774     bcm_gport_t port_sched, l0_sched, l1_sched, queue;
  13775     uint32 max_threshold, min_threshold;
  13776     int num_queues, num_inputs;
  13777     int num_base_queues = 0, total_sub_queues = 0;
  13778     int start_pp_port = 0, end_pp_port = 0;
  13779     int pre_alloc_queues = 0;
  13780     int pp_port_cos = 0;
  13781     uint32 qbase = 0;
  13782     uint32 qoffset = 0;
  13783     soc_reg_t reg;
  13784 
  13785     /* Initialize static variables */
  13786     num_pp_ports[unit]=-1;
  13787     num_port_schedulers[unit]=-1;
  13788     num_s0_schedulers[unit]=-1;
  13789     num_s1_schedulers[unit]=-1;
  13790     num_l0_schedulers[unit]=-1;
  13791     num_l1_schedulers[unit]=-1;
  13792     num_total_schedulers[unit]=-1;
  13793     num_l2_queues[unit]=-1;
  13794     max_l1_shaper_bucket[unit]=-1;
  13795     max_l2_shaper_bucket[unit]=-1;
  13796     soc_max_num_pp_ports[unit] = SOC_MAX_NUM_PP_PORTS;
  13797 
  13798     if (_kt2_max_cosq < 0) {
  13799         _kt2_max_cosq = NUM_COS(unit);
  13800         NUM_COS(unit) = 8;
  13801     }
  13802  
  13803     if (soc_property_get(unit, spn_MMU_MULTI_PACKETS_PER_CELL, 0)) {
  13804         ext_pbmp = soc_property_get_pbmp(unit, spn_PBMP_EXT_MEM, 0);
  13805         SOC_PBMP_COUNT(ext_pbmp, ext_pbmp_count); 
  13806         if (ext_pbmp_count == 0){
  13807             LOG_ERROR(BSL_LS_BCM_COMMON,
  13808                  (BSL_META_U(unit,
  13809                              "With packing mode set you need have"
  13810                              "the pbmp_ext_mem bitmap for the ports"
  13811                              "for those requires external memory \n")));
  13812             return BCM_E_CONFIG; 
  13813         }
  13814     }
  13815 
  13816     BCM_IF_ERROR_RETURN (bcm_kt2_cosq_detach(unit, 0));
  13817 
  13818     numq = soc_property_get(unit, spn_BCM_NUM_COS, BCM_COS_DEFAULT);
  13819 
  13820     if (numq < 1) {
  13821         numq = 1;
  13822     } else if (numq > 8) {
  13823         numq = 8;
  13824     }
  13825 
  13826     /* Create profile for PORT_COS_MAP table */
  13827     if (_bcm_kt2_cos_map_profile[unit] == NULL) {
  13828         _bcm_kt2_cos_map_profile[unit] = sal_alloc(sizeof(soc_profile_mem_t),
  13829                                                   "COS_MAP Profile Mem");
  13830         if (_bcm_kt2_cos_map_profile[unit] == NULL) {
  13831             return BCM_E_MEMORY;
  13832         }
  13833         soc_profile_mem_t_init(_bcm_kt2_cos_map_profile[unit]);
  13834     }
  13835     mem = PORT_COS_MAPm;
  13836     entry_words[0] = sizeof(port_cos_map_entry_t) / sizeof(uint32);
  13837     BCM_IF_ERROR_RETURN(soc_profile_mem_create(unit, &mem, entry_words, 1,
  13838                                                _bcm_kt2_cos_map_profile[unit]));
  13839 
  13840     /* Create profile for EGR_COS_MAP table */
  13841     if (_bcm_kt2_egr_cos_map_profile[unit] == NULL) {
  13842         _bcm_kt2_egr_cos_map_profile[unit] = sal_alloc(sizeof(soc_profile_mem_t),
  13843                                                   "EGR_COS_MAP Profile Mem");
  13844         if (_bcm_kt2_egr_cos_map_profile[unit] == NULL) {
  13845             return BCM_E_MEMORY;
  13846         }
  13847         soc_profile_mem_t_init(_bcm_kt2_egr_cos_map_profile[unit]);
  13848     }
  13849     mem = EGR_COS_MAPm;
  13850     entry_words[0] = sizeof(egr_cos_map_entry_t) / sizeof(uint32);
  13851     BCM_IF_ERROR_RETURN(soc_profile_mem_create(unit, &mem, entry_words, 1,
  13852                                                _bcm_kt2_egr_cos_map_profile[unit]));
  13853     
  13854     /* Create profile for PRIO2COS_LLFC register */
  13855     if (_bcm_kt2_llfc_profile[unit] == NULL) {
  13856         _bcm_kt2_llfc_profile[unit] =
  13857             sal_alloc(sizeof(soc_profile_reg_t), "PRIO2COS_LLFC Profile Reg");
  13858         if (_bcm_kt2_llfc_profile[unit] == NULL) {
  13859             return BCM_E_MEMORY;
  13860         }
  13861         soc_profile_reg_t_init(_bcm_kt2_llfc_profile[unit]);
  13862     }
  13863     reg = PRIO2COS_PROFILEr;
  13864     BCM_IF_ERROR_RETURN
  13865         (soc_profile_reg_create(unit, &reg, 1, _bcm_kt2_llfc_profile[unit]));
  13866 
  13867     /* Inititilise pg profile refcount */
  13868 #if defined(BCM_SABER2_SUPPORT)
  13869     BCM_IF_ERROR_RETURN(bcm_kt2_pg_profile_refcount_init(unit));
  13870 #endif
  13871     /* Create profile for IFP_COS_MAP table. */
  13872     if (_bcm_kt2_ifp_cos_map_profile[unit] == NULL) {
  13873         _bcm_kt2_ifp_cos_map_profile[unit]
  13874             = sal_alloc(sizeof(soc_profile_mem_t), "IFP_COS_MAP Profile Mem");
  13875         if (_bcm_kt2_ifp_cos_map_profile[unit] == NULL) {
  13876             return BCM_E_MEMORY;
  13877         }
  13878         soc_profile_mem_t_init(_bcm_kt2_ifp_cos_map_profile[unit]);
  13879     }
  13880     mem = IFP_COS_MAPm;
  13881     entry_words[0] = sizeof(ifp_cos_map_entry_t) / sizeof(uint32);
  13882     BCM_IF_ERROR_RETURN
  13883         (soc_profile_mem_create(unit, &mem, entry_words, 1,
  13884                                 _bcm_kt2_ifp_cos_map_profile[unit]));    
  13885 
  13886     /* Create profile for MMU_WRED_DROP_CURVE_PROFILE_x tables */
  13887     if (_bcm_kt2_wred_profile[unit] == NULL) {
  13888         _bcm_kt2_wred_profile[unit] = sal_alloc(sizeof(soc_profile_mem_t),
  13889                                                "WRED Profile Mem");
  13890         if (_bcm_kt2_wred_profile[unit] == NULL) {
  13891             return BCM_E_MEMORY;
  13892         }
  13893         soc_profile_mem_t_init(_bcm_kt2_wred_profile[unit]);
  13894     }
  13895     entry_words[0] =
  13896         sizeof(mmu_wred_drop_curve_profile_0_entry_t) / sizeof(uint32);
  13897     entry_words[1] =
  13898         sizeof(mmu_wred_drop_curve_profile_1_entry_t) / sizeof(uint32);
  13899     entry_words[2] =
  13900         sizeof(mmu_wred_drop_curve_profile_2_entry_t) / sizeof(uint32);
  13901     entry_words[3] =
  13902         sizeof(mmu_wred_drop_curve_profile_3_entry_t) / sizeof(uint32);
  13903     entry_words[4] =
  13904         sizeof(mmu_wred_drop_curve_profile_4_entry_t) / sizeof(uint32);
  13905     entry_words[5] =
  13906         sizeof(mmu_wred_drop_curve_profile_5_entry_t) / sizeof(uint32);
  13907     BCM_IF_ERROR_RETURN(soc_profile_mem_create(unit, wred_mems, entry_words, 6,
  13908                                                _bcm_kt2_wred_profile[unit]));
  13909 
  13910     alloc_size = sizeof(_bcm_kt2_mmu_info_t) * 1;
  13911     if (_bcm_kt2_mmu_info[unit] == NULL) {
  13912         _bcm_kt2_mmu_info[unit] =
  13913             sal_alloc(alloc_size, "_bcm_kt2_mmu_info");
  13914 
  13915         if (_bcm_kt2_mmu_info[unit] == NULL) {
  13916             return BCM_E_MEMORY;
  13917         }
  13918     } else {
  13919         _bcm_kt2_cosq_free_memory(_bcm_kt2_mmu_info[unit]);
  13920     }
  13921 
  13922     sal_memset(_bcm_kt2_mmu_info[unit], 0, alloc_size);
  13923 
  13924     mmu_info_p = _bcm_kt2_mmu_info[unit];
  13925 
  13926     /* ======================== */
  13927     /* Time Being commenting below part under if 0 */
  13928     /* ======================== */
  13929     /*
  13930        if (soc_feature(unit, soc_feature_ddr3)) {
  13931        mmu_info_p->num_queues = soc_mem_index_count(unit, LLS_L2_PARENTm);
  13932        } else {
  13933 
  13934        mmu_info_p->num_queues = 1024;
  13935        }
  13936      */
  13937     mmu_info_p->num_queues = soc_mem_index_count(unit, LLS_L2_PARENTm);
  13938     
  13939     mmu_info_p->max_nodes[_BCM_KT2_COSQ_NODE_LEVEL_ROOT] = 
  13940                                   soc_mem_index_count(unit, LLS_PORT_CONFIGm);
  13941     mmu_info_p->max_nodes[_BCM_KT2_COSQ_NODE_LEVEL_S0]   = 
  13942                                   soc_mem_index_count(unit, LLS_S1_CONFIGm);
  13943     mmu_info_p->max_nodes[_BCM_KT2_COSQ_NODE_LEVEL_S1]   = 
  13944                                   2 * soc_mem_index_count(unit, LLS_S1_CONFIGm);
  13945     if (SOC_IS_SABER2(unit)) {
  13946         mmu_info_p->max_nodes[_BCM_KT2_COSQ_NODE_LEVEL_S1]   = 
  13947             soc_mem_index_count(unit, LLS_S1_CONFIGm);
  13948 #if defined BCM_METROLITE_SUPPORT
  13949         if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  13950             /* Allocate additional nodes equal to amount of physical nodes.
  13951              * This is to hold the subport nodes which are reused with physical nodes */
  13952             mmu_info_p->max_nodes[_BCM_KT2_COSQ_NODE_LEVEL_S1] += SOC_INFO(unit).cpu_hg_index;
  13953         }
  13954 #endif
  13955     }
  13956     mmu_info_p->max_nodes[_BCM_KT2_COSQ_NODE_LEVEL_L0]   = 
  13957                                   soc_mem_index_count(unit, LLS_L0_CONFIGm);
  13958     mmu_info_p->max_nodes[_BCM_KT2_COSQ_NODE_LEVEL_L1]   = 
  13959                                   soc_mem_index_count(unit, LLS_L1_CONFIGm);
  13960     mmu_info_p->max_nodes[_BCM_KT2_COSQ_NODE_LEVEL_L2]   = 
  13961                                   mmu_info_p->num_queues;
  13962 
  13963     mmu_info_p->num_nodes = 0;
  13964 
  13965 
  13966     for (i= 0; i < _BCM_KT2_COSQ_NODE_LEVEL_L2; i++) {
  13967         mmu_info_p->num_nodes += mmu_info_p->max_nodes[i];
  13968     }
  13969 
  13970     si = &SOC_INFO(unit);
  13971 
  13972     num_pp_ports[unit] =  si->cpu_hg_pp_port_index;
  13973     num_port_schedulers[unit] = si->cpu_hg_index;
  13974 #if defined BCM_METROLITE_SUPPORT
  13975     if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  13976         num_pp_ports[unit] += num_port_schedulers[unit];
  13977     }
  13978 #endif
  13979 
  13980     pbmp_linkphy = soc_property_get_pbmp(unit, spn_PBMP_LINKPHY, 0);
  13981 
  13982     if (SOC_PBMP_NOT_NULL(pbmp_linkphy)) {
  13983 #ifdef BCM_METROLITE_SUPPORT
  13984         if(SOC_IS_METROLITE(unit))  {
  13985            /* Metrolite doesn't have s0 schedulers */
  13986            num_s0_schedulers[unit] = 0;
  13987         } else
  13988 #endif
  13989         {
  13990            num_s0_schedulers[unit] = soc_mem_index_count(unit, LLS_S0_SHAPER_CONFIG_Cm);
  13991         }
  13992         num_s1_schedulers[unit] = soc_mem_index_count(unit, LLS_S1_SHAPER_CONFIG_Cm);
  13993     } else {
  13994         num_s0_schedulers[unit] = 0;
  13995         num_s1_schedulers[unit] = 0;
  13996     }
  13997     num_l0_schedulers[unit] = soc_mem_index_count(unit,LLS_L0_PARENTm);
  13998     num_l1_schedulers[unit] = soc_mem_index_count(unit,LLS_L1_PARENTm);;
  13999     num_l2_queues[unit]     = soc_mem_index_count(unit,LLS_L2_PARENTm);
  14000     max_l1_shaper_bucket[unit] = num_l1_schedulers[unit] /
  14001                                    soc_mem_index_count(unit,
  14002                                    LLS_L1_SHAPER_CONFIG_Cm);
  14003     if (SOC_IS_SABER2(unit)) {
  14004         max_l2_shaper_bucket[unit] = num_l2_queues[unit] /
  14005                                    soc_mem_index_count(unit,
  14006                                    LLS_L2_SHAPER_CONFIG_Cm);
  14007         l2_shaper_memory[unit][0] = LLS_L2_SHAPER_CONFIG_Cm;
  14008         l2_shaper_memory[unit][1] = LLS_L2_MIN_CONFIG_Cm;
  14009         l2_shaper_memory[unit][2] = INVALIDm;
  14010         l2_shaper_memory[unit][3] = INVALIDm;
  14011         soc_max_num_pp_ports[unit] = num_pp_ports[unit];
  14012     } else {
  14013         max_l2_shaper_bucket[unit] = num_l2_queues[unit] /
  14014                                    soc_mem_index_count(unit,
  14015                                    LLS_L2_SHAPER_CONFIG_LOWERm);
  14016         l2_shaper_memory[unit][0] = LLS_L2_SHAPER_CONFIG_LOWERm;
  14017         l2_shaper_memory[unit][1] = LLS_L2_MIN_CONFIG_LOWER_Cm;
  14018         l2_shaper_memory[unit][2] = LLS_L2_SHAPER_CONFIG_UPPERm;
  14019         l2_shaper_memory[unit][3] = LLS_L2_MIN_CONFIG_UPPER_Cm;
  14020     }
  14021 
  14022     num_total_schedulers[unit] = mmu_info_p->num_nodes;
  14023     LOG_VERBOSE(BSL_LS_BCM_COSQ,
  14024               (BSL_META_U(unit,
  14025                           "Useful Info:\n"
  14026                           "num_pp_ports[unit]:%d num_port_schedulers[unit]:%d num_s0_schedulers[unit]:%d\n"
  14027                           "num_s1_schedulers[unit]:%d num_l0_schedulers[unit]:%d num_l1_schedulers[unit]:%d\n"
  14028                           "num_l2_queues[unit]:%d num_total_schedulers[unit]:%d\n"),
  14029                num_pp_ports[unit], num_port_schedulers[unit], num_s0_schedulers[unit],
  14030                num_s1_schedulers[unit], num_l0_schedulers[unit], num_l1_schedulers[unit],
  14031                num_l2_queues[unit], num_total_schedulers[unit]));
  14032 
  14033     mmu_info_p->port = _bcm_kt2_cosq_alloc_clear((soc_max_num_pp_ports[unit] *
  14034                                             sizeof(_bcm_kt2_cosq_port_info_t)),
  14035                                             "port_info");
  14036     if (mmu_info_p->port == NULL) {
  14037         _bcm_kt2_cosq_free_memory(mmu_info_p);
  14038         return BCM_E_MEMORY;
  14039     }
  14040 
  14041     mmu_info_p->sched_node = _bcm_kt2_cosq_alloc_clear(((num_total_schedulers[unit]) *
  14042                                             sizeof(_bcm_kt2_cosq_node_t)),
  14043                                             "sched_node");
  14044     if (mmu_info_p->sched_node == NULL) {
  14045         _bcm_kt2_cosq_free_memory(mmu_info_p);
  14046         return BCM_E_MEMORY;
  14047     }
  14048 
  14049     mmu_info_p->queue_node = _bcm_kt2_cosq_alloc_clear(((num_l2_queues[unit]) *
  14050                                             sizeof(_bcm_kt2_cosq_node_t)),
  14051                                             "queue_node");
  14052     if (mmu_info_p->queue_node == NULL) {
  14053         _bcm_kt2_cosq_free_memory(mmu_info_p);
  14054         return BCM_E_MEMORY;
  14055     }
  14056 
  14057     mmu_info_p->global_qlist.bits  = _bcm_kt2_cosq_alloc_clear(
  14058                                   SHR_BITALLOCSIZE(mmu_info_p->num_queues),
  14059                                    "global_qlist");
  14060     if (mmu_info_p->global_qlist.bits == NULL) {
  14061         _bcm_kt2_cosq_free_memory(mmu_info_p);
  14062         return BCM_E_MEMORY;
  14063     }
  14064     
  14065     mmu_info_p->l2_global_qlist.bits  = _bcm_kt2_cosq_alloc_clear(
  14066                                   SHR_BITALLOCSIZE(mmu_info_p->num_queues),
  14067                                    "l2_global_qlist");
  14068     if (mmu_info_p->l2_global_qlist.bits == NULL) {
  14069         _bcm_kt2_cosq_free_memory(mmu_info_p);
  14070         return BCM_E_MEMORY;
  14071     }
  14072     for (port = 0; port < (si->lb_port + 1); port++) {
  14073 
  14074         if (SOC_IS_SABER2(unit) && (!SOC_IS_METROLITE(unit)) &&
  14075             soc_saber2_port_is_unused(unit, port)) {
  14076             continue;
  14077         }
  14078 
  14079         SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval));
  14080         if(SOC_WARM_BOOT(unit) && !(IS_LB_PORT(unit, port))) {
  14081            /* In case of warmboot the queue base is restored 
  14082             * from the hardware.
  14083             */ 
  14084            qbase = soc_reg_field_get(unit, ING_COS_MODEr, rval,
  14085                                          BASE_QUEUE_NUMf);
  14086            mmu_info_p->port[port].q_offset =qbase;
  14087            
  14088            i = soc_reg_field_get(unit, ING_COS_MODEr, rval,
  14089                                  SERVICE_BASE_QUEUE_NUMf);
  14090            mmu_info_p->port[port].uc_vlan_base = i ? i :
  14091                                                  mmu_info_p->num_queues -1;
  14092 
  14093            if (IS_HG_PORT(unit, port)) {
  14094                qoffset = KT2_HG_NUM_PHYSICAL_QUEUES ; 
  14095            
  14096            } else if (IS_CPU_PORT(unit,port)) { 
  14097                       qoffset = KT2_CPU_NUM_PHYSICAL_QUEUES ;
  14098            } else {
  14099                       qoffset = KT2_DEFAULT_NUM_PHYSICAL_QUEUES;
  14100            }
  14101            mmu_info_p->port[port].q_limit = qbase + qoffset; 
  14102            si->port_uc_cosq_base[port] =  mmu_info_p->port[port].q_offset ; 
  14103            si->port_num_uc_cosq[port] = qoffset;
  14104         }
  14105         else {  
  14106            mmu_info_p->port[port].q_offset = si->port_uc_cosq_base[port];
  14107             mmu_info_p->port[port].q_limit = si->port_uc_cosq_base[port] + 
  14108                                          si->port_num_uc_cosq[port];
  14109         } 
  14110         /* reserve the queues for the ports from the global bitmap */ 
  14111         BCM_IF_ERROR_RETURN
  14112          (_bcm_kt2_node_index_set(&mmu_info_p->l2_global_qlist,
  14113                                  mmu_info_p->port[port].q_offset,
  14114                                  (mmu_info_p->port[port].q_limit -
  14115                                  mmu_info_p->port[port].q_offset)));
  14116         BCM_IF_ERROR_RETURN
  14117         (_bcm_kt2_node_index_set(&mmu_info_p->global_qlist,
  14118                                  mmu_info_p->port[port].q_offset,
  14119                                  (mmu_info_p->port[port].q_limit -
  14120                                  mmu_info_p->port[port].q_offset)));
  14121 
  14122 
  14123         soc_reg_field_set(unit, ING_COS_MODEr, &rval, BASE_QUEUE_NUMf,
  14124                       mmu_info_p->port[port].q_offset);
  14125         if (IS_LB_PORT(unit, port)) {
  14126             /* Loopback port base starts from 64 */
  14127             soc_reg_field_set(unit, ING_COS_MODEr, &rval, BASE_QUEUE_NUMf,
  14128                               _BCM_KT2_LB_BASE_QUEUE);
  14129         }
  14130         if (IS_HG_PORT(unit, port)) {
  14131             soc_reg_field_set(unit, ING_COS_MODEr, &rval, COS_MODEf, 2);  
  14132         }
  14133         SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, rval));
  14134         
  14135         if (si->port_num_subport[port] > 0) {
  14136             start_pp_port = si->port_subport_base[port];
  14137             end_pp_port = si->port_subport_base[port] +
  14138             si->port_num_subport[port];
  14139 
  14140 #if defined BCM_METROLITE_SUPPORT
  14141             if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  14142                 SOC_PBMP_ITER(SOC_PORT_PP_BITMAP(unit, port), i) {
  14143                     SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, i, &rval));
  14144                     if(SOC_WARM_BOOT(unit)) { 
  14145                     qbase =soc_reg_field_get(unit,ING_COS_MODEr, rval,
  14146                                                             BASE_QUEUE_NUMf);
  14147                     mmu_info_p->port[i].q_offset =qbase;
  14148                     mmu_info_p->port[i].q_limit = qbase + 8 ; 
  14149                     si->port_uc_cosq_base[i] = mmu_info_p->port[i].q_offset;
  14150                     si->port_num_uc_cosq[i] = qoffset ;
  14151                     }
  14152                     else {  
  14153                     mmu_info_p->port[i].q_offset = si->port_uc_cosq_base[i];
  14154                     mmu_info_p->port[i].q_limit = si->port_uc_cosq_base[i] +
  14155                                                 si->port_num_uc_cosq[i];
  14156                     } 
  14157             
  14158                     BCM_IF_ERROR_RETURN
  14159                     (_bcm_kt2_node_index_set(&mmu_info_p->l2_global_qlist,
  14160                                     mmu_info_p->port[i].q_offset,
  14161                                     (mmu_info_p->port[i].q_limit -
  14162                                     mmu_info_p->port[i].q_offset)));
  14163                     BCM_IF_ERROR_RETURN
  14164                     (_bcm_kt2_node_index_set(&mmu_info_p->global_qlist,
  14165                                     mmu_info_p->port[i].q_offset,
  14166                                     (mmu_info_p->port[i].q_limit -
  14167                                     mmu_info_p->port[i].q_offset)));
  14168 
  14169                     soc_reg_field_set(unit, ING_COS_MODEr, &rval, BASE_QUEUE_NUMf,
  14170                                     mmu_info_p->port[i].q_offset);
  14171                     SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, i, rval)); 
  14172                 }
  14173             } else 
  14174 #endif
  14175             {
  14176                 for (i = start_pp_port; i < end_pp_port; i++) {
  14177                     SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, i, &rval));
  14178                     if(SOC_WARM_BOOT(unit)) { 
  14179                     qbase =soc_reg_field_get(unit,ING_COS_MODEr, rval,
  14180                                                             BASE_QUEUE_NUMf);
  14181                     mmu_info_p->port[i].q_offset =qbase;
  14182                     mmu_info_p->port[i].q_limit = qbase + 8 ; 
  14183                     si->port_uc_cosq_base[i] = mmu_info_p->port[i].q_offset;
  14184                     si->port_num_uc_cosq[i] = qoffset ;
  14185                     }
  14186                     else {  
  14187                     mmu_info_p->port[i].q_offset = si->port_uc_cosq_base[i];
  14188                     mmu_info_p->port[i].q_limit = si->port_uc_cosq_base[i] +
  14189                                                 si->port_num_uc_cosq[i];
  14190                     } 
  14191             
  14192                     BCM_IF_ERROR_RETURN
  14193                     (_bcm_kt2_node_index_set(&mmu_info_p->l2_global_qlist,
  14194                                     mmu_info_p->port[i].q_offset,
  14195                                     (mmu_info_p->port[i].q_limit -
  14196                                     mmu_info_p->port[i].q_offset)));
  14197                     BCM_IF_ERROR_RETURN
  14198                     (_bcm_kt2_node_index_set(&mmu_info_p->global_qlist,
  14199                                     mmu_info_p->port[i].q_offset,
  14200                                     (mmu_info_p->port[i].q_limit -
  14201                                     mmu_info_p->port[i].q_offset)));
  14202 
  14203                     soc_reg_field_set(unit, ING_COS_MODEr, &rval, BASE_QUEUE_NUMf,
  14204                                     mmu_info_p->port[i].q_offset);
  14205                     SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, i, rval)); 
  14206                 }
  14207             }
  14208         }
  14209 
  14210         SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval));
  14211 
  14212         if (soc_feature(unit, soc_feature_mmu_packing)) {
  14213             if(SOC_WARM_BOOT(unit)) { 
  14214                qbase =  soc_reg_field_get(unit, RQE_PP_PORT_CONFIGr, 
  14215                                                    rval, BASE_QUEUEf);
  14216                mmu_info_p->port[port].mcq_offset =qbase ;
  14217                if (IS_HG_PORT(unit, port)) {
  14218                    qoffset = KT2_HG_NUM_PHYSICAL_QUEUES ; 
  14219                } else if (IS_CPU_PORT(unit, port)) { 
  14220                           qoffset = KT2_CPU_NUM_PHYSICAL_QUEUES ;
  14221                } else {
  14222                           qoffset = KT2_DEFAULT_NUM_PHYSICAL_QUEUES;
  14223                }
  14224                mmu_info_p->port[port].mcq_limit = qbase + qoffset;  
  14225                si->port_cosq_base[port] = mmu_info_p->port[port].mcq_offset;
  14226                si->port_num_cosq[port] =  qoffset;
  14227            }
  14228            else { 
  14229                    mmu_info_p->port[port].mcq_offset = si->port_cosq_base[port];
  14230                    mmu_info_p->port[port].mcq_limit = si->port_cosq_base[port] +
  14231                                                       si->port_num_cosq[port];                                         
  14232            } 
  14233             BCM_IF_ERROR_RETURN
  14234             (_bcm_kt2_node_index_set(&mmu_info_p->l2_global_qlist,
  14235                                  mmu_info_p->port[port].mcq_offset,
  14236                                  (mmu_info_p->port[port].mcq_limit -
  14237                                  mmu_info_p->port[port].mcq_offset)));
  14238             BCM_IF_ERROR_RETURN
  14239             (_bcm_kt2_node_index_set(&mmu_info_p->global_qlist,
  14240                                  mmu_info_p->port[port].mcq_offset,
  14241                                  (mmu_info_p->port[port].mcq_limit -
  14242                                  mmu_info_p->port[port].mcq_offset)));
  14243         }
  14244         soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr, &rval, BASE_QUEUEf,
  14245                           (soc_feature(unit, soc_feature_mmu_packing)) ? 
  14246                           mmu_info_p->port[port].mcq_offset :
  14247                           mmu_info_p->port[port].q_offset);
  14248 
  14249         if (IS_EXT_MEM_PORT(unit, port)) {
  14250             if (SOC_REG_FIELD_VALID(unit, RQE_PP_PORT_CONFIGr, BUFF_TYPEf)) {
  14251                 soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr,
  14252                                   &rval, BUFF_TYPEf, 1);
  14253             }
  14254         }    
  14255         if (IS_LB_PORT(unit, port)) {
  14256             soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr, &rval, BASE_QUEUEf,
  14257                               _BCM_KT2_LB_BASE_QUEUE);
  14258         }
  14259         if (IS_HG_PORT(unit, port)) {
  14260             soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr,
  14261                               &rval, COS_MODEf, 2);
  14262         }   
  14263         SOC_IF_ERROR_RETURN(WRITE_RQE_PP_PORT_CONFIGr(unit, port, rval));
  14264 
  14265         if (si->port_num_subport[port] > 0) {
  14266 #if defined BCM_METROLITE_SUPPORT
  14267             if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  14268                 SOC_PBMP_ITER(SOC_PORT_PP_BITMAP(unit, port), i) {
  14269                     soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr, &rval, BASE_QUEUEf,
  14270                                     (soc_feature(unit, soc_feature_mmu_packing)) ?
  14271                                     mmu_info_p->port[port].mcq_offset :
  14272                                     mmu_info_p->port[i].q_offset);
  14273 
  14274                     SOC_IF_ERROR_RETURN(WRITE_RQE_PP_PORT_CONFIGr(unit, i, rval)); 
  14275                 }
  14276             } else 
  14277 #endif
  14278             {
  14279                 for (i = start_pp_port; i < end_pp_port; i++) {
  14280                     soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr, &rval, BASE_QUEUEf,
  14281                                     (soc_feature(unit, soc_feature_mmu_packing)) ?
  14282                                     mmu_info_p->port[port].mcq_offset :
  14283                                     mmu_info_p->port[i].q_offset);
  14284 
  14285                     SOC_IF_ERROR_RETURN(WRITE_RQE_PP_PORT_CONFIGr(unit, i, rval)); 
  14286                 }
  14287             }
  14288         }
  14289         
  14290         rval = 0;
  14291         soc_reg_field_set(unit, OP_E2ECC_PORT_CONFIGr, &rval, BASE_QUEUEf,
  14292                           mmu_info_p->port[port].q_offset);
  14293         if (IS_EXT_MEM_PORT(unit, port)) {
  14294             soc_reg_field_set(unit, OP_E2ECC_PORT_CONFIGr, &rval, 
  14295                               BUFF_TYPEf, 1);  
  14296         }    
  14297         if (!IS_LB_PORT(unit, port)) {
  14298             SOC_IF_ERROR_RETURN(WRITE_OP_E2ECC_PORT_CONFIGr(unit, port, rval));
  14299         }
  14300         for (i = mmu_info_p->port[port].q_offset;
  14301              i < mmu_info_p->port[port].q_limit; i++) {
  14302             SOC_IF_ERROR_RETURN (soc_mem_field32_modify(unit,
  14303                     EGR_QUEUE_TO_PP_PORT_MAPm, i, PP_PORTf, port));
  14304         }
  14305 
  14306         if (soc_feature(unit, soc_feature_mmu_packing)) {
  14307             for (i = mmu_info_p->port[port].mcq_offset;
  14308                  i < mmu_info_p->port[port].mcq_limit; i++) {
  14309                 SOC_IF_ERROR_RETURN (soc_mem_field32_modify(unit,
  14310                               EGR_QUEUE_TO_PP_PORT_MAPm, i, PP_PORTf, port));
  14311             }
  14312         }
  14313         if (!IS_LB_PORT(unit, port)) {
  14314             num_base_queues = mmu_info_p->port[port].q_limit;
  14315         }
  14316         if(!SOC_WARM_BOOT(unit)) {
  14317            mmu_info_p->port[port].uc_vlan_base = mmu_info_p->num_queues - 1;
  14318         }
  14319     }
  14320 
  14321     /* mmu_info-> num_base_queues is the maximum number of queue configured 
  14322      * or available with the system */
  14323     mmu_info_p->num_base_queues = mmu_info_p->num_queues; 
  14324 
  14325     mmu_info_p->num_dmvoq_queues = soc_property_get(unit, 
  14326                                                    spn_MMU_NUM_DMVOQ_QUEUES, 
  14327                                                    0);
  14328 
  14329     /* Config variable defining
  14330      * the number of pre reserved subscriber queues
  14331      * spn_MMU_NUM_SUBSCRIBER_QUEUES
  14332      */
  14333 
  14334     mmu_info_p->num_sub_queues = soc_property_get(unit,
  14335                                                    spn_MMU_NUM_SUBSCRIBER_QUEUES,
  14336                                                    0);
  14337 
  14338     mmu_info_p->num_ext_queues  = mmu_info_p->num_queues ; 
  14339                                   
  14340 
  14341     /* Pre reserved queues include DVMOQ and subscriber queues
  14342      * from extended queues
  14343      */
  14344     pre_alloc_queues = mmu_info_p->num_dmvoq_queues +
  14345                        mmu_info_p->num_sub_queues;
  14346 
  14347 
  14348     if (pre_alloc_queues > mmu_info_p->num_queues  ) {
  14349         _bcm_kt2_cosq_free_memory(mmu_info_p);
  14350         return BCM_E_MEMORY;
  14351     }
  14352 
  14353     mmu_info_p->base_dmvoq_queue =  (num_base_queues + 7) & 0xfffffff8;
  14354     
  14355     /* Check if number of dmvoq queue configured is not crossing limit */
  14356     if((mmu_info_p->base_dmvoq_queue + 
  14357         mmu_info_p->num_dmvoq_queues) > num_l2_queues[unit]) {
  14358         LOG_ERROR(BSL_LS_BCM_COMMON,
  14359                  (BSL_META_U(unit,
  14360                              "Configured value of number of DMVOQ"
  14361                              " queue %d more than allowed number %d\n"),
  14362                              mmu_info_p->num_dmvoq_queues,
  14363                              num_l2_queues[unit] - mmu_info_p->base_dmvoq_queue));
  14364         _bcm_kt2_cosq_free_memory(mmu_info_p);
  14365         return BCM_E_CONFIG; 
  14366     }
  14367 
  14368     BCM_IF_ERROR_RETURN
  14369     (_bcm_kt2_node_index_set(&mmu_info_p->l2_global_qlist,
  14370                              mmu_info_p->base_dmvoq_queue,
  14371                              mmu_info_p->num_dmvoq_queues 
  14372                             ));
  14373    BCM_IF_ERROR_RETURN
  14374    (_bcm_kt2_node_index_set(&mmu_info_p->global_qlist,
  14375                              mmu_info_p->base_dmvoq_queue,
  14376                              mmu_info_p->num_dmvoq_queues 
  14377                             ));
  14378 
  14379     mmu_info_p->qset_size       = soc_property_get(unit, 
  14380                                               spn_MMU_SUBSCRIBER_NUM_COS_LEVEL, 
  14381                                               1);
  14382 
  14383     mmu_info_p->l1_gport_pair = _bcm_kt2_cosq_alloc_clear(
  14384                                  (mmu_info_p->num_nodes * sizeof(bcm_gport_t)),
  14385                                  "l1_pair_info");
  14386     if (mmu_info_p->l1_gport_pair == NULL) {
  14387         _bcm_kt2_cosq_free_memory(mmu_info_p);
  14388         return BCM_E_MEMORY;
  14389     }
  14390 
  14391 
  14392     if (mmu_info_p->num_dmvoq_queues > 0) {
  14393         mmu_info_p->dmvoq_qlist.bits  = _bcm_kt2_cosq_alloc_clear(
  14394                 SHR_BITALLOCSIZE(mmu_info_p->num_dmvoq_queues),
  14395                 "dmvoq_qlist");
  14396         if (mmu_info_p->dmvoq_qlist.bits == NULL) {
  14397             _bcm_kt2_cosq_free_memory(mmu_info_p);
  14398             return BCM_E_MEMORY;
  14399         }
  14400     }
  14401 
  14402 
  14403     mmu_info_p->sched_list.bits = _bcm_kt2_cosq_alloc_clear(
  14404                                   SHR_BITALLOCSIZE(mmu_info_p->num_nodes),
  14405                                   "sched_list");
  14406     if (mmu_info_p->sched_list.bits == NULL) {
  14407         _bcm_kt2_cosq_free_memory(mmu_info_p);
  14408         return BCM_E_MEMORY;
  14409     }
  14410 
  14411     for (i = _BCM_KT2_COSQ_NODE_LEVEL_S0; i < _BCM_KT2_COSQ_NODE_LEVEL_L2; 
  14412               i++) { 
  14413         mmu_info_p->sched_hw_list[i].bits = _bcm_kt2_cosq_alloc_clear(
  14414                                             SHR_BITALLOCSIZE
  14415                                             (mmu_info_p->max_nodes[i]),
  14416                                             "sched_hw_list");
  14417         if (mmu_info_p->sched_hw_list[i].bits == NULL) {
  14418             _bcm_kt2_cosq_free_memory(mmu_info_p);
  14419             return BCM_E_MEMORY;
  14420         }
  14421     }
  14422 
  14423     mmu_info_p->l2_base_qlist.bits = _bcm_kt2_cosq_alloc_clear(
  14424                                      SHR_BITALLOCSIZE
  14425                                      (mmu_info_p->num_queues),
  14426                                      "l2_base_qlist");
  14427     if (mmu_info_p->l2_base_qlist.bits == NULL) {
  14428         _bcm_kt2_cosq_free_memory(mmu_info_p);
  14429         return BCM_E_MEMORY;
  14430     }
  14431     
  14432     mmu_info_p->l2_base_mcqlist.bits = _bcm_kt2_cosq_alloc_clear(
  14433                                      SHR_BITALLOCSIZE
  14434                                      (mmu_info_p->num_queues),
  14435                                      "l2_base_mcqlist");
  14436     if (mmu_info_p->l2_base_mcqlist.bits == NULL) {
  14437         _bcm_kt2_cosq_free_memory(mmu_info_p);
  14438         return BCM_E_MEMORY;
  14439     }
  14440 
  14441 
  14442     if (mmu_info_p->num_dmvoq_queues > 0) {
  14443         mmu_info_p->l2_dmvoq_qlist.bits = _bcm_kt2_cosq_alloc_clear(
  14444                 SHR_BITALLOCSIZE
  14445                 (mmu_info_p->num_dmvoq_queues),
  14446                 "l2_dmvoq_qlist");
  14447         if (mmu_info_p->l2_dmvoq_qlist.bits == NULL) {
  14448             _bcm_kt2_cosq_free_memory(mmu_info_p);
  14449             return BCM_E_MEMORY;
  14450         }
  14451     }
  14452 
  14453     for (i = 0; i < num_total_schedulers[unit]; i++) {
  14454         _BCM_KT2_COSQ_LIST_NODE_INIT(mmu_info_p->sched_node, i);
  14455     }
  14456 
  14457     for (i = 0; i < num_l2_queues[unit]; i++) {
  14458         _BCM_KT2_COSQ_LIST_NODE_INIT(mmu_info_p->queue_node, i);
  14459     }
  14460 
  14461     /* reserve last entry of S0, S1, L0 and L1 nodes */
  14462     for (i = _BCM_KT2_COSQ_NODE_LEVEL_S0; i < _BCM_KT2_COSQ_NODE_LEVEL_L2; 
  14463              i++) { 
  14464         BCM_IF_ERROR_RETURN
  14465             (_bcm_kt2_node_index_set(&mmu_info_p->sched_hw_list[i], 
  14466             (mmu_info_p->max_nodes[i] - 1), 1));
  14467     }
  14468 
  14469     if (mmu_info_p->num_sub_queues) {
  14470        if (mmu_info_p->num_dmvoq_queues) {
  14471             /* Pre reserved DVMOQ
  14472              * Revisit as DVMOQ used the indices in multiples of 8
  14473              * hence used shift
  14474              */
  14475             mmu_info_p->base_sub_queue = (mmu_info_p->base_dmvoq_queue +
  14476                                          mmu_info_p->num_dmvoq_queues);
  14477 
  14478         }
  14479         else {
  14480             mmu_info_p->base_sub_queue = num_base_queues;
  14481         }
  14482         /* Check if number of sub queue configured is not crossing limit.
  14483          * Config variable mmu_num_subscriber_queues used to configure this */
  14484         total_sub_queues = mmu_info_p->base_sub_queue +
  14485                                                 mmu_info_p->num_sub_queues;
  14486         if (total_sub_queues > (soc_feature(unit, soc_feature_mmu_packing) ?
  14487                                 num_l2_queues[unit]/2 : num_l2_queues[unit] )) {
  14488             LOG_ERROR(BSL_LS_BCM_COMMON,
  14489                     (BSL_META_U(unit,
  14490                                 "Configured value of number of subscriber"
  14491                                 " queue %d more than allowed number %d\n"),
  14492                      mmu_info_p->num_sub_queues,
  14493                      ((soc_feature(unit, soc_feature_mmu_packing) ?
  14494                       num_l2_queues[unit] / 2 : num_l2_queues[unit]) - mmu_info_p->base_sub_queue)));
  14495             _bcm_kt2_cosq_free_memory(mmu_info_p);
  14496             return BCM_E_CONFIG;
  14497         }
  14498 
  14499         /*setting base sub queue as multiple of 8 same as DMVOQ*/
  14500         mmu_info_p->base_sub_queue =  (mmu_info_p->base_sub_queue + 7) & 0xfffffff8;
  14501         
  14502         mmu_info_p->sub_qlist.bits  = _bcm_kt2_cosq_alloc_clear(
  14503              SHR_BITALLOCSIZE(mmu_info_p->num_sub_queues),
  14504              "sub_qlist");
  14505         if (mmu_info_p->sub_qlist.bits == NULL) {
  14506             _bcm_kt2_cosq_free_memory(mmu_info_p);
  14507             return BCM_E_MEMORY;
  14508         }
  14509 
  14510         mmu_info_p->l2_sub_qlist.bits = _bcm_kt2_cosq_alloc_clear(
  14511                  SHR_BITALLOCSIZE
  14512                  (mmu_info_p->num_sub_queues),
  14513                  "l2_sub_qlist");
  14514 
  14515         if (mmu_info_p->l2_sub_qlist.bits == NULL) {
  14516              _bcm_kt2_cosq_free_memory(mmu_info_p);
  14517              return BCM_E_MEMORY;
  14518         }
  14519 
  14520         BCM_IF_ERROR_RETURN
  14521          (_bcm_kt2_node_index_set(&mmu_info_p->l2_global_qlist,
  14522                                   mmu_info_p->base_sub_queue, 
  14523                                   mmu_info_p->num_sub_queues));
  14524         BCM_IF_ERROR_RETURN
  14525         (_bcm_kt2_node_index_set(&mmu_info_p->global_qlist,
  14526                                   mmu_info_p->base_sub_queue,
  14527                                   mmu_info_p->num_sub_queues));
  14528         if (soc_feature(unit, soc_feature_mmu_packing)) {
  14529             mmu_info_p->sub_mcqlist.bits  = _bcm_kt2_cosq_alloc_clear(
  14530             SHR_BITALLOCSIZE(mmu_info_p->num_sub_queues),
  14531             "sub_mcqlist");
  14532             if (mmu_info_p->sub_mcqlist.bits == NULL) {
  14533                 _bcm_kt2_cosq_free_memory(mmu_info_p);
  14534                 return BCM_E_MEMORY;
  14535             }
  14536 
  14537             mmu_info_p->l2_sub_mcqlist.bits = _bcm_kt2_cosq_alloc_clear(
  14538                  SHR_BITALLOCSIZE
  14539                  (mmu_info_p->num_sub_queues),
  14540                  "l2_sub_mcqlist");
  14541 
  14542             if (mmu_info_p->l2_sub_mcqlist.bits == NULL) {
  14543                 _bcm_kt2_cosq_free_memory(mmu_info_p);
  14544                 return BCM_E_MEMORY;
  14545             }
  14546 
  14547             BCM_IF_ERROR_RETURN
  14548             (_bcm_kt2_node_index_set(&mmu_info_p->l2_global_qlist,
  14549                                   mmu_info_p->base_sub_queue +
  14550                                   mmu_info_p->num_queues/2,
  14551                                   mmu_info_p->num_sub_queues));
  14552         BCM_IF_ERROR_RETURN
  14553         (_bcm_kt2_node_index_set(&mmu_info_p->global_qlist,
  14554                                   mmu_info_p->base_sub_queue +
  14555                                   mmu_info_p->num_queues/2,
  14556                                   mmu_info_p->num_sub_queues));
  14557         }
  14558 
  14559     }else {
  14560        mmu_info_p->base_sub_queue = 0;
  14561     }
  14562 
  14563     if (!SOC_WARM_BOOT(unit)) {    /* Cold Boot */
  14564         /* create LLS tree for CPU */
  14565         port = KT2_CMIC_PORT;
  14566         BCM_IF_ERROR_RETURN
  14567             (bcm_kt2_cosq_gport_add(unit, port, SOC_CMCS_NUM(unit) + 1,
  14568                            0, &port_sched));
  14569         for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) {
  14570              if (NUM_CPU_ARM_COSQ(unit, cmc) == 0) {
  14571                  continue;
  14572              }
  14573              cosq = (NUM_CPU_ARM_COSQ(unit, cmc) + 7) / 8;
  14574 
  14575              /*    coverity[uninit_use_in_call : FALSE]    */
  14576              BCM_IF_ERROR_RETURN
  14577                  (bcm_kt2_cosq_gport_add(unit, port, cosq, 
  14578                                BCM_COSQ_GPORT_SCHEDULER, &l0_sched));
  14579              BCM_IF_ERROR_RETURN
  14580                  (bcm_kt2_cosq_gport_attach(unit, l0_sched, port_sched, cmc));
  14581              cosq = 0;
  14582              num_queues = NUM_CPU_ARM_COSQ(unit, cmc);
  14583              for (i = 0; i < NUM_CPU_ARM_COSQ(unit, cmc); i++) {
  14584                  if (i % 8 == 0) {
  14585                      num_inputs = (num_queues >= 8) ? 8 : num_queues;
  14586                      BCM_IF_ERROR_RETURN
  14587                          (bcm_kt2_cosq_gport_add(unit, port, num_inputs,
  14588                                         BCM_COSQ_GPORT_SCHEDULER,
  14589                                         &l1_sched));
  14590                      BCM_IF_ERROR_RETURN
  14591                           (bcm_kt2_cosq_gport_attach(unit, l1_sched, 
  14592                                                      l0_sched, cosq));  
  14593                      cosq++;
  14594                      num_queues -= num_inputs;
  14595                  } 
  14596                  BCM_IF_ERROR_RETURN
  14597                      (bcm_kt2_cosq_gport_add(unit, port, 1,
  14598                                   BCM_COSQ_GPORT_UCAST_QUEUE_GROUP, &queue));
  14599                  BCM_IF_ERROR_RETURN
  14600                      (bcm_kt2_cosq_gport_attach(unit, queue, l1_sched, 
  14601                                                 (i % 8)));  
  14602 
  14603              }
  14604         }
  14605 
  14606         /* Reserve additional L0 node for RPE as indicated for
  14607          * flow control from MMU to CMIC block, Refer the register
  14608          * LLS_FC_CONFIG - FC_CFG_COSMASK_L0_MAP
  14609          */
  14610         /*    coverity[uninit_use_in_call : FALSE]    */
  14611         BCM_IF_ERROR_RETURN
  14612             (bcm_kt2_cosq_gport_add(unit, port, -1,
  14613                                BCM_COSQ_GPORT_SCHEDULER, &l0_sched));
  14614         BCM_IF_ERROR_RETURN
  14615             (bcm_kt2_cosq_gport_attach(unit, l0_sched, port_sched, cmc));
  14616 
  14617         /* create LLS tree for Loopback port*/
  14618         port = LB_PORT(unit);;
  14619         BCM_IF_ERROR_RETURN
  14620             (_bcm_kt2_port_lls_config_set(unit, port, 
  14621              si->port_uc_cosq_base[port], si->port_num_uc_cosq[port], numq));
  14622 
  14623         
  14624         for (port = 1; port < si->lb_port ; port++) {
  14625              /* don't create lls for invalid port */
  14626              if (!SOC_PORT_VALID(unit, port)) {
  14627                  continue;
  14628              }
  14629              if (SOC_IS_SABER2(unit) && (!SOC_IS_METROLITE(unit)) &&
  14630                  soc_saber2_port_is_unused(unit, port)) {
  14631                  continue;
  14632              }
  14633 #if defined BCM_METROLITE_SUPPORT
  14634              if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  14635                 if (_SOC_IS_PORT_LINKPHY_SUBTAG(unit, port)) {
  14636                     numq = si->port_num_uc_cosq[port];
  14637                 } else {
  14638                     numq = soc_property_get(unit, spn_BCM_NUM_COS, BCM_COS_DEFAULT);
  14639                     if (numq < 1) {
  14640                         numq = 1;
  14641                     } else if (numq > 8) {
  14642                         numq = 8;
  14643                     }
  14644                 }
  14645                 if (!(_SOC_IS_PORT_LINKPHY_SUBTAG(unit, port)) &&
  14646                     _SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, port)) {
  14647                     continue;
  14648                 }
  14649              }
  14650 #endif
  14651              if (IS_HG_PORT(unit, port)) {
  14652                  BCM_IF_ERROR_RETURN
  14653                      (_bcm_kt2_port_lls_config_set(unit, port, 
  14654                       si->port_uc_cosq_base[port], 
  14655                       si->port_num_uc_cosq[port], 
  14656                       numq));
  14657              } else {
  14658                  if (!soc_feature(unit, soc_feature_mmu_packing)) {
  14659                     BCM_IF_ERROR_RETURN
  14660                     (bcm_kt2_cosq_gport_add(unit, port, 1, 0, &port_sched));
  14661                     BCM_IF_ERROR_RETURN
  14662                     (bcm_kt2_cosq_gport_add(unit, port, 1, 
  14663                                         BCM_COSQ_GPORT_SCHEDULER, 
  14664                                         &l0_sched));
  14665                     BCM_IF_ERROR_RETURN
  14666                     (bcm_kt2_cosq_gport_attach(unit, l0_sched, port_sched, 0)); 
  14667                     BCM_IF_ERROR_RETURN
  14668                     (bcm_kt2_cosq_gport_add(unit, port, numq, 
  14669                                         BCM_COSQ_GPORT_SCHEDULER, 
  14670                                         &l1_sched));
  14671                     BCM_IF_ERROR_RETURN
  14672                     (bcm_kt2_cosq_gport_attach(unit, l1_sched, l0_sched, 0));  
  14673                     for (cosq = 0; cosq < numq; cosq++) {
  14674                         BCM_IF_ERROR_RETURN
  14675                         (bcm_kt2_cosq_gport_add(unit, port, 1,
  14676                                 BCM_COSQ_GPORT_UCAST_QUEUE_GROUP, &queue));
  14677                         BCM_IF_ERROR_RETURN
  14678                         (bcm_kt2_cosq_gport_attach(unit, queue, l1_sched, 
  14679                                                 cosq)); 
  14680                         BCM_IF_ERROR_RETURN
  14681                          (bcm_kt2_cosq_gport_sched_set(unit, l1_sched, cosq,
  14682                                                        BCM_COSQ_STRICT, 0)); 
  14683                    }
  14684                  }else {
  14685                     BCM_IF_ERROR_RETURN
  14686                     (_bcm_kt2_packing_config_set(unit, port, numq));
  14687                  }
  14688              }
  14689         }
  14690    } 
  14691     /* Initialize oob driver */
  14692     BCM_IF_ERROR_RETURN(_bcm_oob_init(unit));
  14693 
  14694     /* Add default entries for PORT_COS_MAP memory profile 
  14695      * for front panel ports 
  14696      */
  14697     BCM_IF_ERROR_RETURN(bcm_kt2_cosq_config_set(unit, numq));
  14698 
  14699     /* Add default entries for PORT_COS_MAP memory 
  14700      * profile for subports 
  14701      */
  14702     pp_port_cos = soc_property_port_get(unit, port,
  14703                                         spn_NUM_SUBPORT_COS, 4);
  14704 
  14705     BCM_IF_ERROR_RETURN(_bcm_kt2_subport_cosq_config_set(unit, pp_port_cos));
  14706 
  14707     /* setup subport specific LLS configuration */
  14708     BCM_IF_ERROR_RETURN(_bcm_kt2_subport_config_set(unit));
  14709 
  14710     if (!cosq_sync_lock[unit]) {
  14711         cosq_sync_lock[unit] = sal_mutex_create("KT2 cosq sync lock");
  14712         if (cosq_sync_lock[unit] == NULL) {
  14713             return BCM_E_MEMORY;
  14714         }
  14715     }
  14716 
  14717 #ifdef BCM_WARM_BOOT_SUPPORT
  14718     if (SOC_WARM_BOOT(unit)) {
  14719         if (!SOC_IS_METROLITE(unit)) {
  14720             SOC_PBMP_CLEAR(si->pbm_ext_mem);
  14721             for (port = 1; port < si->lb_port; port++) {
  14722                  SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval));
  14723                  if (soc_reg_field_get(unit, RQE_PP_PORT_CONFIGr, rval, BUFF_TYPEf)) {
  14724                      SOC_PBMP_PORT_ADD(si->pbm_ext_mem, port);
  14725                  }
  14726             }
  14727         }
  14728         return bcm_kt2_cosq_reinit(unit);
  14729     } else {
  14730         BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_wb_alloc(unit));
  14731     }
  14732 #endif /* BCM_WARM_BOOT_SUPPORT */
  14733 
  14734     
  14735    sal_memset(rval64s, 0, sizeof(rval64s));
  14736    prval64s[0] = rval64s;
  14737    profile_index = 0xffffffff;
  14738    PBMP_PORT_ITER(unit, port) {
  14739      if (profile_index == 0xffffffff) {
  14740          BCM_IF_ERROR_RETURN
  14741          (soc_profile_reg_add(unit, _bcm_kt2_llfc_profile[unit],
  14742                               prval64s, 16, &profile_index));
  14743      } else {
  14744          BCM_IF_ERROR_RETURN
  14745          (soc_profile_reg_reference(unit, _bcm_kt2_llfc_profile[unit],
  14746                                                profile_index, 0));
  14747      }
  14748    }
  14749     sal_memset(&entry_tcp_green, 0, sizeof(entry_tcp_green));
  14750     sal_memset(&entry_tcp_yellow, 0, sizeof(entry_tcp_yellow));
  14751     sal_memset(&entry_tcp_red, 0, sizeof(entry_tcp_red));
  14752     sal_memset(&entry_nontcp_green, 0, sizeof(entry_nontcp_green));
  14753     sal_memset(&entry_nontcp_yellow, 0, sizeof(entry_nontcp_yellow));
  14754     sal_memset(&entry_nontcp_red, 0, sizeof(entry_nontcp_red));
  14755     entries[0] = &entry_tcp_green;
  14756     entries[1] = &entry_tcp_yellow;
  14757     entries[2] = &entry_tcp_red;
  14758     entries[3] = &entry_nontcp_green;
  14759     entries[4] = &entry_nontcp_yellow;
  14760     entries[5] = &entry_nontcp_red;
  14761     max_threshold = (1 << soc_mem_field_length(unit, 
  14762                      MMU_WRED_DROP_CURVE_PROFILE_0m, MAX_THDf)) - 1;
  14763     min_threshold = (1 << soc_mem_field_length(unit, 
  14764                      MMU_WRED_DROP_CURVE_PROFILE_0m, MIN_THDf)) - 1;    
  14765     for (i = 0; i < 6; i++) {
  14766         soc_mem_field32_set(unit, wred_mems[i], entries[i], MIN_THDf,
  14767                             max_threshold);
  14768         soc_mem_field32_set(unit, wred_mems[i], entries[i], MAX_THDf,
  14769                             min_threshold);
  14770     }    
  14771     profile_index = 0xffffffff;
  14772     for (port = 0; port < (si->lb_port + 1); port++) {
  14773         if (SOC_IS_SABER2(unit) && (!SOC_IS_METROLITE(unit)) &&
  14774             soc_saber2_port_is_unused(unit, port)) {
  14775             continue;
  14776         }
  14777         BCM_IF_ERROR_RETURN
  14778             (_bcm_kt2_cosq_index_resolve(unit, port, -1,
  14779                                         _BCM_KT2_COSQ_INDEX_STYLE_WRED, NULL,
  14780                                         NULL, &numq));
  14781         for (cosq = 0; cosq < numq; cosq++) {
  14782             if (profile_index == 0xffffffff) {
  14783                 BCM_IF_ERROR_RETURN
  14784                     (soc_profile_mem_add(unit, _bcm_kt2_wred_profile[unit],
  14785                                          entries, 1, &profile_index));
  14786             } else {
  14787                 BCM_IF_ERROR_RETURN
  14788                     (soc_profile_mem_reference(unit,
  14789                                                _bcm_kt2_wred_profile[unit],
  14790                                                profile_index, 0));
  14791             }
  14792         }
  14793     }
  14794     /*
  14795      * Set all CPU queues to disable enqueue.  Enqueue will be enabled when
  14796      * RX DMA is enabled. This is to prevent packets from getting wedged in
  14797      * the CMIC when they don't have a means of egressing from the CMIC.
  14798      */
  14799     if (!(SAL_BOOT_SIMULATION) && !SOC_IS_RCPU_ONLY(unit)) {
  14800         for (i = 0; i < NUM_CPU_COSQ(unit); i++) {
  14801             rval = 0;
  14802             soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_ID0f, i);
  14803             soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_NUMf, 1);
  14804             soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_ACTIVEf, 1);
  14805             if (SOC_PBMP_MEMBER (PBMP_EXT_MEM (unit), CMIC_PORT(unit))) {
  14806                 soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_EXTERNALf, 1);
  14807             }
  14808             SOC_IF_ERROR_RETURN(WRITE_TOQ_FLUSH0r(unit, rval));
  14809             while (rval) {
  14810                 SOC_IF_ERROR_RETURN(READ_TOQ_FLUSH0r(unit, &rval));
  14811                 rval = soc_reg_field_get(unit, TOQ_FLUSH0r, rval,
  14812                                          FLUSH_ACTIVEf);
  14813             }
  14814             rval = 0;
  14815             soc_reg_field_set(unit, TOQ_ERROR2r, &rval, FLUSH_COMPLETEf, 1);
  14816             SOC_IF_ERROR_RETURN(WRITE_TOQ_ERROR2r(unit, rval));
  14817         }
  14818     }
  14819 
  14820     mmu_info_p->curr_merger_index[0] = 1;
  14821     mmu_info_p->curr_merger_index[1] = 0;
  14822     mmu_info_p->curr_merger_index[2] = 0;
  14823     mmu_info_p->curr_merger_index[3] = 0;
  14824 
  14825     if (SOC_IS_SABER2(unit)) {
  14826         if (!SOC_WARM_BOOT(unit)) { /* Cold Boot */
  14827             WRITE_CMIC_CMC0_CH1_COS_CTRL_RX_1r(unit, 0xfffff);
  14828         }
  14829     }
  14830     /* Clear Counters */
  14831     if (!SOC_WARM_BOOT(unit)) {
  14832        BCM_IF_ERROR_RETURN(_bcm_kt2_init_all_queue_counters(unit));
  14833     } 
  14834     /*
  14835      * Enable the MMU to CPU flow control
  14836      * per L0 nodes
  14837      */
  14838     BCM_IF_ERROR_RETURN
  14839        (_bcm_kt2_cosq_cpu_fc_set(unit)); 
  14840      BCM_IF_ERROR_RETURN
  14841         (bcm_kt2_init_fc_map_tbl(unit));
  14842     return BCM_E_NONE;
  14843 }
  14844 
  14845 /*
  14846  * Function:
  14847  *     bcm_kt2_cosq_detach
  14848  * Purpose:
  14849  *     Discard all COS schedule/mapping state.
  14850  * Parameters:
  14851  *     unit - unit number
  14852  * Returns:
  14853  *     BCM_E_XXX
  14854  */
  14855 int
  14856 bcm_kt2_cosq_detach(int unit, int software_state_only)
  14857 {
  14858     if (_bcm_kt2_cos_map_profile[unit] != NULL) {
  14859         SOC_IF_ERROR_RETURN(soc_profile_mem_destroy(unit,
  14860                             _bcm_kt2_cos_map_profile[unit]));
  14861         sal_free(_bcm_kt2_cos_map_profile[unit]);
  14862         _bcm_kt2_cos_map_profile[unit] = NULL;
  14863     }
  14864     if (_bcm_kt2_egr_cos_map_profile[unit] != NULL) {
  14865         SOC_IF_ERROR_RETURN(soc_profile_mem_destroy(unit,
  14866                             _bcm_kt2_egr_cos_map_profile[unit]));
  14867         sal_free(_bcm_kt2_egr_cos_map_profile[unit]);
  14868         _bcm_kt2_egr_cos_map_profile[unit] = NULL;
  14869     }
  14870     if (_bcm_kt2_ifp_cos_map_profile[unit] != NULL) {
  14871         SOC_IF_ERROR_RETURN(soc_profile_mem_destroy(unit,
  14872                             _bcm_kt2_ifp_cos_map_profile[unit]));
  14873         sal_free(_bcm_kt2_ifp_cos_map_profile[unit]);
  14874         _bcm_kt2_ifp_cos_map_profile[unit] = NULL;
  14875     }
  14876     if (_bcm_kt2_wred_profile[unit] != NULL) {
  14877         SOC_IF_ERROR_RETURN(soc_profile_mem_destroy(unit,
  14878                             _bcm_kt2_wred_profile[unit]));
  14879         sal_free(_bcm_kt2_wred_profile[unit]);
  14880         _bcm_kt2_wred_profile[unit] = NULL;
  14881     }
  14882     if (_bcm_kt2_llfc_profile[unit] != NULL) {
  14883         SOC_IF_ERROR_RETURN(soc_profile_reg_destroy(unit,
  14884                             _bcm_kt2_llfc_profile[unit]));
  14885         sal_free(_bcm_kt2_llfc_profile[unit]);
  14886         _bcm_kt2_llfc_profile[unit] = NULL;
  14887     }
  14888     if (_bcm_kt2_mmu_info[unit] != NULL) {
  14889         _bcm_kt2_cosq_free_memory(_bcm_kt2_mmu_info[unit]);
  14890         sal_free(_bcm_kt2_mmu_info[unit]);
  14891         _bcm_kt2_mmu_info[unit] = NULL;
  14892     }
  14893     if (cosq_sync_lock[unit]) {
  14894         sal_mutex_destroy(cosq_sync_lock[unit]);
  14895         cosq_sync_lock[unit] = NULL;
  14896     }
  14897     return BCM_E_NONE;
  14898 }
  14899 
  14900 /*
  14901  * Function:
  14902  *     _bcm_kt2_subport_cosq_config_set
  14903  * Purpose:
  14904  *     Set the number of COS queues for subports.
  14905  * Parameters:
  14906  *     unit - unit number
  14907  *     numq - number of COS queues (1-8).
  14908  * Returns:
  14909  *     BCM_E_XXX
  14910  */
  14911 int
  14912 _bcm_kt2_subport_cosq_config_set(int unit, int numq)
  14913 {
  14914     port_cos_map_entry_t cos_map_entries[16];
  14915     void *entries[1];
  14916     uint32 index , egr_index;
  14917     int count;
  14918     bcm_port_t port;
  14919     int cos, prio;
  14920     uint32 i;
  14921     bcm_pbmp_t      subport_pbmp;
  14922 
  14923     BCM_PBMP_CLEAR(subport_pbmp);
  14924     BCM_PBMP_ASSIGN(subport_pbmp, SOC_INFO(unit).subtag_pp_port_pbm);
  14925     BCM_PBMP_OR(subport_pbmp, SOC_INFO(unit).linkphy_pp_port_pbm);
  14926 
  14927     if (numq < 1 || numq > 8) {
  14928         return BCM_E_PARAM;
  14929     }
  14930     SOC_PBMP_COUNT(subport_pbmp,count);
  14931     if (count == 0) {
  14932         return BCM_E_NONE;
  14933     }
  14934 
  14935     /* Distribute first 8 internal priority levels into the specified number
  14936      * of cosq, map remaining internal priority levels to highest priority
  14937      * cosq.
  14938      */
  14939     sal_memset(cos_map_entries, 0, sizeof(cos_map_entries));
  14940     entries[0] = &cos_map_entries;
  14941     prio = 0;
  14942     for (cos = 0; cos < numq; cos++) {
  14943         for (i = 8 / numq + (cos < 8 % numq ? 1 : 0); i > 0; i--) {
  14944             soc_mem_field32_set(unit, PORT_COS_MAPm, &cos_map_entries[prio],
  14945                                 COSf, cos);
  14946             prio++;
  14947         }
  14948     }
  14949     for (prio = 8; prio < 16; prio++) {
  14950         soc_mem_field32_set(unit, PORT_COS_MAPm, &cos_map_entries[prio], COSf,
  14951                             numq - 1);
  14952     }
  14953 
  14954     BCM_IF_ERROR_RETURN
  14955         (soc_profile_mem_add(unit, _bcm_kt2_cos_map_profile[unit], entries, 16,
  14956                              &index));
  14957     BCM_IF_ERROR_RETURN
  14958         (soc_profile_mem_add(unit, _bcm_kt2_egr_cos_map_profile[unit], entries, 16,
  14959                              &egr_index));
  14960 
  14961     PBMP_ITER(subport_pbmp, port) {
  14962         BCM_IF_ERROR_RETURN
  14963             (soc_mem_field32_modify(unit, COS_MAP_SELm, port, SELECTf,
  14964                                     index / 16));
  14965         BCM_IF_ERROR_RETURN
  14966             (soc_mem_field32_modify(unit, EGR_PORTm, port, EGR_COS_MAP_SELf,
  14967                                     egr_index / 16));
  14968 
  14969     }
  14970 
  14971     for (i = 0; i < count; i++) {
  14972         soc_profile_mem_reference(unit, _bcm_kt2_cos_map_profile[unit], index,
  14973                                   0);
  14974         soc_profile_mem_reference(unit, _bcm_kt2_egr_cos_map_profile[unit], egr_index,
  14975                 0);
  14976 
  14977     }
  14978 
  14979     return BCM_E_NONE;
  14980 }
  14981 
  14982 /*
  14983  * Function:
  14984  *     bcm_kt2_cosq_config_set
  14985  * Purpose:
  14986  *     Set the number of COS queues
  14987  * Parameters:
  14988  *     unit - unit number
  14989  *     numq - number of COS queues (1-8).
  14990  * Returns:
  14991  *     BCM_E_XXX
  14992  */
  14993 int
  14994 bcm_kt2_cosq_config_set(int unit, int numq)
  14995 {
  14996     port_cos_map_entry_t cos_map_entries[16];
  14997     void *entries[1], *hg_entries[1];
  14998     uint32 index, hg_index, egr_index;
  14999     int count, hg_count, egr_count;
  15000     bcm_port_t port;
  15001     int cos, prio;
  15002     uint32 i;
  15003     int cpu_hg_index = 0;
  15004 #ifdef BCM_COSQ_HIGIG_MAP_DISABLE
  15005     port_cos_map_entry_t hg_cos_map_entries[16];
  15006 #endif
  15007     bcm_pbmp_t      all_pbmp;
  15008     int *profile_ref_count, profile_count, ref_count, rv;
  15009     cos_map_sel_entry_t cos_map_sel_entry;
  15010 
  15011     BCM_PBMP_CLEAR(all_pbmp);
  15012     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  15013 
  15014  
  15015     if (numq < 1 || numq > 8) {
  15016         return BCM_E_PARAM;
  15017     }
  15018 
  15019     if(SOC_WARM_BOOT(unit)) {
  15020         _bcm_kt2_num_cosq[unit] = numq;
  15021         return BCM_E_NONE;
  15022     }
  15023 
  15024     profile_count = (soc_mem_index_count(unit, PORT_COS_MAPm) / 16);
  15025     profile_ref_count = sal_alloc(profile_count * sizeof(int), 
  15026                                     "Profile reference count");
  15027 
  15028     sal_memset(profile_ref_count, 0, profile_count * sizeof(int));
  15029 
  15030     if ( soc_feature(unit, soc_feature_flex_port)) {
  15031         rv = _bcm_kt2_flexio_pbmp_update(unit, &all_pbmp);
  15032         if (BCM_FAILURE(rv)) {
  15033             sal_free(profile_ref_count);
  15034             return rv;
  15035 	}
  15036     }
  15037 
  15038     /* Get the profile reference count for front panel ports. */
  15039     PBMP_ITER(all_pbmp, port) {
  15040         rv = READ_COS_MAP_SELm(unit, MEM_BLOCK_ANY, port, &cos_map_sel_entry);
  15041         if (BCM_FAILURE(rv)) {
  15042             sal_free(profile_ref_count);
  15043             return rv;
  15044         }
  15045         index = soc_mem_field32_get(unit, COS_MAP_SELm, &cos_map_sel_entry, SELECTf);
  15046         if (index >= profile_count) {
  15047             LOG_ERROR(BSL_LS_BCM_COMMON,
  15048                  (BSL_META_U(unit, 
  15049                  "Error. COS_MAP_SEL value %d greater than expected %d.\n"), index, profile_count));
  15050             sal_free(profile_ref_count);
  15051             return BCM_E_INTERNAL;
  15052         }
  15053         profile_ref_count[index]++;
  15054     }
  15055 
  15056     cpu_hg_index = SOC_INFO(unit).cpu_hg_pp_port_index;
  15057     if (cpu_hg_index != -1) {
  15058         rv = READ_COS_MAP_SELm(unit, MEM_BLOCK_ANY, cpu_hg_index, &cos_map_sel_entry);
  15059         if (BCM_FAILURE(rv)) {
  15060             sal_free(profile_ref_count);
  15061             return rv;
  15062         }
  15063         index = soc_mem_field32_get(unit, COS_MAP_SELm, &cos_map_sel_entry, SELECTf);
  15064         if (index >= profile_count) {
  15065             LOG_ERROR(BSL_LS_BCM_COMMON,
  15066                  (BSL_META_U(unit, 
  15067                  "Error. COS_MAP_SEL value %d greater than expected %d.\n"), index, profile_count));
  15068             sal_free(profile_ref_count);
  15069             return BCM_E_INTERNAL;
  15070         }
  15071         profile_ref_count[index]++;
  15072     }
  15073 
  15074     /* Clear out old profile referenced with front panel ports */
  15075     index = 0;
  15076     while (index < profile_count) {
  15077         rv = soc_profile_mem_ref_count_get(unit,
  15078                                     _bcm_kt2_cos_map_profile[unit],
  15079                                     (index * 16), &ref_count);
  15080         if (BCM_FAILURE(rv)) {
  15081             sal_free(profile_ref_count);
  15082             return rv;
  15083         }
  15084         while(profile_ref_count[index] && ref_count) {
  15085             rv = soc_profile_mem_delete(unit,
  15086                                 _bcm_kt2_cos_map_profile[unit], (index * 16));
  15087             if (BCM_FAILURE(rv)) {
  15088                 sal_free(profile_ref_count);
  15089                 return rv;
  15090             }
  15091             profile_ref_count[index]--;
  15092             ref_count--;
  15093         }
  15094         /* Clear egress cos_map profile */
  15095         rv = soc_profile_mem_ref_count_get(unit,
  15096                                     _bcm_kt2_egr_cos_map_profile[unit],
  15097                                     (index * 16), &egr_count);
  15098         if (BCM_FAILURE(rv)) {
  15099             sal_free(profile_ref_count);
  15100             return rv;
  15101         }
  15102         while(egr_count) {
  15103             rv = soc_profile_mem_delete(unit,
  15104                                 _bcm_kt2_egr_cos_map_profile[unit], (index * 16));
  15105             if (BCM_FAILURE(rv)) {
  15106                 sal_free(profile_ref_count);
  15107                 return rv;
  15108             }
  15109             egr_count--;
  15110         }
  15111         index++;
  15112     }
  15113     sal_free(profile_ref_count);
  15114 
  15115     /* Distribute first 8 internal priority levels into the specified number
  15116      * of cosq, map remaining internal priority levels to highest priority
  15117      * cosq */
  15118     sal_memset(cos_map_entries, 0, sizeof(cos_map_entries));
  15119     entries[0] = &cos_map_entries;
  15120     hg_entries[0] = &cos_map_entries;
  15121     prio = 0;
  15122     for (cos = 0; cos < numq; cos++) {
  15123         for (i = 8 / numq + (cos < 8 % numq ? 1 : 0); i > 0; i--) {
  15124             soc_mem_field32_set(unit, PORT_COS_MAPm, &cos_map_entries[prio],
  15125                                 COSf, cos);
  15126             soc_mem_field32_set(unit, PORT_COS_MAPm, &cos_map_entries[prio],
  15127                                  HG_COSf, cos);
  15128             prio++;
  15129         }
  15130     }
  15131     for (prio = 8; prio < 16; prio++) {
  15132         soc_mem_field32_set(unit, PORT_COS_MAPm, &cos_map_entries[prio], COSf,
  15133                             numq - 1);
  15134         soc_mem_field32_set(unit, PORT_COS_MAPm, &cos_map_entries[prio],HG_COSf,
  15135                                      numq - 1);
  15136     }
  15137 
  15138     /* Map internal priority levels to CPU CoS queues */
  15139     BCM_IF_ERROR_RETURN(_bcm_esw_cpu_cosq_mapping_default_set(unit, numq));
  15140 
  15141 #ifdef BCM_COSQ_HIGIG_MAP_DISABLE
  15142     /* Use identical mapping for Higig port */
  15143     sal_memset(hg_cos_map_entries, 0, sizeof(hg_cos_map_entries));
  15144     hg_entries[0] = &hg_cos_map_entries;
  15145     prio = 0;
  15146     for (prio = 0; prio < 8; prio++) {
  15147         soc_mem_field32_set(unit, PORT_COS_MAPm, &hg_cos_map_entries[prio],
  15148                             COSf, prio);
  15149     }
  15150     for (prio = 8; prio < 16; prio++) {
  15151         soc_mem_field32_set(unit, PORT_COS_MAPm, &hg_cos_map_entries[prio],
  15152                             COSf, 7);
  15153     }
  15154 
  15155 #endif /* BCM_COSQ_HIGIG_MAP_DISABLE */
  15156 
  15157     BCM_IF_ERROR_RETURN
  15158         (soc_profile_mem_add(unit, _bcm_kt2_cos_map_profile[unit], entries, 16,
  15159                              &index));
  15160     BCM_IF_ERROR_RETURN
  15161         (soc_profile_mem_add(unit, _bcm_kt2_cos_map_profile[unit], hg_entries,
  15162                              16, &hg_index));
  15163     BCM_IF_ERROR_RETURN
  15164         (soc_profile_mem_add(unit, _bcm_kt2_egr_cos_map_profile[unit], entries, 16,
  15165                              &egr_index));
  15166     count = 0;
  15167     hg_count = 0;
  15168 
  15169     PBMP_ITER(all_pbmp, port) {
  15170         if (IS_HG_PORT(unit, port)) {
  15171             BCM_IF_ERROR_RETURN
  15172                 (soc_mem_field32_modify(unit, COS_MAP_SELm, port, SELECTf,
  15173                                         hg_index / 16));
  15174             hg_count++;
  15175         } else {
  15176             BCM_IF_ERROR_RETURN
  15177                 (soc_mem_field32_modify(unit, COS_MAP_SELm, port, SELECTf,
  15178                                         index / 16));
  15179             count++;
  15180         }
  15181         BCM_IF_ERROR_RETURN
  15182             (soc_mem_field32_modify(unit, EGR_PORTm, port, EGR_COS_MAP_SELf,
  15183                                     egr_index / 16));
  15184         soc_profile_mem_reference(unit, _bcm_kt2_egr_cos_map_profile[unit], egr_index,
  15185                 0);
  15186     }
  15187 
  15188     cpu_hg_index = SOC_INFO(unit).cpu_hg_pp_port_index;
  15189     if (cpu_hg_index != -1) {
  15190         BCM_IF_ERROR_RETURN
  15191             (soc_mem_field32_modify(unit, COS_MAP_SELm,
  15192                                     cpu_hg_index, SELECTf,
  15193                                     hg_index / 16));
  15194         hg_count++;
  15195     }
  15196 
  15197     for (i = 1; i < count; i++) {
  15198         soc_profile_mem_reference(unit, _bcm_kt2_cos_map_profile[unit], index,
  15199                                   0);
  15200     }
  15201     for (i = 1; i < hg_count; i++) {
  15202         soc_profile_mem_reference(unit, _bcm_kt2_cos_map_profile[unit],
  15203                                   hg_index, 0);
  15204     }
  15205 
  15206     _bcm_kt2_num_cosq[unit] = numq;
  15207 
  15208     return BCM_E_NONE;
  15209 }
  15210 
  15211 /*
  15212  * Function:
  15213  *     bcm_kt2_cosq_config_get
  15214  * Purpose:
  15215  *     Get the number of cos queues
  15216  * Parameters:
  15217  *     unit - unit number
  15218  *     numq - (Output) number of cosq
  15219  * Returns:
  15220  *     BCM_E_XXX
  15221  */
  15222 int
  15223 bcm_kt2_cosq_config_get(int unit, int *numq)
  15224 {
  15225     if (_bcm_kt2_num_cosq[unit] == 0) {
  15226         return BCM_E_INIT;
  15227     }
  15228 
  15229     if (numq != NULL) {
  15230         *numq = _bcm_kt2_num_cosq[unit];
  15231     }
  15232 
  15233     return BCM_E_NONE;
  15234 }
  15235 
  15236 int
  15237 bcm_kt2_cosq_gport_reattach(int unit, bcm_gport_t sched_gport,
  15238                          bcm_gport_t input_gport, bcm_cos_queue_t cosq)
  15239 {
  15240     _bcm_kt2_cosq_node_t *sched_node;
  15241     _bcm_kt2_mmu_info_t  *mmu_info;
  15242     _bcm_kt2_cosq_node_t *parent , *new_parent;
  15243     int cycle_sel = 0, index, rate_exp = 0;
  15244     int thld_exp = 0, max_bucket = 0;
  15245     bcm_port_t old_port, new_port;
  15246     int alloc_size;
  15247     int max_nodes;
  15248     int temp_index;
  15249     _bcm_kt2_cosq_list_t *list;
  15250 
  15251     if (!BCM_GPORT_IS_SCHEDULER(sched_gport)) {
  15252         return BCM_E_PARAM;
  15253     }
  15254 
  15255     if (cosq < -1) {
  15256         return BCM_E_PARAM;
  15257     }
  15258 
  15259     BCM_IF_ERROR_RETURN
  15260         (_bcm_kt2_cosq_node_get(unit, sched_gport, NULL, NULL, NULL,
  15261                                &sched_node));
  15262 
  15263     if (sched_node->cosq_attached_to < 0) {
  15264         /* Not yet attached */
  15265         return BCM_E_PARAM;
  15266     }
  15267 
  15268     if (!(sched_node->level == _BCM_KT2_COSQ_NODE_LEVEL_L0 ||
  15269           sched_node->level == _BCM_KT2_COSQ_NODE_LEVEL_L1)) {
  15270         return BCM_E_PARAM;
  15271     }
  15272 
  15273    
  15274     BCM_IF_ERROR_RETURN
  15275         (_bcm_kt2_cosq_node_get(unit, input_gport, NULL, &new_port, NULL,
  15276                                 &new_parent));
  15277     if ((new_parent->wrr_mode == 0) || (sched_node->parent->wrr_mode == 0)) {
  15278         return BCM_E_PARAM;
  15279     }
  15280 
  15281     if (new_parent->cosq_map == NULL) {
  15282         BCM_IF_ERROR_RETURN
  15283             (_bcm_kt2_cosq_max_nodes_get(unit, sched_node->level, &max_nodes));
  15284         if (new_parent->numq == -1) {
  15285             new_parent->numq = max_nodes;
  15286         } else {
  15287             if (new_parent->numq > max_nodes) {
  15288                 return BCM_E_PARAM;
  15289             }
  15290         }
  15291 
  15292         alloc_size = SHR_BITALLOCSIZE(new_parent->numq);
  15293         new_parent->cosq_map = _bcm_kt2_cosq_alloc_clear(alloc_size,
  15294                 "new_parent->cosq_map");
  15295         if (new_parent->cosq_map == NULL) {
  15296             return BCM_E_MEMORY;
  15297         }
  15298     }
  15299 
  15300     if (cosq < 0) {
  15301         BCM_IF_ERROR_RETURN
  15302             (_bcm_kt2_cosq_map_index_get(new_parent->cosq_map,
  15303                                          0, new_parent->numq, &cosq));
  15304     } else {
  15305         if (_bcm_kt2_cosq_map_index_is_set(new_parent->cosq_map,
  15306                     cosq) == TRUE) {
  15307             return BCM_E_EXISTS;
  15308         }
  15309     }
  15310 
  15311     BCM_IF_ERROR_RETURN
  15312         (_bcm_kt2_cosq_index_resolve(unit, sched_gport, sched_node->cosq_attached_to,
  15313                                     _BCM_KT2_COSQ_INDEX_STYLE_BUCKET,
  15314                                     NULL, &index, NULL));
  15315 
  15316     /* set max shaper with cycle_sel = 0xF, and store old cycle_sel */
  15317     BCM_IF_ERROR_RETURN
  15318         (_bcm_kt_cosq_bucket_stop(unit, index, sched_node->level,
  15319                                   &cycle_sel, &rate_exp, &thld_exp, &max_bucket));
  15320 
  15321     parent = sched_node->parent;
  15322     BCM_IF_ERROR_RETURN
  15323         (_bcm_kt2_cosq_node_get(unit, parent->gport, NULL, &old_port, NULL,
  15324                                 NULL));
  15325     temp_index = sched_node->hw_index; 
  15326 
  15327     /* detach from old parent */
  15328     BCM_IF_ERROR_RETURN
  15329         (bcm_kt2_cosq_gport_detach(unit, sched_gport, parent->gport,
  15330                                    sched_node->cosq_attached_to));
  15331     mmu_info = _bcm_kt2_mmu_info[unit];
  15332     list = &mmu_info->sched_hw_list[sched_node->level];
  15333     _bcm_kt2_node_index_set(list, temp_index, 1);
  15334 
  15335     sched_node->hw_index = temp_index; 
  15336 
  15337     /* attach to new parent */
  15338     BCM_IF_ERROR_RETURN
  15339         (bcm_kt2_cosq_gport_attach(unit, sched_gport, input_gport, cosq));
  15340 
  15341     /* update queue map to reflect new port */
  15342     if (old_port != new_port) {
  15343         BCM_IF_ERROR_RETURN
  15344             (_bcm_kt2_cosq_queue_map_set(unit, sched_node, new_port));
  15345     }
  15346 
  15347     /* restore cycle_sel */
  15348     BCM_IF_ERROR_RETURN
  15349         (_bcm_kt_cosq_bucket_start(unit, index, sched_node->level,
  15350                            cycle_sel, rate_exp, thld_exp, max_bucket));
  15351 
  15352     return BCM_E_NONE;
  15353 }
  15354 /*
  15355  * Function:
  15356  *     bcm_kt2_cosq_gport_attach
  15357  * Purpose:
  15358  *     Attach sched_port to the specified index (cosq) of input_port
  15359  * Parameters:
  15360  *     unit       - (IN) unit number
  15361  *     sched_port - (IN) scheduler GPORT identifier
  15362  *     input_port - (IN) GPORT to attach to
  15363  *     cosq       - (IN) COS queue to attach to (-1 for first available cosq)
  15364  * Returns:
  15365  *     BCM_E_XXX
  15366  */
  15367 int
  15368 bcm_kt2_cosq_gport_attach(int unit, bcm_gport_t sched_gport,
  15369                          bcm_gport_t input_gport, bcm_cos_queue_t cosq)
  15370 {
  15371     _bcm_kt2_cosq_node_t *sched_node, *input_node;
  15372     bcm_port_t sched_port, input_port, local_port;
  15373     int rv, max_nodes;
  15374     int status = 0; 
  15375     _bcm_kt2_subport_info_t subport_info;
  15376 
  15377     if (_bcm_kt2_mmu_info[unit] == NULL) {
  15378         return BCM_E_INIT;
  15379     }
  15380 
  15381     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(input_gport) ||
  15382         BCM_GPORT_IS_MCAST_QUEUE_GROUP(input_gport) || 
  15383         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(input_gport) ||
  15384         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(input_gport) ||
  15385         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(input_gport)) {
  15386         return BCM_E_PORT;
  15387     }
  15388 
  15389     if(!(BCM_GPORT_IS_UCAST_QUEUE_GROUP(sched_gport) ||
  15390          BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(sched_gport) ||
  15391          BCM_GPORT_IS_MCAST_QUEUE_GROUP(sched_gport) ||
  15392          BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(sched_gport) ||
  15393          BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(sched_gport) ||
  15394          BCM_GPORT_IS_SCHEDULER(sched_gport))) {
  15395         return BCM_E_PORT;
  15396      }
  15397 
  15398     if (cosq < -1) {
  15399         return BCM_E_PARAM;
  15400     }
  15401 
  15402     BCM_IF_ERROR_RETURN
  15403         (_bcm_kt2_cosq_node_get(unit, sched_gport, NULL, &sched_port, NULL,
  15404                                &sched_node));
  15405 
  15406     if (sched_node->cosq_attached_to >= 0) {
  15407         /* Has already attached */
  15408         return BCM_E_EXISTS;
  15409     }
  15410 
  15411     if (BCM_GPORT_IS_SCHEDULER(input_gport) ||
  15412         BCM_GPORT_IS_LOCAL(input_gport) ||
  15413         BCM_GPORT_IS_MODPORT(input_gport)) {
  15414         BCM_IF_ERROR_RETURN
  15415             (_bcm_kt2_cosq_node_get(unit, input_gport, NULL, &input_port, NULL,
  15416                                    &input_node));
  15417     } else {
  15418         BCM_IF_ERROR_RETURN
  15419             (_bcm_kt2_cosq_localport_resolve(unit, input_gport, &input_port));
  15420         input_node = NULL;
  15421     }
  15422 
  15423     if (input_node != NULL) {
  15424         if (!BCM_GPORT_IS_SCHEDULER(input_gport)) {
  15425             if (input_node->numq == 0) {
  15426                 local_port = (BCM_GPORT_IS_LOCAL(input_gport)) ?
  15427                               BCM_GPORT_LOCAL_GET(input_gport) :
  15428                               BCM_GPORT_MODPORT_PORT_GET(input_gport);
  15429                 input_node->gport = input_gport;
  15430                 input_node->hw_index = local_port;
  15431                 input_node->level = _BCM_KT2_COSQ_NODE_LEVEL_ROOT;
  15432                 input_node->cosq_attached_to = 0;
  15433                 input_node->numq = 4; /* Assign max of 4 L0 nodes */
  15434                 input_node->base_index = -1;
  15435             }
  15436 
  15437             if (!BCM_GPORT_IS_SCHEDULER(sched_gport)) {
  15438                 return BCM_E_PARAM;
  15439             }
  15440 
  15441             sched_node->level = (!_bcm_is_port_linkphy_subport(unit, sched_gport, 
  15442                                     num_port_schedulers[unit])) ?
  15443                                     _BCM_KT2_COSQ_NODE_LEVEL_L0 : 
  15444                                     _BCM_KT2_COSQ_NODE_LEVEL_S0; 
  15445         } else {
  15446              if (input_node->level == _BCM_KT2_COSQ_NODE_LEVEL_ROOT) {
  15447                  if (!BCM_GPORT_IS_SCHEDULER(input_gport)) {
  15448                      return BCM_E_PARAM;
  15449                  }
  15450                  sched_node->level = 
  15451                                 (!_bcm_is_port_linkphy_subport(unit, sched_gport,
  15452                                     num_port_schedulers[unit])) ?
  15453                                     _BCM_KT2_COSQ_NODE_LEVEL_L0 : 
  15454                                     _BCM_KT2_COSQ_NODE_LEVEL_S0; 
  15455              }
  15456 
  15457              if (BCM_GPORT_IS_SCHEDULER(input_gport) &&
  15458                  BCM_GPORT_IS_SCHEDULER(sched_gport)) {
  15459                  if (input_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
  15460                      BCM_IF_ERROR_RETURN
  15461                          (bcm_kt2_subport_pp_port_subport_info_get(unit, 
  15462                                                          input_port, 
  15463                                                          &subport_info));
  15464                      if (subport_info.port_type == _BCM_KT2_SUBPORT_TYPE_LINKPHY) {
  15465                          if (SOC_IS_METROLITE(unit)) {
  15466                              sched_node->level = _BCM_KT2_COSQ_NODE_LEVEL_L0;
  15467                          } else { 
  15468                              sched_node->level = _BCM_KT2_COSQ_NODE_LEVEL_S1;
  15469                          }
  15470                          input_node->linkphy_enabled = 1;
  15471                      } else {
  15472                          sched_node->level = _BCM_KT2_COSQ_NODE_LEVEL_L0; 
  15473                      }
  15474                  }
  15475                  if (input_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) {
  15476                       sched_node->level = _BCM_KT2_COSQ_NODE_LEVEL_L0;
  15477                  }
  15478                  if (input_node->level == _BCM_KT2_COSQ_NODE_LEVEL_L0) {
  15479                       sched_node->level = _BCM_KT2_COSQ_NODE_LEVEL_L1;
  15480                  }    
  15481              }
  15482 
  15483              if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(sched_gport) ||
  15484                   BCM_GPORT_IS_MCAST_QUEUE_GROUP(sched_gport) ||
  15485                   BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(sched_gport) ||
  15486                   BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(sched_gport) ||
  15487                   BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(sched_gport)) {
  15488                   if (!BCM_GPORT_IS_SCHEDULER(input_gport)) {
  15489                      return BCM_E_PARAM;
  15490                   }
  15491                  if (input_node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) {
  15492                      return BCM_E_PARAM;
  15493                  }
  15494                  sched_node->level = _BCM_KT2_COSQ_NODE_LEVEL_L2;
  15495              }
  15496 
  15497              BCM_IF_ERROR_RETURN
  15498                  (_bcm_kt2_cosq_max_nodes_get(unit, sched_node->level, &max_nodes));
  15499              if (input_node->numq == -1) {
  15500                  input_node->numq = max_nodes;
  15501              } else {
  15502                  if (input_node->numq > max_nodes) {
  15503                      return BCM_E_PARAM;
  15504                  }
  15505              }
  15506         }
  15507 
  15508         if (input_node->cosq_attached_to < 0) {
  15509             /* Only allow to attach to a node that has already attached */
  15510             return BCM_E_PARAM;
  15511         }
  15512         if (cosq < -1 || (input_node->numq != -1 && cosq >= input_node->numq)) {
  15513             return BCM_E_PARAM;
  15514         }
  15515     }
  15516 
  15517     if (BCM_GPORT_IS_SCHEDULER(input_gport) || 
  15518         BCM_GPORT_IS_LOCAL(input_gport) ||
  15519         BCM_GPORT_IS_MODPORT(input_gport)) {
  15520         if (input_node->cosq_attached_to < 0) {
  15521             /* dont allow to attach to a node that has already attached */
  15522             return BCM_E_PARAM;
  15523         }
  15524 
  15525         sched_node->parent = input_node;
  15526         sched_node->sibling = input_node->child;
  15527         input_node->child = sched_node;
  15528         /* resolve the nodes */
  15529         rv = _bcm_kt2_cosq_node_resolve(unit, sched_node, cosq);
  15530         if (BCM_FAILURE(rv)) {
  15531             input_node->child = sched_node->sibling;
  15532             return rv;
  15533         }
  15534        
  15535         /* Protect LLS hierachy change as 
  15536          * port flush on link flap might be effected 
  15537          * when there is a change in the LLS hierarchy
  15538          */   
  15539         SOC_LLS_SCHEDULER_LOCK(unit);
  15540         soc_kt_port_flush_state_get(unit, input_port, &status);
  15541         if (status) {
  15542             LOG_ERROR(BSL_LS_BCM_COSQ,
  15543              (BSL_META_U(unit,
  15544              "Unit %d Port %d is in flush state, Cannot change LLS hierarchy."
  15545              "\n Attach of Cosq hw_cosq=%d failed.\n"),
  15546             unit, input_port, sched_node->cosq_attached_to));
  15547 
  15548             input_node->child = sched_node->sibling;
  15549             SOC_LLS_SCHEDULER_UNLOCK(unit);
  15550             return BCM_E_RESOURCE;
  15551         }
  15552 
  15553         rv = _bcm_kt2_cosq_sched_node_set(unit, sched_gport, 
  15554                             _BCM_KT2_COSQ_STATE_ENABLE);
  15555         SOC_LLS_SCHEDULER_UNLOCK(unit);
  15556         if (BCM_FAILURE(rv)) {
  15557             return rv;
  15558         }
  15559 
  15560         /* Set the default sched mode to SP. In case where
  15561          * BCM_COSQ_GPORT_SCHEDULER_WFQ flag is set or packing mode is set
  15562          * or cosq offset is greater than 8, we need to set to WRR.
  15563          */
  15564         if (BCM_GPORT_IS_SCHEDULER(input_gport)) {
  15565             if (input_node->wrr_mode ||
  15566                 ((sched_node->level == _BCM_KT2_COSQ_NODE_LEVEL_L2) &&
  15567                 (soc_feature(unit, soc_feature_mmu_packing))) ||
  15568                 (sched_node->cosq_attached_to >= 8)) {
  15569                 BCM_IF_ERROR_RETURN
  15570                     (bcm_kt2_cosq_gport_sched_set(unit, input_gport,
  15571                                                 sched_node->cosq_attached_to,
  15572                                                 BCM_COSQ_WEIGHTED_ROUND_ROBIN,
  15573                                                 1));
  15574             } else if (sched_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
  15575                 BCM_IF_ERROR_RETURN
  15576                     (bcm_kt2_subport_pp_port_subport_info_get(unit, sched_port,
  15577                                                               &subport_info));
  15578                 if (subport_info.port_type == _BCM_KT2_SUBPORT_TYPE_LINKPHY) {
  15579                     BCM_IF_ERROR_RETURN
  15580                         (bcm_kt2_cosq_gport_sched_set(unit, input_gport,
  15581                                                       sched_node->cosq_attached_to,
  15582                                                       BCM_COSQ_WEIGHTED_ROUND_ROBIN,
  15583                                                       1));
  15584                 }
  15585             } else {
  15586                 BCM_IF_ERROR_RETURN
  15587                     (bcm_kt2_cosq_gport_sched_set(unit, input_gport,
  15588                                                 sched_node->cosq_attached_to,
  15589                                                 BCM_COSQ_STRICT, 0));
  15590             }
  15591         }
  15592 
  15593         LOG_INFO(BSL_LS_BCM_COSQ,
  15594                  (BSL_META_U(unit,
  15595                              "                         hw_cosq=%d\n"),
  15596                   sched_node->cosq_attached_to));
  15597     } else {
  15598             return BCM_E_PORT;
  15599     }
  15600 
  15601     return BCM_E_NONE;
  15602 }
  15603 
  15604 int
  15605 bcm_kt2_cosq_gport_validate(int unit, bcm_gport_t sched_gport,
  15606                          bcm_gport_t input_gport, bcm_cos_queue_t cosq)
  15607 {
  15608     _bcm_kt2_cosq_node_t *sched_node, *input_node;
  15609     bcm_port_t sched_port, input_port;
  15610 
  15611     if (_bcm_kt2_mmu_info[unit] == NULL) {
  15612         return BCM_E_INIT;
  15613     }
  15614 
  15615     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(input_gport) ||
  15616             BCM_GPORT_IS_MCAST_QUEUE_GROUP(input_gport) || 
  15617             BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(input_gport) ||
  15618             BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(input_gport) ||
  15619             BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(input_gport)) {
  15620         return BCM_E_PORT;
  15621     }
  15622 
  15623     if(!(BCM_GPORT_IS_UCAST_QUEUE_GROUP(sched_gport) ||
  15624                 BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(sched_gport) ||
  15625                 BCM_GPORT_IS_MCAST_QUEUE_GROUP(sched_gport) ||
  15626                 BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(sched_gport) ||
  15627                 BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(sched_gport) ||
  15628                 BCM_GPORT_IS_SCHEDULER(sched_gport))) {
  15629         return BCM_E_PORT;
  15630     }
  15631 
  15632     BCM_IF_ERROR_RETURN
  15633         (_bcm_kt2_cosq_node_get(unit, sched_gport, NULL, &sched_port, NULL,
  15634                                 &sched_node));
  15635 
  15636     if (BCM_GPORT_IS_SCHEDULER(input_gport) ||
  15637             BCM_GPORT_IS_LOCAL(input_gport) ||
  15638             BCM_GPORT_IS_MODPORT(input_gport)) {
  15639         BCM_IF_ERROR_RETURN
  15640             (_bcm_kt2_cosq_node_get(unit, input_gport, NULL, &input_port, NULL,
  15641                                     &input_node));
  15642     } else {
  15643         BCM_IF_ERROR_RETURN
  15644             (_bcm_kt2_cosq_localport_resolve(unit, input_gport, &input_port));
  15645         input_node = NULL;
  15646     }
  15647 
  15648 #if defined BCM_METROLITE_SUPPORT
  15649     if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  15650         if ((sched_port < num_port_schedulers[unit]) &&
  15651             (input_port < num_port_schedulers[unit]) &&
  15652             (sched_port != input_port) &&
  15653             (!(_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, sched_port) ||
  15654                _SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, input_port)))) {
  15655             return BCM_E_PORT;
  15656         }
  15657     } else 
  15658 #endif
  15659     {
  15660     if ((sched_port < num_port_schedulers[unit]) &&
  15661             (input_port < num_port_schedulers[unit]) &&
  15662             (sched_port != input_port)) {
  15663         return BCM_E_PORT;
  15664     }
  15665     }
  15666     return BCM_E_NONE;
  15667 }
  15668 
  15669 
  15670 /*
  15671  * Function:
  15672  *     bcm_kt2_cosq_gport_detach
  15673  * Purpose:
  15674  *     Detach sched_port to the specified index (cosq) of input_port
  15675  * Parameters:
  15676  *     unit       - (IN) unit number
  15677  *     sched_port - (IN) scheduler GPORT identifier
  15678  *     input_port - (IN) GPORT to attach to
  15679  *     cosq       - (IN) COS queue to attach to (-1 for first available cosq)
  15680  * Returns:
  15681  *     BCM_E_XXX
  15682  */
  15683 int
  15684 bcm_kt2_cosq_gport_detach(int unit, bcm_gport_t sched_gport,
  15685                          bcm_gport_t input_gport, bcm_cos_queue_t cosq)
  15686 {
  15687     _bcm_kt2_cosq_node_t *sched_node, *input_node, *prev_node;
  15688     bcm_port_t sched_port, input_port;
  15689     int rv;
  15690     int status = 0;
  15691       
  15692     if (_bcm_kt2_mmu_info[unit] == NULL) {
  15693         return BCM_E_INIT;
  15694     }
  15695 
  15696     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(input_gport) ||
  15697         BCM_GPORT_IS_MCAST_QUEUE_GROUP(input_gport) ||
  15698         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(input_gport) ||
  15699         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(input_gport) ||
  15700         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(input_gport)) {
  15701         return BCM_E_PARAM;
  15702     }
  15703 
  15704     BCM_IF_ERROR_RETURN
  15705         (_bcm_kt2_cosq_node_get(unit, sched_gport, NULL, &sched_port, NULL,
  15706                                &sched_node));
  15707 
  15708     if (sched_node->cosq_attached_to < 0) {
  15709         /* Not attached yet */
  15710         return BCM_E_PORT;
  15711     }
  15712 
  15713     if (input_gport != BCM_GPORT_INVALID) {
  15714 
  15715         if (BCM_GPORT_IS_SCHEDULER(input_gport) ||
  15716             BCM_GPORT_IS_LOCAL(input_gport) ||
  15717             BCM_GPORT_IS_MODPORT(input_gport)) {
  15718                BCM_IF_ERROR_RETURN
  15719                 (_bcm_kt2_cosq_node_get(unit, input_gport, NULL, &input_port, 
  15720                                         NULL, &input_node));
  15721         }
  15722         else {
  15723             if (!(BCM_GPORT_IS_SCHEDULER(sched_gport) || 
  15724                   BCM_GPORT_IS_UCAST_QUEUE_GROUP(sched_gport) ||
  15725                   BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(sched_gport) ||
  15726                   BCM_GPORT_IS_MCAST_QUEUE_GROUP(sched_gport) ||
  15727                   BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(sched_gport) ||
  15728                   BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(sched_gport) )) {
  15729                 return BCM_E_PARAM;
  15730             }
  15731             else {
  15732                 BCM_IF_ERROR_RETURN
  15733                 (_bcm_kt2_cosq_localport_resolve(unit, input_gport,
  15734                                                 &input_port));
  15735                 input_node = NULL;
  15736             }
  15737         }
  15738     }
  15739 
  15740     /* When local port is passed as gport, BCM_E_PORT is thrown as this
  15741        is not handled in attach scenario */
  15742     if (input_node == NULL) {
  15743         return BCM_E_PORT;
  15744     }
  15745 
  15746     if (sched_node->parent != input_node) {
  15747         return BCM_E_PORT;
  15748     }
  15749 
  15750     if (cosq < -1 || (input_node->numq != -1 && cosq >= input_node->numq)) {
  15751         return BCM_E_PARAM;
  15752     }    
  15753 
  15754     if (cosq != -1) {
  15755         if (sched_node->cosq_attached_to != cosq) {
  15756             return BCM_E_PARAM;
  15757         }
  15758     }
  15759 
  15760     /* Update the hw accordingly 
  15761      * Protect LLS hierachy change as
  15762      * port flush on link flap might be effected
  15763      * when there is a change in the LLS hierarchy
  15764      */
  15765     SOC_LLS_SCHEDULER_LOCK(unit);
  15766     soc_kt_port_flush_state_get(unit, input_port, &status);
  15767     if (status) {
  15768         LOG_ERROR(BSL_LS_BCM_COSQ,
  15769              (BSL_META_U(unit,
  15770          " Unit %d Port %d is in flush state, Cannot change LLS hierarchy."
  15771          "\n Detach of Cosq hw_cosq=%d failed.\n"),
  15772          unit, input_port, sched_node->cosq_attached_to));
  15773         SOC_LLS_SCHEDULER_UNLOCK(unit);
  15774         return BCM_E_RESOURCE;
  15775     }
  15776 
  15777     rv = _bcm_kt2_cosq_sched_node_set(unit, sched_gport, 
  15778                                      _BCM_KT2_COSQ_STATE_DISABLE);
  15779     SOC_LLS_SCHEDULER_UNLOCK(unit);
  15780     if (BCM_FAILURE(rv)) {
  15781        return rv;
  15782     }
  15783     /* unresolve the node - delete this node from parent's child list */
  15784     BCM_IF_ERROR_RETURN
  15785         (_bcm_kt2_cosq_node_unresolve(unit, sched_node, cosq));
  15786 
  15787     /* now remove from the sw tree */
  15788     if (sched_node->parent != NULL) {
  15789         if (sched_node->parent->child == sched_node) {
  15790             sched_node->parent->child = sched_node->sibling;
  15791         } else {
  15792             prev_node = sched_node->parent->child;
  15793             while (prev_node != NULL && prev_node->sibling != sched_node) {
  15794                 prev_node = prev_node->sibling;
  15795             }
  15796             if (prev_node == NULL) {
  15797                 return BCM_E_INTERNAL;
  15798             }
  15799             prev_node->sibling = sched_node->sibling;
  15800        }
  15801         sched_node->parent = NULL;
  15802         sched_node->sibling = NULL;
  15803         sched_node->wrr_in_use = 0;
  15804         sched_node->cosq_attached_to = -1;        
  15805         if (!(BCM_GPORT_IS_UCAST_QUEUE_GROUP(input_gport) ||
  15806               BCM_GPORT_IS_MCAST_QUEUE_GROUP(input_gport) ||        
  15807               BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(input_gport) ||
  15808               BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(input_gport) ||
  15809               BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(input_gport))) {
  15810             if (sched_node->type  !=
  15811                  _BCM_KT2_NODE_SUBSCRIBER_GPORT_ID) {
  15812                 sched_node->hw_index = -1;
  15813             }
  15814         }
  15815      }
  15816 
  15817       LOG_INFO(BSL_LS_BCM_COSQ,
  15818                (BSL_META_U(unit,
  15819                            "                         hw_cosq=%d\n"),
  15820                 sched_node->cosq_attached_to));
  15821 
  15822     return BCM_E_NONE;
  15823 }
  15824 
  15825 /*
  15826  * Function:
  15827  *     bcm_kt2_cosq_gport_attach_get
  15828  * Purpose:
  15829  *     Get attached status of a scheduler port
  15830  * Parameters:
  15831  *     unit       - (IN) unit number
  15832  *     sched_port - (IN) scheduler GPORT identifier
  15833  *     input_port - (OUT) GPORT to attach to
  15834  *     cosq       - (OUT) COS queue to attached to
  15835  * Returns:
  15836  *     BCM_E_XXX
  15837  * Notes:
  15838  */
  15839 int
  15840 bcm_kt2_cosq_gport_attach_get(int unit, bcm_gport_t sched_gport,
  15841                              bcm_gport_t *input_gport, bcm_cos_queue_t *cosq)
  15842 {
  15843     _bcm_kt2_cosq_node_t *sched_node;
  15844     bcm_module_t modid, modid_out;
  15845     bcm_port_t port, port_out;
  15846 
  15847     if (input_gport == NULL || cosq == NULL) {
  15848         return BCM_E_PARAM;
  15849     }
  15850 
  15851     BCM_IF_ERROR_RETURN
  15852         (_bcm_kt2_cosq_node_get(unit, sched_gport, &modid, &port, NULL,
  15853                                &sched_node));
  15854 
  15855     if (sched_node->level == _BCM_KT2_COSQ_NODE_LEVEL_ROOT) {
  15856         return BCM_E_PARAM;
  15857     }    
  15858     
  15859     if (sched_node->cosq_attached_to < 0) {
  15860         /* Not attached yet */
  15861         return BCM_E_NOT_FOUND;
  15862     }
  15863 
  15864     if (sched_node->parent != NULL) { 
  15865         *input_gport = sched_node->parent->gport;
  15866     } else {  /* sched_node is in L2 level */
  15867         BCM_IF_ERROR_RETURN
  15868             (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, modid, port,
  15869                                     &modid_out, &port_out));
  15870         BCM_GPORT_MODPORT_SET(*input_gport, modid_out, port_out);
  15871     }
  15872     *cosq = sched_node->cosq_attached_to;
  15873 
  15874     return BCM_E_NONE;
  15875 }
  15876 
  15877 STATIC int
  15878 _bcm_kt2_cosq_ef_update_war(int unit, bcm_gport_t gport,  bcm_cos_queue_t cosq,
  15879                            int hw_index, lls_l2_parent_entry_t *entry)
  15880 {
  15881     lls_l1_config_entry_t l1_config;
  15882     uint32 min_bw, max_bw, min_burst, max_burst, flags = 0;
  15883     int parent_index, spri_vector;
  15884     uint32 start_pri, vec_3_0 =0, vec_7_4 = 0;
  15885     uint32 rval = 0, bit_offset;
  15886 
  15887     LOG_INFO(BSL_LS_BCM_COSQ,
  15888              (BSL_META_U(unit,
  15889                          "_bcm_kt2_cosq_ef_update_war:unit=%d gport=0x%x cosq=%d idx=%d\n"),
  15890               unit, gport, cosq, hw_index));
  15891    
  15892     BCM_IF_ERROR_RETURN
  15893         (_bcm_kt2_cosq_bucket_get(unit, gport, cosq, &min_bw, &max_bw,
  15894                                  &min_burst, &max_burst, flags)); 
  15895 
  15896     if ((min_bw == 0) && (max_bw == 0)) {
  15897         SOC_IF_ERROR_RETURN
  15898             (soc_mem_write(unit, LLS_L2_PARENTm, MEM_BLOCK_ALL,
  15899                            hw_index, entry));
  15900     } else {
  15901         parent_index = soc_mem_field32_get(unit, LLS_L2_PARENTm, entry, 
  15902                                            C_PARENTf); 
  15903         SOC_IF_ERROR_RETURN
  15904             (soc_mem_read(unit, LLS_L1_CONFIGm, MEM_BLOCK_ALL, parent_index, 
  15905                           &l1_config));
  15906         start_pri = soc_mem_field32_get(unit, LLS_L1_CONFIGm, &l1_config, 
  15907                                         P_START_UC_SPRIf); 
  15908         vec_3_0 = soc_mem_field32_get(unit, LLS_L1_CONFIGm, &l1_config, 
  15909                                       P_NUM_SPRIf);
  15910         vec_7_4 = soc_mem_field32_get(unit, LLS_L1_CONFIGm, &l1_config, 
  15911                                       P_VECT_SPRI_7_4f);
  15912         spri_vector = vec_3_0 | (vec_7_4 << 4);
  15913         bit_offset = hw_index - start_pri;
  15914         if (bit_offset >= 8) {
  15915             return BCM_E_PARAM;
  15916         }
  15917         LOG_INFO(BSL_LS_BCM_COSQ,
  15918                  (BSL_META_U(unit,
  15919                              "parent=%d spri_vector=0x%x bit_offset=%d\n"),
  15920                   parent_index, spri_vector, bit_offset));
  15921         spri_vector &= ~(1 << bit_offset);
  15922         soc_mem_field32_set(unit, LLS_L1_CONFIGm, &l1_config, P_NUM_SPRIf, 
  15923                             (spri_vector & 0xF));
  15924         soc_mem_field32_set(unit, LLS_L1_CONFIGm, &l1_config, P_VECT_SPRI_7_4f, 
  15925                             ((spri_vector >> 4) & 0xF));
  15926         BCM_IF_ERROR_RETURN
  15927             (_bcm_kt2_cosq_bucket_set(unit, gport, cosq, 0, 0,
  15928                                      min_burst, max_burst, flags)); 
  15929         SOC_IF_ERROR_RETURN
  15930             (soc_mem_write(unit, LLS_L2_PARENTm, MEM_BLOCK_ALL,
  15931                            hw_index, entry));
  15932         SOC_IF_ERROR_RETURN
  15933             (soc_mem_write(unit, LLS_L1_CONFIGm, MEM_BLOCK_ALL,
  15934                            parent_index, &l1_config));
  15935 
  15936         soc_reg_field_set(unit, LLS_DEBUG_INJECT_ACTIVATIONr, &rval, 
  15937                           INJECTf, 1);
  15938         /* 0 = enqueue event,1 = shaper event,2 = xon event,3 = xoff event */ 
  15939         soc_reg_field_set(unit, LLS_DEBUG_INJECT_ACTIVATIONr, &rval, 
  15940                           ENTITY_TYPEf, 1);
  15941         /* 0 = port, 1 = level 0, 2 = level 1, 3 = level 2 */
  15942         soc_reg_field_set(unit, LLS_DEBUG_INJECT_ACTIVATIONr, &rval, 
  15943                           ENTITY_LEVELf, 3);
  15944         soc_reg_field_set(unit, LLS_DEBUG_INJECT_ACTIVATIONr, &rval, 
  15945                           ENTITY_IDENTIFIERf, hw_index); 
  15946         SOC_IF_ERROR_RETURN(WRITE_LLS_DEBUG_INJECT_ACTIVATIONr(unit, rval)); 
  15947         spri_vector |= (1 << bit_offset);
  15948         soc_mem_field32_set(unit, LLS_L1_CONFIGm, &l1_config, P_NUM_SPRIf, 
  15949                             (spri_vector & 0xF));
  15950         soc_mem_field32_set(unit, LLS_L1_CONFIGm, &l1_config, P_VECT_SPRI_7_4f, 
  15951                             ((spri_vector >> 4) & 0xF));
  15952         SOC_IF_ERROR_RETURN
  15953             (soc_mem_write(unit, LLS_L1_CONFIGm, MEM_BLOCK_ALL,
  15954                            parent_index, &l1_config));
  15955         BCM_IF_ERROR_RETURN
  15956             (_bcm_kt2_cosq_bucket_set(unit, gport, cosq, min_bw, max_bw,
  15957                                      min_burst, max_burst, flags)); 
  15958     }
  15959 
  15960     return BCM_E_NONE;
  15961 }
  15962 
  15963 STATIC int
  15964 _bcm_kt2_cosq_valid_ef_node(int unit, lls_l1_config_entry_t *entry, 
  15965                            int hw_index)
  15966 {
  15967     lls_l2_parent_entry_t l2_parent;
  15968     int index, start_pri, spri_vector, num_spri, vec_7_4;
  15969     uint32 bit_offset;
  15970     int i;
  15971 
  15972     start_pri = soc_mem_field32_get(unit, LLS_L1_CONFIGm, entry, 
  15973                                     P_START_UC_SPRIf); 
  15974     num_spri = soc_mem_field32_get(unit, LLS_L1_CONFIGm, entry, 
  15975                                    P_NUM_SPRIf);
  15976     if (soc_feature(unit, soc_feature_vector_based_spri)) {
  15977         vec_7_4 = soc_mem_field32_get(unit, LLS_L1_CONFIGm, entry, 
  15978                                       P_VECT_SPRI_7_4f);
  15979         spri_vector = num_spri | (vec_7_4 << 4);
  15980         bit_offset = hw_index - start_pri;
  15981         if (bit_offset >= 8) {
  15982             return BCM_E_PARAM;
  15983         }
  15984         if (!(spri_vector & (1 << bit_offset))) {
  15985             /* werr node cannot be EF */
  15986             return BCM_E_PARAM;
  15987         }
  15988         for (i = 0; i < 8; i++) {
  15989             if (spri_vector & (1 << i)) {
  15990                 index = start_pri + i;
  15991                 SOC_IF_ERROR_RETURN
  15992                      (soc_mem_read(unit, LLS_L2_PARENTm, MEM_BLOCK_ALL,
  15993                                    index, &l2_parent));
  15994                 if (soc_mem_field32_get(unit, LLS_L2_PARENTm, 
  15995                                         &l2_parent, C_EFf) == 1) {
  15996                     /* maximum of 1 EF node is supported */
  15997                     return FALSE;
  15998                 }
  15999             }
  16000         }
  16001     } else {
  16002         if ((hw_index < start_pri) || (hw_index >= (start_pri + num_spri))) {
  16003             /* werr node cannot be EF */
  16004             return BCM_E_PARAM;
  16005         } 
  16006         for (i = start_pri; i < (start_pri + num_spri); i++) {
  16007             SOC_IF_ERROR_RETURN
  16008                 (soc_mem_read(unit, LLS_L2_PARENTm, MEM_BLOCK_ALL,
  16009                               i, &l2_parent));
  16010             if (soc_mem_field32_get(unit, LLS_L2_PARENTm,
  16011                                     &l2_parent, C_EFf) == 1) {
  16012                 /* maximum of 1 EF node is supported */
  16013                 return FALSE;
  16014             }
  16015         }
  16016     }
  16017    
  16018     return TRUE;
  16019 }
  16020 
  16021 STATIC int
  16022 _bcm_kt2_cosq_ef_op_at_index(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
  16023                             int hw_index, _bcm_cosq_op_t op, int *ef_val)
  16024 {
  16025     lls_l2_parent_entry_t entry;
  16026     lls_l1_parent_entry_t l1_entry;
  16027     lls_l1_config_entry_t l1_config;
  16028     lls_l0_config_entry_t l0_config;
  16029     uint32 current_ef = 0, set_ef = 0;
  16030     uint32 index;
  16031 
  16032     SOC_IF_ERROR_RETURN
  16033         (soc_mem_read(unit, LLS_L2_PARENTm, MEM_BLOCK_ALL, hw_index, &entry));
  16034 
  16035     if (op == _BCM_COSQ_OP_GET) {
  16036         *ef_val = soc_mem_field32_get(unit, LLS_L2_PARENTm, &entry, C_EFf);
  16037     } else {
  16038         current_ef = soc_mem_field32_get(unit, LLS_L2_PARENTm, &entry, C_EFf);
  16039         set_ef = (*ef_val != 0) ? 1 : 0;
  16040         soc_mem_field32_set(unit, LLS_L2_PARENTm, &entry, C_EFf, set_ef);
  16041         if ((current_ef == 0) && (set_ef == 1)) {
  16042             index = soc_mem_field32_get(unit, LLS_L2_PARENTm, &entry, 
  16043                                         C_PARENTf); 
  16044             SOC_IF_ERROR_RETURN
  16045                 (soc_mem_read(unit, LLS_L1_CONFIGm, MEM_BLOCK_ALL, 
  16046                               index, &l1_config));
  16047             if (_bcm_kt2_cosq_valid_ef_node(unit, &l1_config, 
  16048                                            hw_index) != TRUE) {
  16049                  return BCM_E_PARAM;
  16050             }  
  16051             soc_mem_field32_set(unit, LLS_L1_CONFIGm, &l1_config, 
  16052                                 P_CFG_EF_PROPAGATEf, set_ef);
  16053             SOC_IF_ERROR_RETURN
  16054                 (soc_mem_write(unit, LLS_L1_CONFIGm, MEM_BLOCK_ALL,
  16055                                index, &l1_config));
  16056             SOC_IF_ERROR_RETURN
  16057                 (soc_mem_read(unit, LLS_L1_PARENTm, MEM_BLOCK_ALL, 
  16058                               index, &l1_entry));
  16059             index = soc_mem_field32_get(unit, LLS_L1_PARENTm, &l1_entry, 
  16060                                         C_PARENTf); 
  16061             SOC_IF_ERROR_RETURN
  16062                 (soc_mem_read(unit, LLS_L0_CONFIGm, MEM_BLOCK_ALL, 
  16063                               index, &l0_config));
  16064             soc_mem_field32_set(unit, LLS_L0_CONFIGm, &l0_config, 
  16065                                 P_CFG_EF_PROPAGATEf, set_ef);
  16066             SOC_IF_ERROR_RETURN
  16067                 (soc_mem_write(unit, LLS_L0_CONFIGm, MEM_BLOCK_ALL,
  16068                                index, &l0_config));
  16069             SOC_IF_ERROR_RETURN
  16070                 (soc_mem_write(unit, LLS_L2_PARENTm, MEM_BLOCK_ALL,
  16071                                hw_index, &entry));
  16072         } else if ((current_ef == 1) && (set_ef == 0)) {
  16073             if (soc_feature(unit, soc_feature_vector_based_spri)) {
  16074                 return _bcm_kt2_cosq_ef_update_war(unit, gport, cosq, 
  16075                                                   hw_index, &entry);
  16076             }  
  16077             SOC_IF_ERROR_RETURN
  16078                 (soc_mem_write(unit, LLS_L2_PARENTm, MEM_BLOCK_ALL,
  16079                                hw_index, &entry));
  16080         } else {
  16081             return BCM_E_NONE;     
  16082         }
  16083     }
  16084 
  16085     return BCM_E_NONE;
  16086 }
  16087 
  16088 STATIC int
  16089 _bcm_kt2_cosq_port_qnum_get(int unit, bcm_gport_t gport,
  16090         bcm_cos_queue_t cosq, bcm_cosq_control_t type, int *arg)
  16091 {
  16092     bcm_port_t local_port;
  16093     if (!arg) {
  16094         return BCM_E_PARAM;
  16095     }
  16096 
  16097     if (!BCM_COSQ_QUEUE_VALID(unit, cosq)) {
  16098         return BCM_E_PARAM;
  16099     }
  16100 
  16101     BCM_IF_ERROR_RETURN
  16102         (_bcm_kt2_cosq_localport_resolve(unit, gport, &local_port));
  16103     if (local_port < 0) {
  16104         return BCM_E_PORT;
  16105     }
  16106 
  16107     if (type == bcmCosqControlPortQueueUcast) {
  16108         *arg = SOC_INFO(unit).port_uc_cosq_base[local_port] + cosq;
  16109     } else {
  16110         *arg = SOC_INFO(unit).port_cosq_base[local_port] + cosq;
  16111     }
  16112 
  16113     return BCM_E_NONE;
  16114 }
  16115 
  16116 STATIC int
  16117 _bcm_kt2_cosq_ef_op(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq, int *arg,
  16118                    _bcm_cosq_op_t op)
  16119 {
  16120     bcm_port_t local_port;
  16121     int index, numq, from_cos, to_cos, ci;
  16122 
  16123     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  16124         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  16125         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) || 
  16126         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  16127         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  16128         BCM_IF_ERROR_RETURN
  16129             (_bcm_kt2_cosq_index_resolve
  16130              (unit, gport, cosq, _BCM_KT2_COSQ_INDEX_STYLE_BUCKET,
  16131               &local_port, &index, NULL));
  16132         return _bcm_kt2_cosq_ef_op_at_index(unit, gport, cosq, 
  16133                                            index, op, arg);
  16134     } else if (BCM_GPORT_IS_SCHEDULER(gport)) {
  16135         return BCM_E_PARAM;
  16136     } else {
  16137         BCM_IF_ERROR_RETURN
  16138             (_bcm_kt2_cosq_index_resolve
  16139              (unit, gport, cosq, _BCM_KT2_COSQ_INDEX_STYLE_BUCKET,
  16140               &local_port, &index, &numq));
  16141         if (cosq == BCM_COS_INVALID) {
  16142             /* Maximum 1 spri can be EF enabled */
  16143             from_cos = to_cos = 0;
  16144         } else {
  16145             from_cos = to_cos = cosq;
  16146         }
  16147         for (ci = from_cos; ci <= to_cos; ci++) {
  16148             BCM_IF_ERROR_RETURN
  16149                 (_bcm_kt2_cosq_index_resolve
  16150                  (unit, gport, ci, _BCM_KT2_COSQ_INDEX_STYLE_BUCKET,
  16151                   &local_port, &index, NULL));
  16152 
  16153             BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_ef_op_at_index(unit,
  16154                                 gport, ci, index, op, arg));
  16155             if (op == _BCM_COSQ_OP_GET) {
  16156                 return BCM_E_NONE;
  16157             }
  16158         }
  16159     }
  16160     return BCM_E_NONE;
  16161 }
  16162 
  16163 int 
  16164 _bcm_kt2_cosq_redirect_parameter_set (int unit, soc_reg_t reg, 
  16165         soc_field_t field, bcm_cos_queue_t cosq, int arg)
  16166 {
  16167     uint32 rval;
  16168     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, cosq, 
  16169                  &rval));
  16170     soc_reg_field_set(unit, reg, &rval, field, arg); 
  16171     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, cosq, 
  16172                                       rval));
  16173     return BCM_E_NONE;
  16174 }
  16175 
  16176 #if defined(BCM_SABER2_SUPPORT)
  16177 STATIC int
  16178 _bcm_sb2_cosq_port_pg_idx_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
  16179                           int *midx) 
  16180 {
  16181     bcm_port_t local_port;
  16182     soc_reg_t reg = INVALIDr;
  16183     int port_pg, pg_profile = 0;
  16184     uint64 rval64;
  16185     uint32 rval;
  16186 
  16187     soc_reg_t pri_to_prigrp_reg = MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r;
  16188     soc_field_t pri_to_prigrp_field[SB2_MAX_LOGICAL_PORTS]={
  16189             SRCPORT_0f,  
  16190             SRCPORT_1f,  SRCPORT_2f,  SRCPORT_3f,  SRCPORT_4f,  
  16191             SRCPORT_5f,  SRCPORT_6f,  SRCPORT_7f,  SRCPORT_8f,  
  16192             SRCPORT_9f,  SRCPORT_10f, SRCPORT_11f, SRCPORT_12f, 
  16193             SRCPORT_13f, SRCPORT_14f, SRCPORT_15f, SRCPORT_16f, 
  16194             SRCPORT_17f, SRCPORT_18f, SRCPORT_19f, SRCPORT_20f, 
  16195             SRCPORT_21f, SRCPORT_22f, SRCPORT_23f, SRCPORT_24f, 
  16196             SRCPORT_25f, SRCPORT_26f, SRCPORT_27f, SRCPORT_28f, 
  16197             SRCPORT_29f
  16198             };                 
  16199 
  16200     static const soc_reg_t prigroup_reg[] = {
  16201         PROFILE0_PRI_GRP0r, PROFILE0_PRI_GRP1r,
  16202         PROFILE1_PRI_GRP0r, PROFILE1_PRI_GRP1r,
  16203         PROFILE2_PRI_GRP0r, PROFILE2_PRI_GRP1r,
  16204         PROFILE3_PRI_GRP0r, PROFILE3_PRI_GRP1r
  16205     };
  16206     static const soc_field_t prigroup_field0[] = {
  16207         PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf,
  16208         PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf
  16209     };
  16210 
  16211     static const soc_field_t prigroup_field1[] = {
  16212         PRI8_GRPf,  PRI9_GRPf,  PRI10_GRPf, PRI11_GRPf,
  16213         PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf
  16214     };
  16215 
  16216     if (midx == NULL) {
  16217         return BCM_E_PARAM;
  16218     }
  16219 
  16220     if (cosq > 15 || cosq < 0) {
  16221         /* Error. Input pri > Max Pri_Grp */
  16222         return BCM_E_PARAM;
  16223     }
  16224 
  16225     BCM_IF_ERROR_RETURN
  16226         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  16227                                 NULL));        
  16228 
  16229     if (local_port < 0) {
  16230         return BCM_E_PORT;
  16231     }
  16232 
  16233     /* The valid fields below are those which correspond to valid
  16234      * PFC ports
  16235      */
  16236     READ_MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r(unit, &rval64);
  16237     if (soc_reg_field_valid(unit, MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r, 
  16238                             pri_to_prigrp_field[local_port])) {
  16239         pg_profile = soc_reg64_field32_get(unit, pri_to_prigrp_reg, rval64, 
  16240                                     pri_to_prigrp_field[local_port]);
  16241 
  16242         if (cosq < 8) {
  16243             reg = prigroup_reg[pg_profile * 2];
  16244             SOC_IF_ERROR_RETURN
  16245                 (soc_reg32_get(unit, reg, local_port, 0, &rval));
  16246             port_pg = soc_reg_field_get(unit, reg, rval, prigroup_field0[cosq]);
  16247         } else {
  16248             reg = prigroup_reg[(pg_profile * 2) + 1];
  16249             SOC_IF_ERROR_RETURN
  16250                 (soc_reg32_get(unit, reg, local_port, 0, &rval));
  16251             port_pg = soc_reg_field_get(unit, reg, rval, prigroup_field1[cosq - 8]);
  16252         }
  16253     } else {
  16254         port_pg = 0;
  16255     }
  16256 #if defined(BCM_METROLITE_SUPPORT)
  16257     if (SOC_IS_METROLITE(unit)) {
  16258         *midx = ML_GET_THDI_PORT_PG(local_port) - 7 + port_pg;
  16259     } else
  16260 #endif 
  16261     {
  16262         *midx = (local_port * SB2_MAX_PRIORITY_GROUPS) + port_pg;
  16263     }
  16264 
  16265     if (*midx < 0) {
  16266         return BCM_E_PARAM;
  16267     }
  16268 
  16269     return BCM_E_NONE;
  16270 }
  16271 #endif
  16272 
  16273 STATIC int
  16274 _bcm_kt2_cosq_port_pg_idx_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
  16275                           int *midx) 
  16276 {
  16277     bcm_port_t local_port;
  16278     soc_reg_t reg = INVALIDr;
  16279     int port_pg, pg_profile = 0;
  16280     uint32 rval;
  16281 
  16282     soc_reg_t pri_to_prigrp_reg = MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r;
  16283     soc_field_t pri_to_prigrp_field[KT2_MAX_LOGICAL_PORTS]={
  16284             SRCPORT_0f,  
  16285             SRCPORT_1f,  SRCPORT_2f,  SRCPORT_3f,  SRCPORT_4f,  
  16286             SRCPORT_5f,  SRCPORT_6f,  SRCPORT_7f,  SRCPORT_8f,  
  16287             SRCPORT_9f,  SRCPORT_10f, SRCPORT_11f, SRCPORT_12f, 
  16288             SRCPORT_13f, SRCPORT_14f, SRCPORT_15f, SRCPORT_16f, 
  16289             SRCPORT_17f, SRCPORT_18f, SRCPORT_19f, SRCPORT_20f, 
  16290             SRCPORT_21f, SRCPORT_22f, SRCPORT_23f, SRCPORT_24f, 
  16291             SRCPORT_25f, SRCPORT_26f, SRCPORT_27f, SRCPORT_28f, 
  16292             SRCPORT_29f, SRCPORT_30f, SRCPORT_31f, SRCPORT_32f, 
  16293             SRCPORT_33f, SRCPORT_34f, SRCPORT_35f, SRCPORT_36f, 
  16294             SRCPORT_37f, SRCPORT_38f, SRCPORT_39f, SRCPORT_40f,
  16295             SRCPORT_41f
  16296             };                 
  16297 
  16298     static const soc_reg_t prigroup_reg[] = {
  16299         MMU_ENQ_PROFILE_0_PRI_GRP0r, MMU_ENQ_PROFILE_0_PRI_GRP1r,
  16300         MMU_ENQ_PROFILE_1_PRI_GRP0r, MMU_ENQ_PROFILE_1_PRI_GRP1r,
  16301         MMU_ENQ_PROFILE_2_PRI_GRP0r, MMU_ENQ_PROFILE_2_PRI_GRP1r,
  16302         MMU_ENQ_PROFILE_3_PRI_GRP0r, MMU_ENQ_PROFILE_3_PRI_GRP1r
  16303     };
  16304 
  16305     static const soc_field_t prigroup_field0[] = {
  16306         PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf,
  16307         PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf
  16308     };
  16309 
  16310     static const soc_field_t prigroup_field1[] = {
  16311         PRI8_GRPf,  PRI9_GRPf,  PRI10_GRPf, PRI11_GRPf,
  16312         PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf
  16313     };
  16314 
  16315     if (midx == NULL) {
  16316         return BCM_E_PARAM;
  16317     }
  16318 
  16319     if (cosq > 15 || cosq < 0) {
  16320         /* Error. Input pri > Max Pri_Grp */
  16321         return BCM_E_PARAM;
  16322     }
  16323 
  16324     BCM_IF_ERROR_RETURN
  16325         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  16326                                 NULL));        
  16327 
  16328     if (local_port < 0) {
  16329         return BCM_E_PORT;
  16330     }
  16331 
  16332     /* The valid fields below are those which correspond to valid
  16333      * PFC ports
  16334      */
  16335     READ_MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r_REG32(unit, &rval);
  16336     if (soc_reg_field_valid(unit, MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r, 
  16337                             pri_to_prigrp_field[local_port])) {
  16338         pg_profile = soc_reg_field_get(unit, pri_to_prigrp_reg, rval, 
  16339                                     pri_to_prigrp_field[local_port]);
  16340 
  16341         if (cosq < 8) {
  16342             reg = prigroup_reg[pg_profile * 2];
  16343             SOC_IF_ERROR_RETURN
  16344                 (soc_reg32_get(unit, reg, local_port, 0, &rval));
  16345             port_pg = soc_reg_field_get(unit, reg, rval, prigroup_field0[cosq]);
  16346         } else {
  16347             reg = prigroup_reg[(pg_profile * 2) + 1];
  16348             SOC_IF_ERROR_RETURN
  16349                 (soc_reg32_get(unit, reg, local_port, 0, &rval));
  16350             port_pg = soc_reg_field_get(unit, reg, rval, prigroup_field1[cosq - 8]);
  16351         }
  16352     } else {
  16353         port_pg = 0;
  16354     }
  16355 
  16356     *midx = (local_port * _BCM_KT2_MAX_PRIORITY_GROUPS) + port_pg;
  16357 
  16358     if (*midx < 0) {
  16359         return BCM_E_PARAM;
  16360     }
  16361 
  16362     return BCM_E_NONE;
  16363 }
  16364 
  16365 
  16366 STATIC int
  16367 _bcm_kt2_cosq_egr_pool_set(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
  16368                           bcm_cosq_control_t type, int arg)
  16369 {
  16370     int startq;
  16371     uint32 max_val;
  16372     uint32 entry[SOC_MAX_MEM_WORDS];
  16373     soc_mem_t mem = INVALIDm;
  16374     soc_mem_t mem2 = INVALIDm;
  16375     soc_field_t fld_limit = INVALIDf, fld_limit2 = INVALIDf;
  16376     int granularity = 1;
  16377     bcm_port_t local_port;
  16378     int cell_size = _BCM_KT2_COSQ_CELLSIZE;
  16379     _bcm_kt2_mmu_info_t *mmu_info;
  16380     _bcm_kt2_cosq_node_t *node;
  16381     int numq;
  16382 
  16383     if (arg < 0) {
  16384         return BCM_E_PARAM;
  16385     }
  16386 
  16387     BCM_IF_ERROR_RETURN
  16388         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  16389                                 &node));        
  16390     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  16391         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  16392         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
  16393         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  16394         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  16395         BCM_GPORT_IS_SCHEDULER(gport)) {
  16396         if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) &&
  16397             (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2)) {
  16398             return BCM_E_PARAM;
  16399         }
  16400         if (BCM_GPORT_IS_SCHEDULER(gport)) {
  16401             BCM_IF_ERROR_RETURN(
  16402                 _bcm_kt2_cosq_child_node_at_input(node, cosq,
  16403                                               &node)); 
  16404         }
  16405         startq = node->hw_index;
  16406     } else {
  16407         mmu_info = _bcm_kt2_mmu_info[unit];
  16408         numq = mmu_info->port[local_port].q_limit -
  16409                 mmu_info->port[local_port].q_offset;
  16410 
  16411         if (cosq < 0 || cosq >= numq) {
  16412             return BCM_E_PARAM;
  16413         }
  16414         startq = mmu_info->port[local_port].q_offset + cosq;
  16415     }
  16416 
  16417     if (IS_EXT_MEM_PORT(unit, local_port)) {
  16418         cell_size = _BCM_KT2_COSQ_EXT_CELLSIZE;
  16419         if (soc_feature(unit, soc_feature_mmu_packing)) {
  16420             cell_size = _BCM_KT2_COSQ_EXT_PACKING_CELLSIZE;
  16421         }
  16422     }    
  16423 
  16424     if (type != bcmCosqControlEgressPoolLimitEnable) {
  16425         arg = arg / cell_size;
  16426     }
  16427 
  16428     mem = MMU_THDO_QCONFIG_CELLm;
  16429     if (type == bcmCosqControlEgressPoolRedLimitBytes) {
  16430         mem = MMU_THDO_QOFFSET_CELLm;
  16431         mem2 = MMU_THDO_QCONFIG_CELLm;
  16432     }
  16433 
  16434     BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
  16435 
  16436     switch (type) {
  16437     case bcmCosqControlEgressPoolLimitBytes:
  16438         fld_limit = Q_SHARED_LIMIT_CELLf;
  16439         fld_limit2 = Q_LIMIT_ENABLE_CELLf;
  16440         granularity = 1;
  16441         break;
  16442     case bcmCosqControlEgressPoolYellowLimitBytes:
  16443         fld_limit = LIMIT_YELLOW_CELLf;
  16444         fld_limit2 = Q_COLOR_ENABLE_CELLf;
  16445         granularity = 8;
  16446         break;
  16447     case bcmCosqControlEgressPoolRedLimitBytes:
  16448         fld_limit = LIMIT_RED_CELLf;
  16449         fld_limit2 = Q_COLOR_ENABLE_CELLf;
  16450         granularity = 8;
  16451         break;
  16452     case bcmCosqControlEgressPoolLimitEnable:
  16453         fld_limit = Q_LIMIT_ENABLE_CELLf;
  16454         granularity = 1;
  16455         break;
  16456     default:
  16457         return BCM_E_UNAVAIL;
  16458     }
  16459 
  16460     /* Check for min/max values */
  16461     max_val = (1 << soc_mem_field_length(unit, mem, fld_limit)) - 1;
  16462     if (IS_EXT_MEM_PORT(unit, local_port)) {
  16463         max_val = soc_kt2_get_max_buffer_size(unit, 1, max_val);
  16464     } else {
  16465         max_val = soc_kt2_get_max_buffer_size(unit, 0, max_val);
  16466     }
  16467     if ((arg < 0) || ((arg/granularity) > max_val)) {
  16468         return BCM_E_PARAM;
  16469     } else {
  16470         soc_mem_field32_set(unit, mem, entry, fld_limit, (arg/granularity));
  16471         if (fld_limit2 != INVALIDr) {
  16472             if (mem2 != INVALIDm) {
  16473                 soc_mem_field32_set(unit, mem2, entry, fld_limit2, 1);
  16474             } else {
  16475                 soc_mem_field32_set(unit, mem, entry, fld_limit2, 1);
  16476             }
  16477         }
  16478     }
  16479     BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
  16480 
  16481     return BCM_E_NONE;
  16482 }
  16483 
  16484 STATIC int
  16485 _bcm_kt2_cosq_egr_queue_set(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
  16486                             bcm_cosq_control_t type, int arg)
  16487 {
  16488     bcm_port_t local_port;
  16489     int startq, startq1;
  16490     uint32 max_val;
  16491     uint32 entry[SOC_MAX_MEM_WORDS];
  16492     soc_mem_t mem = INVALIDm;
  16493     soc_field_t fld_limit = INVALIDf, fld_limit2 = INVALIDf;
  16494     int granularity = 1;
  16495     int shared_size, cur_val, rv, post_update;
  16496     _bcm_kt2_mmu_info_t *mmu_info = _bcm_kt2_mmu_info[unit];
  16497     int cell_size = _BCM_KT2_COSQ_CELLSIZE;
  16498     _bcm_kt2_cosq_node_t *node;
  16499     int limit, numq;
  16500     bcm_kt2_cosq_recalc_type_t recalc_type;
  16501 
  16502     if (arg < 0) {
  16503         return BCM_E_PARAM;
  16504     }
  16505 
  16506     BCM_IF_ERROR_RETURN
  16507         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  16508                                 &node));        
  16509 
  16510     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  16511         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  16512         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
  16513         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  16514         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  16515         BCM_GPORT_IS_SCHEDULER(gport)) {
  16516         if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) &&
  16517             (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2)) {
  16518             return BCM_E_PARAM;
  16519         }
  16520         if (BCM_GPORT_IS_SCHEDULER(gport)) {
  16521             BCM_IF_ERROR_RETURN(
  16522                 _bcm_kt2_cosq_child_node_at_input(node, cosq,
  16523                                               &node)); 
  16524         }
  16525 
  16526         startq = node->hw_index;
  16527         startq1 = node->hw_index;
  16528     } else {
  16529         mmu_info = _bcm_kt2_mmu_info[unit];
  16530         numq = mmu_info->port[local_port].q_limit -
  16531                 mmu_info->port[local_port].q_offset;
  16532 
  16533         if (cosq < 0 || cosq >= numq) {
  16534             return BCM_E_PARAM;
  16535         }
  16536         startq = mmu_info->port[local_port].q_offset + cosq;
  16537         startq1 = mmu_info->port[local_port].mcq_offset + cosq;
  16538     }
  16539 
  16540     if (IS_EXT_MEM_PORT(unit, local_port)) {
  16541         cell_size = _BCM_KT2_COSQ_EXT_CELLSIZE;
  16542         if (soc_feature(unit, soc_feature_mmu_packing)) {
  16543             cell_size = _BCM_KT2_COSQ_EXT_PACKING_CELLSIZE;
  16544         }
  16545     }    
  16546 
  16547     arg /= cell_size;
  16548 
  16549     mem = MMU_THDO_QCONFIG_CELLm;
  16550 
  16551     if ((type == bcmCosqControlEgressUCQueueSharedLimitBytes) ||
  16552         (type == bcmCosqControlEgressUCQueueMinLimitBytes)) {
  16553         if (node && (BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport) ||
  16554                      BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport))) {
  16555             return BCM_E_PARAM;
  16556         }
  16557         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
  16558     } else if ((type == bcmCosqControlEgressMCQueueSharedLimitBytes) ||
  16559                (type == bcmCosqControlEgressMCQueueMinLimitBytes)) {
  16560         if (node && (BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport) ||
  16561                      BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport))) {
  16562             return BCM_E_PARAM;
  16563         }
  16564         startq = startq1;
  16565         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
  16566     }
  16567 
  16568     switch (type) {
  16569     case bcmCosqControlEgressUCQueueSharedLimitBytes:
  16570     case bcmCosqControlEgressMCQueueSharedLimitBytes:
  16571         fld_limit = Q_SHARED_LIMIT_CELLf;
  16572         fld_limit2 = Q_LIMIT_ENABLE_CELLf;
  16573 
  16574         /* Disable queuing when both MIN and SHARED LIMITS are zero.
  16575          * Enable it when either MIN or SHARED LIMIT is non-zero.
  16576          */
  16577         limit = soc_mem_field32_get(unit, mem, entry, Q_MIN_CELLf);
  16578         if (arg == 0 && limit == 0) {
  16579             soc_kt2_cosq_queue_enable(unit, startq, 0);
  16580         } else {
  16581             soc_kt2_cosq_queue_enable(unit, startq, 1);
  16582         }
  16583         granularity = 1;
  16584         break;
  16585     case bcmCosqControlEgressUCQueueMinLimitBytes:
  16586     case bcmCosqControlEgressMCQueueMinLimitBytes:
  16587         fld_limit = Q_MIN_CELLf;
  16588 
  16589         /* Disable queuing when both MIN and SHARED LIMITS are zero.
  16590          * Enable it when either MIN or SHARED LIMIT is non-zero.
  16591          */
  16592         limit = soc_mem_field32_get(unit, mem, entry, Q_SHARED_LIMIT_CELLf);
  16593         if (arg == 0 && limit == 0) {
  16594             soc_kt2_cosq_queue_enable(unit, startq, 0);
  16595         } else {
  16596             soc_kt2_cosq_queue_enable(unit, startq, 1);
  16597         }
  16598         granularity = 1;
  16599         break;
  16600     default:
  16601         return BCM_E_UNAVAIL;
  16602     }
  16603 
  16604     /* Recalculate Shared Values if Min Changed */
  16605     if (IS_EXT_MEM_PORT(unit, local_port)) {
  16606         soc_kt2_mmu_get_shared_size(unit, NULL, &shared_size);
  16607     } else {
  16608         soc_kt2_mmu_get_shared_size(unit, &shared_size, NULL);
  16609     }
  16610     cur_val = soc_mem_field32_get(unit, mem, entry, fld_limit);
  16611         
  16612     if ((arg / granularity) > cur_val) {
  16613         /* New Min Val > Cur Min Val
  16614          * So reduce the Shared values first and then 
  16615          * Increase the Min Value for given resource
  16616          */
  16617         post_update = 0;
  16618     } else if ((arg / granularity) < cur_val) {
  16619         /* New Min Val < Cur Min Val
  16620          * So reduce the Min values first and then 
  16621          * Increase Shared values everywhere
  16622          */
  16623         post_update = 1;
  16624     } else {
  16625         return BCM_E_NONE;
  16626     }
  16627  
  16628     if (!post_update &&
  16629         ((type == bcmCosqControlEgressUCQueueMinLimitBytes) ||
  16630          (type == bcmCosqControlEgressMCQueueMinLimitBytes))) {
  16631         int delta = 0; /* In Cells */
  16632         delta = ((arg / granularity) - cur_val) * granularity;
  16633         if (delta > shared_size) {
  16634             return BCM_E_RESOURCE;
  16635         }
  16636         if (IS_EXT_MEM_PORT(unit, local_port)) {
  16637             recalc_type = BCM_KT2_RECALC_SHARED_EXT_DECREMENT; 
  16638         } else {
  16639             recalc_type = BCM_KT2_RECALC_SHARED_INT_DECREMENT; 
  16640         }
  16641 #if defined(BCM_SABER2_SUPPORT)
  16642         if (SOC_IS_SABER2(unit)) {
  16643             rv = soc_sb2_mmu_config_shared_buf_recalc(unit,
  16644                                                     shared_size - delta, 
  16645                                                     recalc_type);
  16646         } else 
  16647 #endif
  16648         {
  16649             rv = soc_kt2_mmu_config_shared_buf_recalc(unit,
  16650                                                     shared_size - delta, 
  16651                                                     recalc_type);
  16652         }
  16653         if (rv < 0) { 
  16654             return rv;
  16655         }
  16656     }
  16657 
  16658     /* Check for min/max values */
  16659     max_val = (1 << soc_mem_field_length(unit, mem, fld_limit)) - 1;
  16660     if (IS_EXT_MEM_PORT(unit, local_port)) {
  16661         max_val = soc_kt2_get_max_buffer_size(unit, 1, max_val);
  16662     } else {
  16663         max_val = soc_kt2_get_max_buffer_size(unit, 0, max_val);
  16664     }
  16665     if ((arg < 0) || ((arg/granularity) > max_val)) {
  16666         return BCM_E_PARAM;
  16667     } else {
  16668         soc_mem_field32_set(unit, mem, entry, fld_limit, (arg/granularity));
  16669         if (fld_limit2 != INVALIDr) {
  16670             soc_mem_field32_set(unit, mem, entry, fld_limit2, 1);
  16671         }
  16672     }
  16673 
  16674     BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
  16675 
  16676     if (post_update && 
  16677         ((type == bcmCosqControlEgressUCQueueMinLimitBytes) ||
  16678          (type == bcmCosqControlEgressMCQueueMinLimitBytes))) {
  16679         int delta = 0;
  16680         delta = (cur_val - (arg / granularity)) * granularity;
  16681         if (delta > shared_size) {
  16682             return BCM_E_RESOURCE;
  16683         }
  16684         if (IS_EXT_MEM_PORT(unit, local_port)) {
  16685             recalc_type = BCM_KT2_RECALC_SHARED_EXT_INCREMENT; 
  16686         } else {
  16687             recalc_type = BCM_KT2_RECALC_SHARED_INT_INCREMENT; 
  16688         }
  16689 #if defined(BCM_SABER2_SUPPORT)
  16690         if (SOC_IS_SABER2(unit)) {
  16691             rv = soc_sb2_mmu_config_shared_buf_recalc(unit,
  16692                                                     shared_size + delta, 
  16693                                                     recalc_type);
  16694         } else 
  16695 #endif
  16696         {
  16697             rv = soc_kt2_mmu_config_shared_buf_recalc(unit,
  16698                                                     shared_size + delta, 
  16699                                                     recalc_type);
  16700         }
  16701         if (rv < 0) { 
  16702             return rv;
  16703         }
  16704     }
  16705 
  16706     return BCM_E_NONE;
  16707 }
  16708 
  16709 STATIC int
  16710 _bcm_kt2_cosq_ing_res_set(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
  16711                           bcm_cosq_control_t type, int arg)
  16712 {
  16713     bcm_port_t local_port;
  16714     int midx, cell_size = _BCM_KT2_COSQ_CELLSIZE;
  16715     uint32 max_val;
  16716     uint32 entry[SOC_MAX_MEM_WORDS];
  16717     soc_mem_t mem = INVALIDm;
  16718     soc_field_t fld_limit = INVALIDf;
  16719     int granularity = 1;
  16720 
  16721     if (arg < 0) {
  16722         return BCM_E_PARAM;
  16723     }
  16724 
  16725     BCM_IF_ERROR_RETURN
  16726         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  16727                                 NULL));        
  16728 
  16729     if (local_port < 0) {
  16730         return BCM_E_PORT;
  16731     }
  16732 
  16733     if (IS_EXT_MEM_PORT(unit, local_port)) {
  16734         cell_size = _BCM_KT2_COSQ_EXT_CELLSIZE;
  16735         if (soc_feature(unit, soc_feature_mmu_packing)) {
  16736             cell_size = _BCM_KT2_COSQ_EXT_PACKING_CELLSIZE;
  16737         }
  16738     }    
  16739 
  16740     arg /= cell_size;
  16741 
  16742 #if defined(BCM_SABER2_SUPPORT)
  16743     if (SOC_IS_SABER2(unit)) {
  16744         BCM_IF_ERROR_RETURN(
  16745             _bcm_sb2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  16746     } else 
  16747 #endif
  16748     {
  16749         BCM_IF_ERROR_RETURN(
  16750             _bcm_kt2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  16751     }
  16752 
  16753     mem = THDI_PORT_PG_CONFIGm;
  16754 
  16755     BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
  16756 
  16757     switch (type) {
  16758     case bcmCosqControlIngressPortPGSharedLimitBytes:
  16759         fld_limit = PG_SHARED_LIMITf;
  16760         granularity = 1;
  16761         break;
  16762     case bcmCosqControlIngressPortPGMinLimitBytes:
  16763         fld_limit = PG_MIN_LIMITf;
  16764         granularity = 1;
  16765         break;
  16766     case bcmCosqControlIngressPortPGHeadroomLimitBytes: 
  16767         fld_limit = PG_HDRM_LIMITf;
  16768         granularity = 1;
  16769         break;
  16770     case bcmCosqControlIngressPortPGResetFloorBytes: 
  16771         fld_limit = PG_RESET_FLOORf;
  16772         granularity = 1;
  16773         break;
  16774     default:
  16775         return BCM_E_UNAVAIL;
  16776     }
  16777 
  16778     /* Check for min/max values */
  16779     max_val = (1 << soc_mem_field_length(unit, mem, fld_limit)) - 1;
  16780 
  16781     if (IS_EXT_MEM_PORT(unit, local_port)) {
  16782         max_val = soc_kt2_get_max_buffer_size(unit, 1, max_val);
  16783     } else {
  16784         max_val = soc_kt2_get_max_buffer_size(unit, 0, max_val);
  16785     }
  16786 
  16787     if ((arg < 0) || ((arg/granularity) > max_val)) {
  16788         return BCM_E_PARAM;
  16789     } else {
  16790         soc_mem_field32_set(unit, mem, entry, fld_limit, (arg/granularity));
  16791     }
  16792     BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry));
  16793 
  16794     return BCM_E_NONE;
  16795 }
  16796 
  16797 STATIC int
  16798 _bcm_kt2_cosq_alpha_set(int unit, 
  16799                         bcm_gport_t gport, bcm_cos_queue_t cosq,
  16800                         bcm_cosq_control_drop_limit_alpha_value_t arg)
  16801 {
  16802     int startq = -1;
  16803     int midx; 
  16804     uint32 entry[SOC_MAX_MEM_WORDS];
  16805     soc_mem_t mem = INVALIDm;
  16806     int alpha;
  16807     int dynamic_thresh_mode;    
  16808     _bcm_kt2_cosq_node_t *node;
  16809 
  16810     switch(arg) {
  16811     case bcmCosqControlDropLimitAlpha_1_64:
  16812         alpha = SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_64;
  16813         break;
  16814     case bcmCosqControlDropLimitAlpha_1_32:
  16815         alpha = SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_32;
  16816         break;
  16817     case bcmCosqControlDropLimitAlpha_1_16:
  16818         alpha = SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_16;
  16819         break;
  16820     case bcmCosqControlDropLimitAlpha_1_8:
  16821         alpha = SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_8;
  16822         break;
  16823     case bcmCosqControlDropLimitAlpha_1_4:
  16824         alpha = SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_4;
  16825         break;
  16826     case bcmCosqControlDropLimitAlpha_1_2:
  16827         alpha = SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_2;
  16828         break;
  16829     case bcmCosqControlDropLimitAlpha_1:
  16830         alpha = SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1;
  16831         break;   
  16832     case bcmCosqControlDropLimitAlpha_2:
  16833         alpha = SOC_KT2_COSQ_DROP_LIMIT_ALPHA_2;
  16834         break;
  16835     case bcmCosqControlDropLimitAlpha_4:
  16836         alpha = SOC_KT2_COSQ_DROP_LIMIT_ALPHA_4;
  16837         break;
  16838     case bcmCosqControlDropLimitAlpha_8:
  16839         alpha = SOC_KT2_COSQ_DROP_LIMIT_ALPHA_8;
  16840         break;         
  16841     default:
  16842         return BCM_E_PARAM;          
  16843     }
  16844 
  16845     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  16846         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  16847         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
  16848         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  16849         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  16850         BCM_GPORT_IS_SCHEDULER(gport)) {
  16851         BCM_IF_ERROR_RETURN
  16852             (_bcm_kt2_cosq_node_get(unit, gport, NULL, NULL, NULL,
  16853                                    &node));        
  16854         if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) &&
  16855             (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2)) {
  16856             return BCM_E_PARAM;
  16857         }
  16858         if (BCM_GPORT_IS_SCHEDULER(gport)) {
  16859             BCM_IF_ERROR_RETURN(
  16860                 _bcm_kt2_cosq_child_node_at_input(node, cosq,
  16861                                               &node)); 
  16862         }
  16863         startq = node->hw_index;
  16864     }
  16865 
  16866     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  16867         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  16868         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  16869         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  16870 
  16871         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  16872             BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  16873             BCM_IF_ERROR_RETURN
  16874                     (_bcm_kt2_cosq_dynamic_thresh_enable_get(unit, gport, cosq, 
  16875                                    bcmCosqControlEgressUCSharedDynamicEnable, 
  16876                                    &dynamic_thresh_mode));
  16877         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) || 
  16878                    BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  16879             BCM_IF_ERROR_RETURN
  16880                     (_bcm_kt2_cosq_dynamic_thresh_enable_get(unit, gport, cosq, 
  16881                                    bcmCosqControlEgressMCSharedDynamicEnable, 
  16882                                    &dynamic_thresh_mode));
  16883         }
  16884 
  16885         if (!dynamic_thresh_mode){
  16886             return BCM_E_CONFIG;
  16887         } 
  16888         
  16889         mem = MMU_THDO_QCONFIG_CELLm;
  16890 
  16891         BCM_IF_ERROR_RETURN
  16892             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
  16893         soc_mem_field32_set(unit, mem, entry, 
  16894                             Q_SHARED_ALPHA_CELLf, alpha);
  16895         SOC_IF_ERROR_RETURN
  16896             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));                 
  16897     } else {
  16898 #if defined(BCM_SABER2_SUPPORT)
  16899         if (SOC_IS_SABER2(unit)) {
  16900             BCM_IF_ERROR_RETURN(
  16901                 _bcm_sb2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  16902         } else 
  16903 #endif
  16904         {
  16905             BCM_IF_ERROR_RETURN(
  16906                 _bcm_kt2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  16907         }
  16908 
  16909         mem = THDI_PORT_PG_CONFIGm;
  16910 
  16911         BCM_IF_ERROR_RETURN
  16912             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
  16913         soc_mem_field32_set(unit, mem, entry, 
  16914                             PG_SHARED_LIMITf, alpha);
  16915         SOC_IF_ERROR_RETURN
  16916             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry)); 
  16917     } 
  16918     
  16919     return BCM_E_NONE;
  16920 }
  16921 
  16922 STATIC int
  16923 _bcm_kt2_cosq_dynamic_thresh_enable_set(int unit, 
  16924                         bcm_gport_t gport, bcm_cos_queue_t cosq,
  16925                         bcm_cosq_control_t type, int arg)
  16926 {
  16927     bcm_port_t local_port;
  16928     int startq, startq1;
  16929     int midx, numq; 
  16930     uint32 entry[SOC_MAX_MEM_WORDS];
  16931     soc_mem_t mem = INVALIDm;
  16932     _bcm_kt2_mmu_info_t *mmu_info = _bcm_kt2_mmu_info[unit];
  16933     _bcm_kt2_cosq_node_t *node;
  16934 
  16935     BCM_IF_ERROR_RETURN
  16936         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  16937                                 &node));        
  16938 
  16939     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  16940         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  16941         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
  16942         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  16943         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  16944         BCM_GPORT_IS_SCHEDULER(gport)) {
  16945         if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) &&
  16946             (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2)) {
  16947             return BCM_E_PARAM;
  16948         }
  16949         if (BCM_GPORT_IS_SCHEDULER(gport)) {
  16950             BCM_IF_ERROR_RETURN(
  16951                 _bcm_kt2_cosq_child_node_at_input(node, cosq,
  16952                                               &node)); 
  16953         }
  16954 
  16955         startq = node->hw_index;
  16956         startq1 = node->hw_index;
  16957     } else {
  16958         mmu_info = _bcm_kt2_mmu_info[unit];
  16959         numq = mmu_info->port[local_port].q_limit -
  16960                 mmu_info->port[local_port].q_offset;
  16961 
  16962         if (cosq < 0 || cosq >= numq) {
  16963             return BCM_E_PARAM;
  16964         }
  16965         startq = mmu_info->port[local_port].q_offset + cosq;
  16966         startq1 = mmu_info->port[local_port].mcq_offset + cosq;
  16967     }
  16968     
  16969     if (type == bcmCosqControlIngressPortPGSharedDynamicEnable) {
  16970 #if defined(BCM_SABER2_SUPPORT)
  16971         if (SOC_IS_SABER2(unit)) {
  16972             BCM_IF_ERROR_RETURN(
  16973                 _bcm_sb2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  16974         } else 
  16975 #endif
  16976         {
  16977             BCM_IF_ERROR_RETURN(
  16978                 _bcm_kt2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  16979         }
  16980 
  16981         mem = THDI_PORT_PG_CONFIGm;
  16982 
  16983         BCM_IF_ERROR_RETURN
  16984             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
  16985         soc_mem_field32_set(unit, mem, entry, 
  16986                             PG_SHARED_DYNAMICf, arg ? 1 : 0);
  16987         if (arg) {
  16988             soc_mem_field32_set(unit, mem, entry,
  16989                     PG_SHARED_LIMITf, SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_64);
  16990         }
  16991         SOC_IF_ERROR_RETURN
  16992             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry));           
  16993     } else if (type == bcmCosqControlEgressUCSharedDynamicEnable) {
  16994         if (node && 
  16995             BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport)) {
  16996             return BCM_E_PARAM;
  16997         }
  16998         
  16999         mem = MMU_THDO_QCONFIG_CELLm;
  17000         BCM_IF_ERROR_RETURN
  17001             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
  17002         soc_mem_field32_set(unit, mem, entry, 
  17003                             Q_LIMIT_DYNAMIC_CELLf, arg ? 1 : 0);
  17004         if (arg) {
  17005             soc_mem_field32_set(unit, mem, entry,
  17006                     Q_SHARED_ALPHA_CELLf, SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_64);
  17007         }
  17008         SOC_IF_ERROR_RETURN
  17009             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));         
  17010     } else if (type == bcmCosqControlEgressMCSharedDynamicEnable) {
  17011         if (node && BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport)) {
  17012             return BCM_E_PARAM;
  17013         }
  17014 
  17015         mem = MMU_THDO_QCONFIG_CELLm;
  17016         BCM_IF_ERROR_RETURN
  17017             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq1, entry));
  17018         soc_mem_field32_set(unit, mem, entry, 
  17019                             Q_LIMIT_DYNAMIC_CELLf, arg ? 1 : 0);
  17020         if (arg) {
  17021             soc_mem_field32_set(unit, mem, entry,
  17022                     Q_SHARED_ALPHA_CELLf, SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_64);
  17023         }
  17024         SOC_IF_ERROR_RETURN
  17025             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq1, entry));    
  17026     } else {
  17027         return BCM_E_PARAM;
  17028     }
  17029 
  17030     return BCM_E_NONE;
  17031 }
  17032 
  17033 STATIC int
  17034 _bcm_kt2_cosq_egr_queue_limit_enable_set(int unit, bcm_gport_t gport,
  17035                                                  bcm_cos_queue_t cosq,
  17036                                                  bcm_cosq_control_t type,
  17037                                                  int arg)
  17038 {
  17039     bcm_port_t local_port;
  17040     int startq, startq1, numq;
  17041     uint32 entry[SOC_MAX_MEM_WORDS];
  17042     soc_mem_t mem = INVALIDm;
  17043     _bcm_kt2_cosq_node_t *node;
  17044     _bcm_kt2_mmu_info_t *mmu_info = _bcm_kt2_mmu_info[unit];
  17045     int enable;
  17046 
  17047     if (arg < 0) {
  17048         return BCM_E_PARAM;
  17049     }
  17050 
  17051     arg = arg ? 1 : 0;
  17052 
  17053     BCM_IF_ERROR_RETURN
  17054         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  17055                                 &node));        
  17056 
  17057     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  17058         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  17059         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
  17060         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17061         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17062         BCM_GPORT_IS_SCHEDULER(gport)) {
  17063         if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) &&
  17064             (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2)) {
  17065             return BCM_E_PARAM;
  17066         }
  17067         if (BCM_GPORT_IS_SCHEDULER(gport)) {
  17068             BCM_IF_ERROR_RETURN(
  17069                 _bcm_kt2_cosq_child_node_at_input(node, cosq,
  17070                                               &node)); 
  17071         }
  17072 
  17073         startq = node->hw_index;
  17074         startq1 = node->hw_index;
  17075     } else {
  17076         mmu_info = _bcm_kt2_mmu_info[unit];
  17077         numq = mmu_info->port[local_port].q_limit -
  17078                 mmu_info->port[local_port].q_offset;
  17079 
  17080         if (cosq < 0 || cosq >= numq) {
  17081             return BCM_E_PARAM;
  17082         }
  17083         startq = mmu_info->port[local_port].q_offset + cosq;
  17084         startq1 = mmu_info->port[local_port].mcq_offset + cosq;
  17085     }
  17086     
  17087 
  17088     if (type == bcmCosqControlEgressUCQueueLimitEnable) {
  17089         if (node && BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport)) {
  17090             return BCM_E_PARAM;
  17091         }
  17092         mem = MMU_THDO_QCONFIG_CELLm;
  17093 
  17094         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
  17095         enable = soc_mem_field32_get(unit, mem, entry, Q_LIMIT_ENABLE_CELLf);
  17096         if (enable != arg) {
  17097             soc_mem_field32_set(unit, mem, entry, Q_LIMIT_ENABLE_CELLf, arg);
  17098             BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
  17099         }
  17100     }else if (type == bcmCosqControlEgressMCQueueLimitEnable) {
  17101         if (node && BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport)) {
  17102             return BCM_E_PARAM;
  17103         }
  17104         mem = MMU_THDO_QCONFIG_CELLm;
  17105 
  17106         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq1, entry));
  17107         enable = soc_mem_field32_get(unit, mem, entry, Q_LIMIT_ENABLE_CELLf);
  17108         if (enable != arg) {
  17109             soc_mem_field32_set(unit, mem, entry, Q_LIMIT_ENABLE_CELLf, arg);
  17110             BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq1, entry));
  17111         }
  17112     } else {
  17113         return BCM_E_PARAM;
  17114     }
  17115 
  17116     return BCM_E_NONE;
  17117 }
  17118 
  17119 int
  17120 bcm_kt2_cosq_control_set(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
  17121                         bcm_cosq_control_t type, int arg)
  17122 {
  17123     LOG_INFO(BSL_LS_BCM_COSQ,
  17124              (BSL_META_U(unit,
  17125                          "bcm_kt2_cosq_control_set: unit=%d gport=0x%x cosq=%d \
  17126                          type=%d arg=%d\n"),
  17127               unit, gport, cosq, type, arg));
  17128     switch (type) {
  17129     case bcmCosqControlEfPropagation:
  17130         return _bcm_kt2_cosq_ef_op(unit, gport, cosq, &arg, _BCM_COSQ_OP_SET);
  17131    
  17132     case bcmCosqControlRedirectQueueSharedLimitBytes:
  17133         return _bcm_kt2_cosq_redirect_parameter_set(unit, OP_QUEUE_CONFIG_THDORDEQr,
  17134                 Q_SHARED_LIMITf, cosq, arg);
  17135    
  17136     case bcmCosqControlRedirectQueueMinLimitBytes:
  17137         return _bcm_kt2_cosq_redirect_parameter_set(unit, OP_QUEUE_CONFIG1_THDORDEQr,
  17138                 Q_MINf, cosq, arg);
  17139 
  17140     case bcmCosqControlRedirectSharedDynamicEnable:
  17141         return _bcm_kt2_cosq_redirect_parameter_set(unit, OP_QUEUE_CONFIG_THDORDEQr,
  17142                 Q_LIMIT_DYNAMICf, cosq, arg);
  17143 
  17144     case bcmCosqControlRedirectQueueLimitEnable:
  17145         return _bcm_kt2_cosq_redirect_parameter_set(unit, OP_QUEUE_CONFIG_THDORDEQr,
  17146                 Q_LIMIT_ENABLEf, cosq, arg);
  17147 
  17148     case bcmCosqControlRedirectColorDynamicEnable:
  17149         return _bcm_kt2_cosq_redirect_parameter_set(unit, OP_QUEUE_CONFIG1_THDORDEQr,
  17150                 Q_COLOR_DYNAMICf, cosq, arg);
  17151 
  17152     case bcmCosqControlRedirectColorEnable:
  17153         return _bcm_kt2_cosq_redirect_parameter_set(unit, OP_QUEUE_CONFIG1_THDORDEQr,
  17154                 Q_COLOR_ENABLEf, cosq, arg);
  17155     
  17156     case bcmCosqControlEgressPoolLimitBytes:
  17157     case bcmCosqControlEgressPoolYellowLimitBytes:
  17158     case bcmCosqControlEgressPoolRedLimitBytes:
  17159     case bcmCosqControlEgressPoolLimitEnable:
  17160         return _bcm_kt2_cosq_egr_pool_set(unit, gport, cosq, type, arg);
  17161     case bcmCosqControlEgressUCQueueSharedLimitBytes:
  17162     case bcmCosqControlEgressMCQueueSharedLimitBytes:
  17163     case bcmCosqControlEgressUCQueueMinLimitBytes:
  17164     case bcmCosqControlEgressMCQueueMinLimitBytes:
  17165         return _bcm_kt2_cosq_egr_queue_set(unit, gport, cosq, type, arg);
  17166     case bcmCosqControlIngressPortPGSharedLimitBytes:
  17167     case bcmCosqControlIngressPortPGMinLimitBytes:
  17168     case bcmCosqControlIngressPortPGHeadroomLimitBytes:
  17169     case bcmCosqControlIngressPortPGResetFloorBytes:
  17170         return _bcm_kt2_cosq_ing_res_set(unit, gport, cosq, type, arg);
  17171     case bcmCosqControlDropLimitAlpha:
  17172         return _bcm_kt2_cosq_alpha_set(unit, gport, cosq,
  17173                             (bcm_cosq_control_drop_limit_alpha_value_t)arg);
  17174     case bcmCosqControlIngressPortPGSharedDynamicEnable:
  17175     case bcmCosqControlEgressUCSharedDynamicEnable:
  17176     case bcmCosqControlEgressMCSharedDynamicEnable:
  17177         return _bcm_kt2_cosq_dynamic_thresh_enable_set(unit, gport, cosq,
  17178                                                        type, arg);
  17179     case bcmCosqControlEgressUCQueueLimitEnable:
  17180     case bcmCosqControlEgressMCQueueLimitEnable:
  17181         return _bcm_kt2_cosq_egr_queue_limit_enable_set(unit, gport, cosq, type, arg);
  17182 
  17183     default:
  17184         break;
  17185     }
  17186 
  17187     return BCM_E_UNAVAIL;
  17188 }
  17189 
  17190 int
  17191 _bcm_kt2_cosq_redirect_parameter_get (int unit, soc_reg_t reg,
  17192         soc_field_t field, bcm_cos_queue_t cosq, int *arg)
  17193 {
  17194     uint32 rval;
  17195     if (!arg) {
  17196         return BCM_E_PARAM;
  17197     }
  17198 
  17199     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, cosq,
  17200                  &rval));
  17201     *arg = soc_reg_field_get(unit, reg, rval, field);
  17202 
  17203     return BCM_E_NONE;
  17204 }
  17205 
  17206 STATIC int
  17207 _bcm_kt2_cosq_egr_pool_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
  17208                           bcm_cosq_control_t type, int *arg)
  17209 {
  17210 
  17211     int startq;
  17212     uint32 entry[SOC_MAX_MEM_WORDS];
  17213     soc_mem_t mem = INVALIDm;
  17214     soc_field_t fld_limit = INVALIDf;
  17215     int granularity = 1;
  17216     bcm_port_t local_port;
  17217     _bcm_kt2_cosq_node_t *node;
  17218     int cell_size = _BCM_KT2_COSQ_CELLSIZE;
  17219     _bcm_kt2_mmu_info_t *mmu_info = _bcm_kt2_mmu_info[unit];
  17220     int numq;
  17221 
  17222     if (!arg) {
  17223         return BCM_E_PARAM;
  17224     }
  17225 
  17226     BCM_IF_ERROR_RETURN
  17227         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  17228                                 &node));        
  17229     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  17230         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  17231         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
  17232         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17233         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17234         BCM_GPORT_IS_SCHEDULER(gport)) {
  17235         if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) &&
  17236             (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2)) {
  17237             return BCM_E_PARAM;
  17238         }
  17239         if (BCM_GPORT_IS_SCHEDULER(gport)) {
  17240             BCM_IF_ERROR_RETURN(
  17241                 _bcm_kt2_cosq_child_node_at_input(node, cosq,
  17242                                               &node)); 
  17243         }
  17244 
  17245         startq = node->hw_index;
  17246 
  17247     } else {
  17248         mmu_info = _bcm_kt2_mmu_info[unit];
  17249         numq = mmu_info->port[local_port].q_limit -
  17250                 mmu_info->port[local_port].q_offset;
  17251 
  17252         if (cosq < 0 || cosq >= numq) {
  17253             return BCM_E_PARAM;
  17254         }
  17255         startq = mmu_info->port[local_port].q_offset + cosq;
  17256     }
  17257 
  17258     if (IS_EXT_MEM_PORT(unit, local_port)) {
  17259         cell_size = _BCM_KT2_COSQ_EXT_CELLSIZE;
  17260         if (soc_feature(unit, soc_feature_mmu_packing)) {
  17261             cell_size = _BCM_KT2_COSQ_EXT_PACKING_CELLSIZE;
  17262         }
  17263     }    
  17264 
  17265     mem = MMU_THDO_QCONFIG_CELLm;
  17266     if (type == bcmCosqControlEgressPoolRedLimitBytes) {
  17267         mem = MMU_THDO_QOFFSET_CELLm;
  17268     }
  17269 
  17270     BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
  17271 
  17272     switch (type) {
  17273     case bcmCosqControlEgressPoolLimitBytes:
  17274         fld_limit = Q_SHARED_LIMIT_CELLf;
  17275         granularity = 1;
  17276         break;
  17277     case bcmCosqControlEgressPoolYellowLimitBytes:
  17278         fld_limit = LIMIT_YELLOW_CELLf;
  17279         granularity = 8;
  17280         break;
  17281     case bcmCosqControlEgressPoolRedLimitBytes:
  17282         fld_limit = LIMIT_RED_CELLf;
  17283         granularity = 8;
  17284         break;
  17285     case bcmCosqControlEgressPoolLimitEnable:
  17286         fld_limit = Q_LIMIT_ENABLE_CELLf;
  17287         granularity = 1;
  17288         break;
  17289     default:
  17290         return BCM_E_UNAVAIL;
  17291     }
  17292 
  17293     /* Check for min/max values */
  17294     *arg = soc_mem_field32_get(unit, mem, entry, fld_limit);
  17295     if (type == bcmCosqControlEgressPoolLimitEnable) {
  17296         *arg = (*arg) * granularity;
  17297     } else {
  17298         *arg = (*arg) * cell_size * granularity;
  17299     }
  17300 
  17301     return BCM_E_NONE;
  17302 }
  17303 
  17304 STATIC int
  17305 _bcm_kt2_cosq_egr_queue_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
  17306                             bcm_cosq_control_t type, int *arg)
  17307 {
  17308     bcm_port_t local_port;
  17309     int startq, startq1;
  17310     uint32 entry[SOC_MAX_MEM_WORDS];
  17311     soc_mem_t mem = INVALIDm;
  17312     soc_field_t fld_limit = INVALIDf;
  17313     int granularity = 1;
  17314     int cell_size = _BCM_KT2_COSQ_CELLSIZE;
  17315     _bcm_kt2_cosq_node_t *node;
  17316     _bcm_kt2_mmu_info_t *mmu_info = _bcm_kt2_mmu_info[unit];
  17317     int numq;
  17318 
  17319     if (!arg) {
  17320         return BCM_E_PARAM;
  17321     }
  17322 
  17323     BCM_IF_ERROR_RETURN
  17324         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  17325                                 &node));        
  17326     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  17327         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  17328         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
  17329         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17330         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17331         BCM_GPORT_IS_SCHEDULER(gport)) {
  17332         if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) &&
  17333             (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2)) {
  17334             return BCM_E_PARAM;
  17335         }
  17336         if (BCM_GPORT_IS_SCHEDULER(gport)) {
  17337             BCM_IF_ERROR_RETURN(
  17338                 _bcm_kt2_cosq_child_node_at_input(node, cosq,
  17339                                               &node)); 
  17340         }
  17341 
  17342         startq = node->hw_index;
  17343         startq1 = node->hw_index;
  17344     } else {
  17345         mmu_info = _bcm_kt2_mmu_info[unit];
  17346         numq = mmu_info->port[local_port].q_limit -
  17347                 mmu_info->port[local_port].q_offset;
  17348 
  17349         if (cosq < 0 || cosq >= numq) {
  17350             return BCM_E_PARAM;
  17351         }
  17352         startq = mmu_info->port[local_port].q_offset + cosq;
  17353         startq1 = mmu_info->port[local_port].mcq_offset + cosq;
  17354     }
  17355 
  17356     if (IS_EXT_MEM_PORT(unit, local_port)) {
  17357         cell_size = _BCM_KT2_COSQ_EXT_CELLSIZE;
  17358         if (soc_feature(unit, soc_feature_mmu_packing)) {
  17359             cell_size = _BCM_KT2_COSQ_EXT_PACKING_CELLSIZE;
  17360         }
  17361     }    
  17362 
  17363     mem = MMU_THDO_QCONFIG_CELLm;
  17364 
  17365     if ((type == bcmCosqControlEgressUCQueueSharedLimitBytes) ||
  17366         (type == bcmCosqControlEgressUCQueueMinLimitBytes)) {
  17367         if (node && (BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport) ||
  17368                      BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport))) {
  17369             return BCM_E_PARAM;
  17370         }
  17371         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL,
  17372                             startq, entry));
  17373     } else if ((type == bcmCosqControlEgressMCQueueSharedLimitBytes) ||
  17374                (type == bcmCosqControlEgressMCQueueMinLimitBytes)) {
  17375         if (node && (BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport) ||
  17376                      BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(node->gport))) {
  17377             return BCM_E_PARAM;
  17378         }
  17379         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL,
  17380                             startq1, entry));
  17381     }
  17382 
  17383     switch (type) {
  17384     case bcmCosqControlEgressUCQueueSharedLimitBytes:
  17385     case bcmCosqControlEgressMCQueueSharedLimitBytes:
  17386         fld_limit = Q_SHARED_LIMIT_CELLf;
  17387         granularity = 1;
  17388         break;
  17389     case bcmCosqControlEgressUCQueueMinLimitBytes:
  17390     case bcmCosqControlEgressMCQueueMinLimitBytes:
  17391         fld_limit = Q_MIN_CELLf;
  17392         granularity = 1;
  17393         break;
  17394     default:
  17395         return BCM_E_UNAVAIL;
  17396     }
  17397 
  17398     *arg = soc_mem_field32_get(unit, mem, entry, fld_limit);
  17399     *arg = (*arg) * granularity * cell_size;
  17400     return BCM_E_NONE;
  17401 }
  17402 
  17403 STATIC int
  17404 _bcm_kt2_cosq_ing_res_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
  17405                           bcm_cosq_control_t type, int *arg)
  17406 {
  17407     bcm_port_t local_port;
  17408     int midx;
  17409     uint32 entry[SOC_MAX_MEM_WORDS];
  17410     soc_mem_t mem = INVALIDm;
  17411     soc_field_t fld_limit = INVALIDf;
  17412     int granularity = 1;
  17413     int cell_size = _BCM_KT2_COSQ_CELLSIZE;
  17414 
  17415     if (!arg) {
  17416         return BCM_E_PARAM;
  17417     }
  17418 
  17419     BCM_IF_ERROR_RETURN
  17420         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  17421                                 NULL));        
  17422 
  17423     if (local_port < 0) {
  17424         return BCM_E_PORT;
  17425     }
  17426 
  17427     if (IS_EXT_MEM_PORT(unit, local_port)) {
  17428         cell_size = _BCM_KT2_COSQ_EXT_CELLSIZE;
  17429         if (soc_feature(unit, soc_feature_mmu_packing)) {
  17430             cell_size = _BCM_KT2_COSQ_EXT_PACKING_CELLSIZE;
  17431         }
  17432     }    
  17433 
  17434 #if defined(BCM_SABER2_SUPPORT)
  17435     if (SOC_IS_SABER2(unit)) {
  17436         BCM_IF_ERROR_RETURN(
  17437             _bcm_sb2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  17438     } else 
  17439 #endif
  17440     {
  17441         BCM_IF_ERROR_RETURN(
  17442             _bcm_kt2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  17443     }
  17444 
  17445     mem = THDI_PORT_PG_CONFIGm;
  17446 
  17447     BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
  17448 
  17449     switch (type) {
  17450     case bcmCosqControlIngressPortPGSharedLimitBytes:
  17451         fld_limit = PG_SHARED_LIMITf;
  17452         granularity = 1;
  17453         break;
  17454     case bcmCosqControlIngressPortPGMinLimitBytes:
  17455         fld_limit = PG_MIN_LIMITf;
  17456         granularity = 1;
  17457         break;
  17458     case bcmCosqControlIngressPortPGHeadroomLimitBytes:
  17459         fld_limit = PG_HDRM_LIMITf;
  17460         granularity = 1;
  17461         break;
  17462     case bcmCosqControlIngressPortPGResetFloorBytes:
  17463         fld_limit = PG_RESET_FLOORf;
  17464         granularity = 1;
  17465         break;
  17466    default:
  17467         return BCM_E_UNAVAIL;
  17468     }
  17469     *arg = soc_mem_field32_get(unit, mem, entry, fld_limit);
  17470     *arg = (*arg) * granularity * cell_size;
  17471     return BCM_E_NONE;
  17472 }
  17473 
  17474 STATIC int
  17475 _bcm_kt2_cosq_alpha_get(int unit, 
  17476                         bcm_gport_t gport, bcm_cos_queue_t cosq, 
  17477                         bcm_cosq_control_drop_limit_alpha_value_t *arg)
  17478 {
  17479     int startq = -1;
  17480     int midx;  
  17481     uint32 entry[SOC_MAX_MEM_WORDS];
  17482     soc_mem_t mem = INVALIDm;    
  17483     int alpha;
  17484     int dynamic_thresh_mode;    
  17485     _bcm_kt2_cosq_node_t *node;
  17486 
  17487     if (!arg) {
  17488         return BCM_E_PARAM;
  17489     }
  17490 
  17491     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  17492         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  17493         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
  17494         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17495         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17496         BCM_GPORT_IS_SCHEDULER(gport)) {
  17497         BCM_IF_ERROR_RETURN
  17498             (_bcm_kt2_cosq_node_get(unit, gport, NULL, NULL, NULL,
  17499                                    &node));        
  17500         if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) &&
  17501             (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2)) {
  17502             return BCM_E_PARAM;
  17503         }
  17504         if (BCM_GPORT_IS_SCHEDULER(gport)) {
  17505             BCM_IF_ERROR_RETURN(
  17506                 _bcm_kt2_cosq_child_node_at_input(node, cosq,
  17507                                               &node)); 
  17508         }
  17509 
  17510         startq = node->hw_index;
  17511     }
  17512 
  17513     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  17514         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  17515         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17516         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  17517         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  17518             BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  17519             BCM_IF_ERROR_RETURN
  17520                     (_bcm_kt2_cosq_dynamic_thresh_enable_get(unit, gport, cosq, 
  17521                                    bcmCosqControlEgressUCSharedDynamicEnable, 
  17522                                    &dynamic_thresh_mode));
  17523         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  17524                    BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)) {
  17525             BCM_IF_ERROR_RETURN
  17526                     (_bcm_kt2_cosq_dynamic_thresh_enable_get(unit, gport, cosq, 
  17527                                    bcmCosqControlEgressMCSharedDynamicEnable, 
  17528                                    &dynamic_thresh_mode));
  17529         }
  17530         if (!dynamic_thresh_mode){
  17531             return BCM_E_CONFIG;
  17532         } 
  17533         
  17534         mem = MMU_THDO_QCONFIG_CELLm;
  17535 
  17536         BCM_IF_ERROR_RETURN
  17537             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
  17538 
  17539         alpha = soc_mem_field32_get(unit, mem, entry, Q_SHARED_ALPHA_CELLf);  
  17540 
  17541     } else {
  17542 #if defined(BCM_SABER2_SUPPORT)
  17543         if (SOC_IS_SABER2(unit)) {
  17544             BCM_IF_ERROR_RETURN(
  17545                 _bcm_sb2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  17546         } else 
  17547 #endif
  17548         {
  17549             BCM_IF_ERROR_RETURN(
  17550                 _bcm_kt2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  17551         }
  17552 
  17553         mem = THDI_PORT_PG_CONFIGm;
  17554 
  17555         BCM_IF_ERROR_RETURN
  17556             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
  17557 
  17558         alpha = soc_mem_field32_get(unit, mem, entry, PG_SHARED_LIMITf);  
  17559     } 
  17560 
  17561     switch(alpha) {
  17562     case SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_64:
  17563         *arg = bcmCosqControlDropLimitAlpha_1_64;
  17564         break;
  17565     case SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_32:
  17566         *arg = bcmCosqControlDropLimitAlpha_1_32;
  17567         break;
  17568     case SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_16:
  17569         *arg = bcmCosqControlDropLimitAlpha_1_16;
  17570         break;
  17571     case SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_8:
  17572         *arg = bcmCosqControlDropLimitAlpha_1_8;
  17573         break;
  17574     case SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_4:
  17575         *arg = bcmCosqControlDropLimitAlpha_1_4;
  17576         break;
  17577     case SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1_2:
  17578         *arg = bcmCosqControlDropLimitAlpha_1_2;
  17579         break;
  17580     case SOC_KT2_COSQ_DROP_LIMIT_ALPHA_1:
  17581         *arg = bcmCosqControlDropLimitAlpha_1;
  17582         break;   
  17583     case SOC_KT2_COSQ_DROP_LIMIT_ALPHA_2:
  17584         *arg = bcmCosqControlDropLimitAlpha_2;
  17585         break;
  17586     case SOC_KT2_COSQ_DROP_LIMIT_ALPHA_4:
  17587         *arg = bcmCosqControlDropLimitAlpha_4;
  17588         break;
  17589     case SOC_KT2_COSQ_DROP_LIMIT_ALPHA_8:
  17590         *arg = bcmCosqControlDropLimitAlpha_8;
  17591         break;         
  17592     default:
  17593         return BCM_E_PARAM;          
  17594     }
  17595     
  17596     return BCM_E_NONE;
  17597 }
  17598 
  17599 STATIC int
  17600 _bcm_kt2_cosq_dynamic_thresh_enable_get(int unit, 
  17601                         bcm_gport_t gport, bcm_cos_queue_t cosq, 
  17602                         bcm_cosq_control_t type, int *arg)
  17603 {
  17604     bcm_port_t local_port;
  17605     int startq, startq1;
  17606     int midx;  
  17607     uint32 entry[SOC_MAX_MEM_WORDS];
  17608     _bcm_kt2_cosq_node_t *node;
  17609     soc_mem_t mem = INVALIDm;
  17610     _bcm_kt2_mmu_info_t *mmu_info = _bcm_kt2_mmu_info[unit];
  17611     int numq;
  17612     
  17613     if (arg == NULL) {
  17614         return BCM_E_PARAM;
  17615     }
  17616 
  17617     BCM_IF_ERROR_RETURN
  17618         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  17619                                 &node));        
  17620     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  17621         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  17622         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
  17623         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17624         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17625         BCM_GPORT_IS_SCHEDULER(gport)) {
  17626         if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) &&
  17627             (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2)) {
  17628             return BCM_E_PARAM;
  17629         }
  17630         if (BCM_GPORT_IS_SCHEDULER(gport)) {
  17631             BCM_IF_ERROR_RETURN(
  17632                 _bcm_kt2_cosq_child_node_at_input(node, cosq,
  17633                                               &node)); 
  17634         }
  17635 
  17636         startq = node->hw_index;
  17637         startq1 = node->hw_index;
  17638     } else {
  17639         mmu_info = _bcm_kt2_mmu_info[unit];
  17640         numq = mmu_info->port[local_port].q_limit -
  17641                 mmu_info->port[local_port].q_offset;
  17642 
  17643         if (cosq < 0 || cosq >= numq) {
  17644             return BCM_E_PARAM;
  17645         }
  17646         startq = mmu_info->port[local_port].q_offset + cosq;
  17647         startq1 = mmu_info->port[local_port].mcq_offset + cosq;
  17648     }
  17649 
  17650     if (type == bcmCosqControlIngressPortPGSharedDynamicEnable) {
  17651 #if defined(BCM_SABER2_SUPPORT)
  17652         if (SOC_IS_SABER2(unit)) {
  17653             BCM_IF_ERROR_RETURN(
  17654                 _bcm_sb2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  17655         } else 
  17656 #endif
  17657         {
  17658             BCM_IF_ERROR_RETURN(
  17659                 _bcm_kt2_cosq_port_pg_idx_get(unit, gport, cosq, &midx));
  17660         }
  17661 
  17662         mem = THDI_PORT_PG_CONFIGm;
  17663 
  17664         BCM_IF_ERROR_RETURN
  17665             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
  17666         *arg = soc_mem_field32_get(unit, mem, entry, PG_SHARED_DYNAMICf);  
  17667     } else if (type == bcmCosqControlEgressUCSharedDynamicEnable) {
  17668         if (node && BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport)) {
  17669             return BCM_E_PARAM;
  17670         }
  17671         
  17672         mem = MMU_THDO_QCONFIG_CELLm;
  17673         BCM_IF_ERROR_RETURN
  17674             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
  17675         *arg = soc_mem_field32_get(unit, mem, entry, Q_LIMIT_DYNAMIC_CELLf);        
  17676     } else if (type == bcmCosqControlEgressMCSharedDynamicEnable) {
  17677         if (node && BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport)) {
  17678             return BCM_E_PARAM;
  17679         }
  17680 
  17681         mem = MMU_THDO_QCONFIG_CELLm;
  17682         BCM_IF_ERROR_RETURN
  17683             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq1, entry));
  17684         *arg = soc_mem_field32_get(unit, mem, entry, Q_LIMIT_DYNAMIC_CELLf);        
  17685     } else {
  17686         return BCM_E_PARAM;
  17687     }
  17688     
  17689     return BCM_E_NONE;
  17690 }
  17691 
  17692 STATIC int
  17693 _bcm_kt2_cosq_egr_queue_limit_enable_get(int unit, bcm_gport_t gport,
  17694                                                 bcm_cos_queue_t cosq,
  17695                                                 bcm_cosq_control_t type,
  17696                                                 int *arg)
  17697 {
  17698     bcm_port_t local_port;
  17699     int startq, startq1;
  17700     uint32 entry[SOC_MAX_MEM_WORDS];
  17701     soc_mem_t mem = INVALIDm;
  17702     _bcm_kt2_cosq_node_t *node;
  17703     _bcm_kt2_mmu_info_t *mmu_info = _bcm_kt2_mmu_info[unit];
  17704     int numq;
  17705 
  17706     BCM_IF_ERROR_RETURN
  17707         (_bcm_kt2_cosq_node_get(unit, gport, NULL, &local_port, NULL,
  17708                                 &node));        
  17709 
  17710     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  17711         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
  17712         BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport) ||
  17713         BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17714         BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport) ||
  17715         BCM_GPORT_IS_SCHEDULER(gport)) {
  17716         if ((node->level != _BCM_KT2_COSQ_NODE_LEVEL_L1) &&
  17717             (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2)) {
  17718             return BCM_E_PARAM;
  17719         }
  17720         if (BCM_GPORT_IS_SCHEDULER(gport)) {
  17721             BCM_IF_ERROR_RETURN(
  17722                 _bcm_kt2_cosq_child_node_at_input(node, cosq,
  17723                                               &node)); 
  17724         }
  17725 
  17726         startq = node->hw_index;
  17727         startq1 = node->hw_index;
  17728     } else {
  17729         mmu_info = _bcm_kt2_mmu_info[unit];
  17730         numq = mmu_info->port[local_port].q_limit -
  17731                 mmu_info->port[local_port].q_offset;
  17732 
  17733         if (cosq < 0 || cosq >= numq) {
  17734             return BCM_E_PARAM;
  17735         }
  17736         startq = mmu_info->port[local_port].q_offset + cosq;
  17737         startq1 = mmu_info->port[local_port].mcq_offset + cosq;
  17738     }
  17739     
  17740     if (type == bcmCosqControlEgressUCQueueLimitEnable) {
  17741         if (node && BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport)) {
  17742             return BCM_E_PARAM;
  17743         }
  17744         mem = MMU_THDO_QCONFIG_CELLm;
  17745         mem = MMU_THDO_QCONFIG_CELLm;
  17746 
  17747         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
  17748         *arg = soc_mem_field32_get(unit, mem, entry, Q_LIMIT_ENABLE_CELLf);
  17749     } else if (type == bcmCosqControlEgressMCQueueLimitEnable) {
  17750         if (node && BCM_GPORT_IS_UCAST_QUEUE_GROUP(node->gport)) {
  17751             return BCM_E_PARAM;
  17752         }
  17753         mem = MMU_THDO_QCONFIG_CELLm;
  17754 
  17755         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq1, entry));
  17756         *arg = soc_mem_field32_get(unit, mem, entry, Q_LIMIT_ENABLE_CELLf);
  17757     } else {
  17758         return BCM_E_PARAM;
  17759     }
  17760 
  17761     return BCM_E_NONE;
  17762 }
  17763 
  17764 int
  17765 bcm_kt2_cosq_control_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
  17766                         bcm_cosq_control_t type, int *arg)
  17767 {
  17768     LOG_INFO(BSL_LS_BCM_COSQ,
  17769              (BSL_META_U(unit,
  17770                          "bcm_kt2_cosq_control_get: unit=%d gport=0x%x cosq=%d type=%d\n"),
  17771               unit, gport, cosq, type));
  17772     switch (type) {
  17773     case bcmCosqControlEfPropagation:
  17774         return _bcm_kt2_cosq_ef_op(unit, gport, cosq, arg, _BCM_COSQ_OP_GET);
  17775     case bcmCosqControlPortQueueUcast:
  17776     case bcmCosqControlPortQueueMcast:
  17777         return _bcm_kt2_cosq_port_qnum_get(unit, gport, cosq, type, arg);
  17778     case bcmCosqControlRedirectQueueSharedLimitBytes:
  17779         return _bcm_kt2_cosq_redirect_parameter_get(unit, OP_QUEUE_CONFIG_THDORDEQr,
  17780                 Q_SHARED_LIMITf, cosq, arg);
  17781     case bcmCosqControlRedirectQueueMinLimitBytes:
  17782         return _bcm_kt2_cosq_redirect_parameter_get(unit, OP_QUEUE_CONFIG1_THDORDEQr,
  17783                 Q_MINf, cosq, arg);
  17784     case bcmCosqControlRedirectSharedDynamicEnable:
  17785         return _bcm_kt2_cosq_redirect_parameter_get(unit, OP_QUEUE_CONFIG_THDORDEQr,
  17786                 Q_LIMIT_DYNAMICf, cosq, arg);
  17787     case bcmCosqControlRedirectQueueLimitEnable:
  17788         return _bcm_kt2_cosq_redirect_parameter_get(unit, OP_QUEUE_CONFIG_THDORDEQr,
  17789                 Q_LIMIT_ENABLEf, cosq, arg);
  17790     case bcmCosqControlRedirectColorDynamicEnable:
  17791         return _bcm_kt2_cosq_redirect_parameter_get(unit, OP_QUEUE_CONFIG1_THDORDEQr,
  17792                 Q_COLOR_DYNAMICf, cosq, arg);
  17793     case bcmCosqControlRedirectColorEnable:
  17794         return _bcm_kt2_cosq_redirect_parameter_get(unit, OP_QUEUE_CONFIG1_THDORDEQr,
  17795                 Q_COLOR_ENABLEf, cosq, arg);
  17796     case bcmCosqControlEgressPoolLimitBytes:
  17797     case bcmCosqControlEgressPoolYellowLimitBytes:
  17798     case bcmCosqControlEgressPoolRedLimitBytes:
  17799     case bcmCosqControlEgressPoolLimitEnable:
  17800         return _bcm_kt2_cosq_egr_pool_get(unit, gport, cosq, type, arg);
  17801     case bcmCosqControlEgressUCQueueSharedLimitBytes:
  17802     case bcmCosqControlEgressMCQueueSharedLimitBytes:
  17803     case bcmCosqControlEgressUCQueueMinLimitBytes:
  17804     case bcmCosqControlEgressMCQueueMinLimitBytes:
  17805         return _bcm_kt2_cosq_egr_queue_get(unit, gport, cosq, type, arg);
  17806     case bcmCosqControlIngressPortPGSharedLimitBytes:
  17807     case bcmCosqControlIngressPortPGMinLimitBytes:
  17808     case bcmCosqControlIngressPortPGHeadroomLimitBytes:
  17809     case bcmCosqControlIngressPortPGResetFloorBytes:
  17810         return _bcm_kt2_cosq_ing_res_get(unit, gport, cosq, type, arg);
  17811     case bcmCosqControlDropLimitAlpha:
  17812         return _bcm_kt2_cosq_alpha_get(unit, gport, cosq,
  17813                             (bcm_cosq_control_drop_limit_alpha_value_t *)arg);
  17814     case bcmCosqControlIngressPortPGSharedDynamicEnable:
  17815     case bcmCosqControlEgressUCSharedDynamicEnable:
  17816     case bcmCosqControlEgressMCSharedDynamicEnable:
  17817         return _bcm_kt2_cosq_dynamic_thresh_enable_get(unit, gport, cosq,
  17818                                                        type, arg);
  17819     case bcmCosqControlEgressUCQueueLimitEnable:
  17820     case bcmCosqControlEgressMCQueueLimitEnable:
  17821         return _bcm_kt2_cosq_egr_queue_limit_enable_get(unit, gport, cosq, type, arg);
  17822     default:
  17823         break;
  17824     }
  17825 
  17826     return BCM_E_UNAVAIL;
  17827 }
  17828 
  17829 int
  17830 bcm_kt2_cosq_port_flush(int unit, 
  17831                         bcm_port_t port,
  17832                         bcm_cosq_flush_type_t type) 
  17833 {
  17834     _bcm_kt2_mmu_info_t  *mmu_info;
  17835     _bcm_kt2_cosq_node_t *port_node = NULL;
  17836     _bcm_kt2_cosq_node_t *s0_node = NULL;
  17837     _bcm_kt2_cosq_node_t *s1_node = NULL;
  17838     _bcm_kt2_cosq_node_t *l0_node = NULL;
  17839     _bcm_kt2_cosq_node_t *l1_node = NULL;
  17840     _bcm_kt2_cosq_node_t *l2_node = NULL;
  17841     uint32                flush_reg=0;
  17842 
  17843     if (!SOC_PORT_VALID(unit, port)) {
  17844         LOG_CLI((BSL_META_U(unit,
  17845                             "Invalid Port:%d \n"), port));
  17846         return BCM_E_PORT;
  17847     }
  17848     switch (type) {
  17849     case bcmCosqFlushTypePort :
  17850         BCM_IF_ERROR_RETURN(READ_TOQ_FLUSH0r(unit, &flush_reg));
  17851         soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg,
  17852                                 FLUSH_ACTIVEf,1);
  17853         soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, FLUSH_TYPEf,1);
  17854         soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, FLUSH_NUMf,1);
  17855         soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg,
  17856                                 FLUSH_ID0f, port);
  17857         if (IS_EXT_MEM_PORT(unit, port)) {
  17858             soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, 
  17859                               FLUSH_EXTERNALf, 1);
  17860         } else {
  17861             soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, 
  17862                               FLUSH_EXTERNALf, 0);
  17863         }
  17864         BCM_IF_ERROR_RETURN(WRITE_TOQ_FLUSH0r(unit, flush_reg));
  17865         break; 
  17866     case bcmCosqFlushTypeQueue:
  17867     default:
  17868          /* Queue Flushing one by one so ... */
  17869     mmu_info = _bcm_kt2_mmu_info[unit];
  17870     /* get the root node */
  17871     port_node = &mmu_info->sched_node[port];
  17872     if (port_node && port_node->cosq_attached_to < 0) {
  17873         LOG_CLI((BSL_META_U(unit,
  17874                             "No Scheduling node found for port:%d\n"), port));
  17875         return BCM_E_NONE;
  17876     }   
  17877     if (port_node->child == NULL) {
  17878         /*Flushing the Queue when only Root Node is present with no child*/ 
  17879         BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_flush_queues(unit, port,
  17880                                              port_node, port_node->gport));
  17881         break;
  17882      }
  17883      s0_node = port_node->child->level == _BCM_KT2_COSQ_NODE_LEVEL_S0 ? 
  17884                    port_node->child : port_node;
  17885      if (s0_node->child == NULL) {
  17886         /*Flushing the Queue when S0 Node is present with no child*/ 
  17887         BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_flush_queues(unit, port,
  17888                                              s0_node, s0_node->gport));
  17889         break;
  17890      }
  17891 
  17892          do {
  17893              s1_node = s0_node->child->level == _BCM_KT2_COSQ_NODE_LEVEL_S1 ? 
  17894                        s0_node->child : s0_node;
  17895              do {
  17896                  for (l0_node = s1_node->child; 
  17897                       l0_node != NULL; 
  17898          l0_node = l0_node->sibling) {
  17899                       for (l1_node = l0_node->child; 
  17900                            l1_node != NULL; 
  17901               l1_node = l1_node->sibling) {
  17902                            for (l2_node = l1_node->child; 
  17903                                 l2_node != NULL; 
  17904                                 l2_node = l2_node->sibling) {
  17905                                 /* Get Queue from L2 Node */
  17906                                 LOG_VERBOSE(BSL_LS_BCM_COSQ, (BSL_META_U(unit,
  17907                                                     "Flushing Port:%d => "
  17908                                                     "QueueNumber:%d \n"),
  17909                                          port, l2_node->hw_index));
  17910                                 /* Now flush the queue  */
  17911                                 BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_flush_queues(
  17912                                                     unit, port,
  17913                                                     l2_node, l2_node->gport));
  17914                                 /* SDK-116300 After queue flush operation l2 nodes are getting disabled.
  17915                                  Need to enable the l2 nodes after flush. */ 
  17916                                 BCM_IF_ERROR_RETURN(soc_kt2_cosq_queue_enable(unit, l2_node->hw_index, 1));
  17917               }
  17918                    }
  17919               } 
  17920                 if (s1_node == s0_node) {
  17921                     break;
  17922               }
  17923                 s1_node = s1_node->sibling;
  17924             } while (s1_node != NULL);
  17925             if (s0_node == port_node) {
  17926                 break;
  17927          }
  17928             s0_node = s0_node->sibling;
  17929         } while (s0_node != NULL);
  17930         break;
  17931     }
  17932     return BCM_E_NONE;
  17933 }
  17934 
  17935 int
  17936 bcm_kt2_cosq_drop_status_enable_set(int unit, bcm_port_t port, int enable)
  17937 {
  17938     uint32 rval;
  17939     uint64        r64val;
  17940 
  17941     BCM_IF_ERROR_RETURN(READ_OP_E2ECC_PORT_CONFIGr(unit, port, &rval));
  17942     soc_reg_field_set(unit, OP_E2ECC_PORT_CONFIGr, &rval, 
  17943                       COS_MASKf,  enable ? 0xFF : 0x0);
  17944     soc_reg_field_set(unit, OP_E2ECC_PORT_CONFIGr, &rval, 
  17945                       E2ECC_RPT_ENf, enable ? 1 : 0);
  17946     BCM_IF_ERROR_RETURN(WRITE_OP_E2ECC_PORT_CONFIGr(unit, port, rval));
  17947     
  17948 
  17949     BCM_IF_ERROR_RETURN(READ_OP_THR_CONFIGr(unit, &rval));
  17950     soc_reg_field_set(unit, OP_THR_CONFIGr, &rval, EARLY_E2E_SELECTf,
  17951                       enable ? 1 : 0);
  17952     BCM_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, rval));
  17953     
  17954     COMPILER_64_ZERO(r64val);
  17955     soc_reg64_field32_set(unit, MMU_INTFO_CONGST_STr,
  17956             &r64val, ENf, 1);
  17957     SOC_IF_ERROR_RETURN(WRITE_MMU_INTFO_CONGST_STr(unit,
  17958                 port, r64val));
  17959 
  17960     return BCM_E_NONE;
  17961 }
  17962 
  17963 /*
  17964  * Function:
  17965  *      bcm_kt2_cosq_field_classifier_id_create
  17966  * Purpose:
  17967  *      Create an endpoint.
  17968  * Parameters: 
  17969  *      unit          - (IN) Unit number.
  17970  *      classifier    - (IN) Classifier attributes
  17971  *      classifier_id - (OUT) Classifier ID
  17972  * Returns:
  17973  *      BCM_E_xxx
  17974  */     
  17975 int
  17976 bcm_kt2_cosq_field_classifier_id_create(
  17977     int unit,
  17978     bcm_cosq_classifier_t *classifier,
  17979     int *classifier_id)
  17980 {
  17981     int rv;
  17982     int ref_count = 0;
  17983     int ent_per_set = 16;
  17984     int i;
  17985 
  17986     if (NULL == classifier || NULL == classifier_id) {
  17987         return BCM_E_PARAM;
  17988     }
  17989 
  17990     for (i = 0; i < SOC_MEM_SIZE(unit, IFP_COS_MAPm);) {
  17991         rv = soc_profile_mem_ref_count_get
  17992                 (unit, _bcm_kt2_ifp_cos_map_profile[unit], i, &ref_count);
  17993         if (SOC_E_NONE != rv) {
  17994             return (rv);
  17995         }
  17996         if (0 == ref_count) {
  17997             break;
  17998         }
  17999         i = i + ent_per_set;
  18000     }
  18001 
  18002     if (i >= SOC_MEM_SIZE(unit, IFP_COS_MAPm) && ref_count != 0) {
  18003         *classifier_id = 0;
  18004         return (BCM_E_RESOURCE);
  18005     }
  18006 
  18007     _BCM_COSQ_CLASSIFIER_FIELD_SET(*classifier_id, (i / ent_per_set));
  18008 
  18009     return (BCM_E_NONE);
  18010 }
  18011 
  18012 /*
  18013  * Function:
  18014  *      bcm_kt2_cosq_field_classifier_get
  18015  * Purpose:
  18016  *      Get classifier type information.
  18017  * Parameters:
  18018  *      unit          - (IN) Unit number.
  18019  *      classifier_id - (IN) Classifier ID
  18020  *      classifier    - (OUT) Classifier info
  18021  * Returns:
  18022  *      BCM_E_xxx
  18023  */
  18024 int
  18025 bcm_kt2_cosq_field_classifier_get(
  18026     int unit,
  18027     int classifier_id,
  18028     bcm_cosq_classifier_t *classifier)
  18029 {
  18030     sal_memset(classifier, 0, sizeof(bcm_cosq_classifier_t));
  18031 
  18032     if (_BCM_COSQ_CLASSIFIER_IS_FIELD(classifier_id)) {
  18033         classifier->flags |= BCM_COSQ_CLASSIFIER_FIELD;
  18034     }
  18035 
  18036     return BCM_E_NONE;
  18037 }
  18038 
  18039 /*
  18040  * Function:
  18041  *      bcm_kt2_cosq_service_classifier_id_create
  18042  * Purpose:
  18043  *      Create an endpoint.
  18044  * Parameters: 
  18045  *      unit          - (IN) Unit number.
  18046  *      classifier    - (IN) Classifier attributes
  18047  *      classifier_id - (OUT) Classifier ID
  18048  * Returns:
  18049  *      BCM_E_xxx
  18050  */     
  18051 int
  18052 bcm_kt2_cosq_service_classifier_id_create(
  18053     int unit,
  18054     bcm_cosq_classifier_t *classifier,
  18055     int *classifier_id)
  18056 {
  18057     if (NULL == classifier || NULL == classifier_id) {
  18058         return BCM_E_PARAM;
  18059     }
  18060     /* XXX check classifier->vlan for valid vlan */
  18061     if (classifier->flags & BCM_COSQ_CLASSIFIER_VLAN) {
  18062         if (!BCM_VLAN_VALID(classifier->vlan)) {
  18063             return BCM_E_PARAM;
  18064         }
  18065         _BCM_COSQ_CLASSIFIER_SERVICE_SET(*classifier_id,
  18066             classifier->vlan);
  18067     }
  18068     /* XXX check classifier->vfi_index for valid vfi index */
  18069     if (classifier->flags & BCM_COSQ_CLASSIFIER_VFI) {
  18070         /* coverity[unsigned_compare] */
  18071         if ((classifier->vfi_index < 0) || 
  18072                 (classifier->vfi_index > BCM_VLAN_MAX)) {
  18073             /* KT2 supports 4096 vfi indices */
  18074             return BCM_E_PARAM;
  18075         }
  18076         _BCM_COSQ_CLASSIFIER_SERVICE_SET(*classifier_id,
  18077             (classifier->vfi_index + BCM_VLAN_MAX + 1));
  18078     }
  18079     return BCM_E_NONE;
  18080 }
  18081 
  18082 /*
  18083  * Function:
  18084  *      bcm_kt2_cosq_service_classifier_id_destroy
  18085  * Purpose:
  18086  *      free resource associated with this service classifier id.
  18087  * Parameters:
  18088  *      unit          - (IN) Unit number.
  18089  *      classifier_id - (IN) Classifier ID
  18090  * Returns:
  18091  *      BCM_E_xxx
  18092  */     
  18093 int
  18094 bcm_kt2_cosq_service_classifier_id_destroy(
  18095     int unit,
  18096     int classifier_id)
  18097 {
  18098     return BCM_E_NONE;
  18099 }
  18100 
  18101 /*
  18102  * Function:
  18103  *      bcm_kt2_cosq_field_classifier_map_set
  18104  * Purpose:
  18105  *      Set internal priority to ingress field processor CoS queue
  18106  *      override mapping.
  18107  * Parameters:
  18108  *      unit           - (IN) Unit number.
  18109  *      classifier_id  - (IN) Classifier ID
  18110  *      count          - (IN) Number of elements in priority_array and
  18111  *                            cosq_array
  18112  *      priority_array - (IN) Array of internal priorities
  18113  *      cosq_array     - (IN) Array of COS queues
  18114  * Returns:
  18115  *      BCM_E_xxx
  18116  */
  18117 int
  18118 bcm_kt2_cosq_field_classifier_map_set(int unit,
  18119                                       int classifier_id,
  18120                                       int count,
  18121                                       bcm_cos_t *priority_array,
  18122                                       bcm_cos_queue_t *cosq_array)
  18123 {
  18124     int rv;
  18125     int i;
  18126     int max_entries = 16;
  18127     uint32 index;
  18128     void *entries[1];
  18129     ifp_cos_map_entry_t *ent_buf;
  18130     int field_width;
  18131     int ref_count = 0;
  18132  
  18133     /* Input parameter check. */
  18134     if (!_BCM_COSQ_CLASSIFIER_IS_FIELD(classifier_id)) {
  18135         return (BCM_E_PARAM);
  18136     }
  18137 
  18138     if (count > max_entries) {
  18139         return (BCM_E_PARAM);
  18140     }
  18141 
  18142     ent_buf = sal_alloc(sizeof(ifp_cos_map_entry_t) * max_entries,
  18143                         "IFP_COS_MAP entry");
  18144     if (ent_buf == NULL) {
  18145         return (BCM_E_MEMORY);
  18146     }
  18147 
  18148     field_width = soc_mem_field_length(unit, IFP_COS_MAPm, IFP_COSf);
  18149     sal_memset(ent_buf, 0, sizeof(ifp_cos_map_entry_t) * max_entries);
  18150     entries[0] = ent_buf;
  18151     
  18152     for (i = 0; i < count; i++) {
  18153         if (priority_array[i] < max_entries) {
  18154             if (cosq_array[i] >= (1 << field_width)) {
  18155  	            return BCM_E_PARAM;
  18156  	        }
  18157             soc_mem_field32_set(unit, IFP_COS_MAPm, &ent_buf[priority_array[i]],
  18158                                 IFP_COSf, cosq_array[i]);
  18159         }
  18160     }
  18161     
  18162     index = _BCM_COSQ_CLASSIFIER_FIELD_GET(classifier_id);
  18163     rv = soc_profile_mem_ref_count_get
  18164          (unit, _bcm_kt2_ifp_cos_map_profile[unit],
  18165           index * max_entries, &ref_count);
  18166     if (SOC_E_NONE != rv) {
  18167         sal_free(ent_buf);
  18168         return (rv);
  18169     }
  18170     if (ref_count == 0) {
  18171         rv = soc_profile_mem_add(unit, _bcm_kt2_ifp_cos_map_profile[unit],
  18172                                  entries, max_entries, &index);
  18173     } else {
  18174         rv = soc_profile_mem_set(unit, _bcm_kt2_ifp_cos_map_profile[unit],
  18175                                  entries, index * max_entries);
  18176         /* Now decrement the ref_count which got incremented by mem_set */
  18177         BCM_IF_ERROR_RETURN
  18178         (soc_profile_mem_delete(unit,
  18179                                 _bcm_kt2_ifp_cos_map_profile[unit],
  18180                                 index * max_entries));
  18181     }
  18182     sal_free(ent_buf); 
  18183     return (rv);
  18184 }
  18185 
  18186 /*
  18187  * Function:
  18188  *      bcm_kt2_cosq_field_classifier_map_get
  18189  * Purpose:
  18190  *      Get internal priority to ingress field processor CoS queue
  18191  *      override mapping information.
  18192  * Parameters:
  18193  *      unit           - (IN) Unit number.
  18194  *      classifier_id  - (IN) Classifier ID
  18195  *      array_max      - (IN) Size of priority_array and cosq_array
  18196  *      priority_array - (IN) Array of internal priorities
  18197  *      cosq_array     - (OUT) Array of COS queues
  18198  *      array_count    - (OUT) Size of cosq_array
  18199  * Returns:
  18200  *      BCM_E_xxx
  18201  */
  18202 int
  18203 bcm_kt2_cosq_field_classifier_map_get(int unit,
  18204                                       int classifier_id,
  18205                                       int array_max,
  18206                                       bcm_cos_t *priority_array,
  18207                                       bcm_cos_queue_t *cosq_array,
  18208                                       int *array_count)
  18209 {
  18210     int rv;
  18211     int i;
  18212     int ent_per_set = 16;
  18213     uint32 index;
  18214     void *entries[1];
  18215     ifp_cos_map_entry_t *ent_buf;
  18216 
  18217     /* Input parameter check. */
  18218     if (NULL == priority_array || NULL == cosq_array || NULL == array_count) {
  18219         return (BCM_E_PARAM);
  18220     }
  18221 
  18222     /* Allocate entry buffer. */
  18223     ent_buf = sal_alloc(sizeof(ifp_cos_map_entry_t) * ent_per_set,
  18224                         "IFP_COS_MAP entry");
  18225     if (ent_buf == NULL) {
  18226         return (BCM_E_MEMORY);
  18227     }
  18228     sal_memset(ent_buf, 0, sizeof(ifp_cos_map_entry_t) * ent_per_set);
  18229     entries[0] = ent_buf;
  18230 
  18231     /* Get profile table entry set base index. */
  18232     index = _BCM_COSQ_CLASSIFIER_FIELD_GET(classifier_id);
  18233 
  18234     /* Read out entries from profile table into allocated buffer. */
  18235     rv = soc_profile_mem_get(unit, _bcm_kt2_ifp_cos_map_profile[unit],
  18236                              index * ent_per_set, ent_per_set, entries);
  18237     if (!(rv == SOC_E_NOT_FOUND || rv == SOC_E_NONE)) {
  18238         sal_free(ent_buf);
  18239         return rv;
  18240     }
  18241 
  18242     *array_count = array_max > ent_per_set ? ent_per_set : array_max;
  18243 
  18244     /* Copy values into API OUT parameters. */
  18245     for (i = 0; i < *array_count; i++) {
  18246         if (priority_array[i] >= 16) {
  18247             sal_free(ent_buf);
  18248             return BCM_E_PARAM;
  18249         }
  18250         cosq_array[i] = soc_mem_field32_get(unit, IFP_COS_MAPm,
  18251                                             &ent_buf[priority_array[i]],
  18252                                             IFP_COSf);
  18253     }
  18254 
  18255     sal_free(ent_buf);
  18256     return (BCM_E_NONE);
  18257 }
  18258 
  18259 /*
  18260  * Function:
  18261  *      bcm_kt2_cosq_field_classifier_map_clear
  18262  * Purpose:
  18263  *      Delete an internal priority to ingress field processor CoS queue
  18264  *      override mapping profile set.
  18265  * Parameters:
  18266  *      unit          - (IN) Unit number.
  18267  *      classifier_id - (IN) Classifier ID
  18268  * Returns:
  18269  *      BCM_E_xxx
  18270  */
  18271 int
  18272 bcm_kt2_cosq_field_classifier_map_clear(int unit, int classifier_id)
  18273 {
  18274     int ent_per_set = 16;
  18275     uint32 index;
  18276 
  18277     /* Get profile table entry set base index. */
  18278     index = _BCM_COSQ_CLASSIFIER_FIELD_GET(classifier_id);
  18279 
  18280     /* Delete the profile entries set. */
  18281     BCM_IF_ERROR_RETURN
  18282         (soc_profile_mem_delete(unit,
  18283                                 _bcm_kt2_ifp_cos_map_profile[unit],
  18284                                 index * ent_per_set));
  18285     return (BCM_E_NONE);
  18286 }
  18287 
  18288 /*
  18289  * Function:
  18290  *      bcm_kt2_cosq_field_classifier_id_destroy
  18291  * Purpose:
  18292  *      Free resource associated with this field classifier id.
  18293  * Parameters:
  18294  *      unit          - (IN) Unit number.
  18295  *      classifier_id - (IN) Classifier ID
  18296  * Returns:
  18297  *      BCM_E_xxx
  18298  */
  18299 int
  18300 bcm_kt2_cosq_field_classifier_id_destroy(int unit, int classifier_id)
  18301 {
  18302     return (BCM_E_NONE);
  18303 }
  18304 
  18305 /*
  18306  * Function:
  18307  *      bcm_kt2_cosq_service_map_set
  18308  * Purpose:
  18309  *      Set the mapping from port, classifier, and multiple internal priorities
  18310  *      to multiple COS queues in a queue group.
  18311  * Parameters:
  18312  *      unit           - (IN) Unit number.
  18313  *      port           - (IN) local port ID
  18314  *      classifier_id  - (IN) Classifier ID
  18315  *      queue_group    - (IN) Base queue ID
  18316  *      array_count    - (IN) Number of elements in priority_array and
  18317  *                            cosq_array
  18318  *      priority_array - (IN) Array of internal priorities
  18319  *      cosq_array     - (IN) Array of COS queues
  18320  * Returns:
  18321  *      BCM_E_xxx
  18322  * Comments:
  18323  *      <service_cos> =
  18324  *      SERVICE_COS_MAP[VLAN].SERVICE_COS +
  18325  *      ING_QUEUE_OFFSET_MAPPING_TABLE[PRI].QUEUE_OFFSET
  18326  *
  18327  *      Unicast Service Queue Number =
  18328  *      ING_COS_MODE[PORT].SERVICE_BASE_QUEUE_NUM +
  18329  *      PHYSICAL_PORT_BASE_QUEUE[PORT].BASE_QUEUE_NUMBER +
  18330  *      <service_cos>
  18331  *
  18332  *      Multicast Service Queue Number =
  18333  *         RQE_PP_PORT_CONFIG[PORT].BASE_QUEUE + <service_cos>
  18334  */
  18335 int
  18336 bcm_kt2_cosq_service_map_set(
  18337     int unit,
  18338     bcm_port_t port,
  18339     int classifier_id,
  18340     bcm_gport_t queue_group,
  18341     int count,
  18342     bcm_cos_t *priority,
  18343     bcm_cos_queue_t *cosq)
  18344 {
  18345     int rv = BCM_E_NONE;
  18346     int i;
  18347     service_cos_map_entry_t scm;
  18348     ing_queue_offset_mapping_table_entry_t map_entries[16];
  18349     void *entries[1];
  18350     uint32 old_index = 0;
  18351     uint32 new_index = 0;
  18352     int vid;
  18353     int valid_entry;
  18354     _bcm_kt2_cosq_node_t *node;
  18355     uint32 rval = 0, rval1 = 0;
  18356     uint32 uc_base = 0, required_base = 0;
  18357     uint32 service_cos = 0;
  18358     bcm_port_t local_port;
  18359     _bcm_kt2_mmu_info_t *mmu_info;
  18360     _bcm_kt2_cosq_port_info_t *port_info;
  18361 
  18362     if (!_BCM_COSQ_CLASSIFIER_IS_SERVICE(classifier_id)) {
  18363         return BCM_E_PARAM;
  18364     }
  18365 
  18366     /* index above 4K is for VFI */
  18367     vid = _BCM_COSQ_CLASSIFIER_SERVICE_GET(classifier_id);
  18368     
  18369     /* validate the vlan id */
  18370     if (vid < 0 || vid >= SOC_MEM_SIZE(unit, SERVICE_COS_MAPm)) {
  18371         return BCM_E_PARAM;
  18372     }
  18373 
  18374     BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_node_get(unit, queue_group, NULL, 
  18375                                                &local_port, NULL, &node));
  18376 
  18377     if (node->cosq_attached_to < 0) {
  18378         return BCM_E_PARAM;
  18379     }    
  18380 
  18381     /* validate the user parameters */
  18382     if (count > 16) {
  18383         return BCM_E_PARAM;
  18384     }
  18385 
  18386     /* queues allocated for this queue_group should be contiguous.*/
  18387     /* check if user's queue number is valid */
  18388     for (i = 0; i < count; i++) {
  18389         if (cosq[i] >= 8 || priority[i] >= 16) {
  18390             return BCM_E_PARAM;
  18391         }
  18392     }
  18393 
  18394     sal_memset(map_entries, 0, sizeof(map_entries));
  18395 
  18396     BCM_IF_ERROR_RETURN(
  18397         soc_mem_read(unit, SERVICE_COS_MAPm, MEM_BLOCK_ANY, (int)vid, &scm));
  18398     valid_entry = soc_mem_field32_get(unit, SERVICE_COS_MAPm, &scm, VALIDf);
  18399 
  18400     SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval1));
  18401     SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval));
  18402 
  18403     if ((soc_reg_field_get(unit, RQE_PP_PORT_CONFIGr, rval1, COS_MODEf) != 3) &&
  18404         (soc_reg_field_get(unit, ING_COS_MODEr, rval, COS_MODEf) == 3)) {
  18405          uc_base = soc_reg_field_get(unit, ING_COS_MODEr, rval,
  18406                                      SERVICE_BASE_QUEUE_NUMf);
  18407          mmu_info = _bcm_kt2_mmu_info[unit];
  18408          port_info = &mmu_info->port[local_port];
  18409          required_base = port_info->uc_vlan_base < mmu_info->num_queues -1 ?
  18410                          port_info->uc_vlan_base :
  18411                          ((uc_base == 0) ? node->hw_index : uc_base);
  18412          if (uc_base != required_base) {
  18413              uc_base = required_base;
  18414              soc_reg_field_set(unit, ING_COS_MODEr, &rval,
  18415                           SERVICE_BASE_QUEUE_NUMf, uc_base);
  18416              SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, rval));
  18417          }
  18418     } else {
  18419         uc_base = soc_reg_field_get(unit, ING_COS_MODEr, rval, BASE_QUEUE_NUMf);
  18420         if (uc_base != soc_reg_field_get(unit, ING_COS_MODEr, rval,
  18421                                          SERVICE_BASE_QUEUE_NUMf)) {
  18422             /* First time service queuing being configured on this port */
  18423             soc_reg_field_set(unit, ING_COS_MODEr, &rval,
  18424                               SERVICE_BASE_QUEUE_NUMf, uc_base);
  18425             SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, rval));
  18426         }
  18427     }
  18428 
  18429     service_cos = node->hw_index - uc_base;
  18430 
  18431     entries[0] = &map_entries;
  18432     if (valid_entry) {
  18433         uint32 current_service_cos;
  18434         /* 
  18435          * We reached here, so at least one mapping must have been configured.
  18436          * For next configuration base queue must be same.
  18437          */
  18438         current_service_cos = soc_mem_field32_get(unit, SERVICE_COS_MAPm, &scm, SERVICE_COSf);
  18439         if (current_service_cos != service_cos) {
  18440             LOG_ERROR(BSL_LS_BCM_COMMON,
  18441                       (BSL_META_U(unit,
  18442                                   "Error: Cannot satisfy service queue offset "
  18443 				  "requirement for new map on port %d/VID %d, "
  18444 				  "current offset: %d; required offset: %d\n"),
  18445                                   port, vid, current_service_cos, service_cos));
  18446             return BCM_E_PARAM;
  18447         }
  18448         old_index = soc_mem_field32_get(unit, SERVICE_COS_MAPm, &scm,
  18449                                     QUEUE_OFFSET_PROFILE_INDEXf);
  18450         old_index *= 16;
  18451 
  18452         BCM_IF_ERROR_RETURN
  18453             (_bcm_offset_map_table_entry_get(unit, old_index, 16, entries));
  18454         rv = _bcm_offset_map_table_entry_delete(unit, old_index);
  18455         if (!(rv == SOC_E_NOT_FOUND || rv == SOC_E_NONE)) {
  18456             return rv;
  18457         }
  18458     } else {
  18459         soc_mem_field32_set(unit, SERVICE_COS_MAPm, &scm, VALIDf, 1);
  18460     }
  18461 
  18462     for (i = 0; i < count; i++) {
  18463         soc_mem_field32_set(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm, 
  18464                 &map_entries[priority[i]], QUEUE_OFFSETf, cosq[i]);
  18465     }
  18466 
  18467     BCM_IF_ERROR_RETURN
  18468         (_bcm_offset_map_table_entry_add(unit, entries, 16, &new_index));
  18469     
  18470     soc_mem_field32_set(unit, SERVICE_COS_MAPm, &scm, QUEUE_OFFSET_PROFILE_INDEXf,
  18471                         new_index / 16);
  18472     soc_mem_field32_set(unit, SERVICE_COS_MAPm, &scm, SERVICE_COSf,
  18473                         service_cos);
  18474     BCM_IF_ERROR_RETURN(
  18475         soc_mem_write(unit, SERVICE_COS_MAPm, MEM_BLOCK_ANY, (int)vid, &scm));
  18476 
  18477     return BCM_E_NONE;
  18478 }
  18479 
  18480 /*
  18481  * Function:
  18482  *      bcm_kt2_cosq_service_classifier_get
  18483  * Purpose:
  18484  *      Get info about an endpoint.
  18485  * Parameters:
  18486  *      unit          - (IN) Unit number.
  18487  *      classifier_id - (IN) Classifier ID
  18488  *      classifier    - (OUT) Classifier info
  18489  * Returns:
  18490  *      BCM_E_xxx
  18491  */
  18492 int
  18493 bcm_kt2_cosq_service_classifier_get(
  18494     int unit,
  18495     int classifier_id,
  18496     bcm_cosq_classifier_t *classifier)
  18497 {
  18498     int val = 0;
  18499 
  18500     sal_memset(classifier, 0, sizeof(bcm_cosq_classifier_t));
  18501 
  18502     val = _BCM_COSQ_CLASSIFIER_SERVICE_GET(classifier_id);
  18503 
  18504     if (val > BCM_VLAN_MAX) {
  18505         /* VFI classifier */
  18506         classifier->flags = BCM_COSQ_CLASSIFIER_VFI;
  18507         classifier->vfi_index = val - BCM_VLAN_MAX - 1;
  18508     } else {
  18509         classifier->flags = BCM_COSQ_CLASSIFIER_VLAN;
  18510         classifier->vlan = val;
  18511     }
  18512     return BCM_E_NONE;
  18513 }
  18514 
  18515 /*
  18516  * Function:
  18517  *      bcm_kt2_cosq_service_map_get
  18518  * Purpose:
  18519  *      Get the mapping from port, classifier, and multiple internal priorities
  18520  *      to multiple COS queues in a queue group.
  18521  * Parameters:
  18522  *      unit           - (IN) Unit number.
  18523  *      port           - (IN) Local port ID
  18524  *      classifier_id  - (IN) Classifier ID
  18525  *      queue_group    - (OUT) Queue group
  18526  *      array_max      - (IN) Size of priority_array and cosq_array
  18527  *      priority_array - (IN) Array of internal priorities
  18528  *      cosq_array     - (OUT) Array of COS queues
  18529  *      array_count    - (OUT) Size of cosq_array
  18530  * Returns:
  18531  *      BCM_E_xxx
  18532  */
  18533 int
  18534 bcm_kt2_cosq_service_map_get(
  18535     int unit,
  18536     bcm_port_t port,
  18537     int classifier_id,
  18538     bcm_gport_t *queue_group,
  18539     int array_max,
  18540     bcm_cos_t *priority,
  18541     bcm_cos_queue_t *cosq,
  18542     int *array_count)
  18543 {
  18544     service_cos_map_entry_t scm;
  18545     ing_queue_offset_mapping_table_entry_t map_entries[16];
  18546     void *entries[1];
  18547     int index;
  18548     int vid;
  18549     int valid_entry;
  18550     int i;
  18551     int cos_offset;
  18552     uint32 uc_base = 0;
  18553     uint32 rval = 0;
  18554 
  18555     vid = _BCM_COSQ_CLASSIFIER_SERVICE_GET(classifier_id);
  18556 
  18557     BCM_IF_ERROR_RETURN(
  18558         soc_mem_read(unit, SERVICE_COS_MAPm, MEM_BLOCK_ANY, (int)vid, &scm));
  18559 
  18560     valid_entry = soc_mem_field32_get(unit, SERVICE_COS_MAPm, &scm, VALIDf);
  18561     if (!valid_entry) {
  18562         return BCM_E_CONFIG;  /* service queue is not configured */
  18563     }
  18564 
  18565     index = soc_mem_field32_get(unit, SERVICE_COS_MAPm, &scm,
  18566                                 QUEUE_OFFSET_PROFILE_INDEXf);
  18567     index *= 16;
  18568     entries[0] = &map_entries;
  18569     BCM_IF_ERROR_RETURN
  18570         (_bcm_offset_map_table_entry_get(unit, index, 16, entries));
  18571     
  18572     cos_offset = soc_mem_field32_get(unit, SERVICE_COS_MAPm,
  18573                                      &scm, SERVICE_COSf);
  18574 
  18575     BCM_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval));
  18576     uc_base = soc_reg_field_get(unit, ING_COS_MODEr, rval, SERVICE_BASE_QUEUE_NUMf);
  18577 
  18578     bcm_kt2_cosq_subscriber_qid_set(unit, queue_group, cos_offset+uc_base);
  18579     *queue_group |= (port << 16);
  18580     *array_count = array_max > 16 ? 16 :
  18581                    array_max;
  18582                    
  18583     for (i = 0; i < *array_count; i++) {
  18584         if (priority[i] >= 16) {
  18585             return BCM_E_PARAM;
  18586         }
  18587         cosq[i] = soc_mem_field32_get(unit,ING_QUEUE_OFFSET_MAPPING_TABLEm,
  18588                                &map_entries[priority[i]], QUEUE_OFFSETf);
  18589     }
  18590  
  18591     return BCM_E_NONE;      
  18592 }
  18593 
  18594 /*
  18595  * Function:
  18596  *      bcm_kt2_cosq_service_map_clear
  18597  * Purpose:
  18598  *      Clear the mapping from port, classifier, and internal priorities
  18599  *      to COS queues in a queue group.
  18600  * Parameters:
  18601  *      unit          - (IN) Unit number.
  18602  *      port          - (IN) Local port ID
  18603  *      classifier_id - (IN) Classifier ID
  18604  * Returns:
  18605  *      BCM_E_xxx
  18606  */
  18607 int
  18608 bcm_kt2_cosq_service_map_clear(
  18609     int unit,
  18610     bcm_gport_t port,
  18611     int classifier_id)
  18612 {
  18613     int rv = BCM_E_NONE;
  18614     service_cos_map_entry_t scm;
  18615     int index;
  18616     int vid;
  18617     int valid_entry;
  18618 
  18619     vid = _BCM_COSQ_CLASSIFIER_SERVICE_GET(classifier_id);
  18620 
  18621     BCM_IF_ERROR_RETURN(soc_mem_read(unit, SERVICE_COS_MAPm, MEM_BLOCK_ANY,
  18622                         (int)vid, &scm));
  18623 
  18624     valid_entry = soc_mem_field32_get(unit, SERVICE_COS_MAPm, &scm, VALIDf);
  18625     if (!valid_entry) {
  18626         return BCM_E_NONE;  /* service queue is already cleared  */
  18627     }
  18628 
  18629     index = soc_mem_field32_get(unit, SERVICE_COS_MAPm, &scm,
  18630                                QUEUE_OFFSET_PROFILE_INDEXf);
  18631     index *= 16;
  18632 
  18633     /* delete the profile */
  18634     rv = _bcm_offset_map_table_entry_delete(unit, index);
  18635     if (!(rv == SOC_E_NOT_FOUND || rv == SOC_E_NONE)) {
  18636         return rv;
  18637     }
  18638 
  18639     sal_memset(&scm,0, sizeof(service_cos_map_entry_t));
  18640 
  18641     /* Write back updated buffer. */
  18642     BCM_IF_ERROR_RETURN(soc_mem_write(unit, SERVICE_COS_MAPm, MEM_BLOCK_ALL,
  18643                        (int)vid, &scm));
  18644     return BCM_E_NONE;
  18645 }
  18646 /*
  18647  * Function:
  18648  *      _bcm_kt2_cosq_gport_dmvoq_config_set 
  18649  * Purpose:
  18650  *      Setting SOURCE_MODMAP , FC table and BASEINDEX table
  18651  *      appropriately as per the architecture
  18652  * Parameters:
  18653  *      unit           - (IN) Unit number.
  18654  *      gport          - (IN) gport identifier 
  18655  *      cos            - (IN) cos value 
  18656  *      fabric_modid   - (IN) Fabric Mod ID
  18657  *      dest_modid     - (IN) Destination Mod ID
  18658  *      fabric_port    - (IN) Fabric port ID
  18659  * Returns:
  18660  *      BCM_E_xxx
  18661  */
  18662 STATIC int
  18663 _bcm_kt2_cosq_gport_dmvoq_config_set(int unit, bcm_gport_t gport, 
  18664                                 bcm_cos_queue_t cosq,
  18665                                 bcm_module_t dest_modid, 
  18666                                 bcm_module_t fabric_modid,
  18667                                 bcm_port_t fabric_port)
  18668 {
  18669     int  intf_index, rv;
  18670     _bcm_kt2_cosq_node_t *node;
  18671     _bcm_kt2_cosq_node_t *base_node = NULL;
  18672     bcm_port_t local_port;
  18673     mmu_intfi_base_index_tbl_entry_t base_tbl_entry;
  18674     uint32  index;
  18675     uint32  val;
  18676     int stack_port;
  18677     uint32  modport_map_index;
  18678     modport_map_sw_entry_t sw_entry;
  18679     ing_queue_map_entry_t ing_queue_entry;
  18680     ing_queue_offset_mapping_table_entry_t map_entries[16];
  18681     void *entries[1];
  18682     int map_offset = 0, fabric_port_count, port;
  18683     int count = 0, cng_offset;
  18684     mmu_intfi_offset_map_tbl_entry_t offset_map_tbl_entry; 
  18685     _bcm_kt2_mmu_info_t *mmu_info;
  18686     _bcm_kt2_cosq_node_t *node_base;
  18687     int enable, base_queue = 0;
  18688     int istrunk;
  18689     entries[0] = &map_entries;
  18690     mmu_info = _bcm_kt2_mmu_info[unit];
  18691 
  18692     if (fabric_modid >= 64) {
  18693         return BCM_E_PARAM;
  18694     }
  18695 
  18696     if (dest_modid >= 256) {
  18697         return BCM_E_PARAM;
  18698     }
  18699 
  18700     BCM_IF_ERROR_RETURN
  18701         (_bcm_kt2_cosq_node_get(unit, gport, NULL ,&local_port, NULL, &node));
  18702 
  18703     if (!node) {
  18704         return BCM_E_NOT_FOUND;
  18705     }
  18706     if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2) {
  18707         return BCM_E_PARAM;
  18708     }
  18709 
  18710     BCM_IF_ERROR_RETURN(_bcm_kt2_voq_base_node_get(
  18711                 unit, dest_modid, fabric_modid, &base_node));
  18712     if (base_node == NULL) {
  18713         base_node = node ;
  18714     }
  18715     intf_index = _bcm_kt2_cosq_source_intf_set(unit, fabric_modid, 
  18716             0, _BCM_KT2_COSQ_DMVOQ);
  18717 
  18718     if (intf_index < 0) {
  18719         return BCM_E_RESOURCE;
  18720     }
  18721     if (SOC_IS_METROLITE(unit)) {
  18722         intf_index = 0;
  18723     } else if (SOC_IS_SABER2(unit)) {
  18724         if (intf_index > 1) {
  18725             intf_index = 0;
  18726         }
  18727     } else {
  18728         if (intf_index > 3) {
  18729             intf_index = 0;
  18730         }
  18731     }
  18732 
  18733     BCM_PBMP_COUNT(base_node->fabric_pbmp, fabric_port_count);
  18734 
  18735     if (fabric_port_count == 0) {
  18736         map_offset = mmu_info->curr_merger_index[intf_index];
  18737         if (map_offset >= soc_mem_index_count(unit, MMU_INTFI_MERGE_ST_TBLm)) {
  18738             return BCM_E_RESOURCE;
  18739         }
  18740     } else {
  18741         BCM_PBMP_ITER(base_node->fabric_pbmp, port) {
  18742             BCM_IF_ERROR_RETURN(soc_mem_read(unit, MMU_INTFI_OFFSET_MAP_TBLm, 
  18743                         MEM_BLOCK_ALL, 
  18744                         port + (intf_index * 64), &offset_map_tbl_entry));
  18745             map_offset = soc_mem_field32_get(unit, MMU_INTFI_OFFSET_MAP_TBLm,
  18746                     &offset_map_tbl_entry,
  18747                     MAP_OFFSETf);
  18748             break;
  18749         }
  18750     }
  18751 
  18752     /* clean up fabric pbmp code if fabric mod_id and dest mod id are different
  18753        if the mod id are different then we need to update the pbmp else it will 
  18754        be appended as in case of trunk.
  18755      */
  18756     if ((base_node->remote_modid != dest_modid) || 
  18757             (base_node->fabric_modid != fabric_modid)) {
  18758         if (node->hw_index % 8 == 0) { 
  18759             BCM_PBMP_CLEAR(base_node->fabric_pbmp);
  18760 
  18761         }
  18762     } 
  18763     if (!BCM_PBMP_MEMBER(base_node->fabric_pbmp, fabric_port)) {
  18764         if (map_offset == mmu_info->curr_merger_index[intf_index]) {
  18765             mmu_info->curr_merger_index[intf_index]++;
  18766         }
  18767 
  18768         BCM_PBMP_PORT_ADD (base_node->fabric_pbmp, fabric_port);
  18769         BCM_PBMP_COUNT(base_node->fabric_pbmp, fabric_port_count);
  18770         BCM_PBMP_ITER(base_node->fabric_pbmp, port) {
  18771             count++;
  18772             BCM_IF_ERROR_RETURN(soc_mem_read(unit, MMU_INTFI_OFFSET_MAP_TBLm, 
  18773                         MEM_BLOCK_ALL, 
  18774                         port + (intf_index * 64), &offset_map_tbl_entry));
  18775             soc_mem_field32_set(unit, MMU_INTFI_OFFSET_MAP_TBLm, 
  18776                     &offset_map_tbl_entry,
  18777                     MAP_OFFSETf, map_offset);
  18778             soc_mem_field32_set(unit, MMU_INTFI_OFFSET_MAP_TBLm, 
  18779                     &offset_map_tbl_entry,
  18780                     LASTf, count < fabric_port_count ? 0 : 1 );
  18781             BCM_IF_ERROR_RETURN(soc_mem_write(unit, MMU_INTFI_OFFSET_MAP_TBLm, 
  18782                         MEM_BLOCK_ALL, 
  18783                         port + (intf_index * 64), &offset_map_tbl_entry));
  18784         }
  18785     }
  18786 
  18787 
  18788 
  18789     if (node->hw_index % 8 == 0) {
  18790 
  18791         node->remote_modid = dest_modid;
  18792         node->fabric_modid = fabric_modid;
  18793         node_base = mmu_info->queue_node;
  18794         count = 0;
  18795         SOC_IF_ERROR_RETURN
  18796             (READ_MODPORT_MAP_SELr(unit, local_port, &val));
  18797         index = soc_reg_field_get(unit, MODPORT_MAP_SELr, val,
  18798                 MODPORT_MAP_INDEX_UPPERf);
  18799         if (SOC_IS_METROLITE(unit)) {
  18800             modport_map_index  = (index * 64) + dest_modid;
  18801         } else {
  18802             modport_map_index  = (index * 256) + dest_modid;
  18803         }
  18804 
  18805         soc_mem_lock(unit, MODPORT_MAP_SWm);
  18806         rv = soc_mem_read(unit, MODPORT_MAP_SWm, MEM_BLOCK_ANY, modport_map_index,
  18807                 &sw_entry);
  18808         istrunk = soc_mem_field32_get(unit, MODPORT_MAP_SWm, &sw_entry, 
  18809                 ISTRUNK0f); 
  18810         soc_mem_unlock(unit, MODPORT_MAP_SWm);
  18811         for(index = mmu_info->base_dmvoq_queue ; 
  18812                 index < mmu_info->num_queues; index++) {
  18813             if ((node_base[index].remote_modid == dest_modid) &&
  18814                     ((node_base[index].fabric_modid == fabric_modid) || (istrunk))) {
  18815                 count++;
  18816                 BCM_IF_ERROR_RETURN
  18817                     (_bcm_kt2_cosq_node_get(unit, node_base[index].gport, 
  18818                                             NULL ,&port, NULL, NULL));
  18819                 SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &val));
  18820 
  18821                 base_queue = soc_reg_field_get(unit, ING_COS_MODEr, val, BASE_QUEUE_NUMf);
  18822 
  18823             }
  18824         }
  18825         if(count == 1) {
  18826             SOC_IF_ERROR_RETURN
  18827                 (READ_MODPORT_MAP_SELr(unit, local_port, &val));
  18828 
  18829             index = soc_reg_field_get(unit, MODPORT_MAP_SELr, val,
  18830                     MODPORT_MAP_INDEX_UPPERf);
  18831 
  18832             if (SOC_IS_METROLITE(unit)) {
  18833                 modport_map_index  = (index * 64) + dest_modid;
  18834             } else {
  18835                 modport_map_index  = (index * 256) + dest_modid;
  18836             } 
  18837 
  18838             soc_mem_lock(unit, MODPORT_MAP_SWm);
  18839             rv = soc_mem_read(unit, MODPORT_MAP_SWm, MEM_BLOCK_ANY, modport_map_index,
  18840                     &sw_entry);
  18841             if (SOC_SUCCESS(rv)) {
  18842                 enable = soc_mem_field32_get(unit, MODPORT_MAP_SWm, &sw_entry, 
  18843                         ENABLE0f); 
  18844                 if (!enable) { 
  18845 #ifdef BCM_METROLITE_SUPPORT
  18846                     if(SOC_IS_METROLITE(unit))  {
  18847                        stack_port = ((local_port << 5) | local_port);
  18848                     } else
  18849 #endif
  18850                     {
  18851                       stack_port = ((local_port << (SOC_IS_SABER2(unit)? 7: 8)) | local_port);
  18852                     } 
  18853                     soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, DEST0f,
  18854                             stack_port);
  18855                     soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, ISTRUNK0f,0);
  18856                     soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, ADD_DESTINATION_PORTf,
  18857                             0);
  18858                     soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, ENABLE0f, 1);
  18859                 }
  18860                 soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, PER_MODID_QUEUEING_ENABLEf,
  18861                         1);
  18862                 soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, QUEUE_MAP_POINTERf,
  18863                         node->hw_index);
  18864                 rv = soc_mem_write(unit, MODPORT_MAP_SWm, MEM_BLOCK_ALL, modport_map_index,
  18865                         &sw_entry);
  18866             }
  18867             soc_mem_unlock(unit, MODPORT_MAP_SWm);
  18868 
  18869             sal_memset(map_entries, 0, sizeof(map_entries));
  18870             /* Hardcoding the ING_QUEUE_OFFSET_MAPPING_TABLE */
  18871             for (index = 0; index < 16; index++) {
  18872                 soc_mem_field32_set(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm,
  18873                         &map_entries[index], QUEUE_OFFSETf, index > 7 ? 7 : index);
  18874             }
  18875             BCM_IF_ERROR_RETURN
  18876                 (_bcm_offset_map_table_entry_add(unit, entries, 16, &index));
  18877 
  18878             sal_memset(&ing_queue_entry, 0, sizeof(ing_queue_map_entry_t));
  18879             soc_mem_field32_set(unit, ING_QUEUE_MAPm,
  18880                     &ing_queue_entry, QUEUE_SET_BASEf, 
  18881                     node->hw_index - base_queue);
  18882             soc_mem_field32_set(unit, ING_QUEUE_MAPm, &ing_queue_entry,
  18883                     QUEUE_OFFSET_PROFILE_INDEXf, index/16);
  18884             soc_mem_field32_set(unit, ING_QUEUE_MAPm, &ing_queue_entry,
  18885                     ADD_EGRESS_PORT_BASE_QUEUEf, 1);
  18886             BCM_IF_ERROR_RETURN(BCM_XGS3_MEM_WRITE(unit, ING_QUEUE_MAPm,
  18887                         node->hw_index, &ing_queue_entry));
  18888         }
  18889 
  18890         /*
  18891          *  SRC_INTF and MMU_INTFI_BASE_INDEX_TBL is mapped one to one,
  18892          *  so writing the base index at same index where SRC_INTF is written
  18893          */
  18894 
  18895         cng_offset = intf_index * 64 ;
  18896 
  18897         BCM_IF_ERROR_RETURN
  18898             (soc_mem_read(unit, MMU_INTFI_BASE_INDEX_TBLm, 
  18899                           MEM_BLOCK_ALL, intf_index, &base_tbl_entry));
  18900         soc_mem_field32_set(unit, MMU_INTFI_BASE_INDEX_TBLm, &base_tbl_entry, 
  18901                 BASE_ADDRf, cng_offset);
  18902         soc_mem_field32_set(unit, MMU_INTFI_BASE_INDEX_TBLm, &base_tbl_entry, 
  18903                 ENf, (node->level - 3 ));
  18904 
  18905         BCM_IF_ERROR_RETURN(soc_mem_write(unit, MMU_INTFI_BASE_INDEX_TBLm,
  18906                     MEM_BLOCK_ALL, intf_index, &base_tbl_entry));
  18907 
  18908         /* set the mapping from congestion bits in flow control table
  18909          * to corresponding hw_index */
  18910         BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_map_fc_status_to_node(unit, 
  18911                     _BCM_KT2_COSQ_FC_VOQFC,  
  18912                     node->hw_index, (node->level - 2), cng_offset + map_offset));
  18913 
  18914 
  18915     }
  18916     return BCM_E_NONE;
  18917 }
  18918 
  18919 /*
  18920  * Function:
  18921  *      _bcm_kt2_cosq_gport_e2ecc_coe_config_set
  18922  * Purpose:
  18923  *      Setting SOURCE_MODMAP, FC table and BASEINDEX table
  18924  *      appropriately as per the architecture
  18925  * Parameters:
  18926  *      unit           - (IN) Unit number.
  18927  *      gport          - (IN) gport identifier
  18928  *      cos            - (IN) cos value
  18929  * Returns:
  18930  *      BCM_E_xxx
  18931  */
  18932 STATIC int
  18933 _bcm_kt2_cosq_gport_e2ecc_coe_config_set(int unit, bcm_gport_t gport)
  18934 {
  18935     soc_info_t *si;
  18936     int  intf_index;
  18937     _bcm_kt2_cosq_node_t *node;
  18938     bcm_port_t local_port;
  18939     bcm_port_t subport;
  18940     int subport_start = 0;
  18941     int subport_end = 0;
  18942     mmu_intfi_base_index_tbl_entry_t base_tbl_entry;
  18943     int cng_offset;
  18944     int subport_offset = 0;
  18945     uint32 regval;
  18946     int num_subports = 0;
  18947 #if defined BCM_METROLITE_SUPPORT 
  18948     int pp_port = 0;
  18949 #endif 
  18950  
  18951     si = &SOC_INFO(unit);
  18952 
  18953     BCM_IF_ERROR_RETURN
  18954         (_bcm_kt2_cosq_node_get(unit, gport, NULL ,
  18955                                &subport, NULL, &node));
  18956 
  18957     if (!node) {
  18958         return BCM_E_NOT_FOUND;
  18959     }
  18960     if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2) {
  18961         return BCM_E_PARAM;
  18962     }
  18963 
  18964     local_port = node->local_port;
  18965 
  18966     /* Subport base for the COE port */
  18967     subport_start = si->port_subport_base[local_port];
  18968     subport_end = si->port_subport_base[local_port] +
  18969                    si->port_num_subport[local_port];
  18970 
  18971     /* number of subports on the COE port
  18972      * indicating maximum number of FC bytes
  18973      * that can be received on a COE
  18974      * port
  18975      */
  18976     num_subports = si->port_num_subport[local_port];
  18977 
  18978     if (num_subports == 0) {
  18979         return BCM_E_INIT;
  18980     }
  18981 
  18982     /* Maximum of 64 FC bytes are supported in E2ECC
  18983      * message. Hence limiting the number of subports
  18984      * to 64 when more number of subports configured
  18985      * on a COE port.
  18986      */
  18987     num_subports = ((num_subports > 64) ? 64 : num_subports);
  18988 #if defined BCM_METROLITE_SUPPORT
  18989     if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  18990         if (!_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, subport)) {
  18991              return BCM_E_INIT;
  18992         }
  18993         SOC_PBMP_ITER(SOC_PORT_PP_BITMAP(unit, local_port), pp_port) { 
  18994         if (subport != pp_port) { 
  18995             subport_offset++; 
  18996             continue;
  18997         } else { 
  18998             break;
  18999            }  
  19000         }   
  19001     } else 
  19002 #endif
  19003     {
  19004         subport_offset = subport - subport_start;
  19005         if ((subport < subport_start) ||
  19006              (subport > subport_end)) {
  19007               return BCM_E_INIT;
  19008          }
  19009     }
  19010     if (node->hw_index % 8 == 0) {
  19011 
  19012         intf_index = _bcm_kt2_cosq_source_intf_set(unit, 0,
  19013                 local_port, _BCM_KT2_COSQ_E2ECC_COE);
  19014         if (intf_index < 0) {
  19015             return BCM_E_RESOURCE;
  19016         }
  19017 
  19018         /*
  19019          *  SRC_INTF and MMU_INTFI_BASE_INDEX_TBL is mapped one to one,
  19020          *  so writing the base index at same index where SRC_INTF is written
  19021          */
  19022 
  19023         cng_offset = (intf_index * num_subports) ;
  19024         /* set the congestion state bytes max to number of subports on a port
  19025          *  as max num subports  FC bytes  can be received for  for src_intf
  19026          */
  19027         soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, &regval,
  19028                     DATAf, num_subports);
  19029         SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit,
  19030                         intf_index, regval));
  19031 
  19032         BCM_IF_ERROR_RETURN
  19033             (soc_mem_read(unit, MMU_INTFI_BASE_INDEX_TBLm,
  19034                           MEM_BLOCK_ALL, intf_index, &base_tbl_entry));
  19035         soc_mem_field32_set(unit, MMU_INTFI_BASE_INDEX_TBLm, &base_tbl_entry,
  19036                 BASE_ADDRf, cng_offset);
  19037         /* set Enf - 2 for level 2 */
  19038         soc_mem_field32_set(unit, MMU_INTFI_BASE_INDEX_TBLm, &base_tbl_entry,
  19039                 ENf, (node->level - 3 ));
  19040 
  19041         BCM_IF_ERROR_RETURN(soc_mem_write(unit, MMU_INTFI_BASE_INDEX_TBLm,
  19042                     MEM_BLOCK_ALL, intf_index, &base_tbl_entry));
  19043 
  19044         /* set the mapping from congestion bits in flow control table
  19045          * to corresponding hw_index */
  19046         BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_map_fc_status_to_node(unit,
  19047                     _BCM_KT2_COSQ_FC_E2ECC_COE,
  19048                     node->hw_index, (node->level - 2),
  19049                     (cng_offset + (subport_offset))));
  19050 
  19051 
  19052     }
  19053     return BCM_E_NONE;
  19054 }
  19055 
  19056 STATIC int
  19057 _bcm_kt2_cosq_gport_dpvoq_config_set(int unit, bcm_gport_t gport, 
  19058                                 bcm_cos_queue_t cosq,
  19059                                 bcm_module_t dest_modid, 
  19060                                 bcm_port_t dest_port)
  19061 {
  19062     int  intf_index, rv;
  19063     _bcm_kt2_cosq_node_t *node;
  19064     bcm_port_t local_port;
  19065     mmu_intfi_base_index_tbl_entry_t base_tbl_entry;
  19066     uint32  index;
  19067     uint32  val;
  19068     int stack_port;
  19069     uint32  modport_map_index;
  19070     modport_map_sw_entry_t sw_entry;
  19071     ing_queue_map_entry_t ing_queue_entry;
  19072     ing_queue_offset_mapping_table_entry_t map_entries[16];
  19073     physical_port_base_queue_entry_t phy_port_entry;
  19074     void *entries[1];
  19075     int count = 0, cng_offset;
  19076     _bcm_kt2_mmu_info_t *mmu_info;
  19077     _bcm_kt2_cosq_node_t *node_base;
  19078     int enable, base_queue;
  19079     int phy_base_index = 0, offset = 0 , hw_index = 0;
  19080     int port;
  19081     entries[0] = &map_entries;
  19082     mmu_info = _bcm_kt2_mmu_info[unit];
  19083 
  19084     if (dest_modid >= 64) {
  19085         return BCM_E_PARAM;
  19086     }
  19087 
  19088     BCM_IF_ERROR_RETURN
  19089         (_bcm_kt2_cosq_node_get(unit, gport, NULL ,&local_port, NULL, &node));
  19090 
  19091     if (!node) {
  19092         return BCM_E_NOT_FOUND;
  19093     }
  19094     if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2) {
  19095         return BCM_E_PARAM;
  19096     }
  19097 
  19098     if (node->hw_index % 8 == 0) {
  19099 
  19100         node->remote_modid = dest_modid;
  19101         node_base = mmu_info->queue_node;
  19102         count = 0;
  19103         for(index = mmu_info->base_dmvoq_queue ; 
  19104                 index < mmu_info->num_queues ; index++) {
  19105             if (node_base[index].remote_modid == dest_modid) {
  19106                 count++;
  19107                 BCM_IF_ERROR_RETURN
  19108                     (_bcm_kt2_cosq_node_get(unit, node_base[index].gport, 
  19109                                             NULL ,&port, NULL, NULL));
  19110                 SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &val));
  19111                 base_queue = soc_reg_field_get(unit, ING_COS_MODEr, val, BASE_QUEUE_NUMf);
  19112 
  19113                 SOC_IF_ERROR_RETURN (soc_mem_read(unit, PHYSICAL_PORT_BASE_QUEUEm,
  19114                             MEM_BLOCK_ANY, port,
  19115                             &phy_port_entry));
  19116                 phy_base_index = soc_mem_field32_get(unit, PHYSICAL_PORT_BASE_QUEUEm,
  19117                         &phy_port_entry, BASE_QUEUE_NUMBERf);
  19118                 if (!soc_mem_field32_get(unit, PHYSICAL_PORT_BASE_QUEUEm,
  19119                             &phy_port_entry, BASE_QUEUE_NUMBERf)) { 
  19120                     soc_mem_field32_set(unit, PHYSICAL_PORT_BASE_QUEUEm,
  19121                             &phy_port_entry, BASE_QUEUE_NUMBERf, 
  19122                             (node_base[index].hw_index - base_queue) );
  19123                     SOC_IF_ERROR_RETURN (soc_mem_write(unit, PHYSICAL_PORT_BASE_QUEUEm,
  19124                                 MEM_BLOCK_ALL, port,
  19125                                 &phy_port_entry));
  19126                     offset = 0;
  19127                 } else {
  19128                     if ( phy_base_index == node_base[index].hw_index - base_queue) {
  19129                         if ( port == local_port ) {
  19130                             offset = node->hw_index - node_base[index].hw_index;
  19131                         }
  19132                     }
  19133                 }
  19134             }
  19135         }
  19136         SOC_IF_ERROR_RETURN
  19137             (READ_MODPORT_MAP_SELr(unit, local_port, &val));
  19138 
  19139         index = soc_reg_field_get(unit, MODPORT_MAP_SELr, val,
  19140                 MODPORT_MAP_INDEX_UPPERf);
  19141 
  19142         modport_map_index  = (index * 256) + dest_modid;
  19143 
  19144         soc_mem_lock(unit, MODPORT_MAP_SWm);
  19145         rv = soc_mem_read(unit, MODPORT_MAP_SWm, MEM_BLOCK_ANY, modport_map_index,
  19146                 &sw_entry);
  19147 
  19148         if(count == 1) {
  19149             if (SOC_SUCCESS(rv)) {
  19150                 enable = soc_mem_field32_get(unit, MODPORT_MAP_SWm, &sw_entry, 
  19151                         ENABLE0f); 
  19152                 if (!enable) { 
  19153                     stack_port = ((local_port << 8) | local_port);
  19154                     soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, DEST0f,
  19155                             stack_port);
  19156                     soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, ISTRUNK0f,0);
  19157                     soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, ADD_DESTINATION_PORTf,
  19158                             0);
  19159                     soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, ENABLE0f, 1);
  19160                 }
  19161                 soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, ADD_DESTINATION_PORTf,
  19162                         1);
  19163                 soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, PER_MODID_QUEUEING_ENABLEf,
  19164                         1);
  19165                 soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, QUEUE_MAP_POINTERf,
  19166                         node->hw_index);
  19167                 rv = soc_mem_write(unit, MODPORT_MAP_SWm, MEM_BLOCK_ALL, modport_map_index,
  19168                         &sw_entry);
  19169             }
  19170             soc_mem_unlock(unit, MODPORT_MAP_SWm);
  19171 
  19172             sal_memset(map_entries, 0, sizeof(map_entries));
  19173             /* Hardcoding the ING_QUEUE_OFFSET_MAPPING_TABLE */
  19174             for (index = 0; index < 16; index++) {
  19175                 soc_mem_field32_set(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm,
  19176                         &map_entries[index], QUEUE_OFFSETf, index > 7 ? 7 : index);
  19177             }
  19178             BCM_IF_ERROR_RETURN
  19179                 (_bcm_offset_map_table_entry_add(unit, entries, 16, &index));
  19180             SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, local_port, &val));
  19181             base_queue = soc_reg_field_get(unit, ING_COS_MODEr, val, BASE_QUEUE_NUMf);
  19182 
  19183             for (port = 0;  port < KT2_LPBK_PORT; port++) {
  19184                 sal_memset(&ing_queue_entry, 0, sizeof(ing_queue_map_entry_t));
  19185                 soc_mem_field32_set(unit, ING_QUEUE_MAPm,
  19186                         &ing_queue_entry, QUEUE_SET_BASEf, base_queue);
  19187                 soc_mem_field32_set(unit, ING_QUEUE_MAPm, &ing_queue_entry,
  19188                         QUEUE_OFFSET_PROFILE_INDEXf, index/16);
  19189                 soc_mem_field32_set(unit, ING_QUEUE_MAPm, &ing_queue_entry,
  19190                         ADD_EGRESS_PORT_BASE_QUEUEf, 0);
  19191                 BCM_IF_ERROR_RETURN(BCM_XGS3_MEM_WRITE(unit, ING_QUEUE_MAPm,
  19192                             node->hw_index + port , &ing_queue_entry));
  19193             }
  19194 
  19195             sal_memset(&ing_queue_entry, 0, sizeof(ing_queue_map_entry_t));
  19196             soc_mem_field32_set(unit, ING_QUEUE_MAPm,
  19197                     &ing_queue_entry, QUEUE_SET_BASEf, offset);
  19198             soc_mem_field32_set(unit, ING_QUEUE_MAPm, &ing_queue_entry,
  19199                     QUEUE_OFFSET_PROFILE_INDEXf, index/16);
  19200             soc_mem_field32_set(unit, ING_QUEUE_MAPm, &ing_queue_entry,
  19201                     ADD_EGRESS_PORT_BASE_QUEUEf, 1);
  19202             BCM_IF_ERROR_RETURN(BCM_XGS3_MEM_WRITE(unit, ING_QUEUE_MAPm,
  19203                         node->hw_index + dest_port, &ing_queue_entry));
  19204 
  19205         } else if (offset > 0) {
  19206             if (SOC_SUCCESS(rv)) {
  19207                 hw_index = soc_mem_field32_get(unit, MODPORT_MAP_SWm, &sw_entry, 
  19208                         QUEUE_MAP_POINTERf); 
  19209                 soc_mem_unlock(unit, MODPORT_MAP_SWm);
  19210                 sal_memset(&ing_queue_entry, 0, sizeof(ing_queue_map_entry_t));
  19211                 rv = BCM_XGS3_MEM_READ(unit, ING_QUEUE_MAPm,
  19212                         hw_index, &ing_queue_entry);
  19213                 if (!SOC_SUCCESS(rv)) {
  19214                     return rv;
  19215                 }
  19216                 soc_mem_field32_set(unit, ING_QUEUE_MAPm,
  19217                         &ing_queue_entry, QUEUE_SET_BASEf, offset);
  19218                 soc_mem_field32_set(unit, ING_QUEUE_MAPm, &ing_queue_entry,
  19219                         ADD_EGRESS_PORT_BASE_QUEUEf, 1);
  19220                 rv = BCM_XGS3_MEM_WRITE(unit, ING_QUEUE_MAPm,
  19221                         hw_index + dest_port, &ing_queue_entry);
  19222                 if (!SOC_SUCCESS(rv)) {
  19223                     return rv;
  19224                 }
  19225 
  19226             }
  19227         } else {
  19228             soc_mem_unlock(unit, MODPORT_MAP_SWm);
  19229         }
  19230 
  19231         intf_index = _bcm_kt2_cosq_source_intf_set(unit, dest_modid, 
  19232                 0, _BCM_KT2_COSQ_DPVOQ);
  19233         if (intf_index < 0) {
  19234             return BCM_E_RESOURCE;
  19235         }
  19236 
  19237         /*
  19238          *  SRC_INTF and MMU_INTFI_BASE_INDEX_TBL is mapped one to one,
  19239          *  so writing the base index at same index where SRC_INTF is written
  19240          */
  19241 
  19242         cng_offset = intf_index * 64 ;
  19243 
  19244         BCM_IF_ERROR_RETURN
  19245             (soc_mem_read(unit, MMU_INTFI_BASE_INDEX_TBLm, 
  19246                           MEM_BLOCK_ALL, intf_index, &base_tbl_entry));
  19247         soc_mem_field32_set(unit, MMU_INTFI_BASE_INDEX_TBLm, &base_tbl_entry, 
  19248                 BASE_ADDRf, cng_offset);
  19249         soc_mem_field32_set(unit, MMU_INTFI_BASE_INDEX_TBLm, &base_tbl_entry, 
  19250                 ENf, (node->level - 3 ));
  19251 
  19252         BCM_IF_ERROR_RETURN(soc_mem_write(unit, MMU_INTFI_BASE_INDEX_TBLm,
  19253                     MEM_BLOCK_ALL, intf_index, &base_tbl_entry));
  19254 
  19255         /* set the mapping from congestion bits in flow control table
  19256          * to corresponding hw_index */
  19257         BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_map_fc_status_to_node(unit, 
  19258                     _BCM_KT2_COSQ_FC_VOQFC,  
  19259                     node->hw_index , (node->level - 2), cng_offset + dest_port));
  19260 
  19261 
  19262     }
  19263     return BCM_E_NONE;
  19264 }
  19265 /*
  19266  * Function:
  19267  *      bcm_kt2_cosq_gport_congestion_config_set 
  19268  * Purpose:
  19269  *      Setting the dmvoq/dpvoq related configuration
  19270  * Parameters:
  19271  *      unit           - (IN) Unit number.
  19272  *      gport          - (IN) gport identifier 
  19273  *      cos            - (IN) cos value 
  19274  *      config         - (IN) congestion data 
  19275  * Returns:
  19276  *      BCM_E_xxx
  19277  */
  19278 
  19279 int bcm_kt2_cosq_gport_congestion_config_set(int unit, bcm_gport_t gport, 
  19280                                          bcm_cos_queue_t cosq, 
  19281                                          bcm_cosq_congestion_info_t *config)
  19282 {
  19283     /* config is used by DMVOQ/DPVOQ
  19284      * E2ECC COE FC will ignore the config
  19285      * and cos parameters.
  19286      */
  19287 
  19288     bcm_port_t subport;
  19289     _bcm_kt2_cosq_node_t *node;
  19290     int max_subport = SOC_INFO(unit).pp_port_index_max;
  19291     BCM_IF_ERROR_RETURN
  19292         (_bcm_kt2_cosq_node_get(unit, gport, NULL , &subport, NULL, &node));
  19293 
  19294     /* E2ECC on COE -queue added to subport */
  19295     if (soc_feature(unit, soc_feature_subtag_coe) &&
  19296         (_bcm_is_port_linkphy_subport(unit, gport, -1) &&
  19297         (subport <= max_subport))) {
  19298         if (!IS_SUBTAG_PORT(unit, node->local_port)) {
  19299             return BCM_E_PORT;
  19300         }
  19301         return _bcm_kt2_cosq_gport_e2ecc_coe_config_set(unit, gport);
  19302     }
  19303 
  19304     if (!config) {
  19305         return BCM_E_PARAM;
  19306     }
  19307 /* when user specify dest_modid, fabric_port, fabric_modid 
  19308    then we consider as DMVOQ */
  19309     if ((config->dest_modid != -1)  && 
  19310             (config->fabric_port != -1) &&
  19311             (config->fabric_modid != -1)) {
  19312         return _bcm_kt2_cosq_gport_dmvoq_config_set(unit, gport, cosq, 
  19313                                                config->dest_modid,
  19314                                                config->fabric_modid,
  19315                                                config->fabric_port);
  19316     }
  19317 /* when user specify dest_modid, dest_port with fabric_port, fabric_modid as -1
  19318    then we consider as DPVOQ */
  19319  
  19320     if ((config->dest_modid != -1)  && 
  19321             (config->dest_port != -1)) {
  19322         return _bcm_kt2_cosq_gport_dpvoq_config_set(unit, gport, cosq, 
  19323                 config->dest_modid,
  19324                 config->dest_port);
  19325     } 
  19326     return BCM_E_PARAM;
  19327 }
  19328 
  19329 /*
  19330  * Function:
  19331  *      bcm_kt2_cosq_gport_congestion_config_set 
  19332  * Purpose:
  19333  *      Setting the dmvoq/dpvoq related configuration
  19334  * Parameters:
  19335  *      unit           - (IN) Unit number.
  19336  *      gport          - (IN) gport identifier 
  19337  *      cos            - (IN) cos value 
  19338  *      config         - (IN) congestion data 
  19339  * Returns:
  19340  *      BCM_E_xxx
  19341  */
  19342 
  19343 
  19344 int bcm_kt2_cosq_gport_congestion_config_get(int unit, bcm_gport_t port, 
  19345                                          bcm_cos_queue_t cosq, 
  19346                                          bcm_cosq_congestion_info_t *config)
  19347 {
  19348     _bcm_kt2_cosq_node_t *node;
  19349     _bcm_kt2_mmu_info_t *mmu_info;
  19350     int fabric_port = 0;
  19351     int base_index = 0;
  19352     mmu_info = _bcm_kt2_mmu_info[unit];
  19353 
  19354     if (!config) {
  19355         return BCM_E_PARAM;
  19356     }
  19357 
  19358     BCM_IF_ERROR_RETURN
  19359         (_bcm_kt2_cosq_node_get(unit, port, NULL, NULL, NULL, &node));
  19360 
  19361 
  19362     if (!node) {
  19363         return BCM_E_NOT_FOUND;
  19364     }
  19365 
  19366     if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2) {
  19367         return BCM_E_PARAM;
  19368     }
  19369 
  19370 
  19371     BCM_PBMP_ITER(node->fabric_pbmp, fabric_port) {
  19372         config->fabric_port = fabric_port;
  19373         break;
  19374     }
  19375     if ( node->hw_index % 8 != 0){
  19376         /*base hw_index */
  19377         base_index = node->hw_index - (node->hw_index % 8); 
  19378         bcm_kt2_sw_hw_queue(unit, &base_index);  
  19379         node = &(mmu_info->queue_node[base_index]); 
  19380     }
  19381 
  19382     config->dest_modid = node->remote_modid;
  19383     config->dest_port = node->remote_port;
  19384     config->fabric_modid = node->fabric_modid;
  19385 
  19386 
  19387     return BCM_E_NONE;
  19388 }
  19389 
  19390 
  19391 /*
  19392  * Function:
  19393  *     _bcm_kt2_cosq_mapping_set
  19394  * Purpose:
  19395  *     Set COS queue for the specified priority of an ingress port
  19396  * Parameters:
  19397  *     unit     - (IN) unit number
  19398  *     ing_port - (IN) ingress port
  19399  *     gport    - (IN) queue group GPORT identifier
  19400  *     priority - (IN) priority value to map
  19401  *     flags    - (IN) BCM_COSQ_GPORT_XXX_QUEUE_GROUP
  19402  *     gport    - (IN) queue group GPORT identifier
  19403  *     cosq     - (IN) COS queue number
  19404  * Returns:
  19405  *     BCM_E_XXX
  19406  */
  19407 STATIC int
  19408 _bcm_kt2_cosq_mapping_set(int unit, bcm_port_t ing_port, bcm_cos_t priority,
  19409                          uint32 flags, bcm_gport_t gport, bcm_cos_queue_t cosq)
  19410 {
  19411     _bcm_kt2_cosq_node_t *node;
  19412     bcm_port_t local_port;
  19413     ing_queue_map_entry_t ing_queue_entry;
  19414     ing_queue_offset_mapping_table_entry_t map_entries[16];
  19415     void *entries[1];
  19416     int rv;
  19417     uint32 old_index = 0;
  19418     uint32 new_index = 0;
  19419  
  19420     if (priority < 0 || priority >= 16) {
  19421         return BCM_E_PARAM;
  19422     }
  19423 
  19424     if (gport == -1) {
  19425         return BCM_E_UNAVAIL;
  19426     }
  19427 
  19428     switch (flags) {
  19429         case BCM_COSQ_GPORT_DESTMOD_UCAST_QUEUE_GROUP:
  19430             BCM_IF_ERROR_RETURN
  19431                 (_bcm_kt2_cosq_node_get(unit, gport, NULL ,&local_port, NULL, &node));
  19432             if ((!BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(gport)) && (node->parent == NULL)) {
  19433                 return BCM_E_PARAM;
  19434             }
  19435 
  19436             if ( node->hw_index % 8 == 0) {
  19437                 sal_memset(map_entries, 0, sizeof(map_entries));
  19438 
  19439                 BCM_IF_ERROR_RETURN(
  19440                         soc_mem_read(unit, ING_QUEUE_MAPm, MEM_BLOCK_ANY, node->hw_index,
  19441                             &ing_queue_entry));
  19442                 old_index = soc_mem_field32_get(unit, ING_QUEUE_MAPm,
  19443                         &ing_queue_entry, QUEUE_OFFSET_PROFILE_INDEXf);
  19444                 old_index *= 16;
  19445 
  19446                 entries[0] = &map_entries;
  19447                 BCM_IF_ERROR_RETURN
  19448                     (_bcm_offset_map_table_entry_get(unit, old_index, 16, entries));
  19449                 rv = _bcm_offset_map_table_entry_delete(unit, old_index);
  19450                 if (!(rv == SOC_E_NOT_FOUND || rv == SOC_E_NONE)) {
  19451                     return rv;
  19452                 }
  19453                 soc_mem_field32_set(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm, 
  19454                         &map_entries[priority], QUEUE_OFFSETf, cosq);
  19455 
  19456                 BCM_IF_ERROR_RETURN
  19457                     (_bcm_offset_map_table_entry_add(unit, entries, 16, &new_index));
  19458 
  19459                 soc_mem_field32_set(unit, ING_QUEUE_MAPm, &ing_queue_entry,
  19460                         QUEUE_OFFSET_PROFILE_INDEXf,
  19461                         new_index / 16);
  19462                 BCM_IF_ERROR_RETURN(
  19463                         soc_mem_write(unit, ING_QUEUE_MAPm, MEM_BLOCK_ANY, 
  19464                             node->hw_index, &ing_queue_entry));
  19465             }
  19466 
  19467 
  19468             break;
  19469         default:
  19470             return BCM_E_UNAVAIL;
  19471     }
  19472 
  19473     return BCM_E_NONE;
  19474 }
  19475 
  19476 /*
  19477  * Function:
  19478  *     _bcm_kt2_cosq_mapping_get
  19479  * Purpose:
  19480  *     Set COS queue for the specified priority of an ingress port
  19481  * Parameters:
  19482  *     unit     - (IN) unit number
  19483  *     ing_port - (IN) ingress port
  19484  *     gport    - (IN) queue group GPORT identifier
  19485  *     priority - (IN) priority value to map
  19486  *     flags    - (IN) BCM_COSQ_GPORT_XXX_QUEUE_GROUP
  19487  *     gport    - (IN) queue group GPORT identifier
  19488  *     cosq     - (IN) COS queue number
  19489  * Returns:
  19490  *     BCM_E_XXX
  19491  */
  19492 STATIC int
  19493 _bcm_kt2_cosq_mapping_get(int unit, bcm_port_t ing_port, bcm_cos_t priority,
  19494                          uint32 flags, bcm_gport_t *gport, bcm_cos_queue_t *cosq)
  19495 {
  19496     _bcm_kt2_cosq_node_t *node;
  19497     void *entries[1];
  19498     bcm_port_t local_port;
  19499     ing_queue_map_entry_t ing_queue_entry;
  19500     ing_queue_offset_mapping_table_entry_t map_entries[16];
  19501     uint32 index = 0;
  19502  
  19503     if (priority < 0 || priority >= 16) {
  19504         return BCM_E_PARAM;
  19505     }
  19506 
  19507 
  19508     switch (flags) {
  19509         case BCM_COSQ_GPORT_DESTMOD_UCAST_QUEUE_GROUP:
  19510             BCM_IF_ERROR_RETURN
  19511                 (_bcm_kt2_cosq_node_get(unit, *gport, NULL ,&local_port, NULL, &node));
  19512             if ((!BCM_GPORT_IS_DESTMOD_QUEUE_GROUP(*gport)) && (node->parent == NULL)) {
  19513                 return BCM_E_PARAM;
  19514             }
  19515 
  19516             sal_memset(map_entries, 0, sizeof(map_entries));
  19517 
  19518             entries[0] = &map_entries;
  19519             BCM_IF_ERROR_RETURN(
  19520                     soc_mem_read(unit, ING_QUEUE_MAPm, MEM_BLOCK_ANY, node->hw_index,
  19521                         &ing_queue_entry));
  19522             index = soc_mem_field32_get(unit, ING_QUEUE_MAPm,
  19523                     &ing_queue_entry, QUEUE_OFFSET_PROFILE_INDEXf);
  19524             index *= 16;
  19525 
  19526             BCM_IF_ERROR_RETURN
  19527                 (_bcm_offset_map_table_entry_get(unit, index, 16, entries));
  19528             *cosq = soc_mem_field32_get(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm, 
  19529                     &map_entries[priority], QUEUE_OFFSETf);
  19530 
  19531             break;
  19532         default:
  19533             return BCM_E_UNAVAIL;
  19534     }
  19535 
  19536     return BCM_E_NONE;
  19537 }
  19538 int
  19539 bcm_kt2_cosq_gport_mapping_set(int unit, bcm_port_t ing_port,
  19540                               bcm_cos_t int_pri, uint32 flags,
  19541                               bcm_gport_t gport, bcm_cos_queue_t cosq)
  19542 {
  19543     return _bcm_kt2_cosq_mapping_set(unit, ing_port, int_pri, flags, gport,
  19544                                     cosq);
  19545 }
  19546 
  19547 int
  19548 bcm_kt2_cosq_gport_mapping_get(int unit, bcm_port_t ing_port,
  19549                               bcm_cos_t int_pri, uint32 flags,
  19550                               bcm_gport_t *gport, bcm_cos_queue_t *cosq)
  19551 {
  19552     return _bcm_kt2_cosq_mapping_get(unit, ing_port, int_pri, flags, gport,
  19553                                     cosq);
  19554 }
  19555 
  19556 int
  19557 bcm_kt2_cosq_congestion_mapping_set(int unit,int fabric_modid ,
  19558         bcm_cosq_congestion_mapping_info_t *config)
  19559 {
  19560     int profile_index , index, desired_congestion_state;
  19561     int i ,j , value, bit_position, max_value = 0, max_congestion_state;
  19562     mmu_intfi_st_trans_tbl_entry_t st_trans_entry;
  19563     int desired_congestion_value[8] = 
  19564     {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80} ;
  19565    
  19566     /* CHECK if valid fabric_modid is passed. */
  19567     if (fabric_modid < 0) {
  19568         return BCM_E_BADID;
  19569     }
  19570     profile_index = _bcm_kt2_cosq_source_intf_profile_get(unit, fabric_modid, 
  19571             0, _BCM_KT2_COSQ_DMVOQ);
  19572     if (profile_index == -1 ) {
  19573         return BCM_E_PARAM;
  19574     }
  19575     
  19576     /* Find the Max flow control bit */
  19577     for (i = 0; i < 8 ; i++) {
  19578         if (max_value < config->flow_control_bits[i]) {
  19579             max_value =  config->flow_control_bits[i];
  19580         }
  19581     }
  19582     max_congestion_state = 1 << (max_value + 1) ;
  19583 
  19584     if (max_congestion_state > 256 ) {
  19585         return BCM_E_PARAM;
  19586     }
  19587 
  19588     /* Configure all the congestion states as per 
  19589        the flow control bits passed */
  19590     for ( i = 0; i < max_congestion_state ; i++) {
  19591         desired_congestion_state = 0;
  19592         value = i;
  19593         bit_position = 0;
  19594         /* Loop to set all the congestion states bit by bit */
  19595         while ( value != 0 ) {
  19596             if (value & 0x1) {
  19597                 for (j = 0 ; j < 8 ; j++) {
  19598                     if (config->flow_control_bits[j] == bit_position) { 
  19599                         desired_congestion_state |= 
  19600                             desired_congestion_value[j];
  19601                     }
  19602                 }
  19603             }
  19604             bit_position++;
  19605             value = value >> 1;
  19606         }
  19607 
  19608         index = (profile_index  * 256) + i ;
  19609         SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm(
  19610                     unit, MEM_BLOCK_ALL, index,
  19611                     &st_trans_entry));
  19612         soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm,
  19613                 &st_trans_entry, FC_ST_XLATEf,
  19614                 desired_congestion_state);
  19615         SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm(
  19616                     unit, MEM_BLOCK_ALL, index,
  19617                     &st_trans_entry));
  19618 
  19619 
  19620     }
  19621     /* Configure remaining the congestion states as zero */ 
  19622  
  19623     if (max_congestion_state < 256 ) {
  19624         for ( i = max_congestion_state; i < 256 ; i++) {
  19625             index = (profile_index  * 256) + i ;
  19626             SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm(
  19627                         unit, MEM_BLOCK_ALL, index,
  19628                         &st_trans_entry));
  19629             soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm,
  19630                     &st_trans_entry, FC_ST_XLATEf,
  19631                     0);
  19632             SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm(
  19633                         unit, MEM_BLOCK_ALL, index,
  19634                         &st_trans_entry));
  19635         }
  19636     }
  19637 
  19638 
  19639     return BCM_E_NONE;
  19640 
  19641 }
  19642 
  19643 int 
  19644 bcm_kt2_cosq_congestion_mapping_get(int unit,int fabric_modid ,
  19645         bcm_cosq_congestion_mapping_info_t *config)
  19646 {
  19647     int index, profile_index, i;
  19648     mmu_intfi_st_trans_tbl_entry_t st_trans_entry;
  19649     int congestion_data , bit_position;
  19650   
  19651     /* CHECK if valid fabric_modid is passed. */
  19652     if (fabric_modid < 0) {
  19653         return BCM_E_BADID;
  19654     }
  19655     profile_index = _bcm_kt2_cosq_source_intf_profile_get(unit, fabric_modid, 
  19656             0, _BCM_KT2_COSQ_DMVOQ);
  19657     if (profile_index == -1 ) {
  19658         return BCM_E_PARAM;
  19659     }
  19660 
  19661     /* Initially fill all the control bits as -1 */
  19662 
  19663     for (i = 0; i < 8 ; i++) {
  19664         config->flow_control_bits[i] = -1;
  19665     }
  19666     /* Read the congestion state at index 1,2,4,8,16,32,64,128 and update the control bits
  19667        accordingly */
  19668     for (i = 0; i < 8 ; i++) {
  19669         index = ((profile_index  * 256) + (1 << i)) ;
  19670 
  19671         SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm(
  19672                     unit, MEM_BLOCK_ALL, index,
  19673                     &st_trans_entry));
  19674         congestion_data = 
  19675             soc_mem_field32_get(unit, MMU_INTFI_ST_TRANS_TBLm,
  19676                     &st_trans_entry, FC_ST_XLATEf);
  19677         bit_position = 0;
  19678         /* Loop to check all the bits in the congestion data */
  19679         while ( congestion_data != 0 ) {
  19680             if (congestion_data & 0x1) {
  19681                 config->flow_control_bits[bit_position] = i;
  19682             }
  19683             bit_position++;
  19684             congestion_data = congestion_data >> 1;
  19685         }
  19686     }
  19687     return BCM_E_NONE;
  19688 }
  19689 
  19690 
  19691 int
  19692 _bcm_kt2_cosq_dynamic_port_encap_change(int unit,bcm_port_t port) 
  19693 {
  19694 
  19695    bcm_gport_t gport;
  19696    _bcm_kt2_mmu_info_t *mmu_info;
  19697    _bcm_kt2_cosq_list_t *list;
  19698    int numq,cosq; 
  19699    int num_cos = 0;
  19700    int id = 0 ;
  19701    int mcid = 0;
  19702    uint32 rval;
  19703    bcm_gport_t port_sched, l0_sched, l1_sched, queue;
  19704    int rv;
  19705    int limit,offset;
  19706    soc_info_t *si;
  19707    int queuenum = 0;
  19708 
  19709    si = &SOC_INFO(unit);
  19710    mmu_info = _bcm_kt2_mmu_info[unit];
  19711    
  19712 #if defined BCM_METROLITE_SUPPORT
  19713    if (soc_feature(unit, soc_feature_discontinuous_pp_port) &&
  19714        (SOC_PBMP_MEMBER(si->linkphy_pbm, port) ||
  19715         SOC_PBMP_MEMBER(si->subtag_pbm, port))) {
  19716       /* Port encap change should not be called for Linkphy ports */
  19717       return BCM_E_PARAM;
  19718    }
  19719 #endif
  19720 
  19721    bcm_kt2_cosq_config_get(unit, &num_cos);
  19722    BCM_IF_ERROR_RETURN
  19723    (bcm_esw_port_gport_get(unit, port , &gport));
  19724 
  19725 
  19726    list = &mmu_info->global_qlist;
  19727    offset = 0;
  19728 
  19729    /* We do not want to recreate lls tree if we're not involving
  19730     * HG ports.
  19731     */
  19732    if ((si->port_num_uc_cosq[port] == KT2_DEFAULT_NUM_PHYSICAL_QUEUES) && 
  19733        (!IS_HG_PORT(unit, port))) {
  19734        return BCM_E_NONE;
  19735    }
  19736    if ((si->port_num_uc_cosq[port] == KT2_HG_NUM_PHYSICAL_QUEUES) &&
  19737        (IS_HG_PORT(unit, port))) {
  19738         return BCM_E_NONE;
  19739    }
  19740    if (IS_HG_PORT(unit, port)) { 
  19741        numq = KT2_HG_NUM_PHYSICAL_QUEUES; 
  19742    }
  19743    else { 
  19744        numq = KT2_DEFAULT_NUM_PHYSICAL_QUEUES ; 
  19745    }
  19746    limit = mmu_info->num_base_queues;
  19747 
  19748    rv = _bcm_kt2_node_index_get(unit, list->bits, offset, limit,
  19749                                             mmu_info->qset_size, numq, &id);
  19750    if( rv != BCM_E_NONE) { 
  19751       return BCM_E_RESOURCE; 
  19752 
  19753    }
  19754    if (soc_feature(unit, soc_feature_mmu_packing)) {
  19755    /* reserving queues for mc if its packing */
  19756        rv = _bcm_kt2_node_index_get(unit, list->bits, (id + numq), limit,
  19757                                             mmu_info->qset_size, numq, &mcid);
  19758        if (rv != BCM_E_NONE) { 
  19759            return BCM_E_RESOURCE; 
  19760        }
  19761    }
  19762    BCM_IF_ERROR_RETURN
  19763    ( bcm_kt2_cosq_gport_delete(unit , gport));
  19764 
  19765    BCM_IF_ERROR_RETURN
  19766    (_bcm_kt2_node_index_clear(list, si->port_uc_cosq_base[port] ,
  19767                               si->port_num_uc_cosq[port]));
  19768 
  19769    BCM_IF_ERROR_RETURN
  19770    (_bcm_kt2_node_index_set(list ,id, numq)); 
  19771     si->port_uc_cosq_base[port] = id ; 
  19772     si->port_cosq_base[port] = id ; 
  19773     si->port_num_uc_cosq[port] = numq ; 
  19774     mmu_info->port[port].q_offset = id;
  19775     mmu_info->port[port].q_limit = id + numq;
  19776     if (soc_feature(unit, soc_feature_mmu_packing)) {
  19777         BCM_IF_ERROR_RETURN
  19778         (_bcm_kt2_node_index_clear(list, si->port_cosq_base[port] ,
  19779                               si->port_num_cosq[port]));
  19780         BCM_IF_ERROR_RETURN
  19781         (_bcm_kt2_node_index_set(list, mcid, numq)); 
  19782         si->port_cosq_base[port] = mcid ; 
  19783         si->port_num_cosq[port] = numq; 
  19784         mmu_info->port[port].mcq_offset = mcid;
  19785         mmu_info->port[port].mcq_limit = mcid + numq  ;
  19786     }
  19787 
  19788     SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval));
  19789     soc_reg_field_set(unit, ING_COS_MODEr, &rval, BASE_QUEUE_NUMf,
  19790                       mmu_info->port[port].q_offset);
  19791     if (IS_HG_PORT(unit, port)) {
  19792         soc_reg_field_set(unit, ING_COS_MODEr, &rval, COS_MODEf, 2);  
  19793     }
  19794     else { 
  19795         soc_reg_field_set(unit, ING_COS_MODEr, &rval, COS_MODEf, 0);  
  19796     }
  19797     SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, rval));
  19798    
  19799     SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval));
  19800     soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr, &rval, BASE_QUEUEf,
  19801                       (soc_feature(unit, soc_feature_mmu_packing)) ? 
  19802                        mmu_info->port[port].mcq_offset :
  19803                        mmu_info->port[port].q_offset);
  19804 
  19805     if (IS_HG_PORT(unit, port)) {
  19806         soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr,
  19807                             &rval, COS_MODEf, 2);
  19808     }
  19809     else { 
  19810         soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr,
  19811                             &rval, COS_MODEf, 0);
  19812     }
  19813     SOC_IF_ERROR_RETURN(WRITE_RQE_PP_PORT_CONFIGr(unit, port, rval));
  19814             
  19815     for (queuenum = mmu_info->port[port].q_offset;
  19816          queuenum < mmu_info->port[port].q_limit; queuenum++) {
  19817          SOC_IF_ERROR_RETURN (soc_mem_field32_modify(unit,
  19818               EGR_QUEUE_TO_PP_PORT_MAPm, queuenum, PP_PORTf, port));
  19819     }
  19820 
  19821     if (soc_feature(unit, soc_feature_mmu_packing)) {
  19822         for (queuenum = mmu_info->port[port].mcq_offset;
  19823              queuenum < mmu_info->port[port].mcq_limit; queuenum++) {
  19824              SOC_IF_ERROR_RETURN (soc_mem_field32_modify(unit,
  19825                        EGR_QUEUE_TO_PP_PORT_MAPm, queuenum, PP_PORTf, port));
  19826         }
  19827    }
  19828     if (IS_HG_PORT(unit, port)) {
  19829         BCM_IF_ERROR_RETURN
  19830         (_bcm_kt2_port_lls_config_set(unit, port, 
  19831          si->port_uc_cosq_base[port], 
  19832          si->port_num_uc_cosq[port], 
  19833         num_cos));
  19834     } else {
  19835       if (!soc_feature(unit, soc_feature_mmu_packing)) {
  19836           BCM_IF_ERROR_RETURN
  19837           (bcm_kt2_cosq_gport_add(unit, gport, 1, 0, &port_sched));
  19838           BCM_IF_ERROR_RETURN
  19839            (bcm_kt2_cosq_gport_add(unit, port, 1, 
  19840            BCM_COSQ_GPORT_SCHEDULER, 
  19841                            &l0_sched));
  19842           BCM_IF_ERROR_RETURN
  19843            (bcm_kt2_cosq_gport_attach(unit, l0_sched, port_sched, 0)); 
  19844           BCM_IF_ERROR_RETURN
  19845            (bcm_kt2_cosq_gport_add(unit, port,num_cos, 
  19846                                  BCM_COSQ_GPORT_SCHEDULER, 
  19847                                      &l1_sched));
  19848           BCM_IF_ERROR_RETURN
  19849            (bcm_kt2_cosq_gport_attach(unit, l1_sched, l0_sched, 0));  
  19850           for (cosq = 0; cosq < num_cos; cosq++) {
  19851                BCM_IF_ERROR_RETURN
  19852                 (bcm_kt2_cosq_gport_add(unit, port, 1,
  19853                 BCM_COSQ_GPORT_UCAST_QUEUE_GROUP, &queue));
  19854                BCM_IF_ERROR_RETURN
  19855                   (bcm_kt2_cosq_gport_attach(unit, queue, l1_sched, 
  19856                                                cosq));  
  19857                }
  19858       }else {
  19859             BCM_IF_ERROR_RETURN
  19860             (_bcm_kt2_packing_config_set(unit, port, num_cos ));
  19861       }
  19862   }
  19863 return BCM_E_NONE; 
  19864 
  19865 }
  19866 
  19867 /*
  19868  * Function:
  19869  *     _bcm_kt2_port_enqueue_set
  19870  * Purpose:
  19871  *     Enable or Disable the enqueing the packets to the port
  19872  * Parameters:
  19873  *     unit       - (IN) unit number
  19874  *     gport      - (IN) gport of the port 
  19875  *     enable     - (IN) TRUE to enable
  19876  *                      FALSE to disable
  19877  * Returns:
  19878  *     BCM_E_XXX
  19879  */
  19880 
  19881 int
  19882 _bcm_kt2_port_enqueue_set(int unit, bcm_port_t gport,
  19883                           int enable)
  19884 {
  19885     bcm_port_t local_port;
  19886     uint64 tmp64, r64val, rval64;
  19887 
  19888     BCM_IF_ERROR_RETURN
  19889         (_bcm_kt2_cosq_localport_resolve(unit, gport, &local_port));
  19890 
  19891     if (!BCM_PBMP_MEMBER((PBMP_ALL(unit)), local_port)) {
  19892         return BCM_E_PORT; 
  19893     }
  19894     /* Enable in TX direction*/
  19895     BCM_IF_ERROR_RETURN
  19896         (soc_katana2_mmu_port_enable_set(unit, local_port, enable));
  19897 
  19898     /* Enable in RX direction*/
  19899     SOC_IF_ERROR_RETURN(READ_INPUT_PORT_RX_ENABLE_64r(unit, &r64val));
  19900     rval64 = soc_reg64_field_get(unit, INPUT_PORT_RX_ENABLE_64r, r64val,
  19901                                  INPUT_PORT_RX_ENABLEf);
  19902     COMPILER_64_SET(tmp64, 0, 1);
  19903     COMPILER_64_SHL(tmp64, (local_port));
  19904     if (enable) {
  19905         COMPILER_64_OR(rval64, tmp64);
  19906     } else {
  19907         COMPILER_64_NOT(tmp64);
  19908         COMPILER_64_AND(rval64, tmp64);
  19909     }
  19910     
  19911     soc_reg64_field_set(unit, INPUT_PORT_RX_ENABLE_64r, &r64val,
  19912                           INPUT_PORT_RX_ENABLEf, rval64);
  19913     SOC_IF_ERROR_RETURN(WRITE_INPUT_PORT_RX_ENABLE_64r(unit, r64val));
  19914     return BCM_E_NONE;
  19915 }
  19916 /*
  19917  * Function:
  19918  *     bcm_kt2_cosq_gport_e2ecc_transmit_set 
  19919  * Purpose:
  19920  *     Enable or Disable queue of a given port for e2ecc reporting. 
  19921  * Parameters:
  19922  *     unit       - (IN) unit number
  19923  *     gport      - (IN) gport of the port
  19924  *     cosq       - (IN) cosq number (0-7) -1 for all queues.
  19925  *     type       - (IN) Flag indicating e2ecc transmit.
  19926  *     arg        - (IN) TRUE to enable
  19927  *                       FALSE to disable
  19928  * Returns:
  19929  *     BCM_E_XXX
  19930  */
  19931 int
  19932 bcm_kt2_cosq_gport_e2ecc_transmit_set(int unit, bcm_gport_t gport, 
  19933                                       bcm_cos_queue_t cosq,
  19934                                       bcm_cosq_control_t type, 
  19935                                       int arg)
  19936 {
  19937     bcm_port_t port;
  19938     uint32     rval;
  19939     uint32     fval;
  19940     uint64     r64val;
  19941 
  19942     LOG_INFO(BSL_LS_BCM_COSQ,
  19943              (BSL_META_U(unit,
  19944                          "bcm_kt2_cosq_gport_e2ecc_transmit_set: \
  19945                           unit=%d gport=0x%x cosq=%d \
  19946                           type=%d arg=%d\n"),
  19947                           unit, gport, cosq, type, arg));
  19948     switch (type) {
  19949     case bcmCosqControlE2ECCTransmitEnable:
  19950          if ((!BCM_COSQ_QUEUE_VALID(unit, cosq)) && (cosq != -1)) {
  19951                 return BCM_E_PARAM;
  19952          }
  19953          if (BCM_GPORT_IS_SET(gport)) {
  19954              BCM_IF_ERROR_RETURN(
  19955                 bcm_esw_port_local_get(unit, gport, &port));
  19956          } else {
  19957              port = gport;
  19958          }
  19959          if (!SOC_PORT_VALID(unit, port) || !IS_ALL_PORT(unit, port)) {
  19960              return BCM_E_PORT;
  19961          }
  19962  
  19963          BCM_IF_ERROR_RETURN(READ_OP_E2ECC_PORT_CONFIGr(unit, port, &rval)); 
  19964          fval = soc_reg_field_get(unit, OP_E2ECC_PORT_CONFIGr,
  19965                                   rval, COS_MASKf);
  19966          if (cosq != -1) {
  19967              if (arg) {
  19968                  fval |= (1 << cosq);
  19969              } else {
  19970                  fval &= ~(1 << cosq);
  19971              }
  19972          } else {
  19973              if (arg) {
  19974                  fval = 0xff;
  19975              } else {
  19976                  fval = 0;
  19977              }
  19978         }
  19979         soc_reg_field_set(unit, OP_E2ECC_PORT_CONFIGr,
  19980                           &rval, COS_MASKf, fval);
  19981         soc_reg_field_set(unit, OP_E2ECC_PORT_CONFIGr, &rval,
  19982                           E2ECC_RPT_ENf, arg ? 1 : 0);
  19983         BCM_IF_ERROR_RETURN(WRITE_OP_E2ECC_PORT_CONFIGr(unit, port, rval));
  19984         
  19985         /* Now enable monitoring in INTFO if at least one queue active */
  19986         COMPILER_64_ZERO(r64val);
  19987         soc_reg64_field32_set(unit, MMU_INTFO_CONGST_STr,
  19988                               &r64val, ENf, fval ? 1: 0);
  19989         SOC_IF_ERROR_RETURN(WRITE_MMU_INTFO_CONGST_STr(unit,
  19990                             port, r64val));
  19991         break;
  19992     default:
  19993         return BCM_E_UNAVAIL;
  19994     }
  19995 
  19996     return BCM_E_NONE;
  19997 }
  19998 
  19999 /*
  20000  * Function:
  20001  *     bcm_kt2_cosq_gport_e2ecc_transmit_get
  20002  * Purpose:
  20003  *     Get the Enable or Disable value for a queue of a given port for e2ecc reporting.
  20004  * Parameters:
  20005  *     unit       - (IN) unit number
  20006  *     gport      - (IN) gport of the port
  20007  *     cosq       - (IN) cosq number (0-7) -1 for all queues.
  20008  *     type       - (IN) Flag indicating e2ecc transmit.
  20009  *     arg        - (OUT)TRUE to enable
  20010  *                       FALSE to disable
  20011  * Returns:
  20012  *     BCM_E_XXX
  20013  */
  20014 int
  20015 bcm_kt2_cosq_gport_e2ecc_transmit_get(int unit, bcm_gport_t gport,
  20016                                       bcm_cos_queue_t cosq,
  20017                                       bcm_cosq_control_t type,
  20018                                       int *arg)
  20019 {
  20020     bcm_port_t port;
  20021     uint32     rval;
  20022     uint32     fval;
  20023 
  20024     LOG_INFO(BSL_LS_BCM_COSQ,
  20025              (BSL_META_U(unit,
  20026                          "bcm_kt2_cosq_gport_e2ecc_transmit_set: \
  20027                           unit=%d gport=0x%x cosq=%d \
  20028                           type=%d \n"),
  20029                           unit, gport, cosq, type));
  20030     switch (type) {
  20031     case bcmCosqControlE2ECCTransmitEnable:
  20032          if (!BCM_COSQ_QUEUE_VALID(unit, cosq)) {
  20033                 return BCM_E_PARAM;
  20034          }
  20035          if (BCM_GPORT_IS_SET(gport)) {
  20036              BCM_IF_ERROR_RETURN(
  20037                 bcm_esw_port_local_get(unit, gport, &port));
  20038          } else {
  20039              port = gport;
  20040          }
  20041          if (!SOC_PORT_VALID(unit, port) || !IS_ALL_PORT(unit, port)) {
  20042              return BCM_E_PORT;
  20043          }
  20044  
  20045          BCM_IF_ERROR_RETURN(READ_OP_E2ECC_PORT_CONFIGr(unit, port, &rval));
  20046          fval = soc_reg_field_get(unit, OP_E2ECC_PORT_CONFIGr,
  20047                                   rval, COS_MASKf);
  20048          fval = fval & (1 << cosq);  
  20049          *arg = fval ? 1 : 0; 
  20050          break;
  20051     default:
  20052          return BCM_E_UNAVAIL; 
  20053     }
  20054 
  20055     return BCM_E_NONE;
  20056 }
  20057 #if defined(BCM_SABER2_SUPPORT)
  20058 STATIC int
  20059 _bcm_kt2_get_pg_profile_mapping(int unit, int profile_index,
  20060                                 uint32 *reg0, uint32 *reg1)
  20061 {
  20062     uint32 rval, rval1;
  20063 
  20064     if (profile_index < 0 || profile_index > 3) {
  20065         return BCM_E_PARAM;
  20066     }
  20067     if (profile_index == 0) {
  20068         SOC_IF_ERROR_RETURN
  20069                 (READ_MMU_ENQ_PROFILE_0_PRI_GRP0r(unit, &rval));
  20070         SOC_IF_ERROR_RETURN
  20071                 (READ_MMU_ENQ_PROFILE_0_PRI_GRP1r(unit, &rval1));
  20072     } else if (profile_index == 1) {
  20073         SOC_IF_ERROR_RETURN
  20074                 (READ_MMU_ENQ_PROFILE_1_PRI_GRP0r(unit, &rval));
  20075         SOC_IF_ERROR_RETURN
  20076                 (READ_MMU_ENQ_PROFILE_1_PRI_GRP1r(unit, &rval1));
  20077     } else if (profile_index == 2) {
  20078         SOC_IF_ERROR_RETURN
  20079                 (READ_MMU_ENQ_PROFILE_2_PRI_GRP0r(unit, &rval));
  20080         SOC_IF_ERROR_RETURN
  20081                 (READ_MMU_ENQ_PROFILE_2_PRI_GRP1r(unit, &rval1));
  20082     } else {
  20083         SOC_IF_ERROR_RETURN
  20084                 (READ_MMU_ENQ_PROFILE_3_PRI_GRP0r(unit, &rval));
  20085         SOC_IF_ERROR_RETURN
  20086                 (READ_MMU_ENQ_PROFILE_3_PRI_GRP1r(unit, &rval1));
  20087    }
  20088    *reg0 = rval;
  20089    *reg1 = rval1;
  20090    return BCM_E_NONE;
  20091 }
  20092 
  20093 STATIC int
  20094 _bcm_kt2_set_pg_profile_mapping(int unit, int profile_index,
  20095                                 uint32 reg0, uint32 reg1)
  20096 {
  20097 
  20098     if (profile_index < 0 || profile_index > 3) {
  20099         return BCM_E_PARAM;
  20100     }
  20101     if (profile_index == 0) {
  20102         SOC_IF_ERROR_RETURN
  20103                 (WRITE_MMU_ENQ_PROFILE_0_PRI_GRP0r(unit, reg0));
  20104         SOC_IF_ERROR_RETURN
  20105                 (WRITE_MMU_ENQ_PROFILE_0_PRI_GRP1r(unit, reg1));
  20106     } else if (profile_index == 1) {
  20107         SOC_IF_ERROR_RETURN
  20108                 (WRITE_MMU_ENQ_PROFILE_1_PRI_GRP0r(unit, reg0));
  20109         SOC_IF_ERROR_RETURN
  20110                 (WRITE_MMU_ENQ_PROFILE_1_PRI_GRP1r(unit, reg1));
  20111     } else if (profile_index == 2) {
  20112         SOC_IF_ERROR_RETURN
  20113                 (WRITE_MMU_ENQ_PROFILE_2_PRI_GRP0r(unit, reg0));
  20114         SOC_IF_ERROR_RETURN
  20115                 (WRITE_MMU_ENQ_PROFILE_2_PRI_GRP1r(unit, reg1));
  20116     } else {
  20117         SOC_IF_ERROR_RETURN
  20118                 (WRITE_MMU_ENQ_PROFILE_3_PRI_GRP0r(unit, reg0));
  20119         SOC_IF_ERROR_RETURN
  20120                 (WRITE_MMU_ENQ_PROFILE_3_PRI_GRP1r(unit, reg1));
  20121    }
  20122    return BCM_E_NONE;
  20123 }
  20124 
  20125 STATIC int
  20126 _bcm_kt2_get_port_profile_index(int unit, bcm_port_t port, int *p_index)
  20127 {
  20128     uint64 rval64;
  20129     soc_field_t sb2_pri_to_prigrp_field[SB2_MAX_LOGICAL_PORTS]={
  20130             SRCPORT_0f,
  20131             SRCPORT_1f,  SRCPORT_2f,  SRCPORT_3f,  SRCPORT_4f,
  20132             SRCPORT_5f,  SRCPORT_6f,  SRCPORT_7f,  SRCPORT_8f,
  20133             SRCPORT_9f,  SRCPORT_10f, SRCPORT_11f, SRCPORT_12f,
  20134             SRCPORT_13f, SRCPORT_14f, SRCPORT_15f, SRCPORT_16f,
  20135             SRCPORT_17f, SRCPORT_18f, SRCPORT_19f, SRCPORT_20f,
  20136             SRCPORT_21f, SRCPORT_22f, SRCPORT_23f, SRCPORT_24f,
  20137             SRCPORT_25f, SRCPORT_26f, SRCPORT_27f, SRCPORT_28f,
  20138             SRCPORT_29f
  20139             };
  20140     if(SOC_IS_SABER2(unit))  {
  20141        SOC_IF_ERROR_RETURN(
  20142            READ_MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r(unit, &rval64));
  20143        if (soc_reg_field_valid(unit, MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r,
  20144                                sb2_pri_to_prigrp_field[port])) {
  20145            *p_index = soc_reg64_field32_get(unit,
  20146                                             MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r,
  20147                                             rval64,
  20148                                             sb2_pri_to_prigrp_field[port]);
  20149             return BCM_E_NONE;
  20150        }
  20151     }
  20152     return BCM_E_PARAM;
  20153 }
  20154 STATIC int
  20155 _bcm_kt2_config_all_pg_profile_register(int unit, bcm_port_t port)
  20156 {
  20157     int  profile_index;
  20158     uint32 reg0, reg1;
  20159     uint64 rval64;
  20160 
  20161     BCM_IF_ERROR_RETURN(_bcm_kt2_get_port_profile_index(unit, port, &profile_index));
  20162     BCM_IF_ERROR_RETURN(_bcm_kt2_get_pg_profile_mapping(unit, profile_index,
  20163                                                         &reg0, &reg1));
  20164     if (profile_index < 0 || profile_index > 3) {
  20165         return BCM_E_PARAM;
  20166     }
  20167     if (profile_index == 0) {
  20168         SOC_IF_ERROR_RETURN
  20169                 (WRITE_PROFILE0_PRI_GRP0r(unit, reg0));
  20170         SOC_IF_ERROR_RETURN
  20171                 (WRITE_PROFILE0_PRI_GRP1r(unit, reg1));
  20172         if (SOC_REG_IS_VALID(unit, THDIEXT_PROFILE0_PRI_GRP0r)) { 
  20173             SOC_IF_ERROR_RETURN
  20174                     (WRITE_THDIEXT_PROFILE0_PRI_GRP0r(unit, reg0));
  20175         }
  20176         if (SOC_REG_IS_VALID(unit, THDIEXT_PROFILE0_PRI_GRP1r)) {
  20177             SOC_IF_ERROR_RETURN
  20178                     (WRITE_THDIEXT_PROFILE0_PRI_GRP1r(unit, reg1));
  20179         }
  20180         if (SOC_REG_IS_VALID(unit, THDIEMA_PROFILE0_PRI_GRP0r)) {
  20181             SOC_IF_ERROR_RETURN
  20182                     (WRITE_THDIEMA_PROFILE0_PRI_GRP0r(unit, reg0));
  20183         }
  20184         if (SOC_REG_IS_VALID(unit, THDIEMA_PROFILE0_PRI_GRP1r)) {
  20185             SOC_IF_ERROR_RETURN
  20186                     (WRITE_THDIEMA_PROFILE0_PRI_GRP1r(unit, reg1));
  20187         }
  20188         SOC_IF_ERROR_RETURN
  20189                 (WRITE_THDIRQE_PROFILE0_PRI_GRP0r(unit, reg0));
  20190         SOC_IF_ERROR_RETURN
  20191                 (WRITE_THDIRQE_PROFILE0_PRI_GRP1r(unit, reg1));
  20192         SOC_IF_ERROR_RETURN
  20193                 (WRITE_THDIQEN_PROFILE0_PRI_GRP0r(unit, reg0));
  20194         SOC_IF_ERROR_RETURN
  20195                 (WRITE_THDIQEN_PROFILE0_PRI_GRP1r(unit, reg1));
  20196 
  20197     } else if (profile_index == 1) {
  20198         SOC_IF_ERROR_RETURN
  20199                 (WRITE_PROFILE1_PRI_GRP0r(unit, reg0));
  20200         SOC_IF_ERROR_RETURN
  20201                 (WRITE_PROFILE1_PRI_GRP1r(unit, reg1));
  20202         if (SOC_REG_IS_VALID(unit, THDIEXT_PROFILE1_PRI_GRP0r)) {
  20203             SOC_IF_ERROR_RETURN
  20204                     (WRITE_THDIEXT_PROFILE1_PRI_GRP0r(unit, reg0));
  20205         }
  20206         if (SOC_REG_IS_VALID(unit, THDIEXT_PROFILE1_PRI_GRP1r)) {
  20207             SOC_IF_ERROR_RETURN
  20208                     (WRITE_THDIEXT_PROFILE1_PRI_GRP1r(unit, reg1));
  20209         }
  20210         if (SOC_REG_IS_VALID(unit, THDIEMA_PROFILE1_PRI_GRP0r)) {
  20211             SOC_IF_ERROR_RETURN
  20212                     (WRITE_THDIEMA_PROFILE1_PRI_GRP0r(unit, reg0));
  20213         }
  20214         if (SOC_REG_IS_VALID(unit, THDIEMA_PROFILE1_PRI_GRP1r)) {
  20215             SOC_IF_ERROR_RETURN
  20216                     (WRITE_THDIEMA_PROFILE1_PRI_GRP1r(unit, reg1));
  20217         } 
  20218         SOC_IF_ERROR_RETURN
  20219                 (WRITE_THDIRQE_PROFILE1_PRI_GRP0r(unit, reg0));
  20220         SOC_IF_ERROR_RETURN
  20221                 (WRITE_THDIRQE_PROFILE1_PRI_GRP1r(unit, reg1));
  20222         SOC_IF_ERROR_RETURN
  20223                 (WRITE_THDIQEN_PROFILE1_PRI_GRP0r(unit, reg0));
  20224         SOC_IF_ERROR_RETURN
  20225                 (WRITE_THDIQEN_PROFILE1_PRI_GRP1r(unit, reg1));
  20226     } else if (profile_index == 2) {
  20227         SOC_IF_ERROR_RETURN
  20228                 (WRITE_PROFILE2_PRI_GRP0r(unit, reg0));
  20229         SOC_IF_ERROR_RETURN
  20230                 (WRITE_PROFILE2_PRI_GRP1r(unit, reg1));
  20231         if (SOC_REG_IS_VALID(unit, THDIEXT_PROFILE2_PRI_GRP0r)) {
  20232             SOC_IF_ERROR_RETURN
  20233                     (WRITE_THDIEXT_PROFILE2_PRI_GRP0r(unit, reg0));
  20234         }
  20235         if (SOC_REG_IS_VALID(unit, THDIEXT_PROFILE2_PRI_GRP1r)) {
  20236             SOC_IF_ERROR_RETURN
  20237                     (WRITE_THDIEXT_PROFILE2_PRI_GRP1r(unit, reg1));
  20238         }
  20239         if (SOC_REG_IS_VALID(unit, THDIEMA_PROFILE2_PRI_GRP0r)) {
  20240             SOC_IF_ERROR_RETURN
  20241                     (WRITE_THDIEMA_PROFILE2_PRI_GRP0r(unit, reg0));
  20242         }
  20243         if (SOC_REG_IS_VALID(unit, THDIEMA_PROFILE2_PRI_GRP1r)) {
  20244             SOC_IF_ERROR_RETURN
  20245                     (WRITE_THDIEMA_PROFILE2_PRI_GRP1r(unit, reg1));
  20246         }
  20247         SOC_IF_ERROR_RETURN
  20248                 (WRITE_THDIRQE_PROFILE2_PRI_GRP0r(unit, reg0));
  20249         SOC_IF_ERROR_RETURN
  20250                 (WRITE_THDIRQE_PROFILE2_PRI_GRP1r(unit, reg1));
  20251         SOC_IF_ERROR_RETURN
  20252                 (WRITE_THDIQEN_PROFILE2_PRI_GRP0r(unit, reg0));
  20253         SOC_IF_ERROR_RETURN
  20254                 (WRITE_THDIQEN_PROFILE2_PRI_GRP1r(unit, reg1));
  20255     } else {
  20256         SOC_IF_ERROR_RETURN
  20257                 (WRITE_PROFILE3_PRI_GRP0r(unit, reg0));
  20258         SOC_IF_ERROR_RETURN
  20259                 (WRITE_PROFILE3_PRI_GRP1r(unit, reg1));
  20260         if (SOC_REG_IS_VALID(unit, THDIEXT_PROFILE3_PRI_GRP0r)) {
  20261             SOC_IF_ERROR_RETURN
  20262                     (WRITE_THDIEXT_PROFILE3_PRI_GRP0r(unit, reg0));
  20263         }
  20264         if (SOC_REG_IS_VALID(unit, THDIEXT_PROFILE3_PRI_GRP1r)) {
  20265             SOC_IF_ERROR_RETURN
  20266                     (WRITE_THDIEXT_PROFILE3_PRI_GRP1r(unit, reg1));
  20267         }
  20268         if (SOC_REG_IS_VALID(unit, THDIEMA_PROFILE3_PRI_GRP0r)) {
  20269             SOC_IF_ERROR_RETURN
  20270                     (WRITE_THDIEMA_PROFILE3_PRI_GRP0r(unit, reg0));
  20271         }
  20272         if (SOC_REG_IS_VALID(unit, THDIEMA_PROFILE3_PRI_GRP1r)) {
  20273             SOC_IF_ERROR_RETURN
  20274                     (WRITE_THDIEMA_PROFILE3_PRI_GRP1r(unit, reg1));
  20275         } 
  20276         SOC_IF_ERROR_RETURN
  20277                 (WRITE_THDIRQE_PROFILE3_PRI_GRP0r(unit, reg0));
  20278         SOC_IF_ERROR_RETURN
  20279                 (WRITE_THDIRQE_PROFILE3_PRI_GRP1r(unit, reg1));
  20280         SOC_IF_ERROR_RETURN
  20281                 (WRITE_THDIQEN_PROFILE3_PRI_GRP0r(unit, reg0));
  20282         SOC_IF_ERROR_RETURN
  20283                 (WRITE_THDIQEN_PROFILE3_PRI_GRP1r(unit, reg1));
  20284     }
  20285     SOC_IF_ERROR_RETURN(
  20286             READ_MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r(unit, &rval64));
  20287 
  20288     SOC_IF_ERROR_RETURN(
  20289          WRITE_PORT_PROFILE_MAPr(unit, rval64));
  20290     if (SOC_REG_IS_VALID(unit, THDIEXT_PORT_PROFILE_MAPr)) {
  20291         SOC_IF_ERROR_RETURN(
  20292             WRITE_THDIEXT_PORT_PROFILE_MAPr(unit, rval64));
  20293     }
  20294     if (SOC_REG_IS_VALID(unit, THDIEMA_PORT_PROFILE_MAPr)) {
  20295         SOC_IF_ERROR_RETURN(
  20296             WRITE_THDIEMA_PORT_PROFILE_MAPr(unit, rval64));
  20297     }
  20298     SOC_IF_ERROR_RETURN(
  20299          WRITE_THDIRQE_PORT_PROFILE_MAPr(unit, rval64));
  20300     SOC_IF_ERROR_RETURN(
  20301          WRITE_THDIQEN_PORT_PROFILE_MAPr(unit, rval64));
  20302     return BCM_E_NONE;
  20303 }
  20304 
  20305 STATIC int
  20306 _bcm_kt2_check_port_pg_status(int unit, int port, int new_pg, int old_pg)
  20307 {
  20308     uint32    new_mem_idx, old_mem_idx;
  20309     thdi_port_pg_cntrs_entry_t thdi_port_pg_cntrs={{0}};
  20310     thdiext_thdi_port_pg_cntrs_entry_t thdiext_thdi_port_pg_cntrs={{0}};
  20311     thdiema_thdi_port_pg_cntrs_entry_t thdiema_thdi_port_pg_cntrs={{0}};
  20312     thdirqe_thdi_port_pg_cntrs_entry_t thdirqe_thdi_port_pg_cntrs={{0}};
  20313     thdiqen_thdi_port_pg_cntrs_entry_t thdiqen_thdi_port_pg_cntrs = {{0}};
  20314     
  20315     new_mem_idx= (port * SB2_MAX_PRIORITY_GROUPS) + new_pg;
  20316     old_mem_idx= (port * SB2_MAX_PRIORITY_GROUPS) + old_pg;
  20317 
  20318     /* Checm if pg min count is zero or not */
  20319     SOC_IF_ERROR_RETURN (soc_mem_read(
  20320                     unit, THDI_PORT_PG_CNTRSm, MEM_BLOCK_ALL,
  20321                     new_mem_idx, &thdi_port_pg_cntrs));
  20322     if (soc_mem_field32_get(unit, THDI_PORT_PG_CNTRSm,
  20323                 &thdi_port_pg_cntrs, PG_MIN_COUNTf)) {
  20324         return BCM_E_BUSY;
  20325     }
  20326     SOC_IF_ERROR_RETURN (soc_mem_read(
  20327                     unit, THDI_PORT_PG_CNTRSm, MEM_BLOCK_ALL,
  20328                     old_mem_idx, &thdi_port_pg_cntrs));
  20329     if (soc_mem_field32_get(unit, THDI_PORT_PG_CNTRSm,
  20330                 &thdi_port_pg_cntrs, PG_MIN_COUNTf)) {
  20331         return BCM_E_BUSY;
  20332     }
  20333     if (SOC_MEM_IS_VALID(unit, THDIEXT_THDI_PORT_PG_CNTRSm)) {
  20334         SOC_IF_ERROR_RETURN (soc_mem_read(
  20335                     unit, THDIEXT_THDI_PORT_PG_CNTRSm, MEM_BLOCK_ALL,
  20336                     new_mem_idx, &thdiext_thdi_port_pg_cntrs));
  20337         if (soc_mem_field32_get(unit, THDIEXT_THDI_PORT_PG_CNTRSm,
  20338                     &thdiext_thdi_port_pg_cntrs, PG_MIN_COUNTf)) {
  20339             return BCM_E_BUSY;
  20340         }
  20341         SOC_IF_ERROR_RETURN (soc_mem_read(
  20342                     unit, THDIEXT_THDI_PORT_PG_CNTRSm, MEM_BLOCK_ALL,
  20343                     old_mem_idx, &thdiext_thdi_port_pg_cntrs));
  20344         if (soc_mem_field32_get(unit, THDIEXT_THDI_PORT_PG_CNTRSm,
  20345                     &thdiext_thdi_port_pg_cntrs, PG_MIN_COUNTf)) {
  20346             return BCM_E_BUSY;
  20347         }
  20348     }
  20349     if (SOC_MEM_IS_VALID(unit, THDIEMA_THDI_PORT_PG_CNTRSm)) { 
  20350         SOC_IF_ERROR_RETURN (soc_mem_read(
  20351                     unit, THDIEMA_THDI_PORT_PG_CNTRSm, MEM_BLOCK_ALL,
  20352                     new_mem_idx, &thdiema_thdi_port_pg_cntrs));
  20353         if (soc_mem_field32_get(unit, THDIEMA_THDI_PORT_PG_CNTRSm,
  20354                     &thdiema_thdi_port_pg_cntrs, PG_MIN_COUNTf)) {
  20355             return BCM_E_BUSY;
  20356         }
  20357         SOC_IF_ERROR_RETURN (soc_mem_read(
  20358                     unit, THDIEMA_THDI_PORT_PG_CNTRSm, MEM_BLOCK_ALL,
  20359                     old_mem_idx, &thdiema_thdi_port_pg_cntrs));
  20360         if (soc_mem_field32_get(unit, THDIEMA_THDI_PORT_PG_CNTRSm,
  20361                     &thdiema_thdi_port_pg_cntrs, PG_MIN_COUNTf)) {
  20362             return BCM_E_BUSY;
  20363         }
  20364     } 
  20365     SOC_IF_ERROR_RETURN (soc_mem_read(
  20366                     unit, THDIRQE_THDI_PORT_PG_CNTRSm, MEM_BLOCK_ALL,
  20367                     new_mem_idx, &thdirqe_thdi_port_pg_cntrs));
  20368     if (soc_mem_field32_get(unit, THDIRQE_THDI_PORT_PG_CNTRSm,
  20369                 &thdirqe_thdi_port_pg_cntrs, PG_MIN_COUNTf)) {
  20370         return BCM_E_BUSY;
  20371     }
  20372     SOC_IF_ERROR_RETURN (soc_mem_read(
  20373                     unit, THDIRQE_THDI_PORT_PG_CNTRSm, MEM_BLOCK_ALL,
  20374                     old_mem_idx, &thdirqe_thdi_port_pg_cntrs));
  20375     if (soc_mem_field32_get(unit, THDIRQE_THDI_PORT_PG_CNTRSm,
  20376                 &thdirqe_thdi_port_pg_cntrs, PG_MIN_COUNTf)) {
  20377         return BCM_E_BUSY;
  20378     }
  20379 
  20380     SOC_IF_ERROR_RETURN (soc_mem_read(
  20381                     unit, THDIQEN_THDI_PORT_PG_CNTRSm, MEM_BLOCK_ALL,
  20382                     new_mem_idx, &thdiqen_thdi_port_pg_cntrs));
  20383     if (soc_mem_field32_get(unit, THDIQEN_THDI_PORT_PG_CNTRSm,
  20384                 &thdiqen_thdi_port_pg_cntrs, PG_MIN_COUNTf)) {
  20385         return BCM_E_BUSY;
  20386     }
  20387     SOC_IF_ERROR_RETURN (soc_mem_read(
  20388                     unit, THDIQEN_THDI_PORT_PG_CNTRSm, MEM_BLOCK_ALL,
  20389                     old_mem_idx, &thdiqen_thdi_port_pg_cntrs));
  20390     if (soc_mem_field32_get(unit, THDIQEN_THDI_PORT_PG_CNTRSm,
  20391                 &thdiqen_thdi_port_pg_cntrs, PG_MIN_COUNTf)) {
  20392         return BCM_E_BUSY;
  20393     }
  20394 
  20395     return BCM_E_NONE;
  20396 }
  20397 /*
  20398  * Function:
  20399  *      bcm_kt2_port_priority_group_mapping_set
  20400  * Purpose:
  20401  *      Assign a Priority Group for the input priority.
  20402  * Parameters:
  20403  *      unit       - (IN) device id.
  20404  *      gport      - (IN) generic port.
  20405  *      prio       - (IN) input priority.
  20406  *      priority_group  - (IN) priority group ID that the input priority mapped to.
  20407  * Returns:
  20408  *      BCM_E_XXX
  20409  */
  20410 int
  20411 bcm_kt2_port_priority_group_mapping_set(int unit, bcm_gport_t gport,
  20412                                         int prio, int priority_group)
  20413 {
  20414     bcm_port_t port;
  20415     uint32 old_reg0, old_reg1, new_reg0, new_reg1, temp = 0x7;
  20416     int old_profile_index, new_profile_index, free_profile_index = -1;
  20417     uint64 rval64;
  20418     int old_pg = 0x7, new_pg = priority_group;
  20419     soc_field_t sb2_srcport_field_names[SB2_MAX_LOGICAL_PORTS]={
  20420             SRCPORT_0f,
  20421             SRCPORT_1f,  SRCPORT_2f,  SRCPORT_3f,  SRCPORT_4f,
  20422             SRCPORT_5f,  SRCPORT_6f,  SRCPORT_7f,  SRCPORT_8f,
  20423             SRCPORT_9f,  SRCPORT_10f, SRCPORT_11f, SRCPORT_12f,
  20424             SRCPORT_13f, SRCPORT_14f, SRCPORT_15f, SRCPORT_16f,
  20425             SRCPORT_17f, SRCPORT_18f, SRCPORT_19f, SRCPORT_20f,
  20426             SRCPORT_21f, SRCPORT_22f, SRCPORT_23f, SRCPORT_24f,
  20427             SRCPORT_25f, SRCPORT_26f, SRCPORT_27f, SRCPORT_28f,
  20428             SRCPORT_29f
  20429             };
  20430 
  20431     /* PFC : 0-7, SAFC : 0-15. Taking the larger range for comparison */
  20432     if ((prio < KT2_SAFC_INPUT_PRIORITY_MIN) ||
  20433         (prio > KT2_SAFC_INPUT_PRIORITY_MAX)) {
  20434          return BCM_E_PARAM;
  20435     }
  20436 
  20437     if ((priority_group < KT2_PRIOROTY_GROUP_ID_MIN) ||
  20438         (priority_group > KT2_PRIOROTY_GROUP_ID_MAX)) {
  20439         return BCM_E_PARAM;
  20440     }
  20441 
  20442     BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_localport_resolve(unit, gport, &port));
  20443     if ((SB2_MAX_PHYSICAL_PORTS <= port) ||
  20444         !_bcm_kt2_port_pfc_supported(unit, port)) {
  20445         return BCM_E_PORT;
  20446     }
  20447     /* Get the profile index and correponding profile for the port */
  20448     BCM_IF_ERROR_RETURN(_bcm_kt2_get_port_profile_index(unit, port, &old_profile_index));
  20449     BCM_IF_ERROR_RETURN(_bcm_kt2_get_pg_profile_mapping(unit, old_profile_index,
  20450                                                          &old_reg0, &old_reg1));
  20451     if (prio < 8) {
  20452         old_pg = ((old_pg << (prio * 3)) & old_reg0) >> (prio * 3);
  20453     } else {
  20454         old_pg = ((old_pg << ((prio - 8) * 3)) & old_reg1) >> ((prio - 8) * 3);
  20455     }
  20456     if (pg_profile_refcount[unit][old_profile_index] == 1) {
  20457         free_profile_index = old_profile_index;
  20458     }
  20459     if (prio < 8) {
  20460         temp = temp << (prio * 3);
  20461         temp = ~temp;
  20462         temp = old_reg0 & temp;
  20463         temp = temp | (priority_group << (prio * 3));
  20464         for (new_profile_index = 0; new_profile_index < 4; new_profile_index ++) {
  20465              if (pg_profile_refcount[unit][new_profile_index] != 0) {
  20466                  BCM_IF_ERROR_RETURN(_bcm_kt2_get_pg_profile_mapping(unit,
  20467                                                             new_profile_index,
  20468                                                             &new_reg0, &new_reg1));
  20469                  if ((new_reg0 == temp) && (new_reg1 == old_reg1)) {
  20470                       break;
  20471                  }
  20472              } else {
  20473                  if (free_profile_index == -1) {
  20474                      free_profile_index = new_profile_index;
  20475                  }
  20476              }
  20477         }
  20478         if ((new_profile_index == 4) && (free_profile_index == -1)) {
  20479              return BCM_E_RESOURCE;
  20480         }
  20481     } else {
  20482         temp = temp << ((prio - 8) * 3);
  20483         temp = ~temp;
  20484         temp = old_reg1 & temp;
  20485         temp = temp | (priority_group << ((prio - 8) * 3));
  20486         for (new_profile_index = 0; new_profile_index < 4; new_profile_index ++) {
  20487              if (pg_profile_refcount[unit][new_profile_index] != 0) {
  20488                  BCM_IF_ERROR_RETURN(_bcm_kt2_get_pg_profile_mapping(unit,
  20489                                                             new_profile_index,
  20490                                                             &new_reg0, &new_reg1));
  20491                  if ((new_reg1 == temp) && (new_reg0 == old_reg0)) {
  20492                      break;
  20493                  }
  20494              } else {
  20495                  if (free_profile_index == -1) {
  20496                      free_profile_index = new_profile_index;
  20497                  }
  20498              }
  20499          }
  20500          if ((new_profile_index == 4) && (free_profile_index == -1)) {
  20501              return BCM_E_RESOURCE;
  20502          }
  20503 
  20504     }
  20505     /* We reached here either because of an existing profile match or a free profile */
  20506     if (new_profile_index == 4) {
  20507         new_profile_index = free_profile_index;
  20508         if (prio < 8) {
  20509             new_reg0 = temp;
  20510             new_reg1 = old_reg1;
  20511         } else {
  20512             new_reg0 = old_reg0;
  20513             new_reg1 = temp;
  20514         }
  20515     }
  20516     /*
  20517      * For dynamic configuration we need to check status of pgs before 
  20518      * updating it. 
  20519      */
  20520     BCM_IF_ERROR_RETURN(_bcm_kt2_check_port_pg_status(unit, port, new_pg, old_pg));
  20521 
  20522     SOC_IF_ERROR_RETURN(
  20523             READ_MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r(unit, &rval64));
  20524     BCM_IF_ERROR_RETURN(_bcm_kt2_set_pg_profile_mapping(unit, new_profile_index,
  20525                                                         new_reg0, new_reg1));
  20526     if (soc_reg_field_valid(unit, MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r,
  20527                              sb2_srcport_field_names[port])) {
  20528         soc_reg64_field32_set(unit, MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r,
  20529                           &rval64, sb2_srcport_field_names[port],
  20530                           new_profile_index);
  20531     }
  20532     SOC_IF_ERROR_RETURN(
  20533          WRITE_MMU_ENQ_IP_PRI_TO_PG_PROFILE_0r(unit, rval64));
  20534 
  20535     BCM_IF_ERROR_RETURN(
  20536             _bcm_kt2_config_all_pg_profile_register(unit, port));
  20537     /* Now update refcount */
  20538     pg_profile_refcount[unit][old_profile_index] = pg_profile_refcount[unit][old_profile_index] - 1;
  20539     pg_profile_refcount[unit][new_profile_index] = pg_profile_refcount[unit][new_profile_index] + 1;
  20540 
  20541     return BCM_E_NONE;
  20542 }
  20543 
  20544 /*
  20545  * Function:
  20546  *      bcm_kt2_port_priority_group_mapping_get
  20547  * Purpose:
  20548  *      Return Priority Group for the input priority.
  20549  * Parameters:
  20550  *      unit       - (IN) device id.
  20551  *      gport      - (IN) generic port.
  20552  *      prio       - (IN) input priority.
  20553  *      priority_group  - (OUT) priority group ID that the input priority mapped to.
  20554  * Returns:
  20555  *      BCM_E_XXX
  20556  */
  20557 int
  20558 bcm_kt2_port_priority_group_mapping_get(int unit, bcm_gport_t gport,
  20559                                         int prio, int *priority_group)
  20560 {
  20561     bcm_port_t port;
  20562     uint32 reg0, reg1,temp = 0x7;
  20563     int profile_index;
  20564 
  20565     /* PFC : 0-7, SAFC : 0-15. Taking the larger range for comparison */
  20566     if ((prio < KT2_SAFC_INPUT_PRIORITY_MIN) ||
  20567         (prio > KT2_SAFC_INPUT_PRIORITY_MAX)) {
  20568          return BCM_E_PARAM;
  20569     }
  20570 
  20571     if (priority_group == NULL) {
  20572         return BCM_E_PARAM;
  20573     }
  20574 
  20575     BCM_IF_ERROR_RETURN(_bcm_kt2_cosq_localport_resolve(unit, gport, &port));
  20576     if ((SB2_MAX_PHYSICAL_PORTS <= port) ||
  20577         !_bcm_kt2_port_pfc_supported(unit, port)) {
  20578         return BCM_E_PORT;
  20579     }
  20580     /* Get the profile index and correponding profile for the port */
  20581     BCM_IF_ERROR_RETURN(_bcm_kt2_get_port_profile_index(unit, port, &profile_index));
  20582     BCM_IF_ERROR_RETURN(_bcm_kt2_get_pg_profile_mapping(unit, profile_index,
  20583                                                         &reg0, &reg1));
  20584     if (prio < 8) {
  20585         temp = temp << (prio * 3);
  20586         temp = reg0 & temp;
  20587         temp = temp >> (prio * 3);
  20588         *priority_group = temp;
  20589     } else {
  20590         temp = temp << ((prio - 8) * 3);
  20591         temp = reg1 & temp;
  20592         temp = temp >> ((prio - 8) * 3);
  20593     }
  20594     *priority_group = temp;
  20595     return BCM_E_NONE;
  20596 }
  20597 #endif
  20598 
  20599 STATIC int
  20600 _bcm_kt2_dump_config(int unit, bcm_port_t port,
  20601                        _bcm_kt2_cosq_node_t *node)
  20602 {
  20603     int num_spri, first_child, first_mc_child;
  20604     uint32 spmap, ucmap;
  20605     soc_kt2_sched_mode_e sched_mode = SOC_KT2_SCHED_MODE_UNKNOWN;
  20606     int wt = 0;
  20607     char *lvl_name[] = { "Root", "S0", "S1", "L0", "L1", "L2" };
  20608     char *sched_modes[] = {"X", "SP", "WRR", "WDRR"};
  20609     int subport = 0;
  20610     uint32 entry[SOC_MAX_MEM_WORDS];
  20611     soc_info_t *si;
  20612     int physical_port;
  20613     bcm_gport_t pp_port;
  20614     _bcm_kt2_subport_info_t info;
  20615     soc_kt2_sched_mode_e mode = 0;
  20616     int rv = BCM_E_NONE;
  20617     int soc_node_level = node->level;
  20618     int is_mc_queue;
  20619 
  20620     si = &SOC_INFO(unit);
  20621     if ((!(SOC_PBMP_MEMBER(si->linkphy_pbm, port))) &&
  20622                 (node->level != _BCM_KT2_COSQ_NODE_LEVEL_ROOT)) {
  20623         /* KT2 soc level does not include S0 and S1 */
  20624         soc_node_level = soc_node_level - 2; 
  20625     }
  20626 
  20627     /* get sched config */
  20628     if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_L2) {
  20629        SOC_IF_ERROR_RETURN(
  20630             soc_kt2_sched_get_node_config(unit, port,
  20631                         soc_node_level, node->hw_index,
  20632                         &num_spri, &first_child,
  20633                         &first_mc_child, &ucmap, &spmap));
  20634 
  20635     }
  20636     sched_mode = 0;
  20637     if (node->level != _BCM_KT2_COSQ_NODE_LEVEL_ROOT) {
  20638         SOC_IF_ERROR_RETURN(
  20639          soc_kt2_cosq_get_sched_mode(unit, port, soc_node_level,
  20640                                 node->hw_index, &sched_mode, &wt));
  20641     }
  20642 
  20643     if (wt && SOC_PBMP_MEMBER(si->linkphy_pbm, port)) {
  20644 
  20645         /* Re-write the node info if num_streams is 1 */
  20646         if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
  20647                 BCM_IF_ERROR_RETURN
  20648                   (_bcm_kt2_cosq_subport_get(unit, node->gport, &pp_port));
  20649                 BCM_IF_ERROR_RETURN
  20650                    (bcm_kt2_subport_pp_port_subport_info_get(unit, pp_port,
  20651                                                 &info));
  20652             if (info.num_streams == 1) {
  20653                 first_child = node->hw_index;
  20654                 num_spri = 1;
  20655                 spmap = 1;
  20656                 rv = soc_kt2_cosq_s0_sched_get(unit, node->hw_index, &mode);
  20657                 if (rv == BCM_E_NONE) {
  20658                     num_spri = (mode == SOC_KT2_SCHED_MODE_STRICT) ? 1 : 0;
  20659                     spmap = (mode == SOC_KT2_SCHED_MODE_STRICT) ? 1 : 0;
  20660                 }
  20661 
  20662 #ifdef BCM_METROLITE_SUPPORT
  20663                 if(SOC_IS_METROLITE(unit))  {
  20664                    first_child = node->first_child;
  20665                 }
  20666 #endif 
  20667             } else {
  20668                 rv = soc_kt2_cosq_s0_sched_get(unit, node->hw_index, &mode);
  20669                 if (rv == BCM_E_NONE) {
  20670                     num_spri = (mode == SOC_KT2_SCHED_MODE_STRICT) ? 2 : 0;
  20671                     spmap = (mode == SOC_KT2_SCHED_MODE_STRICT) ? 3 : 0;
  20672                 }
  20673             }
  20674         }
  20675 
  20676         if (_bcm_is_port_linkphy_subport(unit, port, -1)) {
  20677             SOC_IF_ERROR_RETURN(_bcm_subport_physical_port_get(unit, port, &physical_port));
  20678 
  20679             SOC_IF_ERROR_RETURN(
  20680                 soc_mem_read(unit, LLS_PORT_CONFIGm, MEM_BLOCK_ALL, physical_port, &entry));
  20681             if (soc_mem_field32_get(unit, LLS_PORT_CONFIGm, entry, PACKET_MODE_WRR_ACCOUNTING_ENABLEf)) {
  20682                 sched_mode = SOC_KT2_SCHED_MODE_WRR;
  20683             } else {
  20684                 sched_mode = SOC_KT2_SCHED_MODE_WDRR;
  20685             }
  20686         }
  20687     }
  20688     switch (node->level) {
  20689         case _BCM_KT2_COSQ_NODE_LEVEL_ROOT:
  20690         case _BCM_KT2_COSQ_NODE_LEVEL_S1:
  20691         case _BCM_KT2_COSQ_NODE_LEVEL_L0:
  20692         case _BCM_KT2_COSQ_NODE_LEVEL_L1:
  20693                  LOG_CLI((BSL_META_U(unit,
  20694                             "  %s.%d : INDEX=%d NUM_SP=%d FC=%d FMC=%d "
  20695                             "UCMAP=0x%08x SPMAP=0x%08x MODE=%s WT=%d\n"),
  20696                  lvl_name[node->level], node->cosq_attached_to,
  20697                  node->hw_index, num_spri,
  20698                  first_child, first_mc_child, ucmap, spmap,
  20699                  sched_modes[sched_mode], wt));
  20700         break;
  20701         case _BCM_KT2_COSQ_NODE_LEVEL_S0:
  20702                 BCM_IF_ERROR_RETURN
  20703                   (_bcm_kt2_cosq_subport_get(unit, node->gport, &subport));
  20704                 LOG_CLI((BSL_META_U(unit,
  20705                 "-------%s subport %d (LLS)------\n"),SOC_PORT_NAME(unit,
  20706                                                       (port)), subport));
  20707                  LOG_CLI((BSL_META_U(unit,
  20708                             "  %s.%d : INDEX=%d NUM_SP=%d FC=%d FMC=%d "
  20709                             "UCMAP=0x%08x SPMAP=0x%08x MODE=%s WT=%d\n"),
  20710                  lvl_name[node->level], node->cosq_attached_to,
  20711                  node->hw_index, num_spri,
  20712                  first_child, first_mc_child, ucmap, spmap,
  20713                  sched_modes[sched_mode], wt));
  20714         break;
  20715         case _BCM_KT2_COSQ_NODE_LEVEL_L2:
  20716                 is_mc_queue = BCM_GPORT_IS_MCAST_QUEUE_GROUP(node->gport) ||
  20717                     BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(node->gport);
  20718                 LOG_CLI((BSL_META_U(unit,
  20719                               "     L2.%d.%s INDEX=%d Mode=%s WEIGHT=%d\n"),
  20720                                    node->cosq_attached_to,
  20721                                    is_mc_queue?"mc":"uc",
  20722                                    node->hw_index,
  20723                                    sched_modes[sched_mode], wt));
  20724         break;
  20725         default:
  20726              return BCM_E_INTERNAL;
  20727 
  20728     }
  20729     return BCM_E_NONE;
  20730 }
  20731 
  20732 STATIC int
  20733 _bcm_kt2_dump_sched(int unit, bcm_port_t port, bcm_gport_t gport)
  20734 {
  20735     _bcm_kt2_cosq_node_t *node;
  20736     _bcm_kt2_cosq_node_t *cur_node;
  20737     int i = 0;
  20738     int start_cos = 0;
  20739     int end_cos = 0;
  20740 
  20741     BCM_IF_ERROR_RETURN
  20742         (_bcm_kt2_cosq_node_get(unit, gport, NULL, NULL, NULL, &node));
  20743 
  20744     if (node != NULL) {
  20745         if (node->level == _BCM_KT2_COSQ_NODE_LEVEL_L2) {
  20746             return BCM_E_INTERNAL;
  20747         }
  20748 
  20749         start_cos = 0;
  20750         end_cos = node->numq;
  20751         _bcm_kt2_dump_config(unit, port, node);
  20752 
  20753         for (i = start_cos; i < end_cos; i++)
  20754         {
  20755             if(_bcm_kt2_cosq_child_node_at_input(node, i, &cur_node)
  20756                        == BCM_E_NOT_FOUND) {
  20757                 continue;
  20758             }
  20759             if (cur_node->level == _BCM_KT2_COSQ_NODE_LEVEL_L2) {
  20760                  BCM_IF_ERROR_RETURN
  20761                    (_bcm_kt2_dump_config(unit, port, cur_node));
  20762             } else {
  20763                 BCM_IF_ERROR_RETURN
  20764                    (_bcm_kt2_dump_sched(unit, port, cur_node->gport));
  20765             }
  20766         }
  20767     }
  20768     return BCM_E_NONE;
  20769 
  20770 }
  20771 
  20772 STATIC int
  20773 _bcm_kt2_cosq_cpu_fc_set(int unit) 
  20774 {
  20775     bcm_pbmp_t pbmp_linkphy;
  20776     uint32 rval;
  20777     uint32 cos_bmp_value = 0;
  20778     uint64 lls_l2;
  20779     uint32 l2_mask=0;
  20780 
  20781     pbmp_linkphy = soc_property_get_pbmp(unit, spn_PBMP_LINKPHY, 0);
  20782     BCM_IF_ERROR_RETURN(READ_LLS_FC_CONFIGr(unit, &rval));
  20783 
  20784     /* Allows CMIC Cosmask flow control to update the
  20785      * XON-XOFF state for those queues 47:0 */
  20786     soc_reg_field_set(unit, LLS_FC_CONFIGr, &rval, FC_CFG_DISABLE_L2_COSMASK_XOFFf, 0);
  20787 
  20788     if (!SOC_IS_METROLITE(unit) && BCM_PBMP_NOT_NULL(pbmp_linkphy)) {
  20789         soc_reg_field_set(unit, LLS_FC_CONFIGr, &rval, FC_CFG_COSMASK_L0_MAPf, 2);
  20790     } else {
  20791         soc_reg_field_set(unit, LLS_FC_CONFIGr, &rval, FC_CFG_COSMASK_L0_MAPf, 1);
  20792     }
  20793     BCM_IF_ERROR_RETURN(WRITE_LLS_FC_CONFIGr(unit, rval));
  20794 
  20795     COMPILER_64_ZERO(lls_l2);
  20796     BCM_IF_ERROR_RETURN
  20797         (soc_mem_read(unit, LLS_L2_XOFFm, MEM_BLOCK_ANY, 0, &lls_l2));
  20798     l2_mask = COMPILER_64_HI(lls_l2);
  20799     l2_mask &= 0xffff0000;
  20800     COMPILER_64_SET(lls_l2, l2_mask, 0);
  20801     BCM_IF_ERROR_RETURN(soc_mem_write(unit, LLS_L2_XOFFm, MEM_BLOCK_ALL, 0, &lls_l2));
  20802 
  20803     cos_bmp_value = 0;
  20804     cos_bmp_value |= (1 << 16);
  20805     rval = 0;
  20806     BCM_IF_ERROR_RETURN(READ_CMIC_CMC0_CH1_COS_CTRL_RX_1r(unit, &rval));
  20807     soc_reg_field_set(unit, CMIC_CMC0_CH1_COS_CTRL_RX_1r, &rval, COS_BMPf, cos_bmp_value);
  20808     WRITE_CMIC_CMC0_CH1_COS_CTRL_RX_1r(unit, rval);
  20809 
  20810     BCM_IF_ERROR_RETURN(READ_CMIC_CMC0_CH2_COS_CTRL_RX_1r(unit, &rval));
  20811     soc_reg_field_set(unit, CMIC_CMC0_CH2_COS_CTRL_RX_1r, &rval, COS_BMPf, cos_bmp_value);
  20812     WRITE_CMIC_CMC0_CH2_COS_CTRL_RX_1r(unit, rval);
  20813 
  20814     BCM_IF_ERROR_RETURN(READ_CMIC_CMC0_CH3_COS_CTRL_RX_1r(unit, &rval));
  20815     soc_reg_field_set(unit, CMIC_CMC0_CH3_COS_CTRL_RX_1r, &rval, COS_BMPf, cos_bmp_value);
  20816     WRITE_CMIC_CMC0_CH3_COS_CTRL_RX_1r(unit, rval);
  20817 
  20818     cos_bmp_value = 0;
  20819     cos_bmp_value |= (1 << 17);
  20820     rval = 0;
  20821     BCM_IF_ERROR_RETURN(READ_CMIC_CMC1_CH1_COS_CTRL_RX_1r(unit, &rval));
  20822     soc_reg_field_set(unit, CMIC_CMC1_CH1_COS_CTRL_RX_1r, &rval, COS_BMPf, cos_bmp_value);
  20823     WRITE_CMIC_CMC1_CH1_COS_CTRL_RX_1r(unit, rval);
  20824     
  20825     cos_bmp_value = 0;
  20826     cos_bmp_value |= (1 << 18);
  20827     rval = 0;
  20828     BCM_IF_ERROR_RETURN(READ_CMIC_CMC2_CH1_COS_CTRL_RX_1r(unit, &rval));
  20829     soc_reg_field_set(unit, CMIC_CMC2_CH1_COS_CTRL_RX_1r, &rval, COS_BMPf, cos_bmp_value);
  20830     WRITE_CMIC_CMC2_CH1_COS_CTRL_RX_1r(unit, rval);
  20831 
  20832     /* SABER2 has 2 channels mapped to one CMC2 */
  20833     if (SOC_IS_SABER2(unit)) {
  20834         cos_bmp_value = 0;
  20835         cos_bmp_value |= (1 << 18);
  20836         rval = 0;
  20837         BCM_IF_ERROR_RETURN(READ_CMIC_CMC2_CH3_COS_CTRL_RX_1r(unit, &rval));
  20838         soc_reg_field_set(unit, CMIC_CMC2_CH3_COS_CTRL_RX_1r, &rval, COS_BMPf, cos_bmp_value);
  20839         WRITE_CMIC_CMC2_CH3_COS_CTRL_RX_1r(unit, rval);
  20840     }
  20841     
  20842     return BCM_E_NONE; 
  20843 }
  20844 
  20845 STATIC int
  20846 _bcm_kt2_dump_port_lls(int unit, bcm_port_t port)
  20847 {
  20848     _bcm_kt2_cosq_node_t *port_info;
  20849     _bcm_kt2_mmu_info_t *mmu_info;
  20850     bcm_port_t port_out;
  20851 
  20852     if (_bcm_kt2_mmu_info[unit] == NULL) {
  20853         return BCM_E_INIT;
  20854     }
  20855     mmu_info = _bcm_kt2_mmu_info[unit];
  20856 
  20857     BCM_IF_ERROR_RETURN
  20858         (_bcm_kt2_cosq_localport_resolve(unit, port, &port_out));
  20859 
  20860     /* root node */
  20861     port_info = &mmu_info->sched_node[port_out];
  20862 
  20863     if (port_info->gport >= 0) {
  20864        _bcm_kt2_dump_sched(unit, port, port_info->gport);
  20865     }
  20866     return BCM_E_NONE;
  20867 }
  20868 
  20869 
  20870 int bcm_kt2_dump_port_lls(int unit, bcm_port_t port)
  20871 {
  20872 
  20873     LOG_CLI((BSL_META_U(unit,
  20874       "-------%s (LLS)------\n"), SOC_PORT_NAME(unit, (port))));
  20875     _bcm_kt2_dump_port_lls(unit, port);
  20876     return SOC_E_NONE;
  20877 }
  20878 
  20879 
  20880 #ifndef BCM_SW_STATE_DUMP_DISABLE
  20881 
  20882 STATIC int
  20883 _bcm_kt2_cosq_node_info_dump(int unit, _bcm_kt2_cosq_node_t *node) 
  20884 {
  20885     LOG_CLI((BSL_META_U(unit,
  20886            "base = %d mc_base_index = %d numq = %d hw_index = %d \n"),
  20887            node->base_index, node->mc_base_index, node->numq, node->hw_index));
  20888     LOG_CLI((BSL_META_U(unit,
  20889                         "level = %d cosq_attach = %d \n"),
  20890              node->level, node->cosq_attached_to));
  20891     LOG_CLI((BSL_META_U(unit,
  20892                         "num_child = %d first_child = %d wrr_in_use = %d \n"), 
  20893              node->num_child, node->first_child,
  20894              node->wrr_in_use));
  20895     LOG_CLI((BSL_META_U(unit,
  20896                         "subport_enabled = %d linkphy_enabled = %d \n"),
  20897              node->subport_enabled,
  20898              node->linkphy_enabled)); 
  20899     if (node->parent != NULL) {
  20900         LOG_CLI((BSL_META_U(unit,
  20901                             "  parent gport = 0x%08x\n"), node->parent->gport));
  20902     }
  20903     if (node->sibling != NULL) {
  20904         LOG_CLI((BSL_META_U(unit,
  20905                             "  sibling gport = 0x%08x\n"), node->sibling->gport));
  20906     }
  20907     if (node->child != NULL) {
  20908         LOG_CLI((BSL_META_U(unit,
  20909                             "  child  gport = 0x%08x\n"), node->child->gport));
  20910     }
  20911 
  20912     return BCM_E_NONE;
  20913 }
  20914 
  20915 STATIC int
  20916 _bcm_kt2_cosq_l0_tree_dump(int unit, _bcm_kt2_cosq_node_t *node) 
  20917 {
  20918     _bcm_kt2_cosq_node_t *l0_node, *l1_node, *l2_node;
  20919 
  20920     for (l0_node = node; l0_node != NULL;
  20921          l0_node = l0_node->sibling) {
  20922          LOG_CLI((BSL_META_U(unit,
  20923                              "=== L0 gport 0x%08x\n"), l0_node->gport));
  20924          BCM_IF_ERROR_RETURN
  20925              (_bcm_kt2_cosq_node_info_dump(unit, l0_node));
  20926 
  20927         for (l1_node = l0_node->child; l1_node != NULL;
  20928              l1_node = l1_node->sibling) {
  20929               LOG_CLI((BSL_META_U(unit,
  20930                                   "=== L1 gport 0x%08x\n"), l1_node->gport));
  20931               BCM_IF_ERROR_RETURN
  20932                   (_bcm_kt2_cosq_node_info_dump(unit, l1_node));
  20933                 
  20934             for (l2_node = l1_node->child; l2_node != NULL;
  20935                  l2_node = l2_node->sibling) {
  20936                  LOG_CLI((BSL_META_U(unit,
  20937                                      "=== L2 gport 0x%08x\n"), l2_node->gport));
  20938                  BCM_IF_ERROR_RETURN
  20939                       (_bcm_kt2_cosq_node_info_dump(unit, l2_node));
  20940             }
  20941         }
  20942     }
  20943 
  20944     return BCM_E_NONE;
  20945 }
  20946 
  20947 STATIC int
  20948 _bcm_kt2_cosq_port_info_dump(int unit, bcm_port_t port) 
  20949 {
  20950     _bcm_kt2_mmu_info_t *mmu_info;
  20951     _bcm_kt2_cosq_node_t *port_node = NULL;
  20952     _bcm_kt2_cosq_node_t *l0_node = NULL;
  20953     _bcm_kt2_cosq_node_t *s0_node = NULL;
  20954     _bcm_kt2_cosq_node_t *s1_node = NULL;
  20955 
  20956     if (!SOC_PORT_VALID(unit, port)) {
  20957         return BCM_E_PORT;
  20958     }
  20959 
  20960     mmu_info = _bcm_kt2_mmu_info[unit];
  20961 
  20962     /* get the root node */
  20963     port_node = &mmu_info->sched_node[port];
  20964 
  20965     if (port_node && port_node->cosq_attached_to < 0) {
  20966         return BCM_E_NONE;
  20967     }    
  20968 
  20969     LOG_CLI((BSL_META_U(unit,
  20970                         "=== port %d\n"), port));
  20971     BCM_IF_ERROR_RETURN
  20972         (_bcm_kt2_cosq_node_info_dump(unit, port_node));
  20973 
  20974     s0_node = port_node->child;
  20975     if (s0_node != NULL && 
  20976         s0_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S0) {
  20977         for (s0_node = port_node->child; s0_node != NULL;
  20978              s0_node = s0_node->sibling) {
  20979              LOG_CLI((BSL_META_U(unit,
  20980                                  "=== S0 gport 0x%08x\n"), s0_node->gport));
  20981              BCM_IF_ERROR_RETURN
  20982                  (_bcm_kt2_cosq_node_info_dump(unit, s0_node));
  20983 
  20984              s1_node = s0_node->child;
  20985              if (s1_node != NULL && 
  20986                  s1_node->level == _BCM_KT2_COSQ_NODE_LEVEL_S1) {
  20987                  for (s1_node = s0_node->child; s1_node != NULL;
  20988                       s1_node = s1_node->sibling) {
  20989                       LOG_CLI((BSL_META_U(unit,
  20990                                           "=== S1 gport 0x%08x\n"), s1_node->gport));
  20991                       BCM_IF_ERROR_RETURN
  20992                           (_bcm_kt2_cosq_node_info_dump(unit, s1_node));
  20993                       for (l0_node = s1_node->child; l0_node != NULL;
  20994                            l0_node = l0_node->sibling) {
  20995                            BCM_IF_ERROR_RETURN
  20996                                 (_bcm_kt2_cosq_l0_tree_dump(unit, l0_node));
  20997                         }
  20998                     }
  20999              } else {
  21000                  l0_node = s1_node;
  21001                  BCM_IF_ERROR_RETURN
  21002                      (_bcm_kt2_cosq_l0_tree_dump(unit, l0_node));
  21003             }
  21004         }
  21005     } else {
  21006         l0_node = port_node->child;
  21007         BCM_IF_ERROR_RETURN
  21008             (_bcm_kt2_cosq_l0_tree_dump(unit, l0_node));
  21009     }
  21010 
  21011     return BCM_E_NONE;
  21012 }
  21013 
  21014 /*
  21015  * Function:
  21016  *     bcm_kt2_cosq_sw_dump
  21017  * Purpose:
  21018  *     Displays COS Queue information maintained by software.
  21019  * Parameters:
  21020  *     unit - Device unit number
  21021  * Returns:
  21022  *     None
  21023  */
  21024 void
  21025 bcm_kt2_cosq_sw_dump(int unit)
  21026 {
  21027     _bcm_kt2_mmu_info_t *mmu_info;
  21028     bcm_port_t port;
  21029     int i;
  21030 
  21031     mmu_info = _bcm_kt2_mmu_info[unit];
  21032 
  21033     LOG_CLI((BSL_META_U(unit,
  21034                         "\nSW Information COSQ - Unit %d\n"), unit));
  21035 
  21036     for (port = 0; port <= KT2_LPBK_PORT; port++) {
  21037         (void)_bcm_kt2_cosq_port_info_dump(unit, port);
  21038     }
  21039 
  21040     LOG_CLI((BSL_META_U(unit,
  21041                         "global_qlist = %d \n"), mmu_info->global_qlist.count));
  21042     LOG_CLI((BSL_META_U(unit,
  21043                         "sched_list = %d \n"), mmu_info->sched_list.count));
  21044     LOG_CLI((BSL_META_U(unit,
  21045                         "l2_base_qlist = %d \n"), mmu_info->l2_base_qlist.count));
  21046     LOG_CLI((BSL_META_U(unit,
  21047                         "l2_base_mcqlist = %d \n"), mmu_info->l2_base_mcqlist.count));
  21048     LOG_CLI((BSL_META_U(unit,
  21049                         "l2_global_qlist = %d \n"), mmu_info->l2_global_qlist.count));
  21050    
  21051     for (i = 0; i < _BCM_KT2_COSQ_NODE_LEVEL_MAX; i++) {
  21052         LOG_CLI((BSL_META_U(unit,
  21053                             "Level %d count = %d \n"), 
  21054                  i, mmu_info->sched_hw_list[i].count));
  21055     }
  21056     
  21057     return;
  21058 }
  21059 #endif /* BCM_SW_STATE_DUMP_DISABLE */
  21060 
  21061 #else /* BCM_KATANA2_SUPPORT */
  21062 int _kt2_cosq_not_empty;
  21063 #endif  /* BCM_KATANA2_SUPPORT */