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

qos.c (343598B)


      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  * All Rights Reserved.$
      7  *
      8  * QoS module
      9  */
     10 #include <soc/defs.h>
     11 #include <shared/bsl.h>
     12 #include <assert.h>
     13 
     14 #include <sal/core/libc.h>
     15 #if defined(BCM_TRIUMPH2_SUPPORT)
     16 
     17 #include <shared/util.h>
     18 #include <soc/cm.h>
     19 #include <soc/drv.h>
     20 #include <soc/scache.h>
     21 #include <bcm/qos.h>
     22 #include <bcm/error.h>
     23 #include <bcm_int/esw/triumph2.h>
     24 #include <bcm_int/esw/qos.h>
     25 #if defined(BCM_TRIUMPH3_SUPPORT)
     26 #include <bcm_int/esw/triumph3.h>
     27 #endif /* BCM_TRIUMPH3_SUPPORT */
     28 #include <bcm_int/esw/triumph.h>
     29 #include <bcm_int/esw/port.h>
     30 #include <bcm_int/esw/firebolt.h>
     31 #include <bcm_int/esw/trx.h>
     32 #include <bcm_int/esw/virtual.h>
     33 #include <bcm_int/esw/xgs3.h>
     34 #include <bcm_int/esw_dispatch.h> 
     35 #include <bcm_int/esw/switch.h>
     36 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
     37 #include <bcm_int/esw/mpls.h>
     38 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */
     39 #if defined(BCM_KATANA2_SUPPORT)
     40 #include <bcm_int/esw/katana2.h>
     41 #endif
     42 #if defined(BCM_SABER2_SUPPORT)
     43 #include <bcm_int/esw/saber2.h>
     44 #endif
     45 #if defined(BCM_TRIDENT2_SUPPORT)
     46 #include <bcm_int/esw/trident2.h>
     47 #endif /* BCM_TRIDENT2_SUPPORT */
     48 #if defined(BCM_TOMAHAWK_SUPPORT)
     49 #include <bcm_int/esw/tomahawk.h>
     50 #endif /* BCM_TOMAHAWK_SUPPORT */
     51 #if defined(BCM_TRIDENT3_SUPPORT)
     52 #include <bcm_int/esw/trident3.h>
     53 #endif
     54 #if defined(BCM_HGPROXY_COE_SUPPORT)
     55 #include <bcm_int/esw/subport.h>
     56 #endif /* BCM_HGPROXY_COE_SUPPORT */
     57 #if defined(INCLUDE_L3)
     58 #include <bcm_int/esw/mim.h>
     59 #endif
     60 
     61 #define _BCM_QOS_MAP_TYPE_MASK           0x3ff
     62 #define _BCM_QOS_MAP_SHIFT                  10
     63 
     64 #define _BCM_QOS_MAP_CHUNK_EGR_MPLS  64
     65 #define _BCM_QOS_MAP_CHUNK_DSCP  64
     66 #define _BCM_QOS_MAP_CHUNK_EGR_DSCP  64
     67 #define _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP  8
     68 #define _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP_1 16
     69 #define _BCM_QOS_MAP_CHUNK_OFFSET_MAP  16
     70 #define _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP 16
     71 #define _BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP 16
     72 #define _BCM_QOS_MAP_CHUNK_PRI_CNG_MAX 64
     73 #define _BCM_QOS_MAP_CHUNK_PRI_CNG  (_bcm_tr2_qos_bk_info[unit].pri_cng_chunk_size)
     74 
     75 #define _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP    \
     76             (soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].inf_pri_cng_mapping)/ \
     77              _BCM_QOS_MAP_CHUNK_PRI_CNG)
     78 #define _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS      \
     79             (soc_mem_index_count(unit, EGR_MPLS_PRI_MAPPINGm)/ \
     80              _BCM_QOS_MAP_CHUNK_EGR_MPLS)
     81 #define _BCM_QOS_MAP_LEN_DSCP_TABLE         \
     82             (soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].dscp_table)/ \
     83              _BCM_QOS_MAP_CHUNK_DSCP)
     84 #define _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE     \
     85              (soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].egr_dscp_table)/ \
     86               _BCM_QOS_MAP_CHUNK_EGR_DSCP) 
     87 #define _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP   \
     88             (soc_mem_is_valid(unit, _bcm_tr2_qos_bk_info[unit].ing_mpls_exp_mapping) ? \
     89              (soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].ing_mpls_exp_mapping)/ \
     90               _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP) : 0)
     91 #define _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP_1   \
     92             (soc_mem_is_valid(unit, ING_MPLS_EXP_MAPPING_1m) ? \
     93              (soc_mem_index_count(unit, ING_MPLS_EXP_MAPPING_1m)/ \
     94               _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP_1) : 0)
     95 #define _BCM_QOS_MAP_LEN_EGR_MPLS_EXP_MAP_3   \
     96             (soc_mem_is_valid(unit, EGR_MPLS_EXP_MAPPING_3m) ? \
     97              (soc_mem_index_count(unit, EGR_MPLS_EXP_MAPPING_3m)/ \
     98               _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP) : 0)
     99 
    100 #ifdef BCM_KATANA_SUPPORT
    101 #define _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE         \
    102             (soc_mem_is_valid(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm) ? \
    103             (soc_mem_index_count(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm)/ \
    104              _BCM_QOS_MAP_CHUNK_OFFSET_MAP) : 0)
    105 #endif
    106 
    107 #ifdef BCM_KATANA2_SUPPORT
    108 #define _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP         \
    109             (SOC_REG_IS_VALID(unit, RQE_QUEUE_OFFSETr) ? \
    110             ((SOC_REG_NUMELS(unit, RQE_QUEUE_OFFSETr)  * 4) / \
    111              _BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP) : 0)
    112 #endif
    113 
    114 #ifdef BCM_SABER2_SUPPORT
    115 #define _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE         \
    116             (soc_mem_is_valid(unit, ING_SERVICE_PRI_MAP_0m) ? \
    117             (soc_mem_index_count(unit, ING_SERVICE_PRI_MAP_0m)/ \
    118              _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP) : 0)
    119 #endif
    120 #define _BCM_QOS_GPORT_IS_VFI_VP_PORT(port) \
    121     (BCM_GPORT_IS_MIM_PORT(port) ||   \
    122      BCM_GPORT_IS_MPLS_PORT(port) || \
    123      BCM_GPORT_IS_VXLAN_PORT(port) || \
    124      BCM_GPORT_IS_L2GRE_PORT(port))
    125 
    126 #if defined(INCLUDE_L3)
    127 #define MIM_INFO(_unit_) (&_bcm_tr2_mim_bk_info[_unit_])
    128 #endif
    129 
    130 typedef struct _bcm_tr2_qos_bookkeeping_s {
    131     SHR_BITDCL *ing_pri_cng_bitmap; /* ING_PRI_CNG_MAP chunks used */
    132     uint32 *pri_cng_hw_idx; /* Actual profile number used */
    133     SHR_BITDCL *egr_mpls_bitmap; /* EGR_MPLS_EXP_MAPPING_1 / 
    134                                   EGR_MPLS_PRI_MAPPING chunks used */
    135     uint32 *egr_mpls_hw_idx; /* Actual profile number used */
    136     SHR_BITDCL *dscp_table_bitmap; /* DSCP_TABLE chunks used */
    137     uint32 *dscp_hw_idx; /* Actual profile number used */
    138     SHR_BITDCL *egr_dscp_table_bitmap; /* EGR_DSCP_TABLE chunks used */
    139     uint32 *egr_dscp_hw_idx; /* Actual profile number used */
    140     SHR_BITDCL *egr_mpls_bitmap_flags; /* indicates if egr_mpls_bitmap
    141                                           entry is L2 or MPLS */
    142     SHR_BITDCL *ing_mpls_exp_bitmap; /* indicates which chunks of 
    143                                 ING_MPLS_EXP_MAPPINGm are used by QOS module */
    144 #ifdef BCM_KATANA_SUPPORT
    145     SHR_BITDCL *offset_map_table_bitmap; /* ING_QUEUE_OFFSET_MAPPING_TABLE
    146                                             chunks used */
    147     uint32     *offset_map_hw_idx;   /* Actual profile number used */
    148 #endif
    149 #ifdef BCM_KATANA2_SUPPORT
    150     SHR_BITDCL *rqe_queue_offset_bitmap; /*  RQE_QUEUE_OFFSET
    151                                             chunks used */
    152     uint32     *rqe_queue_offset_hw_idx;   /* Actual profile number used */
    153     uint32     *rqe_queue_offset_refcount;        /* reference count per profile */
    154 #endif
    155 #ifdef BCM_SABER2_SUPPORT
    156     SHR_BITDCL *service_pri_map_table_bitmap; /* ING_SERVICE_PRI_MAP_0/1/2_TABLE
    157                                             chunks used */
    158     uint32     *service_pri_map_hw_idx;   /* Actual profile number used */
    159     uint32     *service_pri_map_flags;    /* The priority mode flag for a given
    160                                              id */
    161     uint32     pri_cng_hw_idx_reserved;   /* This reserved profile will be used for dynamic */
    162                                           /* update of profile  bound to interface. */
    163 #define MAX_QOS_ING_PRI_PROFILE    64
    164     uint32     qos_profile_binding[BCM_MAX_NUM_UNITS][MAX_QOS_ING_PRI_PROFILE];
    165 #endif
    166     soc_mem_t inf_pri_cng_mapping;
    167     soc_mem_t dscp_table;
    168     /* TD2 and before use only EGR_DSCP_TABLE to store DSCP map info for 
    169      * both inner and outer DSCP.
    170      *
    171      * TD3 use two tables for inner and outer respectively
    172      */
    173     soc_mem_t egr_dscp_table;             /* egress inner dscp map table */
    174     soc_mem_t egr_dscp_table_outer;       /* egress outer dscp map table */
    175     soc_mem_t ing_mpls_exp_mapping;       /* ingress mpls exp mapping */     
    176     uint32    pri_cng_chunk_size;         /* ingress PRI/CNG profile chunk size */
    177 } _bcm_tr2_qos_bookkeeping_t;
    178 
    179 STATIC _bcm_tr2_qos_bookkeeping_t  _bcm_tr2_qos_bk_info[BCM_MAX_NUM_UNITS];
    180 STATIC sal_mutex_t _tr2_qos_mutex[BCM_MAX_NUM_UNITS] = {NULL};
    181 STATIC int tr2_qos_initialized[BCM_MAX_NUM_UNITS]; /* Flag to check init status */
    182 
    183 /*
    184  * QoS resource lock
    185  */
    186 #define QOS_LOCK(unit) \
    187         sal_mutex_take(_tr2_qos_mutex[unit], sal_mutex_FOREVER);
    188 
    189 #define QOS_UNLOCK(unit) \
    190         sal_mutex_give(_tr2_qos_mutex[unit]);
    191 
    192 #define QOS_INFO(_unit_) (&_bcm_tr2_qos_bk_info[_unit_])
    193 #define DSCP_CODE_POINT_CNT 64
    194 #define DSCP_CODE_POINT_MAX (DSCP_CODE_POINT_CNT - 1)
    195 
    196 /*
    197  * ING_PRI_CNG_MAP usage bitmap operations
    198  */
    199 #define _BCM_QOS_ING_PRI_CNG_USED_GET(_u_, _identifier_) \
    200         SHR_BITGET(QOS_INFO(_u_)->ing_pri_cng_bitmap, (_identifier_))
    201 #define _BCM_QOS_ING_PRI_CNG_USED_SET(_u_, _identifier_) \
    202         SHR_BITSET(QOS_INFO((_u_))->ing_pri_cng_bitmap, (_identifier_))
    203 #define _BCM_QOS_ING_PRI_CNG_USED_CLR(_u_, _identifier_) \
    204         SHR_BITCLR(QOS_INFO((_u_))->ing_pri_cng_bitmap, (_identifier_))
    205 #ifdef BCM_SABER2_SUPPORT
    206 #define _BCM_QOS_TRUST_DOT1P_PTR_CACHE_SET(_u_, _p_, _id_) \
    207         ((QOS_INFO(unit)->qos_profile_binding[_u_][_id_]) |= (1 << _p_))
    208 #define _BCM_QOS_TRUST_DOT1P_PTR_CACHE_GET(_u_, _p_, _id_) \
    209         (((QOS_INFO(unit)->qos_profile_binding[_u_][_id_]) >> _p_) & 1)
    210 #define _BCM_QOS_TRUST_DOT1P_PTR_CACHE_CLEAR(_u_, _p_, _id_) \
    211         ((QOS_INFO(unit)->qos_profile_binding[_u_][_id_]) &= (~(1 << _p_)))
    212 #endif
    213 /*
    214  * EGR_MPLS_EXP_MAPPING_1 / EGR_MPLS_PRI_MAPPING usage bitmap operations
    215  */
    216 #define _BCM_QOS_EGR_MPLS_USED_GET(_u_, _identifier_) \
    217         SHR_BITGET(QOS_INFO(_u_)->egr_mpls_bitmap, (_identifier_))
    218 #define _BCM_QOS_EGR_MPLS_USED_SET(_u_, _identifier_) \
    219         SHR_BITSET(QOS_INFO((_u_))->egr_mpls_bitmap, (_identifier_))
    220 #define _BCM_QOS_EGR_MPLS_USED_CLR(_u_, _identifier_) \
    221         SHR_BITCLR(QOS_INFO((_u_))->egr_mpls_bitmap, (_identifier_))
    222 
    223 /*
    224  * DSCP_TABLE usage bitmap operations
    225  */
    226 #define _BCM_QOS_DSCP_TABLE_USED_GET(_u_, _identifier_) \
    227         SHR_BITGET(QOS_INFO(_u_)->dscp_table_bitmap, (_identifier_))
    228 #define _BCM_QOS_DSCP_TABLE_USED_SET(_u_, _identifier_) \
    229         SHR_BITSET(QOS_INFO((_u_))->dscp_table_bitmap, (_identifier_))
    230 #define _BCM_QOS_DSCP_TABLE_USED_CLR(_u_, _identifier_) \
    231         SHR_BITCLR(QOS_INFO((_u_))->dscp_table_bitmap, (_identifier_))
    232 
    233 /*
    234  * EGR_DSCP_TABLE usage bitmap operations
    235  */
    236 #define _BCM_QOS_EGR_DSCP_TABLE_USED_GET(_u_, _identifier_) \
    237         SHR_BITGET(QOS_INFO(_u_)->egr_dscp_table_bitmap, (_identifier_))
    238 #define _BCM_QOS_EGR_DSCP_TABLE_USED_SET(_u_, _identifier_) \
    239         SHR_BITSET(QOS_INFO((_u_))->egr_dscp_table_bitmap, (_identifier_))
    240 #define _BCM_QOS_EGR_DSCP_TABLE_USED_CLR(_u_, _identifier_) \
    241         SHR_BITCLR(QOS_INFO((_u_))->egr_dscp_table_bitmap, (_identifier_))
    242 
    243 /*
    244  * EGR_MPLS flags bitmap operations
    245  */
    246 #define _BCM_QOS_EGR_MPLS_FLAGS_USED_GET(_u_, _identifier_) \
    247         SHR_BITGET(QOS_INFO(_u_)->egr_mpls_bitmap_flags, (_identifier_))
    248 #define _BCM_QOS_EGR_MPLS_FLAGS_USED_SET(_u_, _identifier_) \
    249         SHR_BITSET(QOS_INFO((_u_))->egr_mpls_bitmap_flags, (_identifier_))
    250 #define _BCM_QOS_EGR_MPLS_FLAGS_USED_CLR(_u_, _identifier_) \
    251         SHR_BITCLR(QOS_INFO((_u_))->egr_mpls_bitmap_flags, (_identifier_))
    252 
    253 /*
    254  * ING_MPLS_EXP_MAPPING bitmap operations
    255  */
    256 #define _BCM_QOS_ING_MPLS_EXP_USED_GET(_u_, _identifier_) \
    257         SHR_BITGET(QOS_INFO(_u_)->ing_mpls_exp_bitmap, (_identifier_))
    258 #define _BCM_QOS_ING_MPLS_EXP_USED_SET(_u_, _identifier_) \
    259         SHR_BITSET(QOS_INFO((_u_))->ing_mpls_exp_bitmap, (_identifier_))
    260 #define _BCM_QOS_ING_MPLS_EXP_USED_CLR(_u_, _identifier_) \
    261         SHR_BITCLR(QOS_INFO((_u_))->ing_mpls_exp_bitmap, (_identifier_))
    262 
    263 #define QOS_INIT(unit)                                    \
    264     do {                                                  \
    265         if ((unit < 0) || (unit >= BCM_MAX_NUM_UNITS)) {  \
    266             return BCM_E_UNIT;                            \
    267         }                                                 \
    268         if (!tr2_qos_initialized[unit]) {                           \
    269             return BCM_E_INIT;                            \
    270         }                                                 \
    271     } while (0)
    272 
    273 /*
    274  * ING_QUEUE_OFFSET_MAPPING_TABLE usage bitmap operations
    275  */
    276 #ifdef BCM_KATANA_SUPPORT
    277 #define _BCM_QOS_OFFSET_MAP_TABLE_USED_GET(_u_, _identifier_) \
    278         SHR_BITGET(QOS_INFO(_u_)->offset_map_table_bitmap, (_identifier_))
    279 #define _BCM_QOS_OFFSET_MAP_TABLE_USED_SET(_u_, _identifier_) \
    280         SHR_BITSET(QOS_INFO((_u_))->offset_map_table_bitmap, (_identifier_))
    281 #define _BCM_QOS_OFFSET_MAP_TABLE_USED_CLR(_u_, _identifier_) \
    282         SHR_BITCLR(QOS_INFO((_u_))->offset_map_table_bitmap, (_identifier_))
    283 
    284 #endif
    285 
    286 /*
    287  *RQE_QUEUE_OFFSET using bitmap operations
    288 */
    289 #define _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(_u_, _identifier_) \
    290         SHR_BITGET(QOS_INFO(_u_)->rqe_queue_offset_bitmap, (_identifier_))
    291 #define _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_SET(_u_, _identifier_) \
    292         SHR_BITSET(QOS_INFO((_u_))->rqe_queue_offset_bitmap, (_identifier_))
    293 #define _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_CLR(_u_, _identifier_) \
    294         SHR_BITCLR(QOS_INFO((_u_))->rqe_queue_offset_bitmap, (_identifier_))
    295 
    296 /* ING_SERVICE_PRI_MAP_0/1/2 table usage bitmap operations */
    297 #ifdef BCM_SABER2_SUPPORT
    298 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(_u_, _identifier_) \
    299         SHR_BITGET(QOS_INFO(_u_)->service_pri_map_table_bitmap, (_identifier_))
    300 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_SET(_u_, _identifier_) \
    301         SHR_BITSET(QOS_INFO((_u_))->service_pri_map_table_bitmap, (_identifier_))
    302 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_CLR(_u_, _identifier_) \
    303         SHR_BITCLR(QOS_INFO((_u_))->service_pri_map_table_bitmap, (_identifier_))
    304 
    305 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_GET(_u_, idx) \
    306         (QOS_INFO((_u_))->service_pri_map_flags[idx])
    307 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_SET(_u_, idx, _flags_) \
    308         (QOS_INFO((_u_))->service_pri_map_flags[idx] = (_flags_))
    309 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_CLR(_u_, idx) \
    310         (QOS_INFO((_u_))->service_pri_map_flags[idx] = 0)
    311 #endif
    312 
    313 #if defined(INCLUDE_L3) && defined(BCM_FIREBOLT_SUPPORT)
    314 extern soc_field_t nh_entry_type_field[SOC_MAX_NUM_DEVICES];
    315 #endif
    316 
    317 #ifdef BCM_TRIDENT3_SUPPORT
    318 extern int
    319 bcm_td3_l2_egr_combo_add(int unit,
    320                              uint32 flags,
    321                              bcm_qos_map_t *map,
    322                              int map_id,
    323                              uint32 *hw_idx,
    324                              uint32 entry_per_index);
    325 #endif /* End of BCM_TRIDENT3_SUPPORT */
    326 
    327 void 
    328 _bcm_tr2_qos_id_update(int unit, uint32 dscp_map_id, uint32 new_dscp_map_id)
    329 {
    330     int ifindex;
    331     for (ifindex = 0; ifindex < _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; ifindex++) {
    332         int hw_idx;
    333         hw_idx = QOS_INFO(unit)->egr_dscp_hw_idx[ifindex];
    334         if (hw_idx == dscp_map_id) {
    335             QOS_INFO(unit)->egr_dscp_hw_idx[ifindex] = new_dscp_map_id;
    336         }
    337     }
    338     return;
    339 }
    340 
    341 STATIC int
    342 _bcm_tr2_qos_id_alloc(int unit, SHR_BITDCL *bitmap, uint8 map_type)
    343 {
    344     int i, map_size = -1;
    345 
    346     switch (map_type) {
    347         case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
    348 #ifdef BCM_HURRICANE3_SUPPORT
    349         case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP:
    350 #endif
    351             map_size = _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP;
    352             break;
    353         case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS:
    354 #ifdef BCM_HURRICANE3_SUPPORT
    355         case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS:
    356 #endif
    357             map_size = _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS;
    358             break;
    359         case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
    360             map_size = _BCM_QOS_MAP_LEN_DSCP_TABLE;
    361             break;
    362         case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE:
    363             map_size = _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE;
    364             break;
    365 #ifdef BCM_KATANA_SUPPORT
    366         case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE:
    367             map_size = _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE;
    368             break;
    369 #endif
    370 #ifdef BCM_KATANA2_SUPPORT
    371         case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP:
    372             map_size = _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP;
    373             break;
    374 #endif
    375 #ifdef BCM_SABER2_SUPPORT
    376         case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE:
    377             if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
    378                 map_size = _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE;
    379             } else {
    380                 return BCM_E_PARAM;
    381             }
    382             break;
    383 #endif
    384         default:
    385             return BCM_E_PARAM;
    386     }
    387 
    388     for (i = 0; i < map_size; i++) {
    389         if (!SHR_BITGET(bitmap, i)) {
    390             return i;
    391         }
    392     }
    393     return -1;
    394 }
    395 
    396 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP
    397 /* 
    398  * Function:
    399  *      _bcm_qos_sw_dump
    400  * Purpose:
    401  *      Displays QOS software state info
    402  * Parameters:
    403  *      unit        : (IN) Device Unit Number
    404  * Returns:
    405  *      NONE
    406  */
    407 void
    408 _bcm_tr2_qos_sw_dump(int unit)
    409 {
    410     int     i;
    411 
    412     if (!tr2_qos_initialized[unit]) {
    413         LOG_CLI((BSL_META_U(unit,
    414                             "ERROR: QOS module not initialized on Unit:%d \n"), unit));
    415         return;
    416     }
    417 
    418     LOG_CLI((BSL_META_U(unit,
    419                         "QOS: ING_PRI_CNG_MAP info \n")));
    420     for (i=0; i<_BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; i++) {
    421         if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, i)) {
    422             LOG_CLI((BSL_META_U(unit,
    423                                 "    map id:%4d    HW index:%4d\n"), i, 
    424                      QOS_INFO(unit)->pri_cng_hw_idx[i]));
    425         }
    426     }
    427 
    428     LOG_CLI((BSL_META_U(unit,
    429                         "QOS: EGR_MPLS_PRI_MAPPING info \n")));
    430     for (i=0; i<_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; i++) {
    431         if (_BCM_QOS_EGR_MPLS_USED_GET(unit, i)) {
    432             LOG_CLI((BSL_META_U(unit,
    433                                 "    map id:%4d    HW index:%4d (%s)\n"), i, 
    434                      QOS_INFO(unit)->egr_mpls_hw_idx[i],
    435                      (_BCM_QOS_EGR_MPLS_FLAGS_USED_GET(unit, i)? "MPLS" : "L2")));
    436         }
    437     }
    438 
    439     LOG_CLI((BSL_META_U(unit,
    440                         "QOS: DSCP_TABLE info \n")));
    441     for (i=0; i<_BCM_QOS_MAP_LEN_DSCP_TABLE; i++) {
    442         if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, i)) {
    443             LOG_CLI((BSL_META_U(unit,
    444                                 "    map id:%4d    HW index:%4d\n"), i, 
    445                      QOS_INFO(unit)->dscp_hw_idx[i]));
    446         }
    447     }
    448 
    449     LOG_CLI((BSL_META_U(unit,
    450                         "QOS: EGR_DSCP_TABLE info \n")));
    451     for (i=0; i<_BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; i++) {
    452         if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, i)) {
    453             LOG_CLI((BSL_META_U(unit,
    454                                 "    map id:%4d    HW index:%4d\n"), i, 
    455                      QOS_INFO(unit)->egr_dscp_hw_idx[i]));
    456         }
    457     }
    458 #ifdef BCM_KATANA_SUPPORT
    459     if (QOS_INFO(unit)->offset_map_table_bitmap) {
    460     LOG_CLI((BSL_META_U(unit,
    461                         "QOS: OFFSET_MAP_TABLE info \n")));
    462     for (i=0; i < _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; i++) {
    463         if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, i)) {
    464             LOG_CLI((BSL_META_U(unit,
    465                                 "    map id:%4d    HW index:%4d\n"), i,
    466                      QOS_INFO(unit)->offset_map_hw_idx[i]));
    467         }
    468     }
    469     }
    470 #endif
    471 #ifdef BCM_KATANA2_SUPPORT
    472     if (QOS_INFO(unit)->rqe_queue_offset_bitmap) {
    473     LOG_CLI((BSL_META_U(unit,
    474                         "QOS: RQE_QUEUE_OFFSET info \n")));
    475     for (i=0; i < _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP; i++) {
    476         if (_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, i)) {
    477             LOG_CLI((BSL_META_U(unit,
    478                         "    map id:%4d    HW index:%4d refcoutn %d \n"), i,
    479                          QOS_INFO(unit)->rqe_queue_offset_hw_idx[i],
    480                          QOS_INFO(unit)->rqe_queue_offset_refcount[i]));
    481         }
    482     }
    483     LOG_CLI((BSL_META_U(unit,
    484                         "\n Bitmap: %d \n"),
    485              *QOS_INFO(unit)->rqe_queue_offset_bitmap));
    486     }
    487 #endif /*BCM_KATANA2_SUPPORT */
    488 #ifdef BCM_SABER2_SUPPORT
    489     if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
    490         LOG_CLI((BSL_META_U(unit,
    491                         "QOS: SERVICE_PRI_MAP_TABLE info \n")));
    492         for (i=0; i < _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; i++) {
    493             if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, i)) {
    494                 LOG_CLI((BSL_META_U(unit,
    495                                 "    map id:%4d    HW index:%4d\n"), i,
    496                             QOS_INFO(unit)->service_pri_map_hw_idx[i]));
    497             }
    498         }
    499     }
    500 #endif
    501     LOG_CLI((BSL_META_U(unit,
    502                         "QOS: ING_MPLS_EXP_MAPPING info \n")));
    503     for (i=0; i<_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP; i++) {
    504         if (_BCM_QOS_ING_MPLS_EXP_USED_GET(unit, i)) {
    505             LOG_CLI((BSL_META_U(unit,
    506                                 "    map id:%4d\n"), i));
    507         }
    508     }
    509 }
    510 #endif
    511 
    512 #ifdef BCM_WARM_BOOT_SUPPORT
    513 
    514 #define BCM_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
    515 #define BCM_WB_VERSION_1_1                SOC_SCACHE_VERSION(1,1)
    516 #define BCM_WB_VERSION_1_2                SOC_SCACHE_VERSION(1,2)
    517 #define BCM_WB_DEFAULT_VERSION            BCM_WB_VERSION_1_2
    518 #define _BCM_TR2_REINIT_INVALID_HW_IDX  0xff    /* used as an invalid hw idx */
    519 
    520 /* 
    521  * Function:
    522  *      _bcm_tr2_qos_reinit_scache_len_get
    523  * Purpose:
    524  *      Helper utility to determine scache details.
    525  * Parameters:
    526  *      unit        : (IN) Device Unit Number
    527  *      scache_len  : (OUT) Total required scache length
    528  * Returns:
    529  *      BCM_E_XXX
    530  */
    531 int
    532 _bcm_tr2_qos_reinit_scache_len_get(int unit, uint32* scache_len)
    533 {
    534     if (scache_len == NULL) {
    535         return BCM_E_PARAM;
    536     }
    537 
    538     *scache_len = _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP;
    539     *scache_len += _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS;
    540     *scache_len += _BCM_QOS_MAP_LEN_DSCP_TABLE;
    541     *scache_len += _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE;
    542     *scache_len += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS);
    543     *scache_len += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP);
    544 #ifdef BCM_KATANA_SUPPORT
    545     *scache_len += _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE;
    546 #endif
    547 #ifdef BCM_SABER2_SUPPORT
    548     if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
    549         *scache_len += _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE;
    550     }
    551 #endif
    552 #ifdef BCM_KATANA2_SUPPORT
    553     /* RQE_QUEUE_OFFSET
    554      * replication queue offse profile mapping table
    555      */
    556     *scache_len += (2 * _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE);
    557 #endif
    558 #ifdef BCM_TRIDENT2_SUPPORT
    559     if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) {
    560         _bcm_td2_qos_reinit_scache_len_get(unit, scache_len);
    561     }
    562 #endif
    563 #ifdef BCM_TOMAHAWK_SUPPORT
    564     if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) {
    565         _bcm_th_qos_reinit_scache_len_get(unit, scache_len);
    566     }
    567 #endif
    568     return BCM_E_NONE;
    569 }
    570 
    571 int
    572 _bcm_tr2_qos_reinit_from_hw_state(int unit, soc_mem_t mem, soc_field_t field,
    573                                  uint8 map_type, SHR_BITDCL *hw_idx_bmp, 
    574                                  int hw_idx_bmp_len)
    575 {
    576     int         rv = BCM_E_NONE;
    577     int         idx, min_idx, max_idx, map_id, hw_prof_idx, entry_type = 0;
    578     uint32      buf[SOC_MAX_MEM_FIELD_WORDS];
    579     uint32      *hw_idx_table;
    580     SHR_BITDCL  *map_bmp;
    581 
    582     switch (map_type) {
    583     case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
    584         map_bmp = QOS_INFO(unit)->ing_pri_cng_bitmap;
    585         hw_idx_table = QOS_INFO(unit)->pri_cng_hw_idx;
    586         break;
    587     case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS:
    588         map_bmp = QOS_INFO(unit)->egr_mpls_bitmap;
    589         hw_idx_table = QOS_INFO(unit)->egr_mpls_hw_idx;
    590         break;
    591     case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
    592         map_bmp = QOS_INFO(unit)->dscp_table_bitmap;
    593         hw_idx_table = QOS_INFO(unit)->dscp_hw_idx;
    594         break;
    595     case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE:
    596         map_bmp = QOS_INFO(unit)->egr_dscp_table_bitmap;
    597         hw_idx_table = QOS_INFO(unit)->egr_dscp_hw_idx;
    598         break;
    599 #ifdef BCM_KATANA_SUPPORT
    600     case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE:
    601         map_bmp = QOS_INFO(unit)->offset_map_table_bitmap;
    602         hw_idx_table = QOS_INFO(unit)->offset_map_hw_idx;
    603         break;
    604 #endif
    605 #ifdef BCM_KATANA2_SUPPORT
    606     case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP:
    607         map_bmp = QOS_INFO(unit)->rqe_queue_offset_bitmap;
    608         hw_idx_table = QOS_INFO(unit)->rqe_queue_offset_hw_idx;
    609         break;
    610 #endif /* BCM_KATANA2_SUPPORT */
    611 #ifdef BCM_SABER2_SUPPORT
    612     case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE:
    613         if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
    614             map_bmp = QOS_INFO(unit)->service_pri_map_table_bitmap;
    615             hw_idx_table = QOS_INFO(unit)->service_pri_map_hw_idx;
    616         } else {
    617             return BCM_E_PARAM;
    618         }
    619         break;
    620 #endif
    621     default:
    622         return BCM_E_PARAM;
    623     }
    624 
    625     min_idx = soc_mem_index_min(unit, mem);
    626     max_idx = soc_mem_index_max(unit, mem);
    627     for (idx = min_idx; idx < max_idx; idx++) {
    628         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, idx, &buf);
    629         if (SOC_FAILURE(rv)) {
    630             LOG_ERROR(BSL_LS_BCM_QOS,
    631                       (BSL_META_U(unit,
    632                                   "Error(%s) reading mem(%d) at "
    633                                   "index:%d \n"), soc_errmsg(rv), mem, idx));
    634             return rv;
    635         }
    636         if (mem == EGR_L3_NEXT_HOPm) {
    637             entry_type = soc_mem_field32_get(unit, mem, &buf, ENTRY_TYPEf);
    638             if ((entry_type != 2/* SD-Tag */) && (entry_type != 3/* MIM */)) {
    639                 continue; /* Neither SD-tag nor MiM view */
    640             }
    641         }
    642         if (mem == EGR_VLAN_XLATEm) {
    643 #ifdef BCM_TRIUMPH3_SUPPORT
    644             if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit)) {
    645                 if (SOC_IS_TRIUMPH3(unit)) {
    646                     entry_type = soc_mem_field32_get(unit, mem, &buf, KEY_TYPEf);
    647                 } else if (SOC_IS_TD2_TT2(unit)) {
    648                     entry_type = soc_mem_field32_get(unit, mem, &buf, ENTRY_TYPEf);
    649                 }
    650                 if ((entry_type != 2) && (entry_type != 3)) {
    651                     continue; /* Neither MIM_ISID nor MIM_ISID_DVP */
    652                 }
    653             } else
    654 #endif /* BCM_TRIUMPH3_SUPPORT */
    655             {
    656                 entry_type = soc_mem_field32_get(unit, mem, &buf, ENTRY_TYPEf);
    657                 if ((entry_type != 3) && (entry_type != 4)) {
    658                     continue; /* Neither ISID_XLATE nor ISID_DVP_XLATE */
    659                 }
    660             }
    661         }
    662         /* Some tables have a bit that specifies whether the profile is valid */
    663         if (soc_mem_field_valid(unit, mem, TRUST_OUTER_DOT1Pf)) {
    664             if (soc_mem_field32_get(unit, mem, &buf, TRUST_OUTER_DOT1Pf) == 0) {
    665                 continue;
    666             }
    667         }
    668         if (soc_mem_field_valid(unit, mem, TRUST_DOT1Pf)) {
    669             if (soc_mem_field32_get(unit, mem, &buf, TRUST_DOT1Pf) == 0) {
    670                 continue;
    671             }
    672         }
    673         if (soc_mem_field_valid(unit, mem, SD_TAG__SD_TAG_DOT1P_PRI_SELECTf)) {
    674             if (soc_mem_field32_get(unit, mem, &buf, 
    675                                     SD_TAG__SD_TAG_DOT1P_PRI_SELECTf) == 0) {
    676                 continue;
    677             }
    678         }
    679         if (soc_mem_field_valid(unit, mem, REMARK_DOT1Pf)) {
    680             if (soc_mem_field32_get(unit, mem, &buf, REMARK_DOT1Pf) == 0) {
    681                 continue;
    682             }
    683         }
    684         if (soc_mem_field_valid(unit, mem, DOT1P_PRI_SELECTf)) {
    685             if (soc_mem_field32_get(unit, mem, &buf, DOT1P_PRI_SELECTf) == 0) {
    686                 continue;
    687             }
    688         }
    689         if (soc_mem_field_valid(unit, mem, SD_TAG_DOT1P_PRI_SELECTf)) {
    690             if (soc_mem_field32_get(unit, mem, &buf, 
    691                                     SD_TAG_DOT1P_PRI_SELECTf) == 0) {
    692                 continue;
    693             }
    694         }
    695         if (soc_mem_field_valid(unit, mem, 
    696                                 MIM_ISID__SD_TAG_DOT1P_PRI_SELECTf)) {
    697             if (soc_mem_field32_get(unit, mem, &buf, 
    698                                     MIM_ISID__SD_TAG_DOT1P_PRI_SELECTf) == 0) {
    699                 continue;
    700             }
    701         }
    702         if ((mem == EGR_IP_TUNNELm) || (mem == EGR_L3_INTFm)) {
    703             if (soc_mem_field32_get(unit, mem, &buf, DSCP_SELf) != 2) {
    704                 continue;
    705             }
    706         }
    707 
    708         if (mem == L3_IIFm && field == TRUST_DSCP_PTRf) {
    709             int field_len = 0, iif_profile_idx = 0;
    710             iif_profile_entry_t l3_iif_profile;
    711 
    712             COMPILER_REFERENCE(field_len);
    713             if (soc_feature(unit, soc_feature_l3_iif_profile)) {
    714                 field_len = soc_mem_field_length(unit, L3_IIF_PROFILEm, field);
    715                 iif_profile_idx = soc_mem_field32_get(unit, mem, &buf,
    716                                                       L3_IIF_PROFILE_INDEXf);
    717                 BCM_IF_ERROR_RETURN(soc_mem_read(unit, L3_IIF_PROFILEm,
    718                                      SOC_BLOCK_ANY, iif_profile_idx,
    719                                      &l3_iif_profile));
    720                 hw_prof_idx = soc_mem_field32_get(unit, L3_IIF_PROFILEm,
    721                                                   &l3_iif_profile,
    722                                                   TRUST_DSCP_PTRf);
    723             } else {
    724                 field_len = soc_mem_field_length(unit, mem, field);
    725                 hw_prof_idx = soc_mem_field32_get(unit, mem, &buf, field);
    726             }
    727 #if defined(INCLUDE_L3)
    728             if (field_len == _BCM_TR_L3_TRUST_DSCP_PTR_BIT_SIZE) { 
    729                 if (hw_prof_idx == 0x3f) {
    730                     continue;
    731                 }
    732             } else if (field_len == _BCM_TD_L3_TRUST_DSCP_PTR_BIT_SIZE) {
    733                 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TRIDENT2X(unit) ||
    734                     SOC_IS_TOMAHAWKX(unit) || SOC_IS_GREYHOUND2(unit)) {
    735                     if (hw_prof_idx == 0x7f) {
    736                         continue;
    737                     } 
    738                 } else {
    739                     if (hw_prof_idx == 0x0) {
    740                         continue;
    741                     }
    742                 }
    743             }
    744 #endif
    745         } else {
    746             hw_prof_idx = soc_mem_field32_get(unit, mem, &buf, field);
    747         }
    748 
    749         if (hw_prof_idx > (hw_idx_bmp_len - 1)) {
    750             LOG_ERROR(BSL_LS_BCM_QOS,
    751                       (BSL_META_U(unit,
    752                                   "Invalid profile(%d) in mem(%d) "
    753                                   "at index:%d\n"), hw_prof_idx, mem, idx));
    754             return BCM_E_INTERNAL;
    755         }
    756         if (hw_prof_idx && (!SHR_BITGET(hw_idx_bmp, hw_prof_idx))) {
    757             /* non-zero profile id and not stored previously */
    758             map_id = _bcm_tr2_qos_id_alloc(unit, map_bmp, map_type);
    759             if (map_id < 0) {
    760                 LOG_ERROR(BSL_LS_BCM_QOS,
    761                           (BSL_META_U(unit,
    762                                       "Invalid profile(%d) in mem"
    763                                       "(%d) at index:%d\n"), hw_prof_idx, mem, idx));
    764                 return BCM_E_RESOURCE;
    765             }
    766             hw_idx_table[map_id] = hw_prof_idx;
    767             SHR_BITSET(hw_idx_bmp, hw_prof_idx);
    768             SHR_BITSET(map_bmp, map_id);
    769         }
    770     }
    771     
    772     return rv;
    773 }
    774 
    775 /* 
    776  * Function:
    777  *      _bcm_tr2_qos_unsynchronized_reinit
    778  * Purpose:
    779  *      This routine handles Level 1 Warmboot init. In this style of reinit, the 
    780  *      map-ids allocated previously are not guaranteed to be the same.
    781  *      Cold-boot: Does nothing
    782  *      Warm-boot: The data-structures are populated by reading the HW tables. 
    783  * Parameters:
    784  *      unit    : (IN) Device Unit Number
    785  * Returns:
    786  *      BCM_E_XXX
    787  */
    788 int
    789 _bcm_tr2_qos_unsynchronized_reinit(int unit)
    790 {
    791     int                 rv = BCM_E_NONE;
    792     int                 bmp_len;
    793     SHR_BITDCL          *temp_bmp;
    794 
    795     /* read hw tables and populate the state */
    796     bmp_len = _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP;
    797     temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp");
    798     sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len));
    799     
    800     if (soc_mem_is_valid(unit, SOURCE_VPm)) {
    801         rv = _bcm_tr2_qos_reinit_from_hw_state(unit, SOURCE_VPm, 
    802                            TRUST_DOT1P_PTRf, _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP,
    803                            temp_bmp, bmp_len);
    804     }
    805     if (BCM_SUCCESS(rv) && soc_mem_is_valid(unit, LPORT_TABm)) {
    806         rv = _bcm_tr2_qos_reinit_from_hw_state(unit, LPORT_TABm, 
    807                            TRUST_DOT1P_PTRf, _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP,
    808                            temp_bmp, bmp_len);
    809     }
    810     if (BCM_SUCCESS(rv) && soc_mem_is_valid(unit, PORT_TABm)) {
    811         rv = _bcm_tr2_qos_reinit_from_hw_state(unit, PORT_TABm, 
    812                            TRUST_DOT1P_PTRf, _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP,
    813                            temp_bmp, bmp_len);
    814     }
    815     if (BCM_SUCCESS(rv) && soc_mem_field_valid(unit, VLAN_PROFILE_TABm, 
    816                                                TRUST_DOT1P_PTRf)) {
    817         rv = _bcm_tr2_qos_reinit_from_hw_state(unit, VLAN_PROFILE_TABm, 
    818                            TRUST_DOT1P_PTRf, _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP,
    819                            temp_bmp, bmp_len);
    820     }
    821     if (BCM_SUCCESS(rv) && soc_mem_is_valid(unit, VFIm) &&
    822         soc_mem_field_valid(unit, VFIm, TRUST_DOT1P_PTRf)) {
    823         rv = _bcm_tr2_qos_reinit_from_hw_state(unit, VFIm, 
    824                            TRUST_DOT1P_PTRf, _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP,
    825                            temp_bmp, bmp_len);
    826     }
    827     sal_free(temp_bmp);
    828 
    829     /* now extract EGR_MPLS_PRI_MAPPING state */
    830     if (BCM_SUCCESS(rv)) {
    831         bmp_len = _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS;
    832         temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp");
    833         sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len));
    834         if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 
    835                                 SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf)) {
    836             rv = _bcm_tr2_qos_reinit_from_hw_state(unit, EGR_L3_NEXT_HOPm, 
    837                            SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf, 
    838                            _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, temp_bmp, bmp_len);
    839         }
    840         if (BCM_SUCCESS(rv) && soc_mem_is_valid(unit, EGR_IP_TUNNELm)) {
    841             rv = _bcm_tr2_qos_reinit_from_hw_state(unit, EGR_IP_TUNNELm, 
    842                            DOT1P_MAPPING_PTRf, _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS,
    843                            temp_bmp, bmp_len);
    844         }
    845         if (BCM_SUCCESS(rv) && 
    846             soc_mem_is_valid(unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm) &&
    847             soc_mem_field_valid(unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 
    848                                 SD_TAG_DOT1P_MAPPING_PTRf)) {
    849             rv = _bcm_tr2_qos_reinit_from_hw_state(unit, 
    850                      EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 
    851                      SD_TAG_DOT1P_MAPPING_PTRf, _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS,
    852                      temp_bmp, bmp_len);
    853         }
    854         if (BCM_SUCCESS(rv) && 
    855             soc_mem_field_valid(unit, EGR_VLANm, DOT1P_MAPPING_PTRf)) {
    856             rv = _bcm_tr2_qos_reinit_from_hw_state(unit, 
    857                      EGR_VLANm, DOT1P_MAPPING_PTRf, 
    858                      _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS,
    859                      temp_bmp, bmp_len);
    860         }
    861         if (BCM_SUCCESS(rv) && soc_mem_is_valid(unit, EGR_VLAN_XLATEm) &&
    862             soc_mem_field_valid(unit, EGR_VLAN_XLATEm, 
    863                                 MIM_ISID__DOT1P_MAPPING_PTRf)) {
    864             rv = _bcm_tr2_qos_reinit_from_hw_state(unit, 
    865                      EGR_VLAN_XLATEm, MIM_ISID__DOT1P_MAPPING_PTRf, 
    866                      _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS,
    867                      temp_bmp, bmp_len);
    868         }
    869         sal_free(temp_bmp);
    870     }
    871 
    872     /* now extract DSCP_TABLE state */
    873     if (BCM_SUCCESS(rv) && 
    874         soc_feature(unit, soc_feature_l3_ingress_interface)) {
    875         bmp_len = _BCM_QOS_MAP_LEN_DSCP_TABLE;
    876         temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp");
    877         sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len));
    878         if (soc_mem_field_valid(unit, L3_IIFm, TRUST_DSCP_PTRf)) {
    879             rv = _bcm_tr2_qos_reinit_from_hw_state(unit, L3_IIFm, 
    880                                                    TRUST_DSCP_PTRf,
    881                               _BCM_QOS_MAP_TYPE_DSCP_TABLE, temp_bmp, bmp_len);
    882         }
    883         if (BCM_SUCCESS(rv) && 
    884             soc_mem_is_valid(unit, SOURCE_VPm) &&
    885             soc_mem_field_valid(unit, SOURCE_VPm, TRUST_DSCP_PTRf)) {
    886             rv = _bcm_tr2_qos_reinit_from_hw_state(unit, SOURCE_VPm, 
    887                                                    TRUST_DSCP_PTRf,
    888                               _BCM_QOS_MAP_TYPE_DSCP_TABLE, temp_bmp, bmp_len);
    889         }
    890         sal_free(temp_bmp);
    891     }
    892 
    893     /* now extract EGR_DSCP_TABLE state */
    894     if (BCM_SUCCESS(rv)) {
    895         bmp_len = _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE;
    896         temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp");
    897         sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len));
    898         if (soc_mem_field_valid(unit, EGR_IP_TUNNELm, DSCP_MAPPING_PTRf)) {
    899             rv = _bcm_tr2_qos_reinit_from_hw_state(unit, EGR_IP_TUNNELm, 
    900                             DSCP_MAPPING_PTRf,_BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE,
    901                             temp_bmp, bmp_len);
    902         }
    903         if (soc_mem_field_valid(unit, EGR_L3_INTFm, DSCP_MAPPING_PTRf)) {
    904             rv = _bcm_tr2_qos_reinit_from_hw_state(unit, EGR_L3_INTFm, 
    905                             DSCP_MAPPING_PTRf,_BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE,
    906                             temp_bmp, bmp_len);
    907         }
    908         sal_free(temp_bmp);
    909     }
    910 #ifdef BCM_TRIDENT2_SUPPORT
    911     if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) {
    912         rv = _bcm_td2_qos_unsynchronized_reinit(unit);
    913     }
    914 #endif /* BCM_TRIDENT2_SUPPORT */
    915 #ifdef BCM_TOMAHAWK_SUPPORT
    916     if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) {
    917         rv = _bcm_th_qos_unsynchronized_reinit(unit);
    918     }
    919 #endif /* BCM_TOMAHAWK_SUPPORT */
    920     return rv;
    921 }
    922 
    923 /* 
    924  * Function:
    925  *      _bcm_tr2_qos_extended_reinit
    926  * Purpose:
    927  *      This routine handles Level 2 Warmboot init. 
    928  *      Cold-boot: scache location is allocated.
    929  *      Warm-boot: The data-structs are populated from recovered scache state
    930  * Parameters:
    931  *      unit    : (IN) Device Unit Number
    932  * Returns:
    933  *      BCM_E_XXX
    934  */
    935 int
    936 _bcm_tr2_qos_extended_reinit(int unit)
    937 {
    938     soc_scache_handle_t handle;
    939     uint8               *scache_ptr;
    940     uint32              hw_idx, scache_len, additional_scache_size = 0;
    941     int                 idx;
    942     int                 rv = BCM_E_NONE;
    943     uint16                 recovered_ver;
    944 #ifdef BCM_KATANA2_SUPPORT
    945     int                 refcount = 0;
    946 #endif
    947 
    948 
    949     BCM_IF_ERROR_RETURN(_bcm_tr2_qos_reinit_scache_len_get(unit, &scache_len));
    950     SOC_SCACHE_HANDLE_SET(handle, unit, BCM_MODULE_QOS, 0);
    951 
    952     if (SOC_WARM_BOOT(unit)) {
    953         /* during warm-boot recover state */
    954         BCM_IF_ERROR_RETURN(_bcm_esw_scache_ptr_get(unit, handle, FALSE,
    955                                             scache_len, &scache_ptr, 
    956                                             BCM_WB_DEFAULT_VERSION, &recovered_ver));
    957 
    958         /* recover from scache into book-keeping structs */
    959         for (idx = 0; idx < _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; idx++) {
    960             hw_idx = (uint32) (*scache_ptr++);
    961             if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) {
    962                 _BCM_QOS_ING_PRI_CNG_USED_SET(unit, idx);
    963                 QOS_INFO(unit)->pri_cng_hw_idx[idx] = hw_idx;
    964             }
    965         }
    966         for (idx = 0; idx < _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; idx++) {
    967             hw_idx = (uint32) (*scache_ptr++);
    968             if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) {
    969                 _BCM_QOS_EGR_MPLS_USED_SET(unit, idx);
    970                 QOS_INFO(unit)->egr_mpls_hw_idx[idx] = hw_idx;
    971             }
    972         }
    973         for (idx = 0; idx < _BCM_QOS_MAP_LEN_DSCP_TABLE; idx++) {
    974             hw_idx = (uint32) (*scache_ptr++);
    975             if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) {
    976                 _BCM_QOS_DSCP_TABLE_USED_SET(unit, idx);
    977                 QOS_INFO(unit)->dscp_hw_idx[idx] = hw_idx;
    978             }
    979         }
    980         for (idx = 0; idx < _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; idx++) {
    981             hw_idx = (uint32) (*scache_ptr++);
    982             if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) {
    983                 _BCM_QOS_EGR_DSCP_TABLE_USED_SET(unit, idx);
    984                 QOS_INFO(unit)->egr_dscp_hw_idx[idx] = hw_idx;
    985             }
    986         }
    987         sal_memcpy(QOS_INFO(unit)->egr_mpls_bitmap_flags, scache_ptr, 
    988                    SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS));
    989         scache_ptr += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS);
    990         sal_memcpy(QOS_INFO(unit)->ing_mpls_exp_bitmap, scache_ptr, 
    991                    SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP));
    992         scache_ptr += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP);
    993 #ifdef BCM_KATANA_SUPPORT
    994         for (idx = 0; idx < _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; idx++) {
    995             hw_idx = (uint32) (*scache_ptr++);
    996             if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) {
    997                 _BCM_QOS_OFFSET_MAP_TABLE_USED_SET(unit, idx);
    998                 QOS_INFO(unit)->offset_map_hw_idx[idx] = hw_idx;
    999             }
   1000         }
   1001 #endif
   1002 #ifdef BCM_SABER2_SUPPORT
   1003         if (soc_feature(unit, soc_feature_oam_service_pri_map)) {            
   1004             for (idx = 0; idx < _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; idx++) {
   1005                 hw_idx = (uint32) (*scache_ptr++);
   1006                 if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) {
   1007                     _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_SET(unit, idx);
   1008                     QOS_INFO(unit)->service_pri_map_hw_idx[idx] = hw_idx;
   1009                 }
   1010             }
   1011         }
   1012 #endif
   1013 #ifdef BCM_KATANA2_SUPPORT
   1014         /* RQE_QUEUE_OFFSET
   1015          * Replication queue offset profile mapping table
   1016         * Hw indices
   1017         * refcount
   1018         */
   1019        if (recovered_ver >=  BCM_WB_VERSION_1_1) {
   1020            for (idx = 0; idx < _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP; idx++) {
   1021                hw_idx = (uint32) (*scache_ptr++);
   1022                if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) {
   1023                    _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_SET(unit,  idx);
   1024                    QOS_INFO(unit)->rqe_queue_offset_hw_idx[idx] = hw_idx;
   1025                }
   1026                refcount = (uint32) (*scache_ptr++);
   1027                if (refcount != 0) {
   1028                    QOS_INFO(unit)->rqe_queue_offset_refcount[idx] = refcount;
   1029                }
   1030            }
   1031        } else {
   1032            additional_scache_size += 2 * _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE;
   1033        }
   1034 #endif /* BCM_KATANA2_SUPPORT */
   1035 #ifdef BCM_TRIDENT2_SUPPORT
   1036         if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) {
   1037             if (recovered_ver >= BCM_WB_VERSION_1_2) {
   1038                 BCM_IF_ERROR_RETURN(_bcm_td2_qos_extended_reinit(unit, &scache_ptr));
   1039             } else {
   1040                 BCM_IF_ERROR_RETURN(_bcm_td2_qos_reinit_scache_len_get(unit,
   1041                                         &additional_scache_size));
   1042             } 
   1043         }            
   1044 #endif /* BCM_TRIDENT2_SUPPORT */  
   1045 #ifdef BCM_TOMAHAWK_SUPPORT
   1046         if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) {
   1047             if (recovered_ver >= BCM_WB_VERSION_1_2) {
   1048                 BCM_IF_ERROR_RETURN(_bcm_th_qos_extended_reinit(unit, &scache_ptr));
   1049             } else {
   1050                 BCM_IF_ERROR_RETURN(
   1051                     _bcm_th_qos_reinit_scache_len_get(unit, 
   1052                                                       &additional_scache_size));        
   1053             }
   1054         }
   1055 #endif /* BCM_TOMAHAWK_SUPPORT */        
   1056         if (additional_scache_size > 0) {
   1057             /* Need to realloc unavailable space for subsequent syncs */
   1058             SOC_IF_ERROR_RETURN
   1059                 (soc_scache_realloc(unit, handle, additional_scache_size));
   1060         } 
   1061     } else {
   1062         /* During cold-boot. Allocate a stable cache if not already done */
   1063         rv = _bcm_esw_scache_ptr_get(unit, handle, TRUE, scache_len, 
   1064                                      &scache_ptr, BCM_WB_DEFAULT_VERSION, NULL);
   1065     }
   1066 
   1067     return rv;
   1068 }
   1069 
   1070 /* 
   1071  * Function:
   1072  *      _bcm_tr2_qos_reinit_hw_profiles_update
   1073  * Purpose:
   1074  *      Updates the shared memory profile tables reference counts
   1075  * Parameters:
   1076  *      unit    : (IN) Device Unit Number
   1077  * Returns:
   1078  *      BCM_E_XXX
   1079  */
   1080 int
   1081 _bcm_tr2_qos_reinit_hw_profiles_update (int unit)
   1082 {
   1083     int     i;
   1084 
   1085     for (i=0; i<_BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; i++) {
   1086         if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, i)) {
   1087             BCM_IF_ERROR_RETURN(_bcm_ing_pri_cng_map_entry_reference(unit, 
   1088                               ((QOS_INFO(unit)->pri_cng_hw_idx[i]) * 
   1089                                _BCM_QOS_MAP_CHUNK_PRI_CNG), 
   1090                                _BCM_QOS_MAP_CHUNK_PRI_CNG));
   1091         }
   1092     }
   1093     for (i=0; i<_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; i++) {
   1094         if (_BCM_QOS_EGR_MPLS_USED_GET(unit, i)) {
   1095             BCM_IF_ERROR_RETURN(_bcm_egr_mpls_combo_map_entry_reference(unit, 
   1096                              ((QOS_INFO(unit)->egr_mpls_hw_idx[i]) * 
   1097                               _BCM_QOS_MAP_CHUNK_EGR_MPLS), 
   1098                              _BCM_QOS_MAP_CHUNK_EGR_MPLS));
   1099         }
   1100     }
   1101     for (i=0; i<_BCM_QOS_MAP_LEN_DSCP_TABLE; i++) {
   1102         /* For all port dscp profiles have been reserved on TD, 
   1103          * should skip this operation during warmboot
   1104          */
   1105         if (SOC_IS_TRIDENT(unit) && 
   1106             ((i >= 0) && (i < SOC_PORT_MAX(unit,all)))) {
   1107             continue;
   1108         }
   1109         if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, i)) {
   1110             BCM_IF_ERROR_RETURN(_bcm_dscp_table_entry_reference(unit, 
   1111                                  ((QOS_INFO(unit)->dscp_hw_idx[i]) * 
   1112                                   _BCM_QOS_MAP_CHUNK_DSCP), 
   1113                                  _BCM_QOS_MAP_CHUNK_DSCP));
   1114         }
   1115     }
   1116     for (i=0; i<_BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; i++) {
   1117         if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, i)) {
   1118 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1119             if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   1120                 BCM_IF_ERROR_RETURN(_bcm_egr_qos_profile_mem_reference(unit,
   1121                                      ((QOS_INFO(unit)->egr_dscp_hw_idx[i]) *
   1122                                       _BCM_QOS_MAP_CHUNK_EGR_DSCP),
   1123                                      _BCM_QOS_MAP_CHUNK_EGR_DSCP));
   1124             } else
   1125 #endif
   1126             {
   1127                 BCM_IF_ERROR_RETURN(_bcm_egr_dscp_table_entry_reference(unit,
   1128                                      ((QOS_INFO(unit)->egr_dscp_hw_idx[i]) *
   1129                                       _BCM_QOS_MAP_CHUNK_EGR_DSCP),
   1130                                      _BCM_QOS_MAP_CHUNK_EGR_DSCP));
   1131             }
   1132         }
   1133     }
   1134 #ifdef BCM_KATANA_SUPPORT
   1135     for (i=0; i< _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; i++) {
   1136         if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, i)) {
   1137             BCM_IF_ERROR_RETURN(_bcm_offset_map_table_entry_reference(unit,
   1138                                  ((QOS_INFO(unit)->offset_map_hw_idx[i]) *
   1139                                   _BCM_QOS_MAP_CHUNK_OFFSET_MAP),
   1140                                  _BCM_QOS_MAP_CHUNK_OFFSET_MAP));
   1141         }
   1142     }
   1143 
   1144 #endif
   1145 
   1146 #ifdef BCM_SABER2_SUPPORT
   1147     if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   1148         for (i=0; i< _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; i++) {
   1149             if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, i)) {
   1150                 BCM_IF_ERROR_RETURN(_bcm_service_pri_map_table_entry_reference(unit,
   1151                             ((QOS_INFO(unit)->service_pri_map_hw_idx[i]) *
   1152                              _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP),
   1153                             _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP));
   1154             }
   1155         }
   1156     }
   1157 #endif
   1158 #ifdef BCM_TRIDENT2_SUPPORT
   1159     if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) {
   1160         BCM_IF_ERROR_RETURN(_bcm_td2_qos_reinit_hw_profiles_update(unit));
   1161     }            
   1162 #endif /* BCM_TRIDENT2_SUPPORT */ 
   1163 #ifdef BCM_TOMAHAWK_SUPPORT
   1164     if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) {
   1165         BCM_IF_ERROR_RETURN(_bcm_th_qos_reinit_hw_profiles_update(unit));
   1166     }
   1167 #endif
   1168 
   1169     return BCM_E_NONE;
   1170 }
   1171 
   1172 int
   1173 _bcm_tr2_qos_reinit_profiles_ref_update (int unit)
   1174 {
   1175     int i;
   1176     int rv;
   1177     int hw_idx;
   1178 
   1179     for (i = 0; i < _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; i++) {
   1180         if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, i)) {
   1181             hw_idx = QOS_INFO(unit)->pri_cng_hw_idx[i];
   1182             if (hw_idx == 0) {
   1183                 continue;
   1184             }
   1185 
   1186             do {
   1187                 rv = _bcm_ing_pri_cng_map_entry_delete(
   1188                     unit, hw_idx * _BCM_QOS_MAP_CHUNK_PRI_CNG);
   1189 
   1190                 if (rv != BCM_E_NONE && rv != BCM_E_NOT_FOUND) {
   1191                     return rv;
   1192                 }
   1193             } while (rv == BCM_E_NONE);
   1194         }
   1195     }
   1196 
   1197     for (i = 0; i < _BCM_QOS_MAP_LEN_DSCP_TABLE; i++) {
   1198         if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, i)) {
   1199             hw_idx = QOS_INFO(unit)->dscp_hw_idx[i];
   1200             if (hw_idx == 0) {
   1201                 continue;
   1202             }
   1203 
   1204             do {
   1205                 rv = _bcm_dscp_table_entry_delete(
   1206                     unit, hw_idx * _BCM_QOS_MAP_CHUNK_DSCP);
   1207 
   1208                 if (rv != BCM_E_NONE && rv != BCM_E_NOT_FOUND) {
   1209                     return rv;
   1210                 }
   1211             } while (rv == BCM_E_NONE);
   1212         }
   1213     }
   1214 
   1215     return BCM_E_NONE;
   1216 }
   1217 
   1218 /* 
   1219  * Function:
   1220  *      _bcm_tr2_qos_reinit
   1221  * Purpose:
   1222  *      Top level QOS init routine for Warm-Boot
   1223  * Parameters:
   1224  *      unit    : (IN) Device Unit Number
   1225  * Returns:
   1226  *      BCM_E_XXX
   1227  */
   1228 int
   1229 _bcm_tr2_qos_reinit(int unit)
   1230 {
   1231     int rv = BCM_E_NONE;
   1232     int stable_size = 0;
   1233 
   1234     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
   1235 
   1236     if (stable_size == 0) {
   1237         if (!SOC_WARM_BOOT(unit)) {
   1238             return rv; /* do nothing in cold-boot */
   1239         }
   1240         rv = _bcm_tr2_qos_unsynchronized_reinit(unit);
   1241     } else {
   1242         /* Limited is same as extended */
   1243         rv = _bcm_tr2_qos_extended_reinit(unit);
   1244     }
   1245 
   1246     if (SOC_IS_TD2_TT2(unit)) {
   1247         if (BCM_SUCCESS(rv)) {
   1248             rv = _bcm_tr2_qos_reinit_profiles_ref_update(unit);
   1249         }
   1250     }
   1251 
   1252     if (BCM_SUCCESS(rv)) {
   1253         rv = _bcm_tr2_qos_reinit_hw_profiles_update(unit);
   1254     }
   1255 
   1256     return rv;
   1257 }
   1258 
   1259 /* 
   1260  * Function:
   1261  *      bcm_tr2_qos_sync
   1262  * Purpose:
   1263  *      This routine extracts the state that needs to be stored from the 
   1264  *      book-keeping structs and stores it in the allocated scache location 
   1265  * Compression format:  0   - A     pri_cng_hw_idx table
   1266  *                      A+1 - B     egr_mpls_hw_idx table
   1267  *                      B+1 - C     dscp_hw_idx table
   1268  *                      C+1 - D     egr_dscp_hw_idx table
   1269  *                      D+1 - E     egr_mpls flags
   1270  *                      E+1 - F     ing_mpls_exp table usage by QOS module
   1271  * Parameters:
   1272  *      unit    : (IN) Device Unit Number
   1273  * Returns:
   1274  *      BCM_E_XXX
   1275  */
   1276 int
   1277 _bcm_tr2_qos_sync(int unit)
   1278 {
   1279     soc_scache_handle_t handle;
   1280     uint8               *scache_ptr;
   1281     uint32              hw_idx, scache_len;
   1282     int                 idx;
   1283 #ifdef BCM_KATANA2_SUPPORT
   1284     uint32              refcount;
   1285 #endif
   1286     QOS_INIT(unit);
   1287     BCM_IF_ERROR_RETURN(_bcm_tr2_qos_reinit_scache_len_get(unit, &scache_len));
   1288     SOC_SCACHE_HANDLE_SET(handle, unit, BCM_MODULE_QOS, 0);
   1289     BCM_IF_ERROR_RETURN(_bcm_esw_scache_ptr_get(unit, handle, FALSE,
   1290                                                 scache_len, &scache_ptr, 
   1291                                                 BCM_WB_DEFAULT_VERSION, NULL));
   1292 
   1293     /* now store the state into the compressed format */
   1294     for (idx = 0; idx < _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; idx++) {
   1295         if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, idx)) {
   1296             hw_idx = QOS_INFO(unit)->pri_cng_hw_idx[idx];
   1297         } else {
   1298             hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX;
   1299         }
   1300         *scache_ptr++ = hw_idx;
   1301     }
   1302     for (idx = 0; idx < _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; idx++) {
   1303         if (_BCM_QOS_EGR_MPLS_USED_GET(unit, idx)) {
   1304             hw_idx = QOS_INFO(unit)->egr_mpls_hw_idx[idx];
   1305         } else {
   1306             hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX;
   1307         }
   1308         *scache_ptr++ = hw_idx;
   1309     }
   1310     for (idx = 0; idx < _BCM_QOS_MAP_LEN_DSCP_TABLE; idx++) {
   1311         if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, idx)) {
   1312             hw_idx = QOS_INFO(unit)->dscp_hw_idx[idx];
   1313         } else {
   1314             hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX;
   1315         }
   1316         *scache_ptr++ = hw_idx;
   1317     }
   1318     for (idx = 0; idx < _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; idx++) {
   1319         if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, idx)) {
   1320             hw_idx = QOS_INFO(unit)->egr_dscp_hw_idx[idx];
   1321         } else {
   1322             hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX;
   1323         }
   1324         *scache_ptr++ = hw_idx;
   1325     }
   1326     sal_memcpy(scache_ptr, QOS_INFO(unit)->egr_mpls_bitmap_flags, 
   1327                SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS));
   1328     scache_ptr += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS);
   1329     sal_memcpy(scache_ptr, QOS_INFO(unit)->ing_mpls_exp_bitmap, 
   1330                SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP));
   1331     scache_ptr += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP);
   1332 #ifdef BCM_KATANA_SUPPORT
   1333     for (idx = 0; idx < _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; idx++) {
   1334         if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, idx)) {
   1335             hw_idx = QOS_INFO(unit)->offset_map_hw_idx[idx];
   1336         } else {
   1337             hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX;
   1338         }
   1339         *scache_ptr++ = hw_idx;
   1340     }
   1341 #endif
   1342 
   1343 #ifdef BCM_SABER2_SUPPORT
   1344     if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   1345         for (idx = 0; idx < _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; idx++) {
   1346             if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, idx)) {
   1347                 hw_idx = QOS_INFO(unit)->service_pri_map_hw_idx[idx];
   1348             } else {
   1349                 hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX;
   1350             }
   1351             *scache_ptr++ = hw_idx;
   1352         }
   1353     }
   1354 #endif
   1355    /* Replication queue offset profile Map table
   1356     * RQE_QUEUE_OFFSETr
   1357     * store the valid hardware indices
   1358     * store the reference count per profile
   1359     */
   1360 #ifdef BCM_KATANA2_SUPPORT
   1361    for (idx = 0; idx < _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP; idx++) {
   1362        if (_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, idx)) {
   1363            hw_idx = QOS_INFO(unit)->rqe_queue_offset_hw_idx[idx];
   1364            refcount = QOS_INFO(unit)->rqe_queue_offset_refcount[idx];
   1365        } else {
   1366            hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX;
   1367            refcount = 0;
   1368        }
   1369        *scache_ptr++ = hw_idx;
   1370        *scache_ptr++ = refcount;
   1371    }
   1372 #endif /* BCM_KATANA2_SUPPORT */
   1373 #ifdef BCM_TRIDENT2_SUPPORT
   1374     if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) {
   1375         BCM_IF_ERROR_RETURN(_bcm_td2_qos_sync(unit, &scache_ptr));
   1376     }            
   1377 #endif /* BCM_TRIDENT2_SUPPORT */ 
   1378 #ifdef BCM_TOMAHAWK_SUPPORT
   1379     if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) {
   1380         BCM_IF_ERROR_RETURN(_bcm_th_qos_sync(unit, &scache_ptr));
   1381     }
   1382 #endif /* BCM_TOMAHAWK_SUPPORT */
   1383 
   1384     return BCM_E_NONE;
   1385 }
   1386 #endif
   1387 
   1388 #if defined(BCM_TOMAHAWK3_SUPPORT)
   1389 STATIC int
   1390 _bcm_th3_qos_validate_map_type(int unit, int map_id)
   1391 {
   1392     int id;
   1393     int map_size;
   1394 
   1395     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   1396 
   1397     switch (map_id >> _BCM_QOS_MAP_SHIFT) {
   1398         case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
   1399             map_size = _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP;
   1400             break;
   1401 
   1402         case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS:
   1403             map_size = _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS;
   1404             break;
   1405 
   1406         case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
   1407             map_size = _BCM_QOS_MAP_LEN_DSCP_TABLE;
   1408             break;
   1409 
   1410         case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE:
   1411             map_size = _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE;
   1412             break;
   1413 
   1414         default:
   1415 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   1416             if (map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) {
   1417                 id = map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_NUM_MASK;
   1418                 map_size = _bcm_tr_get_ing_mpls_index_size(unit);
   1419             } else
   1420 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */
   1421             {
   1422                 return BCM_E_PARAM;
   1423             }
   1424     }
   1425 
   1426     return (id >= map_size) ? BCM_E_PARAM : BCM_E_NONE;
   1427 }
   1428 #endif /* BCM_TOMAHAWK3_SUPPORT */
   1429 
   1430 STATIC void
   1431 _bcm_tr2_qos_free_resources(int unit)
   1432 {
   1433     _bcm_tr2_qos_bookkeeping_t *qos_info = QOS_INFO(unit);
   1434 
   1435     if (!qos_info) {
   1436     /* coverity[dead_error_line] */
   1437         return;
   1438     }
   1439 
   1440     /* Destroy ingress profile bitmap */
   1441     if (qos_info->ing_pri_cng_bitmap) {
   1442         sal_free(qos_info->ing_pri_cng_bitmap);
   1443         qos_info->ing_pri_cng_bitmap = NULL;
   1444     }
   1445     if (qos_info->pri_cng_hw_idx) {
   1446         sal_free(qos_info->pri_cng_hw_idx);
   1447         qos_info->pri_cng_hw_idx = NULL;
   1448     }
   1449 
   1450     if (qos_info->egr_mpls_hw_idx) {
   1451         int id;
   1452         /* Delete all combo mpls hw index profiles */
   1453         for (id = 0; id < _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; id++)
   1454         {
   1455             if (qos_info->egr_mpls_hw_idx[id] != 0) {
   1456                 _bcm_egr_mpls_combo_map_entry_delete (unit, 
   1457                                            (qos_info->egr_mpls_hw_idx[id] *
   1458                                             _BCM_QOS_MAP_CHUNK_EGR_MPLS));
   1459                 qos_info->egr_mpls_hw_idx[id] = 0;
   1460                 _BCM_QOS_EGR_MPLS_USED_CLR(unit, id);
   1461                 _BCM_QOS_EGR_MPLS_FLAGS_USED_CLR(unit, id);
   1462             }
   1463         }
   1464         sal_free(qos_info->egr_mpls_hw_idx);
   1465         qos_info->egr_mpls_hw_idx = NULL;
   1466     }
   1467 
   1468     /* Destroy egress profile usage bitmap */
   1469     if (qos_info->egr_mpls_bitmap) {
   1470         sal_free(qos_info->egr_mpls_bitmap);
   1471         qos_info->egr_mpls_bitmap = NULL;
   1472     }
   1473 
   1474     /* Destroy DSCP table profile usage bitmap */
   1475     if (qos_info->dscp_table_bitmap) {
   1476         sal_free(qos_info->dscp_table_bitmap);
   1477         qos_info->dscp_table_bitmap = NULL;
   1478     }
   1479     if (qos_info->dscp_hw_idx) {
   1480         sal_free(qos_info->dscp_hw_idx);
   1481         qos_info->dscp_hw_idx = NULL;
   1482     }
   1483 
   1484     /* Destroy egress DSCP table profile usage bitmap */
   1485     if (qos_info->egr_dscp_table_bitmap) {
   1486         sal_free(qos_info->egr_dscp_table_bitmap);
   1487         qos_info->egr_dscp_table_bitmap = NULL;
   1488     }
   1489     if (qos_info->egr_dscp_hw_idx) {
   1490         sal_free(qos_info->egr_dscp_hw_idx);
   1491         qos_info->egr_dscp_hw_idx = NULL;
   1492     }
   1493 
   1494     /* Destroy egress profile flags bitmap */
   1495     if (qos_info->egr_mpls_bitmap_flags) {
   1496         sal_free(qos_info->egr_mpls_bitmap_flags);
   1497         qos_info->egr_mpls_bitmap_flags = NULL;
   1498     }
   1499 
   1500     /* Destroy ing_mpls_exp bitmap */
   1501     if (qos_info->ing_mpls_exp_bitmap) {
   1502         sal_free(qos_info->ing_mpls_exp_bitmap);
   1503         qos_info->ing_mpls_exp_bitmap = NULL;
   1504     }
   1505 #ifdef BCM_KATANA_SUPPORT
   1506 /* Destroy queue map table profile usage bitmap */
   1507     if (qos_info->offset_map_table_bitmap) {
   1508         sal_free(qos_info->offset_map_table_bitmap);
   1509         qos_info->offset_map_table_bitmap = NULL;
   1510     }
   1511     if (qos_info->offset_map_hw_idx) {
   1512         sal_free(qos_info->offset_map_hw_idx);
   1513         qos_info->offset_map_hw_idx = NULL;
   1514     }
   1515 #endif
   1516 
   1517 #ifdef BCM_SABER2_SUPPORT
   1518     if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   1519         /* Destroy service pri map table profile usage bitmap */
   1520         if (qos_info->service_pri_map_table_bitmap) {
   1521             sal_free(qos_info->service_pri_map_table_bitmap);
   1522             qos_info->service_pri_map_table_bitmap = NULL;
   1523         }
   1524         if (qos_info->service_pri_map_hw_idx) {
   1525             sal_free(qos_info->service_pri_map_hw_idx);
   1526             qos_info->service_pri_map_hw_idx = NULL;
   1527         }
   1528         if (qos_info->service_pri_map_flags) {
   1529             sal_free(qos_info->service_pri_map_flags);
   1530             qos_info->service_pri_map_flags = NULL;
   1531         }
   1532     }
   1533 #endif
   1534 #ifdef BCM_KATANA2_SUPPORT
   1535 /* Destroy RQE QUEUE MAP table profile usage bitmap */
   1536     if (qos_info->rqe_queue_offset_bitmap) {
   1537         sal_free(qos_info->rqe_queue_offset_bitmap);
   1538         qos_info->rqe_queue_offset_bitmap = NULL;
   1539     }
   1540     if (qos_info->rqe_queue_offset_hw_idx) {
   1541         sal_free(qos_info->rqe_queue_offset_hw_idx);
   1542         qos_info->rqe_queue_offset_hw_idx = NULL;
   1543     }
   1544     if (qos_info->rqe_queue_offset_refcount) {
   1545         sal_free(qos_info->rqe_queue_offset_refcount);
   1546         qos_info->rqe_queue_offset_refcount = NULL;
   1547     }
   1548 #endif
   1549     
   1550     /* Destroy the mutex */
   1551     if (_tr2_qos_mutex[unit]) {
   1552         sal_mutex_destroy(_tr2_qos_mutex[unit]);
   1553         _tr2_qos_mutex[unit] = NULL;
   1554     }
   1555 }
   1556 
   1557 /* Initialize the QoS module. */
   1558 int 
   1559 bcm_tr2_qos_init(int unit)
   1560 {
   1561     _bcm_tr2_qos_bookkeeping_t *qos_info = QOS_INFO(unit);
   1562     int ing_profiles, egr_profiles, rv = BCM_E_NONE;
   1563     int dscp_profiles, egr_dscp_profiles, ing_mpls_profiles;
   1564 #ifdef BCM_KATANA_SUPPORT
   1565     int offset_map_profiles = 0;
   1566 #endif
   1567 #ifdef BCM_SABER2_SUPPORT
   1568     int service_pri_map_profiles = 0, pid, index;
   1569     ing_pri_cng_map_entry_t pri_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX];
   1570     ing_untagged_phb_entry_t phb;
   1571     void *entries[2];
   1572 #ifdef BCM_WARM_BOOT_SUPPORT
   1573     bcm_port_t port;
   1574 #endif
   1575 #endif
   1576 #ifdef BCM_KATANA2_SUPPORT
   1577     int rqe_queue_offset_profiles = 0;
   1578 #endif
   1579 
   1580     if (SOC_IS_TRIDENT3X(unit)) {
   1581         qos_info->inf_pri_cng_mapping = PHB_MAPPING_TBL_1m;
   1582         qos_info->dscp_table = PHB_MAPPING_TBL_2m;
   1583         qos_info->ing_mpls_exp_mapping = PHB_MAPPING_TBL_3m;
   1584         qos_info->egr_dscp_table = EGR_ZONE_4_QOS_MAPPING_TABLEm;
   1585         qos_info->egr_dscp_table_outer = EGR_ZONE_2_QOS_MAPPING_TABLEm;
   1586         qos_info->pri_cng_chunk_size = 64;
   1587     } else {
   1588         qos_info->inf_pri_cng_mapping = ING_PRI_CNG_MAPm;
   1589         qos_info->dscp_table = DSCP_TABLEm;
   1590         qos_info->egr_dscp_table = EGR_DSCP_TABLEm;
   1591         qos_info->ing_mpls_exp_mapping = ING_MPLS_EXP_MAPPINGm;
   1592         qos_info->pri_cng_chunk_size = 16;
   1593     }
   1594 
   1595    ing_profiles = _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP;
   1596    dscp_profiles = _BCM_QOS_MAP_LEN_DSCP_TABLE;
   1597    egr_profiles = _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS;
   1598    egr_dscp_profiles = _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE;
   1599    ing_mpls_profiles = _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP;
   1600 
   1601 #ifdef BCM_KATANA_SUPPORT
   1602     offset_map_profiles = _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE;
   1603 #endif
   1604 #ifdef BCM_KATANA2_SUPPORT
   1605     rqe_queue_offset_profiles = _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP;
   1606 #endif
   1607 #ifdef BCM_SABER2_SUPPORT
   1608     service_pri_map_profiles = _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE;
   1609 #endif
   1610 
   1611     if (tr2_qos_initialized[unit]) {
   1612         BCM_IF_ERROR_RETURN(bcm_tr2_qos_detach(unit));
   1613     }
   1614 
   1615     /* Create mutex */
   1616     if (NULL == _tr2_qos_mutex[unit]) {
   1617         _tr2_qos_mutex[unit] = sal_mutex_create("qos mutex");
   1618         if (_tr2_qos_mutex[unit] == NULL) {
   1619             _bcm_tr2_qos_free_resources(unit);
   1620             return BCM_E_MEMORY;
   1621         }
   1622     }
   1623 
   1624     /* Allocate ingress profile usage bitmap */
   1625     if (NULL == qos_info->ing_pri_cng_bitmap) {
   1626         qos_info->ing_pri_cng_bitmap =
   1627             sal_alloc(SHR_BITALLOCSIZE(ing_profiles), "ing_pri_cng_bitmap");
   1628         if (qos_info->ing_pri_cng_bitmap == NULL) {
   1629             _bcm_tr2_qos_free_resources(unit);
   1630             return BCM_E_MEMORY;
   1631         }
   1632     }
   1633     sal_memset(qos_info->ing_pri_cng_bitmap, 0, SHR_BITALLOCSIZE(ing_profiles));
   1634     if (NULL == qos_info->pri_cng_hw_idx) {
   1635         qos_info->pri_cng_hw_idx = 
   1636             sal_alloc(sizeof(uint32) * ing_profiles, "pri_cng_hw_idx");
   1637         if (qos_info->pri_cng_hw_idx == NULL) {
   1638             _bcm_tr2_qos_free_resources(unit);
   1639             return BCM_E_MEMORY;
   1640         }    
   1641     }
   1642     sal_memset(qos_info->pri_cng_hw_idx, 0, (sizeof(uint32) * ing_profiles));
   1643 
   1644     /* Allocate egress profile usage bitmap */
   1645     if (NULL == qos_info->egr_mpls_bitmap) {
   1646         qos_info->egr_mpls_bitmap =
   1647             sal_alloc(SHR_BITALLOCSIZE(egr_profiles), "egr_mpls_bitmap");
   1648         if (qos_info->egr_mpls_bitmap == NULL) {
   1649             _bcm_tr2_qos_free_resources(unit);
   1650             return BCM_E_MEMORY;
   1651         }
   1652     }
   1653     sal_memset(qos_info->egr_mpls_bitmap, 0, SHR_BITALLOCSIZE(egr_profiles));
   1654     if (NULL == qos_info->egr_mpls_hw_idx) {
   1655         qos_info->egr_mpls_hw_idx = 
   1656             sal_alloc(sizeof(uint32) * egr_profiles, "egr_mpls_hw_idx");
   1657         if (qos_info->egr_mpls_hw_idx == NULL) {
   1658             _bcm_tr2_qos_free_resources(unit);
   1659             return BCM_E_MEMORY;
   1660         }    
   1661     }
   1662     sal_memset(qos_info->egr_mpls_hw_idx, 0, (sizeof(uint32) * egr_profiles));
   1663 
   1664     /* Allocate DSCP_TABLE profile usage bitmap */
   1665     if (NULL == qos_info->dscp_table_bitmap) {
   1666         qos_info->dscp_table_bitmap =
   1667             sal_alloc(SHR_BITALLOCSIZE(dscp_profiles), "dscp_table_bitmap");
   1668         if (qos_info->dscp_table_bitmap == NULL) {
   1669             _bcm_tr2_qos_free_resources(unit);
   1670             return BCM_E_MEMORY;
   1671         }
   1672     }
   1673     sal_memset(qos_info->dscp_table_bitmap, 0, SHR_BITALLOCSIZE(dscp_profiles));
   1674     if (SOC_IS_TRIDENT(unit)) {
   1675         int i;
   1676         for (i = 0; i < SOC_PORT_MAX(unit,all); i++) {
   1677             SHR_BITSET(qos_info->dscp_table_bitmap, i);
   1678         } 
   1679     }
   1680    
   1681     if (NULL == qos_info->dscp_hw_idx) {
   1682         qos_info->dscp_hw_idx = 
   1683             sal_alloc(sizeof(uint32) * dscp_profiles, "dscp_hw_idx");
   1684         if (qos_info->dscp_hw_idx == NULL) {
   1685             _bcm_tr2_qos_free_resources(unit);
   1686             return BCM_E_MEMORY;
   1687         }    
   1688     }
   1689     sal_memset(qos_info->dscp_hw_idx, 0, (sizeof(uint32) * dscp_profiles));
   1690 
   1691     /* Allocate EGR_DSCP_TABLE profile usage bitmap */
   1692     if (NULL == qos_info->egr_dscp_table_bitmap) {
   1693         qos_info->egr_dscp_table_bitmap =
   1694             sal_alloc(SHR_BITALLOCSIZE(egr_dscp_profiles), "egr_dscp_table_bitmap");
   1695         if (qos_info->egr_dscp_table_bitmap == NULL) {
   1696             _bcm_tr2_qos_free_resources(unit);
   1697             return BCM_E_MEMORY;
   1698         }
   1699     }
   1700     sal_memset(qos_info->egr_dscp_table_bitmap, 0, 
   1701                SHR_BITALLOCSIZE(egr_dscp_profiles));
   1702     if (NULL == qos_info->egr_dscp_hw_idx) {
   1703         qos_info->egr_dscp_hw_idx = 
   1704             sal_alloc(sizeof(uint32) * egr_dscp_profiles, "egr_dscp_hw_idx");
   1705         if (qos_info->egr_dscp_hw_idx == NULL) {
   1706             _bcm_tr2_qos_free_resources(unit);
   1707             return BCM_E_MEMORY;
   1708         }    
   1709     }
   1710     sal_memset(qos_info->egr_dscp_hw_idx, 0, (sizeof(uint32) * egr_dscp_profiles));
   1711 
   1712     /* Allocate egress profile usage bitmap */
   1713     if (NULL == qos_info->egr_mpls_bitmap_flags) {
   1714         qos_info->egr_mpls_bitmap_flags =
   1715             sal_alloc(SHR_BITALLOCSIZE(egr_profiles), "egr_mpls_bitmap_flags");
   1716         if (qos_info->egr_mpls_bitmap_flags == NULL) {
   1717             _bcm_tr2_qos_free_resources(unit);
   1718             return BCM_E_MEMORY;
   1719         }
   1720     }
   1721     sal_memset(qos_info->egr_mpls_bitmap_flags, 0, SHR_BITALLOCSIZE(egr_profiles));
   1722 
   1723     /* Allocate ingress mpls profile usage bitmap */
   1724     if (NULL == qos_info->ing_mpls_exp_bitmap) {
   1725         qos_info->ing_mpls_exp_bitmap =
   1726             sal_alloc(SHR_BITALLOCSIZE(ing_mpls_profiles), "ing_mpls_exp_bitmap");
   1727         if (qos_info->ing_mpls_exp_bitmap == NULL) {
   1728             _bcm_tr2_qos_free_resources(unit);
   1729             return BCM_E_MEMORY;
   1730         }
   1731     }
   1732     sal_memset(qos_info->ing_mpls_exp_bitmap, 0, SHR_BITALLOCSIZE(ing_mpls_profiles));
   1733 
   1734 #if defined(BCM_TOMAHAWK3_SUPPORT)
   1735     if (SOC_IS_TOMAHAWK3(unit)) {
   1736         /* For TH3 skip further initializations */
   1737     } else
   1738 #endif/* BCM_TOMAHAWK3_SUPPORT */
   1739     {
   1740 #ifdef BCM_KATANA_SUPPORT
   1741      /* Allocate queue offset map usage bitmap */
   1742     if (NULL == qos_info->offset_map_table_bitmap) {
   1743         qos_info->offset_map_table_bitmap =
   1744             sal_alloc(SHR_BITALLOCSIZE(offset_map_profiles),
   1745                                           "offset_map_table_bitmap");
   1746         if (qos_info->offset_map_table_bitmap == NULL) {
   1747             _bcm_tr2_qos_free_resources(unit);
   1748             return BCM_E_MEMORY;
   1749         }
   1750     }
   1751     sal_memset(qos_info->offset_map_table_bitmap, 0, 
   1752                                     SHR_BITALLOCSIZE(offset_map_profiles));
   1753     if (NULL == qos_info->offset_map_hw_idx) {
   1754         qos_info->offset_map_hw_idx =
   1755                sal_alloc(sizeof(uint32) * offset_map_profiles,
   1756                          "offset_map_hw_idx");
   1757         if (qos_info->offset_map_hw_idx == NULL) {
   1758             _bcm_tr2_qos_free_resources(unit);
   1759             return BCM_E_MEMORY;
   1760         }
   1761     }
   1762     sal_memset(qos_info->offset_map_hw_idx, 0, 
   1763                               (sizeof(uint32) * offset_map_profiles));
   1764 #endif /* BCM_KATANA_SUPPORT */
   1765 
   1766 #ifdef BCM_SABER2_SUPPORT
   1767     if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   1768         /* Allocate queue offset map usage bitmap */
   1769         if (NULL == qos_info->service_pri_map_table_bitmap) {
   1770             qos_info->service_pri_map_table_bitmap =
   1771                 sal_alloc(SHR_BITALLOCSIZE(service_pri_map_profiles),
   1772                         "service_pri_map_table_bitmap");
   1773             if (qos_info->service_pri_map_table_bitmap == NULL) {
   1774                 _bcm_tr2_qos_free_resources(unit);
   1775                 return BCM_E_MEMORY;
   1776             }
   1777         }
   1778         sal_memset(qos_info->service_pri_map_table_bitmap, 0, 
   1779                 SHR_BITALLOCSIZE(service_pri_map_profiles));
   1780         if (NULL == qos_info->service_pri_map_hw_idx) {
   1781             qos_info->service_pri_map_hw_idx =
   1782                 sal_alloc(sizeof(uint32) * service_pri_map_profiles,
   1783                         "service_pri_map_hw_idx");
   1784             if (qos_info->service_pri_map_hw_idx == NULL) {
   1785                 _bcm_tr2_qos_free_resources(unit);
   1786                 return BCM_E_MEMORY;
   1787             }
   1788         }
   1789         sal_memset(qos_info->service_pri_map_hw_idx, 0, 
   1790                 (sizeof(uint32) * service_pri_map_profiles));
   1791 
   1792         if (NULL == qos_info->service_pri_map_flags) {
   1793             qos_info->service_pri_map_flags =
   1794                 sal_alloc(sizeof(uint32) * service_pri_map_profiles,
   1795                         "service_pri_map_flags");
   1796             if (qos_info->service_pri_map_flags == NULL) {
   1797                 _bcm_tr2_qos_free_resources(unit);
   1798                 return BCM_E_MEMORY;
   1799             }
   1800         }
   1801         sal_memset(qos_info->service_pri_map_flags, 0, 
   1802                 (sizeof(uint32) * service_pri_map_profiles));
   1803     }
   1804     /* On Saber2 we need to reserve one more profile for dynamic update */
   1805     if (SOC_IS_SABER2(unit)) {
   1806         for (pid = 0; pid < MAX_QOS_ING_PRI_PROFILE; pid++) {
   1807              QOS_INFO(unit)->qos_profile_binding[unit][pid] = 0;
   1808         }
   1809 #ifdef BCM_WARM_BOOT_SUPPORT
   1810         if (SOC_WARM_BOOT(unit)) {
   1811             for (port = SB2_CMIC + 1; port < SB2_LPBK; port++) {
   1812                  rv = _bcm_tr2_port_tab_get(unit, port,
   1813                                             TRUST_DOT1P_PTRf, &index);
   1814                  if (BCM_FAILURE(rv)) {
   1815                      return rv;
   1816                  }
   1817                  _BCM_QOS_TRUST_DOT1P_PTR_CACHE_SET(unit, port, index);
   1818             }
   1819         }
   1820 #endif /* BCM_WARM_BOOT_SUPPORT */
   1821         sal_memset(pri_map, 0, sizeof(ing_pri_cng_map_entry_t) *
   1822                                       _BCM_QOS_MAP_CHUNK_PRI_CNG);
   1823         sal_memset(&phb, 0, sizeof(phb));
   1824         entries[0] = &pri_map;
   1825         entries[1] = &phb;
   1826 
   1827         for (index = 0; index < _BCM_QOS_MAP_CHUNK_PRI_CNG; index ++) {
   1828              soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map[index], PRIf,
   1829                                  7);
   1830              soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map[index],
   1831                                  CNGf, 1);
   1832         }
   1833         BCM_IF_ERROR_RETURN(_bcm_ing_pri_cng_map_entry_add(unit, entries,
   1834                                             _BCM_QOS_MAP_CHUNK_PRI_CNG,
   1835                                                    (uint32 *)&index));
   1836         QOS_INFO(unit)->pri_cng_hw_idx_reserved = index;
   1837     }
   1838 #endif /* BCM_SABER2_SUPPORT */
   1839 #ifdef BCM_KATANA2_SUPPORT
   1840      /* Allocate RQE_QUEUE_OFFSET map usage bitmap */
   1841     if (NULL == qos_info->rqe_queue_offset_bitmap) {
   1842         qos_info->rqe_queue_offset_bitmap =
   1843             sal_alloc(SHR_BITALLOCSIZE(rqe_queue_offset_profiles),
   1844                                           "rqe_queue_offset_bitmap");
   1845         if (qos_info->rqe_queue_offset_bitmap == NULL) {
   1846             _bcm_tr2_qos_free_resources(unit);
   1847             return BCM_E_MEMORY;
   1848         }
   1849     }
   1850     sal_memset(qos_info->rqe_queue_offset_bitmap, 0,
   1851                                     SHR_BITALLOCSIZE(rqe_queue_offset_profiles));
   1852     if (NULL == qos_info->rqe_queue_offset_hw_idx) {
   1853         qos_info->rqe_queue_offset_hw_idx =
   1854                sal_alloc(sizeof(uint32) * rqe_queue_offset_profiles,
   1855                          "rqe_queue_offset_hw_idx");
   1856         if (qos_info->rqe_queue_offset_hw_idx == NULL) {
   1857             _bcm_tr2_qos_free_resources(unit);
   1858             return BCM_E_MEMORY;
   1859         }
   1860     }
   1861     sal_memset(qos_info->rqe_queue_offset_hw_idx, 0,
   1862                               (sizeof(uint32) * rqe_queue_offset_profiles));
   1863 
   1864     if (NULL == qos_info->rqe_queue_offset_refcount) {
   1865         qos_info->rqe_queue_offset_refcount =
   1866                sal_alloc(sizeof(uint32) * rqe_queue_offset_profiles,
   1867                          "rqe_queue_offset_refcount");
   1868         if (qos_info->rqe_queue_offset_refcount == NULL) {
   1869             _bcm_tr2_qos_free_resources(unit);
   1870             return BCM_E_MEMORY;
   1871         }
   1872     }
   1873     sal_memset(qos_info->rqe_queue_offset_refcount, 0,
   1874                               (sizeof(uint32)* rqe_queue_offset_profiles));
   1875 #endif /* BCM_KATANA_SUPPORT */
   1876     }
   1877 
   1878 #ifdef BCM_WARM_BOOT_SUPPORT
   1879     rv = _bcm_tr2_qos_reinit(unit); 
   1880     if (SOC_FAILURE(rv)) {
   1881         _bcm_tr2_qos_free_resources(unit);
   1882         return rv;
   1883     }
   1884 #endif /* BCM_WARM_BOOT_SUPPORT */
   1885 
   1886     tr2_qos_initialized[unit] = TRUE;
   1887     return rv;
   1888 }
   1889 
   1890 /* Detach the QoS module. */
   1891 int 
   1892 bcm_tr2_qos_detach(int unit)
   1893 {
   1894     int rv = BCM_E_NONE;
   1895     _bcm_tr2_qos_free_resources(unit);
   1896     tr2_qos_initialized[unit] = FALSE;
   1897     return rv;
   1898 }
   1899 
   1900 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1901 STATIC int
   1902 _bcm_td2p_egr_qos_combo_map_create(int unit, uint32 flags, int *map_id) 
   1903 {
   1904     egr_qos_l2_map_entry_t  egr_pri_cng_map[_BCM_QOS_MAP_CHUNK_EGR_DSCP];
   1905     egr_qos_l3_map_entry_t egr_dscp_table[_BCM_QOS_MAP_CHUNK_EGR_DSCP];
   1906     int id, index = -1, rv = BCM_E_NONE;
   1907     void *entries[2];
   1908 
   1909     /* Check for pre-specified ID */
   1910     id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   1911 
   1912     /* Reserve a chunk in the EGR_DSCP_TABLE */
   1913     sal_memset(egr_pri_cng_map, 0, sizeof(egr_pri_cng_map));
   1914     entries[0] = &egr_pri_cng_map;  
   1915     sal_memset(egr_dscp_table, 0, sizeof(egr_dscp_table));
   1916     entries[1] = &egr_dscp_table;
   1917     BCM_IF_ERROR_RETURN(_bcm_egr_qos_profile_entry_add(unit, entries, 
   1918                                                         _BCM_QOS_MAP_CHUNK_EGR_DSCP,
   1919                                                                (uint32 *)&index));
   1920 
   1921     QOS_INFO(unit)->egr_dscp_hw_idx[id] = (index / 
   1922                                            _BCM_QOS_MAP_CHUNK_EGR_DSCP);
   1923     return rv;
   1924 }
   1925 
   1926 STATIC int
   1927 _bcm_td2p_egr_qos_combo_map_destroy(int unit, int map_id) 
   1928 {    
   1929     int id, rv = BCM_E_UNAVAIL;
   1930 
   1931     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   1932 
   1933     if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) {
   1934         return BCM_E_NOT_FOUND;
   1935     } else {
   1936         rv = _bcm_egr_qos_profile_entry_delete
   1937                 (unit, (QOS_INFO(unit)->egr_dscp_hw_idx[id] * 
   1938                  _BCM_QOS_MAP_CHUNK_EGR_DSCP));
   1939         if (BCM_E_NONE == rv) {
   1940             QOS_INFO(unit)->egr_dscp_hw_idx[id] = 0;
   1941             _BCM_QOS_EGR_DSCP_TABLE_USED_CLR(unit, id);
   1942         }
   1943     }
   1944     return rv;
   1945 }
   1946 
   1947 STATIC int
   1948 _bcm_td2p_egr_qos_combo_map_add(int unit, uint32 flags, bcm_qos_map_t *map, int map_id) 
   1949 {
   1950     int alloc_size, offset, cng, id, index, rv = BCM_E_NONE;
   1951     uint8 *egr_pri_cng_map;
   1952     uint8 *egr_dscp_table;
   1953     void *entries[3], *entry;
   1954     soc_mem_t qos_l2_map_mem;
   1955     soc_mem_t qos_l3_map_mem;
   1956 
   1957     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   1958 
   1959     /* Assign memory ID based on chip */
   1960     if (SOC_IS_TRIDENT3X(unit)) {
   1961         qos_l2_map_mem = EGR_ZONE_1_DOT1P_MAPPING_TABLE_4m;
   1962         qos_l3_map_mem = EGR_ZONE_4_QOS_MAPPING_TABLEm;
   1963     } else {
   1964         qos_l2_map_mem = EGR_PRI_CNG_MAPm;
   1965         qos_l3_map_mem = EGR_DSCP_TABLEm;
   1966     }
   1967 
   1968     /* Allocate memory for DMA */
   1969     alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_DSCP * 
   1970                   soc_mem_entry_words(unit, qos_l2_map_mem) * sizeof(uint32)); 
   1971     
   1972     egr_pri_cng_map = soc_cm_salloc(unit, alloc_size,
   1973                                 "TD2PLUS egr_pri_cng table");
   1974     if (NULL == egr_pri_cng_map) {
   1975      return (BCM_E_MEMORY);
   1976     }
   1977     sal_memset(egr_pri_cng_map, 0, alloc_size);
   1978 
   1979     alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_DSCP *
   1980                   soc_mem_entry_words(unit, qos_l3_map_mem) * sizeof(uint32));
   1981     egr_dscp_table = soc_cm_salloc(unit, alloc_size,
   1982                                    "TD2PLUS egr_dscp table");
   1983     if (NULL == egr_dscp_table) {        
   1984         soc_cm_sfree(unit, egr_pri_cng_map);
   1985         return (BCM_E_MEMORY);
   1986     }
   1987     sal_memset(egr_dscp_table, 0, alloc_size);
   1988 
   1989     /* Base index of table in hardware */
   1990     index = (QOS_INFO(unit)->egr_dscp_hw_idx[id] * 
   1991              _BCM_QOS_MAP_CHUNK_EGR_DSCP);
   1992 
   1993     /* Offset within table */
   1994     cng = _BCM_COLOR_ENCODING(unit, map->color);
   1995     offset = (map->int_pri << 2) | cng;
   1996 
   1997     /* Read the old profile chunk */
   1998     rv = soc_mem_read_range(unit, qos_l2_map_mem, MEM_BLOCK_ANY, 
   1999                            index, 
   2000                            index + (_BCM_QOS_MAP_CHUNK_EGR_DSCP -1), 
   2001                            egr_pri_cng_map);
   2002     if (BCM_FAILURE(rv)) {
   2003        soc_cm_sfree(unit, egr_dscp_table);
   2004        soc_cm_sfree(unit, egr_pri_cng_map);
   2005        return (rv);
   2006     }
   2007 
   2008     rv = soc_mem_read_range(unit, qos_l3_map_mem, MEM_BLOCK_ANY, 
   2009                             index, 
   2010                             index + (_BCM_QOS_MAP_CHUNK_EGR_DSCP -1), 
   2011                             egr_dscp_table);
   2012     if (BCM_FAILURE(rv)) {
   2013         soc_cm_sfree(unit, egr_dscp_table);
   2014         soc_cm_sfree(unit, egr_pri_cng_map);
   2015         return (rv);
   2016     }
   2017 
   2018     /* Modify what's needed */
   2019     entry = (void *)(egr_pri_cng_map + 
   2020                      soc_mem_entry_words(unit, qos_l2_map_mem) * sizeof(uint32) * offset);
   2021     soc_mem_field32_set(unit, qos_l2_map_mem, (uint32 *)entry, PRIf, map->pkt_pri);
   2022     soc_mem_field32_set(unit, qos_l2_map_mem, (uint32 *)entry, CFIf, map->pkt_cfi);
   2023     
   2024     entry = (void *)(egr_dscp_table +
   2025                      soc_mem_entry_words(unit, qos_l3_map_mem) * sizeof(uint32) * offset);
   2026     if (SOC_IS_TRIDENT3X(unit)) {
   2027         soc_mem_field32_set(unit, qos_l3_map_mem, (uint32 *)entry, QOSf, map->dscp);
   2028     } else {
   2029         soc_mem_field32_set(unit, qos_l3_map_mem, (uint32 *)entry, DSCPf, map->dscp);
   2030     }
   2031     /* Delete the old profile chunk */
   2032     rv = _bcm_egr_qos_profile_entry_delete(unit, index);
   2033     if (BCM_FAILURE(rv)) {
   2034         soc_cm_sfree(unit, egr_dscp_table);
   2035         soc_cm_sfree(unit, egr_pri_cng_map);
   2036         return (rv);
   2037     }
   2038 
   2039     /* Add new chunk and store new HW index */
   2040     entries[0] = egr_pri_cng_map;
   2041     entries[1] = egr_dscp_table;
   2042     if (SOC_IS_TRIDENT3X(unit)) {
   2043         entries[2] = egr_dscp_table; /* same for Zone2 dscp */
   2044     }
   2045     rv = _bcm_egr_qos_profile_entry_add(unit, entries, 
   2046                                        _BCM_QOS_MAP_CHUNK_EGR_DSCP, 
   2047                                        (uint32 *)&index);
   2048 
   2049     QOS_INFO(unit)->egr_dscp_hw_idx[id] = (index / 
   2050                                           _BCM_QOS_MAP_CHUNK_EGR_DSCP);
   2051 
   2052     /* Free the DMA memory */
   2053     soc_cm_sfree(unit, egr_dscp_table);
   2054     soc_cm_sfree(unit, egr_pri_cng_map);
   2055     
   2056     return rv;
   2057 }
   2058 #endif
   2059 
   2060 STATIC int
   2061 _bcm_tr2_qos_l2_map_create(int unit, uint32 flags, int *map_id) 
   2062 {
   2063     ing_pri_cng_map_entry_t ing_pri_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX];
   2064     ing_untagged_phb_entry_t ing_untagged_phb;
   2065     egr_mpls_pri_mapping_entry_t egr_mpls_pri_map[_BCM_QOS_MAP_CHUNK_EGR_MPLS];
   2066     egr_mpls_exp_mapping_1_entry_t egr_mpls_exp_map[_BCM_QOS_MAP_CHUNK_EGR_MPLS];
   2067     egr_mpls_exp_mapping_2_entry_t egr_mpls_exp_map2[_BCM_QOS_MAP_CHUNK_EGR_MPLS];
   2068     int id, index = -1, rv = BCM_E_NONE;
   2069     void *entries[3];
   2070 
   2071     /* Check parameters */
   2072     if (NULL == map_id) {
   2073         return BCM_E_PARAM;
   2074     }
   2075 
   2076     if (flags & BCM_QOS_MAP_INGRESS) {
   2077         /* Check for pre-specified ID */
   2078         if (flags & BCM_QOS_MAP_WITH_ID) {
   2079             id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   2080             if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 
   2081                 _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP) {
   2082                 return BCM_E_BADID;
   2083             }
   2084             if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   2085                 return BCM_E_PARAM;
   2086             }
   2087             if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   2088                 if (!(flags & BCM_QOS_MAP_REPLACE)) {
   2089                     return BCM_E_EXISTS;
   2090                 }
   2091             } else {
   2092                 _BCM_QOS_ING_PRI_CNG_USED_SET(unit, id);
   2093             }
   2094         } else {
   2095             id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->ing_pri_cng_bitmap, 
   2096                                    _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP);
   2097             if (id == -1) {
   2098                 return BCM_E_RESOURCE;
   2099             }
   2100             _BCM_QOS_ING_PRI_CNG_USED_SET(unit, id);
   2101             *map_id = id | (_BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP 
   2102                       << _BCM_QOS_MAP_SHIFT);
   2103         }
   2104         /* Reserve a chunk in the ING_PRI_CNG_MAP table */
   2105         sal_memset(ing_pri_map, 0, sizeof(ing_pri_map));
   2106         sal_memset(&ing_untagged_phb, 0, sizeof(ing_untagged_phb));
   2107         entries[0] = &ing_pri_map;
   2108         entries[1] = &ing_untagged_phb;
   2109         BCM_IF_ERROR_RETURN(_bcm_ing_pri_cng_map_entry_add(unit, entries, 
   2110                                             _BCM_QOS_MAP_CHUNK_PRI_CNG,
   2111                                                            (uint32 *)&index));
   2112         QOS_INFO(unit)->pri_cng_hw_idx[id] = (index / 
   2113                                               _BCM_QOS_MAP_CHUNK_PRI_CNG);
   2114     } else if (flags & BCM_QOS_MAP_EGRESS) {
   2115         /* Check for pre-specified ID */
   2116         if (flags & BCM_QOS_MAP_WITH_ID) {
   2117             id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   2118             if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 
   2119                 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) {
   2120                 return BCM_E_BADID;
   2121             }
   2122             if (_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   2123                 if (!(flags & BCM_QOS_MAP_REPLACE)) {
   2124                     return BCM_E_EXISTS;
   2125                 }
   2126             }
   2127         } else {
   2128             id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->egr_mpls_bitmap, 
   2129                                    _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS);
   2130             if (id == -1) {
   2131                 return BCM_E_RESOURCE;
   2132             }
   2133             *map_id = id | (_BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS 
   2134                       << _BCM_QOS_MAP_SHIFT);
   2135         }
   2136         /* Reserve a chunk in the EGR_MPLS_EXP_MAPPING_1/EGR_MPLS_PRI_MAPPING 
   2137            tables - these two tables always done together */
   2138 
   2139         if (SOC_IS_TRIDENT3X(unit)) {
   2140 #ifdef BCM_TRIDENT3_SUPPORT
   2141             rv = bcm_td3_qos_map_create(unit, (uint32 *)&index, _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   2142             if (BCM_FAILURE(rv)) {
   2143                 return rv;
   2144             }
   2145 #endif
   2146         } else {
   2147             sal_memset(egr_mpls_pri_map, 0, sizeof(egr_mpls_pri_map));
   2148             entries[0] = egr_mpls_pri_map;
   2149             sal_memset(egr_mpls_exp_map, 0, sizeof(egr_mpls_exp_map));
   2150             entries[1] = egr_mpls_exp_map;
   2151             sal_memset(egr_mpls_exp_map2, 0, sizeof(egr_mpls_exp_map2));
   2152             entries[2] = egr_mpls_exp_map2;
   2153             BCM_IF_ERROR_RETURN(_bcm_egr_mpls_combo_map_entry_add(unit, entries, 
   2154                                                    _BCM_QOS_MAP_CHUNK_EGR_MPLS,
   2155                                                               (uint32 *)&index));
   2156         }
   2157         QOS_INFO(unit)->egr_mpls_hw_idx[id] = (index / 
   2158                                                _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   2159         _BCM_QOS_EGR_MPLS_USED_SET(unit, id);   
   2160     }
   2161     return rv;
   2162 } 
   2163 
   2164 STATIC int
   2165 _bcm_tr2_qos_l3_map_create(int unit, uint32 flags, int *map_id) 
   2166 {
   2167     dscp_table_entry_t dscp_table[_BCM_QOS_MAP_CHUNK_DSCP];
   2168     egr_dscp_table_entry_t egr_dscp_table[_BCM_QOS_MAP_CHUNK_EGR_DSCP];
   2169     int id, index = -1, rv = BCM_E_NONE;
   2170     void *entries[2];
   2171 
   2172     /* Check parameters */
   2173     if (NULL == map_id) {
   2174         return BCM_E_PARAM;
   2175     }
   2176 
   2177     if (flags & BCM_QOS_MAP_INGRESS) {
   2178         /* Check for pre-specified ID */
   2179         if (flags & BCM_QOS_MAP_WITH_ID) {
   2180             id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   2181             if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 
   2182                 _BCM_QOS_MAP_TYPE_DSCP_TABLE) {
   2183                 return BCM_E_BADID;
   2184             }
   2185             if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) {
   2186                 if (!(flags & BCM_QOS_MAP_REPLACE)) {
   2187                     return BCM_E_EXISTS;
   2188                 }
   2189             } else {
   2190                 _BCM_QOS_DSCP_TABLE_USED_SET(unit, id);
   2191             }
   2192         } else {
   2193             id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->dscp_table_bitmap, 
   2194                                    _BCM_QOS_MAP_TYPE_DSCP_TABLE);
   2195             if (id == -1) {
   2196                 return BCM_E_RESOURCE;
   2197             }
   2198             _BCM_QOS_DSCP_TABLE_USED_SET(unit, id);
   2199             *map_id = id | (_BCM_QOS_MAP_TYPE_DSCP_TABLE 
   2200                       << _BCM_QOS_MAP_SHIFT);
   2201         }
   2202         /* Reserve a chunk in the DSCP_TABLE */
   2203         sal_memset(dscp_table, 0, sizeof(dscp_table));
   2204         entries[0] = &dscp_table;
   2205         BCM_IF_ERROR_RETURN(_bcm_dscp_table_entry_add(unit, entries, 
   2206                                                       _BCM_QOS_MAP_CHUNK_DSCP,
   2207                                                       (uint32 *)&index));
   2208         QOS_INFO(unit)->dscp_hw_idx[id] = index / _BCM_QOS_MAP_CHUNK_DSCP;
   2209     } else if (flags & BCM_QOS_MAP_EGRESS) {
   2210         /* Check for pre-specified ID */
   2211         if (flags & BCM_QOS_MAP_WITH_ID) {
   2212             id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   2213             if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 
   2214                 _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE) {
   2215                 return BCM_E_BADID;
   2216             }
   2217             if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) {
   2218                 if (!(flags & BCM_QOS_MAP_REPLACE)) {
   2219                     return BCM_E_EXISTS;
   2220                 }
   2221             } else {
   2222                 _BCM_QOS_EGR_DSCP_TABLE_USED_SET(unit, id);
   2223             }
   2224         } else {
   2225             id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->egr_dscp_table_bitmap, 
   2226                                    _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE);
   2227             if (id == -1) {
   2228                 return BCM_E_RESOURCE;
   2229             }
   2230             _BCM_QOS_EGR_DSCP_TABLE_USED_SET(unit, id);
   2231             *map_id = id | (_BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE 
   2232                       << _BCM_QOS_MAP_SHIFT);
   2233         }
   2234 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   2235         if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   2236             rv = _bcm_td2p_egr_qos_combo_map_create(unit, flags, map_id); 
   2237             if (BCM_FAILURE(rv)) {
   2238                 return (rv);
   2239             }
   2240         } else
   2241 #endif
   2242         { 
   2243             /* Reserve a chunk in the EGR_DSCP_TABLE */
   2244             sal_memset(egr_dscp_table, 0, sizeof(egr_dscp_table));
   2245             entries[0] = &egr_dscp_table;
   2246             if (SOC_IS_TRIDENT3X(unit)) {
   2247                 /* use same setting for both Zone2 and Zone4 */
   2248                 entries[1] = &egr_dscp_table; /* for Zone2 */
   2249             }
   2250             BCM_IF_ERROR_RETURN(_bcm_egr_dscp_table_entry_add(unit, entries, 
   2251                                                        _BCM_QOS_MAP_CHUNK_EGR_DSCP,
   2252                                                               (uint32 *)&index, 0));
   2253             QOS_INFO(unit)->egr_dscp_hw_idx[id] = (index / 
   2254                                                    _BCM_QOS_MAP_CHUNK_EGR_DSCP);
   2255         }
   2256     }
   2257     return rv;
   2258 }
   2259 
   2260 STATIC int
   2261 _bcm_tr2_qos_mpls_map_create(int unit, uint32 flags, int *map_id) 
   2262 {
   2263     /* Check parameters */
   2264     if (NULL == map_id) {
   2265         return BCM_E_PARAM;
   2266     }
   2267 
   2268     if (flags & BCM_QOS_MAP_INGRESS) {
   2269         /* The ING_MPLS_EXP_MAPPING table is used */
   2270 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   2271         uint32 mpls_exp_map_flags = BCM_MPLS_EXP_MAP_INGRESS;
   2272 
   2273         if (flags & BCM_QOS_MAP_WITH_ID) {
   2274             mpls_exp_map_flags |= BCM_MPLS_EXP_MAP_WITH_ID;
   2275         }
   2276 
   2277         BCM_IF_ERROR_RETURN(bcm_tr_mpls_exp_map_create(unit,
   2278                                             mpls_exp_map_flags, map_id));
   2279         _BCM_QOS_ING_MPLS_EXP_USED_SET(unit, 
   2280                         ((*map_id) & _BCM_TR_MPLS_EXP_MAP_TABLE_NUM_MASK));
   2281 #endif
   2282     } else if (flags & BCM_QOS_MAP_EGRESS) {
   2283         /* The EGR_MPLS_EXP_MAPPING_1 table is used */
   2284         /* Shared with L2 egress map */
   2285         uint32 qos_map_flags = BCM_QOS_MAP_EGRESS;
   2286 
   2287         if (flags & BCM_QOS_MAP_WITH_ID) {
   2288             qos_map_flags |= BCM_QOS_MAP_WITH_ID;
   2289         }
   2290 
   2291         BCM_IF_ERROR_RETURN(_bcm_tr2_qos_l2_map_create(unit, qos_map_flags,
   2292                                                        map_id));
   2293         _BCM_QOS_EGR_MPLS_FLAGS_USED_SET(unit, 
   2294                                          ((*map_id) & _BCM_QOS_MAP_TYPE_MASK));
   2295     } else {
   2296         return BCM_E_PARAM;
   2297     }
   2298     return BCM_E_NONE;
   2299 }
   2300 
   2301 #ifdef BCM_APACHE_SUPPORT
   2302 STATIC int
   2303 _bcm_tr2_qos_mpls_exp_to_phb_cng_map_create(int unit, uint32 flags, int *map_id)
   2304 {
   2305     if (flags & BCM_QOS_MAP_INGRESS) {
   2306         /* The ING_MPLS_EXP_MAPPING_1 table is used */
   2307 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   2308         uint32 mpls_exp_map_flags = BCM_MPLS_EXP_MAP_INGRESS;
   2309 
   2310         if (flags & BCM_QOS_MAP_WITH_ID) {
   2311             mpls_exp_map_flags |= BCM_MPLS_EXP_MAP_WITH_ID;
   2312         }
   2313 
   2314         BCM_IF_ERROR_RETURN(bcm_tr_mpls_exp_to_phb_cng_map_create(unit,
   2315                                             mpls_exp_map_flags, map_id));
   2316 #endif
   2317     } else if (flags & BCM_QOS_MAP_EGRESS) {
   2318 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   2319         /* The EGR_MPLS_EXP_MAPPING_3 table is used */
   2320         BCM_IF_ERROR_RETURN(bcm_tr_mpls_exp_to_phb_cng_map_create(unit,
   2321                                             BCM_MPLS_EXP_MAP_EGRESS, map_id));
   2322 #endif
   2323     } else {
   2324         return BCM_E_PARAM;
   2325     }
   2326     return BCM_E_NONE;
   2327 }
   2328 #endif
   2329 
   2330 #ifdef BCM_HURRICANE3_SUPPORT
   2331 STATIC int
   2332 _bcm_hr3_qos_miml_map_create(int unit, uint32 flags, int *map_id) 
   2333 {
   2334     ing_pri_cng_map_entry_t ing_pri_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX];
   2335     ing_untagged_phb_entry_t ing_untagged_phb;
   2336     egr_mpls_pri_mapping_entry_t egr_mpls_pri_map[_BCM_QOS_MAP_CHUNK_EGR_MPLS];
   2337     egr_mpls_exp_mapping_1_entry_t egr_mpls_exp_map[_BCM_QOS_MAP_CHUNK_EGR_MPLS];
   2338     egr_mpls_exp_mapping_2_entry_t egr_mpls_exp_map2[_BCM_QOS_MAP_CHUNK_EGR_MPLS];
   2339     int id, index = -1, rv = BCM_E_NONE;
   2340     void *entries[3];
   2341     if (flags & BCM_QOS_MAP_INGRESS) {
   2342         /* Check for pre-specified ID */
   2343         if (flags & BCM_QOS_MAP_WITH_ID) {
   2344             id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   2345             if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 
   2346                 _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP) {
   2347                 return BCM_E_BADID;
   2348             }
   2349             if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   2350                 return BCM_E_PARAM;
   2351             }
   2352             if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   2353                 if (!(flags & BCM_QOS_MAP_REPLACE)) {
   2354                     return BCM_E_EXISTS;
   2355                 }
   2356             } else {
   2357                 _BCM_QOS_ING_PRI_CNG_USED_SET(unit, id);
   2358             }
   2359         } else {
   2360             id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->ing_pri_cng_bitmap, 
   2361                                    _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP);
   2362             if (id == -1) {
   2363                 return BCM_E_RESOURCE;
   2364             }
   2365             _BCM_QOS_ING_PRI_CNG_USED_SET(unit, id);
   2366             *map_id = id | (_BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP 
   2367                       << _BCM_QOS_MAP_SHIFT);
   2368         }
   2369         /* Reserve a chunk in the ING_PRI_CNG_MAP table */
   2370         sal_memset(ing_pri_map, 0, sizeof(ing_pri_map));
   2371         entries[0] = &ing_pri_map;
   2372         entries[1] = &ing_untagged_phb;
   2373         BCM_IF_ERROR_RETURN(_bcm_ing_pri_cng_map_entry_add(unit, entries, 
   2374                                             _BCM_QOS_MAP_CHUNK_PRI_CNG,
   2375                                                            (uint32 *)&index));
   2376         QOS_INFO(unit)->pri_cng_hw_idx[id] = (index / 
   2377                                               _BCM_QOS_MAP_CHUNK_PRI_CNG);
   2378     } else if (flags & BCM_QOS_MAP_EGRESS) {
   2379         /* Check for pre-specified ID */
   2380         if (flags & BCM_QOS_MAP_WITH_ID) {
   2381             id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   2382             if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 
   2383                 _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS) {
   2384                 return BCM_E_BADID;
   2385             }
   2386             if (_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   2387                 if (!(flags & BCM_QOS_MAP_REPLACE)) {
   2388                     return BCM_E_EXISTS;
   2389                 }
   2390             } else {
   2391                 _BCM_QOS_EGR_MPLS_USED_SET(unit, id);
   2392             }
   2393         } else {
   2394             id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->egr_mpls_bitmap, 
   2395                                    _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS);
   2396             if (id == -1) {
   2397                 return BCM_E_RESOURCE;
   2398             }
   2399             _BCM_QOS_EGR_MPLS_USED_SET(unit, id);
   2400             *map_id = id | (_BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS 
   2401                       << _BCM_QOS_MAP_SHIFT);
   2402         }
   2403         /* Reserve a chunk in the EGR_MPLS_EXP_MAPPING_1/EGR_MPLS_PRI_MAPPING 
   2404            tables - these two tables always done together */
   2405         sal_memset(egr_mpls_pri_map, 0, sizeof(egr_mpls_pri_map));
   2406         entries[0] = egr_mpls_pri_map;
   2407         sal_memset(egr_mpls_exp_map, 0, sizeof(egr_mpls_exp_map));
   2408         entries[1] = egr_mpls_exp_map;
   2409         sal_memset(egr_mpls_exp_map2, 0, sizeof(egr_mpls_exp_map2));
   2410         entries[2] = egr_mpls_exp_map2;
   2411         BCM_IF_ERROR_RETURN(_bcm_egr_mpls_combo_map_entry_add(unit, entries, 
   2412                                                    _BCM_QOS_MAP_CHUNK_EGR_MPLS,
   2413                                                               (uint32 *)&index));
   2414         QOS_INFO(unit)->egr_mpls_hw_idx[id] = (index / 
   2415                                                _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   2416     }
   2417     return rv;
   2418 } 
   2419 #endif /* BCM_HURRICANE3_SUPPORT */
   2420 
   2421 #ifdef BCM_KATANA_SUPPORT
   2422 /* Create a ING_QUEUE_OFFSET_MAP profile */
   2423 STATIC int 
   2424 _bcm_kt_ing_queue_offset_map_create(int unit, uint32 flags, int *map_id)
   2425 {
   2426     ing_queue_offset_mapping_table_entry_t 
   2427                              offset_map_table[_BCM_QOS_MAP_CHUNK_OFFSET_MAP];
   2428     void *entries[1];
   2429     int id = 0, index = -1;
   2430     if (flags & BCM_QOS_MAP_WITH_ID) {
   2431       /* Check for pre-specified ID */
   2432         id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   2433         if ((*map_id >> _BCM_QOS_MAP_SHIFT) !=
   2434             _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE) {
   2435             return BCM_E_BADID;
   2436         }
   2437         if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id)) {
   2438             if (!(flags & BCM_QOS_MAP_REPLACE)) {
   2439                 return BCM_E_EXISTS;
   2440             }
   2441         } else {
   2442                 _BCM_QOS_OFFSET_MAP_TABLE_USED_SET(unit, id);
   2443         }
   2444 
   2445     } else {
   2446         id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->offset_map_table_bitmap,
   2447                                   _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE);
   2448             if (id == -1) {
   2449                 return BCM_E_RESOURCE;
   2450             }
   2451             _BCM_QOS_OFFSET_MAP_TABLE_USED_SET(unit, id);
   2452             *map_id = id | (_BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE
   2453                                                      << _BCM_QOS_MAP_SHIFT);
   2454     }
   2455     /* Reserve a chunk in the ING_QUEUE_OFFSET_MAPPING_TABLE */
   2456     sal_memset(offset_map_table, 0, sizeof(offset_map_table));
   2457     entries[0] = &offset_map_table;
   2458     BCM_IF_ERROR_RETURN(_bcm_offset_map_table_entry_add(unit, entries,
   2459                      _BCM_QOS_MAP_CHUNK_OFFSET_MAP, (uint32 *)&index));
   2460     QOS_INFO(unit)->offset_map_hw_idx[id] = 
   2461                                    (index / _BCM_QOS_MAP_CHUNK_OFFSET_MAP);
   2462     return BCM_E_NONE;
   2463 }
   2464 #endif /* BCM_KATANA_SUPPORT */
   2465 #ifdef BCM_KATANA2_SUPPORT
   2466 /* Create a RQE_QUEUE_OFFSET profile */
   2467 STATIC int
   2468 _bcm_kt2_rqe_queue_offset_map_create(int unit, uint32 flags, int *map_id)
   2469 {
   2470     int id = 0;
   2471     if (flags & BCM_QOS_MAP_WITH_ID) {
   2472       /* Check for pre-specified ID */
   2473         id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   2474         if ((*map_id >> _BCM_QOS_MAP_SHIFT) !=
   2475             _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP) {
   2476             return BCM_E_BADID;
   2477         }
   2478         if (_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) {
   2479             if (!(flags & BCM_QOS_MAP_REPLACE)) {
   2480                 return BCM_E_EXISTS;
   2481             }
   2482         } else {
   2483             _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_SET(unit, id);
   2484         }
   2485     } else {
   2486         id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->rqe_queue_offset_bitmap,
   2487                                    _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP);
   2488             if (id == -1) {
   2489                 return BCM_E_RESOURCE;
   2490             }
   2491             _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_SET(unit, id);
   2492             *map_id = id | (_BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP
   2493                                                      << _BCM_QOS_MAP_SHIFT);
   2494     }
   2495     QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] = id;
   2496     return BCM_E_NONE;
   2497 }
   2498 STATIC
   2499 int
   2500 _bcm_rqe_queue_offset_map_table_compare(int unit, uint32 *entry, int id, int *profile_offset)
   2501 {
   2502     int i = 0, hw_idx;
   2503     int pri = 0;
   2504     int no_match_flag = 1;
   2505     int value = 0;
   2506     int queue_offset = 0;
   2507     int rv = BCM_E_NONE;
   2508     soc_field_t profile_field[] = {Q_OFFSET0f,
   2509                                    Q_OFFSET1f,
   2510                                    Q_OFFSET2f,
   2511                                    Q_OFFSET3f};
   2512 
   2513     hw_idx = QOS_INFO(unit)->rqe_queue_offset_hw_idx[id];
   2514     while (i < _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP) {
   2515         if (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, i)) {
   2516             i++;
   2517             continue;
   2518         }
   2519         if (i == hw_idx) {
   2520             i++;
   2521             continue;
   2522         }
   2523 
   2524         for (pri = 0, no_match_flag =0;
   2525              pri < _BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP;
   2526              pri++) {
   2527             value = soc_reg_field_get(unit, RQE_QUEUE_OFFSETr,
   2528                                          entry[pri]/* regval[priority]*/,
   2529                                           profile_field[hw_idx]/* profile  being set*/);
   2530             queue_offset = soc_reg_field_get(unit , RQE_QUEUE_OFFSETr,
   2531                                      entry[pri] /* regval[priority]*/,
   2532                                      profile_field[i] /* profile compared against*/);
   2533 
   2534             if (value != queue_offset) {
   2535               /* single mismatch is no profile match*/
   2536               no_match_flag = 1;
   2537               break;
   2538             }
   2539         }
   2540         if (!no_match_flag) {
   2541         /* first match return profile_offset id */
   2542            *profile_offset = i;
   2543            break;
   2544         }
   2545         /* increment to next profile */
   2546         i++;
   2547     }
   2548     if (no_match_flag) {
   2549         *profile_offset = id;
   2550         rv = BCM_E_NOT_FOUND;
   2551     }
   2552     return rv;
   2553 }
   2554 STATIC
   2555 int
   2556 _bcm_rqe_queue_offset_map_table_sw_delete (int unit, int id)
   2557 {
   2558 
   2559     int i = 0;
   2560     int p_idx = 0;
   2561     int rv = BCM_E_NONE;
   2562     int refcount = 0;
   2563     uint32 rqe_queue_offset_profile[_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP];
   2564     soc_field_t profile_field[] = {Q_OFFSET0f,
   2565                                    Q_OFFSET1f,
   2566                                    Q_OFFSET2f,
   2567                                    Q_OFFSET3f};
   2568 
   2569     if (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) {
   2570         return BCM_E_NOT_FOUND;
   2571     }
   2572     sal_memset(rqe_queue_offset_profile, 0, sizeof(rqe_queue_offset_profile));
   2573     /* Read the profile chunk */
   2574     for (i = 0; i <_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP;
   2575          i++) {
   2576         rv = READ_RQE_QUEUE_OFFSETr(unit, i,
   2577                            &rqe_queue_offset_profile[i]);
   2578         if (BCM_FAILURE(rv)) {
   2579             return rv;
   2580         }
   2581     }
   2582 
   2583     /* get the hw id
   2584      * decrement the refcount
   2585      * if refcount is 0
   2586      * delete the profile_offset fields
   2587      */
   2588     p_idx = QOS_INFO(unit)->rqe_queue_offset_hw_idx[id];
   2589     QOS_INFO(unit)->rqe_queue_offset_refcount[p_idx]--;
   2590     refcount = QOS_INFO(unit)->rqe_queue_offset_refcount[p_idx];
   2591 
   2592     if (!refcount) {
   2593         for(i=0; i<_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP;
   2594          i++) {
   2595             soc_reg_field_set(unit, RQE_QUEUE_OFFSETr,
   2596                   &rqe_queue_offset_profile[i], profile_field[p_idx],
   2597                   0);
   2598             rv = WRITE_RQE_QUEUE_OFFSETr(unit, i,
   2599                            rqe_queue_offset_profile[i]);
   2600             if (BCM_FAILURE(rv)) {
   2601                 return rv;
   2602             }
   2603 
   2604          }
   2605     }
   2606 
   2607     return BCM_E_NONE;
   2608 
   2609 }
   2610 int
   2611 _bcm_rqe_queue_offset_map_multi_get(int unit, uint32 flags,
   2612                           int id, int array_size,
   2613                           bcm_qos_map_t *array, int *array_count)
   2614 {
   2615     int idx;
   2616     int count = 0;
   2617     int hw_id = 0;
   2618     int num_entries = 0;
   2619 
   2620     uint32      entry;
   2621     bcm_qos_map_t   *map = NULL;
   2622     soc_field_t profile_field[] = {Q_OFFSET0f,
   2623                                    Q_OFFSET1f,
   2624                                    Q_OFFSET2f,
   2625                                    Q_OFFSET3f};
   2626     /* QOS_LOCK -lock is taken by parent
   2627      */
   2628     num_entries = _BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP;
   2629     hw_id = QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] ;
   2630 
   2631     for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) {
   2632         /* read the profile offset on the hw_id
   2633          */
   2634         map = &array[idx];
   2635         map->int_pri = idx;
   2636         READ_RQE_QUEUE_OFFSETr(unit, idx, &entry);
   2637         map->queue_offset = soc_reg_field_get(unit, RQE_QUEUE_OFFSETr,
   2638               entry, profile_field[hw_id]);
   2639         count++;
   2640 
   2641     }
   2642 
   2643     *array_count = count;
   2644     return BCM_E_NONE;
   2645 
   2646 
   2647 }
   2648 #endif /* BCM_KATANA2_SUPPORT */
   2649 
   2650 #ifdef BCM_SABER2_SUPPORT
   2651 /* Create a ING_SERVICE_PRI_MAP profile */
   2652 STATIC int 
   2653 _bcm_sb2_ing_service_pri_map_create(int unit, uint32 flags, int *map_id)
   2654 {
   2655     ing_service_pri_map_0_entry_t  
   2656         service_pri_map_table[_BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP];
   2657     void *entries[_BCM_SB2_OAM_PRI_MAP_TABLE_MAX];
   2658     int pri = 0;
   2659     int id = 0, index = -1;
   2660     soc_mem_t mem = ING_SERVICE_PRI_MAP_0m;
   2661     int table;
   2662     if (flags & BCM_QOS_MAP_WITH_ID) {
   2663       /* Check for pre-specified ID */
   2664         id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   2665         if ((*map_id >> _BCM_QOS_MAP_SHIFT) !=
   2666             _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE) {
   2667             return BCM_E_BADID;
   2668         }
   2669         if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) {
   2670             if (!(flags & BCM_QOS_MAP_REPLACE)) {
   2671                 return BCM_E_EXISTS;
   2672             }
   2673         } else {
   2674                 _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_SET(unit, id);
   2675         }
   2676 
   2677     } else {
   2678         id = _bcm_tr2_qos_id_alloc(unit,
   2679              QOS_INFO(unit)->service_pri_map_table_bitmap,
   2680              _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE);
   2681             if (id == -1) {
   2682                 return BCM_E_RESOURCE;
   2683             }
   2684             _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_SET(unit, id);
   2685             *map_id = id | (_BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE
   2686                                                      << _BCM_QOS_MAP_SHIFT);
   2687     }
   2688     /* Reserve a chunk in the ING_SERVICE_PRI_MAP_0/1/2 TABLE */
   2689     for ( pri = 0; pri < _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP; pri++) {
   2690         /* Clear ingress service pri map profile entry. */
   2691         sal_memcpy(&service_pri_map_table[pri], soc_mem_entry_null(unit, mem),
   2692                 soc_mem_entry_words(unit, mem) * sizeof(uint32));
   2693 
   2694         soc_mem_field32_set(unit, mem, 
   2695                 &service_pri_map_table[pri], OFFSET_VALIDf, 1);
   2696     }
   2697     for (table = 0; table < _BCM_SB2_OAM_PRI_MAP_TABLE_MAX; table++) {
   2698         /* Assign every table with same set of values */
   2699         entries[table] = &service_pri_map_table;
   2700     }
   2701     BCM_IF_ERROR_RETURN(_bcm_service_pri_map_table_entry_add(unit, entries,
   2702                      _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP, (uint32 *)&index));
   2703     QOS_INFO(unit)->service_pri_map_hw_idx[id] = 
   2704                                    (index / _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP);
   2705     _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_SET(unit, id, flags);
   2706     return BCM_E_NONE;
   2707 }
   2708 #endif /* BCM_SABER2_SUPPORT */
   2709 
   2710 /* Create a QoS map profile */
   2711 /* This will allocate an ID and a profile index with all-zero mapping */
   2712 int 
   2713 bcm_tr2_qos_map_create(int unit, uint32 flags, int *map_id)
   2714 {
   2715     int rv = BCM_E_UNAVAIL;
   2716     QOS_INIT(unit);
   2717     if (flags == 0) {
   2718         return BCM_E_PARAM;
   2719     }
   2720     QOS_LOCK(unit);
   2721     if (flags & BCM_QOS_MAP_L2) {
   2722         rv = _bcm_tr2_qos_l2_map_create(unit, flags, map_id);
   2723     } else if (flags & BCM_QOS_MAP_L3) {
   2724         rv = _bcm_tr2_qos_l3_map_create(unit, flags, map_id);
   2725     } else if (flags & BCM_QOS_MAP_MPLS) {
   2726         if (!soc_feature(unit, soc_feature_mpls)) {
   2727             QOS_UNLOCK(unit);
   2728             return rv;
   2729         }
   2730         rv = _bcm_tr2_qos_mpls_map_create(unit, flags, map_id);
   2731     }
   2732 #ifdef BCM_KATANA_SUPPORT
   2733     else if (flags & BCM_QOS_MAP_QUEUE) {
   2734         rv = _bcm_kt_ing_queue_offset_map_create(unit, flags, map_id);
   2735     }
   2736 #endif
   2737 #ifdef BCM_KATANA2_SUPPORT
   2738     else if (flags & BCM_QOS_MAP_REPLICATION) {
   2739         rv = _bcm_kt2_rqe_queue_offset_map_create(unit, flags, map_id);
   2740     }
   2741 #endif
   2742 #ifdef BCM_APACHE_SUPPORT
   2743     else if ((flags & BCM_QOS_MAP_OAM_MPLS_EXP) &&
   2744             ((flags & BCM_QOS_MAP_INGRESS) || 
   2745              (flags & BCM_QOS_MAP_EGRESS))) {
   2746             if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) {
   2747                 rv = _bcm_tr2_qos_mpls_exp_to_phb_cng_map_create(unit, flags, map_id);
   2748             } else {
   2749                 QOS_UNLOCK(unit);
   2750                 return BCM_E_UNAVAIL;
   2751             }
   2752     }
   2753 #endif
   2754 
   2755 #ifdef BCM_SABER2_SUPPORT
   2756     else if (
   2757             (flags & BCM_QOS_MAP_OAM_INTPRI)         ||
   2758             (flags & BCM_QOS_MAP_OAM_OUTER_VLAN_PCP) ||
   2759             (flags & BCM_QOS_MAP_OAM_INNER_VLAN_PCP) ||
   2760             (flags & BCM_QOS_MAP_OAM_MPLS_EXP)      
   2761             ) {
   2762         if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   2763             rv = _bcm_sb2_ing_service_pri_map_create(unit, flags, map_id);
   2764         } else {
   2765             QOS_UNLOCK(unit);
   2766             return BCM_E_PARAM;
   2767         }
   2768     }
   2769 #endif
   2770     
   2771 #ifdef BCM_HURRICANE3_SUPPORT
   2772     else if (flags & BCM_QOS_MAP_MIML) {
   2773         if (!soc_feature(unit, soc_feature_miml)) {
   2774             QOS_UNLOCK(unit);
   2775             return rv;
   2776         }
   2777         rv = _bcm_hr3_qos_miml_map_create(unit, flags, map_id);
   2778     }
   2779 #endif
   2780 #ifdef BCM_WARM_BOOT_SUPPORT
   2781     SOC_CONTROL_LOCK(unit);
   2782     SOC_CONTROL(unit)->scache_dirty = 1;
   2783     SOC_CONTROL_UNLOCK(unit);
   2784 #endif
   2785     QOS_UNLOCK(unit);
   2786     return rv;
   2787 }
   2788 
   2789 /*
   2790  * Function:
   2791  *      _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_clear
   2792  * Purpose:
   2793  *      Clear the IPRI mapping pointer from EGR_VLAN_CONTROL_3 register for all ports
   2794  * Parameters:
   2795  *      unit       - (IN) BCM unit.
   2796  *      index      - (IN) Index to access EGR_MPLS_EXP_MAPPING_2m table.
   2797  * Returns:
   2798  *      BCM_E_XXX
   2799  */
   2800 int
   2801 _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_clear(int unit, int index)
   2802 {
   2803     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   2804 	    int rv, alloc_size;
   2805         uint32 rval;
   2806         char *buf;
   2807         void *entries[1];
   2808         uint8 pri = 0;
   2809         int  id=0;
   2810 		bcm_port_t port;
   2811         uint32 old_index=0;
   2812 
   2813         if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m)) {
   2814             alloc_size = 64 * sizeof(egr_pri_cng_map_entry_t);
   2815             buf = soc_cm_salloc(unit, alloc_size, "TR2 egr mpls exp map2");
   2816             if (NULL == buf) {
   2817                 return (BCM_E_MEMORY);
   2818             }
   2819             id = (index * _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   2820             rv = soc_mem_read_range(unit, EGR_MPLS_EXP_MAPPING_2m, MEM_BLOCK_ANY, 
   2821                                     id,
   2822                                     (id + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)),
   2823                                     (void *) buf);
   2824             if (BCM_FAILURE(rv)) {
   2825                 soc_cm_sfree(unit, buf);
   2826                 return rv;
   2827             }
   2828 
   2829             /* Check if priority is configured for given QOS MAP ID profile */
   2830             for (id = 0; id < _BCM_QOS_MAP_CHUNK_EGR_MPLS; id++) {
   2831                 entries[0] = soc_mem_table_idx_to_pointer(unit,
   2832                                                   EGR_MPLS_EXP_MAPPING_2m,
   2833                                                   void *, buf, id);
   2834                 if (!SOC_IS_TRIDENT3X(unit)) {
   2835                     pri = soc_mem_field32_get(unit, EGR_MPLS_EXP_MAPPING_2m,
   2836                                               entries[0], PRIf);
   2837                 }
   2838                 /* Priority configured, proceed with configuration of
   2839                  * VLAN_CONTROL_3 register, with IPRI_MAPPING_PTR and
   2840                  * IPRI_CIF_SEL fields.
   2841                  */
   2842                 if (pri) {
   2843                       break;
   2844                 }
   2845             }
   2846             soc_cm_sfree(unit, buf);
   2847         }
   2848 
   2849         /* Priority field is not configured in EGR_MPLS_EXP_MAPPING_2m table,
   2850          * skip VLAN_CONTROL_3 register configuration.
   2851          */
   2852         if ((!pri)) {
   2853             return BCM_E_NONE;
   2854         }
   2855 
   2856 		/* Iterate over ports, clear the mapping pointer */
   2857 		PBMP_PORT_ITER(unit, port)
   2858 		{
   2859 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   2860             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   2861                 soc_mem_t mem = EGR_VLAN_CONTROL_3m;
   2862                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
   2863                     BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_get(unit,
   2864                         port, mem, IPRI_MAPPING_PTRf, &old_index));
   2865                     if (old_index == index) {
   2866                         soc_field_t fields[2] = {
   2867                             IPRI_MAPPING_PTRf, IPRI_CFI_SELf
   2868                         };
   2869                         uint32 values[2] = {0, 0};
   2870                         BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_fields_set(
   2871                             unit, port, mem, 2, fields, values));
   2872                     }
   2873                 } else {
   2874                     egr_vlan_control_3_entry_t entry;
   2875                     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, &entry);
   2876                     BCM_IF_ERROR_RETURN(rv);
   2877 
   2878                     old_index = soc_mem_field32_get(unit, mem, &entry,
   2879                                                     IPRI_MAPPING_PTRf);
   2880                     if (old_index == index) {
   2881                         soc_mem_field32_set(unit, mem, &entry,
   2882                             IPRI_MAPPING_PTRf, 0);
   2883                         soc_mem_field32_set(unit, mem, &entry,
   2884                             IPRI_CFI_SELf, 0);
   2885                         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, port,
   2886                                 &entry);
   2887                         BCM_IF_ERROR_RETURN(rv);
   2888                     }
   2889                 }
   2890             } else
   2891 #endif
   2892             {
   2893                 rv = READ_EGR_VLAN_CONTROL_3r(unit, port, &rval);
   2894                 BCM_IF_ERROR_RETURN(rv);
   2895                 old_index = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r,
   2896                         rval, IPRI_MAPPING_PTRf);
   2897                 /* Clear mapping pointer */
   2898                 if (old_index == index) {
   2899                     soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval,
   2900                                       IPRI_MAPPING_PTRf, 0);
   2901                     soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval,
   2902                                       IPRI_CFI_SELf, 0);
   2903                     rv = WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval);
   2904                     BCM_IF_ERROR_RETURN(rv);
   2905                 }
   2906             }
   2907 		}
   2908     }
   2909 
   2910     return BCM_E_NONE;
   2911 }
   2912 
   2913 
   2914 /* Destroy a QoS map profile */
   2915 /* This will free the profile index and de-allocate the ID */
   2916 int 
   2917 bcm_tr2_qos_map_destroy(int unit, int map_id)
   2918 {
   2919     int id, rv = BCM_E_UNAVAIL;
   2920     QOS_INIT(unit);
   2921 
   2922 #if defined (BCM_TOMAHAWK3_SUPPORT)
   2923     if (SOC_IS_TOMAHAWK3(unit)) {
   2924         BCM_IF_ERROR_RETURN(_bcm_th3_qos_validate_map_type(unit, map_id));
   2925     }
   2926 #endif
   2927 
   2928     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   2929     QOS_LOCK(unit);
   2930     switch (map_id >> _BCM_QOS_MAP_SHIFT) {
   2931     case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
   2932 #ifdef BCM_HURRICANE3_SUPPORT
   2933     case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP:
   2934 #endif
   2935         if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   2936             QOS_UNLOCK(unit);
   2937             return BCM_E_PARAM;
   2938         }
   2939         if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   2940             QOS_UNLOCK(unit);
   2941             return BCM_E_NOT_FOUND;
   2942         } else {
   2943             rv = _bcm_ing_pri_cng_map_entry_delete
   2944                      (unit, QOS_INFO(unit)->pri_cng_hw_idx[id] * 
   2945                       _BCM_QOS_MAP_CHUNK_PRI_CNG);
   2946             QOS_INFO(unit)->pri_cng_hw_idx[id] = 0;
   2947             _BCM_QOS_ING_PRI_CNG_USED_CLR(unit, id);
   2948         }
   2949         break;
   2950     case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS:
   2951 #ifdef BCM_HURRICANE3_SUPPORT
   2952     case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS:
   2953 #endif
   2954         if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   2955             QOS_UNLOCK(unit);
   2956             return BCM_E_NOT_FOUND;
   2957         } else {
   2958             if ( SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   2959                  (SOC_IS_TD_TT(unit) && !SOC_IS_TOMAHAWK3(unit))) {
   2960                 /* Clear existing map from port EGR_VLAN_CONTROL_3 register */
   2961                 rv = _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_clear(unit,
   2962                                           QOS_INFO(unit)->egr_mpls_hw_idx[id]);
   2963                 if (BCM_FAILURE(rv)) {
   2964                 LOG_ERROR(BSL_LS_BCM_QOS,
   2965                           (BSL_META_U(unit,
   2966                                       "Clear qos mapid (%d) from "
   2967                            " EGR_VLAN_CONTROL_3 register failed\n"),
   2968                            QOS_INFO(unit)->egr_mpls_hw_idx[id]));
   2969                 }
   2970             }
   2971             rv = _bcm_egr_mpls_combo_map_entry_delete (unit, 
   2972                                        (QOS_INFO(unit)->egr_mpls_hw_idx[id] *
   2973                                         _BCM_QOS_MAP_CHUNK_EGR_MPLS));
   2974             QOS_INFO(unit)->egr_mpls_hw_idx[id] = 0;
   2975             _BCM_QOS_EGR_MPLS_USED_CLR(unit, id);
   2976             _BCM_QOS_EGR_MPLS_FLAGS_USED_CLR(unit, id);
   2977         }
   2978         break;
   2979 #ifdef BCM_APACHE_SUPPORT
   2980     case _BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP:
   2981         if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) {
   2982 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   2983             rv = bcm_tr_mpls_exp_to_phb_cng_map_destroy(unit, map_id);
   2984 #endif
   2985         } else {
   2986             QOS_UNLOCK(unit);
   2987             return BCM_E_PARAM;
   2988         }
   2989         break;
   2990 #endif
   2991     case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
   2992         if (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) {
   2993             QOS_UNLOCK(unit);
   2994             return BCM_E_NOT_FOUND;
   2995         } else {
   2996             rv = _bcm_dscp_table_entry_delete
   2997                      (unit, (QOS_INFO(unit)->dscp_hw_idx[id] * 
   2998                       _BCM_QOS_MAP_CHUNK_DSCP));
   2999             QOS_INFO(unit)->dscp_hw_idx[id] = 0;
   3000             _BCM_QOS_DSCP_TABLE_USED_CLR(unit, id);
   3001         }
   3002         break;
   3003     case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE:
   3004 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   3005         if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   3006             rv = _bcm_td2p_egr_qos_combo_map_destroy(unit, map_id); 
   3007             if (BCM_FAILURE(rv)) {
   3008                 QOS_UNLOCK(unit);
   3009                 return (rv);
   3010             }
   3011         } else 
   3012 #endif
   3013         {
   3014             if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) {
   3015                 QOS_UNLOCK(unit);
   3016                 return BCM_E_NOT_FOUND;
   3017             } else {
   3018                 rv = _bcm_egr_dscp_table_entry_delete
   3019                         (unit, (QOS_INFO(unit)->egr_dscp_hw_idx[id] * 
   3020                          _BCM_QOS_MAP_CHUNK_EGR_DSCP));
   3021                 if (BCM_E_NONE == rv) {
   3022                     QOS_INFO(unit)->egr_dscp_hw_idx[id] = 0;
   3023                     _BCM_QOS_EGR_DSCP_TABLE_USED_CLR(unit, id);
   3024                 }
   3025             }
   3026         }
   3027         break;
   3028 #ifdef BCM_KATANA_SUPPORT
   3029     case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE:
   3030         if (!_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id)) {
   3031             QOS_UNLOCK(unit);
   3032             return BCM_E_NOT_FOUND;
   3033         } else {
   3034             rv = _bcm_offset_map_table_entry_delete
   3035                      (unit, (QOS_INFO(unit)->offset_map_hw_idx[id] *
   3036                       _BCM_QOS_MAP_CHUNK_OFFSET_MAP));
   3037             QOS_INFO(unit)->offset_map_hw_idx[id] = 0;
   3038             _BCM_QOS_OFFSET_MAP_TABLE_USED_CLR(unit, id);
   3039         }
   3040         break;
   3041 #endif
   3042 
   3043 #ifdef BCM_SABER2_SUPPORT
   3044     case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE:
   3045         if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   3046             if (!_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) {
   3047                 QOS_UNLOCK(unit);
   3048                 return BCM_E_NOT_FOUND;
   3049             } else {
   3050                 rv = _bcm_service_pri_map_table_entry_delete
   3051                     (unit, (QOS_INFO(unit)->service_pri_map_hw_idx[id] *
   3052                             _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP));
   3053                 QOS_INFO(unit)->service_pri_map_hw_idx[id] = 0;
   3054                 _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_CLR(unit, id);
   3055                 _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_CLR(unit, id);
   3056             }
   3057         } else {
   3058             QOS_UNLOCK(unit);
   3059             return BCM_E_PARAM;            
   3060         }
   3061         break;
   3062 #endif
   3063 #ifdef BCM_KATANA2_SUPPORT
   3064     case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP:
   3065         if (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) {
   3066             QOS_UNLOCK(unit);
   3067             return BCM_E_NOT_FOUND;
   3068         } else {
   3069             rv = _bcm_rqe_queue_offset_map_table_sw_delete(unit,
   3070                  id);
   3071             QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] = 0;
   3072             _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_CLR(unit, id);
   3073         }
   3074         break;
   3075 #endif
   3076 
   3077     default:
   3078 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   3079         if (map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) {
   3080             if (!soc_feature(unit, soc_feature_mpls)) {
   3081                 QOS_UNLOCK(unit);
   3082                 return rv;
   3083             }
   3084             rv = bcm_tr_mpls_exp_map_destroy(unit, map_id);
   3085             if (BCM_SUCCESS(rv)) {
   3086                 _BCM_QOS_ING_MPLS_EXP_USED_CLR(unit,
   3087                     (map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_NUM_MASK));
   3088             }
   3089         } else
   3090 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */
   3091         {
   3092             rv = BCM_E_PARAM;
   3093         }
   3094         break;
   3095     }
   3096 #ifdef BCM_WARM_BOOT_SUPPORT
   3097     SOC_CONTROL_LOCK(unit);
   3098     SOC_CONTROL(unit)->scache_dirty = 1;
   3099     SOC_CONTROL_UNLOCK(unit);
   3100 #endif
   3101     QOS_UNLOCK(unit);
   3102     return rv;
   3103 }
   3104 
   3105 #ifdef BCM_SABER2_SUPPORT
   3106 STATIC int
   3107 _bcm_sb2_qos_oam_pri_map_mpls_exp_check(bcm_qos_map_t *map)
   3108 {
   3109     if ((map->exp > _BCM_SB2_MPLS_EXP_MAX) ||
   3110        (map->exp < _BCM_SB2_MPLS_EXP_MIN)) {
   3111         return BCM_E_PARAM;
   3112     }
   3113     return BCM_E_NONE;
   3114 }
   3115 
   3116 STATIC int
   3117 _bcm_sb2_qos_oam_pri_map_pkt_pri_check(bcm_qos_map_t *map)
   3118 {
   3119     if (map->pkt_pri > _BCM_SB2_PKT_PRI_MAX) {
   3120         return BCM_E_PARAM;
   3121     }
   3122     return BCM_E_NONE;
   3123 }
   3124 
   3125 STATIC int
   3126 _bcm_sb2_qos_oam_pri_map_int_pri_check(bcm_qos_map_t *map)
   3127 {
   3128     if ((map->int_pri > _BCM_SB2_INT_PRI_MAX) ||
   3129        (map->int_pri < _BCM_SB2_INT_PRI_MIN)) {
   3130         return BCM_E_PARAM;
   3131     }
   3132     return BCM_E_NONE;
   3133 }
   3134 
   3135 STATIC int
   3136 _bcm_sb2_qos_oam_pri_map_counter_offset_check(bcm_qos_map_t *map)
   3137 {
   3138     if (map->counter_offset > _BCM_SB2_OAM_PRI_MAP_COUNTER_OFFSET_MAX ||
   3139        map->counter_offset < _BCM_SB2_OAM_PRI_MAP_COUNTER_OFFSET_MIN) {
   3140         return BCM_E_PARAM;
   3141     }
   3142     return BCM_E_NONE;
   3143 }
   3144 
   3145 STATIC int
   3146 _bcm_sb2_qos_oam_pri_map_params_check(uint32 flags, bcm_qos_map_t *map)
   3147 {
   3148     BCM_IF_ERROR_RETURN(_bcm_sb2_qos_oam_pri_map_counter_offset_check(map)); 
   3149 
   3150     if (flags & BCM_QOS_MAP_OAM_INTPRI) {
   3151         BCM_IF_ERROR_RETURN(_bcm_sb2_qos_oam_pri_map_int_pri_check(map));
   3152     } else if ((flags & BCM_QOS_MAP_OAM_OUTER_VLAN_PCP) || 
   3153                (flags & BCM_QOS_MAP_OAM_INNER_VLAN_PCP)) {
   3154         BCM_IF_ERROR_RETURN(_bcm_sb2_qos_oam_pri_map_pkt_pri_check(map));
   3155     } else if (flags & BCM_QOS_MAP_OAM_MPLS_EXP) {
   3156         BCM_IF_ERROR_RETURN(_bcm_sb2_qos_oam_pri_map_mpls_exp_check(map));
   3157     } else {
   3158         return BCM_E_PARAM;
   3159     }
   3160 
   3161     return BCM_E_NONE;
   3162 }
   3163 
   3164 STATIC int
   3165 _bcm_sb2_service_pri_map_flags_pri_get(bcm_qos_map_t *map, uint32 flags, int *pri)
   3166 {
   3167     if (flags & BCM_QOS_MAP_OAM_INTPRI) {
   3168             *pri = map->int_pri;
   3169     } else if ((flags & BCM_QOS_MAP_OAM_OUTER_VLAN_PCP) || 
   3170                (flags & BCM_QOS_MAP_OAM_INNER_VLAN_PCP)) {
   3171             *pri = map->pkt_pri;
   3172     } else if (flags & BCM_QOS_MAP_OAM_MPLS_EXP) {
   3173             *pri = map->exp;
   3174     } else {
   3175         return BCM_E_PARAM;
   3176     }
   3177 
   3178     return BCM_E_NONE;
   3179 }
   3180 
   3181 int
   3182 _bcm_sb2_service_pri_map_flags_pri_set(uint32 flags, int pri, bcm_qos_map_t *map)
   3183 {
   3184     if (flags & BCM_QOS_MAP_OAM_INTPRI) {
   3185             map->int_pri = pri;
   3186     } else if ((flags & BCM_QOS_MAP_OAM_OUTER_VLAN_PCP) || 
   3187                (flags & BCM_QOS_MAP_OAM_INNER_VLAN_PCP)) {
   3188             map->pkt_pri = pri;
   3189     } else if (flags & BCM_QOS_MAP_OAM_MPLS_EXP) {
   3190             map->exp = pri;
   3191     } else {
   3192         return BCM_E_PARAM;
   3193     }
   3194 
   3195     return BCM_E_NONE;
   3196 }
   3197 int
   3198 _bcm_sb2_service_pri_map_flags_max_pri_get(uint32 flags, int *max_pri)
   3199 {
   3200     if (flags & BCM_QOS_MAP_OAM_INTPRI) {
   3201            *max_pri = _BCM_SB2_INT_PRI_MAX; 
   3202     } else if ((flags & BCM_QOS_MAP_OAM_OUTER_VLAN_PCP) || 
   3203                (flags & BCM_QOS_MAP_OAM_INNER_VLAN_PCP)) {
   3204             *max_pri = _BCM_SB2_PKT_PRI_MAX;
   3205     } else if (flags & BCM_QOS_MAP_OAM_MPLS_EXP) {
   3206             *max_pri = _BCM_SB2_MPLS_EXP_MAX; 
   3207     } else {
   3208         return BCM_E_PARAM;
   3209     }
   3210 
   3211     return BCM_E_NONE;
   3212 }
   3213 
   3214 #endif
   3215 #ifdef BCM_SABER2_SUPPORT
   3216 STATIC int
   3217 bcm_tr2_qos_port_map_set_internal(int unit, bcm_port_t port,
   3218                                   soc_field_t field, int hw_index)
   3219 {
   3220    int rv;
   3221 
   3222    soc_mem_lock(unit, PORT_TABm);
   3223    rv = _bcm_tr2_port_tab_set(unit, port, field,
   3224                               hw_index/_BCM_QOS_MAP_CHUNK_PRI_CNG);
   3225    soc_mem_unlock(unit, PORT_TABm);
   3226    return rv;
   3227 }
   3228 STATIC int
   3229 bcm_tr2_qos_copy_ing_pri_cng_entry(int unit,
   3230                                    int src_index,
   3231                                    int dest_index,
   3232                                    int num_entry)
   3233 {
   3234    uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS];
   3235    int idx;
   3236 
   3237    for (idx = 0; idx < num_entry; idx++) {
   3238         SOC_IF_ERROR_RETURN(
   3239             READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ALL,
   3240                                   src_index + idx, &pri_map));
   3241         SOC_IF_ERROR_RETURN(
   3242             WRITE_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ALL,
   3243                                    dest_index + idx, &pri_map));
   3244    }
   3245    return SOC_E_NONE;
   3246 }
   3247 #endif
   3248 /* Add an entry to a QoS map */
   3249 /* Read the existing profile chunk, modify what's needed and add the 
   3250  * new profile. This can result in the HW profile index changing for a 
   3251  * given ID */
   3252 int 
   3253 bcm_tr2_qos_map_add(int unit, uint32 flags, bcm_qos_map_t *map, int map_id, int internal)
   3254 {
   3255     int alloc_size, offset, cng, id, index, rv = BCM_E_NONE, int_pri_max = 15;
   3256     ing_pri_cng_map_entry_t ing_pri_map[16];
   3257     phb_mapping_tbl_1_entry_t new_ing_pri_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX];
   3258     ing_untagged_phb_entry_t ing_untagged_phb;
   3259     egr_mpls_pri_mapping_entry_t *egr_mpls_pri_map;
   3260     egr_mpls_exp_mapping_1_entry_t *egr_mpls_exp_map;
   3261     egr_mpls_exp_mapping_2_entry_t *egr_mpls_exp_map2;
   3262     dscp_table_entry_t *dscp_table;
   3263     egr_dscp_table_entry_t *egr_dscp_table;
   3264     void *entries[3], *entry;
   3265 #ifdef BCM_KATANA_SUPPORT
   3266     ing_queue_offset_mapping_table_entry_t *offset_map_table;
   3267 #endif
   3268 #ifdef BCM_KATANA2_SUPPORT
   3269     int hw_idx = -1;
   3270     uint32 rqe_queue_offset_profile[_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP];
   3271     soc_field_t profile_field[] = {Q_OFFSET0f,
   3272                                    Q_OFFSET1f,
   3273                                    Q_OFFSET2f,
   3274                                    Q_OFFSET3f};
   3275     int i;
   3276     int profile_offset = 0;
   3277 #endif
   3278 
   3279 #ifdef BCM_SABER2_SUPPORT
   3280     ing_service_pri_map_0_entry_t *service_pri_map_table;
   3281     int pri = 0;
   3282     uint32 conf_flags = 0;
   3283     void *mem_entries[_BCM_SB2_OAM_PRI_MAP_TABLE_MAX];
   3284     int table = 0;
   3285     bcm_port_t port;
   3286 #endif
   3287     int untagged = FALSE;
   3288 
   3289     QOS_INIT(unit);
   3290 
   3291     /* Check incoming parameters */
   3292     if (NULL == map) {
   3293         return BCM_E_PARAM;
   3294     }
   3295 
   3296 #if defined (BCM_TOMAHAWK3_SUPPORT)
   3297     if (SOC_IS_TOMAHAWK3(unit)) {
   3298         BCM_IF_ERROR_RETURN(_bcm_th3_qos_validate_map_type(unit, map_id));
   3299     }
   3300 #endif
   3301 
   3302     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   3303     QOS_LOCK(unit);
   3304     switch (map_id >> _BCM_QOS_MAP_SHIFT) {
   3305     case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
   3306 #ifdef BCM_HURRICANE3_SUPPORT
   3307     case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP:
   3308 #endif
   3309         if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   3310            QOS_UNLOCK(unit);
   3311            return BCM_E_PARAM;
   3312         }
   3313         if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   3314             QOS_UNLOCK(unit);
   3315             return BCM_E_PARAM;
   3316         } else {
   3317 #ifdef BCM_HURRICANE3_SUPPORT
   3318             if (soc_feature(unit, soc_feature_miml)) {
   3319                 if (!((flags & BCM_QOS_MAP_L2) || (flags & BCM_QOS_MAP_MIML)) || 
   3320                     !(flags & BCM_QOS_MAP_INGRESS)) {
   3321                     QOS_UNLOCK(unit);
   3322                     return BCM_E_PARAM;
   3323                 } 
   3324             } else
   3325 #endif
   3326             {
   3327                 if (!(flags & BCM_QOS_MAP_L2) || !(flags & BCM_QOS_MAP_INGRESS)) {
   3328                     QOS_UNLOCK(unit);
   3329                     return BCM_E_PARAM;
   3330                 } 
   3331             }
   3332 
   3333             if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_IS_VALID(unit, ING_UNTAGGED_PHBm))) {
   3334                 if (flags & BCM_QOS_MAP_L2_UNTAGGED) {
   3335                     untagged = TRUE;
   3336                     map->pkt_pri = 0;
   3337                     map->pkt_cfi = 0;
   3338                 }
   3339             }
   3340 
   3341             if (SOC_IS_TRIUMPH2(unit) || SOC_IS_ENDURO(unit)||
   3342                 SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit) ||
   3343                 SOC_IS_GREYHOUND2(unit)) {  
   3344                 int_pri_max = 7;
   3345             }   
   3346 
   3347             if ((map->int_pri > int_pri_max) || (map->int_pri < 0) || 
   3348                 (map->pkt_pri > 7) || (map->pkt_cfi > 1) || 
   3349                 ((map->color != bcmColorGreen) && 
   3350                 (map->color != bcmColorYellow) && 
   3351                 (map->color != bcmColorRed))) {
   3352                 QOS_UNLOCK(unit);
   3353                 return BCM_E_PARAM;
   3354             }
   3355             if (SOC_IS_TRIDENT3X(unit)) {
   3356                 entries[0] = new_ing_pri_map;
   3357             } else {
   3358                 entries[0] = ing_pri_map;
   3359             }
   3360             entries[1] = &ing_untagged_phb;
   3361 
   3362             /* Base index of table in hardware */
   3363             index = QOS_INFO(unit)->pri_cng_hw_idx[id] * 
   3364                     _BCM_QOS_MAP_CHUNK_PRI_CNG;
   3365 
   3366             rv = _bcm_ing_pri_cng_map_entry_get(unit, index, 
   3367                                                 _BCM_QOS_MAP_CHUNK_PRI_CNG, 
   3368                                                 entries);
   3369             if (BCM_FAILURE(rv)) {
   3370                 QOS_UNLOCK(unit);
   3371                 return (rv);
   3372             }
   3373 
   3374             if (untagged) {
   3375                 if (SOC_IS_TRIDENT3X(unit)) {
   3376                     /* TD3 tagged and untagged shared the same table
   3377                        bit 5 is indicating untaged packet or not */
   3378                     /* Offset within table */
   3379                     offset = 1 << 4 |(map->pkt_pri << 1) | map->pkt_cfi;
   3380 
   3381                     /* Modify what's needed */
   3382                     entry = &new_ing_pri_map[offset];
   3383                     soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry,
   3384                                         INT_PRIf, map->int_pri);
   3385                     soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry,
   3386                                         CNGf, _BCM_COLOR_ENCODING(unit, map->color));
   3387                 } else {
   3388                     soc_mem_field32_set(unit, ING_UNTAGGED_PHBm,
   3389                                         &ing_untagged_phb, PRIf, map->int_pri);
   3390                     soc_mem_field32_set(unit, ING_UNTAGGED_PHBm,
   3391                                         &ing_untagged_phb, CNGf,
   3392                                         _BCM_COLOR_ENCODING(unit, map->color));
   3393                 }
   3394             } else {
   3395                 /* Offset within table */
   3396                 offset = (map->pkt_pri << 1) | map->pkt_cfi;
   3397                 /* Modify what's needed */
   3398                 if (SOC_IS_TRIDENT3X(unit)) {
   3399                     entry = &new_ing_pri_map[offset];
   3400                     soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry,
   3401                                         INT_PRIf, map->int_pri);
   3402                     soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry,
   3403                                         CNGf, _BCM_COLOR_ENCODING(unit, map->color));
   3404                 } else {
   3405                     entry = &ing_pri_map[offset];
   3406                     soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, entry,
   3407                                         PRIf, map->int_pri);
   3408                     soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, entry,
   3409                                         CNGf, _BCM_COLOR_ENCODING(unit, map->color));
   3410                }
   3411            }
   3412 #ifdef BCM_SABER2_SUPPORT
   3413            for (port = SB2_CMIC + 1; port < SB2_LPBK; port++) {
   3414                 if (_BCM_QOS_TRUST_DOT1P_PTR_CACHE_GET(unit, port,
   3415                     index/_BCM_QOS_MAP_CHUNK_PRI_CNG)) {
   3416                     break;
   3417                  }
   3418            }
   3419            if (SOC_IS_SABER2(unit) && (!internal) && (port != SB2_LPBK)) {
   3420                rv = bcm_tr2_qos_copy_ing_pri_cng_entry(unit, index,
   3421                     QOS_INFO(unit)->pri_cng_hw_idx_reserved,
   3422                     _BCM_QOS_MAP_CHUNK_PRI_CNG);
   3423                if (BCM_FAILURE(rv)) {
   3424                    QOS_UNLOCK(unit);
   3425                    return (rv);
   3426                }
   3427                for (port = SB2_CMIC + 1; port < SB2_LPBK; port++) {
   3428                     if (_BCM_QOS_TRUST_DOT1P_PTR_CACHE_GET(unit, port,
   3429                         index/_BCM_QOS_MAP_CHUNK_PRI_CNG)) {
   3430                         rv = bcm_tr2_qos_port_map_set_internal(unit, port,
   3431                              TRUST_DOT1P_PTRf,
   3432                              QOS_INFO(unit)->pri_cng_hw_idx_reserved);
   3433                         if (BCM_FAILURE(rv)) {
   3434                             QOS_UNLOCK(unit);
   3435                             return (rv);
   3436                         }
   3437                     }
   3438                }
   3439            }
   3440 #endif
   3441            /* Delete the old profile chunk */
   3442            rv = _bcm_ing_pri_cng_map_entry_delete(unit, index);
   3443            if (BCM_FAILURE(rv)) {
   3444                QOS_UNLOCK(unit);
   3445                return (rv);
   3446            }
   3447 
   3448            /* Add new chunk and store new HW index */
   3449            rv = _bcm_ing_pri_cng_map_entry_add(unit, entries,
   3450                                               _BCM_QOS_MAP_CHUNK_PRI_CNG,
   3451                                               (uint32 *)&index);
   3452            QOS_INFO(unit)->pri_cng_hw_idx[id] = (index /
   3453                                                  _BCM_QOS_MAP_CHUNK_PRI_CNG);
   3454 #ifdef BCM_SABER2_SUPPORT
   3455            if (SOC_IS_SABER2(unit) && (!internal)) {
   3456                for (port = SB2_CMIC; port < SB2_LPBK; port++) {
   3457                     if (_BCM_QOS_TRUST_DOT1P_PTR_CACHE_GET(unit, port,
   3458                         index/_BCM_QOS_MAP_CHUNK_PRI_CNG)) {
   3459                         rv = bcm_tr2_qos_port_map_set_internal(unit, port,
   3460                              TRUST_DOT1P_PTRf, index);
   3461                         if (BCM_FAILURE(rv)) {
   3462                             QOS_UNLOCK(unit);
   3463                             return (rv);
   3464                         }
   3465                     }
   3466                }
   3467            }
   3468 #endif
   3469         }
   3470         break;
   3471 #ifdef BCM_APACHE_SUPPORT
   3472     case _BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP:
   3473         if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) {
   3474 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   3475             bcm_mpls_exp_map_t ing_exp_map;
   3476             bcm_mpls_exp_map_t_init(&ing_exp_map);
   3477             if (flags & BCM_QOS_MAP_OAM_MPLS_EXP){
   3478                 if((!(flags & BCM_QOS_MAP_INGRESS)) && 
   3479                    (!(flags & BCM_QOS_MAP_EGRESS))){
   3480                     QOS_UNLOCK(unit);
   3481                     return BCM_E_PARAM;
   3482                 }
   3483             } else {
   3484                 QOS_UNLOCK(unit);
   3485                 return BCM_E_PARAM;
   3486             }
   3487             if ((map->int_pri > 15) || (map->int_pri < 0) ||
   3488                     (map->exp > 7) || (map->exp < 0) ||
   3489                     ((map->color != bcmColorGreen) &&
   3490                      (map->color != bcmColorYellow) &&
   3491                      (map->color != bcmColorRed))) {
   3492                 QOS_UNLOCK(unit);
   3493                 return BCM_E_PARAM;
   3494             }
   3495             /* Call the triumph/mpls.c implementation */
   3496             ing_exp_map.exp = map->exp;
   3497             ing_exp_map.priority = map->int_pri;
   3498             ing_exp_map.color = map->color;
   3499             rv = bcm_tr_mpls_exp_to_phb_cng_map_set(unit, map_id, &ing_exp_map);
   3500 #endif
   3501         } else {
   3502             QOS_UNLOCK(unit);
   3503             return BCM_E_PARAM;
   3504         }
   3505         break;
   3506 #endif
   3507     case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS:
   3508 #ifdef BCM_HURRICANE3_SUPPORT
   3509     case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS:
   3510 #endif
   3511         if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   3512             QOS_UNLOCK(unit);
   3513             return BCM_E_PARAM;
   3514         } else if (SOC_IS_TRIDENT3X(unit)) {
   3515 #ifdef BCM_TRIDENT3_SUPPORT
   3516             /* TRIDENT3 QoS memory map and binding takes Flex Path */
   3517             rv = bcm_td3_l2_egr_combo_add(unit, flags, map, map_id, 
   3518                                           &QOS_INFO(unit)->egr_mpls_hw_idx[id],
   3519                                           _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   3520             if (BCM_FAILURE(rv)) {
   3521                QOS_UNLOCK(unit);
   3522                return rv;
   3523             }
   3524 #endif /* End of BCM_TRIDENT3_SUPPORT */
   3525         } else {
   3526             /*  BCM_QOS_MAP_L2 is pseudonym of BCM_QOS_MAP_L2_OUTER_TAG.*/
   3527 #ifdef BCM_HURRICANE3_SUPPORT
   3528             if (soc_feature(unit, soc_feature_miml)) {
   3529                 if (!((flags & BCM_QOS_MAP_L2) ||
   3530                       (flags & BCM_QOS_MAP_L2_INNER_TAG)||
   3531                       (flags & BCM_QOS_MAP_MPLS) ||
   3532                       (flags & BCM_QOS_MAP_MIML))||
   3533                     !(flags & BCM_QOS_MAP_EGRESS)) {
   3534                     QOS_UNLOCK(unit);
   3535                     return BCM_E_PARAM;
   3536                 }
   3537             } else
   3538 #endif
   3539             {
   3540                 if (!((flags & BCM_QOS_MAP_L2) ||
   3541                       (flags & BCM_QOS_MAP_L2_INNER_TAG)||
   3542                       (flags & BCM_QOS_MAP_MPLS))||
   3543                     !(flags & BCM_QOS_MAP_EGRESS)) {
   3544                     QOS_UNLOCK(unit);
   3545                     return BCM_E_PARAM;
   3546                 }
   3547 
   3548 #if defined (BCM_TOMAHAWK3_SUPPORT)
   3549                 /* No double/inner tag support in TH3 */
   3550                 if (SOC_IS_TOMAHAWK3(unit) &&
   3551                     (flags & BCM_QOS_MAP_L2_INNER_TAG)) {
   3552                     QOS_UNLOCK(unit);
   3553                     return BCM_E_PARAM;
   3554                 }
   3555 #endif
   3556             }
   3557             if ((map->int_pri > 15) || (map->int_pri < 0) || 
   3558                 (map->pkt_pri > 7) || (map->pkt_cfi > 1) || 
   3559                 ((map->color != bcmColorGreen) && 
   3560                 (map->color != bcmColorYellow) && 
   3561                 (map->color != bcmColorRed))) {
   3562                 QOS_UNLOCK(unit);
   3563                 return BCM_E_PARAM;
   3564             }
   3565             if (flags & BCM_QOS_MAP_MPLS) {
   3566                 if ((map->exp > 7) || (map->exp < 0)) {
   3567                     QOS_UNLOCK(unit);
   3568                     return BCM_E_PARAM;
   3569                 }
   3570             }
   3571 
   3572             /* Allocate memory for DMA */
   3573             alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_MPLS * 
   3574                          sizeof(egr_mpls_pri_mapping_entry_t));
   3575             egr_mpls_pri_map = soc_cm_salloc(unit, alloc_size,
   3576                                              "TR2 egr mpls pri map");
   3577             if (NULL == egr_mpls_pri_map) {
   3578                 QOS_UNLOCK(unit);
   3579                 return (BCM_E_MEMORY);
   3580             }
   3581             sal_memset(egr_mpls_pri_map, 0, alloc_size);
   3582 
   3583             alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_MPLS * 
   3584                           sizeof(egr_mpls_exp_mapping_1_entry_t));
   3585             egr_mpls_exp_map = soc_cm_salloc(unit, alloc_size,
   3586                                              "TR2 egr mpls exp map");
   3587             if (NULL == egr_mpls_exp_map) {
   3588                 sal_free(egr_mpls_pri_map);
   3589                 QOS_UNLOCK(unit);
   3590                 return (BCM_E_MEMORY);
   3591             }
   3592             sal_memset(egr_mpls_exp_map, 0, alloc_size);
   3593 
   3594             alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_MPLS * 
   3595                           sizeof(egr_mpls_exp_mapping_2_entry_t));
   3596             egr_mpls_exp_map2= soc_cm_salloc(unit, alloc_size,
   3597                                              "TR2 egr mpls exp map2");
   3598             if (NULL == egr_mpls_exp_map2) {
   3599                 sal_free(egr_mpls_pri_map);
   3600                 sal_free(egr_mpls_exp_map);
   3601                 QOS_UNLOCK(unit);
   3602                 return (BCM_E_MEMORY);
   3603             }
   3604             sal_memset(egr_mpls_exp_map2, 0, alloc_size);
   3605 
   3606             /* Base index of table in hardware */
   3607             index = (QOS_INFO(unit)->egr_mpls_hw_idx[id] * 
   3608                      _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   3609 
   3610             /* Offset within table */
   3611             cng = _BCM_COLOR_ENCODING(unit, map->color);
   3612             offset = (map->int_pri << 2) | cng;
   3613 
   3614             /* Read the old profile chunk */
   3615             rv = soc_mem_read_range(unit, EGR_MPLS_PRI_MAPPINGm, MEM_BLOCK_ANY, 
   3616                                     index, 
   3617                                     (index + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)),
   3618                                     egr_mpls_pri_map);
   3619             if (BCM_FAILURE(rv)) {
   3620                 goto cleanup;
   3621             }
   3622             if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) {
   3623                 rv = soc_mem_read_range(unit, EGR_MPLS_EXP_MAPPING_1m, MEM_BLOCK_ANY, 
   3624                                         index, 
   3625                                         (index + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)),
   3626                                         egr_mpls_exp_map);
   3627                 if (BCM_FAILURE(rv)) {
   3628                     goto cleanup;
   3629                 }
   3630             }
   3631 
   3632             if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m)) {
   3633                 rv = soc_mem_read_range(unit, EGR_MPLS_EXP_MAPPING_2m, MEM_BLOCK_ANY, 
   3634                                         index, 
   3635                                         (index + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)),
   3636                                         egr_mpls_exp_map2);
   3637                 if (BCM_FAILURE(rv)) {
   3638                     goto cleanup;
   3639                 }
   3640             }
   3641 
   3642             /* Modify what's needed */
   3643             entry = &egr_mpls_pri_map[offset];
   3644             soc_mem_field32_set(unit, EGR_MPLS_PRI_MAPPINGm, entry, 
   3645                                 NEW_PRIf, map->pkt_pri);
   3646             soc_mem_field32_set(unit, EGR_MPLS_PRI_MAPPINGm, entry,
   3647                                 NEW_CFIf, map->pkt_cfi);
   3648             if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) {
   3649                 entry = &egr_mpls_exp_map[offset];
   3650 
   3651                 /* Modify for OUTER VLAN remarking */
   3652                 if (!SOC_IS_TRIDENT3X(unit)) {
   3653                     if (flags & BCM_QOS_MAP_L2_OUTER_TAG ) {
   3654                         soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_1m, entry,
   3655                                         PRIf, map->pkt_pri);
   3656                         soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_1m, entry,
   3657                                         CFIf, map->pkt_cfi);
   3658                     }
   3659                 } 
   3660                 if (flags & BCM_QOS_MAP_MPLS) {
   3661                     soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_1m, entry, 
   3662                                         MPLS_EXPf, map->exp);
   3663                 }
   3664             }
   3665             if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m)) {
   3666                 entry = &egr_mpls_exp_map2[offset];
   3667 
   3668                 /* Modify for INNER VLAN remarking */
   3669                 if (!SOC_IS_TRIDENT3X(unit)) {
   3670                     if (flags & BCM_QOS_MAP_L2_INNER_TAG ) {
   3671                         soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_2m, entry,
   3672                                             PRIf, map->pkt_pri);
   3673                         soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_2m, entry,
   3674                                             CFIf, map->pkt_cfi);
   3675                     }
   3676                 }
   3677                 if (flags & BCM_QOS_MAP_MPLS) {
   3678                     soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_2m, entry, 
   3679                                         MPLS_EXPf, map->exp);
   3680                 }
   3681             }
   3682 
   3683             /* Delete the old profile chunk */
   3684             rv = _bcm_egr_mpls_combo_map_entry_delete(unit, index);
   3685             if (BCM_FAILURE(rv)) {
   3686                 goto cleanup;
   3687             }
   3688 
   3689             /* Add new chunk and store new HW index */
   3690             entries[0] = egr_mpls_pri_map;
   3691             entries[1] = egr_mpls_exp_map;
   3692             entries[2] = egr_mpls_exp_map2;
   3693             rv = _bcm_egr_mpls_combo_map_entry_add(unit, entries,
   3694                                                    _BCM_QOS_MAP_CHUNK_EGR_MPLS, 
   3695                                                    (uint32 *)&index);
   3696             QOS_INFO(unit)->egr_mpls_hw_idx[id] = (index / 
   3697                                                   _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   3698 
   3699             cleanup:
   3700                 /* Free the DMA memory */
   3701                 soc_cm_sfree(unit, egr_mpls_pri_map);
   3702                 soc_cm_sfree(unit, egr_mpls_exp_map);
   3703                 soc_cm_sfree(unit, egr_mpls_exp_map2);
   3704         }
   3705         break;
   3706     case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
   3707         if (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) {
   3708             QOS_UNLOCK(unit);
   3709             return BCM_E_PARAM;
   3710         } else {
   3711             if (!(flags & BCM_QOS_MAP_L3) || !(flags & BCM_QOS_MAP_INGRESS)) {
   3712                 QOS_UNLOCK(unit);
   3713                 return BCM_E_PARAM;
   3714             }
   3715             if ((map->int_pri > 15) || (map->int_pri < 0) ||
   3716                 (map->dscp > DSCP_CODE_POINT_MAX) || (map->dscp < 0) ||
   3717                 ((map->color != bcmColorGreen) && 
   3718                  (map->color != bcmColorYellow) && 
   3719                  (map->color != bcmColorRed))) {
   3720                 QOS_UNLOCK(unit);
   3721                 return BCM_E_PARAM;
   3722             }
   3723 
   3724             /* Allocate memory for DMA */
   3725             if (SOC_IS_TRIDENT3X(unit)) {
   3726                 alloc_size = _BCM_QOS_MAP_CHUNK_DSCP * sizeof(phb_mapping_tbl_2_entry_t);
   3727             } else {
   3728                 alloc_size = _BCM_QOS_MAP_CHUNK_DSCP * sizeof(dscp_table_entry_t);
   3729             }
   3730 
   3731             dscp_table = soc_cm_salloc(unit, alloc_size,
   3732                                        "TR2 dscp table");
   3733             if (NULL == dscp_table) {
   3734                 QOS_UNLOCK(unit);
   3735                 return (BCM_E_MEMORY);
   3736             }
   3737             sal_memset(dscp_table, 0, alloc_size);
   3738 
   3739             /* Base index of table in hardware */
   3740             index = QOS_INFO(unit)->dscp_hw_idx[id] * _BCM_QOS_MAP_CHUNK_DSCP;
   3741 
   3742             /* Offset within table */
   3743             offset = map->dscp;
   3744 
   3745             /* Read the old profile chunk */
   3746             rv = soc_mem_read_range(unit, _bcm_tr2_qos_bk_info[unit].dscp_table, 
   3747                                     MEM_BLOCK_ANY, 
   3748                                     index, index + (_BCM_QOS_MAP_CHUNK_DSCP-1),
   3749                                     dscp_table);
   3750             if (BCM_FAILURE(rv)) {
   3751                 soc_cm_sfree(unit, dscp_table);
   3752                 QOS_UNLOCK(unit);
   3753                 return (rv);
   3754             }
   3755 
   3756             /* Modify what's needed */
   3757             entry = &dscp_table[offset];
   3758             cng = _BCM_COLOR_ENCODING(unit, map->color);
   3759 
   3760             if (SOC_IS_TRIDENT3X(unit)) {
   3761                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCPf, map->dscp);
   3762                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, INT_PRIf, map->int_pri);
   3763                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCP_VALIDf, 1);
   3764                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, CNGf, cng);
   3765             } else {
   3766                 soc_DSCP_TABLEm_field32_set(unit, entry, DSCPf, map->dscp);
   3767                 soc_DSCP_TABLEm_field32_set(unit, entry, PRIf, map->int_pri);
   3768                 soc_DSCP_TABLEm_field32_set(unit, entry, CNGf, cng);
   3769             }
   3770 
   3771             /* Delete the old profile chunk */
   3772             rv = _bcm_dscp_table_entry_delete(unit, index);
   3773             if (BCM_FAILURE(rv)) {
   3774                 soc_cm_sfree(unit, dscp_table);
   3775                 QOS_UNLOCK(unit);
   3776                 return (rv);
   3777             }
   3778 
   3779             /* Add new chunk and store new HW index */
   3780             entries[0] = dscp_table;
   3781             rv = _bcm_dscp_table_entry_add(unit, entries, _BCM_QOS_MAP_CHUNK_DSCP, 
   3782                                            (uint32 *)&index);
   3783             QOS_INFO(unit)->dscp_hw_idx[id] = index / _BCM_QOS_MAP_CHUNK_DSCP;
   3784 
   3785             /* Free the DMA memory */
   3786             soc_cm_sfree(unit, dscp_table);
   3787         }
   3788         break;
   3789     case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE:
   3790         if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) {
   3791             QOS_UNLOCK(unit);
   3792             return BCM_E_PARAM;
   3793         } else {
   3794             if (!(flags & BCM_QOS_MAP_L3) || !(flags & BCM_QOS_MAP_EGRESS)) {
   3795                 QOS_UNLOCK(unit);
   3796                 return BCM_E_PARAM;
   3797             }
   3798             if ((map->int_pri > 15) || (map->int_pri < 0) ||
   3799                 (map->dscp > DSCP_CODE_POINT_MAX) || (map->dscp < 0) ||
   3800                 ((map->color != bcmColorGreen) && 
   3801                  (map->color != bcmColorYellow) && 
   3802                  (map->color != bcmColorRed))) {
   3803                 QOS_UNLOCK(unit);
   3804                 return BCM_E_PARAM;
   3805             }
   3806 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   3807             if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   3808                 rv = _bcm_td2p_egr_qos_combo_map_add(unit, flags, map, map_id); 
   3809                 if (BCM_FAILURE(rv)) {
   3810                     QOS_UNLOCK(unit);
   3811                     return (rv);
   3812                 }
   3813 
   3814             } else
   3815 #endif
   3816             {
   3817                 /* Allocate memory for DMA */
   3818                 if (SOC_IS_TRIDENT3X(unit)) {
   3819                     alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_DSCP * 
   3820                                   sizeof(egr_zone_2_qos_mapping_table_entry_t));
   3821                 } else {
   3822                     alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_DSCP *
   3823                                   sizeof(egr_dscp_table_entry_t));
   3824                 }
   3825                 egr_dscp_table = soc_cm_salloc(unit, alloc_size,
   3826                                                "TR2 egr_dscp table");
   3827                 if (NULL == egr_dscp_table) {
   3828                     QOS_UNLOCK(unit);
   3829                     return (BCM_E_MEMORY);
   3830                 }
   3831                 sal_memset(egr_dscp_table, 0, alloc_size);
   3832 
   3833                 /* Base index of table in hardware */
   3834                 index = (QOS_INFO(unit)->egr_dscp_hw_idx[id] * 
   3835                          _BCM_QOS_MAP_CHUNK_EGR_DSCP);
   3836 
   3837                 /* Offset within table */
   3838                 cng = _BCM_COLOR_ENCODING(unit, map->color);
   3839                 offset = (map->int_pri << 2) | cng;
   3840 
   3841                 /* Read the old profile chunk */
   3842                 /* For now, TD3 keeps inner and outer DSCP table the same, so we
   3843                  * read only one table for read acces but two tables for write access
   3844                  */
   3845                 rv = soc_mem_read_range(unit, _bcm_tr2_qos_bk_info[unit].egr_dscp_table, 
   3846                                         MEM_BLOCK_ANY, 
   3847                                         index, 
   3848                                         index + (_BCM_QOS_MAP_CHUNK_EGR_DSCP -1), 
   3849                                         egr_dscp_table);
   3850                 if (BCM_FAILURE(rv)) {
   3851                     soc_cm_sfree(unit, egr_dscp_table);
   3852                     QOS_UNLOCK(unit);
   3853                     return (rv);
   3854                 }
   3855 
   3856                 /* Modify what's needed */
   3857                 entry = &egr_dscp_table[offset];
   3858                 if (SOC_IS_TRIDENT3X(unit)) {
   3859                     soc_EGR_ZONE_4_QOS_MAPPING_TABLEm_field32_set(unit, entry, QOSf, map->dscp);
   3860                 } else {
   3861                     soc_EGR_DSCP_TABLEm_field32_set(unit, entry, DSCPf, map->dscp);
   3862                 }
   3863 
   3864                 /* Delete the old profile chunk */
   3865                 rv = _bcm_egr_dscp_table_entry_delete(unit, index);
   3866                 if (BCM_FAILURE(rv)) {
   3867                     soc_cm_sfree(unit, egr_dscp_table);
   3868                     QOS_UNLOCK(unit);
   3869                     return (rv);
   3870                 }
   3871 
   3872                 /* Add new chunk and store new HW index */
   3873                 entries[0] = egr_dscp_table;
   3874                 if (SOC_IS_TRIDENT3X(unit)) {
   3875                     /* use same setting for both Zone2 and Zone4 */
   3876                     entries[1] = egr_dscp_table; /* for Zone2 */
   3877                 }
   3878                 rv = _bcm_egr_dscp_table_entry_add(unit, entries, 
   3879                                                    _BCM_QOS_MAP_CHUNK_EGR_DSCP, 
   3880                                                    (uint32 *)&index, 0);
   3881                 QOS_INFO(unit)->egr_dscp_hw_idx[id] = (index / 
   3882                                                       _BCM_QOS_MAP_CHUNK_EGR_DSCP);
   3883 
   3884                 /* Free the DMA memory */
   3885                 soc_cm_sfree(unit, egr_dscp_table);
   3886             }
   3887         }
   3888         break;
   3889 #ifdef BCM_KATANA_SUPPORT
   3890     case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE:
   3891         if (!_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id)) {
   3892             QOS_UNLOCK(unit);
   3893             return BCM_E_PARAM;
   3894         } else {
   3895             if ((map->int_pri > 15) || (map->int_pri < 0) ||
   3896                 (map->queue_offset < 0) || (map->queue_offset > 7)) { /* max no of queues =8 */
   3897                 QOS_UNLOCK(unit);
   3898                 return BCM_E_PARAM;
   3899             }
   3900             /* Allocate memory for DMA */
   3901             alloc_size = _BCM_QOS_MAP_CHUNK_OFFSET_MAP * 
   3902                                sizeof(ing_queue_offset_mapping_table_entry_t);
   3903             offset_map_table = soc_cm_salloc(unit, alloc_size,
   3904                                        "KT Offset map table");
   3905             if (NULL == offset_map_table) {
   3906                 QOS_UNLOCK(unit);
   3907                 return (BCM_E_MEMORY);
   3908             }
   3909             sal_memset(offset_map_table, 0, alloc_size);
   3910 
   3911             /* Base index of table in hardware */
   3912             index = QOS_INFO(unit)->offset_map_hw_idx[id] * 
   3913                                    _BCM_QOS_MAP_CHUNK_OFFSET_MAP;
   3914 
   3915             /* Offset within table */
   3916             offset = map->queue_offset;
   3917 
   3918             /* Read the old profile chunk */
   3919             rv = soc_mem_read_range(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm, 
   3920                                     MEM_BLOCK_ANY, index, 
   3921                                     index + (_BCM_QOS_MAP_CHUNK_OFFSET_MAP - 1),
   3922                                     offset_map_table);
   3923             if (BCM_FAILURE(rv)) {
   3924                 soc_cm_sfree(unit, offset_map_table);
   3925                 QOS_UNLOCK(unit);
   3926                 return (rv);
   3927             }
   3928 
   3929             /* Modify what's needed */
   3930             entry = &offset_map_table[map->int_pri];
   3931             soc_ING_QUEUE_OFFSET_MAPPING_TABLEm_field32_set(unit, entry, 
   3932                                            QUEUE_OFFSETf, map->queue_offset);
   3933 
   3934             /* Delete the old profile chunk */
   3935             rv = _bcm_offset_map_table_entry_delete(unit, index);
   3936             if (BCM_FAILURE(rv)) {
   3937                 soc_cm_sfree(unit, offset_map_table);
   3938                 QOS_UNLOCK(unit);
   3939                 return (rv);
   3940             }
   3941 
   3942             /* Add new chunk and store new HW index */
   3943             entries[0] = offset_map_table;
   3944             rv = _bcm_offset_map_table_entry_add(unit, entries, 
   3945                                       _BCM_QOS_MAP_CHUNK_OFFSET_MAP,
   3946                                                     (uint32 *)&index);
   3947             QOS_INFO(unit)->offset_map_hw_idx[id] = 
   3948                                  index / _BCM_QOS_MAP_CHUNK_OFFSET_MAP;
   3949 
   3950             /* Free the DMA memory */
   3951             soc_cm_sfree(unit, offset_map_table);
   3952         }
   3953         break;
   3954 #endif
   3955 #ifdef BCM_SABER2_SUPPORT
   3956     case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE:
   3957         if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   3958             if (!_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) {
   3959                 QOS_UNLOCK(unit);
   3960                 return BCM_E_PARAM;
   3961             } else {
   3962 
   3963                 conf_flags = _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_GET(unit, id);
   3964                 if (flags != conf_flags) {
   3965                     return BCM_E_PARAM;
   3966                 }
   3967                 BCM_IF_ERROR_RETURN(
   3968                     _bcm_sb2_qos_oam_pri_map_params_check(flags, map));
   3969 
   3970                 /* Allocate memory for DMA */
   3971                 alloc_size = _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP * 
   3972                     sizeof(ing_service_pri_map_0_entry_t);
   3973                 service_pri_map_table = soc_cm_salloc(unit, alloc_size,
   3974                         "SB2 service pri map table");
   3975                 if (NULL == service_pri_map_table) {
   3976                     QOS_UNLOCK(unit);
   3977                     return (BCM_E_MEMORY);
   3978                 }
   3979                 sal_memset(service_pri_map_table, 0, alloc_size);
   3980 
   3981                 /* Base index of table in hardware */
   3982                 index = QOS_INFO(unit)->service_pri_map_hw_idx[id] * 
   3983                     _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP;
   3984 
   3985                 /* Offset within table */
   3986                 offset = map->counter_offset;
   3987 
   3988                 /* Read the old profile chunk from one of the tables.*/
   3989                 
   3990                 rv = soc_mem_read_range(unit, ING_SERVICE_PRI_MAP_0m, 
   3991                         MEM_BLOCK_ANY, index, 
   3992                         index + (_BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP - 1),
   3993                         service_pri_map_table);
   3994                 if (BCM_FAILURE(rv)) {
   3995                     soc_cm_sfree(unit, service_pri_map_table);
   3996                     QOS_UNLOCK(unit);
   3997                     return (rv);
   3998                 }
   3999 
   4000                 /* Modify what's needed */
   4001                 rv = _bcm_sb2_service_pri_map_flags_pri_get(map, flags, &pri);
   4002                 if (BCM_FAILURE(rv)) {
   4003                     soc_cm_sfree(unit, service_pri_map_table);
   4004                     QOS_UNLOCK(unit);
   4005                     return (rv);
   4006                 }
   4007                 entry = &service_pri_map_table[pri];
   4008                 soc_ING_SERVICE_PRI_MAP_0m_field32_set(unit, entry, 
   4009                         OFFSETf, offset);
   4010                 soc_ING_SERVICE_PRI_MAP_0m_field32_set(unit, entry, 
   4011                         OFFSET_VALIDf, 1);
   4012                 soc_ING_SERVICE_PRI_MAP_0m_field32_set(unit, entry, 
   4013                         LM_COLORf, map->color);
   4014 
   4015                 /* Delete the old profile chunk */
   4016                 rv = _bcm_service_pri_map_table_entry_delete(unit, index);
   4017                 if (BCM_FAILURE(rv)) {
   4018                     soc_cm_sfree(unit, service_pri_map_table);
   4019                     QOS_UNLOCK(unit);
   4020                     return (rv);
   4021                 }
   4022 
   4023                 /* Add new chunk and store new HW index */
   4024                 for (table = 0; table < _BCM_SB2_OAM_PRI_MAP_TABLE_MAX; table++) {
   4025                     mem_entries[table] = service_pri_map_table;
   4026                 }
   4027                 rv = _bcm_service_pri_map_table_entry_add(unit, mem_entries, 
   4028                         _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP,
   4029                         (uint32 *)&index);
   4030 
   4031                 QOS_INFO(unit)->service_pri_map_hw_idx[id] = 
   4032                     index / _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP;
   4033 
   4034                 /* Free the DMA memory */
   4035                 soc_cm_sfree(unit, service_pri_map_table);
   4036             }
   4037         } else {
   4038             QOS_UNLOCK(unit);
   4039             return BCM_E_PARAM;
   4040         }
   4041         break;
   4042 #endif
   4043 #ifdef BCM_KATANA2_SUPPORT
   4044     case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP:
   4045         if (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) {
   4046             QOS_UNLOCK(unit);
   4047             return BCM_E_PARAM;
   4048         } else {
   4049             if ((map->int_pri > 15) || (map->int_pri < 0) ||
   4050                 (map->queue_offset < 0) || (map->queue_offset > 7)) { /* max no of queues =8 */
   4051                 QOS_UNLOCK(unit);
   4052                 return BCM_E_PARAM;
   4053             }
   4054 
   4055             sal_memset(rqe_queue_offset_profile, 0,
   4056                        sizeof(rqe_queue_offset_profile));
   4057 
   4058             /* Offset within table */
   4059             offset = map->queue_offset;
   4060 
   4061             /* Read the profile chunk */
   4062             for (i = 0; i <_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP;
   4063                  i++) {
   4064                 rv = READ_RQE_QUEUE_OFFSETr(unit, i,
   4065                                    &rqe_queue_offset_profile[i]);
   4066                 if (BCM_FAILURE(rv)) {
   4067                     QOS_UNLOCK(unit);
   4068                     return rv;
   4069                 }
   4070             }
   4071 
   4072             hw_idx = QOS_INFO(unit)->rqe_queue_offset_hw_idx[id];
   4073             entry = &rqe_queue_offset_profile[0];
   4074             /* Modify what's needed */
   4075             soc_reg_field_set(unit, RQE_QUEUE_OFFSETr,
   4076                   &rqe_queue_offset_profile[map->int_pri], profile_field[id],
   4077                   map->queue_offset);
   4078 
   4079             /* delete the old profile chunk or decrement the refcount*/
   4080             if (QOS_INFO(unit)->rqe_queue_offset_refcount[hw_idx]) {
   4081                 QOS_INFO(unit)->rqe_queue_offset_refcount[hw_idx]--;
   4082             }
   4083             /* update the cache priority entry with new offset
   4084              * compare function to campare is new map_id is
   4085              * same as exisiting map id
   4086              * if same increment reference count
   4087              * else push the changes to the hw
   4088              */
   4089             _bcm_rqe_queue_offset_map_table_compare(unit, entry, id, &profile_offset);
   4090 
   4091             if (profile_offset == id) {
   4092                 if (id != hw_idx) {
   4093                     for (i = 0; i <_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP; i++) {
   4094                          if (i != map->int_pri) {
   4095                              soc_reg_field_set(unit, RQE_QUEUE_OFFSETr,
   4096                                                &rqe_queue_offset_profile[i], profile_field[id],
   4097                                                soc_reg_field_get(unit, RQE_QUEUE_OFFSETr,
   4098                                                                  rqe_queue_offset_profile[i],
   4099                                                                  profile_field[hw_idx]));
   4100                          }
   4101                          rv = WRITE_RQE_QUEUE_OFFSETr(unit, i,
   4102                                                       rqe_queue_offset_profile[i]);
   4103                          if (BCM_FAILURE(rv)) {
   4104                              QOS_INFO(unit)->rqe_queue_offset_refcount[hw_idx]++;
   4105                              QOS_UNLOCK(unit);
   4106                              return rv;
   4107                          }
   4108                     }
   4109                 } else {
   4110                /* write to hardware and increment the refcount */
   4111                /* Add new chunk and store new HW index */
   4112                 rv = WRITE_RQE_QUEUE_OFFSETr(unit, map->int_pri,
   4113                        rqe_queue_offset_profile[map->int_pri]);
   4114                 if (BCM_FAILURE(rv)) {
   4115                     QOS_INFO(unit)->rqe_queue_offset_refcount[hw_idx]++;
   4116                     QOS_UNLOCK(unit);
   4117                     return rv;
   4118                 }
   4119                 }
   4120                 QOS_INFO(unit)->rqe_queue_offset_refcount[id]++;
   4121                 QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] = id;
   4122             } else {
   4123                 /* matching profile found
   4124                  * delete the profile at current index
   4125                  * Temporaryily increment the refcount for the current index.
   4126                  * delete the profile at current index
   4127                  * increment the refcount of the matching profile index
   4128                  */
   4129                 QOS_INFO(unit)->rqe_queue_offset_refcount[hw_idx]++;
   4130                 rv = _bcm_rqe_queue_offset_map_table_sw_delete(unit, hw_idx);
   4131                 if (BCM_FAILURE(rv)) {
   4132                     QOS_UNLOCK(unit);
   4133                     return rv;
   4134                 }
   4135 
   4136                 QOS_INFO(unit)->rqe_queue_offset_refcount[profile_offset]++;
   4137 
   4138                 QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] = profile_offset;
   4139 
   4140             }
   4141         }
   4142         break;
   4143 #endif
   4144 
   4145     default:
   4146 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   4147         if (map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) {
   4148             bcm_mpls_exp_map_t ing_exp_map;
   4149             bcm_mpls_exp_map_t_init(&ing_exp_map);
   4150             if (!(flags & BCM_QOS_MAP_MPLS) || !(flags & BCM_QOS_MAP_INGRESS)) {
   4151                 QOS_UNLOCK(unit);
   4152                 return BCM_E_PARAM;
   4153             }
   4154             if ((map->int_pri > 15) || (map->int_pri < 0) || 
   4155                 (map->exp > 7) || (map->exp < 0) || 
   4156                 ((map->color != bcmColorGreen) && 
   4157                 (map->color != bcmColorYellow) && 
   4158                 (map->color != bcmColorRed))) {
   4159                 QOS_UNLOCK(unit);
   4160                 return BCM_E_PARAM;
   4161             }
   4162             /* Call the triumph/mpls.c implementation */
   4163             ing_exp_map.exp = map->exp;
   4164             ing_exp_map.priority = map->int_pri;
   4165             ing_exp_map.color = map->color;
   4166             rv = bcm_tr_mpls_exp_map_set(unit, map_id, &ing_exp_map);
   4167         } else
   4168 #endif /* defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) */
   4169 #if defined(BCM_HGPROXY_COE_SUPPORT)
   4170         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 
   4171             (flags & BCM_QOS_MAP_SUBPORT)) {
   4172             rv = bcmi_xgs5_subport_egr_subtag_dot1p_map_add(unit, map);
   4173         } else
   4174 #endif
   4175 #if defined(BCM_KATANA2_SUPPORT)
   4176         if (SOC_IS_KATANA2(unit) && (flags == BCM_QOS_MAP_SUBPORT)) {
   4177             rv = bcm_kt2_subport_egr_subtag_dot1p_map_add(unit, map);
   4178         } else
   4179 #endif /* defined(BCM_KATANA2_SUPPORT) */
   4180         {
   4181             QOS_UNLOCK(unit);
   4182             return BCM_E_PARAM;
   4183         }
   4184         break;
   4185     }
   4186         
   4187 #ifdef BCM_WARM_BOOT_SUPPORT
   4188     SOC_CONTROL_LOCK(unit);
   4189     SOC_CONTROL(unit)->scache_dirty = 1;
   4190     SOC_CONTROL_UNLOCK(unit);
   4191 #endif
   4192     QOS_UNLOCK(unit);
   4193     return rv;
   4194 }
   4195 
   4196 /* Clear an entry from a QoS map */
   4197 /* Read the existing profile chunk, modify what's needed and add the 
   4198  * new profile. This can result in the HW profile index changing for a 
   4199  * given ID */
   4200 int 
   4201 bcm_tr2_qos_map_delete(int unit, uint32 flags, bcm_qos_map_t *map, int map_id)
   4202 {
   4203     int rv = BCM_E_NONE;
   4204     bcm_qos_map_t clr_map;
   4205 
   4206     QOS_INIT(unit);
   4207 
   4208     /* Check for incoming parameter */
   4209     if (NULL == map) {
   4210         return BCM_E_PARAM;
   4211     }
   4212 
   4213 #if defined(BCM_TOMAHAWK3_SUPPORT)
   4214     if (SOC_IS_TOMAHAWK3(unit)) {
   4215         BCM_IF_ERROR_RETURN(_bcm_th3_qos_validate_map_type(unit, map_id));
   4216     }
   4217 #endif
   4218 
   4219     switch (map_id >> _BCM_QOS_MAP_SHIFT) {
   4220     case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
   4221 #ifdef BCM_HURRICANE3_SUPPORT
   4222     case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP:
   4223 #endif
   4224         sal_memcpy(&clr_map, map, sizeof(clr_map));
   4225         clr_map.int_pri = 0;
   4226         clr_map.color = bcmColorGreen;
   4227         rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1);
   4228         break;
   4229     case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS:
   4230 #ifdef BCM_HURRICANE3_SUPPORT
   4231     case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS:
   4232 #endif
   4233         sal_memcpy(&clr_map, map, sizeof(clr_map));
   4234         clr_map.pkt_pri = 0;
   4235         clr_map.pkt_cfi = 0;
   4236         clr_map.exp = 0;
   4237         rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1);
   4238         break;
   4239     case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
   4240         sal_memcpy(&clr_map, map, sizeof(clr_map));
   4241         clr_map.int_pri = 0;
   4242         clr_map.color = bcmColorGreen;
   4243         rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1);
   4244         break;
   4245     case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE:
   4246         sal_memcpy(&clr_map, map, sizeof(clr_map));
   4247         clr_map.pkt_pri = 0;
   4248         clr_map.pkt_cfi = 0;
   4249         clr_map.dscp = 0;
   4250         rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1);
   4251         break;
   4252 #ifdef BCM_KATANA_SUPPORT
   4253     case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE:
   4254         sal_memcpy(&clr_map, map, sizeof(clr_map));
   4255         clr_map.queue_offset = 0;
   4256         rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1);
   4257         break;
   4258 #endif
   4259 #ifdef BCM_KATANA2_SUPPORT
   4260     case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP:
   4261         sal_memcpy(&clr_map, map, sizeof(clr_map));
   4262         clr_map.queue_offset = 0;
   4263         rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1);
   4264         break;
   4265 #endif
   4266 #ifdef BCM_SABER2_SUPPORT
   4267     case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE:
   4268         if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   4269             sal_memcpy(&clr_map, map, sizeof(clr_map));
   4270             clr_map.counter_offset = 0;
   4271             rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1);
   4272         } else {
   4273             rv = BCM_E_PARAM;
   4274         }
   4275         break;
   4276 #endif
   4277 
   4278     default:
   4279 #if defined(BCM_HGPROXY_COE_SUPPORT)
   4280         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 
   4281             (flags & BCM_QOS_MAP_SUBPORT)) {
   4282             rv = bcmi_xgs5_subport_egr_subtag_dot1p_map_delete(unit, map);
   4283         } else
   4284 #endif
   4285 #if defined(BCM_KATANA2_SUPPORT)
   4286         if (SOC_IS_KATANA2(unit) && (flags == BCM_QOS_MAP_SUBPORT)) {
   4287             rv = bcm_kt2_subport_egr_subtag_dot1p_map_delete(unit, map);
   4288         } else
   4289 #endif /* defined(BCM_KATANA2_SUPPORT) */
   4290         {
   4291             sal_memcpy(&clr_map, map, sizeof(clr_map));
   4292             clr_map.int_pri = 0;
   4293             clr_map.color = bcmColorGreen;
   4294             rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1);
   4295         }
   4296         break;
   4297     }
   4298 #ifdef BCM_WARM_BOOT_SUPPORT
   4299     SOC_CONTROL_LOCK(unit);
   4300     SOC_CONTROL(unit)->scache_dirty = 1;
   4301     SOC_CONTROL_UNLOCK(unit);
   4302 #endif
   4303     return rv;
   4304 }
   4305 
   4306 /*
   4307  * Function:
   4308  *      _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_set
   4309  * Purpose:
   4310  *      Configure the IPRI mapping index to port's EGR_VLAN_CONTROL_3 register
   4311  *      for inner vlan priority remarking through EGR_MPLS_EXP_MAPPING_2 table.
   4312  * Parameters:
   4313  *      unit       - (IN) BCM unit.
   4314  *      port       - (IN) Port number.
   4315  *      index      - (IN) Index to access EGR_MPLS_EXP_MAPPING_2m table.
   4316  * Returns:
   4317  *      BCM_E_XXX
   4318  */
   4319 int
   4320 _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_set(int unit,
   4321                                                     bcm_port_t port,
   4322                                                     int index)
   4323 {
   4324     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   4325 	    int rv, alloc_size;
   4326         uint32 rval;
   4327         char *buf;
   4328         void *entries[1];
   4329         uint8 pri = 0;
   4330         int  id=0;
   4331         if (SOC_IS_TRIDENT3X(unit)) {
   4332             if (SOC_MEM_IS_VALID(unit, EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m)) {
   4333                 alloc_size = 64 * sizeof(egr_zone_1_dot1p_mapping_table_3_entry_t);
   4334                 buf = soc_cm_salloc(unit, alloc_size, "TD3 EGR ZONE 1 PRI buf");
   4335                 if (NULL == buf) {
   4336                     return (BCM_E_MEMORY);
   4337                 }
   4338                 id = (index * _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   4339                 rv = soc_mem_read_range(unit, EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m, MEM_BLOCK_ANY,
   4340                                         id,
   4341                                         (id + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)),
   4342                                         (void *) buf);
   4343                 if (BCM_FAILURE(rv)) {
   4344                     soc_cm_sfree(unit, buf);
   4345                     return rv;
   4346                 }
   4347 
   4348                 /* Check if priority is configured for given QOS MAP ID profile */
   4349                 for (id = 0; id < _BCM_QOS_MAP_CHUNK_EGR_MPLS; id++) {
   4350                     entries[0] = soc_mem_table_idx_to_pointer(unit,
   4351                                                       EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m,
   4352                                                       void *, buf, id);
   4353                     pri = soc_mem_field32_get(unit, EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m,
   4354                                               entries[0], PRIf);
   4355                     /* Priority configured, proceed with configuration of
   4356                      * VLAN_CONTROL_3 register, with IPRI_MAPPING_PTR and
   4357                      * IPRI_CIF_SEL fields.
   4358                      */
   4359                     if (pri) {
   4360                           break;
   4361                     }
   4362                 }
   4363                 soc_cm_sfree(unit, buf);
   4364             }
   4365         } else {
   4366             if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m)) {
   4367                 alloc_size = 64 * sizeof(egr_pri_cng_map_entry_t);
   4368                 buf = soc_cm_salloc(unit, alloc_size, "TR2 egr mpls exp map2");
   4369                 if (NULL == buf) {
   4370                     return (BCM_E_MEMORY);
   4371                 }
   4372                 id = (index * _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   4373                 rv = soc_mem_read_range(unit, EGR_MPLS_EXP_MAPPING_2m, MEM_BLOCK_ANY, 
   4374                                         id,
   4375                                         (id + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)),
   4376                                         (void *) buf);
   4377                 if (BCM_FAILURE(rv)) {
   4378                     soc_cm_sfree(unit, buf);
   4379                     return rv;
   4380                 }
   4381 
   4382                 /* Check if priority is configured for given QOS MAP ID profile */
   4383                 for (id = 0; id < _BCM_QOS_MAP_CHUNK_EGR_MPLS; id++) {
   4384                     entries[0] = soc_mem_table_idx_to_pointer(unit,
   4385                                                       EGR_MPLS_EXP_MAPPING_2m,
   4386                                                       void *, buf, id);
   4387                     pri = soc_mem_field32_get(unit, EGR_MPLS_EXP_MAPPING_2m,
   4388                                               entries[0], PRIf);
   4389                     /* Priority configured, proceed with configuration of
   4390                      * VLAN_CONTROL_3 register, with IPRI_MAPPING_PTR and
   4391                      * IPRI_CIF_SEL fields.
   4392                      */
   4393                     if (pri) {
   4394                           break;
   4395                     }
   4396                 }
   4397                 soc_cm_sfree(unit, buf);
   4398             }
   4399         }
   4400 
   4401         /* Priority field is not configured in EGR_MPLS_EXP_MAPPING_2m table,
   4402          * skip VLAN_CONTROL_3 register configuration.
   4403          */
   4404         if ((!pri)) {
   4405             return BCM_E_NONE;
   4406         }
   4407 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   4408         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   4409             egr_vlan_control_3_entry_t entry;
   4410             soc_field_t fields[2];
   4411             uint32 values[2];
   4412 
   4413             if (SOC_IS_TRIDENT3X(unit)) {
   4414                 fields[0] = IPRI_MAPPING_PTRf;
   4415                 fields[1] = IPRI_CFI_SELf;
   4416                 values[0] = index;
   4417                 values[1] = 1;
   4418 
   4419                 /* Write 2 field/value pair to EGR_LPORT_PROFILE */
   4420                 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_fields_set(
   4421                                     unit, port, EGR_VLAN_CONTROL_3m, 2, fields, values));
   4422             } else {
   4423                 rv = READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry);
   4424                 BCM_IF_ERROR_RETURN(rv);
   4425 
   4426                 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry,
   4427                                     IPRI_MAPPING_PTRf, index);
   4428 
   4429                 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry,
   4430                                     IPRI_CFI_SELf, 1);
   4431                 rv = WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry);
   4432                 BCM_IF_ERROR_RETURN(rv);
   4433             }
   4434         } else
   4435 #endif
   4436         {
   4437             rv = READ_EGR_VLAN_CONTROL_3r(unit, port, &rval);
   4438             BCM_IF_ERROR_RETURN(rv);
   4439             soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval,
   4440                     IPRI_MAPPING_PTRf, index);
   4441 
   4442             soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRI_CFI_SELf, 1);
   4443             rv = WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval);
   4444             BCM_IF_ERROR_RETURN(rv);
   4445         }
   4446     }
   4447 
   4448     return BCM_E_NONE;
   4449 }
   4450 
   4451 
   4452 /* Attach a QoS map to an object (Gport) */
   4453 int 
   4454 bcm_tr2_qos_port_map_set(int unit, bcm_gport_t port, int ing_map, int egr_map)
   4455 {
   4456     int index, id, alloc_size, rv = BCM_E_NONE, idx;
   4457     uint8 pri, cfi;
   4458     char *buf, *buf2;
   4459     void *entries[1];
   4460     soc_mem_t source_mem = INVALIDm;
   4461     soc_field_t new_pri_field=0;
   4462     soc_field_t new_cfi_field=0;
   4463     uint32 rval = 0;
   4464 #ifdef INCLUDE_L3
   4465     source_vp_entry_t svp;
   4466     egr_wlan_dvp_entry_t wlan_dvp;
   4467     uint32 tnl_entry[SOC_MAX_MEM_FIELD_WORDS];
   4468     int tunnel, vp, encap_id, nhi, l3_iif = 0;
   4469     int tunnel_id_max, tunnel_count;
   4470     egr_l3_next_hop_entry_t egr_nh;
   4471     soc_field_t dot1p_pri_select_field=0;
   4472     soc_field_t dot1p_mapping_ptr_field=0;
   4473     int l3_nh_entry_type = 0;
   4474     int vc_swap_idx;
   4475     egr_mpls_vc_and_swap_label_table_entry_t vc_swap_entry;
   4476     _bcm_vp_info_t vp_info;
   4477 #endif
   4478 
   4479     QOS_INIT(unit);
   4480 
   4481     QOS_LOCK(unit);
   4482 #if defined(BCM_TOMAHAWK3_SUPPORT)
   4483     if (SOC_IS_TOMAHAWK3(unit)) {
   4484         /* Validate given ingress map for non supported types and IDs */
   4485         if ((ing_map > 0) &&
   4486             (BCM_E_NONE != _bcm_th3_qos_validate_map_type(unit, ing_map))) {
   4487             QOS_UNLOCK(unit);
   4488             return BCM_E_PARAM;
   4489         }
   4490         /* Validate given egress map for non supported types and IDs */
   4491         if ((egr_map > 0) &&
   4492             (BCM_E_NONE != _bcm_th3_qos_validate_map_type(unit, egr_map))) {
   4493             QOS_UNLOCK(unit);
   4494             return BCM_E_PARAM;
   4495         }
   4496     }
   4497 #endif /* BCM_TOMAHAWK3_SUPPORT */
   4498 
   4499 #ifdef INCLUDE_L3
   4500     if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 
   4501         !BCM_GPORT_IS_LOCAL(port)) {
   4502 
   4503 #if defined(BCM_TOMAHAWK3_SUPPORT)
   4504         if (SOC_IS_TOMAHAWK3(unit) && !BCM_GPORT_IS_TUNNEL(port)) {
   4505             QOS_UNLOCK(unit);
   4506             return BCM_E_PARAM;
   4507         }
   4508 #endif /* BCM_TOMAHAWK3_SUPPORT */
   4509 
   4510         /* Deal with different types of gports */
   4511         if (_BCM_QOS_GPORT_IS_VFI_VP_PORT(port) ||
   4512             BCM_GPORT_IS_VLAN_PORT(port) ||
   4513             BCM_GPORT_IS_NIV_PORT(port) ||
   4514             BCM_GPORT_IS_EXTENDER_PORT(port)) {
   4515             /* Deal with MiM and MPLS ports */
   4516             if (BCM_GPORT_IS_VLAN_PORT(port)) {
   4517                 vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
   4518                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
   4519                     QOS_UNLOCK(unit);
   4520                     return BCM_E_BADID;
   4521                 } 
   4522             } else if (BCM_GPORT_IS_MIM_PORT(port)) {
   4523                 vp = BCM_GPORT_MIM_PORT_ID_GET(port);
   4524                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
   4525                     QOS_UNLOCK(unit);
   4526                     return BCM_E_BADID;
   4527                 } 
   4528             } else if BCM_GPORT_IS_VXLAN_PORT(port) {
   4529                 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
   4530                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) {
   4531                     QOS_UNLOCK(unit);
   4532                     return BCM_E_BADID;
   4533                 }
   4534             } else if BCM_GPORT_IS_L2GRE_PORT(port) {
   4535                 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
   4536                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) {
   4537                     QOS_UNLOCK(unit);
   4538                     return BCM_E_BADID;
   4539                 }
   4540             } else if (BCM_GPORT_IS_EXTENDER_PORT(port)) {
   4541                 vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port);
   4542                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) {
   4543                     QOS_UNLOCK(unit);
   4544                     return BCM_E_BADID;
   4545                 }
   4546             } else if (BCM_GPORT_IS_NIV_PORT(port)) {
   4547                 vp = BCM_GPORT_NIV_PORT_ID_GET(port);
   4548                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) {
   4549                     QOS_UNLOCK(unit);
   4550                     return BCM_E_BADID;
   4551                 }
   4552             } else {
   4553                 vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
   4554                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
   4555                     QOS_UNLOCK(unit);
   4556                     return BCM_E_BADID;
   4557                 } 
   4558             }
   4559 
   4560             if (ing_map != -1) { /* -1 means no change */
   4561                 /* TRUST_DOT1P_PTR from SOURCE_VP table */
   4562                 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp);
   4563                 if (rv < 0) {
   4564                     QOS_UNLOCK(unit);
   4565                     return rv;
   4566                 }
   4567                 if (ing_map == 0) {
   4568                     /* Clear the existing map */
   4569                     soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DOT1P_PTRf, 0);
   4570                     if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V4f)) {
   4571                         soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V4f, 0);
   4572                     }
   4573                     if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V6f)) {
   4574                         soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V6f, 0);
   4575                     }
   4576                     if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_PTRf)) {
   4577                         soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_PTRf, 0);
   4578                     }
   4579                 } else {
   4580                     /* Use the provided map */
   4581                     id = ing_map & _BCM_QOS_MAP_TYPE_MASK; 
   4582                     switch (ing_map >> _BCM_QOS_MAP_SHIFT) {
   4583                       case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
   4584                         if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   4585                             QOS_UNLOCK(unit);
   4586                             return BCM_E_PARAM;
   4587                         }
   4588                         if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   4589                             QOS_UNLOCK(unit);
   4590                             return BCM_E_PARAM;
   4591                         }
   4592                         soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DOT1P_PTRf,
   4593                         QOS_INFO(unit)->pri_cng_hw_idx[id]);
   4594                         break;
   4595 
   4596                       case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
   4597                         if (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) {
   4598                             QOS_UNLOCK(unit);
   4599                             return BCM_E_PARAM;
   4600                         }
   4601                         if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_PTRf)) {
   4602                             soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_PTRf,
   4603                             QOS_INFO(unit)->dscp_hw_idx[id]);
   4604                         }
   4605                         if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V4f)) {
   4606                             soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V4f, 1);
   4607                         }
   4608 
   4609                         if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V6f)) {
   4610                             soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V6f, 1);
   4611                         }
   4612                         break;
   4613                     }
   4614                 }
   4615                 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp);
   4616                 if (rv < 0) {
   4617                     QOS_UNLOCK(unit);
   4618                     return rv;
   4619                 }
   4620             }
   4621             if (egr_map != -1) { /* -1 means no change */
   4622                 /* SD_TAG::DOT1P_MAPPING_PTR from EGR_L3_NEXT_HOP */
   4623                 if (BCM_GPORT_IS_MIM_PORT(port)) {
   4624                     rv = bcm_tr2_multicast_mim_encap_get(unit, 0, 0, port, 
   4625                                                          &encap_id);
   4626                 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
   4627                     rv = bcm_esw_multicast_vxlan_encap_get(unit, 0, 0, port,
   4628                                                            &encap_id);
   4629                 } else {
   4630                     rv = bcm_tr2_multicast_vpls_encap_get(unit, 0, 0, port, 
   4631                                                           &encap_id);
   4632                 }
   4633                 if (rv < 0) {
   4634                     QOS_UNLOCK(unit);
   4635                     return rv;
   4636                 }
   4637 #if defined(BCM_ENDURO_SUPPORT)
   4638                 if (SOC_IS_ENDURO(unit) && BCM_GPORT_IS_MIM_PORT(port)) {
   4639                     nhi = encap_id;
   4640                 } else 
   4641 #endif /* BCM_ENDURO_SUPPORT */
   4642                 {
   4643                     nhi = encap_id - BCM_XGS3_DVP_EGRESS_IDX_MIN(unit);
   4644                 }
   4645                 rv = soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 
   4646                                   nhi, &egr_nh);
   4647                 if (rv < 0) {
   4648                     QOS_UNLOCK(unit);
   4649                     return rv;
   4650                 }
   4651                 
   4652                 if(BCM_GPORT_IS_MPLS_PORT(port)) {
   4653                     l3_nh_entry_type = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm,
   4654                                            &egr_nh, nh_entry_type_field[unit]);
   4655                 }
   4656 
   4657                 if (BCM_GPORT_IS_MPLS_PORT(port) &&
   4658                     (l3_nh_entry_type == 0x1)) {
   4659                     if (soc_feature(unit, soc_feature_mpls_enhanced)) {
   4660                         vc_swap_idx = soc_EGR_L3_NEXT_HOPm_field32_get(
   4661                                          unit, &egr_nh,
   4662                                          MPLS__VC_AND_SWAP_INDEXf);
   4663                     } else {
   4664                         vc_swap_idx = soc_EGR_L3_NEXT_HOPm_field32_get(
   4665                                          unit, &egr_nh, VC_AND_SWAP_INDEXf);
   4666                     }
   4667                     if (vc_swap_idx > 0) {
   4668                         rv = soc_mem_read(unit,
   4669                                           EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
   4670                                           MEM_BLOCK_ANY, vc_swap_idx,
   4671                                           &vc_swap_entry);
   4672                         if (rv < 0) {
   4673                             QOS_UNLOCK(unit);
   4674                             return rv;
   4675                         }
   4676                         if (soc_mem_field_valid(unit,
   4677                             EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
   4678                             SD_TAG_DOT1P_PRI_SELECTf)) {
   4679                             if (egr_map == 0) {
   4680                                 /* Clear the existing map */
   4681                                 index = 0;
   4682                                 soc_mem_field32_set(
   4683                                     unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
   4684                                     &vc_swap_entry, SD_TAG_DOT1P_PRI_SELECTf,
   4685                                     0);
   4686                             } else {
   4687                                 /* Use the provided map */
   4688                                 if ((egr_map >> _BCM_QOS_MAP_SHIFT) !=
   4689                                      _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) {
   4690                                     QOS_UNLOCK(unit);
   4691                                     return BCM_E_PARAM;
   4692                                 }
   4693                                 id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   4694                                 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   4695                                     QOS_UNLOCK(unit);
   4696                                     return BCM_E_PARAM;
   4697                                 }
   4698                                 index = QOS_INFO(unit)->egr_mpls_hw_idx[id];
   4699                                 soc_mem_field32_set(
   4700                                     unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
   4701                                     &vc_swap_entry, SD_TAG_DOT1P_PRI_SELECTf,
   4702                                     1);
   4703                             }
   4704                             soc_mem_field32_set(
   4705                                 unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
   4706                                 &vc_swap_entry, SD_TAG_DOT1P_MAPPING_PTRf,
   4707                                 index);
   4708                             rv = soc_mem_write(
   4709                                     unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
   4710                                     MEM_BLOCK_ALL, vc_swap_idx, &vc_swap_entry);
   4711                             if (rv < 0) {
   4712                                 QOS_UNLOCK(unit);
   4713                                 return rv;
   4714                             }
   4715                         }
   4716                     }
   4717                 } else {
   4718                     /*  For Katana chip, bit position for DOT1P_PRI_SELECT and
   4719                         DOT1P_MAPPING_PTR fields are different in MIM and SD_TAG
   4720                         views hence below adding below expandable logic for
   4721                         selecting appropriate fields.
   4722                      */
   4723                     if (BCM_GPORT_IS_MIM_PORT(port) &&
   4724                         ((MIM_INFO(unit)->port_info[vp].flags &
   4725                         _BCM_MIM_PORT_TYPE_NETWORK) ||
   4726                         (MIM_INFO(unit)->port_info[vp].flags &
   4727                         _BCM_MIM_PORT_TYPE_PEER))) {
   4728                         if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm,
   4729                                                 MIM__DOT1P_PRI_SELECTf) &&
   4730                             soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm,
   4731                                                 MIM__DOT1P_MAPPING_PTRf)) {
   4732                             dot1p_pri_select_field = MIM__DOT1P_PRI_SELECTf;
   4733                             dot1p_mapping_ptr_field = MIM__DOT1P_MAPPING_PTRf;
   4734                         } else {
   4735                             QOS_UNLOCK(unit);
   4736                             return BCM_E_INTERNAL;
   4737                         }
   4738                     } else if (BCM_GPORT_IS_VXLAN_PORT(port)){
   4739                         rv = _bcm_vp_info_get(unit, vp, &vp_info);
   4740                         if (rv < 0) {
   4741                             QOS_UNLOCK(unit);
   4742                             return rv;
   4743                         }
   4744                         if (!(vp_info.flags & _BCM_VP_INFO_NETWORK_PORT)) {
   4745                             dot1p_pri_select_field =
   4746                                 SD_TAG__SD_TAG_DOT1P_PRI_SELECTf;
   4747                             dot1p_mapping_ptr_field =
   4748                                 SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf;
   4749                         } else {
   4750                             QOS_UNLOCK(unit);
   4751                             return BCM_E_PARAM;
   4752                         }
   4753                     } else {
   4754                         dot1p_pri_select_field =
   4755                             SD_TAG__SD_TAG_DOT1P_PRI_SELECTf;
   4756                         dot1p_mapping_ptr_field =
   4757                             SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf;
   4758                     }
   4759 
   4760                     if (egr_map == 0) {
   4761                         /* Clear the existing map */
   4762                         index = 0;
   4763                         soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh,
   4764                                             dot1p_pri_select_field,0);
   4765                     } else {
   4766                         /* Use the provided map */
   4767                         if ((egr_map >> _BCM_QOS_MAP_SHIFT) !=
   4768                              _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) {
   4769                             QOS_UNLOCK(unit);
   4770                             return BCM_E_PARAM;
   4771                         }
   4772                         id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   4773                         if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   4774                             QOS_UNLOCK(unit);
   4775                             return BCM_E_PARAM;
   4776                         }
   4777                         index = QOS_INFO(unit)->egr_mpls_hw_idx[id];
   4778                         soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh,
   4779                                             dot1p_pri_select_field,1);
   4780                     }
   4781                     soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh,
   4782                                         dot1p_mapping_ptr_field, index);
   4783                     rv = soc_mem_write(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ALL,
   4784                                        nhi, &egr_nh);
   4785                     if (rv < 0) {
   4786                         QOS_UNLOCK(unit);
   4787                         return rv;
   4788                     }
   4789                 }
   4790             }
   4791         } else if (BCM_GPORT_IS_WLAN_PORT(port)) {
   4792             /* Deal with WLAN ports */
   4793             vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
   4794             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) {
   4795                 QOS_UNLOCK(unit);
   4796                 return BCM_E_BADID;
   4797             }
   4798             if (ing_map != -1) { /* -1 means no change */
   4799                 if (ing_map == 0) {
   4800                     /* Clear the existing map */
   4801                     index = 0;
   4802                 } else {
   4803                     /* Use the provided map */
   4804                     if ((ing_map >> _BCM_QOS_MAP_SHIFT) != 
   4805                          _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP) {
   4806                         QOS_UNLOCK(unit);
   4807                         return BCM_E_PARAM;
   4808                     }
   4809                     id = ing_map & _BCM_QOS_MAP_TYPE_MASK;
   4810                     if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   4811                         QOS_UNLOCK(unit);
   4812                         return BCM_E_PARAM;
   4813                     }
   4814                     if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   4815                         QOS_UNLOCK(unit);
   4816                         return BCM_E_PARAM;
   4817                     }
   4818                     index = QOS_INFO(unit)->pri_cng_hw_idx[id];
   4819                 }
   4820 #if defined(BCM_TRIUMPH3_SUPPORT)
   4821                 if (SOC_IS_TRIUMPH3(unit)) {
   4822                     rv = bcm_tr3_wlan_lport_field_set(unit, port,
   4823                                                       TRUST_DOT1P_PTRf, index);
   4824                 } else
   4825 #endif /* BCM_TRIUMPH3_SUPPORT */
   4826                 { 
   4827                     rv = bcm_tr2_wlan_lport_field_set(unit, port,
   4828                                                       TRUST_DOT1P_PTRf, index);
   4829                 }
   4830                 if (rv < 0) {
   4831                     QOS_UNLOCK(unit);
   4832                     return rv;
   4833                 }
   4834             }
   4835 
   4836             if (egr_map != -1) { /* -1 means no change */
   4837 #if defined(BCM_TRIUMPH3_SUPPORT)
   4838                 if (SOC_IS_TRIUMPH3(unit)) {
   4839                     if (egr_map == 0) {
   4840                         /* Clear the existing map */
   4841                         index = 0;
   4842                     } else {
   4843                         if ((egr_map >> _BCM_QOS_MAP_SHIFT) != 
   4844                              _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) {
   4845                             QOS_UNLOCK(unit);
   4846                             return BCM_E_PARAM;
   4847                         }
   4848                         id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   4849                         if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   4850                             QOS_UNLOCK(unit);
   4851                             return BCM_E_PARAM;
   4852                         }
   4853                         index = QOS_INFO(unit)->egr_mpls_hw_idx[id];
   4854                     }
   4855 
   4856                     rv = _bcm_tr3_qos_wlan_port_map_set(
   4857                                             unit, port, egr_map, index);
   4858                     if (rv < 0) {
   4859                         QOS_UNLOCK(unit);
   4860                         return rv;
   4861                     }
   4862                 } else
   4863 #endif /* BCM_TRIUMPH3_SUPPORT */
   4864                 {
   4865                     /* EGR_WLAN_DVP.TUNNEL_INDEX points to CAPWAP initiator.
   4866                      * EGR_IP_TUNNEL.DOT1P_MAPPING_PTR contains the map */
   4867                     rv = READ_EGR_WLAN_DVPm(unit, MEM_BLOCK_ANY, vp, &wlan_dvp);
   4868                     if (rv < 0) {
   4869                         QOS_UNLOCK(unit);
   4870                         return rv;
   4871                     }
   4872                     tunnel = soc_EGR_WLAN_DVPm_field32_get(unit, &wlan_dvp, 
   4873                                                            TUNNEL_INDEXf);
   4874                     rv = soc_mem_read(unit, EGR_IP_TUNNELm, MEM_BLOCK_ANY, 
   4875                                       tunnel, tnl_entry);
   4876                     if (rv < 0) {
   4877                         QOS_UNLOCK(unit);
   4878                         return rv;
   4879                     }
   4880                     if (egr_map == 0) {
   4881                         /* Clear the existing map */
   4882                         index = 0;
   4883                         soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry, 
   4884                                             DOT1P_PRI_SELECTf, 0);
   4885                     } else {
   4886                         /* Use the provided map */
   4887                         if ((egr_map >> _BCM_QOS_MAP_SHIFT) != 
   4888                              _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) {
   4889                             QOS_UNLOCK(unit);
   4890                             return BCM_E_PARAM;
   4891                         }
   4892                         id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   4893                         if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   4894                             QOS_UNLOCK(unit);
   4895                             return BCM_E_PARAM;
   4896                         }
   4897                         index = QOS_INFO(unit)->egr_mpls_hw_idx[id];
   4898                         soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry, 
   4899                                             DOT1P_PRI_SELECTf, 1);
   4900                     }
   4901                     soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry,  
   4902                                         DOT1P_MAPPING_PTRf, index);
   4903                     rv = soc_mem_write(unit, EGR_IP_TUNNELm, MEM_BLOCK_ALL, 
   4904                                        tunnel, tnl_entry);
   4905                     if (rv < 0) {
   4906                         QOS_UNLOCK(unit);
   4907                         return rv;
   4908                     }
   4909                 }
   4910             }
   4911         } else if (BCM_GPORT_IS_TUNNEL(port)) {
   4912             /* Deal with tunnel initiators and terminators */
   4913             tunnel = BCM_GPORT_TUNNEL_ID_GET(port);
   4914 
   4915             if (ing_map != -1) { /* -1 means no change */
   4916 
   4917                 if (SOC_MEM_FIELD_VALID(unit, L3_TUNNELm, TUNNEL_IDf)) {
   4918                 /* Get L3_IIF from L3_TUNNEL.
   4919                  * Get TRUST_DSCP_PTR from L3_IIF */
   4920                 tunnel_id_max = soc_mem_index_max(unit, L3_TUNNELm);
   4921                 tunnel_count = soc_mem_index_count(unit, L3_TUNNELm);
   4922                 alloc_size = tunnel_count * sizeof(tnl_entry);
   4923                 buf = soc_cm_salloc(unit, alloc_size, "TR2 L3 TUNNEL");
   4924                 if (NULL == buf) {
   4925                     QOS_UNLOCK(unit);
   4926                     return (BCM_E_MEMORY);
   4927                 }
   4928                 rv = soc_mem_read_range(unit, L3_TUNNELm, MEM_BLOCK_ANY,  
   4929                                         0, tunnel_id_max, (void *)buf);
   4930                 if (rv < 0) {
   4931                     soc_cm_sfree(unit, buf);
   4932                     QOS_UNLOCK(unit);
   4933                     return rv;
   4934                 }
   4935 
   4936                     for (index = 0; index < tunnel_id_max; index++) 
   4937                     {
   4938                         entries[0] = soc_mem_table_idx_to_pointer(unit, L3_TUNNELm, 
   4939                                                                   void *, buf, 
   4940                                                                   index);
   4941                         if (tunnel == soc_mem_field32_get(unit, L3_TUNNELm, 
   4942                                                           entries[0], TUNNEL_IDf)) {
   4943                             /* Tunnel found - get L3_IIF */
   4944                             l3_iif = soc_mem_field32_get(unit, L3_TUNNELm, 
   4945                                                          entries[0], L3_IIFf);
   4946                             break; 
   4947                         }
   4948                     }
   4949 
   4950                 soc_cm_sfree(unit, buf);
   4951                 if (index == tunnel_id_max) {
   4952                     QOS_UNLOCK(unit);
   4953                     return BCM_E_NOT_FOUND; /* Tunnel not found */
   4954                 }
   4955                 } else {
   4956                     index = tunnel;
   4957                 }
   4958 
   4959                 if (ing_map == 0) {
   4960                     /* Clear the existing map */
   4961                     index = 0;
   4962                 } else {
   4963                     /* Use the provided map */
   4964                     if ((ing_map >> _BCM_QOS_MAP_SHIFT) != 
   4965                          _BCM_QOS_MAP_TYPE_DSCP_TABLE) {
   4966                         QOS_UNLOCK(unit);
   4967                         return BCM_E_PARAM;
   4968                     }
   4969                     id = ing_map & _BCM_QOS_MAP_TYPE_MASK;
   4970                     if (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) {
   4971                         QOS_UNLOCK(unit);
   4972                         return BCM_E_PARAM;
   4973                     }
   4974                     index = QOS_INFO(unit)->dscp_hw_idx[id];
   4975                 }
   4976                 if (soc_mem_field_valid(unit, L3_IIFm, TRUST_DSCP_PTRf)) {
   4977                     rv = soc_mem_field32_modify(unit, L3_IIFm, l3_iif, 
   4978                                             TRUST_DSCP_PTRf, index);
   4979                 }
   4980 #ifdef BCM_TRIDENT2_SUPPORT
   4981                 if (SOC_IS_TD2_TT2(unit)) { /* Get l3 iif profile entry */
   4982                     uint32 l3_index, old_profile_index = 0;
   4983                     void *entries[1];
   4984                     iif_profile_entry_t l3_iif_profile;
   4985                     iif_entry_t entry;
   4986                     entries[0] = &l3_iif_profile;
   4987 
   4988                     /* Read interface config from hw. */
   4989                     rv = soc_mem_read(unit, L3_IIFm, MEM_BLOCK_ANY, l3_iif,
   4990                                       (uint32 *)&entry);
   4991                     if (BCM_SUCCESS(rv)) {
   4992                         l3_index = soc_mem_field32_get(unit, L3_IIFm, 
   4993                                                        (uint32 *)&entry,
   4994                                                       L3_IIF_PROFILE_INDEXf); 
   4995                         rv = _bcm_l3_iif_profile_entry_get(unit, 
   4996                                               l3_index, 1, entries);
   4997                         old_profile_index = l3_index;
   4998                         if (BCM_SUCCESS(rv)) {
   4999                             (void)soc_mem_field32_set(unit, L3_IIF_PROFILEm,
   5000                                                       &l3_iif_profile,
   5001                                                       TRUST_DSCP_PTRf, index);
   5002                         
   5003                             _bcm_l3_iif_profile_entry_update(unit, entries,
   5004                                                                  &l3_index);
   5005                             if (BCM_SUCCESS(rv)) {
   5006                                 if (l3_index != old_profile_index) {
   5007                                     soc_mem_field32_set(unit, L3_IIFm, 
   5008                                                         (uint32 *)&entry,
   5009                                                         L3_IIF_PROFILE_INDEXf, 
   5010                                                         l3_index);
   5011                                     /* write l3_iif entry to hw */
   5012                                     rv = soc_mem_write(unit, L3_IIFm, 
   5013                                                        MEM_BLOCK_ALL, l3_iif,
   5014                                                        (uint32 *)&entry);
   5015                                     /* remove the old entry */
   5016                                     if ((BCM_SUCCESS(rv)) && 
   5017                                             old_profile_index) {
   5018                                         _bcm_l3_iif_profile_entry_delete(unit, 
   5019                                                            old_profile_index);
   5020                                     } else {
   5021                                         /* remove the new entry as hw write
   5022                                            of new entry is failed.
   5023                                          */
   5024                                         _bcm_l3_iif_profile_entry_delete(unit, 
   5025                                                                     l3_index);
   5026                                     }
   5027                                 }
   5028                             }
   5029                         }
   5030                     }
   5031                 }
   5032 #endif /* BCM_TRIDENT2_SUPPORT */
   5033                 if (rv < 0) {
   5034                     QOS_UNLOCK(unit);
   5035                     return rv;
   5036                 }
   5037             }
   5038             if (egr_map != -1) { /* -1 means no change */
   5039                 /* DSCP_MAPPING_PTR from EGR_IP_TUNNEL */
   5040                 rv = soc_mem_read(unit, EGR_IP_TUNNELm, MEM_BLOCK_ANY, 
   5041                                   tunnel, tnl_entry);
   5042                 if (rv < 0) {
   5043                     QOS_UNLOCK(unit);
   5044                     return rv;
   5045                 }
   5046                 if (egr_map == 0) {
   5047                     /* Clear existing map */
   5048                     index = 0;
   5049                     soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry, 
   5050                                         DSCP_SELf, 0);
   5051                 } else {
   5052                     /* Use the provided map */
   5053                     if ((egr_map >> _BCM_QOS_MAP_SHIFT) != 
   5054                          _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE) {
   5055                         QOS_UNLOCK(unit);
   5056                         return BCM_E_PARAM;
   5057                     }
   5058                     id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   5059                     if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) {
   5060                         QOS_UNLOCK(unit);
   5061                         return BCM_E_PARAM;
   5062                     }
   5063                     index = QOS_INFO(unit)->egr_dscp_hw_idx[id];
   5064                     soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry, 
   5065                                         DSCP_SELf, 2);
   5066                 }
   5067                 soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry,  
   5068                                     DSCP_MAPPING_PTRf, index);
   5069                 rv = soc_mem_write(unit, EGR_IP_TUNNELm, MEM_BLOCK_ALL, 
   5070                                    tunnel, tnl_entry);
   5071                 if (rv < 0) {
   5072                     QOS_UNLOCK(unit);
   5073                     return rv;
   5074                 }
   5075             }
   5076         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
   5077 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(BCM_HGPROXY_COE_SUPPORT)
   5078             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   5079                 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   5080                 if (ing_map != -1) { /* -1 means no change */
   5081                     /* Make the port's TRUST_DOT1_PTR point to the profile index */
   5082                     if (ing_map == 0) {
   5083                         /* Clear the existing map */
   5084                         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
   5085                                                    TRUST_DOT1P_PTRf, 0);
   5086                         if (BCM_FAILURE(rv)) {
   5087                             QOS_UNLOCK(unit);
   5088                             return rv;
   5089                         }
   5090                     } else {
   5091                         id = ing_map & _BCM_QOS_MAP_TYPE_MASK;
   5092                         switch (ing_map >> _BCM_QOS_MAP_SHIFT) {
   5093                           case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
   5094                             if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   5095                                 QOS_UNLOCK(unit);
   5096                                 return BCM_E_PARAM;
   5097                             }
   5098                             if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   5099                                 QOS_UNLOCK(unit);
   5100                                 return BCM_E_PARAM;
   5101                             }
   5102                             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
   5103                                                    TRUST_DOT1P_PTRf,
   5104                                                    QOS_INFO(unit)->pri_cng_hw_idx[id]);
   5105                             if (BCM_FAILURE(rv)) {
   5106                                 QOS_UNLOCK(unit);
   5107                                 return rv;
   5108                             }
   5109                             break;
   5110                           default:
   5111                             rv = BCM_E_CONFIG;
   5112                         }
   5113                     }
   5114                 }
   5115 
   5116                 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   5117                     if (egr_map != -1) { /* -1 means no change */
   5118                         if (egr_map == 0) {
   5119                             /* Clear the existing map */
   5120                             rv = _bcm_esw_egr_port_tab_set(unit,
   5121                                                             port,
   5122                                                             EGR_QOS_PROFILE_INDEXf,
   5123                                                             0);
   5124                             if (BCM_FAILURE(rv)) {
   5125                                 QOS_UNLOCK(unit);
   5126                                 return rv;
   5127                             }
   5128                         } else {
   5129                             if ((egr_map >> _BCM_QOS_MAP_SHIFT) != _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE) {
   5130                                 QOS_UNLOCK(unit);
   5131                                 return BCM_E_PARAM;
   5132                             }
   5133                             id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   5134                             if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) {
   5135                                 QOS_UNLOCK(unit);
   5136                                 return BCM_E_PARAM;
   5137                             }
   5138 
   5139                             index = QOS_INFO(unit)->egr_dscp_hw_idx[id];
   5140                             rv = _bcm_esw_egr_port_tab_set(unit,
   5141                                                         port,
   5142                                                         EGR_QOS_PROFILE_INDEXf,
   5143                                                         index);
   5144                             if (BCM_FAILURE(rv)) {
   5145                                 QOS_UNLOCK(unit);
   5146                                 return rv;
   5147                             }
   5148                         }
   5149                     }
   5150                 }
   5151             }
   5152 #endif
   5153         } else {
   5154             QOS_UNLOCK(unit);
   5155             return BCM_E_PARAM;
   5156         }
   5157     } else
   5158 #endif
   5159     {
   5160         /* Deal with physical ports */
   5161         if (BCM_GPORT_IS_SET(port)) {
   5162             if (bcm_esw_port_local_get(unit, port, &port) < 0) {
   5163                 QOS_UNLOCK(unit);
   5164                 return BCM_E_PARAM;
   5165             }
   5166         }
   5167         if (!SOC_PORT_VALID(unit, port)) {
   5168             QOS_UNLOCK(unit);
   5169             return BCM_E_PARAM;
   5170         }
   5171         if (ing_map != -1) { /* -1 means no change */
   5172             /* Make the port's TRUST_DOT1_PTR point to the profile index */
   5173             if (ing_map == 0) {
   5174                 /* Clear the existing map */
   5175                 if (SOC_IS_TRIDENT3X(unit)) {
   5176                     PORT_LOCK(unit);
   5177                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 
   5178                                                TRUST_DOT1P_PTRf, 0);
   5179                     if (BCM_SUCCESS(rv)) {
   5180                         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
   5181                                                    TRUST_DSCP_V4f, 0);
   5182                     }
   5183                     if (BCM_SUCCESS(rv)) {
   5184                         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
   5185                                                    TRUST_DSCP_V6f, 0);
   5186                     }
   5187                     if (BCM_SUCCESS(rv)) {
   5188                         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
   5189                                                    TRUST_DSCP_PTRf, 0);
   5190                     }
   5191                     PORT_UNLOCK(unit);
   5192                 } else {
   5193                     soc_mem_lock(unit, PORT_TABm);
   5194                     rv = _bcm_tr2_port_tab_set(unit, port, TRUST_DOT1P_PTRf, 0);
   5195                     if (BCM_SUCCESS(rv) &&
   5196                         soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V4f)) {
   5197                         rv = _bcm_tr2_port_tab_set(unit, port, TRUST_DSCP_V4f, 0);
   5198                     }
   5199                     if (BCM_SUCCESS(rv) &&
   5200                         soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V6f)) {
   5201                         rv = _bcm_tr2_port_tab_set(unit, port, TRUST_DSCP_V6f, 0);
   5202                     }
   5203                     if (BCM_SUCCESS(rv) &&
   5204                         soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_PTRf)) {
   5205                         rv = _bcm_tr2_port_tab_set(unit, port, TRUST_DSCP_PTRf, 0);
   5206                     }
   5207                     soc_mem_unlock(unit, PORT_TABm);  
   5208                 }    
   5209             } else {
   5210                 id = ing_map & _BCM_QOS_MAP_TYPE_MASK; 
   5211                 switch (ing_map >> _BCM_QOS_MAP_SHIFT) {
   5212                   case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
   5213                     if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   5214                         QOS_UNLOCK(unit);
   5215                         return BCM_E_PARAM;
   5216                     }
   5217                     if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   5218                         QOS_UNLOCK(unit);
   5219                         return BCM_E_PARAM;
   5220                     }
   5221                     if (SOC_IS_TRIDENT3X(unit)) {
   5222                         PORT_LOCK(unit);
   5223                         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, TRUST_DOT1P_PTRf,
   5224                                                QOS_INFO(unit)->pri_cng_hw_idx[id]);
   5225                         PORT_UNLOCK(unit);
   5226                     } else {
   5227 #ifdef BCM_SABER2_SUPPORT
   5228                         if (SOC_IS_SABER2(unit)) {
   5229                             rv = _bcm_tr2_port_tab_get(unit, port,TRUST_DOT1P_PTRf, &idx);
   5230                             if (BCM_FAILURE(rv)) {
   5231                                 QOS_UNLOCK(unit);
   5232                                 return rv;
   5233                             }
   5234                             _BCM_QOS_TRUST_DOT1P_PTR_CACHE_CLEAR(unit, port, idx/
   5235                                                                 _BCM_QOS_MAP_CHUNK_PRI_CNG);
   5236                             _BCM_QOS_TRUST_DOT1P_PTR_CACHE_SET(unit, port,
   5237                                                               QOS_INFO(unit)->pri_cng_hw_idx[id]);
   5238                         }
   5239 #endif
   5240                         soc_mem_lock(unit, PORT_TABm);
   5241                         rv = _bcm_tr2_port_tab_set(unit, port, TRUST_DOT1P_PTRf,
   5242                                                QOS_INFO(unit)->pri_cng_hw_idx[id]);
   5243                         soc_mem_unlock(unit, PORT_TABm);
   5244                     }
   5245                     break;
   5246                   case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
   5247                     if (SOC_IS_KATANA(unit)) {
   5248                         /* TRUST_DSCP_PTR is already reserved for katana. So don't overwrite
   5249                          * Return error if user is tyring to set some other map other than
   5250                          * the default one.
   5251                          */
   5252                         soc_mem_lock(unit, PORT_TABm);
   5253                         rv = _bcm_tr2_port_tab_get(unit, port,TRUST_DSCP_PTRf, &idx);
   5254                         if (ing_map != idx) {
   5255                             rv = BCM_E_CONFIG;
   5256                         }
   5257                         soc_mem_unlock(unit, PORT_TABm);
   5258                     } else if (soc_mem_field_valid(unit,PORT_TABm,
   5259                                                    TRUST_DSCP_PTRf)) {
   5260                         soc_mem_lock(unit, PORT_TABm);
   5261                         rv = _bcm_tr2_port_tab_set(
   5262                                 unit, port, TRUST_DSCP_PTRf,
   5263                                 QOS_INFO(unit)->dscp_hw_idx[id]);
   5264                         soc_mem_unlock(unit, PORT_TABm);
   5265                     } else if (SOC_IS_TRIDENT3X(unit)) {
   5266                         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
   5267                                                    TRUST_DSCP_PTRf, QOS_INFO(unit)->dscp_hw_idx[id]);
   5268                         if (BCM_FAILURE(rv)) {
   5269                             QOS_UNLOCK(unit);
   5270                             return rv;
   5271                         }
   5272 
   5273                         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
   5274                                                    TRUST_DSCP_V4f, 1);
   5275                         if (BCM_FAILURE(rv)) {
   5276                             QOS_UNLOCK(unit);
   5277                             return rv;
   5278                         }
   5279 
   5280                         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
   5281                                                    TRUST_DSCP_V6f, 1);
   5282                         if (BCM_FAILURE(rv)) {
   5283                             QOS_UNLOCK(unit);
   5284                             return rv;
   5285                         }
   5286                     } else if (SOC_IS_TRIDENT(unit)) {
   5287                         /* Allocate memory for DMA */
   5288                         alloc_size = _BCM_QOS_MAP_CHUNK_DSCP *
   5289                                      sizeof(dscp_table_entry_t);
   5290                         buf = soc_cm_salloc(unit, alloc_size,
   5291                                             "TR2 dscp table");
   5292                         if (NULL == buf) {
   5293                             QOS_UNLOCK(unit);
   5294                             return BCM_E_MEMORY;
   5295                         }
   5296                         sal_memset(buf, 0, alloc_size);
   5297                         /* Base index of table in hardware */
   5298                         index = QOS_INFO(unit)->dscp_hw_idx[id] *
   5299                                 _BCM_QOS_MAP_CHUNK_DSCP;
   5300                         /* Read the profile chunk */
   5301                         rv = soc_mem_read_range(
   5302                                  unit, _bcm_tr2_qos_bk_info[unit].dscp_table, 
   5303                                  MEM_BLOCK_ANY, index,
   5304                                  index + _BCM_QOS_MAP_CHUNK_DSCP - 1,
   5305                                  buf);
   5306                         if (BCM_FAILURE(rv)) {
   5307                             soc_cm_sfree(unit, buf);
   5308                             QOS_UNLOCK(unit);
   5309                             return rv;
   5310                         }
   5311                         /* Write the port's chunk */
   5312                         rv = soc_mem_write_range(
   5313                                  unit, _bcm_tr2_qos_bk_info[unit].dscp_table, 
   5314                                  MEM_BLOCK_ANY,
   5315                                  port * _BCM_QOS_MAP_CHUNK_DSCP,
   5316                                  (port + 1) * _BCM_QOS_MAP_CHUNK_DSCP - 1,
   5317                                  buf);
   5318                         soc_cm_sfree(unit, buf);
   5319                     }
   5320 
   5321                     soc_mem_lock(unit, PORT_TABm);
   5322                     if (BCM_SUCCESS(rv) && 
   5323                         soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V4f)) {
   5324                         rv = _bcm_tr2_port_tab_set(unit, port, 
   5325                                                    TRUST_DSCP_V4f, 1);
   5326                     }
   5327                     if (BCM_SUCCESS(rv) &&
   5328                         soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V6f)) {
   5329                         rv = _bcm_tr2_port_tab_set(unit, port, 
   5330                                                    TRUST_DSCP_V6f, 1);
   5331                     }
   5332                     soc_mem_unlock(unit, PORT_TABm);
   5333                     break;
   5334 #ifdef BCM_HURRICANE3_SUPPORT
   5335                   case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP:
   5336                     if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   5337                         QOS_UNLOCK(unit);
   5338                         return BCM_E_PARAM;
   5339                     }
   5340                     if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   5341                         QOS_UNLOCK(unit);
   5342                         return BCM_E_PARAM;
   5343                     }
   5344                     if (!soc_feature(unit, soc_feature_miml)) {
   5345                         QOS_UNLOCK(unit);
   5346                         return BCM_E_PARAM;
   5347                     }
   5348                     soc_mem_lock(unit, PORT_TABm);
   5349                     rv = _bcm_tr2_port_tab_set(unit, port, MIML_DOT1P_MAPPING_PTRf,
   5350                                            QOS_INFO(unit)->pri_cng_hw_idx[id]);
   5351                     soc_mem_unlock(unit, PORT_TABm);
   5352                     break;
   5353 #endif
   5354                   default:
   5355                     rv = BCM_E_CONFIG;
   5356                 }
   5357             }
   5358         }
   5359         if (egr_map != -1) { /* -1 means no change */
   5360             alloc_size = 64 * sizeof(egr_pri_cng_map_entry_t);
   5361             buf = soc_cm_salloc(unit, alloc_size, "TR2 egr pri cng map");
   5362             if (NULL == buf) {
   5363                 QOS_UNLOCK(unit);
   5364                 return (BCM_E_MEMORY);
   5365             }
   5366             sal_memset(buf, 0, alloc_size);
   5367             index = port << 6;
   5368             if (egr_map == 0) {
   5369                 /* Clear the existing map */
   5370 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5371                 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   5372                    rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_QOS_PROFILE_INDEXf, 0); 
   5373                    if (BCM_FAILURE(rv)) {
   5374                         soc_cm_sfree(unit, buf);
   5375                         QOS_UNLOCK(unit);
   5376                         return rv;
   5377                     } 
   5378                 } else if (SOC_IS_TRIDENT3X(unit)) {
   5379                    /* Reset L3 pointer */
   5380                    rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_QOS_PROFILE_INDEXf, 0);
   5381                    if (BCM_FAILURE(rv)) {
   5382                         soc_cm_sfree(unit, buf);
   5383                         QOS_UNLOCK(unit);
   5384                         return rv;
   5385                     }
   5386                    /* Reset L2 pointer */
   5387                    rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_DOT1P_PROFILE_INDEXf, 0);
   5388                    if (BCM_FAILURE(rv)) {
   5389                         soc_cm_sfree(unit, buf);
   5390                         QOS_UNLOCK(unit);
   5391                         return rv;
   5392                     }
   5393                 } else 
   5394 #endif
   5395                 {
   5396                     rv = soc_mem_write_range(unit, EGR_PRI_CNG_MAPm, MEM_BLOCK_ALL, 
   5397                                              index, index + 63, (void *)buf);
   5398                     if (BCM_FAILURE(rv)) {
   5399                         soc_cm_sfree(unit, buf);
   5400                         QOS_UNLOCK(unit);
   5401                         return rv;
   5402                     }
   5403                 }
   5404                 if ( SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   5405                      (SOC_IS_TD_TT(unit) && !SOC_IS_TOMAHAWK3(unit) )) {
   5406 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5407                     if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   5408                         soc_mem_t mem = EGR_VLAN_CONTROL_3m;
   5409                         if (soc_feature(unit, soc_feature_egr_all_profile)) {
   5410                             soc_field_t fields[2] = {
   5411                                 IPRI_MAPPING_PTRf, IPRI_CFI_SELf
   5412                             };
   5413                             uint32 values[2] = {0, 0};
   5414                             BCM_IF_ERROR_RETURN(
   5415                                 bcm_esw_port_egr_lport_fields_set(unit,
   5416                                 port, mem, 2, fields, values));
   5417                         } else {
   5418                             egr_vlan_control_3_entry_t entry;
   5419 
   5420                             rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   5421                                               port, &entry);
   5422                             if (BCM_FAILURE(rv)) {
   5423                                 soc_cm_sfree(unit, buf);
   5424                                 QOS_UNLOCK(unit);
   5425                                 return rv;
   5426                             }
   5427 
   5428                             soc_mem_field32_set(unit, mem, &entry,
   5429                                                 IPRI_MAPPING_PTRf, 0);
   5430                             soc_mem_field32_set(unit, mem, &entry,
   5431                                                 IPRI_CFI_SELf, 0);
   5432                             rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY,
   5433                                                port, &entry);
   5434                             if (BCM_FAILURE(rv)) {
   5435                                 soc_cm_sfree(unit, buf);
   5436                                 QOS_UNLOCK(unit);
   5437                                 return rv;
   5438                             }
   5439                         }
   5440                     } else
   5441 #endif
   5442                     {
   5443                         /* Clear existing map from port EGR_VLAN_CONTROL_3 register */
   5444                         rv = READ_EGR_VLAN_CONTROL_3r(unit, port, &rval);
   5445                         if (BCM_FAILURE(rv)) {
   5446                             soc_cm_sfree(unit, buf);
   5447                             QOS_UNLOCK(unit);
   5448                             return rv;
   5449                         }
   5450 
   5451                         soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval,
   5452                                 IPRI_MAPPING_PTRf, 0);
   5453                         soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval,
   5454                                 IPRI_CFI_SELf, 0);
   5455                         rv = WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval);
   5456                         if (BCM_FAILURE(rv)) {
   5457                             soc_cm_sfree(unit, buf);
   5458                             QOS_UNLOCK(unit);
   5459                             return rv;
   5460                         }
   5461                     }
   5462                 }
   5463             } else {
   5464                 if (((egr_map >> _BCM_QOS_MAP_SHIFT) != _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) &&
   5465                    ((egr_map >> _BCM_QOS_MAP_SHIFT) != _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE)) {
   5466                     QOS_UNLOCK(unit);
   5467                     return BCM_E_PARAM;
   5468                 }
   5469                 id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   5470                 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id) && 
   5471                     !_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) {
   5472                     QOS_UNLOCK(unit);
   5473                     return BCM_E_PARAM;
   5474                 }
   5475 
   5476 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5477                 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   5478                     if ((egr_map >> _BCM_QOS_MAP_SHIFT) == _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE) {
   5479                         id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   5480                         index = QOS_INFO(unit)->egr_dscp_hw_idx[id];
   5481                         rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_QOS_PROFILE_INDEXf, index); 
   5482                         if (BCM_FAILURE(rv)) {
   5483                             soc_cm_sfree(unit, buf);
   5484                             QOS_UNLOCK(unit);
   5485                             return rv;
   5486                         }
   5487                     }
   5488                 } else if (SOC_IS_TRIDENT3X(unit)) {
   5489                     /* TD3 can not support egr_qos_combo_profile, but it needs
   5490                        to program the same port reference pointer */
   5491                     if ((egr_map >> _BCM_QOS_MAP_SHIFT) == _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) {
   5492                         id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   5493                         index = QOS_INFO(unit)->egr_mpls_hw_idx[id];
   5494                         rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_DOT1P_PROFILE_INDEXf, index);
   5495                         if (BCM_FAILURE(rv)) {
   5496                             soc_cm_sfree(unit, buf);
   5497                             QOS_UNLOCK(unit);
   5498                             return rv;
   5499                         }
   5500                     } else if ((egr_map >> _BCM_QOS_MAP_SHIFT) == _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE) {
   5501                         id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   5502                         index = QOS_INFO(unit)->egr_dscp_hw_idx[id];
   5503                         rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_QOS_PROFILE_INDEXf, index);
   5504                         if (BCM_FAILURE(rv)) {
   5505                             soc_cm_sfree(unit, buf);
   5506                             QOS_UNLOCK(unit);
   5507                             return rv;
   5508                         }
   5509                     }
   5510                 } else
   5511 #endif
   5512                 {
   5513                     /* Copy the corresponding chunk from EGR_MPLS profiles to the 
   5514                      * EGR_PRI_CNG_MAP table, which is directly indexed by port */
   5515                     buf2 = soc_cm_salloc(unit, alloc_size, "TR2 egr mpls exp map");
   5516                     if (NULL == buf2) {
   5517                         soc_cm_sfree(unit, buf);
   5518                         QOS_UNLOCK(unit);
   5519                         return (BCM_E_MEMORY);
   5520                     }
   5521                     sal_memset(buf2, 0, alloc_size);
   5522                     index = (QOS_INFO(unit)->egr_mpls_hw_idx[id] * 
   5523                              _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   5524 
   5525                     if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) {
   5526                         source_mem = EGR_MPLS_EXP_MAPPING_1m;
   5527                         new_pri_field = PRIf;
   5528                         new_cfi_field = CFIf;
   5529                     } else {
   5530                         source_mem = EGR_MPLS_PRI_MAPPINGm;
   5531                         new_pri_field = NEW_PRIf;
   5532                         new_cfi_field = NEW_CFIf;
   5533                     }
   5534                     rv = soc_mem_read_range(unit, source_mem,	
   5535                                             MEM_BLOCK_ANY, index, index + 63, 
   5536                                             (void *)buf2);
   5537                     if (BCM_FAILURE(rv)) {
   5538                         soc_cm_sfree(unit, buf);
   5539                         soc_cm_sfree(unit, buf2);
   5540                         QOS_UNLOCK(unit);
   5541                         return rv;
   5542                     }
   5543                     for (index = 0; index < _BCM_QOS_MAP_CHUNK_EGR_MPLS; index++) {
   5544                         entries[0] = soc_mem_table_idx_to_pointer(unit, 
   5545                                                           source_mem, 
   5546                                                           void *, buf2, index);
   5547                         pri = soc_mem_field32_get(unit, source_mem, 
   5548                                                   entries[0], new_pri_field);
   5549                         cfi = soc_mem_field32_get(unit, source_mem, 
   5550                                                   entries[0], new_cfi_field);
   5551                         entries[0] = soc_mem_table_idx_to_pointer(unit, 
   5552                                                   EGR_PRI_CNG_MAPm, 
   5553                                                   void *, buf, index);
   5554                         soc_mem_field32_set(unit, EGR_PRI_CNG_MAPm, 
   5555                                             entries[0], PRIf, pri);
   5556                         soc_mem_field32_set(unit, EGR_PRI_CNG_MAPm, 
   5557                                             entries[0], CFIf, cfi);
   5558                     } 
   5559 
   5560                     index = port << 6;
   5561                     rv = soc_mem_write_range(unit, EGR_PRI_CNG_MAPm, MEM_BLOCK_ALL, 
   5562                                              index, index + 63, (void *)buf);
   5563                     if (BCM_FAILURE(rv)) {
   5564                         soc_cm_sfree(unit, buf);
   5565                         soc_cm_sfree(unit, buf2);
   5566                         QOS_UNLOCK(unit);
   5567                         return rv;
   5568                     }
   5569                     soc_cm_sfree(unit, buf2);
   5570                 } 
   5571                 if ((egr_map >> _BCM_QOS_MAP_SHIFT) == _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) {
   5572                     if ( SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   5573                          (SOC_IS_TD_TT(unit) && !SOC_IS_TOMAHAWK3(unit))) {
   5574 
   5575                         /*  Add IPRI_MAPPING_PTR to EGR_VLAN_CONTROL_3 register for
   5576                          *  inner vlan priority remarking to access appropriate
   5577                          *  index from EGR_MPLS_EXP_MAPPING_2m table.
   5578                          */
   5579                         index = QOS_INFO(unit)->egr_mpls_hw_idx[id];
   5580                         rv = _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_set(unit, port, index);  
   5581 
   5582                         if (BCM_FAILURE(rv)) {
   5583                             soc_cm_sfree(unit, buf);
   5584                             QOS_UNLOCK(unit);
   5585                             return rv;
   5586                         }
   5587                     }
   5588                 }
   5589             }
   5590             soc_cm_sfree(unit, buf);
   5591         }
   5592     }
   5593 #ifdef BCM_WARM_BOOT_SUPPORT
   5594     SOC_CONTROL_LOCK(unit);
   5595     SOC_CONTROL(unit)->scache_dirty = 1;
   5596     SOC_CONTROL_UNLOCK(unit);
   5597 #endif
   5598     QOS_UNLOCK(unit);
   5599     return rv;
   5600 }
   5601 
   5602 
   5603 
   5604 int
   5605 bcm_tr2_qos_port_map_type_get(int unit, bcm_gport_t port, uint32 flags,
   5606                               int *map_id)
   5607 {
   5608     int rv = BCM_E_NONE;
   5609     uint32 rval = 0;
   5610     int32 profile_idx = -1;
   5611     int32 trust_dscp_v4 = 0;
   5612     int32 trust_dscp_v6 = 0;
   5613     int32 use_profile;
   5614 #ifdef INCLUDE_L3
   5615     source_vp_entry_t svp;
   5616     egr_wlan_dvp_entry_t wlan_dvp;
   5617     uint32 tnl_entry[SOC_MAX_MEM_FIELD_WORDS];
   5618     int tunnel, vp, encap_id, nhi, l3_iif = 0;
   5619     int tunnel_id_max, tunnel_count;
   5620     egr_l3_next_hop_entry_t egr_nh;
   5621     soc_field_t dot1p_pri_select_field=0;
   5622     soc_field_t dot1p_mapping_ptr_field=0;
   5623     int l3_nh_entry_type = 0;
   5624     int vc_swap_idx;
   5625     egr_mpls_vc_and_swap_label_table_entry_t vc_swap_entry;
   5626     _bcm_vp_info_t vp_info;
   5627 #endif
   5628     int index;
   5629     int alloc_size;
   5630     void *entries[1];
   5631     soc_mem_t source_mem = INVALIDm;
   5632     soc_field_t new_pri_field = 0;
   5633     soc_field_t new_cfi_field = 0;
   5634     int id, num_map;
   5635     uint8 pri, cfi, new_pri, new_cfi;
   5636     char *buf, *buf2;
   5637 
   5638     if (map_id == NULL) {
   5639         return BCM_E_PARAM;
   5640     }
   5641 
   5642     flags &= (~(BCM_QOS_MAP_WITH_ID | BCM_QOS_MAP_REPLACE));
   5643 
   5644     QOS_INIT(unit);
   5645     QOS_LOCK(unit);
   5646 
   5647 #ifdef INCLUDE_L3
   5648     if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&
   5649         !BCM_GPORT_IS_LOCAL(port)) {
   5650 
   5651 #if defined(BCM_TOMAHAWK3_SUPPORT)
   5652         if (SOC_IS_TOMAHAWK3(unit) && !BCM_GPORT_IS_TUNNEL(port)) {
   5653             QOS_UNLOCK(unit);
   5654             return BCM_E_PARAM;
   5655         }
   5656 #endif /* BCM_TOMAHAWK3_SUPPORT */
   5657 
   5658         /* Deal with different types of gports */
   5659         if (_BCM_QOS_GPORT_IS_VFI_VP_PORT(port) ||
   5660             BCM_GPORT_IS_VLAN_PORT(port) ||
   5661             BCM_GPORT_IS_NIV_PORT(port) ||
   5662             BCM_GPORT_IS_EXTENDER_PORT(port)) {
   5663             /* Deal with MiM and MPLS ports */
   5664             if (BCM_GPORT_IS_VLAN_PORT(port)) {
   5665                 vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
   5666                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
   5667                     QOS_UNLOCK(unit);
   5668                     return BCM_E_BADID;
   5669                 }
   5670             } else if (BCM_GPORT_IS_MIM_PORT(port)) {
   5671                 vp = BCM_GPORT_MIM_PORT_ID_GET(port);
   5672                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
   5673                     QOS_UNLOCK(unit);
   5674                     return BCM_E_BADID;
   5675                 }
   5676             } else if BCM_GPORT_IS_VXLAN_PORT(port) {
   5677                 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
   5678                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) {
   5679                     QOS_UNLOCK(unit);
   5680                     return BCM_E_BADID;
   5681                 }
   5682             } else if BCM_GPORT_IS_L2GRE_PORT(port) {
   5683                 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
   5684                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) {
   5685                     QOS_UNLOCK(unit);
   5686                     return BCM_E_BADID;
   5687                 }
   5688             } else if (BCM_GPORT_IS_EXTENDER_PORT(port)) {
   5689                 vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port);
   5690                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) {
   5691                     QOS_UNLOCK(unit);
   5692                     return BCM_E_BADID;
   5693                 }
   5694             } else if (BCM_GPORT_IS_NIV_PORT(port)) {
   5695                 vp = BCM_GPORT_NIV_PORT_ID_GET(port);
   5696                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) {
   5697                     QOS_UNLOCK(unit);
   5698                     return BCM_E_BADID;
   5699                 }
   5700             } else {
   5701                 vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
   5702                 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
   5703                     QOS_UNLOCK(unit);
   5704                     return BCM_E_BADID;
   5705                 }
   5706             }
   5707 
   5708             if ((flags & BCM_QOS_MAP_INGRESS) == BCM_QOS_MAP_INGRESS) {
   5709                 flags &= ~BCM_QOS_MAP_INGRESS;
   5710                 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp);
   5711                 if (BCM_FAILURE(rv)) {
   5712                     QOS_UNLOCK(unit);
   5713                     return rv;
   5714                 }
   5715 
   5716                 if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) {
   5717                     flags &= ~BCM_QOS_MAP_L2;
   5718                     profile_idx = soc_SOURCE_VPm_field32_get(unit,
   5719                                       &svp, TRUST_DOT1P_PTRf);
   5720                     rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   5721                             _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, map_id);
   5722                 } else if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) {
   5723                     flags &= ~BCM_QOS_MAP_L3;
   5724                     if (soc_mem_field_valid(unit, SOURCE_VPm, TRUST_DSCP_V4f)) {
   5725                        trust_dscp_v4 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V4f);
   5726                     }
   5727                     if (soc_mem_field_valid(unit, SOURCE_VPm, TRUST_DSCP_V6f)) {
   5728                         trust_dscp_v6 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V6f);
   5729                     }
   5730                     /* if DSCP trust enabled */
   5731                     if ((trust_dscp_v4 != 0) || (trust_dscp_v6 != 0)) {
   5732                         if (soc_mem_field_valid(unit, SOURCE_VPm, TRUST_DSCP_PTRf)) {
   5733                             profile_idx = soc_SOURCE_VPm_field32_get(unit, &svp,
   5734                                             TRUST_DSCP_PTRf);
   5735                             rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   5736                                     _BCM_QOS_MAP_TYPE_DSCP_TABLE, map_id);
   5737                         } else {
   5738                             rv = BCM_E_INTERNAL;
   5739                         }
   5740                     } else {
   5741                         rv = BCM_E_NOT_FOUND;
   5742                     }
   5743                 } else {
   5744                     rv = BCM_E_PARAM;
   5745                 }
   5746                 /* invalid flags */
   5747                 if (flags) {
   5748                     rv = BCM_E_PARAM;
   5749                 }
   5750                 /* could return with map_id now */
   5751                 QOS_UNLOCK(unit);
   5752                 return rv;
   5753             } else if ((flags & BCM_QOS_MAP_EGRESS) == BCM_QOS_MAP_EGRESS) {
   5754                 flags &= ~BCM_QOS_MAP_EGRESS;
   5755                 if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) {
   5756                     flags &= ~BCM_QOS_MAP_L2;
   5757 
   5758                     /* SD_TAG::DOT1P_MAPPING_PTR from EGR_L3_NEXT_HOP */
   5759                     if (BCM_GPORT_IS_MIM_PORT(port)) {
   5760                         rv = bcm_tr2_multicast_mim_encap_get(unit, 0, 0, port,
   5761                                                              &encap_id);
   5762                     } else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
   5763                         rv = bcm_esw_multicast_vxlan_encap_get(unit, 0, 0, port,
   5764                                                                &encap_id);
   5765                     } else {
   5766                         rv = bcm_tr2_multicast_vpls_encap_get(unit, 0, 0, port,
   5767                                                               &encap_id);
   5768                     }
   5769                     if (BCM_FAILURE(rv)) {
   5770                         QOS_UNLOCK(unit);
   5771                         return rv;
   5772                     }
   5773 #if defined(BCM_ENDURO_SUPPORT)
   5774                     if (SOC_IS_ENDURO(unit) && BCM_GPORT_IS_MIM_PORT(port)) {
   5775                         nhi = encap_id;
   5776                     } else
   5777 #endif /* BCM_ENDURO_SUPPORT */
   5778                     {
   5779                         nhi = encap_id - BCM_XGS3_DVP_EGRESS_IDX_MIN(unit);
   5780                     }
   5781                     rv = soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY,
   5782                                       nhi, &egr_nh);
   5783                     if (BCM_FAILURE(rv)) {
   5784                         QOS_UNLOCK(unit);
   5785                         return rv;
   5786                     }
   5787 
   5788                     if (BCM_GPORT_IS_MPLS_PORT(port)) {
   5789                         l3_nh_entry_type = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm,
   5790                                                &egr_nh, nh_entry_type_field[unit]);
   5791                     }
   5792 
   5793                     if (BCM_GPORT_IS_MPLS_PORT(port) &&
   5794                         (l3_nh_entry_type == 0x1)) {
   5795                         if (soc_feature(unit, soc_feature_mpls_enhanced)) {
   5796                              vc_swap_idx = soc_EGR_L3_NEXT_HOPm_field32_get(
   5797                                               unit, &egr_nh,
   5798                                               MPLS__VC_AND_SWAP_INDEXf);
   5799                         } else {
   5800                              vc_swap_idx = soc_EGR_L3_NEXT_HOPm_field32_get(
   5801                                               unit, &egr_nh,
   5802                                               VC_AND_SWAP_INDEXf);
   5803                         }
   5804                         if (vc_swap_idx > 0) {
   5805                             rv = soc_mem_read(unit,
   5806                                               EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
   5807                                               MEM_BLOCK_ANY, vc_swap_idx,
   5808                                               &vc_swap_entry);
   5809                             if (rv < 0) {
   5810                                 QOS_UNLOCK(unit);
   5811                                 return rv;
   5812                             }
   5813                             if (soc_mem_field_valid(unit,
   5814                                 EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
   5815                                 SD_TAG_DOT1P_PRI_SELECTf)) {
   5816                                 use_profile =
   5817                                     soc_mem_field32_get(
   5818                                         unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
   5819                                         &vc_swap_entry,
   5820                                         SD_TAG_DOT1P_PRI_SELECTf);
   5821                                 if (use_profile == 1) {
   5822                                     profile_idx = soc_mem_field32_get(
   5823                                         unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm,
   5824                                         &vc_swap_entry,
   5825                                         SD_TAG_DOT1P_MAPPING_PTRf);
   5826                                     rv = _bcm_tr2_qos_idx2id(
   5827                                             unit, profile_idx,
   5828                                             _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS,
   5829                                             map_id);
   5830                                 } else {
   5831                                     rv = BCM_E_NOT_FOUND;
   5832                                 }
   5833                             }
   5834                         }
   5835                     } else {
   5836                         /*
   5837                          * For Katana chip, bit position for DOT1P_PRI_SELECT and
   5838                          * DOT1P_MAPPING_PTR fields are different in MIM and SD_TAG
   5839                          * views.
   5840                          */
   5841                         if (BCM_GPORT_IS_MIM_PORT(port) &&
   5842                             ((MIM_INFO(unit)->port_info[vp].flags &
   5843                             _BCM_MIM_PORT_TYPE_NETWORK) ||
   5844                             (MIM_INFO(unit)->port_info[vp].flags &
   5845                             _BCM_MIM_PORT_TYPE_PEER))) {
   5846                             if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm,
   5847                                                     MIM__DOT1P_PRI_SELECTf) &&
   5848                                 soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm,
   5849                                                     MIM__DOT1P_MAPPING_PTRf)) {
   5850                                 dot1p_pri_select_field = MIM__DOT1P_PRI_SELECTf;
   5851                                 dot1p_mapping_ptr_field =
   5852                                     MIM__DOT1P_MAPPING_PTRf;
   5853                             } else {
   5854                                 QOS_UNLOCK(unit);
   5855                                 return BCM_E_INTERNAL;
   5856                             }
   5857                         } else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
   5858                             rv = _bcm_vp_info_get(unit, vp, &vp_info);
   5859                             if (rv < 0) {
   5860                                 QOS_UNLOCK(unit);
   5861                                 return rv;
   5862                             }
   5863                             if (!(vp_info.flags & _BCM_VP_INFO_NETWORK_PORT)) {
   5864                                 dot1p_pri_select_field =
   5865                                     SD_TAG__SD_TAG_DOT1P_PRI_SELECTf;
   5866                                 dot1p_mapping_ptr_field =
   5867                                     SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf;
   5868                             } else {
   5869                                 QOS_UNLOCK(unit);
   5870                                 return BCM_E_PARAM;
   5871                             }
   5872                         } else {
   5873                             dot1p_pri_select_field =
   5874                                 SD_TAG__SD_TAG_DOT1P_PRI_SELECTf;
   5875                             dot1p_mapping_ptr_field =
   5876                                 SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf;
   5877                         }
   5878 
   5879                         use_profile = soc_mem_field32_get(
   5880                                          unit, EGR_L3_NEXT_HOPm, &egr_nh,
   5881                                          dot1p_pri_select_field);
   5882                         if (use_profile == 1) {
   5883                             profile_idx = soc_mem_field32_get(
   5884                                              unit, EGR_L3_NEXT_HOPm, &egr_nh,
   5885                                              dot1p_mapping_ptr_field);
   5886                             rv = _bcm_tr2_qos_idx2id(
   5887                                     unit, profile_idx,
   5888                                     _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, map_id);
   5889                         } else {
   5890                             rv = BCM_E_NOT_FOUND;
   5891                         }
   5892                     }
   5893                 }else {
   5894                     rv = BCM_E_PARAM;
   5895                 }
   5896                 /* invalid flags */
   5897                 if (flags) {
   5898                     rv = BCM_E_PARAM;
   5899                 }
   5900 
   5901                 QOS_UNLOCK(unit);
   5902                 return rv;
   5903             } else {
   5904                 QOS_UNLOCK(unit);
   5905                 rv = BCM_E_PARAM;
   5906                 return rv;
   5907             }
   5908         } else if (BCM_GPORT_IS_WLAN_PORT(port)) {
   5909             /* Deal with WLAN ports */
   5910             vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
   5911             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) {
   5912                 QOS_UNLOCK(unit);
   5913                 return BCM_E_BADID;
   5914             }
   5915 
   5916             if ((flags & BCM_QOS_MAP_INGRESS) == BCM_QOS_MAP_INGRESS) {
   5917                 flags &= ~BCM_QOS_MAP_INGRESS;
   5918 
   5919                 if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) {
   5920                     flags &= ~BCM_QOS_MAP_L2;
   5921 #if defined(BCM_TRIUMPH3_SUPPORT)
   5922                     if (SOC_IS_TRIUMPH3(unit)) {
   5923                         rv = bcm_tr3_wlan_lport_field_get(unit, port,
   5924                                  TRUST_DOT1P_PTRf, &profile_idx);
   5925                     } else
   5926 #endif /* BCM_TRIUMPH3_SUPPORT */
   5927                     {
   5928                         rv = bcm_tr2_wlan_lport_field_get(unit, port,
   5929                                  TRUST_DOT1P_PTRf, &profile_idx);
   5930                     }
   5931                     if (BCM_FAILURE(rv)) {
   5932                         QOS_UNLOCK(unit);
   5933                         return rv;
   5934                     }
   5935 
   5936                     rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   5937                              _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, map_id);
   5938                 } else {
   5939                     rv = BCM_E_PARAM;
   5940                 }
   5941 
   5942                 if (flags) {
   5943                     rv = BCM_E_PARAM;
   5944                 }
   5945 
   5946                 QOS_UNLOCK(unit);
   5947                 return rv;
   5948             } else if ((flags & BCM_QOS_MAP_EGRESS) == BCM_QOS_MAP_EGRESS){
   5949                 flags &= ~BCM_QOS_MAP_EGRESS;
   5950 
   5951                 if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) {
   5952                     flags &= ~BCM_QOS_MAP_L2;
   5953 
   5954 #if defined(BCM_TRIUMPH3_SUPPORT)
   5955                     if (SOC_IS_TRIUMPH3(unit)) {
   5956                         /* not support */
   5957                         rv = BCM_E_UNAVAIL;
   5958                         QOS_UNLOCK(unit);
   5959                         return rv;
   5960                     } else
   5961 #endif /* BCM_TRIUMPH3_SUPPORT */
   5962                     {
   5963                         /*
   5964                          * EGR_WLAN_DVP.TUNNEL_INDEX points to CAPWAP initiator.
   5965                          * EGR_IP_TUNNEL.DOT1P_MAPPING_PTR contains the map
   5966                          */
   5967                         rv = READ_EGR_WLAN_DVPm(unit, MEM_BLOCK_ANY, vp, &wlan_dvp);
   5968                         if (BCM_FAILURE(rv)) {
   5969                             QOS_UNLOCK(unit);
   5970                             return rv;
   5971                         }
   5972                         tunnel = soc_EGR_WLAN_DVPm_field32_get(unit, &wlan_dvp,
   5973                                                                TUNNEL_INDEXf);
   5974                         rv = soc_mem_read(unit, EGR_IP_TUNNELm, MEM_BLOCK_ANY,
   5975                                           tunnel, tnl_entry);
   5976                         if (BCM_FAILURE(rv)) {
   5977                             QOS_UNLOCK(unit);
   5978                             return rv;
   5979                         }
   5980                         use_profile = soc_mem_field32_get(unit, EGR_IP_TUNNELm,
   5981                                           tnl_entry, DOT1P_PRI_SELECTf);
   5982                         if (use_profile) {
   5983                             profile_idx = soc_mem_field32_get(unit, EGR_IP_TUNNELm,
   5984                                               tnl_entry, DOT1P_MAPPING_PTRf);
   5985                             rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   5986                                      _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, map_id);
   5987                         } else {
   5988                             rv = BCM_E_NOT_FOUND;
   5989                         }
   5990                     }
   5991                 } else {
   5992                     rv = BCM_E_PARAM;
   5993                 }
   5994 
   5995                 if (flags) {
   5996                     rv = BCM_E_PARAM;
   5997                 }
   5998 
   5999                 QOS_UNLOCK(unit);
   6000                 return rv;
   6001             } else {
   6002                 rv = BCM_E_PARAM;
   6003                 QOS_UNLOCK(unit);
   6004                 return rv;
   6005             }
   6006         } else if (BCM_GPORT_IS_TUNNEL(port)) {
   6007             /* Deal with tunnel initiators and terminators */
   6008             tunnel = BCM_GPORT_TUNNEL_ID_GET(port);
   6009             if ((flags & BCM_QOS_MAP_INGRESS) == BCM_QOS_MAP_INGRESS) {
   6010                 flags &= ~BCM_QOS_MAP_INGRESS;
   6011 
   6012                 if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) {
   6013                     flags &= ~BCM_QOS_MAP_L3;
   6014 
   6015                     if (SOC_MEM_FIELD_VALID(unit, L3_TUNNELm, TUNNEL_IDf)) {
   6016                     /*
   6017                      * Get L3_IIF from L3_TUNNEL.
   6018                      * Get TRUST_DSCP_PTR from L3_IIF
   6019                      */
   6020                     tunnel_id_max = soc_mem_index_max(unit, L3_TUNNELm);
   6021                     tunnel_count = soc_mem_index_count(unit, L3_TUNNELm);
   6022                     alloc_size = tunnel_count * sizeof(tnl_entry);
   6023                     buf = soc_cm_salloc(unit, alloc_size, "TR2 L3 TUNNEL");
   6024                     if (NULL == buf) {
   6025                         QOS_UNLOCK(unit);
   6026                         return (BCM_E_MEMORY);
   6027                     }
   6028                     rv = soc_mem_read_range(unit, L3_TUNNELm, MEM_BLOCK_ANY,
   6029                                             0, tunnel_id_max, (void *)buf);
   6030                     if (BCM_FAILURE(rv)) {
   6031                         soc_cm_sfree(unit, buf);
   6032                         QOS_UNLOCK(unit);
   6033                         return rv;
   6034                     }
   6035 
   6036                         for (index = 0; index < tunnel_id_max; index++) {
   6037                             entries[0] = soc_mem_table_idx_to_pointer(unit, L3_TUNNELm,
   6038                                                                       void *, buf,
   6039                                                                       index);
   6040                             if (tunnel == soc_mem_field32_get(unit, L3_TUNNELm,
   6041                                               entries[0], TUNNEL_IDf)) {
   6042                                 /* Tunnel found - get L3_IIF */
   6043                                 l3_iif = soc_mem_field32_get(unit, L3_TUNNELm,
   6044                                                              entries[0], L3_IIFf);
   6045                                 break;
   6046                             }
   6047                         }
   6048 
   6049                     soc_cm_sfree(unit, buf);
   6050                     if (index == tunnel_id_max) {
   6051                         QOS_UNLOCK(unit);
   6052                         return BCM_E_NOT_FOUND; /* Tunnel not found */
   6053                     }
   6054                     } else {
   6055                         index = tunnel;
   6056                     }
   6057 
   6058                     if (soc_mem_field_valid(unit, L3_IIFm, TRUST_DSCP_PTRf)) {
   6059                         profile_idx = soc_mem_field32_get(unit, L3_IIFm, &l3_iif,
   6060                                           TRUST_DSCP_PTRf);
   6061                         rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   6062                                  _BCM_QOS_MAP_TYPE_DSCP_TABLE, map_id);
   6063                     }
   6064 
   6065 #ifdef BCM_TRIDENT2_SUPPORT
   6066                     if (SOC_IS_TD2_TT2(unit)) { /* Get l3 iif profile entry */
   6067                         uint32 l3_index;
   6068                         void *entries[1];
   6069                         iif_profile_entry_t l3_iif_profile;
   6070                         iif_entry_t entry;
   6071                         entries[0] = &l3_iif_profile;
   6072 
   6073                         /* Read interface config from hw. */
   6074                         rv = soc_mem_read(unit, L3_IIFm, MEM_BLOCK_ANY, l3_iif,
   6075                                          (uint32 *)&entry);
   6076                         if (BCM_SUCCESS(rv)) {
   6077                             l3_index = soc_mem_field32_get(unit, L3_IIFm,
   6078                                            (uint32 *)&entry, L3_IIF_PROFILE_INDEXf);
   6079                             rv = _bcm_l3_iif_profile_entry_get(unit,
   6080                                      l3_index, 1, entries);
   6081 
   6082                             if (BCM_SUCCESS(rv)) {
   6083                                 profile_idx = soc_mem_field32_get(unit, L3_IIF_PROFILEm,
   6084                                                   &l3_iif_profile, TRUST_DSCP_PTRf);
   6085                                 rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   6086                                           _BCM_QOS_MAP_TYPE_DSCP_TABLE, map_id);
   6087                             }
   6088                         }
   6089                     }
   6090 #endif /* BCM_TRIDENT2_SUPPORT */
   6091 
   6092                 } else {
   6093                     rv = BCM_E_PARAM;
   6094                 }
   6095 
   6096                 if (flags) {
   6097                     rv = BCM_E_PARAM;
   6098                 }
   6099 
   6100                 QOS_UNLOCK(unit);
   6101                 return rv;
   6102             } else if ((flags & BCM_QOS_MAP_EGRESS) == BCM_QOS_MAP_EGRESS) {
   6103                 flags &= ~BCM_QOS_MAP_EGRESS;
   6104 
   6105                 if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) {
   6106                     flags &= ~BCM_QOS_MAP_L3;
   6107                     /* DSCP_MAPPING_PTR from EGR_IP_TUNNEL */
   6108                     rv = soc_mem_read(unit, EGR_IP_TUNNELm, MEM_BLOCK_ANY,
   6109                                       tunnel, tnl_entry);
   6110                     if (rv < 0) {
   6111                         QOS_UNLOCK(unit);
   6112                         return rv;
   6113                     }
   6114 
   6115                     use_profile = soc_mem_field32_get(unit, EGR_IP_TUNNELm,
   6116                                       tnl_entry, DSCP_SELf);
   6117                     if (use_profile == 2) {
   6118                         profile_idx = soc_mem_field32_get(unit, EGR_IP_TUNNELm,
   6119                                           tnl_entry, DSCP_MAPPING_PTRf);
   6120                         rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   6121                                  _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE, map_id);
   6122                     } else {
   6123                         rv = BCM_E_NOT_FOUND;
   6124                     }
   6125                 } else {
   6126                     rv = BCM_E_PARAM;
   6127                 }
   6128 
   6129                 if (flags) {
   6130                     rv = BCM_E_PARAM;
   6131                 }
   6132 
   6133                 QOS_UNLOCK(unit);
   6134                 return rv;
   6135             } else {
   6136                 rv = BCM_E_PARAM;
   6137                 QOS_UNLOCK(unit);
   6138                 return rv;
   6139             }
   6140         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
   6141 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(BCM_HGPROXY_COE_SUPPORT)
   6142             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   6143                 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   6144                 if ((flags & BCM_QOS_MAP_INGRESS) == BCM_QOS_MAP_INGRESS) {
   6145                     flags &= ~BCM_QOS_MAP_INGRESS;
   6146 
   6147                     if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) {
   6148                         flags &= ~BCM_QOS_MAP_L2;
   6149                         rv = _bcm_esw_port_tab_get(unit, port,
   6150                                                   TRUST_DOT1P_PTRf,
   6151                                                   &profile_idx);
   6152                         if (BCM_FAILURE(rv)) {
   6153                             QOS_UNLOCK(unit);
   6154                             return rv;
   6155                         }
   6156                         rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   6157                                  _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, map_id);
   6158                     } else {
   6159                         rv = BCM_E_PARAM;
   6160                     }
   6161 
   6162                     if (flags) {
   6163                         /*more flags that could not be handled*/
   6164                         rv = BCM_E_PARAM;
   6165                     }
   6166                     /*could return with map_id now*/
   6167                     QOS_UNLOCK(unit);
   6168                     return rv;
   6169                 } else if ((flags & BCM_QOS_MAP_EGRESS) == BCM_QOS_MAP_EGRESS) {
   6170                     flags &= ~BCM_QOS_MAP_EGRESS;
   6171                     if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) {
   6172                         flags &= ~BCM_QOS_MAP_L3;
   6173                         if (soc_feature(unit, soc_feature_egr_qos_combo_profile) ||
   6174                             SOC_IS_TRIDENT3X(unit)) {
   6175                             /* TRIDENT 3 programs same port index pointer
   6176                                without feature combo_profile */
   6177                             rv = _bcm_esw_egr_port_tab_get(unit, port,
   6178                                                           EGR_QOS_PROFILE_INDEXf,
   6179                                                           &profile_idx);
   6180                             if (BCM_FAILURE(rv)) {
   6181                                 QOS_UNLOCK(unit);
   6182                                 return rv;
   6183                             }
   6184                             rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   6185                                      _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE, map_id);
   6186                         }
   6187                     } else {
   6188                         rv = BCM_E_PARAM;
   6189                     }
   6190                     /*invalid flags*/
   6191                     if (flags) {
   6192                         rv = BCM_E_PARAM;
   6193                     }
   6194 
   6195                     QOS_UNLOCK(unit);
   6196                     return rv;
   6197                 } else {
   6198                     QOS_UNLOCK(unit);
   6199                     rv = BCM_E_PARAM;
   6200                     return rv;
   6201                 }
   6202             }
   6203 #endif
   6204         } else {
   6205             QOS_UNLOCK(unit);
   6206             rv = BCM_E_PARAM;
   6207             return rv;
   6208         }
   6209 
   6210     } else
   6211 #endif
   6212     {
   6213         /* Deal with physical ports */
   6214         if (BCM_GPORT_IS_SET(port)) {
   6215             if (bcm_esw_port_local_get(unit, port, &port) < 0) {
   6216                 QOS_UNLOCK(unit);
   6217                 return BCM_E_PARAM;
   6218             }
   6219         }
   6220         if (!SOC_PORT_VALID(unit, port)) {
   6221             QOS_UNLOCK(unit);
   6222             return BCM_E_PARAM;
   6223         }
   6224 
   6225         if ((flags & BCM_QOS_MAP_INGRESS) == BCM_QOS_MAP_INGRESS) {
   6226             flags &= ~BCM_QOS_MAP_INGRESS;
   6227 
   6228             if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) {
   6229                 flags &= ~BCM_QOS_MAP_L2;
   6230                 if (SOC_IS_TRIDENT3X(unit)) {
   6231                     rv = _bcm_esw_port_tab_get(unit, port, TRUST_DOT1P_PTRf, &profile_idx);
   6232                 } else {
   6233                     rv = _bcm_tr2_port_tab_get(unit, port, TRUST_DOT1P_PTRf, &profile_idx);
   6234                 }
   6235                 if (BCM_FAILURE(rv)) {
   6236                     QOS_UNLOCK(unit);
   6237                     return rv;
   6238                 }
   6239                 rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   6240                          _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, map_id);
   6241             } else if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) {
   6242                 flags &= ~BCM_QOS_MAP_L3;
   6243 
   6244                 if (SOC_IS_KATANA(unit)) {
   6245                     rv = _bcm_tr2_port_tab_get(unit, port, TRUST_DSCP_PTRf, &profile_idx);
   6246                 } else if (soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_PTRf)) {
   6247                     rv = _bcm_tr2_port_tab_get(unit, port, TRUST_DSCP_PTRf,
   6248                                                &profile_idx);
   6249                 } else if (SOC_IS_TRIDENT3X(unit)) {
   6250                     rv = _bcm_esw_port_tab_get(unit, port, TRUST_DSCP_PTRf, &profile_idx);
   6251                 } else if (SOC_IS_TRIDENT(unit)) {
   6252                     rv = BCM_E_UNAVAIL;
   6253                 }
   6254 
   6255                 if (BCM_SUCCESS(rv) &&
   6256                     soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V4f)) {
   6257                         rv = _bcm_tr2_port_tab_get(unit, port,
   6258                                  TRUST_DSCP_V4f, &trust_dscp_v4);
   6259                 }
   6260                 if (BCM_SUCCESS(rv) &&
   6261                     soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V6f)) {
   6262                         rv = _bcm_tr2_port_tab_get(unit, port,
   6263                                  TRUST_DSCP_V6f, &trust_dscp_v6);
   6264                 }
   6265 
   6266                 /* if DSCP trust enabled */
   6267                 if (BCM_SUCCESS(rv)){
   6268                     if (SOC_IS_TRIDENT3X(unit)) {
   6269                        rv = _bcm_esw_port_tab_get(unit, port, TRUST_DSCP_V4f, &trust_dscp_v4);
   6270                        if (BCM_FAILURE(rv)) {
   6271                             QOS_UNLOCK(unit);
   6272                             return rv;
   6273                         }
   6274 
   6275                        rv = _bcm_esw_port_tab_get(unit, port, TRUST_DSCP_V6f, &trust_dscp_v6);
   6276                        if (BCM_FAILURE(rv)) {
   6277                             QOS_UNLOCK(unit);
   6278                             return rv;
   6279                        }
   6280                     }
   6281 
   6282                     if ((trust_dscp_v4 != 0) || (trust_dscp_v6 != 0)) {
   6283                         rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   6284                                                  _BCM_QOS_MAP_TYPE_DSCP_TABLE,
   6285                                                  map_id);
   6286                     } else {
   6287                       rv = BCM_E_NOT_FOUND;
   6288                     }
   6289                 }
   6290             }
   6291 
   6292 #ifdef BCM_HURRICANE3_SUPPORT
   6293             else if ((flags & BCM_QOS_MAP_MIML) == BCM_QOS_MAP_MIML) {
   6294                 flags &= ~BCM_QOS_MAP_MIML;
   6295 
   6296                 if (!soc_feature(unit, soc_feature_miml)) {
   6297                     QOS_UNLOCK(unit);
   6298                     return BCM_E_PARAM;
   6299                 }
   6300                 rv = _bcm_tr2_port_tab_get(unit, port, MIML_DOT1P_MAPPING_PTRf,
   6301                                            &profile_idx);
   6302                 if (BCM_SUCCESS(rv)){
   6303                     rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   6304                              _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP, map_id);
   6305                 }
   6306             }
   6307 #endif
   6308             else {
   6309                 rv = BCM_E_PARAM;
   6310             }
   6311 
   6312             if (flags) {
   6313                 /*more flags that could not be handled*/
   6314                 rv = BCM_E_PARAM;
   6315             }
   6316             /*could return with map_id now*/
   6317             QOS_UNLOCK(unit);
   6318             return rv;
   6319         } else if ((flags & BCM_QOS_MAP_EGRESS) == BCM_QOS_MAP_EGRESS) {
   6320             flags &= ~BCM_QOS_MAP_EGRESS;
   6321             if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) {
   6322                 flags &= ~BCM_QOS_MAP_L2;
   6323 
   6324 #if defined(BCM_TOMAHAWK3_SUPPORT)
   6325                 if (SOC_IS_TOMAHAWK3(unit)) {
   6326                     /* EGR_PRI_CNG_MAPm will be searched if rv = NOT_FOUND */
   6327                     rv = BCM_E_NOT_FOUND;
   6328                 } else
   6329 #endif
   6330                 if ( SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
   6331                                                           SOC_IS_TD_TT(unit)) {
   6332 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   6333                     if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   6334                         egr_vlan_control_3_entry_t entry;
   6335                         uint32 values[2];
   6336                         soc_field_t fields[2];
   6337 
   6338                         fields[0] = IPRI_MAPPING_PTRf;
   6339                         fields[1] = IPRI_CFI_SELf;
   6340 
   6341                         if (SOC_IS_TRIDENT3X(unit)) {
   6342                             rv = bcm_esw_port_egr_lport_fields_get(unit, port, EGR_VLAN_CONTROL_3m,
   6343                                                                    2, fields, values);
   6344                             if (BCM_FAILURE(rv)) {
   6345                                 QOS_UNLOCK(unit);
   6346                                 return rv;
   6347                             }
   6348                             profile_idx = values[0];
   6349                             use_profile = values[1];
   6350                         } else {
   6351                             rv = READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port,
   6352                                                       &entry);
   6353                             if (BCM_FAILURE(rv)) {
   6354                                 QOS_UNLOCK(unit);
   6355                                 return rv;
   6356                             }
   6357 
   6358                             profile_idx = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m,
   6359                                                               &entry, IPRI_MAPPING_PTRf);
   6360                             use_profile = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m,
   6361                                                               &entry, IPRI_CFI_SELf);
   6362                         }
   6363                     } else
   6364 #endif
   6365                     {
   6366                         rv = READ_EGR_VLAN_CONTROL_3r(unit, port, &rval);
   6367                         if (BCM_FAILURE(rv)) {
   6368                             QOS_UNLOCK(unit);
   6369                             return rv;
   6370                         }
   6371 
   6372                         profile_idx =  soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r,
   6373                                                          rval, IPRI_MAPPING_PTRf);
   6374                         use_profile =  soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r,
   6375                                                          rval, IPRI_CFI_SELf);
   6376 
   6377                     }
   6378                     if (use_profile) {
   6379                         rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   6380                                   _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, map_id);
   6381                     } else {
   6382                         rv = BCM_E_NOT_FOUND;
   6383                     }
   6384                 }
   6385 
   6386                 if (!soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   6387                     if (rv == BCM_E_NOT_FOUND) {
   6388                         alloc_size = 64 * sizeof(egr_pri_cng_map_entry_t);
   6389                         buf = soc_cm_salloc(unit, alloc_size,
   6390                                             "TR2 egr pri cng map");
   6391                         if (NULL == buf) {
   6392                             QOS_UNLOCK(unit);
   6393                             return (BCM_E_MEMORY);
   6394                         }
   6395                         sal_memset(buf, 0, alloc_size);
   6396 
   6397                         buf2 = soc_cm_salloc(unit, alloc_size,
   6398                                              "TR2 egr mpls exp map");
   6399                         if (NULL == buf2) {
   6400                             soc_cm_sfree(unit, buf);
   6401                             QOS_UNLOCK(unit);
   6402                             return (BCM_E_MEMORY);
   6403                         }
   6404                         sal_memset(buf2, 0, alloc_size);
   6405 
   6406                         if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) {
   6407                             source_mem = EGR_MPLS_EXP_MAPPING_1m;
   6408                             new_pri_field = PRIf;
   6409                             new_cfi_field = CFIf;
   6410                         } else {
   6411                             source_mem = EGR_MPLS_PRI_MAPPINGm;
   6412                             new_pri_field = NEW_PRIf;
   6413                             new_cfi_field = NEW_CFIf;
   6414                         }
   6415 
   6416                         index = port << 6;
   6417                         rv = soc_mem_read_range(unit, EGR_PRI_CNG_MAPm,
   6418                                                 MEM_BLOCK_ANY, index,
   6419                                                 index + 63, (void *)buf);
   6420                         if (BCM_FAILURE(rv)) {
   6421                             soc_cm_sfree(unit, buf);
   6422                             soc_cm_sfree(unit, buf2);
   6423                             QOS_UNLOCK(unit);
   6424                             return rv;
   6425                         }
   6426 
   6427                         num_map = soc_mem_index_count(unit, source_mem) / 64;
   6428                         for (id = 0; id < num_map; id++) {
   6429                             if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   6430                                 continue;
   6431                             }
   6432                             index = (QOS_INFO(unit)->egr_mpls_hw_idx[id] *
   6433                                      _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   6434                             rv = soc_mem_read_range(unit, source_mem,
   6435                                                     MEM_BLOCK_ANY, index,
   6436                                                     index + 63,
   6437                                                     (void *)buf2);
   6438                             if (BCM_FAILURE(rv)) {
   6439                                 soc_cm_sfree(unit, buf);
   6440                                 soc_cm_sfree(unit, buf2);
   6441                                 QOS_UNLOCK(unit);
   6442                                 return rv;
   6443                             }
   6444                             for (index = 0; index < _BCM_QOS_MAP_CHUNK_EGR_MPLS;
   6445                                  index++) {
   6446                                 entries[0] = soc_mem_table_idx_to_pointer(
   6447                                                  unit, source_mem, void *, buf2,
   6448                                                  index);
   6449                                 new_pri = soc_mem_field32_get(unit, source_mem,
   6450                                                               entries[0],
   6451                                                               new_pri_field);
   6452                                 new_cfi = soc_mem_field32_get(unit, source_mem,
   6453                                                               entries[0],
   6454                                                               new_cfi_field);
   6455                                 entries[0] = soc_mem_table_idx_to_pointer(
   6456                                                  unit, EGR_PRI_CNG_MAPm, void *,
   6457                                                  buf, index);
   6458                                 pri = soc_mem_field32_get(unit,
   6459                                                           EGR_PRI_CNG_MAPm,
   6460                                                           entries[0], PRIf);
   6461                                 cfi = soc_mem_field32_get(unit,
   6462                                                           EGR_PRI_CNG_MAPm,
   6463                                                           entries[0], CFIf);
   6464                                 if ((new_pri != pri) || (new_cfi != cfi)) {
   6465                                     break;
   6466                                 }
   6467                             }
   6468                             if (index >= _BCM_QOS_MAP_CHUNK_EGR_MPLS) {
   6469                                 *map_id = id | (_BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS
   6470                                                 << _BCM_QOS_MAP_SHIFT);
   6471                                 break;
   6472                             }
   6473                         }
   6474 
   6475                         soc_cm_sfree(unit, buf);
   6476                         soc_cm_sfree(unit, buf2);
   6477 
   6478                         if (id >= num_map) {
   6479                             rv = BCM_E_NOT_FOUND;
   6480                         }
   6481                     }
   6482                 }
   6483             } else if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) {
   6484                 flags &= ~BCM_QOS_MAP_L3;
   6485 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   6486                 if (soc_feature(unit, soc_feature_egr_qos_combo_profile) ||
   6487                    (SOC_IS_TRIDENT3X(unit))) {
   6488                     /* TRIDENT 3 programs same port index pointer without feature combo_profile */
   6489                     rv = _bcm_esw_egr_port_tab_get(unit, port, EGR_QOS_PROFILE_INDEXf, &profile_idx);
   6490                     if (BCM_FAILURE(rv)) {
   6491                         QOS_UNLOCK(unit);
   6492                         return rv;
   6493                     }
   6494 
   6495                     rv = _bcm_tr2_qos_idx2id(unit, profile_idx,
   6496                              _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE, map_id);
   6497 
   6498                 } else
   6499 #endif
   6500                 {
   6501                     rv = BCM_E_PARAM;
   6502                 }
   6503             } else {
   6504                 rv = BCM_E_PARAM;
   6505             }
   6506             /*invalid flags*/
   6507             if (flags) {
   6508                 rv = BCM_E_PARAM;
   6509             }
   6510 
   6511             QOS_UNLOCK(unit);
   6512             return rv;
   6513         } else {
   6514             QOS_UNLOCK(unit);
   6515             rv = BCM_E_PARAM;
   6516             return rv;
   6517         }
   6518     }
   6519 
   6520     QOS_UNLOCK(unit);
   6521     return rv;
   6522 }
   6523 
   6524 
   6525 
   6526 /* Retrieve a QOS map attached to an Object (Gport) */
   6527 int
   6528 bcm_tr2_qos_port_map_get(int unit, bcm_gport_t port, 
   6529                          int *ing_map, int *egr_map)
   6530 {
   6531     return BCM_E_UNAVAIL;
   6532 }
   6533 
   6534 /* Attach a QoS map to vlan,port */
   6535 int 
   6536 bcm_tr2_qos_port_vlan_map_set(int unit, bcm_gport_t port, bcm_vlan_t vid, int ing_map, int egr_map)
   6537 {
   6538     pbmp_t pbmp, ubmp;
   6539     int rv = BCM_E_NONE;
   6540     int id, cur_id, map_id;
   6541     egr_vlan_entry_t egr_vtab;
   6542 
   6543     QOS_INIT(unit);
   6544 
   6545     /* Validate Args */
   6546     /* Deal with physical ports */
   6547     if (BCM_GPORT_IS_SET(port)) {
   6548 
   6549 #if defined(BCM_TOMAHAWK3_SUPPORT)
   6550         if (SOC_IS_TOMAHAWK3(unit) &&
   6551             !BCM_GPORT_IS_LOCAL(port) &&
   6552             !BCM_GPORT_IS_MODPORT(port)) {
   6553             return BCM_E_PARAM;
   6554         }
   6555 #endif
   6556 
   6557         if (bcm_esw_port_local_get(unit, port, &port) < 0) {
   6558             return BCM_E_PARAM;
   6559         }
   6560     }
   6561 
   6562     if (vid == BCM_VLAN_NONE) {
   6563         return BCM_E_PARAM;
   6564     }
   6565 
   6566     if (!SOC_PORT_VALID(unit, port)) {
   6567         return BCM_E_PARAM;
   6568     }
   6569 
   6570     /* check vlan membership for the port */
   6571     BCM_IF_ERROR_RETURN(
   6572         bcm_esw_vlan_port_get(unit, vid, &pbmp, &ubmp));
   6573     if (!SOC_PBMP_MEMBER(pbmp, port)) {
   6574         return BCM_E_PARAM;
   6575     }
   6576     
   6577     QOS_LOCK(unit);
   6578 
   6579 #if defined(BCM_TOMAHAWK3_SUPPORT)
   6580     if (SOC_IS_TOMAHAWK3(unit)) {
   6581         /* Validate given ingress map for non supported types and IDs */
   6582         if ((ing_map > 0) &&
   6583             (BCM_E_NONE != _bcm_th3_qos_validate_map_type(unit, ing_map))) {
   6584             QOS_UNLOCK(unit);
   6585             return BCM_E_PARAM;
   6586         }
   6587         /* Validate given egress map for non supported types and IDs */
   6588         if ((egr_map > 0) &&
   6589             (BCM_E_NONE != _bcm_th3_qos_validate_map_type(unit, egr_map))) {
   6590             QOS_UNLOCK(unit);
   6591             return BCM_E_PARAM;
   6592         }
   6593     }
   6594 #endif /* BCM_TOMAHAWK3_SUPPORT */
   6595 
   6596     map_id = 0;
   6597     if (ing_map != -1) { /* -1 means no change */
   6598         /*
   6599          * chips that do not support ingress mapping, only accept ing_map=-1
   6600          */
   6601         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || \
   6602             SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND2(unit)) {
   6603             QOS_UNLOCK(unit);
   6604             return BCM_E_UNAVAIL;
   6605         }
   6606 
   6607         /* Make the port's vlan TRUST_DOT1_PTR point to the profile index */
   6608         if (ing_map != 0) {
   6609             if ((ing_map >> _BCM_QOS_MAP_SHIFT) != 
   6610                  _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP) {
   6611                 QOS_UNLOCK(unit);
   6612                 return BCM_E_PARAM;
   6613             }
   6614             id = ing_map & _BCM_QOS_MAP_TYPE_MASK;
   6615             if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   6616                 QOS_UNLOCK(unit);
   6617                 return BCM_E_PARAM;
   6618             }
   6619             if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   6620                 QOS_UNLOCK(unit);
   6621                 return BCM_E_PARAM;
   6622             }
   6623             map_id = QOS_INFO(unit)->pri_cng_hw_idx[id];
   6624         } else {
   6625             map_id = -1;
   6626         }
   6627     }
   6628 
   6629     if (ing_map != -1) { /* -1 means no change */
   6630         QOS_UNLOCK(unit);
   6631         /* Since below function does not require QoS lock
   6632          * and is causing race condition with VLAN and L3IIF locks,
   6633          * its being released.
   6634          */
   6635         rv = _bcm_tr2_qos_pvmid_set(unit, vid, map_id);
   6636         if (BCM_FAILURE(rv)) {
   6637             return rv;
   6638         }
   6639         /* Lock re-acquired for further processing. */
   6640         QOS_LOCK(unit);
   6641     }
   6642 
   6643     map_id = 0;
   6644     if (egr_map != -1) { /* -1 means no change */
   6645         if (egr_map != 0) {
   6646             if ((egr_map >> _BCM_QOS_MAP_SHIFT) != 
   6647                  _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) {
   6648                 QOS_UNLOCK(unit);
   6649                 return BCM_E_PARAM;
   6650             }
   6651             id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   6652             if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   6653                 QOS_UNLOCK(unit);
   6654                 return BCM_E_PARAM;
   6655             }
   6656             map_id = QOS_INFO(unit)->egr_mpls_hw_idx[id];
   6657         }
   6658 
   6659         soc_mem_lock(unit, EGR_VLANm);
   6660         
   6661         sal_memset(&egr_vtab, 0, sizeof(egr_vlan_entry_t));
   6662         rv = soc_mem_read(unit, EGR_VLANm, MEM_BLOCK_ANY, vid, &egr_vtab);
   6663         if (BCM_FAILURE(rv)) {
   6664             soc_mem_unlock(unit, EGR_VLANm);
   6665             QOS_UNLOCK(unit);
   6666             return rv;
   6667         }
   6668         
   6669         /* Check for VLAN validity */
   6670         if (0 == soc_EGR_VLANm_field32_get(unit, &egr_vtab, VALIDf)) {
   6671             soc_mem_unlock(unit, EGR_VLANm);
   6672             QOS_UNLOCK(unit);
   6673             return BCM_E_NOT_FOUND;
   6674         }
   6675 
   6676         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || \
   6677             SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND2(unit)) {
   6678             soc_EGR_VLANm_field32_set(unit, &egr_vtab, DOT1P_MAPPING_PTRf, map_id);
   6679 
   6680             soc_EGR_VLANm_field32_set(unit, &egr_vtab, REMARK_DOT1Pf, 1);
   6681 
   6682             rv = soc_mem_write(unit, EGR_VLANm,MEM_BLOCK_ALL, vid, &egr_vtab);
   6683         } else {
   6684             cur_id = soc_EGR_VLANm_field32_get(unit, &egr_vtab, DOT1P_MAPPING_PTRf);
   6685             if (map_id != cur_id) {
   6686                 soc_EGR_VLANm_field32_set(unit, &egr_vtab, DOT1P_MAPPING_PTRf, map_id);
   6687 
   6688                 if (SOC_MEM_FIELD_VALID(unit, EGR_VLANm, REMARK_DOT1Pf)) {
   6689                     soc_EGR_VLANm_field32_set(unit, &egr_vtab, REMARK_DOT1Pf,
   6690                                               (map_id == 0) ? 0 : 1);
   6691                 }
   6692             
   6693                 if (SOC_MEM_FIELD_VALID(unit, EGR_VLANm, REMARK_CFIf)) {
   6694                     soc_EGR_VLANm_field32_set(unit, &egr_vtab, REMARK_CFIf,
   6695                                                 (map_id == 0) ? 0 : 1);
   6696                 }
   6697                 rv = soc_mem_write(unit, EGR_VLANm,MEM_BLOCK_ALL, vid, &egr_vtab);
   6698             }
   6699         }
   6700 
   6701         soc_mem_unlock(unit, EGR_VLANm);
   6702     }
   6703 
   6704     QOS_UNLOCK(unit);
   6705     
   6706     return rv;
   6707 }
   6708 
   6709 
   6710 /* Retrieve a QOS map attached to an vlan and port */
   6711 int
   6712 bcm_tr2_qos_port_vlan_map_get(int unit, bcm_gport_t port, bcm_vlan_t vid,
   6713                          int *ing_map, int *egr_map)
   6714 {
   6715     pbmp_t pbmp, ubmp;
   6716     int rv, idx;
   6717     int map_id;
   6718     egr_vlan_entry_t egr_vtab;
   6719 
   6720     QOS_INIT(unit);
   6721 
   6722     if (ing_map == NULL) {
   6723         return BCM_E_PARAM;
   6724     }
   6725 
   6726     if (egr_map == NULL) {
   6727         return BCM_E_PARAM;
   6728     }
   6729 
   6730     /* Deal with physical ports */
   6731     if (BCM_GPORT_IS_SET(port)) {
   6732 
   6733 #if defined(BCM_TOMAHAWK3_SUPPORT)
   6734         if (SOC_IS_TOMAHAWK3(unit) &&
   6735             !BCM_GPORT_IS_LOCAL(port) &&
   6736             !BCM_GPORT_IS_MODPORT(port)) {
   6737             return BCM_E_PARAM;
   6738         }
   6739 #endif
   6740 
   6741         if (bcm_esw_port_local_get(unit, port, &port) < 0) {
   6742             return BCM_E_PARAM;
   6743         }
   6744     }
   6745 
   6746     if (vid == BCM_VLAN_NONE) {
   6747         return BCM_E_PARAM;
   6748     }
   6749 
   6750     if (!SOC_PORT_VALID(unit, port)) {
   6751         return BCM_E_PARAM;
   6752     }
   6753 
   6754 
   6755     /* check vlan membership for the port */
   6756     BCM_IF_ERROR_RETURN(
   6757         bcm_esw_vlan_port_get(unit, vid, &pbmp, &ubmp));
   6758     if (!SOC_PBMP_MEMBER(pbmp, port)) {
   6759         return BCM_E_PARAM;
   6760     }
   6761 
   6762     QOS_LOCK(unit);
   6763 
   6764     rv = _bcm_tr2_qos_pvmid_get(unit, vid, &map_id);
   6765     if (BCM_FAILURE(rv)) {
   6766         QOS_UNLOCK(unit);
   6767         return rv;
   6768     }
   6769 
   6770     *ing_map = -1;
   6771     for (idx = 0; idx < _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; idx++) {
   6772         if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, idx) &&
   6773             (QOS_INFO(unit)->pri_cng_hw_idx[idx] == map_id)) {
   6774             *ing_map = idx | 
   6775                     (_BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP << _BCM_QOS_MAP_SHIFT);
   6776             break;
   6777         }
   6778     }
   6779 
   6780     soc_mem_lock(unit, EGR_VLANm);
   6781 
   6782     sal_memset(&egr_vtab, 0, sizeof(egr_vlan_entry_t));
   6783     rv = soc_mem_read(unit, EGR_VLANm, MEM_BLOCK_ANY, vid, &egr_vtab);
   6784     if (BCM_FAILURE(rv)) {
   6785         soc_mem_unlock(unit, EGR_VLANm);
   6786         QOS_UNLOCK(unit);
   6787         return rv;
   6788     }
   6789     
   6790     /* Check for VLAN validity */
   6791     if (0 == soc_EGR_VLANm_field32_get(unit, &egr_vtab, VALIDf)) {
   6792         soc_mem_unlock(unit, EGR_VLANm);
   6793         QOS_UNLOCK(unit);
   6794         return BCM_E_NOT_FOUND;
   6795     }
   6796 
   6797     map_id = soc_EGR_VLANm_field32_get(unit, &egr_vtab, DOT1P_MAPPING_PTRf);
   6798 
   6799     soc_mem_unlock(unit, EGR_VLANm);
   6800 
   6801     *egr_map = -1;
   6802     for (idx = 0; idx < _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; idx++) {
   6803         if (_BCM_QOS_EGR_MPLS_USED_GET(unit, idx) &&
   6804             (QOS_INFO(unit)->egr_mpls_hw_idx[idx] == map_id)) {
   6805             *egr_map = idx | 
   6806                     (_BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS << _BCM_QOS_MAP_SHIFT);
   6807             break;
   6808         }
   6809     }
   6810 
   6811     QOS_UNLOCK(unit);
   6812     return rv;
   6813 }
   6814 
   6815 /* bcm_tr2_qos_map_multi_get */
   6816 int
   6817 bcm_tr2_qos_map_multi_get(int unit, uint32 flags,
   6818                           int map_id, int array_size, 
   6819                           bcm_qos_map_t *array, int *array_count)
   6820 {
   6821     int             rv = BCM_E_NONE;
   6822     int             num_entries, idx, id, hw_id, alloc_size, entry_size, count;
   6823     int             entry_size_ext = 0; 
   6824     int             entry_size_ext_2 = 0;
   6825     int             alloc_size_ext = 0;
   6826     int             alloc_size_ext_2 = 0;
   6827     uint8           *dma_buf = NULL; 
   6828     uint8           *dma_buf_ext = NULL;
   6829     uint8           *dma_buf_ext_2 = NULL;
   6830     void            *entry;
   6831     soc_mem_t       mem;
   6832     soc_mem_t       mem_ext;
   6833     soc_mem_t       mem_ext_2;
   6834 
   6835     bcm_qos_map_t   *map;
   6836     soc_field_t     field;
   6837 
   6838     /* ignore with_id & replace flags */
   6839     flags &= (~(BCM_QOS_MAP_WITH_ID | BCM_QOS_MAP_REPLACE));
   6840     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   6841     mem = INVALIDm;
   6842     mem_ext = INVALIDm;
   6843 
   6844     mem_ext_2 = INVALIDm;
   6845 
   6846     hw_id = 0;
   6847     num_entries = 0;
   6848     entry_size = 0;
   6849 
   6850 #if defined(BCM_TOMAHAWK3_SUPPORT)
   6851     if (SOC_IS_TOMAHAWK3(unit)) {
   6852         BCM_IF_ERROR_RETURN(_bcm_th3_qos_validate_map_type(unit, map_id));
   6853     }
   6854 #endif
   6855 
   6856     QOS_LOCK(unit);
   6857 
   6858     if (SOC_IS_TRIDENT3X(unit)) {
   6859        field = INT_PRIf;
   6860     } else {
   6861        field = PRIf;
   6862     }
   6863 
   6864     switch (map_id >> _BCM_QOS_MAP_SHIFT) {
   6865     case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
   6866         if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   6867             rv = BCM_E_PARAM;
   6868             QOS_UNLOCK(unit);
   6869             BCM_IF_ERROR_RETURN(rv);
   6870         }
   6871         if (((flags != (BCM_QOS_MAP_L2 | BCM_QOS_MAP_INGRESS)) &&
   6872             (flags != (BCM_QOS_MAP_L2 | BCM_QOS_MAP_INGRESS |
   6873                        BCM_QOS_MAP_L2_UNTAGGED))) ||
   6874             (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id))) {
   6875             rv = BCM_E_PARAM;
   6876         }
   6877 
   6878         if (flags & BCM_QOS_MAP_L2_UNTAGGED) {
   6879             if (SOC_IS_TRIDENT3X(unit)) {
   6880                 hw_id = QOS_INFO(unit)->pri_cng_hw_idx[id] * _BCM_QOS_MAP_CHUNK_PRI_CNG;
   6881                 num_entries = _BCM_QOS_MAP_CHUNK_PRI_CNG;
   6882                 mem = PHB_MAPPING_TBL_1m;
   6883                 entry_size = sizeof(phb_mapping_tbl_1_entry_t);
   6884             } else {
   6885                 hw_id = QOS_INFO(unit)->pri_cng_hw_idx[id];
   6886                 num_entries = 1;
   6887                 entry_size = sizeof(ing_untagged_phb_entry_t);
   6888                 mem = ING_UNTAGGED_PHBm;
   6889             }
   6890         } else {
   6891             num_entries = _BCM_QOS_MAP_CHUNK_PRI_CNG;
   6892             hw_id = QOS_INFO(unit)->pri_cng_hw_idx[id]* _BCM_QOS_MAP_CHUNK_PRI_CNG;
   6893             if (SOC_IS_TRIDENT3X(unit)) {
   6894                  mem = PHB_MAPPING_TBL_1m;
   6895                  entry_size = sizeof(phb_mapping_tbl_1_entry_t);
   6896             } else {
   6897                  mem = ING_PRI_CNG_MAPm;
   6898                  entry_size = sizeof(ing_pri_cng_map_entry_t);
   6899             }
   6900         }
   6901         break;
   6902     case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS:
   6903         if (((flags != (BCM_QOS_MAP_L2 | BCM_QOS_MAP_EGRESS)) &&
   6904             (flags != (BCM_QOS_MAP_L2_INNER_TAG | BCM_QOS_MAP_EGRESS)) &&
   6905             (flags != (BCM_QOS_MAP_MPLS | BCM_QOS_MAP_EGRESS))) ||
   6906             (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id))) {
   6907             rv = BCM_E_PARAM;
   6908         }
   6909         if ((flags & BCM_QOS_MAP_L2_OUTER_TAG) &&
   6910             (flags & BCM_QOS_MAP_L2_INNER_TAG)) {
   6911             rv = BCM_E_PARAM;
   6912         }
   6913 #if defined(BCM_TOMAHAWK3_SUPPORT)
   6914         /* TH3 does not support double/inner VLAN Tag */
   6915         if (SOC_IS_TOMAHAWK3(unit) &&
   6916             (flags & BCM_QOS_MAP_L2_INNER_TAG)) {
   6917             rv = BCM_E_PARAM;
   6918         }
   6919 #endif
   6920 
   6921         num_entries = _BCM_QOS_MAP_CHUNK_EGR_MPLS;
   6922         entry_size = sizeof(egr_mpls_pri_mapping_entry_t);
   6923         hw_id = (QOS_INFO(unit)->egr_mpls_hw_idx[id] * 
   6924                 _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   6925         mem = EGR_MPLS_PRI_MAPPINGm;
   6926         if (SOC_IS_TRIDENT3X(unit)) {
   6927             if (flags & BCM_QOS_MAP_L2_OUTER_TAG) { 
   6928                 entry_size_ext = sizeof(egr_zone_1_dot1p_mapping_table_3_entry_t);
   6929                 mem_ext = EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m;
   6930             }
   6931             if (flags & BCM_QOS_MAP_MPLS) {
   6932                 entry_size_ext_2 = sizeof(egr_mpls_exp_mapping_1_entry_t);
   6933                 mem_ext_2 = EGR_MPLS_EXP_MAPPING_1m;
   6934             }
   6935         } else if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m) && 
   6936 		          ((flags & BCM_QOS_MAP_L2_OUTER_TAG) || 
   6937                   (flags & BCM_QOS_MAP_MPLS))) {                      
   6938             entry_size_ext = sizeof(egr_mpls_exp_mapping_1_entry_t);
   6939             mem_ext = EGR_MPLS_EXP_MAPPING_1m;
   6940         } else if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m) &&
   6941             ((flags & BCM_QOS_MAP_L2_INNER_TAG ||
   6942              (flags & BCM_QOS_MAP_MPLS)))) {
   6943             entry_size_ext_2 = sizeof(egr_mpls_exp_mapping_2_entry_t);
   6944             mem_ext_2 = EGR_MPLS_EXP_MAPPING_2m;
   6945         }
   6946 
   6947         break;
   6948 #ifdef BCM_APACHE_SUPPORT
   6949     case _BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP:
   6950         if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) {
   6951 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   6952             id = id & _BCM_TR_MPLS_EXP_MAP_TABLE_NUM_MASK;
   6953 
   6954             if ((flags == (BCM_QOS_MAP_OAM_MPLS_EXP | BCM_QOS_MAP_INGRESS)) &&
   6955                 (bcm_tr_mpls_exp_to_phb_cng_map_usage_get(unit, flags, 
   6956                                                           id) != BCM_E_NONE)) {
   6957                 rv = BCM_E_PARAM;
   6958                 QOS_UNLOCK(unit);
   6959                 BCM_IF_ERROR_RETURN(rv);
   6960             }
   6961             if ((flags == (BCM_QOS_MAP_OAM_MPLS_EXP | BCM_QOS_MAP_EGRESS)) &&
   6962                 (bcm_tr_mpls_exp_to_phb_cng_map_usage_get(unit, flags, 
   6963                                                           id) != BCM_E_NONE)) {
   6964                 rv = BCM_E_PARAM;
   6965                 QOS_UNLOCK(unit);
   6966                 BCM_IF_ERROR_RETURN(rv);
   6967             }
   6968             rv = bcm_tr_mpls_exp_to_phb_cng_map_profile_id_get(unit, flags, 
   6969                     id, &hw_id);
   6970             if(rv == BCM_E_NONE){ 
   6971                 hw_id = hw_id * _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP;
   6972                 num_entries = _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP;
   6973                 if (flags & BCM_QOS_MAP_INGRESS){
   6974                     entry_size = sizeof(ing_mpls_exp_mapping_1_entry_t);
   6975                     mem = ING_MPLS_EXP_MAPPING_1m;
   6976                 }else if (flags & BCM_QOS_MAP_EGRESS){
   6977                     entry_size = sizeof(egr_mpls_exp_mapping_3_entry_t);
   6978                     mem = EGR_MPLS_EXP_MAPPING_3m;
   6979                 }
   6980             } else { 
   6981                 rv = BCM_E_PARAM;
   6982             }
   6983 #endif
   6984 
   6985         } else {
   6986             rv = BCM_E_PARAM;
   6987         }
   6988         break;
   6989 #endif
   6990     case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
   6991         if ((flags != (BCM_QOS_MAP_L3 | BCM_QOS_MAP_INGRESS)) ||
   6992             (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id))) {
   6993             rv = BCM_E_PARAM;
   6994         }
   6995         num_entries = _BCM_QOS_MAP_CHUNK_DSCP;
   6996         if (SOC_IS_TRIDENT3X(unit)) {
   6997             entry_size = sizeof(phb_mapping_tbl_2_entry_t);
   6998         } else {
   6999             entry_size = sizeof(dscp_table_entry_t);
   7000         }
   7001         hw_id = QOS_INFO(unit)->dscp_hw_idx[id] * _BCM_QOS_MAP_CHUNK_DSCP;
   7002         mem = _bcm_tr2_qos_bk_info[unit].dscp_table;
   7003         break;
   7004     case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE:
   7005         if ((flags != (BCM_QOS_MAP_L3 | BCM_QOS_MAP_EGRESS)) ||
   7006             (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id))) {
   7007             rv = BCM_E_PARAM;
   7008         }
   7009         num_entries = _BCM_QOS_MAP_CHUNK_EGR_DSCP;
   7010         if (SOC_IS_TRIDENT3X(unit)) {
   7011             entry_size = sizeof(egr_zone_4_qos_mapping_table_entry_t);
   7012         } else {
   7013             entry_size = sizeof(egr_dscp_table_entry_t);
   7014         }
   7015         hw_id = (QOS_INFO(unit)->egr_dscp_hw_idx[id] * 
   7016                 _BCM_QOS_MAP_CHUNK_EGR_DSCP);
   7017         mem = _bcm_tr2_qos_bk_info[unit].egr_dscp_table;
   7018 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   7019         if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   7020             entry_size_ext = sizeof(egr_pri_cng_map_entry_t);
   7021             mem_ext = EGR_PRI_CNG_MAPm;
   7022         }
   7023 #endif
   7024         break;
   7025 #ifdef BCM_KATANA_SUPPORT
   7026     case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE:
   7027         if ((flags != (BCM_QOS_MAP_QUEUE)) ||
   7028             (!_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id))) {
   7029             rv = BCM_E_PARAM;
   7030         }
   7031         num_entries = _BCM_QOS_MAP_CHUNK_OFFSET_MAP;
   7032         entry_size = sizeof(ing_queue_offset_mapping_table_entry_t);
   7033         hw_id = QOS_INFO(unit)->offset_map_hw_idx[id] *
   7034                                        _BCM_QOS_MAP_CHUNK_OFFSET_MAP;
   7035         mem = ING_QUEUE_OFFSET_MAPPING_TABLEm;
   7036         break;
   7037 #endif
   7038 #ifdef BCM_KATANA2_SUPPORT
   7039     case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP:
   7040         if ((flags != (BCM_QOS_MAP_REPLICATION)) ||
   7041             (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id))) {
   7042             rv = BCM_E_PARAM;
   7043             QOS_UNLOCK(unit);
   7044             BCM_IF_ERROR_RETURN(rv);
   7045         }
   7046         rv = _bcm_rqe_queue_offset_map_multi_get(unit, flags, id,
   7047                                array_size, array, array_count);
   7048 
   7049         QOS_UNLOCK(unit);
   7050         return rv;
   7051 #endif
   7052 #ifdef BCM_SABER2_SUPPORT
   7053     case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE:
   7054         if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   7055             if (((flags != BCM_QOS_MAP_OAM_INTPRI) &&
   7056                         (flags != BCM_QOS_MAP_OAM_OUTER_VLAN_PCP)&&
   7057                         (flags != BCM_QOS_MAP_OAM_INNER_VLAN_PCP)&&
   7058                         (flags != BCM_QOS_MAP_OAM_MPLS_EXP      )) ||
   7059                     (!_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id))) {
   7060                 rv = BCM_E_PARAM;
   7061             }
   7062             num_entries = _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP;
   7063             entry_size = sizeof(ing_service_pri_map_0_entry_t);
   7064             hw_id = QOS_INFO(unit)->service_pri_map_hw_idx[id] *
   7065                 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP;
   7066             /* All memories (ING_SERVICE_PRI_MAP_0/1/2m and EGR_SERVICE_PRI_MAP_0/1/2m) 
   7067              * have similar profiles. So choosing one of the memories. 
   7068              */
   7069             mem = ING_SERVICE_PRI_MAP_0m;
   7070         } else {
   7071             rv = BCM_E_PARAM;
   7072         }
   7073         break;
   7074 #endif
   7075     default:
   7076 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   7077         if ((map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_MASK) == 
   7078             _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) {
   7079             /* Map created using TR mpls module */
   7080             if (flags != (BCM_QOS_MAP_MPLS | BCM_QOS_MAP_INGRESS)) {
   7081                 rv = BCM_E_PARAM;
   7082             }
   7083             id = map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_NUM_MASK;
   7084             if (!_BCM_QOS_ING_MPLS_EXP_USED_GET(unit, id)) {
   7085                 rv = BCM_E_PARAM;
   7086             }
   7087             num_entries = _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP;
   7088             if (SOC_IS_TRIDENT3X(unit)) {
   7089                 entry_size = sizeof(phb_mapping_tbl_3_entry_t);
   7090                 mem = PHB_MAPPING_TBL_3m;
   7091             } else {
   7092                 entry_size = sizeof(ing_mpls_exp_mapping_entry_t);
   7093                 mem = ING_MPLS_EXP_MAPPINGm;
   7094             }
   7095 
   7096             if (soc_feature(unit, soc_feature_td3_style_mpls)) {
   7097                 hw_id = id << 6;
   7098             } else {
   7099                 hw_id = id * num_entries; /* soc profile mem is not used. So direct hw index */
   7100             }
   7101         } else 
   7102 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */
   7103         {
   7104             rv = BCM_E_PARAM;
   7105         }
   7106     }
   7107     QOS_UNLOCK(unit);
   7108     BCM_IF_ERROR_RETURN(rv);
   7109 
   7110     if (NULL == array_count) {
   7111         return BCM_E_PARAM;
   7112     }
   7113 
   7114     if (array_size == 0) { /* querying the size of map-chunk */
   7115         *array_count = num_entries;
   7116         return BCM_E_NONE;
   7117     }
   7118     if (!array) {
   7119         return BCM_E_PARAM;
   7120     }
   7121 
   7122     /* Allocate memory for DMA & regular */
   7123     alloc_size = num_entries * entry_size;
   7124     dma_buf = soc_cm_salloc(unit, alloc_size, "TR2 qos multi get DMA buf");
   7125     if (!dma_buf) {
   7126         return BCM_E_MEMORY;
   7127     }
   7128     sal_memset(dma_buf, 0, alloc_size);
   7129 
   7130     /* Read the profile chunk */
   7131     rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, hw_id, 
   7132                             (hw_id + num_entries - 1), dma_buf);
   7133     if (BCM_FAILURE(rv)) {
   7134         soc_cm_sfree(unit, dma_buf);
   7135         return rv;
   7136     }
   7137     if (mem_ext != INVALIDm) {
   7138         alloc_size_ext = num_entries * entry_size_ext;
   7139         dma_buf_ext = soc_cm_salloc(unit, alloc_size_ext, "TR2 qos multi get external DMA buf");
   7140         if (!dma_buf_ext) {
   7141             soc_cm_sfree(unit, dma_buf);
   7142             return BCM_E_MEMORY;
   7143         }
   7144         sal_memset(dma_buf_ext, 0, alloc_size_ext);
   7145 
   7146         /* Read the profile chunk */
   7147         rv = soc_mem_read_range(unit, mem_ext, MEM_BLOCK_ANY, hw_id,
   7148                                 (hw_id + num_entries - 1), dma_buf_ext);
   7149         if (BCM_FAILURE(rv)) {
   7150             soc_cm_sfree(unit, dma_buf);
   7151             soc_cm_sfree(unit, dma_buf_ext);
   7152             return rv;
   7153         }
   7154     }
   7155 
   7156     if (mem_ext_2 != INVALIDm) {
   7157         alloc_size_ext_2 = num_entries * entry_size_ext_2;
   7158         dma_buf_ext_2 = soc_cm_salloc(unit, alloc_size_ext_2, "TR2 qos multi get external_2 DMA buf");
   7159         if (!dma_buf_ext_2) {
   7160             soc_cm_sfree(unit, dma_buf);
   7161             if (dma_buf_ext) {
   7162                 soc_cm_sfree(unit, dma_buf_ext);
   7163             }
   7164             return BCM_E_MEMORY;
   7165         }
   7166         sal_memset(dma_buf_ext_2, 0, alloc_size_ext_2);
   7167 
   7168         /* Read the profile chunk */
   7169         rv = soc_mem_read_range(unit, mem_ext_2, MEM_BLOCK_ANY, hw_id,
   7170                                 (hw_id + num_entries - 1), dma_buf_ext_2);
   7171         if (BCM_FAILURE(rv)) {
   7172             soc_cm_sfree(unit, dma_buf);
   7173             if (dma_buf_ext) {
   7174                 soc_cm_sfree(unit, dma_buf_ext);
   7175             }
   7176             soc_cm_sfree(unit, dma_buf_ext_2);
   7177             return rv;
   7178         }
   7179     }
   7180 
   7181     count = 0;
   7182     QOS_LOCK(unit);
   7183     switch (map_id >> _BCM_QOS_MAP_SHIFT) {
   7184     case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
   7185         for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) {
   7186             map = &array[idx];
   7187             sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   7188             map->pkt_pri = ((idx & 0x1e) >> 1);
   7189             map->pkt_cfi = (idx & 0x1);
   7190             entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 
   7191                                                  dma_buf, idx);
   7192             map->int_pri = soc_mem_field32_get(unit, mem, entry, field);
   7193             map->color = _BCM_COLOR_DECODING(unit, soc_mem_field32_get(unit, 
   7194                                  mem, entry, CNGf));
   7195             count++;
   7196         }
   7197         break;
   7198     case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS:
   7199         for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) {
   7200             map = &array[idx];
   7201             sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   7202             map->int_pri = ((idx & 0x3c) >> 2);
   7203             map->color = _BCM_COLOR_DECODING(unit, (idx & 0x3));
   7204             entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 
   7205                                                  dma_buf, idx);
   7206             map->pkt_pri = soc_mem_field32_get(unit, mem, entry, NEW_PRIf);
   7207             map->pkt_cfi = soc_mem_field32_get(unit, mem, entry, NEW_CFIf);
   7208             if (dma_buf_ext) {
   7209                 entry = soc_mem_table_idx_to_pointer(unit, mem_ext, void *, 
   7210                                                      dma_buf_ext, idx);
   7211                 if (flags & BCM_QOS_MAP_L2_OUTER_TAG) {
   7212                     map->pkt_pri = soc_mem_field32_get(unit, 
   7213                                                        mem_ext,
   7214                                                        entry,
   7215                                                        PRIf);
   7216                     map->pkt_cfi = soc_mem_field32_get(unit, 
   7217                                                        mem_ext,
   7218                                                        entry,
   7219                                                        CFIf);
   7220                 }
   7221                 if (!SOC_IS_TRIDENT3X(unit)) {
   7222                    /* For none Trident3 chips, MPLS_EXP is coming from same memory map */
   7223                     if (flags & BCM_QOS_MAP_MPLS) {
   7224                         map->exp = soc_mem_field32_get(unit, mem_ext, entry,
   7225                                                        MPLS_EXPf);
   7226                     }
   7227                 }             
   7228             } else if (dma_buf_ext_2) {
   7229                 entry = soc_mem_table_idx_to_pointer(unit, mem_ext_2, void *,
   7230                                                      dma_buf_ext_2, idx);
   7231                 if (flags & BCM_QOS_MAP_MPLS) {
   7232                     map->exp = soc_mem_field32_get(unit, mem_ext_2, entry,
   7233                                                    MPLS_EXPf);
   7234                 }
   7235             }
   7236             count++;
   7237         }
   7238         break;
   7239 #ifdef BCM_APACHE_SUPPORT
   7240 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   7241     case _BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP:
   7242         for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) {
   7243             map = &array[idx];
   7244             sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   7245             map->exp = idx;
   7246             entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
   7247                     dma_buf, idx);
   7248             map->color = _BCM_COLOR_DECODING(unit,soc_mem_field32_get(unit,
   7249                         mem, entry, CNGf));
   7250             map->int_pri = soc_mem_field32_get(unit, mem, entry, PHBf);
   7251             count++;
   7252         }
   7253         break;
   7254 #endif
   7255 #endif
   7256     case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
   7257         for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) {
   7258             map = &array[idx];
   7259             sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   7260             map->dscp = idx;
   7261             entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 
   7262                                                  dma_buf, idx);
   7263             map->int_pri = soc_mem_field32_get(unit, mem, entry, field);
   7264             map->color = _BCM_COLOR_DECODING(unit, soc_mem_field32_get(unit, 
   7265                                  mem, entry, CNGf));
   7266             count++;
   7267         }
   7268         break;
   7269     case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE:
   7270         for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) {
   7271             map = &array[idx];
   7272             sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   7273             map->int_pri = ((idx & 0x3c) >> 2);
   7274             map->color = _BCM_COLOR_DECODING(unit, (idx & 0x3));
   7275             entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 
   7276                                                  dma_buf, idx);
   7277             if (SOC_IS_TRIDENT3X(unit)) {
   7278                 map->dscp = soc_mem_field32_get(unit, mem, entry, QOSf);
   7279             } else {
   7280                 map->dscp = soc_mem_field32_get(unit, mem, entry, DSCPf);
   7281             }
   7282 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   7283             if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
   7284                 if (dma_buf_ext) {
   7285                     entry = soc_mem_table_idx_to_pointer(unit, mem_ext, void *,
   7286                                                          dma_buf_ext, idx);
   7287                     map->pkt_pri = soc_mem_field32_get(unit,
   7288                                                        EGR_PRI_CNG_MAPm,
   7289                                                        entry,
   7290                                                        PRIf);
   7291                     map->pkt_cfi = soc_mem_field32_get(unit,
   7292                                                        EGR_PRI_CNG_MAPm,
   7293                                                        entry,
   7294                                                        CFIf);
   7295                 }
   7296             }
   7297 #endif
   7298             count++;
   7299         }
   7300         break;
   7301 #ifdef BCM_KATANA_SUPPORT
   7302     case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE:
   7303         for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) {
   7304             map = &array[idx];
   7305             sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   7306             map->int_pri = idx;
   7307             entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
   7308                                                  dma_buf, idx);
   7309             map->queue_offset = soc_mem_field32_get(unit, mem, entry, 
   7310                                                           QUEUE_OFFSETf);
   7311             count++;
   7312         }
   7313         break;
   7314 #endif
   7315 #ifdef BCM_SABER2_SUPPORT
   7316     case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE:
   7317         for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) {
   7318             map = &array[idx];
   7319             sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   7320             map->int_pri = idx;
   7321             entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
   7322                                                  dma_buf, idx);
   7323             map->counter_offset = soc_mem_field32_get(unit, mem, entry, 
   7324                                                           OFFSETf);
   7325             count++;
   7326         }
   7327         break;
   7328 #endif
   7329     default:
   7330 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   7331         if ((map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_MASK) == 
   7332             _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) {
   7333             for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) {
   7334                 map = &array[idx];
   7335                 sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   7336                 map->exp = idx;
   7337                 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 
   7338                                                      dma_buf, idx);
   7339                 map->color = _BCM_COLOR_DECODING(unit,soc_mem_field32_get(unit,
   7340                                  mem, entry, CNGf));
   7341                 map->int_pri = soc_mem_field32_get(unit, mem, entry, field);
   7342                 count++;
   7343             }
   7344         } else 
   7345 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */
   7346         {
   7347             rv = BCM_E_INTERNAL; /* should not hit this */
   7348         }
   7349     }
   7350     QOS_UNLOCK(unit);
   7351 	if (dma_buf) {
   7352         soc_cm_sfree(unit, dma_buf);
   7353 	}
   7354     if (dma_buf_ext) {
   7355         soc_cm_sfree(unit, dma_buf_ext);
   7356     }
   7357     if (dma_buf_ext_2) {
   7358         soc_cm_sfree(unit, dma_buf_ext_2);
   7359     }
   7360     BCM_IF_ERROR_RETURN(rv);
   7361 
   7362     *array_count = count;
   7363     return BCM_E_NONE;
   7364 }
   7365 
   7366 /* Get the list of all created Map-ids along with corresponding flags */
   7367 int
   7368 bcm_tr2_qos_multi_get(int unit, int array_size, int *map_ids_array, 
   7369                       int *flags_array, int *array_count)
   7370 {
   7371     int rv = BCM_E_NONE;
   7372     int idx, count;
   7373 
   7374     QOS_INIT(unit);
   7375     QOS_LOCK(unit);
   7376     if (array_size == 0) {
   7377         /* querying the number of map-ids for storage allocation */
   7378         if (array_count == NULL) {
   7379             rv = BCM_E_PARAM;
   7380         }
   7381         if (BCM_SUCCESS(rv)) {
   7382             count = 0;
   7383             *array_count = 0;
   7384             SHR_BITCOUNT_RANGE(QOS_INFO(unit)->ing_pri_cng_bitmap, count, 
   7385                                0, _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP);
   7386             *array_count += count;
   7387             count = 0;
   7388             SHR_BITCOUNT_RANGE(QOS_INFO(unit)->egr_mpls_bitmap, count,
   7389                                0, _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS);
   7390             *array_count += count;
   7391             count = 0;
   7392             SHR_BITCOUNT_RANGE(QOS_INFO(unit)->dscp_table_bitmap, count,
   7393                                0, _BCM_QOS_MAP_LEN_DSCP_TABLE);
   7394             /* For all port dscp profiles have been reserved on TD. */
   7395             if (SOC_IS_TRIDENT(unit)) {
   7396                 count -= SOC_PORT_MAX(unit, all);
   7397             }
   7398             *array_count += count;
   7399             count = 0;
   7400             SHR_BITCOUNT_RANGE(QOS_INFO(unit)->egr_dscp_table_bitmap, count,
   7401                                0, _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE);
   7402             *array_count += count;
   7403 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   7404             count = 0;
   7405             SHR_BITCOUNT_RANGE(QOS_INFO(unit)->ing_mpls_exp_bitmap, count,
   7406                                0, _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP);
   7407             *array_count += count;
   7408 #ifdef BCM_APACHE_SUPPORT
   7409             if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) {
   7410                 count = 0;
   7411                 bcm_tr_mpls_exp_to_phb_cng_map_profile_range_get(unit, 
   7412                         BCM_QOS_MAP_INGRESS, 
   7413                         &count);
   7414                 *array_count += count;
   7415                 count = 0;
   7416                 bcm_tr_mpls_exp_to_phb_cng_map_profile_range_get(unit, 
   7417                         BCM_QOS_MAP_EGRESS, 
   7418                         &count);
   7419                 *array_count += count;
   7420             }
   7421 #endif
   7422 #endif
   7423 #ifdef BCM_KATANA_SUPPORT
   7424             count = 0;
   7425             SHR_BITCOUNT_RANGE(QOS_INFO(unit)->offset_map_table_bitmap, count,
   7426                                0, _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE);
   7427             *array_count += count;
   7428 #endif
   7429 #ifdef BCM_SABER2_SUPPORT
   7430             if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   7431                 count = 0;
   7432                 SHR_BITCOUNT_RANGE(QOS_INFO(unit)->service_pri_map_table_bitmap, count,
   7433                         0, _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE);
   7434                 *array_count += count;
   7435             }
   7436 #endif
   7437 #ifdef BCM_KATANA2_SUPPORT
   7438             count = 0;
   7439             SHR_BITCOUNT_RANGE(QOS_INFO(unit)->rqe_queue_offset_bitmap, count,
   7440                                0, _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP);
   7441             *array_count += count;
   7442 #endif /* BCM_KATANA2_SUPPORT */
   7443 #ifdef BCM_TRIDENT2_SUPPORT
   7444             if (soc_feature(unit, soc_feature_fcoe)) {
   7445                 _bcm_td2_qos_fcoe_get(unit, array_size, NULL, NULL, &count);
   7446                 *array_count += count;
   7447             }
   7448             if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) {
   7449                 count = 0;
   7450                 rv = _bcm_td2_qos_multi_get(unit, array_size, NULL, NULL, &count);
   7451                 if (BCM_SUCCESS(rv)) {
   7452                     *array_count += count;
   7453                 }
   7454             }
   7455 #endif /* BCM_TRIDENT2_SUPPORT */
   7456 #ifdef BCM_TOMAHAWK_SUPPORT
   7457             if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) {
   7458                 count = 0;
   7459                 rv = _bcm_th_qos_multi_get(unit, array_size, NULL, NULL, &count);
   7460                 if (BCM_SUCCESS(rv)) {
   7461                     *array_count += count;
   7462                 }
   7463             }
   7464 #endif /* BCM_TOMAHAWK_SUPPORT */
   7465         }
   7466     } else {
   7467         if ((map_ids_array == NULL) || (flags_array == NULL) || 
   7468             (array_count == NULL)) {
   7469             rv = BCM_E_PARAM;
   7470         }
   7471         if (BCM_SUCCESS(rv)) {
   7472             count = 0;
   7473             for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) && 
   7474                          (count < array_size)); idx++) {
   7475                 if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, idx)) {
   7476                     *(map_ids_array + count) = idx | 
   7477                      (_BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP << _BCM_QOS_MAP_SHIFT);
   7478                     *(flags_array + count) = (BCM_QOS_MAP_L2 | 
   7479                                               BCM_QOS_MAP_INGRESS);
   7480                     count++;
   7481                 }
   7482             }
   7483             for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS) && 
   7484                          (count < array_size)); idx++) {
   7485                 if (_BCM_QOS_EGR_MPLS_USED_GET(unit, idx)) {
   7486                     *(map_ids_array + count) = idx | 
   7487                      (_BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS << _BCM_QOS_MAP_SHIFT);
   7488                     *(flags_array + count) = (BCM_QOS_MAP_EGRESS |
   7489                                  (_BCM_QOS_EGR_MPLS_FLAGS_USED_GET(unit, idx)? 
   7490                                   BCM_QOS_MAP_MPLS : BCM_QOS_MAP_L2));
   7491                     count++;
   7492                 }
   7493             }
   7494             for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_DSCP_TABLE) && 
   7495                          (count < array_size)); idx++) {
   7496                 /* For all port dscp profiles have been reserved on TD. */
   7497                 if (SOC_IS_TRIDENT(unit)) {
   7498                     if (idx < SOC_PORT_MAX(unit, all)) {
   7499                         continue;
   7500                     }
   7501                 }
   7502                 if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, idx)) {
   7503                     *(map_ids_array + count) = idx | 
   7504                      (_BCM_QOS_MAP_TYPE_DSCP_TABLE << _BCM_QOS_MAP_SHIFT);
   7505                     *(flags_array + count) = (BCM_QOS_MAP_L3 | 
   7506                                               BCM_QOS_MAP_INGRESS);
   7507                     count++;
   7508                 }
   7509             }
   7510             for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE) && 
   7511                          (count < array_size)); idx++) {
   7512                 if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, idx)) {
   7513                     *(map_ids_array + count) = idx | 
   7514                      (_BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE << _BCM_QOS_MAP_SHIFT);
   7515                     *(flags_array + count) = (BCM_QOS_MAP_L3 | 
   7516                                               BCM_QOS_MAP_EGRESS);
   7517                     count++;
   7518                 }
   7519             }
   7520 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   7521             for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP) && 
   7522                          (count < array_size)); idx++) {
   7523                 if (_BCM_QOS_ING_MPLS_EXP_USED_GET(unit, idx)) {
   7524                     *(map_ids_array + count) = (idx | 
   7525                                       _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS);
   7526                     *(flags_array + count) = (BCM_QOS_MAP_MPLS | 
   7527                                               BCM_QOS_MAP_INGRESS);
   7528                     count++;
   7529                 }
   7530             }
   7531 #ifdef BCM_APACHE_SUPPORT
   7532             if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) {
   7533                 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP_1) &&
   7534                             (count < array_size)); idx++) {
   7535                     if ((bcm_tr_mpls_exp_to_phb_cng_map_usage_get(unit,
   7536                                 (BCM_QOS_MAP_MPLS |
   7537                                  BCM_QOS_MAP_INGRESS),
   7538                                 idx)) == BCM_E_NONE) {
   7539                         *(map_ids_array + count) = (idx |
   7540                                 _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) |
   7541                             (_BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP
   7542                              << _BCM_QOS_MAP_SHIFT);
   7543                         *(flags_array + count) = (BCM_QOS_MAP_OAM_MPLS_EXP |
   7544                                 BCM_QOS_MAP_INGRESS);
   7545                         count++;
   7546                     }
   7547                 }
   7548                 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_EGR_MPLS_EXP_MAP_3) &&
   7549                             (count < array_size)); idx++) {
   7550                     if ((bcm_tr_mpls_exp_to_phb_cng_map_usage_get(unit,
   7551                                 (BCM_QOS_MAP_MPLS |
   7552                                  BCM_QOS_MAP_EGRESS),
   7553                                 idx)) == BCM_E_NONE) {
   7554                         *(map_ids_array + count) = (idx |
   7555                                 _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_EGRESS) |
   7556                             (_BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP
   7557                              << _BCM_QOS_MAP_SHIFT);
   7558                         *(flags_array + count) = (BCM_QOS_MAP_OAM_MPLS_EXP |
   7559                                 BCM_QOS_MAP_EGRESS);
   7560                         count++;
   7561                     }
   7562                 }
   7563             }
   7564 #endif
   7565 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */
   7566 #ifdef BCM_KATANA_SUPPORT
   7567             for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE) &&
   7568                          (count < array_size)); idx++) {
   7569                 if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, idx)) {
   7570                     *(map_ids_array + count) = idx |
   7571                      (_BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE << 
   7572                                                      _BCM_QOS_MAP_SHIFT);
   7573                     *(flags_array + count) = BCM_QOS_MAP_QUEUE;
   7574                     count++;
   7575                 }
   7576             }
   7577 #endif /* BCM_KATANA_SUPPORT */
   7578 #ifdef BCM_SABER2_SUPPORT
   7579             if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   7580                 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE) &&
   7581                             (count < array_size)); idx++) {
   7582                     if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, idx)) {
   7583                         *(map_ids_array + count) = idx |
   7584                             (_BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE << 
   7585                              _BCM_QOS_MAP_SHIFT);
   7586                         *(flags_array + count) = 
   7587                             _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_GET(unit, idx);
   7588                         count++;
   7589                     }
   7590                 }
   7591             }
   7592 #endif /* BCM_KATANA_SUPPORT */
   7593 #ifdef BCM_KATANA2_SUPPORT
   7594             for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP) &&
   7595                          (count < array_size)); idx++) {
   7596                 if (_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, idx)) {
   7597                     *(map_ids_array + count) = idx |
   7598                      (_BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP <<
   7599                                                      _BCM_QOS_MAP_SHIFT);
   7600                     *(flags_array + count) = BCM_QOS_MAP_REPLICATION;
   7601                     count++;
   7602                 }
   7603             }
   7604 #endif /* BCM_KATANA2_SUPPORT */
   7605 #ifdef BCM_TRIDENT2_SUPPORT
   7606             if (soc_feature(unit, soc_feature_fcoe)) {
   7607                 _bcm_td2_qos_fcoe_get(unit, array_size, map_ids_array,
   7608                                       flags_array, &count);
   7609             }
   7610             *array_count = count;
   7611             if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) {
   7612                 rv = _bcm_td2_qos_multi_get(unit, (array_size - count),
   7613                                                   (map_ids_array + count),
   7614                                                   (flags_array + count), &count);
   7615                 if (BCM_SUCCESS(rv)) {
   7616                     *array_count += count;
   7617                 }
   7618                 count = *array_count;
   7619             }
   7620 #endif /* BCM_TRIDENT2_SUPPORT */
   7621 #ifdef BCM_TOMAHAWK_SUPPORT
   7622             if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) {
   7623                 if (count < array_size) {
   7624                     rv = _bcm_th_qos_multi_get(unit, (array_size - count),
   7625                                                      (map_ids_array + count),
   7626                                                      (flags_array + count), array_count);
   7627                     if (BCM_SUCCESS(rv)) {
   7628                         count += *array_count;
   7629                     }
   7630                 }
   7631             }
   7632 #endif /* BCM_TOMAHAWK_SUPPORT */
   7633             *array_count = count;
   7634         }
   7635     }
   7636     QOS_UNLOCK(unit);
   7637     return rv;
   7638 }
   7639 
   7640 /* Function:
   7641 *	   _bcm_tr2_qos_id2idx
   7642 * Purpose:
   7643 *	   Translate map ID into hardware table index used by API
   7644 * Parameters:
   7645 * Returns:
   7646 *	   BCM_E_XXX
   7647 */	   
   7648 int
   7649 _bcm_tr2_qos_id2idx(int unit, int map_id, int *hw_idx)
   7650 {
   7651     int id;
   7652 
   7653     QOS_INIT(unit);
   7654 
   7655     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   7656 
   7657     QOS_LOCK(unit);
   7658     switch (map_id >> _BCM_QOS_MAP_SHIFT) {
   7659     case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
   7660 #ifdef BCM_HURRICANE3_SUPPORT
   7661     case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP:
   7662 #endif
   7663          if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) {
   7664             QOS_UNLOCK(unit);
   7665             return BCM_E_PARAM;
   7666          }
   7667          if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   7668               QOS_UNLOCK(unit);
   7669               return BCM_E_NOT_FOUND;
   7670          } else {
   7671               *hw_idx = QOS_INFO(unit)->pri_cng_hw_idx[id];
   7672          }
   7673          break;
   7674     case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS:
   7675 #ifdef BCM_HURRICANE3_SUPPORT
   7676     case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS:
   7677 #endif
   7678          if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   7679               QOS_UNLOCK(unit);
   7680               return BCM_E_NOT_FOUND;
   7681          } else {
   7682               *hw_idx = QOS_INFO(unit)->egr_mpls_hw_idx[id];
   7683          }
   7684          break;
   7685     case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
   7686          if (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) {
   7687               QOS_UNLOCK(unit);
   7688               return BCM_E_NOT_FOUND;
   7689          } else {
   7690               *hw_idx = QOS_INFO(unit)->dscp_hw_idx[id];
   7691          }
   7692          break;
   7693     case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE:
   7694          if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) {
   7695               QOS_UNLOCK(unit);
   7696               return BCM_E_NOT_FOUND;
   7697          } else {
   7698               *hw_idx =  QOS_INFO(unit)->egr_dscp_hw_idx[id];
   7699          }
   7700          break;
   7701 #ifdef BCM_KATANA_SUPPORT
   7702     case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE:
   7703          if (!_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id)) {
   7704               QOS_UNLOCK(unit);
   7705               return BCM_E_NOT_FOUND;
   7706          } else {
   7707               *hw_idx = QOS_INFO(unit)->offset_map_hw_idx[id];
   7708          }
   7709          break;
   7710 #endif
   7711 #ifdef BCM_SABER2_SUPPORT
   7712     case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE:
   7713          if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   7714              if (!_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) {
   7715                  QOS_UNLOCK(unit);
   7716                  return BCM_E_NOT_FOUND;
   7717              } else {
   7718                  *hw_idx = QOS_INFO(unit)->service_pri_map_hw_idx[id];
   7719              }
   7720          } else {
   7721              QOS_UNLOCK(unit);
   7722              return BCM_E_PARAM;
   7723          }
   7724          break;
   7725 #endif
   7726 #ifdef BCM_KATANA2_SUPPORT
   7727     case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP:
   7728          if (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) {
   7729               QOS_UNLOCK(unit);
   7730               return BCM_E_NOT_FOUND;
   7731          } else {
   7732               *hw_idx = QOS_INFO(unit)->rqe_queue_offset_hw_idx[id];
   7733          }
   7734          break;
   7735 #endif
   7736 
   7737     default:
   7738          QOS_UNLOCK(unit);
   7739          return BCM_E_NOT_FOUND;
   7740     }
   7741     QOS_UNLOCK(unit);
   7742     return BCM_E_NONE;
   7743 }
   7744 
   7745 /* Function:
   7746 *	   _bcm_tr2_qos_id2idx
   7747 * Purpose:
   7748 *	   Translate hardware table index into map ID used by API 
   7749 * Parameters:
   7750 * Returns:
   7751 *	   BCM_E_XXX
   7752 */	   
   7753 int
   7754 _bcm_tr2_qos_idx2id(int unit, int hw_idx, int type, int *map_id)
   7755 {
   7756     int id, num_map;
   7757 
   7758     QOS_INIT(unit);
   7759 
   7760     switch (type) {
   7761     case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP:
   7762         for (id = 0; id <_BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; id++) {
   7763             if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   7764                 if (QOS_INFO(unit)->pri_cng_hw_idx[id] == hw_idx) {
   7765                      *map_id = id | (_BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP
   7766                                                              << _BCM_QOS_MAP_SHIFT);
   7767                      return BCM_E_NONE;
   7768                 }
   7769             }
   7770         }
   7771         break;
   7772 
   7773 #ifdef BCM_HURRICANE3_SUPPORT
   7774      case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP:
   7775          for (id = 0; id <_BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; id++) {
   7776              if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) {
   7777                  if (QOS_INFO(unit)->pri_cng_hw_idx[id] == hw_idx) {
   7778                       *map_id = id | (_BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP
   7779                                                               << _BCM_QOS_MAP_SHIFT);
   7780                       return BCM_E_NONE;
   7781                  }
   7782              }
   7783          }
   7784          break;
   7785 #endif
   7786 
   7787     case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS:
   7788          if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) {
   7789              num_map = soc_mem_index_count(unit, EGR_MPLS_EXP_MAPPING_1m) / 64;
   7790          } else {
   7791              num_map = soc_mem_index_count(unit, EGR_MPLS_PRI_MAPPINGm) / 64;
   7792          }
   7793          for (id = 0; id < num_map; id++) {
   7794               if (_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   7795                    if (QOS_INFO(unit)->egr_mpls_hw_idx[id] == hw_idx) {
   7796                         *map_id = id | (_BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS 
   7797                                                                 << _BCM_QOS_MAP_SHIFT);
   7798                         return BCM_E_NONE;
   7799                    }
   7800               }
   7801          }
   7802          break;
   7803     case _BCM_QOS_MAP_TYPE_DSCP_TABLE:
   7804          num_map = soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].dscp_table) / 64;
   7805          for (id = 0; id < num_map; id++) {
   7806               if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) {
   7807                    if (QOS_INFO(unit)->dscp_hw_idx[id] == hw_idx) {
   7808                         *map_id = id | (_BCM_QOS_MAP_TYPE_DSCP_TABLE 
   7809                                                                 << _BCM_QOS_MAP_SHIFT);
   7810                         return BCM_E_NONE;
   7811                    }
   7812               }
   7813          }
   7814          break;
   7815     case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE:
   7816          num_map = soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].egr_dscp_table) / 64;
   7817          for (id = 0; id < num_map; id++) {
   7818               if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) {
   7819                    if (QOS_INFO(unit)->egr_dscp_hw_idx[id] == hw_idx) {
   7820                         *map_id = id | (_BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE 
   7821                                                                 << _BCM_QOS_MAP_SHIFT);
   7822                         return BCM_E_NONE;
   7823                    }
   7824               }
   7825          }
   7826          break;
   7827 #ifdef BCM_KATANA_SUPPORT
   7828      case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE:
   7829          num_map = soc_mem_index_count(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm) /
   7830                                                  _BCM_QOS_MAP_CHUNK_OFFSET_MAP;
   7831          for (id = 0; id < num_map; id++) {
   7832               if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id)) {
   7833                    if (QOS_INFO(unit)->offset_map_hw_idx[id] == hw_idx) {
   7834                         *map_id = 
   7835                            id | (_BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE << 
   7836                                                            _BCM_QOS_MAP_SHIFT);
   7837                         return BCM_E_NONE;
   7838                    }
   7839               }
   7840          }
   7841          break;
   7842 #endif
   7843 #ifdef BCM_KATANA2_SUPPORT
   7844      case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP:
   7845          num_map = _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP;
   7846          for (id = 0; id < num_map; id++) {
   7847               if (_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) {
   7848                    if (QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] == hw_idx) {
   7849                         *map_id =
   7850                            id | (_BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP <<
   7851                                                            _BCM_QOS_MAP_SHIFT);
   7852                         return BCM_E_NONE;
   7853                    }
   7854               }
   7855          }
   7856          break;
   7857 #endif
   7858 #ifdef BCM_SABER2_SUPPORT
   7859      case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE:
   7860          if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   7861              for (id = 0; id < _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; id++) {
   7862                  if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) {
   7863                      if (QOS_INFO(unit)->service_pri_map_hw_idx[id] == hw_idx) {
   7864                          *map_id = 
   7865                              id | (_BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE << 
   7866                                      _BCM_QOS_MAP_SHIFT);
   7867                          return BCM_E_NONE;
   7868                      }
   7869                  }
   7870              }
   7871          }
   7872          break;
   7873 #endif
   7874 #ifdef BCM_HURRICANE3_SUPPORT
   7875     case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS:
   7876          if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) {
   7877              num_map = soc_mem_index_count(unit, EGR_MPLS_EXP_MAPPING_1m) / 64;
   7878          } else {
   7879              num_map = soc_mem_index_count(unit, EGR_MPLS_PRI_MAPPINGm) / 64;
   7880          }
   7881          for (id = 0; id < num_map; id++) {
   7882               if (_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) {
   7883                    if (QOS_INFO(unit)->egr_mpls_hw_idx[id] == hw_idx) {
   7884                         *map_id = id | (_BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS 
   7885                                                                 << _BCM_QOS_MAP_SHIFT);
   7886                         return BCM_E_NONE;
   7887                    }
   7888               }
   7889          }
   7890          break;
   7891 #endif
   7892     default:
   7893          return BCM_E_NOT_FOUND;
   7894     }
   7895     return BCM_E_NOT_FOUND;
   7896 }
   7897 
   7898 #ifdef INCLUDE_L3
   7899 int
   7900 _bcm_tr2_vp_dscp_map_mode_set(int unit, bcm_gport_t port, int mode)
   7901 {
   7902     source_vp_entry_t svp;
   7903     int rv = BCM_E_NONE;
   7904     uint32 vp = -1;
   7905     int mode_ipv4 = 0, mode_ipv6 = 0;
   7906     /* Deal with different types of gports */
   7907     if (_BCM_QOS_GPORT_IS_VFI_VP_PORT(port)) {
   7908         /* Deal with MiM and MPLS ports */
   7909         if (BCM_GPORT_IS_MIM_PORT(port)) {
   7910             vp = BCM_GPORT_MIM_PORT_ID_GET(port);
   7911             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
   7912                 return BCM_E_BADID;
   7913             }
   7914         } else if BCM_GPORT_IS_VXLAN_PORT(port) {
   7915             vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
   7916             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) {
   7917                 return BCM_E_BADID;
   7918             }
   7919         } else if BCM_GPORT_IS_L2GRE_PORT(port) {
   7920             vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
   7921             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) {
   7922                 return BCM_E_BADID;
   7923             }
   7924         } else {
   7925             vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
   7926             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
   7927                 return BCM_E_BADID;
   7928             }
   7929         }
   7930     }
   7931     rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp);
   7932     if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V4f)) {
   7933         mode_ipv4 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V4f);
   7934     }
   7935     if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V6f)) {
   7936         mode_ipv6 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V6f);
   7937     }
   7938     switch (mode) {
   7939         case BCM_PORT_DSCP_MAP_NONE:
   7940             mode_ipv4 = 0;
   7941             mode_ipv6 = 0;
   7942             break;
   7943         case BCM_PORT_DSCP_MAP_ZERO:
   7944             if (soc_feature(unit, soc_feature_dscp_map_mode_all)) {
   7945                 return BCM_E_UNAVAIL;
   7946             }
   7947             /* coverity[MISSING_BREAK : FALSE] */
   7948         case BCM_PORT_DSCP_MAP_ALL:
   7949             mode_ipv4 = 1;
   7950             mode_ipv6 = 1;
   7951             break;
   7952         case BCM_PORT_DSCP_MAP_IPV4_ONLY:
   7953             mode_ipv4 = 1;
   7954             break;
   7955         case BCM_PORT_DSCP_MAP_IPV6_ONLY:
   7956             mode_ipv6 = 1;
   7957             break;
   7958         case BCM_PORT_DSCP_MAP_IPV4_NONE:
   7959             mode_ipv4 = 0;
   7960             break;
   7961         case BCM_PORT_DSCP_MAP_IPV6_NONE:
   7962             mode_ipv6 = 0;
   7963             break;
   7964     }
   7965     if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V4f)) {
   7966         soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V4f, mode_ipv4);
   7967     }
   7968     if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V6f)) {
   7969         soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V6f, mode_ipv6);
   7970     }
   7971     /* coverity[negative_returns : FALSE] */
   7972     rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp);
   7973     return rv;
   7974 }
   7975 
   7976 /*
   7977  * Function:
   7978  *      _bcm_tr2_vp_dscp_map_set
   7979  * Description:
   7980  *      Set packet dscp to internal priority and internal dscp 
   7981  * Parameters:
   7982  *      unit         - (IN) Device number
   7983  *      port         - (IN) Port number
   7984  *      srccp        - (IN) Packet dscp
   7985  *      mapcp        - (IN) Internal dscp
   7986  *      prio         - (IN) Internal priority
   7987  * Return Value:
   7988  *      BCM_E_XXX
   7989  * 
   7990  * Note:
   7991  *      This function should be invoked after initializing SVP DSCP_PTR
   7992  */
   7993 int
   7994 _bcm_tr2_vp_dscp_map_set(int unit, bcm_gport_t port, int srccp, int mapcp,
   7995                          int prio)
   7996 {
   7997     source_vp_entry_t        svp;
   7998     void                     *entries[2];
   7999     uint32                   old_profile_index = 0;
   8000     int                      index = 0;
   8001     int                      rv = BCM_E_NONE;
   8002     dscp_table_entry_t       dscp_table[64];
   8003     int                      offset = 0, i = 0, cng;   
   8004     void                     *entry;
   8005     int                      vp = -1;
   8006     bcm_module_t             mod_out;
   8007     bcm_port_t               port_out;
   8008     bcm_trunk_t              trunk_out;
   8009 
   8010     /* Deal with different types of gports */
   8011     if (BCM_GPORT_IS_MPLS_PORT(port)) {
   8012         BCM_IF_ERROR_RETURN(
   8013             _bcm_esw_gport_resolve(unit, port, &mod_out, 
   8014                                    &port_out, &trunk_out, &vp));
   8015     } else {
   8016         return BCM_E_PORT;
   8017     }
   8018 
   8019     cng = 0; /* Green */
   8020     if (prio < BCM_PRIO_MIN) {
   8021         return BCM_E_PARAM;
   8022     }
   8023     if (prio & BCM_PRIO_RED) {
   8024         cng = 0x01;  /* Red */
   8025         prio &= ~BCM_PRIO_RED;
   8026     } else if (prio & BCM_PRIO_YELLOW) {
   8027         cng = 0x03;  /* Yellow  */
   8028         prio &= ~BCM_PRIO_YELLOW;
   8029     }
   8030     if ((prio & ~BCM_PRIO_MASK) != 0) {
   8031         return BCM_E_PARAM;
   8032     }
   8033     if (prio > BCM_PRIO_MAX) {
   8034          return BCM_E_PARAM;
   8035     } 
   8036         
   8037     if (!soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_PTRf)) {
   8038         return BCM_E_INTERNAL;
   8039     }
   8040     
   8041     rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp);
   8042     if (BCM_FAILURE(rv)) {
   8043         return rv;
   8044     }
   8045     
   8046     old_profile_index = _BCM_QOS_MAP_CHUNK_DSCP *
   8047                         soc_mem_field32_get(unit, SOURCE_VPm, 
   8048                                             &svp, TRUST_DSCP_PTRf); 
   8049 
   8050     sal_memset(dscp_table, 0, sizeof(dscp_table));
   8051 
   8052     /* Base index of table in hardware */
   8053 
   8054     entries[0] = &dscp_table;
   8055 
   8056     rv =  _bcm_dscp_table_entry_get(unit, old_profile_index, 
   8057                                     _BCM_QOS_MAP_CHUNK_DSCP, entries);
   8058     if (BCM_FAILURE(rv)) {
   8059         return rv;
   8060     }
   8061     
   8062     offset = srccp;
   8063     /* Modify what's needed */
   8064 
   8065     if (offset < 0) {
   8066         for (i = 0; i <= DSCP_CODE_POINT_MAX; i++) {
   8067              entry = &dscp_table[i];
   8068              if (SOC_IS_TRIDENT3X(unit)) {
   8069                  soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCPf, mapcp);
   8070                  soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCP_VALIDf, 1);
   8071                  soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, INT_PRIf, prio);
   8072                  soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, CNGf, cng);
   8073              } else {
   8074                  soc_DSCP_TABLEm_field32_set(unit, entry, DSCPf, mapcp);
   8075                  soc_DSCP_TABLEm_field32_set(unit, entry, PRIf, prio);
   8076                  soc_DSCP_TABLEm_field32_set(unit, entry, CNGf, cng);
   8077              }
   8078         }
   8079     } else {
   8080         entry = &dscp_table[offset];
   8081         if (SOC_IS_TRIDENT3X(unit)) {
   8082             soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCPf, mapcp);
   8083             soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCP_VALIDf, 1);
   8084             soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, INT_PRIf, prio);
   8085             soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, CNGf, cng);
   8086         } else {
   8087             soc_DSCP_TABLEm_field32_set(unit, entry, DSCPf, mapcp);
   8088             soc_DSCP_TABLEm_field32_set(unit, entry, PRIf, prio);
   8089             soc_DSCP_TABLEm_field32_set(unit, entry, CNGf, cng);
   8090         }
   8091     }
   8092 
   8093     /* Add new chunk and store new HW index */
   8094 
   8095     rv = _bcm_dscp_table_entry_add(unit, entries, _BCM_QOS_MAP_CHUNK_DSCP, 
   8096                                    (uint32 *)&index);
   8097     if (BCM_FAILURE(rv)) {
   8098         return rv;
   8099     }
   8100 
   8101     if (index != old_profile_index) {
   8102         soc_mem_field32_set(unit, SOURCE_VPm, &svp, TRUST_DSCP_PTRf,
   8103                             index / _BCM_QOS_MAP_CHUNK_DSCP);
   8104         rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp);
   8105         if (BCM_FAILURE(rv)) {
   8106             return rv;;
   8107         }
   8108     }
   8109 
   8110     rv = _bcm_dscp_table_entry_delete(unit, old_profile_index);
   8111     return rv;
   8112 }
   8113 #endif
   8114 
   8115 /*
   8116  * Function:
   8117  *      _bcm_tr2_vp_ing_pri_cng_set
   8118  * Description:
   8119  *      Set packet priority and cfi to internal priority and color mapping
   8120  * Parameters:
   8121  *      unit         - (IN) Device number
   8122  *      port         - (IN) Port number
   8123  *      untagged     - (IN) For untagged packet (ignore pkt_pri, cfi argumnet)
   8124  *      pkt_pri      - (IN) Packet priority (802.1p cos)
   8125  *      cfi          - (IN) Packet CFI
   8126  *      int_pri      - (IN) Internal priority
   8127  *      color        - (IN) Color
   8128  * Return Value:
   8129  *      BCM_E_XXX
   8130  * Note:
   8131  *      When both pkt_pri and cfi are -1, the setting is for untagged packet
   8132  *      This function should be invoked after initializing SVP DOT1P_PTR
   8133  */
   8134 int
   8135 _bcm_tr2_vp_ing_pri_cng_set(int unit, bcm_gport_t port, int untagged,
   8136                             int pkt_pri, int cfi,
   8137                             int int_pri, bcm_color_t color)
   8138 {
   8139     source_vp_entry_t        svp;
   8140     ing_pri_cng_map_entry_t  map[16];
   8141     phb_mapping_tbl_1_entry_t phb_new_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX]; 
   8142     ing_untagged_phb_entry_t phb;
   8143     void                     *entries[2], *entry;
   8144     uint32                   profile_index, old_profile_index;
   8145     int                      index;
   8146     int                      pkt_pri_cur, pkt_pri_min, pkt_pri_max;
   8147     int                      cfi_cur, cfi_min, cfi_max;
   8148     int                      rv = BCM_E_NONE;
   8149     int                      vp = -1;
   8150     bcm_module_t             mod_out;
   8151     bcm_port_t               port_out;
   8152     bcm_trunk_t              trunk_out;
   8153 
   8154     /* Deal with different types of gports */
   8155     if (BCM_GPORT_IS_MPLS_PORT(port)) {
   8156         BCM_IF_ERROR_RETURN(
   8157             _bcm_esw_gport_resolve(unit, port, &mod_out, 
   8158                                    &port_out, &trunk_out, &vp));
   8159     } else {
   8160         return BCM_E_PORT;
   8161     }
   8162 
   8163     if (pkt_pri < 0) {
   8164         pkt_pri_min = 0;
   8165         pkt_pri_max = 7;
   8166     } else {
   8167         pkt_pri_min = pkt_pri;
   8168         pkt_pri_max = pkt_pri;
   8169     }
   8170 
   8171     if (cfi < 0) {
   8172         cfi_min = 0;
   8173         cfi_max = 1;
   8174     } else {
   8175         cfi_min = cfi;
   8176         cfi_max = cfi;
   8177     }
   8178 
   8179     if (!soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DOT1P_PTRf)) {
   8180         return BCM_E_INTERNAL;
   8181     }
   8182     
   8183     /* Get profile index from source_vp table. */
   8184     rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp);
   8185     if (BCM_FAILURE(rv)) {
   8186         return rv;
   8187     }
   8188 
   8189     old_profile_index =
   8190         soc_mem_field32_get(unit, SOURCE_VPm, &svp, TRUST_DOT1P_PTRf) * _BCM_QOS_MAP_CHUNK_PRI_CNG;
   8191 
   8192     if (SOC_IS_TRIDENT3X(unit)) {
   8193         entries[0] = phb_new_map;
   8194     } else {
   8195         entries[0] = map;
   8196     }
   8197     entries[1] = &phb;
   8198 
   8199     rv = _bcm_ing_pri_cng_map_entry_get(unit, old_profile_index, _BCM_QOS_MAP_CHUNK_PRI_CNG, entries);
   8200     if (BCM_FAILURE(rv)) {
   8201         return rv;
   8202     }    
   8203 
   8204     if (untagged) {
   8205          if (SOC_IS_TRIDENT3X(unit)) {
   8206              /* TD3 tagged and untagged shared the same table
   8207                 bit 5 is indicating untaged packet or not */
   8208              /* Offset within table */
   8209              index  = 1 << 4 | pkt_pri << 1 | cfi;
   8210 
   8211              /* Modify what's needed */
   8212              entry = &phb_new_map[index];
   8213              soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry,
   8214                                  INT_PRIf, int_pri);
   8215              soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry,
   8216                                  CNGf, _BCM_COLOR_ENCODING(unit, color));
   8217         } else {
   8218             if (int_pri >= 0) {
   8219                 soc_mem_field32_set(unit, ING_UNTAGGED_PHBm, &phb, PRIf, int_pri);
   8220             }
   8221             if (color >= 0) {
   8222                 soc_mem_field32_set(unit, ING_UNTAGGED_PHBm, &phb, CNGf,
   8223                                     _BCM_COLOR_ENCODING(unit, color));
   8224             }
   8225         }
   8226     } else {
   8227         for (pkt_pri_cur = pkt_pri_min; pkt_pri_cur <= pkt_pri_max;
   8228              pkt_pri_cur++) {
   8229             for (cfi_cur = cfi_min; cfi_cur <= cfi_max; cfi_cur++) {
   8230                 index = (pkt_pri_cur << 1) | cfi_cur;
   8231                 if (int_pri >= 0) {
   8232                     if (SOC_IS_TRIDENT3X(unit)) {
   8233                         soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index],
   8234                                             INT_PRIf, int_pri);
   8235                     } else {
   8236                         soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &map[index],
   8237                                             PRIf, int_pri);
   8238                     }
   8239                 }
   8240                 if (color >= 0) {
   8241                     if (SOC_IS_TRIDENT3X(unit)) {
   8242                         soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index],
   8243                                             CNGf, _BCM_COLOR_ENCODING(unit, color));
   8244                     } else {
   8245                         soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &map[index],
   8246                                             CNGf, _BCM_COLOR_ENCODING(unit, color));
   8247                     }
   8248                 }
   8249             }
   8250         }
   8251     }
   8252 
   8253     rv = _bcm_ing_pri_cng_map_entry_add(unit, entries, 16, &profile_index);
   8254     if (BCM_FAILURE(rv)) {
   8255         return rv;
   8256     }
   8257 
   8258     if (profile_index != old_profile_index) {
   8259         soc_mem_field32_set(unit, SOURCE_VPm, &svp, TRUST_DOT1P_PTRf,
   8260                             profile_index / 16);
   8261         rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp);
   8262         if (BCM_FAILURE(rv)) {
   8263             return rv;
   8264         }
   8265     }
   8266 
   8267     rv = _bcm_ing_pri_cng_map_entry_delete(unit, old_profile_index);
   8268     if (BCM_FAILURE(rv)) {
   8269         return rv;
   8270     }
   8271 
   8272     return rv;
   8273 }
   8274 
   8275 #ifdef INCLUDE_L3
   8276 int
   8277 _bcm_tr2_vp_dscp_map_mode_get(int unit, bcm_gport_t port, int *mode)
   8278 {
   8279     source_vp_entry_t svp;
   8280     int rv = BCM_E_NONE;
   8281     uint32 vp = -1;
   8282     int mode_ipv4 = 0, mode_ipv6 = 0;
   8283     /* Deal with different types of gports */
   8284     if (_BCM_QOS_GPORT_IS_VFI_VP_PORT(port)) {
   8285         /* Deal with MiM and MPLS ports */
   8286         if (BCM_GPORT_IS_MIM_PORT(port)) {
   8287             vp = BCM_GPORT_MIM_PORT_ID_GET(port);
   8288             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
   8289                 return BCM_E_BADID;
   8290             }
   8291         } else if BCM_GPORT_IS_VXLAN_PORT(port) {
   8292             vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
   8293             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) {
   8294                 return BCM_E_BADID;
   8295             }
   8296         } else if BCM_GPORT_IS_L2GRE_PORT(port) {
   8297             vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
   8298             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) {
   8299                 return BCM_E_BADID;
   8300             }
   8301         } else {
   8302             vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
   8303             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
   8304                 return BCM_E_BADID;
   8305             }
   8306         }
   8307     }
   8308     rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp);
   8309     if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V4f)) {
   8310         mode_ipv4 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V4f);
   8311     }
   8312     if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V6f)) {
   8313         mode_ipv6 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V6f);
   8314     }
   8315     if (mode_ipv4 && mode_ipv6) {
   8316         if (soc_feature(unit, soc_feature_dscp_map_mode_all)) {
   8317             *mode = BCM_PORT_DSCP_MAP_ALL;
   8318         } else {
   8319             *mode = BCM_PORT_DSCP_MAP_ZERO;
   8320         }
   8321     } else if (mode_ipv4) {
   8322         *mode = BCM_PORT_DSCP_MAP_IPV4_ONLY;
   8323     } else if (mode_ipv6) {
   8324         *mode = BCM_PORT_DSCP_MAP_IPV6_ONLY;
   8325     } else {
   8326         *mode = BCM_PORT_DSCP_MAP_NONE;
   8327     }
   8328     return rv;
   8329 }
   8330 
   8331 
   8332 /*
   8333  * Function:
   8334  *      _bcm_tr2_vp_dscp_map_get
   8335  * Description:
   8336  *      Get packet dscp to internal priority and internal dscp 
   8337  * Parameters:
   8338  *      unit         - (IN) Device number
   8339  *      port         - (IN) Port number
   8340  *      srccp        - (IN) Packet dscp
   8341  *      mapcp        - (OUT) Internal dscp
   8342  *      prio         - (OUT) Internal priority
   8343  * Return Value:
   8344  *      BCM_E_XXX
   8345  */
   8346 int
   8347 _bcm_tr2_vp_dscp_map_get(int unit, bcm_gport_t port, int srccp, int *mapcp,
   8348                       int *prio)
   8349 {
   8350     source_vp_entry_t       svp;
   8351     int                     rv = BCM_E_NONE;
   8352     int                     index = 0;
   8353     int                     base;
   8354     int                     cng;
   8355     uint32 de[SOC_MAX_MEM_FIELD_WORDS]; 
   8356     int                     vp = -1;
   8357     bcm_module_t            mod_out;
   8358     bcm_port_t              port_out;
   8359     bcm_trunk_t             trunk_out;
   8360 
   8361     /* Deal with different types of gports */
   8362     if (BCM_GPORT_IS_MPLS_PORT(port)) {
   8363         BCM_IF_ERROR_RETURN(
   8364             _bcm_esw_gport_resolve(unit, port, &mod_out, 
   8365                                    &port_out, &trunk_out, &vp));
   8366     } else {
   8367         return BCM_E_PORT;
   8368     }
   8369 
   8370     if (!soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_PTRf)) {
   8371         return BCM_E_INTERNAL;
   8372     }    
   8373     
   8374     rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp);
   8375     if (BCM_FAILURE(rv)) {
   8376         return rv;
   8377     }
   8378     
   8379     index = soc_mem_field32_get(unit, SOURCE_VPm, &svp, TRUST_DSCP_PTRf);
   8380     
   8381     if (srccp < -1 || srccp > DSCP_CODE_POINT_MAX ||
   8382         mapcp == NULL || prio == NULL) {
   8383         return BCM_E_PARAM;
   8384     }
   8385 
   8386     /* look up in DSCP_TABLEm */
   8387     if (srccp < 0) {
   8388         srccp = 0;
   8389     }
   8390     
   8391     base = (index * DSCP_CODE_POINT_CNT);
   8392 
   8393     if (SOC_IS_TRIDENT3X(unit)) {
   8394         SOC_IF_ERROR_RETURN(
   8395                 READ_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ANY, base + srccp, &de));
   8396         *mapcp = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &de, DSCPf);
   8397         *prio = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &de, INT_PRIf);
   8398 
   8399         cng   = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &de, CNGf);
   8400     } else {
   8401         SOC_IF_ERROR_RETURN(
   8402              READ_DSCP_TABLEm(unit, MEM_BLOCK_ANY, base + srccp, &de));
   8403         *mapcp = soc_DSCP_TABLEm_field32_get(unit, &de, DSCPf);
   8404         *prio = soc_DSCP_TABLEm_field32_get(unit, &de, PRIf);
   8405 
   8406         cng   = soc_DSCP_TABLEm_field32_get(unit, &de, CNGf);
   8407     }
   8408 
   8409     if (cng == 1) {
   8410         *prio |= BCM_PRIO_RED;
   8411     } else if (cng == 3) {
   8412         *prio |= BCM_PRIO_YELLOW;
   8413     } else if (cng != 0) {
   8414         *prio |= BCM_PRIO_DROP_FIRST;
   8415     }
   8416 
   8417     return BCM_E_NONE;
   8418 }
   8419 #endif
   8420 
   8421 #ifdef BCM_SABER2_SUPPORT
   8422 /* Called from OAM module to get the index and the priority mode
   8423  * configured. 
   8424  */
   8425 int _bcm_sb2_ing_service_pri_map_info_get(int unit, int pri_map_id,
   8426                                           uint32 *hw_idx, uint32 *pri_mode)
   8427 {
   8428     int id = 0;
   8429     if (soc_feature(unit, soc_feature_oam_service_pri_map)) {
   8430         id = pri_map_id & _BCM_QOS_MAP_TYPE_MASK;
   8431         if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) {
   8432             *hw_idx = QOS_INFO(unit)->service_pri_map_hw_idx[id] * 
   8433                                     _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP; 
   8434             *pri_mode = _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_GET(unit, id); 
   8435             return BCM_E_NONE;
   8436         }
   8437     } else {
   8438         return BCM_E_UNAVAIL;
   8439     }
   8440     /* Invalid unit or pri_map_id if it reaches here */
   8441     return BCM_E_PARAM;
   8442 }
   8443 
   8444 int _bcm_sb2_service_pri_map_info_id_get(int unit, uint32 hw_idx, int *pri_map_id)
   8445 {
   8446    return _bcm_tr2_qos_idx2id(unit, (hw_idx / _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP),
   8447                                _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE, pri_map_id); 
   8448 }
   8449 
   8450 int _bcm_sb2_service_pri_map_reference_add(int unit, int pri_map_id)
   8451 {
   8452     int id = 0;
   8453     id = pri_map_id & _BCM_QOS_MAP_TYPE_MASK;
   8454     BCM_IF_ERROR_RETURN(_bcm_service_pri_map_table_entry_reference(unit,
   8455                 ((QOS_INFO(unit)->service_pri_map_hw_idx[id]) *
   8456                  _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP),
   8457                 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP));
   8458     return BCM_E_NONE;
   8459 }
   8460 #endif
   8461 
   8462 /*
   8463  * Function:
   8464  *      _bcm_tr2_vp_ing_pri_cng_get
   8465  * Description:
   8466  *      Get packet priority and cfi to internal priority and color mapping
   8467  * Parameters:
   8468  *      unit         - (IN) Device number
   8469  *      port         - (IN) Port number
   8470  *      untagged     - (IN) For untagged packet (ignore pkt_pri, cfi argumnet)
   8471  *      pkt_pri      - (IN) Packet priority (802.1p cos)
   8472  *      cfi          - (IN) Packet CFI
   8473  *      int_pri      - (OUT) Internal priority
   8474  *      color        - (OUT) Color
   8475  * Return Value:
   8476  *      BCM_E_XXX
   8477  * Note:
   8478  *      When both pkt_pri and cfi are -1, the setting is for untagged packet
   8479  */
   8480 int
   8481 _bcm_tr2_vp_ing_pri_cng_get(int unit, bcm_gport_t port, int untagged,
   8482                             int pkt_pri, int cfi,
   8483                             int *int_pri, bcm_color_t *color)
   8484 {
   8485     source_vp_entry_t        svp;
   8486     ing_pri_cng_map_entry_t  map[16];
   8487     phb_mapping_tbl_1_entry_t phb_new_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX];
   8488     ing_untagged_phb_entry_t phb;
   8489     void                     *entries[2];
   8490     uint32                   profile_index;
   8491     int                      index;
   8492     int                      hw_color;
   8493     int                      vp = -1;
   8494     bcm_module_t             mod_out;
   8495     bcm_port_t               port_out;
   8496     bcm_trunk_t              trunk_out;
   8497 
   8498     /* Deal with different types of gports */
   8499     if (BCM_GPORT_IS_MPLS_PORT(port)) {
   8500         BCM_IF_ERROR_RETURN(
   8501             _bcm_esw_gport_resolve(unit, port, &mod_out, 
   8502                                    &port_out, &trunk_out, &vp));
   8503     } else {
   8504         return BCM_E_PORT;
   8505     }
   8506 
   8507     if (!soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_PTRf)) {
   8508         return BCM_E_INTERNAL;
   8509     }    
   8510     
   8511     BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp));
   8512 
   8513     profile_index =
   8514         soc_mem_field32_get(unit, SOURCE_VPm, &svp, TRUST_DOT1P_PTRf) * _BCM_QOS_MAP_CHUNK_PRI_CNG;
   8515 
   8516     if (SOC_IS_TRIDENT3X(unit)) {
   8517         entries[0] = phb_new_map;
   8518     } else {
   8519         entries[0] = map;
   8520     }
   8521     entries[1] = &phb;
   8522 
   8523     BCM_IF_ERROR_RETURN
   8524         (_bcm_ing_pri_cng_map_entry_get(unit, profile_index, _BCM_QOS_MAP_CHUNK_PRI_CNG, entries));
   8525     if (untagged) {
   8526         if (SOC_IS_TRIDENT3X(unit)) {
   8527             index = 1<<4 | (pkt_pri << 1) | cfi;
   8528             if (int_pri != NULL) {
   8529                 *int_pri = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index], PRIf);
   8530             }
   8531             if (color != NULL) {
   8532                 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index], CNGf);
   8533                 *color = _BCM_COLOR_DECODING(unit, hw_color);
   8534             }
   8535         } else {
   8536             if (int_pri != NULL) {
   8537                 *int_pri = soc_mem_field32_get(unit, ING_UNTAGGED_PHBm, &phb,
   8538                                                PRIf);
   8539             }
   8540             if (color != NULL) {
   8541                 hw_color = soc_mem_field32_get(unit, ING_UNTAGGED_PHBm, &phb,
   8542                                            CNGf);
   8543                 *color = _BCM_COLOR_DECODING(unit, hw_color);
   8544             }
   8545         }
   8546     } else {
   8547         index = (pkt_pri << 1) | cfi;
   8548         if (SOC_IS_TRIDENT3X(unit)) {
   8549             if (int_pri != NULL) {
   8550                 *int_pri = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index], PRIf);
   8551             }
   8552             if (color != NULL) {
   8553                 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index], CNGf);
   8554                 *color = _BCM_COLOR_DECODING(unit, hw_color);
   8555             }
   8556         } else {
   8557             if (int_pri != NULL) {
   8558                 *int_pri = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &map[index],
   8559                                                PRIf);
   8560             }
   8561             if (color != NULL) {
   8562                 hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &map[index],
   8563                                                CNGf);
   8564                 *color = _BCM_COLOR_DECODING(unit, hw_color);
   8565             }
   8566         }
   8567     }
   8568 
   8569     return BCM_E_NONE;
   8570 }
   8571 
   8572 #if defined(BCM_TRIDENT3_SUPPORT) && defined(INCLUDE_L3)
   8573 int
   8574 bcm_td3_mpls_combo_add (int unit, uint32 flags, bcm_mpls_exp_map_t *mpls_map,
   8575         int map_id, uint32 hw_idx, uint32 entry_per_index)
   8576 {
   8577     int rv = BCM_E_NONE;
   8578     bcm_qos_map_t qos_map;
   8579 
   8580       if (flags == BCM_QOS_MAP_EGRESS)
   8581       {
   8582           if (mpls_map == NULL) {
   8583              return BCM_E_PARAM;
   8584           }
   8585           sal_memset(&qos_map, 0x0, sizeof(bcm_qos_map_t));
   8586           qos_map.int_pri  = mpls_map->priority;
   8587           qos_map.exp      = mpls_map->exp;
   8588           qos_map.pkt_pri  = mpls_map->pkt_pri;
   8589           qos_map.pkt_cfi  = mpls_map->pkt_cfi;
   8590           /*color validation check to continue Legacy
   8591            *behaviour of mpls exp map config*/
   8592           if (mpls_map->color > bcmColorRed) {
   8593               mpls_map->color = bcmColorGreen;
   8594           }
   8595           qos_map.color    = mpls_map->color;
   8596           rv = bcm_td3_l2_egr_combo_add (unit, BCM_QOS_MAP_MPLS | BCM_QOS_MAP_EGRESS, &qos_map, map_id,
   8597                       &hw_idx, _BCM_QOS_MAP_CHUNK_EGR_MPLS);
   8598       }
   8599     return rv;
   8600 }
   8601 #endif
   8602 
   8603 #endif