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

thresholds.c (124383B)


      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  * Thresholds API implemenation for Tomahawk3
      8  */
      9 #if defined(BCM_TOMAHAWK3_SUPPORT)
     10 #include <bcm_int/esw/pfc.h>
     11 #include <bcm_int/esw/port.h>
     12 #include <bcm_int/esw/tomahawk3.h>
     13 #include <soc/feature.h>
     14 #include <soc/drv.h>
     15 #include <soc/types.h>
     16 #include <soc/scache.h>
     17 #include <soc/profile_mem.h>
     18 #include <soc/debug.h>
     19 #include <soc/tomahawk3.h>
     20 #include <soc/dma.h>
     21 #include <soc/mmu_config.h>
     22 
     23 
     24 /*
     25  * Function:
     26         _bcm_th3_cosq_port_inp_pri_to_pg_profile_set
     27 * Purpose:
     28  *      Set the profile for Input priortty to PG mapping for a port
     29  * Parameters:
     30  *      unit       - (IN) device id.
     31  *      port       - (IN) Port number.
     32  *      profile_id - (IN) Profile index
     33  * Returns      :
     34  *      BCM_E_XXX
     35  */
     36 
     37 int
     38 _bcm_th3_cosq_port_inp_pri_to_pg_profile_set(
     39     int unit,
     40     bcm_port_t port,
     41     int profile_id)
     42 {
     43     uint32 rval;
     44 
     45     if (!SOC_PORT_VALID(unit, port)) {
     46         return BCM_E_PORT;
     47     }
     48 
     49     if ((profile_id < 0) || (profile_id >= _TH3_MMU_NUM_MAX_PROFILES)) {
     50         return BCM_E_PARAM;
     51     }
     52 
     53     rval = 0;
     54     BCM_IF_ERROR_RETURN(
     55         soc_tomahawk3_itm_reg32_get(unit, MMU_THDI_ING_PORT_CONFIGr,
     56                                     -1, port, 0, &rval));
     57     /* soc_reg_field_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval,
     58                       PG_PROFILE_SELf, buf_port->prigroup_profile_idx); */
     59     soc_reg_field_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval,
     60                  INPPRI_PROFILE_SELf, profile_id);
     61     BCM_IF_ERROR_RETURN(
     62         soc_tomahawk3_itm_reg32_set(unit, MMU_THDI_ING_PORT_CONFIGr,
     63                                     -1, port, 0, rval));
     64 
     65     return BCM_E_NONE;
     66 }
     67 
     68 /*
     69  * Function:
     70         _bcm_th3_cosq_port_inp_pri_to_pg_profile_get
     71 * Purpose:
     72  *      Get the profile for Input priortty to PG mapping for a port
     73  * Parameters:
     74  *      unit       - (IN) device id.
     75  *      port       - (IN) Port number.
     76  *      profile_id - (IN) Profile index
     77  * Returns      :
     78  *      BCM_E_XXX
     79  */
     80 
     81 int
     82 _bcm_th3_cosq_port_inp_pri_to_pg_profile_get(
     83     int unit,
     84     bcm_port_t port,
     85     int *profile_id)
     86 {
     87     uint32 rval;
     88 
     89     if (!SOC_PORT_VALID(unit, port)) {
     90         return BCM_E_PORT;
     91     }
     92 
     93     if (profile_id == NULL) {
     94         return BCM_E_PARAM;
     95     }
     96 
     97     rval = 0;
     98     BCM_IF_ERROR_RETURN(
     99         soc_tomahawk3_itm_reg32_get(unit, MMU_THDI_ING_PORT_CONFIGr,
    100                                     -1, port, 0, &rval));
    101     *profile_id = soc_reg_field_get(unit, MMU_THDI_ING_PORT_CONFIGr, rval,
    102                                    INPPRI_PROFILE_SELf);
    103 
    104     return BCM_E_NONE;
    105 }
    106 
    107 /*
    108  * Function:
    109         _bcm_th3_cosq_port_pg_profile_set
    110 * Purpose:
    111  *      Set the profile for PG to SPID/HPID/PFCPRI mapping for a port
    112  * Parameters:
    113  *      unit       - (IN) device id.
    114  *      port       - (IN) Port number.
    115  *      profile_id - (IN) Profile index
    116  * Returns      :
    117  *      BCM_E_XXX
    118  */
    119 
    120 int
    121 _bcm_th3_cosq_port_pg_profile_set(
    122     int unit,
    123     bcm_port_t port,
    124     int profile_id)
    125 {
    126     uint32 rval;
    127 
    128     if (!SOC_PORT_VALID(unit, port)) {
    129         return BCM_E_PORT;
    130     }
    131 
    132     if ((profile_id < 0) || (profile_id >= _TH3_MMU_NUM_MAX_PROFILES)) {
    133         return BCM_E_PARAM;
    134     }
    135 
    136     rval = 0;
    137     BCM_IF_ERROR_RETURN(
    138         soc_tomahawk3_itm_reg32_get(unit, MMU_THDI_ING_PORT_CONFIGr,
    139                                     -1, port, 0, &rval));
    140     soc_reg_field_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval,
    141                       PG_PROFILE_SELf, profile_id);
    142     BCM_IF_ERROR_RETURN(
    143         soc_tomahawk3_itm_reg32_set(unit, MMU_THDI_ING_PORT_CONFIGr,
    144                                     -1, port, 0, rval));
    145 
    146     return BCM_E_NONE;
    147 }
    148 
    149 /*
    150  * Function:
    151         _bcm_th3_cosq_port_pg_profile_get
    152 * Purpose:
    153  *      Get the profile for PG to SPID/HPID/PFCPRI mapping for a port
    154  * Parameters:
    155  *      unit       - (IN) device id.
    156  *      port       - (IN) Port number.
    157  *      profile_id - (OUT) Profile index
    158  * Returns      :
    159  *      BCM_E_XXX
    160  */
    161 
    162 int
    163 _bcm_th3_cosq_port_pg_profile_get(
    164     int unit,
    165     bcm_port_t port,
    166     int *profile_id)
    167 {
    168     uint32 rval;
    169 
    170     if (!SOC_PORT_VALID(unit, port)) {
    171         return BCM_E_PORT;
    172     }
    173 
    174     if (profile_id == NULL) {
    175         return BCM_E_PARAM;
    176     }
    177 
    178     rval = 0;
    179     BCM_IF_ERROR_RETURN(
    180         soc_tomahawk3_itm_reg32_get(unit, MMU_THDI_ING_PORT_CONFIGr,
    181                                     -1, port, 0, &rval));
    182     *profile_id = soc_reg_field_get(unit, MMU_THDI_ING_PORT_CONFIGr, rval,
    183                                    PG_PROFILE_SELf);
    184 
    185     return BCM_E_NONE;
    186 }
    187 
    188 /*
    189  * Function:
    190         bcm_tomahawk3_cosq_priority_group_mapping_profile_set
    191 * Purpose:
    192  *  Set a profile for the following mappings: Input Pri to priority group UC
    193  *                                            Input Pri to priority group MC
    194  *                                            Priority Group to Service Pool
    195  *                                            Priority Group to Headroom Pool
    196  * Parameters:
    197  *      unit       - (IN) device id.
    198  *      profile_index     - (IN) Profile index.
    199  *      type       - (IN) Mapping type
    200  *      array_count   - (IN) actual size of array arg
    201  *      arg - (IN) Value of ouput to mapping type
    202  * Returns:
    203  *      BCM_E_XXX
    204  */
    205 int
    206 bcm_tomahawk3_cosq_priority_group_mapping_profile_set(
    207     int unit,
    208     int profile_index,
    209     bcm_cosq_priority_group_mapping_profile_type_t type,
    210     int array_count,
    211     int* arg)
    212 {
    213     int i;
    214     uint64 rval;
    215     soc_field_t field_pri[_TH3_MMU_NUM_INT_PRI] = {
    216             INPPRI0_PGf, INPPRI1_PGf, INPPRI2_PGf,
    217             INPPRI3_PGf, INPPRI4_PGf, INPPRI5_PGf,
    218             INPPRI6_PGf, INPPRI7_PGf, INPPRI8_PGf,
    219             INPPRI9_PGf, INPPRI10_PGf, INPPRI11_PGf,
    220             INPPRI12_PGf, INPPRI13_PGf, INPPRI14_PGf,
    221             INPPRI15_PGf};
    222     soc_field_t field_hpid[_TH3_MMU_NUM_PG] = {
    223             PG0_HPIDf, PG1_HPIDf, PG2_HPIDf,
    224             PG3_HPIDf, PG4_HPIDf, PG5_HPIDf,
    225             PG6_HPIDf, PG7_HPIDf};
    226     soc_field_t field_spid[_TH3_MMU_NUM_PG] = {
    227             PG0_SPIDf, PG1_SPIDf, PG2_SPIDf,
    228             PG3_SPIDf, PG4_SPIDf, PG5_SPIDf,
    229             PG6_SPIDf, PG7_SPIDf};
    230 
    231     if ((profile_index < 0) || (profile_index >= _TH3_MMU_NUM_MAX_PROFILES)) {
    232         return BCM_E_PARAM;
    233     }
    234 
    235     if (arg == NULL) {
    236         return SOC_E_PARAM;
    237     }
    238 
    239     switch (type) {
    240         case bcmCosqInputPriPriorityGroupUcMapping:
    241             COMPILER_64_ZERO(rval);
    242             SOC_IF_ERROR_RETURN
    243                 (soc_reg64_get(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr,
    244                                REG_PORT_ANY, profile_index, &rval));
    245             if ((array_count <= 0) || (array_count > _TH3_MMU_NUM_INT_PRI)) {
    246                 return BCM_E_PARAM;
    247             }
    248             for (i = 0; i < array_count; i++) {
    249                 if (arg[i] != -1) {
    250                     if ((arg[i] < 0) || (arg[i] >= _TH3_MMU_NUM_PG)) {
    251                         return BCM_E_PARAM;
    252                     }
    253                 } else {
    254                     continue;
    255                 }
    256                 soc_reg64_field32_set(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr, &rval,
    257                     field_pri[i], arg[i]);
    258             }
    259             SOC_IF_ERROR_RETURN
    260                 (soc_reg64_set(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr,
    261                                REG_PORT_ANY, profile_index, rval));
    262             break;
    263         case bcmCosqInputPriPriorityGroupMcMapping:
    264             COMPILER_64_ZERO(rval);
    265             SOC_IF_ERROR_RETURN
    266                 (soc_reg64_get(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr,
    267                                REG_PORT_ANY, profile_index, &rval));
    268             if ((array_count <= 0) || (array_count > _TH3_MMU_NUM_INT_PRI)) {
    269                 return BCM_E_PARAM;
    270             }
    271             for (i = 0; i < array_count; i++) {
    272                 if (arg[i] != -1) {
    273                     if ((arg[i] < 0) || (arg[i] >= _TH3_MMU_NUM_PG)) {
    274                         return BCM_E_PARAM;
    275                     }
    276                 } else {
    277                     continue;
    278                 }
    279                 soc_reg64_field32_set(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr, &rval,
    280                     field_pri[i], arg[i]);
    281             }
    282             SOC_IF_ERROR_RETURN
    283                 (soc_reg64_set(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr,
    284                                REG_PORT_ANY, profile_index, rval));
    285             break;
    286         case bcmCosqPriorityGroupServicePoolMapping:
    287             COMPILER_64_ZERO(rval);
    288             SOC_IF_ERROR_RETURN
    289                 (soc_reg64_get(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY,
    290                                profile_index, &rval));
    291             if ((array_count <= 0) || (array_count > _TH3_MMU_NUM_PG)) {
    292                 return BCM_E_PARAM;
    293             }
    294             for (i = 0; i < array_count; i++) {
    295                 if (arg[i] != -1) {
    296                     if ((arg[i] < 0) || (arg[i] >= _TH3_MMU_NUM_POOL)) {
    297                         return BCM_E_PARAM;
    298                     }
    299                 } else {
    300                     continue;
    301                 }
    302                 soc_reg64_field32_set(unit, MMU_THDI_PG_PROFILEr, &rval,
    303                     field_spid[i], arg[i]);
    304             }
    305             SOC_IF_ERROR_RETURN
    306                 (soc_reg64_set(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY,
    307                                profile_index, rval));
    308             break;
    309         case bcmCosqPriorityGroupHeadroomPoolMapping:
    310             COMPILER_64_ZERO(rval);
    311             SOC_IF_ERROR_RETURN
    312                 (soc_reg64_get(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY,
    313                                profile_index, &rval));
    314             if ((array_count <= 0) || (array_count > _TH3_MMU_NUM_PG)) {
    315                 return BCM_E_PARAM;
    316             }
    317             for (i = 0; i < array_count; i++) {
    318                 if (arg[i] != -1) {
    319                     if ((arg[i] < 0) || (arg[i] >= _TH3_MMU_NUM_POOL)) {
    320                         return BCM_E_PARAM;
    321                     }
    322                 } else {
    323                     continue;
    324                 }
    325                 soc_reg64_field32_set(unit, MMU_THDI_PG_PROFILEr, &rval,
    326                     field_hpid[i], arg[i]);
    327             }
    328             SOC_IF_ERROR_RETURN
    329                 (soc_reg64_set(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY,
    330                                profile_index, rval));
    331             break;
    332         default:
    333             return BCM_E_PARAM;
    334 
    335     }
    336 
    337     return BCM_E_NONE;
    338 }
    339 
    340 
    341 /*
    342  * Function:
    343         bcm_tomahawk3_cosq_priority_group_mapping_profile_get
    344 * Purpose:
    345  *  Set a profile for the following mappings: Input Pri to priority group UC
    346  *                                            Input Pri to priority group MC
    347  *                                            Priority Group to Service Pool
    348  *                                            Priority Group to Headroom Pool
    349  * Parameters:
    350  *      unit       - (IN) device id.
    351  *      profile_index     - (IN) Profile index.
    352  *      type       - (IN) Mapping type
    353  *      array_max   - (IN) Max size of array
    354  *      array_count - (OUT) actual size of array
    355  *      arg - (OUT) Value of ouput to mapping type
    356  * Returns:
    357  *      BCM_E_XXX
    358  */
    359 int
    360 bcm_tomahawk3_cosq_priority_group_mapping_profile_get(
    361     int unit,
    362     int profile_index,
    363     bcm_cosq_priority_group_mapping_profile_type_t type,
    364     int array_max,
    365     int* arg,
    366     int* array_count)
    367 {
    368     int i;
    369     uint64 rval;
    370     soc_field_t field_pri[_TH3_MMU_NUM_INT_PRI] = {
    371             INPPRI0_PGf, INPPRI1_PGf, INPPRI2_PGf,
    372             INPPRI3_PGf, INPPRI4_PGf, INPPRI5_PGf,
    373             INPPRI6_PGf, INPPRI7_PGf, INPPRI8_PGf,
    374             INPPRI9_PGf, INPPRI10_PGf, INPPRI11_PGf,
    375             INPPRI12_PGf, INPPRI13_PGf, INPPRI14_PGf,
    376             INPPRI15_PGf};
    377     soc_field_t field_hpid[_TH3_MMU_NUM_PG] = {
    378             PG0_HPIDf, PG1_HPIDf, PG2_HPIDf,
    379             PG3_HPIDf, PG4_HPIDf, PG5_HPIDf,
    380             PG6_HPIDf, PG7_HPIDf};
    381     soc_field_t field_spid[_TH3_MMU_NUM_PG] = {
    382             PG0_SPIDf, PG1_SPIDf, PG2_SPIDf,
    383             PG3_SPIDf, PG4_SPIDf, PG5_SPIDf,
    384             PG6_SPIDf, PG7_SPIDf};
    385 
    386     if ((profile_index < 0) || (profile_index >= _TH3_MMU_NUM_MAX_PROFILES)) {
    387         return BCM_E_PARAM;
    388     }
    389 
    390     if (((array_max == 0) && (arg != NULL)) ||
    391         ((array_max != 0) && (arg == NULL))) {
    392         return SOC_E_PARAM;
    393     }
    394 
    395     *array_count = 0;
    396     switch (type) {
    397         case bcmCosqInputPriPriorityGroupUcMapping:
    398             COMPILER_64_ZERO(rval);
    399             SOC_IF_ERROR_RETURN
    400                 (soc_reg64_get(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr,
    401                                REG_PORT_ANY, profile_index, &rval));
    402             for (i = 0; ((i < _TH3_MMU_NUM_INT_PRI) && (i < array_max)); i++) {
    403                 arg[i] = soc_reg64_field32_get(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr,
    404                         rval, field_pri[i]);
    405 
    406             }
    407             *array_count = i;
    408             break;
    409         case bcmCosqInputPriPriorityGroupMcMapping:
    410             COMPILER_64_ZERO(rval);
    411             SOC_IF_ERROR_RETURN
    412                 (soc_reg64_get(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr,
    413                                REG_PORT_ANY, profile_index, &rval));
    414             for (i = 0; ((i < _TH3_MMU_NUM_INT_PRI) && (i < array_max)); i++) {
    415                 arg[i] = soc_reg64_field32_get(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr,
    416                         rval, field_pri[i]);
    417             }
    418             *array_count = i;
    419             break;
    420         case bcmCosqPriorityGroupServicePoolMapping:
    421             COMPILER_64_ZERO(rval);
    422             SOC_IF_ERROR_RETURN
    423                 (soc_reg64_get(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY,
    424                                profile_index, &rval));
    425             for (i = 0; ((i < _TH3_MMU_NUM_PG) && (i < array_max)); i++) {
    426                 arg[i] = soc_reg64_field32_get(unit, MMU_THDI_PG_PROFILEr,
    427                         rval, field_spid[i]);
    428             }
    429             *array_count = i;
    430             break;
    431         case bcmCosqPriorityGroupHeadroomPoolMapping:
    432             COMPILER_64_ZERO(rval);
    433             SOC_IF_ERROR_RETURN
    434                 (soc_reg64_get(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY,
    435                                profile_index, &rval));
    436             for (i = 0; ((i < _TH3_MMU_NUM_PG) && (i < array_max)); i++) {
    437                 arg[i] = soc_reg64_field32_get(unit, MMU_THDI_PG_PROFILEr,
    438                         rval, field_hpid[i]);
    439             }
    440             *array_count = i;
    441             break;
    442         default:
    443             return BCM_E_PARAM;
    444 
    445     }
    446 
    447     return BCM_E_NONE;
    448 }
    449 
    450 /*
    451  * Function:
    452         bcm_tomahawk3_cosq_service_pool_override_set
    453 * Purpose:
    454  *      Set service pool overrides for CPU, Multicast and Mirror
    455  * Parameters:
    456  *      unit       - (IN) device id.
    457  *      type       - (IN) Service pool override type
    458  *      service_pool   - (IN) Service pool id
    459  *      enable - (IN) Enable/Disable service pool override
    460  * Returns:
    461  *      BCM_E_XXX
    462  */
    463 int
    464 bcm_tomahawk3_cosq_service_pool_override_set(
    465     int unit,
    466     bcm_cosq_service_pool_override_type_t type,
    467     bcm_service_pool_id_t service_pool,
    468     int enable)
    469 {
    470     uint64 rval;
    471 
    472     if ((service_pool < 0) || (service_pool >= _TH3_MMU_NUM_POOL)) {
    473         return BCM_E_PARAM;
    474     }
    475 
    476     if ((enable < 0) || (enable > 1)) {
    477         return BCM_E_PARAM;
    478     }
    479     switch (type) {
    480         case bcmCosqServicePoolOverrideCpu:
    481             COMPILER_64_ZERO(rval);
    482             SOC_IF_ERROR_RETURN
    483                 (soc_reg_get(unit, MMU_THDI_CPU_SPID_OVERRIDE_CTRLr,
    484                              REG_PORT_ANY, -1, &rval));
    485             soc_reg64_field32_set(unit, MMU_THDI_CPU_SPID_OVERRIDE_CTRLr, &rval,
    486                     SPIDf, service_pool);
    487             soc_reg64_field32_set(unit, MMU_THDI_CPU_SPID_OVERRIDE_CTRLr, &rval,
    488                     ENABLEf, enable);
    489             SOC_IF_ERROR_RETURN
    490                 (soc_reg_set(unit,  MMU_THDI_CPU_SPID_OVERRIDE_CTRLr,
    491                              REG_PORT_ANY, -1, rval));
    492             break;
    493         case bcmCosqServicePoolOverrideMcPkt:
    494             COMPILER_64_ZERO(rval);
    495             SOC_IF_ERROR_RETURN
    496                 (soc_reg_get(unit, MMU_THDI_MC_SPID_OVERRIDE_CTRLr,
    497                              REG_PORT_ANY, -1, &rval));
    498             soc_reg64_field32_set(unit, MMU_THDI_MC_SPID_OVERRIDE_CTRLr, &rval,
    499                     SPIDf, service_pool);
    500             soc_reg64_field32_set(unit, MMU_THDI_MC_SPID_OVERRIDE_CTRLr, &rval,
    501                     ENABLEf, enable);
    502             SOC_IF_ERROR_RETURN
    503                 (soc_reg_set(unit,  MMU_THDI_MC_SPID_OVERRIDE_CTRLr,
    504                              REG_PORT_ANY, -1, rval));
    505             break;
    506         case bcmCosqServicePoolOverrideMirror:
    507             COMPILER_64_ZERO(rval);
    508             SOC_IF_ERROR_RETURN
    509                 (soc_reg_get(unit, MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr,
    510                              REG_PORT_ANY, -1, &rval));
    511             soc_reg64_field32_set(unit, MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr, &rval,
    512                     SPIDf, service_pool);
    513             soc_reg64_field32_set(unit, MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr, &rval,
    514                     ENABLEf, enable);
    515             SOC_IF_ERROR_RETURN
    516                 (soc_reg_set(unit,  MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr,
    517                              REG_PORT_ANY, -1, rval));
    518             break;
    519         default:
    520             return BCM_E_PARAM;
    521     }
    522     return BCM_E_NONE;
    523 }
    524 
    525 
    526 /*
    527  * Function:
    528         bcm_tomahawk3_cosq_service_pool_override_get
    529 * Purpose:
    530  *      Set service pool overrides for CPU, Multicast and Mirror
    531  * Parameters:
    532  *      unit       - (IN) device id.
    533  *      type       - (IN) Service pool override type
    534  *      service_pool   - (OUT) Service pool id
    535  *      enable - (OUT) Enable/Disable service pool override
    536  * Returns:
    537  *      BCM_E_XXX
    538  */
    539 int
    540 bcm_tomahawk3_cosq_service_pool_override_get(
    541     int unit,
    542     bcm_cosq_service_pool_override_type_t type,
    543     bcm_service_pool_id_t* service_pool,
    544     int* enable)
    545 {
    546     uint64 rval;
    547 
    548     switch (type) {
    549         case bcmCosqServicePoolOverrideCpu:
    550             COMPILER_64_ZERO(rval);
    551             SOC_IF_ERROR_RETURN
    552                 (soc_reg_get(unit, MMU_THDI_CPU_SPID_OVERRIDE_CTRLr,
    553                              REG_PORT_ANY, -1, &rval));
    554             *service_pool = soc_reg64_field32_get(unit,
    555                     MMU_THDI_CPU_SPID_OVERRIDE_CTRLr, rval, SPIDf);
    556             *enable = soc_reg64_field32_get(unit,
    557                     MMU_THDI_CPU_SPID_OVERRIDE_CTRLr, rval, ENABLEf);
    558             break;
    559         case bcmCosqServicePoolOverrideMcPkt:
    560             COMPILER_64_ZERO(rval);
    561             SOC_IF_ERROR_RETURN
    562                 (soc_reg_get(unit, MMU_THDI_MC_SPID_OVERRIDE_CTRLr,
    563                              REG_PORT_ANY, -1, &rval));
    564             *service_pool = soc_reg64_field32_get(unit,
    565                     MMU_THDI_MC_SPID_OVERRIDE_CTRLr, rval, SPIDf);
    566             *enable = soc_reg64_field32_get(unit,
    567                     MMU_THDI_MC_SPID_OVERRIDE_CTRLr, rval, ENABLEf);
    568             break;
    569         case bcmCosqServicePoolOverrideMirror:
    570             COMPILER_64_ZERO(rval);
    571             SOC_IF_ERROR_RETURN
    572                 (soc_reg_get(unit, MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr,
    573                              REG_PORT_ANY, -1, &rval));
    574             *service_pool = soc_reg64_field32_get(unit,
    575                     MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr, rval, SPIDf);
    576             *enable = soc_reg64_field32_get(unit,
    577                     MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr, rval, ENABLEf);
    578             break;
    579         default:
    580             return BCM_E_PARAM;
    581     }
    582     return BCM_E_NONE;
    583 }
    584 
    585 /*
    586  * Function:
    587         bcm_tomahawk3_cosq_port_priority_group_property_set
    588 * Purpose:
    589  *      Get per port per priority group properties : Lossless, Pause
    590  * Parameters:
    591  *      unit       - (IN) device id.
    592  *      port       - (IN) Port number.
    593  *      priority_group_id - (IN) Priority group
    594  *      type       - (IN) Property type (Lossless or Pause enable)
    595  *      arg        - (IN) Value based on property type
    596  * Returns      :
    597  *      BCM_E_XXX
    598  */
    599 
    600 int
    601 bcm_tomahawk3_cosq_port_priority_group_property_set(
    602     int unit,
    603     bcm_port_t port,
    604     int priority_group_id,
    605     bcm_cosq_port_prigroup_control_t type,
    606     int arg)
    607 {
    608     uint64 rval;
    609     int pg_lossless;
    610 
    611     if (!SOC_PORT_VALID(unit, port)) {
    612         return BCM_E_PORT;
    613     }
    614 
    615     switch (type) {
    616         case bcmCosqPriorityGroupLossless:
    617             if ((priority_group_id < 0) ||
    618                 (priority_group_id >= _TH3_MMU_NUM_PG)) {
    619                 return BCM_E_PARAM;
    620             }
    621             COMPILER_64_ZERO(rval);
    622             SOC_IF_ERROR_RETURN
    623                 (soc_reg_get(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, &rval));
    624             pg_lossless = soc_reg64_field32_get(unit,
    625                     MMU_THDI_ING_PORT_CONFIGr, rval, PG_IS_LOSSLESSf);
    626             if (arg) {
    627                 pg_lossless = pg_lossless | (1 << priority_group_id);
    628             } else {
    629                 pg_lossless &= (0xff ^ (1 << priority_group_id));
    630             }
    631             soc_reg64_field32_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval,
    632                       PG_IS_LOSSLESSf, pg_lossless);
    633             SOC_IF_ERROR_RETURN
    634                 (soc_reg_set(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, rval));
    635             break;
    636         case bcmCosqPauseEnable:
    637             COMPILER_64_ZERO(rval);
    638             SOC_IF_ERROR_RETURN
    639                 (soc_reg_get(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, &rval));
    640             soc_reg64_field32_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval,
    641                       PAUSE_ENABLEf, arg);
    642             /* Disable PFC if pause is enabled */
    643             if (arg == 1) {
    644                 soc_reg64_field32_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval,
    645                       PFC_PG_ENABLEf, 0);
    646             }
    647             SOC_IF_ERROR_RETURN
    648                 (soc_reg_set(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, rval));
    649             break;
    650     }
    651 
    652     return BCM_E_NONE;
    653 }
    654 /*
    655  * Function:
    656         bcm_tomahawk3_cosq_port_priority_group_property_get
    657 * Purpose:
    658  *      Get per port per priority group properties : Lossless, Pause
    659  * Parameters:
    660  *      unit       - (IN) device id.
    661  *      port       - (IN) Port number.
    662  *      priority_group_id - (IN) Priority group
    663  *      type       - (IN) Property type (Lossless or Pause enable)
    664  *      arg        - (OUT) Value based on property type
    665  * Returns      :
    666  *      BCM_E_XXX
    667  */
    668 
    669 int
    670 bcm_tomahawk3_cosq_port_priority_group_property_get(
    671     int unit,
    672     bcm_port_t port,
    673     int priority_group_id,
    674     bcm_cosq_port_prigroup_control_t type,
    675     int *arg)
    676 {
    677     uint64 rval;
    678     int pg_lossless;
    679 
    680     if (!SOC_PORT_VALID(unit, port)) {
    681         return BCM_E_PORT;
    682     }
    683 
    684     switch (type) {
    685         case bcmCosqPriorityGroupLossless:
    686             if ((priority_group_id < 0) ||
    687                 (priority_group_id >= _TH3_MMU_NUM_PG)) {
    688                 return BCM_E_PARAM;
    689             }
    690             COMPILER_64_ZERO(rval);
    691             SOC_IF_ERROR_RETURN
    692                 (soc_reg_get(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, &rval));
    693             pg_lossless = soc_reg64_field32_get(unit, MMU_THDI_ING_PORT_CONFIGr,
    694                     rval, PG_IS_LOSSLESSf);
    695             *arg = (pg_lossless & (1 << priority_group_id)) >> priority_group_id;
    696             break;
    697         case bcmCosqPauseEnable:
    698             COMPILER_64_ZERO(rval);
    699             SOC_IF_ERROR_RETURN
    700                 (soc_reg_get(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, &rval));
    701             *arg = soc_reg64_field32_get(unit, MMU_THDI_ING_PORT_CONFIGr,
    702                     rval, PAUSE_ENABLEf);
    703             break;
    704     }
    705 
    706     return BCM_E_NONE;
    707 }
    708 
    709 STATIC int
    710 _bcm_th3_cosq_ing_pool_set(int unit, bcm_gport_t gport,
    711                           bcm_cos_t prigroup,
    712                           bcm_cosq_control_t type, int arg)
    713 {
    714     if ((arg < 0) || (arg >= _TH3_MMU_NUM_POOL)) {
    715             return BCM_E_PARAM;
    716     }
    717 
    718 
    719     /* Expects priority group as input in Tomahawk3
    720      * Future enhancement is to create gport type for priority group
    721      */
    722     if ((prigroup < 0) || (prigroup >= _TH3_MMU_NUM_PG)) {
    723         return BCM_E_PARAM;
    724     }
    725 
    726     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
    727         BCM_GPORT_IS_SCHEDULER(gport) ||
    728         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
    729         return BCM_E_PARAM;
    730     }
    731 
    732     if (type == bcmCosqControlIngressPool) {
    733         BCM_IF_ERROR_RETURN(
    734             _bcm_th3_cosq_ingress_sp_set_by_pg(unit, gport, prigroup, arg));
    735     } else if (type == bcmCosqControlIngressHeadroomPool) {
    736         BCM_IF_ERROR_RETURN(
    737             _bcm_th3_cosq_ingress_hdrm_pool_set_by_pg(unit, gport, prigroup, arg));
    738     } else {
    739         return BCM_E_PARAM;
    740     }
    741 
    742     return BCM_E_NONE;
    743 }
    744 
    745 
    746 STATIC int
    747 _bcm_th3_cosq_ing_pool_get(int unit, bcm_gport_t gport,
    748                           bcm_cos_t prigroup,
    749                           bcm_cosq_control_t type, int *arg)
    750 {
    751     if (arg == NULL) {
    752         return BCM_E_PARAM;
    753     }
    754 
    755     /* Expects priority group as input in Tomahawk3
    756      * Future enhancement is to create gport type for priority group
    757      */
    758     if ((prigroup < 0) || (prigroup >= _TH3_MMU_NUM_PG)) {
    759         return BCM_E_PARAM;
    760     }
    761 
    762     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
    763         BCM_GPORT_IS_SCHEDULER(gport) ||
    764         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
    765         return BCM_E_PARAM;
    766     }
    767 
    768     if (type == bcmCosqControlIngressPool) {
    769         BCM_IF_ERROR_RETURN(
    770             _bcm_th3_cosq_ingress_sp_get_by_pg(unit, gport, prigroup, arg));
    771     } else if (type == bcmCosqControlIngressHeadroomPool) {
    772         BCM_IF_ERROR_RETURN(
    773             _bcm_th3_cosq_ingress_hdrm_pool_get_by_pg(unit, gport, prigroup, arg));
    774     } else {
    775         return BCM_E_PARAM;
    776     }
    777     return BCM_E_NONE;
    778 }
    779 
    780 
    781 STATIC int
    782 _bcm_th3_cosq_dynamic_thresh_enable_get(int unit,
    783                         bcm_gport_t gport, bcm_cos_queue_t cosq,
    784                         bcm_cosq_control_t type, int* arg)
    785 {
    786     bcm_port_t local_port;
    787     int startq;
    788     int pipe;
    789     int from_cos, to_cos, ci;
    790     int midx;
    791     uint32 entry[SOC_MAX_MEM_WORDS];
    792     soc_mem_t mem = INVALIDm;
    793     int port_pg;
    794     /*
    795     soc_field_t field_pgshared_limit[_TH3_MMU_NUM_PG] = {
    796             PG0_SHARED_LIMITf, PG1_SHARED_LIMITf, PG2_SHARED_LIMITf,
    797             PG3_SHARED_LIMITf, PG4_SHARED_LIMITf, PG5_SHARED_LIMITf,
    798             PG6_SHARED_LIMITf, PG7_SHARED_LIMITf};
    799     */
    800     soc_field_t field_pgshared_dynamic[_TH3_MMU_NUM_PG] = {
    801             PG0_SHARED_DYNAMICf, PG1_SHARED_DYNAMICf, PG2_SHARED_DYNAMICf,
    802             PG3_SHARED_DYNAMICf, PG4_SHARED_DYNAMICf, PG5_SHARED_DYNAMICf,
    803             PG6_SHARED_DYNAMICf, PG7_SHARED_DYNAMICf};
    804 
    805 
    806     if (!arg) {
    807         return BCM_E_PARAM;
    808     }
    809 
    810     if (type == bcmCosqControlIngressPortPGSharedDynamicEnable) {
    811         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
    812             BCM_GPORT_IS_SCHEDULER(gport) ||
    813             BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
    814             return BCM_E_PARAM;
    815         }
    816         BCM_IF_ERROR_RETURN
    817             (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
    818 
    819         if (local_port < 0) {
    820             return BCM_E_PORT;
    821         }
    822         /* Expects that cosq is priority group in Tomahawk3
    823          * Future enhancement is to create gport type of priority group
    824          */
    825         if ((cosq < 0) || (cosq >= _TH3_MMU_NUM_PG)) {
    826             return BCM_E_PARAM;
    827         }
    828         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
    829 
    830         port_pg = cosq;
    831 
    832         mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDI_PORT_PG_SHARED_CONFIGm)[pipe];
    833         if (mem != INVALIDm) {
    834             sal_memset(&entry, 0, sizeof(entry));
    835             midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port,
    836                              MMU_THDI_PORT_PG_SHARED_CONFIGm,0);
    837             BCM_IF_ERROR_RETURN
    838                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
    839             *arg = soc_mem_field32_get(unit, mem, entry, field_pgshared_dynamic[port_pg]);
    840         }
    841     } else if (type == bcmCosqControlEgressUCSharedDynamicEnable) {
    842         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
    843             BCM_IF_ERROR_RETURN
    844                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
    845                                             _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
    846                                             &local_port, &startq, NULL));
    847         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
    848             return BCM_E_PARAM;
    849         } else {
    850             if (cosq == BCM_COS_INVALID) {
    851                 from_cos = to_cos = 0;
    852             } else {
    853                 from_cos = to_cos = cosq;
    854             }
    855 
    856             BCM_IF_ERROR_RETURN
    857                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
    858             if (local_port < 0) {
    859                 return BCM_E_PORT;
    860             }
    861             for (ci = from_cos; ci <= to_cos; ci++) {
    862                 BCM_IF_ERROR_RETURN
    863                     (_bcm_th3_cosq_index_resolve(unit, local_port, ci,
    864                                          _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
    865                                          NULL, &startq, NULL));
    866 
    867             }
    868         }
    869         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
    870         mem = MMU_THDO_QUEUE_CONFIGm;
    871 
    872         BCM_IF_ERROR_RETURN
    873             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
    874         *arg = soc_mem_field32_get(unit, mem, entry, LIMIT_DYNAMICf);
    875     } else if (type == bcmCosqControlEgressMCSharedDynamicEnable) {
    876         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
    877             return BCM_E_PARAM;
    878         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
    879             BCM_IF_ERROR_RETURN
    880                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
    881                                       _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
    882                                       &local_port, &startq, NULL));
    883         }
    884         else {
    885             if (cosq == BCM_COS_INVALID) {
    886                 from_cos = to_cos = 0;
    887             } else {
    888                 from_cos = to_cos = cosq;
    889             }
    890 
    891             BCM_IF_ERROR_RETURN
    892                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
    893             if (local_port < 0) {
    894                 return BCM_E_PORT;
    895             }
    896             for (ci = from_cos; ci <= to_cos; ci++) {
    897                 BCM_IF_ERROR_RETURN
    898                     (_bcm_th3_cosq_index_resolve(unit, local_port, ci,
    899                                          _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
    900                                          NULL, &startq, NULL));
    901 
    902             }
    903         }
    904 
    905         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
    906         mem = MMU_THDO_QUEUE_CONFIGm;
    907 
    908         BCM_IF_ERROR_RETURN
    909             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
    910         *arg = soc_mem_field32_get(unit, mem, entry, LIMIT_DYNAMICf);
    911     }
    912     else {
    913         return BCM_E_PARAM;
    914     }
    915 
    916     return BCM_E_NONE;
    917 }
    918 
    919 
    920 STATIC int
    921 _bcm_th3_cosq_dynamic_thresh_enable_set(int unit,
    922                         bcm_gport_t gport, bcm_cos_queue_t cosq,
    923                         bcm_cosq_control_t type, int arg)
    924 {
    925     bcm_port_t local_port;
    926     int startq;
    927     int pipe;
    928     int from_cos, to_cos, ci;
    929     int midx;
    930     /* uint32 rval; */
    931     uint32 entry[SOC_MAX_MEM_WORDS];
    932     soc_mem_t mem = INVALIDm;
    933     /* soc_reg_t reg = INVALIDr; */
    934     int port_pg;
    935     soc_field_t field_pgshared_limit[_TH3_MMU_NUM_PG] = {
    936             PG0_SHARED_LIMITf, PG1_SHARED_LIMITf, PG2_SHARED_LIMITf,
    937             PG3_SHARED_LIMITf, PG4_SHARED_LIMITf, PG5_SHARED_LIMITf,
    938             PG6_SHARED_LIMITf, PG7_SHARED_LIMITf};
    939     soc_field_t field_pgshared_dynamic[_TH3_MMU_NUM_PG] = {
    940             PG0_SHARED_DYNAMICf, PG1_SHARED_DYNAMICf, PG2_SHARED_DYNAMICf,
    941             PG3_SHARED_DYNAMICf, PG4_SHARED_DYNAMICf, PG5_SHARED_DYNAMICf,
    942             PG6_SHARED_DYNAMICf, PG7_SHARED_DYNAMICf};
    943 
    944 
    945     if (type == bcmCosqControlIngressPortPGSharedDynamicEnable) {
    946         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
    947             BCM_GPORT_IS_SCHEDULER(gport) ||
    948             BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
    949             return BCM_E_PARAM;
    950         }
    951         BCM_IF_ERROR_RETURN
    952             (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
    953 
    954         if (local_port < 0) {
    955             return BCM_E_PORT;
    956         }
    957         /* Expects that cosq is priority group in Tomahawk3
    958          * Future enhancement is to create gport type of priority group
    959          */
    960         if ((cosq < 0) || (cosq >= _TH3_MMU_NUM_PG)) {
    961             return BCM_E_PARAM;
    962         }
    963         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
    964 
    965         port_pg = cosq;
    966 
    967         mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDI_PORT_PG_SHARED_CONFIGm)[pipe];
    968         if (mem != INVALIDm) {
    969             sal_memset(&entry, 0, sizeof(entry));
    970             midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port,
    971                              MMU_THDI_PORT_PG_SHARED_CONFIGm,0);
    972             BCM_IF_ERROR_RETURN
    973                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
    974             soc_mem_field32_set(unit, mem, entry,
    975                             field_pgshared_dynamic[port_pg], arg ? 1 : 0);
    976             if(arg) {
    977                 /* Set default alpha value*/
    978                 soc_mem_field32_set(unit, mem, entry, field_pgshared_limit[port_pg],
    979                                     SOC_TH3_COSQ_DROP_LIMIT_ALPHA_2); /* Value: 8 */
    980             }
    981             SOC_IF_ERROR_RETURN
    982                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry));
    983         }
    984     } else if (type == bcmCosqControlEgressUCSharedDynamicEnable) {
    985         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
    986             BCM_IF_ERROR_RETURN
    987                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
    988                                             _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
    989                                             &local_port, &startq, NULL));
    990         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
    991             return BCM_E_PARAM;
    992         } else {
    993             if (cosq == BCM_COS_INVALID) {
    994                 from_cos = to_cos = 0;
    995             } else {
    996                 from_cos = to_cos = cosq;
    997             }
    998 
    999             BCM_IF_ERROR_RETURN
   1000                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1001             if (local_port < 0) {
   1002                 return BCM_E_PORT;
   1003             }
   1004             for (ci = from_cos; ci <= to_cos; ci++) {
   1005                 BCM_IF_ERROR_RETURN
   1006                     (_bcm_th3_cosq_index_resolve(unit, local_port, ci,
   1007                                          _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1008                                          NULL, &startq, NULL));
   1009 
   1010             }
   1011         }
   1012         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1013         mem = MMU_THDO_QUEUE_CONFIGm;
   1014 
   1015         BCM_IF_ERROR_RETURN
   1016             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1017         soc_mem_field32_set(unit, mem, entry,
   1018                             LIMIT_DYNAMICf, arg ? 1 : 0);
   1019         if(arg) {
   1020             soc_mem_field32_set(unit, mem, entry, SHARED_ALPHAf,
   1021                                SOC_TH3_COSQ_DROP_LIMIT_ALPHA_2);
   1022         }
   1023         SOC_IF_ERROR_RETURN
   1024             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1025     } else if (type == bcmCosqControlEgressMCSharedDynamicEnable) {
   1026         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1027             return BCM_E_PARAM;
   1028         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1029             BCM_IF_ERROR_RETURN
   1030                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1031                                       _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1032                                       &local_port, &startq, NULL));
   1033         }
   1034         else {
   1035             if (cosq == BCM_COS_INVALID) {
   1036                 from_cos = to_cos = 0;
   1037             } else {
   1038                 from_cos = to_cos = cosq;
   1039             }
   1040 
   1041             BCM_IF_ERROR_RETURN
   1042                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1043             if (local_port < 0) {
   1044                 return BCM_E_PORT;
   1045             }
   1046             for (ci = from_cos; ci <= to_cos; ci++) {
   1047                 BCM_IF_ERROR_RETURN
   1048                     (_bcm_th3_cosq_index_resolve(unit, local_port, ci,
   1049                                          _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1050                                          NULL, &startq, NULL));
   1051 
   1052             }
   1053         }
   1054 
   1055         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1056         mem = MMU_THDO_QUEUE_CONFIGm;
   1057 
   1058         BCM_IF_ERROR_RETURN
   1059             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1060         soc_mem_field32_set(unit, mem, entry, LIMIT_DYNAMICf, arg ? 1 : 0);
   1061         if(arg) {
   1062             soc_mem_field32_set(unit, mem, entry, SHARED_ALPHAf,
   1063                                 SOC_TH3_COSQ_DROP_LIMIT_ALPHA_2);
   1064         }
   1065         SOC_IF_ERROR_RETURN
   1066             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1067     }
   1068 else {
   1069         return BCM_E_PARAM;
   1070     }
   1071 
   1072     return BCM_E_NONE;
   1073 }
   1074 
   1075 STATIC int
   1076 _bcm_th3_cosq_alpha_set(int unit,
   1077                        bcm_gport_t gport, bcm_cos_queue_t cosq,
   1078                        bcm_cosq_control_drop_limit_alpha_value_t arg)
   1079 {
   1080     bcm_port_t local_port;
   1081     int startq, midx, pipe;
   1082     /* uint32 rval; */
   1083     uint32 entry[SOC_MAX_MEM_WORDS];
   1084     soc_mem_t mem = INVALIDm;
   1085     int alpha, dynamic_thresh_mode, port_pg;
   1086     /* int phy_port, mmu_port, local_mmu_port; */
   1087     soc_field_t field_pgshared_limit[_TH3_MMU_NUM_PG] = {
   1088             PG0_SHARED_LIMITf, PG1_SHARED_LIMITf, PG2_SHARED_LIMITf,
   1089             PG3_SHARED_LIMITf, PG4_SHARED_LIMITf, PG5_SHARED_LIMITf,
   1090             PG6_SHARED_LIMITf, PG7_SHARED_LIMITf};
   1091 
   1092 
   1093     switch(arg) {
   1094     case bcmCosqControlDropLimitAlpha_1_128:
   1095         alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_128;
   1096         break;
   1097     case bcmCosqControlDropLimitAlpha_1_64:
   1098         alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_64;
   1099         break;
   1100     case bcmCosqControlDropLimitAlpha_1_32:
   1101         alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_32;
   1102         break;
   1103     case bcmCosqControlDropLimitAlpha_1_16:
   1104         alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_16;
   1105         break;
   1106     case bcmCosqControlDropLimitAlpha_1_8:
   1107         alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_8;
   1108         break;
   1109     case bcmCosqControlDropLimitAlpha_1_4:
   1110         alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_4;
   1111         break;
   1112     case bcmCosqControlDropLimitAlpha_1_2:
   1113         alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_2;
   1114         break;
   1115     case bcmCosqControlDropLimitAlpha_1:
   1116         alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1;
   1117         break;
   1118     case bcmCosqControlDropLimitAlpha_2:
   1119         alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_2;
   1120         break;
   1121     case bcmCosqControlDropLimitAlpha_4:
   1122         alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_4;
   1123         break;
   1124     case bcmCosqControlDropLimitAlpha_8:
   1125         alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_8;
   1126         break;
   1127     default:
   1128         return BCM_E_PARAM;
   1129     }
   1130 
   1131     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1132         BCM_IF_ERROR_RETURN
   1133                 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq,
   1134                                    bcmCosqControlEgressUCSharedDynamicEnable,
   1135                                    &dynamic_thresh_mode));
   1136         if (!dynamic_thresh_mode){
   1137             return BCM_E_CONFIG;
   1138         }
   1139 
   1140         BCM_IF_ERROR_RETURN
   1141             (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1142                                      _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1143                                      &local_port, &startq, NULL));
   1144         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1145 
   1146         mem = MMU_THDO_QUEUE_CONFIGm;
   1147 
   1148         BCM_IF_ERROR_RETURN
   1149             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1150         soc_mem_field32_set(unit, mem, entry,
   1151                             SHARED_ALPHAf, alpha);
   1152         SOC_IF_ERROR_RETURN
   1153             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1154     } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1155         BCM_IF_ERROR_RETURN
   1156                 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq,
   1157                                    bcmCosqControlEgressMCSharedDynamicEnable,
   1158                                    &dynamic_thresh_mode));
   1159         if (!dynamic_thresh_mode){
   1160             return BCM_E_CONFIG;
   1161         }
   1162 
   1163         BCM_IF_ERROR_RETURN
   1164             (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1165                                      _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1166                                      &local_port, &startq, NULL));
   1167         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1168 
   1169         mem = MMU_THDO_QUEUE_CONFIGm;
   1170 
   1171         BCM_IF_ERROR_RETURN
   1172             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1173         soc_mem_field32_set(unit, mem, entry, SHARED_ALPHAf, alpha);
   1174         SOC_IF_ERROR_RETURN
   1175             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1176 
   1177     } else if (BCM_GPORT_IS_LOCAL(gport)) {
   1178         /* Shared limits are not applicable for Qgroup in Tomahawk3 */
   1179         /* _bcm_th3_cosq_dynamic_thresh_enable_get will return error for
   1180            bcmCosqControlEgressUCQueueGroupSharedDynamicEnable, type
   1181         */
   1182         return BCM_E_PARAM;
   1183     } else {
   1184         BCM_IF_ERROR_RETURN
   1185                 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq,
   1186                                    bcmCosqControlIngressPortPGSharedDynamicEnable,
   1187                                    &dynamic_thresh_mode));
   1188         if (!dynamic_thresh_mode){
   1189             return BCM_E_CONFIG;
   1190         }
   1191 
   1192         BCM_IF_ERROR_RETURN
   1193             (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1194         if (local_port < 0) {
   1195             return BCM_E_PORT;
   1196         }
   1197         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1198 
   1199         /* Expects that cosq is priority group in Tomahawk3
   1200          * Future enhancement is to create gport type of priority group
   1201          */
   1202         if ((cosq < 0) || (cosq >= _TH3_MMU_NUM_PG)) {
   1203             return BCM_E_PARAM;
   1204         }
   1205         port_pg = cosq;
   1206 
   1207         mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDI_PORT_PG_SHARED_CONFIGm)[pipe];
   1208         sal_memset(&entry, 0, sizeof(entry));
   1209         midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port,
   1210                          MMU_THDI_PORT_PG_SHARED_CONFIGm,0);
   1211         BCM_IF_ERROR_RETURN
   1212             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
   1213         soc_mem_field32_set(unit, mem, entry, field_pgshared_limit[port_pg], alpha);
   1214         SOC_IF_ERROR_RETURN
   1215             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry));
   1216     }
   1217 
   1218     return BCM_E_NONE;
   1219 }
   1220 
   1221 
   1222 
   1223 STATIC int
   1224 _bcm_th3_cosq_alpha_get(int unit,
   1225                         bcm_gport_t gport, bcm_cos_queue_t cosq,
   1226                         bcm_cosq_control_drop_limit_alpha_value_t *arg)
   1227 {
   1228     bcm_port_t local_port;
   1229     int startq, midx, pipe;
   1230     uint32 entry[SOC_MAX_MEM_WORDS];
   1231     soc_mem_t mem = INVALIDm;
   1232     int alpha, dynamic_thresh_mode, port_pg;
   1233     soc_field_t field_pgshared_limit[_TH3_MMU_NUM_PG] = {
   1234             PG0_SHARED_LIMITf, PG1_SHARED_LIMITf, PG2_SHARED_LIMITf,
   1235             PG3_SHARED_LIMITf, PG4_SHARED_LIMITf, PG5_SHARED_LIMITf,
   1236             PG6_SHARED_LIMITf, PG7_SHARED_LIMITf};
   1237 
   1238 
   1239     if (!arg) {
   1240         return BCM_E_PARAM;
   1241     }
   1242 
   1243     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1244         BCM_IF_ERROR_RETURN
   1245                 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq,
   1246                                    bcmCosqControlEgressUCSharedDynamicEnable,
   1247                                    &dynamic_thresh_mode));
   1248         if (!dynamic_thresh_mode){
   1249             return BCM_E_CONFIG;
   1250         }
   1251 
   1252         BCM_IF_ERROR_RETURN
   1253             (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1254                                      _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1255                                      &local_port, &startq, NULL));
   1256         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1257 
   1258         mem = MMU_THDO_QUEUE_CONFIGm;
   1259 
   1260         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL,
   1261                                  startq, entry));
   1262         alpha = soc_mem_field32_get(unit, mem, entry, SHARED_ALPHAf);
   1263 
   1264     } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1265         BCM_IF_ERROR_RETURN
   1266                 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq,
   1267                                    bcmCosqControlEgressMCSharedDynamicEnable,
   1268                                    &dynamic_thresh_mode));
   1269         if (!dynamic_thresh_mode){
   1270             return BCM_E_CONFIG;
   1271         }
   1272 
   1273         BCM_IF_ERROR_RETURN
   1274             (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1275                                      _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1276                                      &local_port, &startq, NULL));
   1277         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1278 
   1279         mem = MMU_THDO_QUEUE_CONFIGm;
   1280         BCM_IF_ERROR_RETURN
   1281             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1282         alpha = soc_mem_field32_get(unit, mem, entry, SHARED_ALPHAf);
   1283 
   1284     } else {
   1285         BCM_IF_ERROR_RETURN
   1286                 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq,
   1287                                    bcmCosqControlIngressPortPGSharedDynamicEnable,
   1288                                    &dynamic_thresh_mode));
   1289         if (!dynamic_thresh_mode){
   1290             return BCM_E_CONFIG;
   1291         }
   1292 
   1293         BCM_IF_ERROR_RETURN
   1294             (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1295         if (local_port < 0) {
   1296             return BCM_E_PORT;
   1297         }
   1298 
   1299         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1300 
   1301         /* Expects that cosq is priority group in Tomahawk3
   1302          * Future enhancement is to create gport type of priority group
   1303          */
   1304         if ((cosq < 0) || (cosq >= _TH3_MMU_NUM_PG)) {
   1305             return BCM_E_PARAM;
   1306         }
   1307         port_pg = cosq;
   1308 
   1309         mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDI_PORT_PG_SHARED_CONFIGm)[pipe];
   1310         sal_memset(&entry, 0, sizeof(entry));
   1311         midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port,
   1312                          MMU_THDI_PORT_PG_SHARED_CONFIGm,0);
   1313         BCM_IF_ERROR_RETURN
   1314             (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
   1315         alpha = soc_mem_field32_get(unit, mem, entry, field_pgshared_limit[port_pg]);
   1316     }
   1317 
   1318     switch(alpha) {
   1319     case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_128:
   1320         *arg = bcmCosqControlDropLimitAlpha_1_128;
   1321         break;
   1322     case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_64:
   1323         *arg = bcmCosqControlDropLimitAlpha_1_64;
   1324         break;
   1325     case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_32:
   1326         *arg = bcmCosqControlDropLimitAlpha_1_32;
   1327         break;
   1328     case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_16:
   1329         *arg = bcmCosqControlDropLimitAlpha_1_16;
   1330         break;
   1331     case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_8:
   1332         *arg = bcmCosqControlDropLimitAlpha_1_8;
   1333         break;
   1334     case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_4:
   1335         *arg = bcmCosqControlDropLimitAlpha_1_4;
   1336         break;
   1337     case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_2:
   1338         *arg = bcmCosqControlDropLimitAlpha_1_2;
   1339         break;
   1340     case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1:
   1341         *arg = bcmCosqControlDropLimitAlpha_1;
   1342         break;
   1343     case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_2:
   1344         *arg = bcmCosqControlDropLimitAlpha_2;
   1345         break;
   1346     case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_4:
   1347         *arg = bcmCosqControlDropLimitAlpha_4;
   1348         break;
   1349     case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_8:
   1350         *arg = bcmCosqControlDropLimitAlpha_8;
   1351         break;
   1352     default:
   1353         return BCM_E_PARAM;
   1354     }
   1355 
   1356     return BCM_E_NONE;
   1357 }
   1358 
   1359 /*
   1360  * Function: _bcm_th3_cosq_egr_queue_color_limit_set
   1361  * Purpose: Set Red and Yellow color limit per queue
   1362  *          IF color mode dynamic: limit should be between 0-7
   1363  *                                 0: 100% of green threshold
   1364  *                                 1: 12.5% of green threshold
   1365  *                                 2: 25% of green threshold
   1366  *                                 3: 37.5% of green threshold
   1367  *                                 4: 50% of green threshold
   1368  *                                 5: 67.5% of green threshold
   1369  *                                 6: 75% of green threshold
   1370  *                                 7: 87.5% of green threshold
   1371  *          If color mode static: Limit is number of bytes
   1372 */
   1373 
   1374 STATIC int
   1375 _bcm_th3_cosq_egr_queue_color_limit_set(int unit, bcm_gport_t gport,
   1376                                         bcm_cos_queue_t cosq,
   1377                                         bcm_cosq_control_t type,
   1378                                         int arg)
   1379 {
   1380     bcm_port_t local_port;
   1381     int startq, pipe;
   1382     uint32 entry[SOC_MAX_MEM_WORDS];
   1383     soc_mem_t mem = INVALIDm;
   1384     soc_field_t fld_limit = INVALIDf;
   1385     int color_mode, granularity, max_val;
   1386 
   1387     if (arg < 0) {
   1388         return BCM_E_PARAM;
   1389     }
   1390     granularity = 8;
   1391 
   1392     if ((type == bcmCosqControlEgressUCQueueRedLimit) ||
   1393         (type == bcmCosqControlEgressUCQueueYellowLimit)) {
   1394         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1395             BCM_IF_ERROR_RETURN
   1396                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1397                                             _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1398                                             &local_port, &startq, NULL));
   1399         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1400             return BCM_E_PARAM;
   1401         } else {
   1402             if (cosq < 0) {
   1403                 return BCM_E_PARAM;
   1404             }
   1405             BCM_IF_ERROR_RETURN
   1406                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1407             if (local_port < 0) {
   1408                 return BCM_E_PORT;
   1409             }
   1410             BCM_IF_ERROR_RETURN
   1411                 (_bcm_th3_cosq_index_resolve
   1412                  (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1413                   NULL, &startq, NULL));
   1414         }
   1415 
   1416         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1417 
   1418         if (type == bcmCosqControlEgressUCQueueRedLimit) {
   1419             fld_limit = LIMIT_REDf;
   1420         } else {
   1421             fld_limit = LIMIT_YELLOWf;
   1422         }
   1423 
   1424         mem = MMU_THDO_QUEUE_CONFIGm;
   1425         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1426         color_mode = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf);
   1427 
   1428         if (color_mode == 1) { /* Dynamic color limit */
   1429             if (arg > 7) { /* Legal values are 0 - 7 */
   1430                 return BCM_E_PARAM;
   1431             } else {
   1432                 soc_mem_field32_set(unit, mem, entry, fld_limit, arg);
   1433             }
   1434         } else { /* Static color limit */
   1435             arg = (arg + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL;
   1436 
   1437             /* Check for min/max values */
   1438             max_val = (1 << soc_mem_field_length(unit, mem, fld_limit)) - 1;
   1439             if ((arg < 0) || ((arg/granularity) > max_val)) {
   1440                 return BCM_E_PARAM;
   1441             } else {
   1442                 soc_mem_field32_set(unit, mem, entry, fld_limit, (arg/granularity));
   1443             }
   1444         }
   1445         BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1446     } else if ((type == bcmCosqControlEgressMCQueueRedLimit) ||
   1447                (type == bcmCosqControlEgressMCQueueYellowLimit)) {
   1448         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1449             return BCM_E_PARAM;
   1450         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1451             BCM_IF_ERROR_RETURN
   1452                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1453                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1454                                             &local_port, &startq, NULL));
   1455         } else {
   1456             if (cosq < 0) {
   1457                 return BCM_E_PARAM;
   1458             }
   1459             BCM_IF_ERROR_RETURN
   1460                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1461             if (local_port < 0) {
   1462                 return BCM_E_PORT;
   1463             }
   1464             BCM_IF_ERROR_RETURN
   1465                 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq,
   1466                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1467                                             NULL, &startq, NULL));
   1468         }
   1469 
   1470         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1471 
   1472         if (type == bcmCosqControlEgressMCQueueRedLimit) {
   1473             fld_limit = LIMIT_REDf;
   1474         } else {
   1475             fld_limit = LIMIT_YELLOWf;
   1476         }
   1477 
   1478         mem = MMU_THDO_QUEUE_CONFIGm;
   1479         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1480         color_mode = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf);
   1481 
   1482         if (color_mode == 1) { /* Dynamic color limit */
   1483             if (arg > 7) { /* Legal values are 0 - 7 */
   1484                 return BCM_E_PARAM;
   1485             } else {
   1486                 soc_mem_field32_set(unit, mem, entry, fld_limit, arg);
   1487             }
   1488         } else { /* Static color limit */
   1489             arg = (arg + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL;
   1490 
   1491             /* Check for min/max values */
   1492             max_val = (1 << soc_mem_field_length(unit, mem, fld_limit)) - 1;
   1493             if ((arg < 0) || ((arg/granularity) > max_val)) {
   1494                 return BCM_E_PARAM;
   1495             } else {
   1496                 soc_mem_field32_set(unit, mem, entry, fld_limit, (arg/granularity));
   1497             }
   1498         }
   1499         BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1500 
   1501     } else {
   1502         return BCM_E_PARAM;
   1503     }
   1504 
   1505     return BCM_E_NONE;
   1506 }
   1507 
   1508 /*
   1509  * Function: _bcm_th3_cosq_egr_queue_color_limit_get
   1510  * Purpose: Get Red and Yellow color limit per queue
   1511  * Return value: IF color mode dynamic: limit should be between 0-7
   1512  *                                 0: 100% of green threshold
   1513  *                                 1: 12.5% of green threshold
   1514  *                                 2: 25% of green threshold
   1515  *                                 3: 37.5% of green threshold
   1516  *                                 4: 50% of green threshold
   1517  *                                 5: 67.5% of green threshold
   1518  *                                 6: 75% of green threshold
   1519  *                                 7: 87.5% of green threshold
   1520  *          If color mode static: Limit is number of bytes
   1521 */
   1522 
   1523 STATIC int
   1524 _bcm_th3_cosq_egr_queue_color_limit_get(int unit, bcm_gport_t gport,
   1525                                         bcm_cos_queue_t cosq,
   1526                                         bcm_cosq_control_t type,
   1527                                         int* arg)
   1528 {
   1529     bcm_port_t local_port;
   1530     int startq, pipe;
   1531     uint32 entry[SOC_MAX_MEM_WORDS];
   1532     soc_mem_t mem = INVALIDm;
   1533     soc_field_t fld_limit = INVALIDf;
   1534     int color_mode, granularity;
   1535 
   1536     if (!arg) {
   1537         return BCM_E_PARAM;
   1538     }
   1539 
   1540     granularity = 8;
   1541 
   1542     if ((type == bcmCosqControlEgressUCQueueRedLimit) ||
   1543         (type == bcmCosqControlEgressUCQueueYellowLimit)) {
   1544         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1545             BCM_IF_ERROR_RETURN
   1546                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1547                                             _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1548                                             &local_port, &startq, NULL));
   1549         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1550             return BCM_E_PARAM;
   1551         } else {
   1552             if (cosq < 0) {
   1553                 return BCM_E_PARAM;
   1554             }
   1555             BCM_IF_ERROR_RETURN
   1556                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1557             if (local_port < 0) {
   1558                 return BCM_E_PORT;
   1559             }
   1560             BCM_IF_ERROR_RETURN
   1561                 (_bcm_th3_cosq_index_resolve
   1562                  (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1563                   NULL, &startq, NULL));
   1564         }
   1565 
   1566         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1567 
   1568         if (type == bcmCosqControlEgressUCQueueRedLimit) {
   1569             fld_limit = LIMIT_REDf;
   1570         } else {
   1571             fld_limit = LIMIT_YELLOWf;
   1572         }
   1573 
   1574         mem = MMU_THDO_QUEUE_CONFIGm;
   1575         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1576         color_mode = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf);
   1577 
   1578         if (color_mode == 1) { /* Dynamic color limit */
   1579             *arg = soc_mem_field32_get(unit, mem, entry, fld_limit);
   1580         } else { /* Static color limit */
   1581             *arg = soc_mem_field32_get(unit, mem, entry, fld_limit);
   1582             *arg = (*arg) * granularity * _TH3_MMU_BYTES_PER_CELL;
   1583         }
   1584     } else if ((type == bcmCosqControlEgressMCQueueRedLimit) ||
   1585                (type == bcmCosqControlEgressMCQueueYellowLimit)) {
   1586         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1587             return BCM_E_PARAM;
   1588         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1589             BCM_IF_ERROR_RETURN
   1590                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1591                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1592                                             &local_port, &startq, NULL));
   1593         } else {
   1594             if (cosq < 0) {
   1595                 return BCM_E_PARAM;
   1596             }
   1597             BCM_IF_ERROR_RETURN
   1598                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1599             if (local_port < 0) {
   1600                 return BCM_E_PORT;
   1601             }
   1602             BCM_IF_ERROR_RETURN
   1603                 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq,
   1604                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1605                                             NULL, &startq, NULL));
   1606         }
   1607 
   1608         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1609 
   1610         if (type == bcmCosqControlEgressMCQueueRedLimit) {
   1611             fld_limit = LIMIT_REDf;
   1612         } else {
   1613             fld_limit = LIMIT_YELLOWf;
   1614         }
   1615 
   1616         mem = MMU_THDO_QUEUE_CONFIGm;
   1617         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1618         color_mode = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf);
   1619 
   1620         if (color_mode == 1) { /* Dynamic color limit */
   1621             *arg = soc_mem_field32_get(unit, mem, entry, fld_limit);
   1622         } else { /* Static color limit */
   1623             *arg = soc_mem_field32_get(unit, mem, entry, fld_limit);
   1624             *arg = (*arg) * granularity * _TH3_MMU_BYTES_PER_CELL;
   1625         }
   1626 
   1627     } else {
   1628         return BCM_E_PARAM;
   1629     }
   1630 
   1631     return BCM_E_NONE;
   1632 }
   1633 
   1634 
   1635 /*
   1636  * Function: _bcm_th3_cosq_egr_queue_color_limit_mode_set
   1637  * Purpose: Set color limit mode per queue to static (0) or
   1638  *          dynamic (1)
   1639 */
   1640 
   1641 STATIC int
   1642 _bcm_th3_cosq_egr_queue_color_limit_mode_set(int unit, bcm_gport_t gport,
   1643                                              bcm_cos_queue_t cosq,
   1644                                              bcm_cosq_control_t type,
   1645                                              int arg)
   1646 {
   1647     bcm_port_t local_port;
   1648     int startq, pipe;
   1649     uint32 entry[SOC_MAX_MEM_WORDS];
   1650     soc_mem_t mem = INVALIDm;
   1651     int enable;
   1652 
   1653     if (arg < 0) {
   1654         return BCM_E_PARAM;
   1655     }
   1656 
   1657     arg = arg ? 1 : 0;
   1658 
   1659     if (type == bcmCosqControlEgressUCQueueColorLimitDynamicEnable) {
   1660         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1661             BCM_IF_ERROR_RETURN
   1662                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1663                                             _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1664                                             &local_port, &startq, NULL));
   1665         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1666             return BCM_E_PARAM;
   1667         } else {
   1668             if (cosq < 0) {
   1669                 return BCM_E_PARAM;
   1670             }
   1671             BCM_IF_ERROR_RETURN
   1672                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1673             if (local_port < 0) {
   1674                 return BCM_E_PORT;
   1675             }
   1676             BCM_IF_ERROR_RETURN
   1677                 (_bcm_th3_cosq_index_resolve
   1678                  (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1679                   NULL, &startq, NULL));
   1680         }
   1681 
   1682         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1683 
   1684         mem = MMU_THDO_QUEUE_CONFIGm;
   1685         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1686         enable = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf);
   1687         if (enable != arg) {
   1688             soc_mem_field32_set(unit, mem, entry, COLOR_LIMIT_MODEf, arg);
   1689             /* Reset the Red and Yellow limits when color limit mode is changed */
   1690             soc_mem_field32_set(unit, mem, entry, LIMIT_REDf, 0);
   1691             soc_mem_field32_set(unit, mem, entry, LIMIT_YELLOWf, 0);
   1692             BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1693         }
   1694     } else if (type == bcmCosqControlEgressMCQueueColorLimitDynamicEnable) {
   1695         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1696             return BCM_E_PARAM;
   1697         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1698             BCM_IF_ERROR_RETURN
   1699                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1700                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1701                                             &local_port, &startq, NULL));
   1702         } else {
   1703             if (cosq < 0) {
   1704                 return BCM_E_PARAM;
   1705             }
   1706             BCM_IF_ERROR_RETURN
   1707                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1708             if (local_port < 0) {
   1709                 return BCM_E_PORT;
   1710             }
   1711             BCM_IF_ERROR_RETURN
   1712                 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq,
   1713                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1714                                             NULL, &startq, NULL));
   1715         }
   1716 
   1717         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1718 
   1719         mem = MMU_THDO_QUEUE_CONFIGm;
   1720         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1721         enable = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf);
   1722         if (enable != arg) {
   1723             soc_mem_field32_set(unit, mem, entry, COLOR_LIMIT_MODEf, arg);
   1724             /* Reset the Red and Yellow limits when color limit mode is changed */
   1725             soc_mem_field32_set(unit, mem, entry, LIMIT_REDf, 0);
   1726             soc_mem_field32_set(unit, mem, entry, LIMIT_YELLOWf, 0);
   1727             BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1728         }
   1729     } else {
   1730         return BCM_E_PARAM;
   1731     }
   1732 
   1733     return BCM_E_NONE;
   1734 }
   1735 
   1736 /*
   1737  * Function: _bcm_th3_cosq_egr_queue_color_limit_mode_get
   1738  * Purpose: Get color limit mode per queue.
   1739  * Returns: 0 (static) or 1 (dynamic)
   1740 */
   1741 STATIC int
   1742 _bcm_th3_cosq_egr_queue_color_limit_mode_get(int unit, bcm_gport_t gport,
   1743                                              bcm_cos_queue_t cosq,
   1744                                              bcm_cosq_control_t type,
   1745                                              int* arg)
   1746 {
   1747     bcm_port_t local_port;
   1748     int startq, pipe;
   1749     uint32 entry[SOC_MAX_MEM_WORDS];
   1750     soc_mem_t mem = INVALIDm;
   1751 
   1752     if (arg == NULL) {
   1753         return BCM_E_PARAM;
   1754     }
   1755 
   1756     if (type == bcmCosqControlEgressUCQueueColorLimitDynamicEnable) {
   1757         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1758             BCM_IF_ERROR_RETURN
   1759                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1760                                             _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1761                                             &local_port, &startq, NULL));
   1762         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1763             return BCM_E_PARAM;
   1764         } else {
   1765             if (cosq < 0) {
   1766                 return BCM_E_PARAM;
   1767             }
   1768             BCM_IF_ERROR_RETURN
   1769                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1770             if (local_port < 0) {
   1771                 return BCM_E_PORT;
   1772             }
   1773             BCM_IF_ERROR_RETURN
   1774                 (_bcm_th3_cosq_index_resolve
   1775                  (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1776                   NULL, &startq, NULL));
   1777         }
   1778 
   1779         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1780 
   1781         mem = MMU_THDO_QUEUE_CONFIGm;
   1782         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1783         *arg = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf);
   1784     } else if (type == bcmCosqControlEgressMCQueueColorLimitDynamicEnable) {
   1785         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1786             return BCM_E_PARAM;
   1787         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1788             BCM_IF_ERROR_RETURN
   1789                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1790                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1791                                             &local_port, &startq, NULL));
   1792         } else {
   1793             if (cosq < 0) {
   1794                 return BCM_E_PARAM;
   1795             }
   1796             BCM_IF_ERROR_RETURN
   1797                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1798             if (local_port < 0) {
   1799                 return BCM_E_PORT;
   1800             }
   1801             BCM_IF_ERROR_RETURN
   1802                 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq,
   1803                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1804                                             NULL, &startq, NULL));
   1805         }
   1806 
   1807         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1808 
   1809         mem = MMU_THDO_QUEUE_CONFIGm;
   1810         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1811         *arg = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf);
   1812     } else {
   1813         return BCM_E_PARAM;
   1814     }
   1815 
   1816     return BCM_E_NONE;
   1817 }
   1818 
   1819 
   1820 STATIC int
   1821 _bcm_th3_cosq_egr_queue_limit_enable_set(int unit, bcm_gport_t gport,
   1822                                         bcm_cos_queue_t cosq,
   1823                                         bcm_cosq_control_t type,
   1824                                         int arg)
   1825 {
   1826     bcm_port_t local_port;
   1827     int startq, pipe;
   1828     uint32 entry[SOC_MAX_MEM_WORDS];
   1829     soc_mem_t mem = INVALIDm;
   1830     int enable;
   1831 
   1832     if (arg < 0) {
   1833         return BCM_E_PARAM;
   1834     }
   1835 
   1836     arg = arg ? 1 : 0;
   1837 
   1838     if (type == bcmCosqControlEgressUCQueueLimitEnable) {
   1839         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1840             BCM_IF_ERROR_RETURN
   1841                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1842                                             _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1843                                             &local_port, &startq, NULL));
   1844         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1845             return BCM_E_PARAM;
   1846         } else {
   1847             if (cosq < 0) {
   1848                 return BCM_E_PARAM;
   1849             }
   1850             BCM_IF_ERROR_RETURN
   1851                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1852             if (local_port < 0) {
   1853                 return BCM_E_PORT;
   1854             }
   1855             BCM_IF_ERROR_RETURN
   1856                 (_bcm_th3_cosq_index_resolve
   1857                  (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1858                   NULL, &startq, NULL));
   1859         }
   1860 
   1861         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1862 
   1863         mem = MMU_THDO_QUEUE_CONFIGm;
   1864         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1865         enable = soc_mem_field32_get(unit, mem, entry, LIMIT_ENABLEf);
   1866         if (enable != arg) {
   1867             soc_mem_field32_set(unit, mem, entry, LIMIT_ENABLEf, arg);
   1868             BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1869         }
   1870     } else if (type == bcmCosqControlEgressMCQueueLimitEnable) {
   1871         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1872             return BCM_E_PARAM;
   1873         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1874             BCM_IF_ERROR_RETURN
   1875                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1876                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1877                                             &local_port, &startq, NULL));
   1878         } else {
   1879             if (cosq < 0) {
   1880                 return BCM_E_PARAM;
   1881             }
   1882             BCM_IF_ERROR_RETURN
   1883                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1884             if (local_port < 0) {
   1885                 return BCM_E_PORT;
   1886             }
   1887             BCM_IF_ERROR_RETURN
   1888                 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq,
   1889                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1890                                             NULL, &startq, NULL));
   1891         }
   1892 
   1893         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1894 
   1895         mem = MMU_THDO_QUEUE_CONFIGm;
   1896         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1897         enable = soc_mem_field32_get(unit, mem, entry, LIMIT_ENABLEf);
   1898         if (enable != arg) {
   1899             soc_mem_field32_set(unit, mem, entry, LIMIT_ENABLEf, arg);
   1900             BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1901         }
   1902     } else {
   1903         return BCM_E_PARAM;
   1904     }
   1905 
   1906     return BCM_E_NONE;
   1907 }
   1908 
   1909 STATIC int
   1910 _bcm_th3_cosq_egr_queue_limit_enable_get(int unit, bcm_gport_t gport,
   1911                                         bcm_cos_queue_t cosq,
   1912                                         bcm_cosq_control_t type,
   1913                                         int* arg)
   1914 {
   1915     bcm_port_t local_port;
   1916     int startq, pipe;
   1917     uint32 entry[SOC_MAX_MEM_WORDS];
   1918     soc_mem_t mem = INVALIDm;
   1919 
   1920     if (arg == NULL) {
   1921         return BCM_E_PARAM;
   1922     }
   1923 
   1924     if (type == bcmCosqControlEgressUCQueueLimitEnable) {
   1925         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1926             BCM_IF_ERROR_RETURN
   1927                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1928                                             _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1929                                             &local_port, &startq, NULL));
   1930         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1931             return BCM_E_PARAM;
   1932         } else {
   1933             if (cosq < 0) {
   1934                 return BCM_E_PARAM;
   1935             }
   1936             BCM_IF_ERROR_RETURN
   1937                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1938             if (local_port < 0) {
   1939                 return BCM_E_PORT;
   1940             }
   1941             BCM_IF_ERROR_RETURN
   1942                 (_bcm_th3_cosq_index_resolve
   1943                  (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   1944                   NULL, &startq, NULL));
   1945         }
   1946 
   1947         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1948 
   1949         mem = MMU_THDO_QUEUE_CONFIGm;
   1950         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1951         *arg = soc_mem_field32_get(unit, mem, entry, LIMIT_ENABLEf);
   1952     } else if (type == bcmCosqControlEgressMCQueueLimitEnable) {
   1953         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   1954             return BCM_E_PARAM;
   1955         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   1956             BCM_IF_ERROR_RETURN
   1957                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   1958                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1959                                             &local_port, &startq, NULL));
   1960         } else {
   1961             if (cosq < 0) {
   1962                 return BCM_E_PARAM;
   1963             }
   1964             BCM_IF_ERROR_RETURN
   1965                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   1966             if (local_port < 0) {
   1967                 return BCM_E_PORT;
   1968             }
   1969             BCM_IF_ERROR_RETURN
   1970                 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq,
   1971                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   1972                                             NULL, &startq, NULL));
   1973         }
   1974 
   1975         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   1976 
   1977         mem = MMU_THDO_QUEUE_CONFIGm;
   1978         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   1979         *arg = soc_mem_field32_get(unit, mem, entry, LIMIT_ENABLEf);
   1980     } else {
   1981         return BCM_E_PARAM;
   1982     }
   1983 
   1984     return BCM_E_NONE;
   1985 }
   1986 
   1987 /*
   1988  * Function: _bcm_th3_cosq_egr_queue_color_limit_enable_set
   1989  * Purpose: Enable/Disable queue color discard thresholds for color congestion management
   1990  * Set (1) to enable or (0) to disable
   1991 */
   1992 
   1993 STATIC int
   1994 _bcm_th3_cosq_egr_queue_color_limit_enable_set(int unit, bcm_gport_t gport,
   1995                                              bcm_cos_queue_t cosq,
   1996                                              bcm_cosq_control_t type,
   1997                                              int arg)
   1998 {
   1999     bcm_port_t local_port;
   2000     int startq, pipe;
   2001     uint32 entry[SOC_MAX_MEM_WORDS];
   2002     soc_mem_t mem = INVALIDm;
   2003     int enable;
   2004 
   2005     if (arg < 0) {
   2006         return BCM_E_PARAM;
   2007     }
   2008 
   2009     arg = arg ? 1 : 0;
   2010 
   2011     if (type == bcmCosqControlEgressUCQueueColorLimitEnable) {
   2012         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   2013             BCM_IF_ERROR_RETURN
   2014                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   2015                                             _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   2016                                             &local_port, &startq, NULL));
   2017         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   2018             return BCM_E_PARAM;
   2019         } else {
   2020             if (cosq < 0) {
   2021                 return BCM_E_PARAM;
   2022             }
   2023             BCM_IF_ERROR_RETURN
   2024                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   2025             if (local_port < 0) {
   2026                 return BCM_E_PORT;
   2027             }
   2028             BCM_IF_ERROR_RETURN
   2029                 (_bcm_th3_cosq_index_resolve
   2030                  (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   2031                   NULL, &startq, NULL));
   2032         }
   2033 
   2034         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   2035 
   2036         mem = MMU_THDO_QUEUE_CONFIGm;
   2037         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   2038         enable = soc_mem_field32_get(unit, mem, entry, COLOR_ENABLEf);
   2039         if (enable != arg) {
   2040             soc_mem_field32_set(unit, mem, entry, COLOR_ENABLEf, arg);
   2041             BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   2042         }
   2043     } else if (type == bcmCosqControlEgressMCQueueColorLimitEnable) {
   2044         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   2045             return BCM_E_PARAM;
   2046         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   2047             BCM_IF_ERROR_RETURN
   2048                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   2049                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   2050                                             &local_port, &startq, NULL));
   2051         } else {
   2052             if (cosq < 0) {
   2053                 return BCM_E_PARAM;
   2054             }
   2055             BCM_IF_ERROR_RETURN
   2056                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   2057             if (local_port < 0) {
   2058                 return BCM_E_PORT;
   2059             }
   2060             BCM_IF_ERROR_RETURN
   2061                 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq,
   2062                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   2063                                             NULL, &startq, NULL));
   2064         }
   2065 
   2066         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   2067 
   2068         mem = MMU_THDO_QUEUE_CONFIGm;
   2069         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   2070         enable = soc_mem_field32_get(unit, mem, entry, COLOR_ENABLEf);
   2071         if (enable != arg) {
   2072             soc_mem_field32_set(unit, mem, entry, COLOR_ENABLEf, arg);
   2073             BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry));
   2074         }
   2075     } else {
   2076         return BCM_E_PARAM;
   2077     }
   2078 
   2079     return BCM_E_NONE;
   2080 }
   2081 
   2082 /*
   2083  * Function: _bcm_th3_cosq_egr_queue_color_limit_enable_get
   2084  * Purpose: Get color limit enable status per queue.
   2085  * Returns: 0 (disabled) or 1 (enabled)
   2086 */
   2087 STATIC int
   2088 _bcm_th3_cosq_egr_queue_color_limit_enable_get(int unit, bcm_gport_t gport,
   2089                                              bcm_cos_queue_t cosq,
   2090                                              bcm_cosq_control_t type,
   2091                                              int* arg)
   2092 {
   2093     bcm_port_t local_port;
   2094     int startq, pipe;
   2095     uint32 entry[SOC_MAX_MEM_WORDS];
   2096     soc_mem_t mem = INVALIDm;
   2097 
   2098     if (arg == NULL) {
   2099         return BCM_E_PARAM;
   2100     }
   2101 
   2102     if (type == bcmCosqControlEgressUCQueueColorLimitEnable) {
   2103         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   2104             BCM_IF_ERROR_RETURN
   2105                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   2106                                             _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   2107                                             &local_port, &startq, NULL));
   2108         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   2109             return BCM_E_PARAM;
   2110         } else {
   2111             if (cosq < 0) {
   2112                 return BCM_E_PARAM;
   2113             }
   2114             BCM_IF_ERROR_RETURN
   2115                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   2116             if (local_port < 0) {
   2117                 return BCM_E_PORT;
   2118             }
   2119             BCM_IF_ERROR_RETURN
   2120                 (_bcm_th3_cosq_index_resolve
   2121                  (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE,
   2122                   NULL, &startq, NULL));
   2123         }
   2124 
   2125         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   2126 
   2127         mem = MMU_THDO_QUEUE_CONFIGm;
   2128         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   2129         *arg = soc_mem_field32_get(unit, mem, entry, COLOR_ENABLEf);
   2130     } else if (type == bcmCosqControlEgressMCQueueColorLimitEnable) {
   2131         if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) {
   2132             return BCM_E_PARAM;
   2133         } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   2134             BCM_IF_ERROR_RETURN
   2135                 (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   2136                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   2137                                             &local_port, &startq, NULL));
   2138         } else {
   2139             if (cosq < 0) {
   2140                 return BCM_E_PARAM;
   2141             }
   2142             BCM_IF_ERROR_RETURN
   2143                 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   2144             if (local_port < 0) {
   2145                 return BCM_E_PORT;
   2146             }
   2147             BCM_IF_ERROR_RETURN
   2148                 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq,
   2149                                             _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE,
   2150                                             NULL, &startq, NULL));
   2151         }
   2152 
   2153         SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   2154 
   2155         mem = MMU_THDO_QUEUE_CONFIGm;
   2156         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry));
   2157         *arg = soc_mem_field32_get(unit, mem, entry, COLOR_ENABLEf);
   2158     } else {
   2159         return BCM_E_PARAM;
   2160     }
   2161 
   2162     return BCM_E_NONE;
   2163 }
   2164 
   2165 /*
   2166  * This function is used to get ingress pool
   2167  * limit given Ingress [Port, Priority Group]
   2168  */
   2169 STATIC int
   2170 _bcm_th3_cosq_ing_res_limit_get(int unit, bcm_gport_t gport, bcm_cos_t cosq,
   2171                                bcm_cosq_buffer_id_t buffer,
   2172                                bcm_cosq_control_t type, int* arg)
   2173 {
   2174     uint32 rval = 0x0;
   2175     int pool;
   2176     int local_port, pipe, itm, idx;
   2177     soc_reg_t reg = INVALIDr;
   2178     soc_field_t fld_limit = INVALIDf;
   2179 
   2180     if (!arg) {
   2181         return BCM_E_PARAM;
   2182     }
   2183 
   2184     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   2185         BCM_GPORT_IS_SCHEDULER(gport) ||
   2186         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   2187         return BCM_E_PARAM;
   2188     }
   2189     BCM_IF_ERROR_RETURN
   2190             (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   2191 
   2192     if (!SOC_PORT_VALID(unit, local_port)) {
   2193         return BCM_E_PORT;
   2194     }
   2195     if (type == bcmCosqControlIngressPoolLimitBytes) {
   2196         BCM_IF_ERROR_RETURN
   2197             (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq,
   2198                                        bcmCosqControlIngressPool,
   2199                                        &pool));
   2200         reg = MMU_THDI_BUFFER_CELL_LIMIT_SPr;
   2201         fld_limit = LIMITf;
   2202     } else if (type == bcmCosqControlIngressPoolResetOffsetLimitBytes) {
   2203         BCM_IF_ERROR_RETURN
   2204             (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq,
   2205                                        bcmCosqControlIngressPool,
   2206                                        &pool));
   2207         reg = MMU_THDI_CELL_RESET_LIMIT_OFFSET_SPr;
   2208         fld_limit = OFFSETf;
   2209     } else if (type == bcmCosqControlIngressHeadroomPoolLimitBytes) {
   2210         BCM_IF_ERROR_RETURN
   2211             (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq,
   2212                                        bcmCosqControlIngressHeadroomPool,
   2213                                        &pool));
   2214         reg = MMU_THDI_HDRM_BUFFER_CELL_LIMIT_HPr;
   2215         fld_limit = LIMITf;
   2216     } else {
   2217         return BCM_E_PARAM;
   2218     }
   2219     SOC_IF_ERROR_RETURN(
   2220         soc_port_pipe_get(unit, local_port, &pipe));
   2221 
   2222     itm = 0;
   2223     for (idx = 0; idx < NUM_ITM(unit); idx++) {
   2224         if (SOC_INFO(unit).ipipe_itm_map[pipe] & (1 << idx)) {
   2225             itm = idx;
   2226         }
   2227     }
   2228 
   2229     if (buffer != BCM_COSQ_BUFFER_ID_INVALID) { 
   2230         if (!(SOC_INFO(unit).ipipe_itm_map[pipe] & (1 << buffer))) {
   2231             return BCM_E_PARAM;
   2232         }
   2233     }
   2234 
   2235     SOC_IF_ERROR_RETURN(
   2236         soc_tomahawk3_itm_reg32_get(unit, reg,
   2237                                    itm, itm, pool, &rval));
   2238     *arg = soc_reg_field_get(unit, reg, rval, fld_limit);
   2239     *arg = (*arg) * _TH3_MMU_BYTES_PER_CELL;
   2240 
   2241     return BCM_E_NONE;
   2242 }
   2243 
   2244 /*
   2245  * This function is used to set ingress pool
   2246  * limit given Ingress [Port, Priority Group]
   2247  */
   2248 STATIC int
   2249 _bcm_th3_cosq_ing_res_limit_set(int unit, bcm_gport_t gport, bcm_cos_t cosq,
   2250                                bcm_cosq_buffer_id_t buffer,
   2251                                bcm_cosq_control_t type, int arg)
   2252 {
   2253     uint32 rval = 0x0;
   2254     int pool;
   2255     int local_port, pipe, itm, idx;
   2256     soc_reg_t reg = INVALIDr;
   2257     soc_field_t fld_limit = INVALIDf;
   2258     int max_value;
   2259     int pool_limit = 0;
   2260     int headroom_limit = 0;
   2261     int total_limit = 0;
   2262     int mmu_total_cells = 0;
   2263 
   2264     if (arg < 0) {
   2265         return BCM_E_PARAM;
   2266     }
   2267 
   2268     if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
   2269         BCM_GPORT_IS_SCHEDULER(gport) ||
   2270         BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
   2271         return BCM_E_PARAM;
   2272     }
   2273     BCM_IF_ERROR_RETURN
   2274             (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port));
   2275 
   2276     if (!SOC_PORT_VALID(unit, local_port)) {
   2277         return BCM_E_PORT;
   2278     }
   2279 
   2280     BCM_IF_ERROR_RETURN(_bcm_th3_cosq_ing_res_limit_get(
   2281         unit, gport, cosq, buffer,
   2282         bcmCosqControlIngressPoolLimitBytes, &pool_limit));
   2283     BCM_IF_ERROR_RETURN(_bcm_th3_cosq_ing_res_limit_get(
   2284         unit, gport, cosq, buffer,
   2285         bcmCosqControlIngressHeadroomPoolLimitBytes, &headroom_limit));
   2286 
   2287     if (type == bcmCosqControlIngressPoolLimitBytes) {
   2288         BCM_IF_ERROR_RETURN
   2289             (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq,
   2290                                        bcmCosqControlIngressPool,
   2291                                        &pool));
   2292         reg = MMU_THDI_BUFFER_CELL_LIMIT_SPr;
   2293         fld_limit = LIMITf;
   2294         max_value = _TH3_THDI_BUFFER_CELL_LIMIT_SP_MAX;
   2295         total_limit = arg + headroom_limit;
   2296     } else if (type == bcmCosqControlIngressPoolResetOffsetLimitBytes) {
   2297         BCM_IF_ERROR_RETURN
   2298             (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq,
   2299                                        bcmCosqControlIngressPool,
   2300                                        &pool));
   2301         reg = MMU_THDI_CELL_RESET_LIMIT_OFFSET_SPr;
   2302         fld_limit = OFFSETf;
   2303         max_value = _TH3_THDI_BUFFER_CELL_LIMIT_SP_MAX;
   2304     } else if (type == bcmCosqControlIngressHeadroomPoolLimitBytes) {
   2305         BCM_IF_ERROR_RETURN
   2306             (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq,
   2307                                        bcmCosqControlIngressHeadroomPool,
   2308                                        &pool));
   2309         reg = MMU_THDI_HDRM_BUFFER_CELL_LIMIT_HPr;
   2310         fld_limit = LIMITf;
   2311         max_value = _TH3_THDI_HDRM_BUFFER_CELL_LIMIT_HP_MAX;
   2312         total_limit = arg + pool_limit;
   2313     } else {
   2314         return BCM_E_PARAM;
   2315     }
   2316     arg = (arg + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL;
   2317     if (arg > max_value) {
   2318        LOG_WARN(BSL_LS_BCM_COSQ,
   2319            (BSL_META_U(unit, "Warning: Request of %d bytes exceeds maximum of %d bytes\n"),
   2320             arg * _TH3_MMU_BYTES_PER_CELL,
   2321            max_value * _TH3_MMU_BYTES_PER_CELL));
   2322         return BCM_E_PARAM;
   2323     }
   2324 
   2325     total_limit = (total_limit + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL;
   2326     mmu_total_cells = _TH3_MMU_TOTAL_CELLS_PER_ITM;
   2327     if (total_limit > mmu_total_cells) {
   2328        LOG_WARN(BSL_LS_BCM_COSQ,
   2329            (BSL_META_U(unit, "Warning: Total allocation of %d bytes exceeds maximum of %d bytes\n"),
   2330             total_limit * _TH3_MMU_BYTES_PER_CELL,
   2331            mmu_total_cells * _TH3_MMU_BYTES_PER_CELL));
   2332         return BCM_E_PARAM;
   2333     }
   2334 
   2335     soc_reg_field_set(unit, reg, &rval, fld_limit, arg);
   2336     SOC_IF_ERROR_RETURN(
   2337         soc_port_pipe_get(unit, local_port, &pipe));
   2338 
   2339     itm = 0;
   2340     for (idx = 0; idx < NUM_ITM(unit); idx++) {
   2341         if (SOC_INFO(unit).ipipe_itm_map[pipe] & (1 << idx)) {
   2342             itm = idx;
   2343         }
   2344     }
   2345 
   2346     if (buffer != BCM_COSQ_BUFFER_ID_INVALID) { 
   2347         if (!(SOC_INFO(unit).ipipe_itm_map[pipe] & (1 << buffer))) {
   2348             return BCM_E_PARAM;
   2349         }
   2350     }
   2351 
   2352     SOC_IF_ERROR_RETURN(
   2353         soc_tomahawk3_itm_reg32_set(unit, reg,
   2354                                    itm, itm, pool, rval));
   2355 
   2356     if (type == bcmCosqControlIngressPoolLimitBytes) {
   2357         BCM_IF_ERROR_RETURN(
   2358             _bcm_th3_mmu_set_shared_size(unit, itm, arg));
   2359 
   2360     }
   2361 
   2362     return BCM_E_NONE;
   2363 }
   2364 
   2365 
   2366 STATIC int
   2367 _bcm_th3_cosq_egr_port_pool_get(int unit, bcm_gport_t gport,
   2368                                bcm_cos_queue_t cosq,
   2369                                bcm_cosq_control_t type, int* arg)
   2370 {
   2371     bcm_port_t local_port;
   2372     uint32 entry[SOC_MAX_MEM_WORDS];
   2373     soc_mem_t mem = INVALIDm;
   2374     soc_field_t fld_limit = INVALIDf;
   2375     int granularity = 1;
   2376     int pool, midx, pipe;
   2377     int gport_type = 0;
   2378 
   2379     if (!arg) {
   2380         return BCM_E_PARAM;
   2381     }
   2382 
   2383     BCM_IF_ERROR_RETURN
   2384         (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   2385                                     _BCM_TH3_COSQ_INDEX_STYLE_EGR_POOL,
   2386                                     &local_port, &pool, NULL));
   2387     SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   2388 
   2389     gport_type = BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
   2390                  BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport);
   2391 
   2392     if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
   2393        (!gport_type && (cosq >= _bcm_th3_get_num_ucq(unit)))) {
   2394         switch (type) {
   2395             case bcmCosqControlEgressPortPoolYellowLimitBytes:
   2396                 fld_limit = SP_YELLOW_LIMITf;
   2397                 granularity = 8;
   2398                 mem = MMU_THDO_CONFIG_PORTSP_MCm;
   2399                 break;
   2400             case bcmCosqControlEgressPortPoolRedLimitBytes:
   2401                 fld_limit = SP_RED_LIMITf;
   2402                 granularity = 8;
   2403                 mem = MMU_THDO_CONFIG_PORTSP_MCm;
   2404                 break;
   2405             case bcmCosqControlEgressPortPoolSharedLimitBytes:
   2406                 fld_limit = SP_SHARED_LIMITf;
   2407                 mem = MMU_THDO_CONFIG_PORTSP_MCm;
   2408                 break;
   2409             case bcmCosqControlEgressPortPoolSharedResumeBytes:
   2410                 granularity = 8;
   2411                 fld_limit = SHARED_RESUMEf;
   2412                 mem = MMU_THDO_RESUME_PORT_MC0m;
   2413                 break;
   2414             case bcmCosqControlEgressPortPoolYellowResumeBytes:
   2415                 granularity = 8;
   2416                 fld_limit = YELLOW_RESUMEf;
   2417                 mem = MMU_THDO_RESUME_PORT_MC0m;
   2418                 break;
   2419             case bcmCosqControlEgressPortPoolRedResumeBytes:
   2420                 granularity = 8;
   2421                 fld_limit = RED_RESUMEf;
   2422                 mem = MMU_THDO_RESUME_PORT_MC0m;
   2423                 break;
   2424             default:
   2425                 return BCM_E_UNAVAIL;
   2426         }
   2427         midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, mem, pool);
   2428         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
   2429 
   2430         *arg = soc_mem_field32_get(unit, mem, entry, fld_limit);
   2431         *arg = (*arg) * granularity * _TH3_MMU_BYTES_PER_CELL;
   2432     } else {
   2433         switch (type) {
   2434             case bcmCosqControlEgressPortPoolYellowLimitBytes:
   2435                 mem = MMU_THDO_CONFIG_PORT_UC0m;
   2436                 switch (pool) {
   2437                     case 0: fld_limit = SP0_YELLOW_LIMITf; break;
   2438                     case 1: fld_limit = SP1_YELLOW_LIMITf; break;
   2439                     case 2: fld_limit = SP2_YELLOW_LIMITf; break;
   2440                     case 3: fld_limit = SP3_YELLOW_LIMITf; break;
   2441                 }
   2442                 granularity = 8;
   2443                 break;
   2444             case bcmCosqControlEgressPortPoolRedLimitBytes:
   2445                 mem = MMU_THDO_CONFIG_PORT_UC0m;
   2446                 switch (pool) {
   2447                     case 0: fld_limit = SP0_RED_LIMITf; break;
   2448                     case 1: fld_limit = SP1_RED_LIMITf; break;
   2449                     case 2: fld_limit = SP2_RED_LIMITf; break;
   2450                     case 3: fld_limit = SP3_RED_LIMITf; break;
   2451                 }
   2452                 granularity = 8;
   2453                 break;
   2454             case bcmCosqControlEgressPortPoolSharedLimitBytes:
   2455                 mem = MMU_THDO_CONFIG_PORT_UC0m;
   2456                 switch (pool) {
   2457                     case 0: fld_limit = SP0_SHARED_LIMITf; break;
   2458                     case 1: fld_limit = SP1_SHARED_LIMITf; break;
   2459                     case 2: fld_limit = SP2_SHARED_LIMITf; break;
   2460                     case 3: fld_limit = SP3_SHARED_LIMITf; break;
   2461                 }
   2462                 break;
   2463             case bcmCosqControlEgressPortPoolSharedResumeBytes:
   2464                 mem = MMU_THDO_RESUME_PORT_UC0m;
   2465                 fld_limit = SHARED_RESUMEf;
   2466                 granularity = 8;
   2467                 break;
   2468             case bcmCosqControlEgressPortPoolYellowResumeBytes:
   2469                 mem = MMU_THDO_RESUME_PORT_UC0m;
   2470                 fld_limit = YELLOW_RESUMEf;
   2471                 granularity = 8;
   2472                 break;
   2473             case bcmCosqControlEgressPortPoolRedResumeBytes:
   2474                 mem = MMU_THDO_RESUME_PORT_UC0m;
   2475                 fld_limit = RED_RESUMEf;
   2476                 granularity = 8;
   2477                 break;
   2478             default:
   2479                 return BCM_E_UNAVAIL;
   2480         }
   2481         midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, mem, pool);
   2482         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
   2483 
   2484         *arg = soc_mem_field32_get(unit, mem, entry, fld_limit);
   2485         *arg = (*arg) * granularity * _TH3_MMU_BYTES_PER_CELL;
   2486     }
   2487 
   2488     return BCM_E_NONE;
   2489 }
   2490 
   2491 
   2492 STATIC int
   2493 _bcm_th3_cosq_egr_port_pool_set(int unit, bcm_gport_t gport,
   2494                                bcm_cos_queue_t cosq,
   2495                                bcm_cosq_control_t type, int arg)
   2496 {
   2497     bcm_port_t local_port;
   2498     uint32 max_val;
   2499     uint32 entry[SOC_MAX_MEM_WORDS];
   2500     soc_mem_t mem = INVALIDm;
   2501     soc_field_t fld_limit = INVALIDf;
   2502     int granularity = 1;
   2503     int final_value = 0;
   2504     int pool, midx, pipe;
   2505     int gport_type = 0;
   2506 
   2507     if (arg < 0) {
   2508         return BCM_E_PARAM;
   2509     }
   2510 
   2511     BCM_IF_ERROR_RETURN
   2512         (_bcm_th3_cosq_index_resolve(unit, gport, cosq,
   2513                                     _BCM_TH3_COSQ_INDEX_STYLE_EGR_POOL,
   2514                                     &local_port, &pool, NULL));
   2515     SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe));
   2516     gport_type = BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
   2517                  BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport);
   2518 
   2519     if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) ||
   2520        (!gport_type && (cosq >= _bcm_th3_get_num_ucq(unit)))) {
   2521         switch (type) {
   2522             case bcmCosqControlEgressPortPoolYellowLimitBytes:
   2523                 fld_limit = SP_YELLOW_LIMITf;
   2524                 granularity = 8;
   2525                 mem = MMU_THDO_CONFIG_PORTSP_MCm;
   2526                 break;
   2527             case bcmCosqControlEgressPortPoolRedLimitBytes:
   2528                 fld_limit = SP_RED_LIMITf;
   2529                 granularity = 8;
   2530                 mem = MMU_THDO_CONFIG_PORTSP_MCm;
   2531                 break;
   2532             case bcmCosqControlEgressPortPoolSharedLimitBytes:
   2533                 fld_limit = SP_SHARED_LIMITf;
   2534                 mem = MMU_THDO_CONFIG_PORTSP_MCm;
   2535                 break;
   2536             case bcmCosqControlEgressPortPoolSharedResumeBytes:
   2537                 fld_limit = SHARED_RESUMEf;
   2538                 granularity = 8;
   2539                 mem = MMU_THDO_RESUME_PORT_MC0m;
   2540                 break;
   2541             case bcmCosqControlEgressPortPoolYellowResumeBytes:
   2542                 fld_limit = YELLOW_RESUMEf;
   2543                 granularity = 8;
   2544                 mem = MMU_THDO_RESUME_PORT_MC0m;
   2545                 break;
   2546             case bcmCosqControlEgressPortPoolRedResumeBytes:
   2547                 fld_limit = RED_RESUMEf;
   2548                 granularity = 8;
   2549                 mem = MMU_THDO_RESUME_PORT_MC0m;
   2550                 break;
   2551             default:
   2552                 return BCM_E_UNAVAIL;
   2553         }
   2554 
   2555         midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, mem, pool);
   2556         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
   2557         final_value = (arg + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL;
   2558 
   2559         /* Check for min/max values */
   2560         max_val = (1 << soc_mem_field_length(unit, mem, fld_limit)) - 1;
   2561         if ((final_value < 0) || ((final_value/granularity) > max_val)) {
   2562              return BCM_E_PARAM;
   2563         } else {
   2564              soc_mem_field32_set(unit, mem, entry, fld_limit, (final_value/granularity));
   2565         }
   2566         BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry));
   2567     } else {
   2568        switch (type) {
   2569            case bcmCosqControlEgressPortPoolYellowLimitBytes:
   2570                mem = MMU_THDO_CONFIG_PORT_UC0m;
   2571                switch (pool) {
   2572                   case 0: fld_limit = SP0_YELLOW_LIMITf; break;
   2573                   case 1: fld_limit = SP1_YELLOW_LIMITf; break;
   2574                   case 2: fld_limit = SP2_YELLOW_LIMITf; break;
   2575                   case 3: fld_limit = SP3_YELLOW_LIMITf; break;
   2576                }
   2577                granularity = 8;
   2578                break;
   2579            case bcmCosqControlEgressPortPoolRedLimitBytes:
   2580                mem = MMU_THDO_CONFIG_PORT_UC0m;
   2581                switch (pool) {
   2582                   case 0: fld_limit = SP0_RED_LIMITf; break;
   2583                   case 1: fld_limit = SP1_RED_LIMITf; break;
   2584                   case 2: fld_limit = SP2_RED_LIMITf; break;
   2585                   case 3: fld_limit = SP3_RED_LIMITf; break;
   2586                }
   2587                granularity = 8;
   2588                break;
   2589            case bcmCosqControlEgressPortPoolSharedLimitBytes:
   2590                mem = MMU_THDO_CONFIG_PORT_UC0m;
   2591                switch (pool) {
   2592                   case 0: fld_limit = SP0_SHARED_LIMITf; break;
   2593                   case 1: fld_limit = SP1_SHARED_LIMITf; break;
   2594                   case 2: fld_limit = SP2_SHARED_LIMITf; break;
   2595                   case 3: fld_limit = SP3_SHARED_LIMITf; break;
   2596                }
   2597                break;
   2598            case bcmCosqControlEgressPortPoolSharedResumeBytes:
   2599                mem = MMU_THDO_RESUME_PORT_UC0m;
   2600                fld_limit = SHARED_RESUMEf;
   2601                granularity = 8;
   2602                break;
   2603            case bcmCosqControlEgressPortPoolRedResumeBytes:
   2604                mem = MMU_THDO_RESUME_PORT_UC0m;
   2605                fld_limit = RED_RESUMEf;
   2606                granularity = 8;
   2607                break;
   2608            case bcmCosqControlEgressPortPoolYellowResumeBytes:
   2609                mem = MMU_THDO_RESUME_PORT_UC0m;
   2610                fld_limit = YELLOW_RESUMEf;
   2611                granularity = 8;
   2612                break;
   2613            default:
   2614                return BCM_E_UNAVAIL;
   2615        }
   2616 
   2617        final_value = (arg + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL;
   2618        midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, mem, pool);
   2619        BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry));
   2620 
   2621        /* Check for min/max values */
   2622        max_val = (1 << soc_mem_field_length(unit, mem, fld_limit)) - 1;
   2623        if ((final_value < 0) || ((final_value/granularity) > max_val)) {
   2624            return BCM_E_PARAM;
   2625        } else {
   2626            soc_mem_field32_set(unit, mem, entry, fld_limit, (final_value/granularity));
   2627        }
   2628        BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry));
   2629     }
   2630 
   2631     return BCM_E_NONE;
   2632 }
   2633 
   2634 
   2635 /*
   2636  * Function:
   2637  *      bcm_th3_cosq_control_set
   2638  * Purpose:
   2639  *      Set specified feature configuration
   2640  *
   2641  * Parameters:
   2642  *      unit - (IN) Unit number.
   2643  *      port - (IN) GPORT ID.
   2644  *      cosq - (IN) COS queue.
   2645  *      buffer-(IN) XPE ID
   2646  *      type - (IN) feature
   2647  *      arg  - (IN) feature value
   2648  * Returns:
   2649  *      BCM_E_XXX
   2650  * Notes:
   2651  */
   2652 int
   2653 bcm_th3_cosq_control_set(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
   2654                         bcm_cosq_buffer_id_t buffer,
   2655                         bcm_cosq_control_t type, int arg)
   2656 {
   2657     uint32 kbits_burst_min, kbits_burst_max;
   2658     uint32 kbits_burst;
   2659 
   2660     kbits_burst_min = 0;
   2661     kbits_burst_max = 0;
   2662 
   2663     COMPILER_REFERENCE(kbits_burst_min);
   2664     COMPILER_REFERENCE(kbits_burst_max);
   2665 
   2666     switch (type) {
   2667         case bcmCosqControlBandwidthBurstMax:
   2668             kbits_burst = arg & 0x7fffffff;
   2669             BCM_IF_ERROR_RETURN
   2670                 (bcm_th3_cosq_gport_bandwidth_burst_get(unit, gport, cosq,
   2671                                                        &kbits_burst_min,
   2672                                                        &kbits_burst_max));
   2673             return bcm_th3_cosq_gport_bandwidth_burst_set(unit, gport, cosq,
   2674                                                          kbits_burst_min,
   2675                                                          kbits_burst);
   2676         case bcmCosqControlBandwidthBurstMin:
   2677             kbits_burst = arg & 0x7fffffff;
   2678             BCM_IF_ERROR_RETURN
   2679                 (bcm_th3_cosq_gport_bandwidth_burst_get(unit, gport, cosq,
   2680                                                        &kbits_burst_min,
   2681                                                        &kbits_burst_max));
   2682             return bcm_th3_cosq_gport_bandwidth_burst_set(unit, gport, cosq,
   2683                                                          kbits_burst,
   2684                                                          kbits_burst_max);
   2685         case bcmCosqControlEgressPool:
   2686         case bcmCosqControlEgressPoolLimitBytes:
   2687         case bcmCosqControlEgressPoolYellowLimitBytes:
   2688         case bcmCosqControlEgressPoolRedLimitBytes:
   2689         case bcmCosqControlEgressPoolLimitEnable:
   2690         case bcmCosqControlUCEgressPool:
   2691         case bcmCosqControlMCEgressPool:
   2692         case bcmCosqControlEgressPoolSharedLimitBytes:
   2693         case bcmCosqControlEgressPoolResumeLimitBytes:
   2694         case bcmCosqControlEgressPoolYellowSharedLimitBytes:
   2695         case bcmCosqControlEgressPoolYellowResumeLimitBytes:
   2696         case bcmCosqControlEgressPoolRedSharedLimitBytes:
   2697         case bcmCosqControlEgressPoolRedResumeLimitBytes:
   2698         case bcmCosqControlEgressPoolHighCongestionLimitBytes:
   2699         case bcmCosqControlEgressPoolLowCongestionLimitBytes:
   2700             return _bcm_th3_cosq_egr_pool_set(unit, gport, cosq, buffer, type, arg);
   2701         case bcmCosqControlEgressUCQueueSharedLimitBytes:
   2702         case bcmCosqControlEgressMCQueueSharedLimitBytes:
   2703         case bcmCosqControlEgressUCQueueMinLimitBytes:
   2704         case bcmCosqControlEgressMCQueueMinLimitBytes:
   2705         case bcmCosqControlEgressUCQueueResumeOffsetBytes:
   2706         case bcmCosqControlEgressMCQueueResumeOffsetBytes:
   2707             return _bcm_th3_cosq_egr_queue_set(unit, gport, cosq, type, arg);
   2708         case bcmCosqControlIngressPortPGSharedLimitBytes:
   2709         case bcmCosqControlIngressPortPGMinLimitBytes:
   2710         case bcmCosqControlIngressPortPoolMinLimitBytes:
   2711         case bcmCosqControlIngressPortPoolSharedLimitBytes:
   2712         case bcmCosqControlIngressPortPGHeadroomLimitBytes:
   2713         case bcmCosqControlIngressPortPGResetFloorBytes:
   2714         case bcmCosqControlIngressPortPGResetOffsetBytes:
   2715         case bcmCosqControlIngressPortPoolResumeLimitBytes:
   2716             return _bcm_th3_cosq_ing_res_set(unit, gport, cosq, type, arg);
   2717         case bcmCosqControlIngressPool:
   2718         case bcmCosqControlIngressHeadroomPool:
   2719             /*
   2720              * This function is used to set headroom pool
   2721              * or shared pool for given Ingress [Port, Priority]
   2722              */
   2723             return _bcm_th3_cosq_ing_pool_set(unit, gport, cosq, type, arg);
   2724         case bcmCosqControlDropLimitAlpha:
   2725             return _bcm_th3_cosq_alpha_set(unit, gport, cosq,
   2726                                 (bcm_cosq_control_drop_limit_alpha_value_t)arg);
   2727         case bcmCosqControlIngressPortPGSharedDynamicEnable:
   2728         case bcmCosqControlEgressUCSharedDynamicEnable:
   2729         case bcmCosqControlEgressMCSharedDynamicEnable:
   2730             return _bcm_th3_cosq_dynamic_thresh_enable_set(unit, gport, cosq,
   2731                                                           type, arg);
   2732         case bcmCosqControlEgressPortPoolYellowLimitBytes:
   2733         case bcmCosqControlEgressPortPoolRedLimitBytes:
   2734         case bcmCosqControlEgressPortPoolSharedLimitBytes:
   2735         case bcmCosqControlEgressPortPoolSharedResumeBytes:
   2736         case bcmCosqControlEgressPortPoolYellowResumeBytes:
   2737         case bcmCosqControlEgressPortPoolRedResumeBytes:
   2738             return _bcm_th3_cosq_egr_port_pool_set(unit, gport, cosq, type, arg);
   2739         case bcmCosqControlEgressUCQueueLimitEnable:
   2740         case bcmCosqControlEgressMCQueueLimitEnable:
   2741             return _bcm_th3_cosq_egr_queue_limit_enable_set(unit, gport, cosq,
   2742                                                            type, arg);
   2743         case bcmCosqControlIngressPoolLimitBytes:
   2744         case bcmCosqControlIngressPoolResetOffsetLimitBytes:
   2745         case bcmCosqControlIngressHeadroomPoolLimitBytes:
   2746             return _bcm_th3_cosq_ing_res_limit_set(unit, gport, cosq, buffer, type, arg);
   2747         case bcmCosqControlEgressUCQueueGroupMinEnable:
   2748         case bcmCosqControlEgressMCQueueGroupMinEnable:
   2749             return _bcm_th3_cosq_qgroup_limit_enables_set(unit, gport, cosq,
   2750                     type, arg);
   2751         case bcmCosqControlEgressUCQueueGroupMinLimitBytes:
   2752         case bcmCosqControlEgressMCQueueGroupMinLimitBytes:
   2753             return _bcm_th3_cosq_qgroup_limit_set(unit, gport, cosq, type, arg);
   2754         case bcmCosqControlEgressUCQueueColorLimitDynamicEnable:
   2755         case bcmCosqControlEgressMCQueueColorLimitDynamicEnable:
   2756             return _bcm_th3_cosq_egr_queue_color_limit_mode_set(unit, gport, cosq,
   2757                                                            type, arg);
   2758         case bcmCosqControlEgressUCQueueColorLimitEnable:
   2759         case bcmCosqControlEgressMCQueueColorLimitEnable:
   2760             return _bcm_th3_cosq_egr_queue_color_limit_enable_set(unit, gport, cosq,
   2761                                                            type, arg);
   2762         case bcmCosqControlEgressUCQueueRedLimit:
   2763         case bcmCosqControlEgressUCQueueYellowLimit:
   2764         case bcmCosqControlEgressMCQueueRedLimit:
   2765         case bcmCosqControlEgressMCQueueYellowLimit:
   2766             return _bcm_th3_cosq_egr_queue_color_limit_set(unit, gport, cosq, type, arg);
   2767         default:
   2768             break;
   2769     }
   2770     return BCM_E_UNAVAIL;
   2771 }
   2772 
   2773 /*
   2774  * Function:
   2775  *      bcm_th3_cosq_control_get
   2776  * Purpose:
   2777  *      Get specified feature configuration
   2778  *
   2779  * Parameters:
   2780  *      unit - (IN) Unit number.
   2781  *      port - (IN) GPORT ID.
   2782  *      cosq - (IN) COS queue.
   2783  *      buffer-(IN) XPE ID
   2784  *      type - (IN) feature
   2785  *      arg  - (OUT) feature value
   2786  * Returns:
   2787  *      BCM_E_XXX
   2788  * Notes:
   2789  */
   2790 
   2791 int
   2792 bcm_th3_cosq_control_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq,
   2793                         bcm_cosq_buffer_id_t buffer,
   2794                         bcm_cosq_control_t type, int *arg)
   2795 {
   2796     uint32 kburst_tmp, kbits_burst;
   2797 
   2798     switch (type) {
   2799         case bcmCosqControlBandwidthBurstMax:
   2800             BCM_IF_ERROR_RETURN
   2801                 (bcm_th3_cosq_gport_bandwidth_burst_get(unit, gport, cosq,
   2802                                                        &kburst_tmp,
   2803                                                        &kbits_burst));
   2804             *arg = kbits_burst & 0x7fffffff;
   2805             return BCM_E_NONE;
   2806         case bcmCosqControlBandwidthBurstMin:
   2807             return bcm_th3_cosq_gport_bandwidth_burst_get(unit, gport, cosq,
   2808                                                          (uint32*)arg,
   2809                                                          &kburst_tmp);
   2810         case bcmCosqControlEgressPool:
   2811         case bcmCosqControlEgressPoolLimitBytes:
   2812         case bcmCosqControlEgressPoolYellowLimitBytes:
   2813         case bcmCosqControlEgressPoolRedLimitBytes:
   2814         case bcmCosqControlEgressPoolLimitEnable:
   2815         case bcmCosqControlUCEgressPool:
   2816         case bcmCosqControlMCEgressPool:
   2817         case bcmCosqControlEgressPoolSharedLimitBytes:
   2818         case bcmCosqControlEgressPoolResumeLimitBytes:
   2819         case bcmCosqControlEgressPoolYellowSharedLimitBytes:
   2820         case bcmCosqControlEgressPoolYellowResumeLimitBytes:
   2821         case bcmCosqControlEgressPoolRedSharedLimitBytes:
   2822         case bcmCosqControlEgressPoolRedResumeLimitBytes:
   2823         case bcmCosqControlEgressPoolHighCongestionLimitBytes:
   2824         case bcmCosqControlEgressPoolLowCongestionLimitBytes:
   2825             return _bcm_th3_cosq_egr_pool_get(unit, gport, cosq, buffer, type, arg);
   2826         case bcmCosqControlEgressUCQueueSharedLimitBytes:
   2827         case bcmCosqControlEgressMCQueueSharedLimitBytes:
   2828         case bcmCosqControlEgressUCQueueMinLimitBytes:
   2829         case bcmCosqControlEgressMCQueueMinLimitBytes:
   2830         case bcmCosqControlEgressUCQueueResumeOffsetBytes:
   2831         case bcmCosqControlEgressMCQueueResumeOffsetBytes:
   2832             return _bcm_th3_cosq_egr_queue_get(unit, gport, cosq, type, arg);
   2833         case bcmCosqControlIngressPortPGSharedLimitBytes:
   2834         case bcmCosqControlIngressPortPGMinLimitBytes:
   2835         case bcmCosqControlIngressPortPoolMinLimitBytes:
   2836         case bcmCosqControlIngressPortPoolSharedLimitBytes:
   2837         case bcmCosqControlIngressPortPGHeadroomLimitBytes:
   2838         case bcmCosqControlIngressPortPGResetFloorBytes:
   2839         case bcmCosqControlIngressPortPGResetOffsetBytes:
   2840         case bcmCosqControlIngressPortPoolResumeLimitBytes:
   2841             return _bcm_th3_cosq_ing_res_get(unit, gport, cosq, type, arg);
   2842         case bcmCosqControlIngressPool:
   2843         case bcmCosqControlIngressHeadroomPool:
   2844             /*
   2845              * This function is used to set headroom pool
   2846              * or shared pool for given Ingress [Port, Priority]
   2847              */
   2848             return _bcm_th3_cosq_ing_pool_get(unit, gport, cosq, type, arg);
   2849         case bcmCosqControlDropLimitAlpha:
   2850             return _bcm_th3_cosq_alpha_get(unit, gport, cosq,
   2851                                 (bcm_cosq_control_drop_limit_alpha_value_t *)arg);
   2852         case bcmCosqControlIngressPortPGSharedDynamicEnable:
   2853         case bcmCosqControlEgressUCSharedDynamicEnable:
   2854         case bcmCosqControlEgressMCSharedDynamicEnable:
   2855             return _bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq,
   2856                                                           type, arg);
   2857         case bcmCosqControlEgressPortPoolYellowLimitBytes:
   2858         case bcmCosqControlEgressPortPoolRedLimitBytes:
   2859         case bcmCosqControlEgressPortPoolSharedLimitBytes:
   2860         case bcmCosqControlEgressPortPoolSharedResumeBytes:
   2861         case bcmCosqControlEgressPortPoolYellowResumeBytes:
   2862         case bcmCosqControlEgressPortPoolRedResumeBytes:
   2863             return _bcm_th3_cosq_egr_port_pool_get(unit, gport, cosq, type, arg);
   2864         case bcmCosqControlEgressUCQueueLimitEnable:
   2865         case bcmCosqControlEgressMCQueueLimitEnable:
   2866             return _bcm_th3_cosq_egr_queue_limit_enable_get(unit, gport, cosq,
   2867                                                            type, arg);
   2868         case bcmCosqControlIngressPoolLimitBytes:
   2869         case bcmCosqControlIngressPoolResetOffsetLimitBytes:
   2870         case bcmCosqControlIngressHeadroomPoolLimitBytes:
   2871             return _bcm_th3_cosq_ing_res_limit_get(unit, gport, cosq, buffer, type, arg);
   2872         case bcmCosqControlEgressUCQueueGroupMinEnable:
   2873         case bcmCosqControlEgressMCQueueGroupMinEnable:
   2874             return _bcm_th3_cosq_qgroup_limit_enables_get(unit, gport, cosq,
   2875                     type, arg);
   2876         case bcmCosqControlEgressUCQueueGroupMinLimitBytes:
   2877         case bcmCosqControlEgressMCQueueGroupMinLimitBytes:
   2878             return _bcm_th3_cosq_qgroup_limit_get(unit, gport, cosq, type, arg);
   2879         case bcmCosqControlEgressUCQueueColorLimitDynamicEnable:
   2880         case bcmCosqControlEgressMCQueueColorLimitDynamicEnable:
   2881             return _bcm_th3_cosq_egr_queue_color_limit_mode_get(unit, gport, cosq,
   2882                                                            type, arg);
   2883         case bcmCosqControlEgressUCQueueColorLimitEnable:
   2884         case bcmCosqControlEgressMCQueueColorLimitEnable:
   2885             return _bcm_th3_cosq_egr_queue_color_limit_enable_get(unit, gport, cosq,
   2886                                                            type, arg);
   2887         case bcmCosqControlEgressUCQueueRedLimit:
   2888         case bcmCosqControlEgressUCQueueYellowLimit:
   2889         case bcmCosqControlEgressMCQueueRedLimit:
   2890         case bcmCosqControlEgressMCQueueYellowLimit:
   2891             return _bcm_th3_cosq_egr_queue_color_limit_get(unit, gport, cosq, type, arg);
   2892         default:
   2893             break;
   2894     }
   2895     return BCM_E_UNAVAIL;
   2896 
   2897 }
   2898 
   2899 int bcm_tomahawk3_cosq_control_dynamic_get(int unit,
   2900         bcm_cosq_control_t type, bcm_cosq_dynamic_setting_type_t *dynamic)
   2901 {
   2902     switch (type) {
   2903         case bcmCosqControlEgressPool:
   2904         case bcmCosqControlUCEgressPool:
   2905         case bcmCosqControlMCEgressPool:
   2906         case bcmCosqControlEgressUCQueueGroupMinEnable:
   2907         case bcmCosqControlEgressMCQueueGroupMinEnable:
   2908             *dynamic = bcmCosqDynamicTypeConditional;
   2909             break;
   2910         case bcmCosqControlIngressPool:
   2911         case bcmCosqControlIngressHeadroomPool:
   2912             *dynamic = bcmCosqDynamicTypeFixed;
   2913             break;
   2914         case bcmCosqControlBandwidthBurstMax:
   2915         case bcmCosqControlBandwidthBurstMin:
   2916         case bcmCosqControlEgressPoolLimitBytes:
   2917         case bcmCosqControlEgressPoolYellowLimitBytes:
   2918         case bcmCosqControlEgressPoolRedLimitBytes:
   2919         case bcmCosqControlEgressPoolLimitEnable:
   2920         case bcmCosqControlEgressPoolSharedLimitBytes:
   2921         case bcmCosqControlEgressPoolResumeLimitBytes:
   2922         case bcmCosqControlEgressPoolYellowSharedLimitBytes:
   2923         case bcmCosqControlEgressPoolYellowResumeLimitBytes:
   2924         case bcmCosqControlEgressPoolRedSharedLimitBytes:
   2925         case bcmCosqControlEgressPoolRedResumeLimitBytes:
   2926         case bcmCosqControlEgressUCQueueSharedLimitBytes:
   2927         case bcmCosqControlEgressMCQueueSharedLimitBytes:
   2928         case bcmCosqControlEgressUCQueueMinLimitBytes:
   2929         case bcmCosqControlEgressMCQueueMinLimitBytes:
   2930         case bcmCosqControlEgressUCQueueResumeOffsetBytes:
   2931         case bcmCosqControlEgressMCQueueResumeOffsetBytes:
   2932         case bcmCosqControlEgressPoolHighCongestionLimitBytes:
   2933         case bcmCosqControlEgressPoolLowCongestionLimitBytes:
   2934         case bcmCosqControlIngressPortPGSharedLimitBytes:
   2935         case bcmCosqControlIngressPortPGMinLimitBytes:
   2936         case bcmCosqControlIngressPortPoolMinLimitBytes:
   2937         case bcmCosqControlIngressPortPoolSharedLimitBytes:
   2938         case bcmCosqControlIngressPortPGHeadroomLimitBytes:
   2939         case bcmCosqControlIngressPortPGResetFloorBytes:
   2940         case bcmCosqControlIngressPortPGResetOffsetBytes:
   2941         case bcmCosqControlIngressPortPoolResumeLimitBytes:
   2942         case bcmCosqControlDropLimitAlpha:
   2943         case bcmCosqControlIngressPortPGSharedDynamicEnable:
   2944         case bcmCosqControlEgressUCSharedDynamicEnable:
   2945         case bcmCosqControlEgressMCSharedDynamicEnable:
   2946         case bcmCosqControlEgressPortPoolYellowLimitBytes:
   2947         case bcmCosqControlEgressPortPoolRedLimitBytes:
   2948         case bcmCosqControlEgressPortPoolSharedLimitBytes:
   2949         case bcmCosqControlEgressPortPoolSharedResumeBytes:
   2950         case bcmCosqControlEgressPortPoolYellowResumeBytes:
   2951         case bcmCosqControlEgressPortPoolRedResumeBytes:
   2952         case bcmCosqControlEgressUCQueueLimitEnable:
   2953         case bcmCosqControlEgressMCQueueLimitEnable:
   2954         case bcmCosqControlIngressPoolLimitBytes:
   2955         case bcmCosqControlIngressPoolResetOffsetLimitBytes:
   2956         case bcmCosqControlIngressHeadroomPoolLimitBytes:
   2957         case bcmCosqControlEgressUCQueueGroupMinLimitBytes:
   2958         case bcmCosqControlEgressMCQueueGroupMinLimitBytes:
   2959         case bcmCosqControlEgressUCQueueColorLimitDynamicEnable:
   2960         case bcmCosqControlEgressMCQueueColorLimitDynamicEnable:
   2961         case bcmCosqControlEgressUCQueueColorLimitEnable:
   2962         case bcmCosqControlEgressMCQueueColorLimitEnable:
   2963         case bcmCosqControlEgressUCQueueRedLimit:
   2964         case bcmCosqControlEgressUCQueueYellowLimit:
   2965         case bcmCosqControlEgressMCQueueRedLimit:
   2966         case bcmCosqControlEgressMCQueueYellowLimit:
   2967             *dynamic = bcmCosqDynamicTypeFlexible;
   2968             break;
   2969         default:
   2970             break;
   2971     }
   2972     return BCM_E_UNAVAIL;
   2973 }
   2974 
   2975 int
   2976 bcm_th3_cosq_service_pool_get(
   2977     int unit,
   2978     bcm_service_pool_id_t id,
   2979     bcm_cosq_service_pool_t *cosq_service_pool)
   2980 {
   2981     uint32 rval;
   2982     soc_field_t fld_enable = INVALIDf;
   2983     int color_limit_enable = 0;
   2984 
   2985     if (cosq_service_pool == NULL) {
   2986         return BCM_E_PARAM;
   2987     }
   2988 
   2989     if (id < 0 || (id > _TH3_MMU_NUM_POOL - 1)) {
   2990         return BCM_E_PARAM;
   2991     }
   2992 
   2993     rval = 0;
   2994     SOC_IF_ERROR_RETURN(
   2995                 soc_tomahawk3_itm_reg32_get(unit,
   2996                     MMU_THDO_SHARED_DB_POOL_CONFIGr, -1, -1, -1, &rval));
   2997 
   2998     switch (cosq_service_pool->type) {
   2999         case bcmCosqServicePoolColorAware:
   3000             fld_enable = POOL_COLOR_LIMIT_ENABLEf;
   3001             break;
   3002         default:
   3003             return BCM_E_PARAM;
   3004     }
   3005 
   3006     color_limit_enable = soc_reg_field_get(unit, MMU_THDO_SHARED_DB_POOL_CONFIGr, rval,
   3007                                                    fld_enable);
   3008     color_limit_enable &= (1 << id);
   3009     cosq_service_pool->enabled = (color_limit_enable != 0) ? 1 : 0;
   3010 
   3011     return BCM_E_NONE;
   3012 }
   3013 
   3014 int
   3015 bcm_th3_cosq_service_pool_set(
   3016     int unit,
   3017     bcm_service_pool_id_t id,
   3018     bcm_cosq_service_pool_t cosq_service_pool)
   3019 {
   3020     uint32 rval;
   3021     soc_field_t fld_enable = INVALIDf;
   3022     int color_limit_enable = 0;
   3023 
   3024     if (id < 0 || (id > _TH3_MMU_NUM_POOL - 1)) {
   3025         return BCM_E_PARAM;
   3026     }
   3027 
   3028     rval = 0;
   3029     SOC_IF_ERROR_RETURN(
   3030                 soc_tomahawk3_itm_reg32_get(unit,
   3031                     MMU_THDO_SHARED_DB_POOL_CONFIGr, -1, -1, -1, &rval));
   3032     switch (cosq_service_pool.type) {
   3033         case bcmCosqServicePoolColorAware:
   3034             fld_enable = POOL_COLOR_LIMIT_ENABLEf;
   3035             break;
   3036         default:
   3037             return BCM_E_PARAM;
   3038     }
   3039     color_limit_enable = soc_reg_field_get(unit, MMU_THDO_SHARED_DB_POOL_CONFIGr, rval,
   3040                                                    fld_enable);
   3041     if (cosq_service_pool.enabled) {
   3042         color_limit_enable |= (1 << id);
   3043     } else {
   3044         color_limit_enable &= (~(1 << id));
   3045         color_limit_enable = color_limit_enable & 0xf;
   3046     }
   3047     soc_reg_field_set(unit, MMU_THDO_SHARED_DB_POOL_CONFIGr, &rval,
   3048                       fld_enable, color_limit_enable);
   3049     SOC_IF_ERROR_RETURN(soc_tomahawk3_itm_reg32_set(unit,
   3050                             MMU_THDO_SHARED_DB_POOL_CONFIGr, -1, -1,
   3051                             -1, rval));
   3052 
   3053     return BCM_E_NONE;
   3054 
   3055 }
   3056 
   3057 static int
   3058 _bcm_th3_adjust_delta_hdrm_service_pools(int unit, int itm, int hdrm_pool, int
   3059         service_pool, uint32 new_hp_limit) {
   3060     soc_reg_t reg;
   3061     int cur_sp_limit[_TH3_ITMS_PER_DEV];
   3062     uint32 old_hp_limit[_TH3_ITMS_PER_DEV] = {0},
   3063            new_sp_limit[_TH3_ITMS_PER_DEV] = {0};
   3064     uint32 rval = 0;
   3065 
   3066     /* Retrieve old value of headroom pool limit */
   3067     reg = MMU_THDI_HDRM_BUFFER_CELL_LIMIT_HPr;
   3068     BCM_IF_ERROR_RETURN(soc_tomahawk3_itm_reg32_get(unit, reg,
   3069                                     itm, itm, hdrm_pool, &old_hp_limit[itm]));
   3070     if (old_hp_limit[itm] != new_hp_limit) {
   3071         /* Delta of headroom pool limit */
   3072         BCM_IF_ERROR_RETURN(_bcm_th3_mmu_get_shared_size(unit, itm,
   3073                     &cur_sp_limit[itm]));
   3074         if (old_hp_limit[itm] > new_hp_limit) {
   3075             new_sp_limit[itm] = cur_sp_limit[itm] + (old_hp_limit[itm] - new_hp_limit);
   3076             new_sp_limit[itm] = MIN(_TH3_THDI_BUFFER_CELL_LIMIT_SP_MAX,
   3077                     new_sp_limit[itm]);
   3078         } else {
   3079             if (cur_sp_limit[itm] > (new_hp_limit - old_hp_limit[itm])) {
   3080                 new_sp_limit[itm] = cur_sp_limit[itm] - (new_hp_limit -
   3081                         old_hp_limit[itm]);
   3082             } else {
   3083                 LOG_WARN(BSL_LS_BCM_COSQ,
   3084                     (BSL_META_U(unit, "Warning: Given input params result"
   3085                                 "in Headroom pool limit addition greater"
   3086                                 "than available shared space: %d for itm:"
   3087                                 "%d. Try reducing the number of lossless"
   3088                                 "classes\n"), cur_sp_limit[itm], itm));
   3089                 return BCM_E_RESOURCE;
   3090             }
   3091         }
   3092         /* Update the saved shared limit */
   3093         reg = MMU_THDI_HDRM_BUFFER_CELL_LIMIT_HPr;
   3094         BCM_IF_ERROR_RETURN(_bcm_th3_mmu_set_shared_size(unit, itm,
   3095                     new_sp_limit[itm]));
   3096         BCM_IF_ERROR_RETURN(soc_tomahawk3_itm_reg32_set(unit, reg,
   3097                                     itm, itm, hdrm_pool, new_hp_limit));
   3098         /* Update the Service pool shared limit for SP 0 */
   3099         reg = MMU_THDI_BUFFER_CELL_LIMIT_SPr;
   3100         soc_reg_field_set(unit, reg, &rval, LIMITf, new_sp_limit[itm]);
   3101         BCM_IF_ERROR_RETURN(
   3102             soc_tomahawk3_itm_reg32_set(unit, reg,
   3103                                itm, itm, service_pool, rval));
   3104     }
   3105     return BCM_E_NONE;
   3106 }
   3107 
   3108 /* Function to set Headroom Pool limit based on packet distribution and number
   3109  * of lossless classes */
   3110 int
   3111 bcm_tomahawk3_cosq_hdrm_pool_limit_set(int unit, int hdrm_pool, int num_lossless_class,
   3112     int arr_size, bcm_cosq_pkt_size_dist_t *pkt_dist_array)
   3113 {
   3114     int rv, hdrm, i;
   3115     _soc_pkt_size_dist_t *size_dist;
   3116     uint32 fld_val;
   3117     int itm;
   3118     uint32 itm_map;
   3119     int speed = 0, port;
   3120     soc_info_t *si = &SOC_INFO(unit);
   3121 #define _TH3_MMU_DEF_HDRM_CABLE_LEN 100
   3122 
   3123     if ((arr_size > 3) || (pkt_dist_array == NULL) ) {
   3124         return BCM_E_PARAM;
   3125     }
   3126     if (hdrm_pool > _TH3_MMU_NUM_POOL) {
   3127         return BCM_E_PARAM;
   3128     }
   3129 
   3130     size_dist = sal_alloc(arr_size * sizeof(bcm_cosq_pkt_size_dist_t),
   3131             "size dist");
   3132     if (size_dist == NULL) {
   3133         return BCM_E_MEMORY;
   3134     }
   3135 
   3136     for (i = 0; i < arr_size; i++) {
   3137         size_dist[i].pkt_size = pkt_dist_array[i].pkt_size;
   3138         size_dist[i].dist_perc = pkt_dist_array[i].dist_perc;
   3139     }
   3140     PBMP_PORT_ITER(unit, port) {
   3141         speed = MAX(speed, si->port_speed_max[port]);
   3142     }
   3143 
   3144     rv = soc_th3_get_port_pg_headroom(unit, speed, _TH3_MMU_DEF_HDRM_CABLE_LEN,
   3145             arr_size, size_dist, &hdrm);
   3146     sal_free(size_dist);
   3147     if (rv) {
   3148         return rv;
   3149     }
   3150 
   3151     fld_val = hdrm * num_lossless_class;
   3152     itm_map = SOC_INFO(unit).itm_map;
   3153     for (itm = 0; itm < NUM_ITM(unit); itm ++) {
   3154         if (itm_map & (1 << itm)) {
   3155             SOC_IF_ERROR_RETURN(_bcm_th3_adjust_delta_hdrm_service_pools(unit, itm,
   3156                     hdrm_pool, 0, fld_val));
   3157         }
   3158     }
   3159 #undef _TH3_MMU_DEF_HDRM_CABLE_LEN
   3160     return rv;
   3161 }
   3162 
   3163 int
   3164 bcm_tomahawk3_cosq_port_prigrp_hdrm_set(int unit, bcm_port_t port, uint32 pri_bmp,
   3165     int cable_len, int arr_size, bcm_cosq_pkt_size_dist_t *pkt_dist_array)
   3166 {
   3167     _soc_pkt_size_dist_t *size_dist;
   3168     int i, rv = 0, speed;
   3169     int hdrm;
   3170     int pri_pg_prof, pri_i, uc_pg, mc_pg, pg_i;
   3171     soc_field_t pri_pg_flds[_TH3_MMU_NUM_INT_PRI] = {
   3172         INPPRI0_PGf, INPPRI1_PGf, INPPRI2_PGf,
   3173         INPPRI3_PGf, INPPRI4_PGf, INPPRI5_PGf,
   3174         INPPRI6_PGf, INPPRI7_PGf, INPPRI8_PGf,
   3175         INPPRI9_PGf, INPPRI10_PGf, INPPRI11_PGf,
   3176         INPPRI12_PGf, INPPRI13_PGf, INPPRI14_PGf,
   3177         INPPRI15_PGf};
   3178     soc_field_t field_pghdrm_limit[_TH3_MMU_NUM_PG] = {
   3179         PG0_HDRM_LIMITf, PG1_HDRM_LIMITf, PG2_HDRM_LIMITf,
   3180         PG3_HDRM_LIMITf, PG4_HDRM_LIMITf, PG5_HDRM_LIMITf,
   3181         PG6_HDRM_LIMITf, PG7_HDRM_LIMITf};
   3182     uint32 pg_bmp = 0x0;
   3183     uint64 rval64;
   3184     soc_info_t *si = &SOC_INFO(unit);
   3185     int pipe, midx;
   3186     uint32 entry[SOC_MAX_MEM_WORDS];
   3187     soc_mem_t mem = INVALIDm;
   3188     int delta = 0, old_limit;
   3189     int itm;
   3190     uint32 old_hp_limit = 0, itm_map = 0;
   3191 
   3192     /* Parameter checks */
   3193     if (!SOC_PORT_VALID(unit, port)) {
   3194         return BCM_E_PORT;
   3195     }
   3196     if ((arr_size > 3) || (pkt_dist_array == NULL) || (pri_bmp > 0xffff)) {
   3197         return BCM_E_PARAM;
   3198     }
   3199 
   3200 
   3201     size_dist = sal_alloc(arr_size * sizeof(bcm_cosq_pkt_size_dist_t),
   3202             "size dist");
   3203     if (size_dist == NULL) {
   3204         return BCM_E_MEMORY;
   3205     }
   3206 
   3207     for (i = 0; i < arr_size; i++) {
   3208         size_dist[i].pkt_size = pkt_dist_array[i].pkt_size;
   3209         size_dist[i].dist_perc = pkt_dist_array[i].dist_perc;
   3210     }
   3211 
   3212     rv = bcm_esw_port_speed_get(unit, port, &speed);
   3213     if (rv) {
   3214         goto exit;
   3215     }
   3216 
   3217     rv = soc_th3_get_port_pg_headroom(unit, speed, cable_len, arr_size,
   3218             size_dist, &hdrm);
   3219     if (rv) {
   3220         goto exit;
   3221     }
   3222     rv = _bcm_th3_cosq_port_inp_pri_to_pg_profile_get(unit, port, &pri_pg_prof);
   3223     if (rv) {
   3224         goto exit;
   3225     }
   3226     for (pri_i = 0; pri_i < _TH3_MMU_NUM_INT_PRI; pri_i++) {
   3227         if (pri_bmp & (1U << pri_i)) {
   3228             COMPILER_64_ZERO(rval64);
   3229             rv = soc_reg64_get(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr,
   3230                                    REG_PORT_ANY, pri_pg_prof, &rval64);
   3231             if (rv) {
   3232                 goto exit;
   3233             }
   3234             uc_pg = soc_reg64_field32_get(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr,
   3235                             rval64, pri_pg_flds[pri_i]);
   3236             pg_bmp |= (1U << uc_pg);
   3237             COMPILER_64_ZERO(rval64);
   3238             rv = soc_reg64_get(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr,
   3239                                    REG_PORT_ANY, pri_pg_prof, &rval64);
   3240             if (rv) {
   3241                 goto exit;
   3242             }
   3243             mc_pg = soc_reg64_field32_get(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr,
   3244                             rval64, pri_pg_flds[pri_i]);
   3245             pg_bmp |= (1U << mc_pg);
   3246         }
   3247     }
   3248 
   3249     pipe = si->port_pipe[port];
   3250     mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDI_PORT_PG_HDRM_CONFIGm)[pipe];
   3251     midx = SOC_TH3_MMU_LOCAL_PORT(unit, port);
   3252     for (pg_i = 0; pg_i < _TH3_MMU_NUM_PG; pg_i++) {
   3253         if (pg_bmp & (1U << pg_i)) {
   3254             rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx,
   3255                         entry);
   3256             if (rv) {
   3257                 goto exit;
   3258             }
   3259             old_limit = soc_mem_field32_get(unit, mem, entry,
   3260                     field_pghdrm_limit[pg_i]);
   3261             delta += (hdrm - old_limit);
   3262             soc_mem_field32_set(unit, mem, entry, field_pghdrm_limit[pg_i], hdrm);
   3263             rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry);
   3264             if (rv) {
   3265                 goto exit;
   3266             }
   3267         }
   3268     }
   3269     itm_map = si->ipipe_itm_map[pipe];
   3270     for (itm = 0; itm < NUM_ITM(unit); itm++) {
   3271         if (itm_map & (1 << itm)) {
   3272             /* Retrieve old value of headroom pool limit */
   3273             rv = soc_tomahawk3_itm_reg32_get(unit,
   3274                     MMU_THDI_HDRM_BUFFER_CELL_LIMIT_HPr, itm, itm, 0,
   3275                     &old_hp_limit);
   3276             if (rv) {
   3277                 goto exit;
   3278             }
   3279             rv = _bcm_th3_adjust_delta_hdrm_service_pools(unit, itm,
   3280                             0, 0, (old_hp_limit + delta));
   3281             if (rv) {
   3282                 goto exit;
   3283             }
   3284         }
   3285     }
   3286 
   3287 exit:
   3288     sal_free(size_dist);
   3289     return rv;
   3290 }
   3291 
   3292 #endif