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


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        qos.c
      8  * Purpose:     Trident2 QoS functions
      9  */
     10 
     11 #include <soc/mem.h>
     12 #include <soc/debug.h>
     13 #include <soc/cm.h>
     14 #include <soc/drv.h>
     15 #include <soc/register.h>
     16 #include <soc/memory.h>
     17 #include <soc/hash.h>
     18 #include <soc/l2x.h>
     19 #include <soc/trident2.h>
     20 #include <bcm/l2.h>
     21 #include <bcm/error.h>
     22 #include <bcm/stat.h>
     23 #include <bcm/fcoe.h>
     24 #include <bcm_int/esw/trx.h>
     25 #include <bcm_int/esw/l2.h>
     26 #include <bcm_int/esw/qos.h>
     27 #include <bcm_int/esw/fcoe.h>
     28 #include <bcm_int/esw/trident.h>
     29 #include <bcm_int/esw/trident2.h>
     30 #include <bcm_int/esw/triumph2.h>
     31 #include <bcm_int/esw/xgs3.h>
     32 #ifdef BCM_TRIDENT3_SUPPORT
     33 #include <bcm_int/esw/trident3.h>
     34 #endif
     35 
     36 #ifdef BCM_TRIDENT2_SUPPORT
     37 
     38 #define _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP          8
     39 #define _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP         64
     40 #define _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP     16
     41 #define _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP 64
     42 
     43 #define _BCM_QOS_MAX_VFT_PRIORITIES             8
     44 #define _BCM_QOS_MAX_VSAN_PRIORITIES            16
     45 #define _BCM_QOS_MAX_PKT_PRIORITIES             8
     46 #define _BCM_QOS_MAX_INT_PRIORITIES             16
     47 #define _BCM_QOS_MAX_PKT_DES             2
     48 #define _BCM_QOS_PRI_BIT_SHIFT           2
     49 
     50 #define _BCM_QOS_MAX_VFT_PRI_MAPS                  \
     51     ((SOC_MEM_IS_VALID(unit, ING_VFT_PRI_MAPm)) ?   \
     52             (soc_mem_index_count(unit, ING_VFT_PRI_MAPm)/ \
     53              _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP) : 0)
     54 
     55 #define _BCM_QOS_MAX_VSAN_PRI_MAPS                   \
     56             (soc_mem_index_count(unit, EGR_VSAN_INTPRI_MAPm)/ \
     57              _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP)
     58 
     59 #define _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS                   \
     60             (soc_mem_index_count(unit, ING_ETAG_PCP_MAPPINGm)/ \
     61              _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP)
     62 
     63 #define _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS                   \
     64             (soc_mem_is_valid(unit, VFT_QOS_INFO(unit)->egr_etag_mem) ? \
     65              (soc_mem_index_count(unit, VFT_QOS_INFO(unit)->egr_etag_mem)/ \
     66               _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP) : 0)
     67 
     68 #define _BCM_QOS_MAX_VFT_PRI_MAP_IDS         ((_BCM_QOS_MAX_VFT_PRI_MAPS) * 8)
     69 #define _BCM_QOS_MAX_VSAN_PRI_MAP_IDS        ((_BCM_QOS_MAX_VSAN_PRI_MAPS) * 8)
     70 #define _BCM_QOS_MAX_L2_VLAN_ETAG_MAP_IDS    ((_BCM_QOS_MAX_L2_VLAN_ETAG_MAPS)\
     71                                           * _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP)
     72 #define _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAP_IDS    ((_BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS)\
     73 											  * _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP)
     74 
     75 
     76 #define _BCM_QOS_MAP_TYPE_MASK           0x7ff
     77 #define _BCM_QOS_MAP_SHIFT                  11
     78 
     79 #define _BCM_QOS_NO_MAP                     -1
     80 
     81 typedef struct _bcm_td2_qos_bookkeeping_s {
     82     SHR_BITDCL *ing_vft_pri_map;
     83     uint32     *ing_vft_pri_map_hwidx;
     84     SHR_BITDCL *ing_l2_vlan_etag_map;
     85     uint32     *ing_l2_vlan_etag_map_hwidx;   
     86     SHR_BITDCL *egr_vft_pri_map;
     87     uint32     *egr_vft_pri_map_hwidx;
     88     SHR_BITDCL *egr_vsan_intpri_map;
     89     uint32     *egr_vsan_intpri_map_hwidx;
     90     SHR_BITDCL *egr_l2_vlan_etag_map;
     91     uint32     *egr_l2_vlan_etag_map_hwidx;
     92     sal_mutex_t qos_mutex;
     93     soc_mem_t  egr_etag_mem;
     94 } _bcm_td2_qos_bookkeeping_t;
     95 
     96 static _bcm_td2_qos_bookkeeping_t _bcm_td2_qos_bk_info[BCM_MAX_NUM_UNITS];
     97 static int _bcm_td2_qos_initialized[BCM_MAX_NUM_UNITS] = { 0 };
     98 
     99 #define VFT_QOS_INFO(_unit_) (&_bcm_td2_qos_bk_info[_unit_])
    100 
    101 #define _BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_GET(_u_, _identifier_) \
    102         SHR_BITGET(VFT_QOS_INFO(_u_)->ing_vft_pri_map, (_identifier_))
    103 #define _BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_SET(_u_, _identifier_) \
    104         SHR_BITSET(VFT_QOS_INFO((_u_))->ing_vft_pri_map, (_identifier_))
    105 #define _BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_CLR(_u_, _identifier_) \
    106         SHR_BITCLR(VFT_QOS_INFO((_u_))->ing_vft_pri_map, (_identifier_))
    107 
    108 #define _BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_GET(_u_, _identifier_) \
    109         SHR_BITGET(VFT_QOS_INFO(_u_)->ing_l2_vlan_etag_map, (_identifier_))
    110 #define _BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_SET(_u_, _identifier_) \
    111         SHR_BITSET(VFT_QOS_INFO((_u_))->ing_l2_vlan_etag_map, (_identifier_))
    112 #define _BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_CLR(_u_, _identifier_) \
    113         SHR_BITCLR(VFT_QOS_INFO((_u_))->ing_l2_vlan_etag_map, (_identifier_))
    114 
    115 #define _BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_GET(_u_, _identifier_) \
    116         SHR_BITGET(VFT_QOS_INFO(_u_)->egr_vft_pri_map, (_identifier_))
    117 #define _BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_SET(_u_, _identifier_) \
    118         SHR_BITSET(VFT_QOS_INFO((_u_))->egr_vft_pri_map, (_identifier_))
    119 #define _BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_CLR(_u_, _identifier_) \
    120         SHR_BITCLR(VFT_QOS_INFO((_u_))->egr_vft_pri_map, (_identifier_))
    121 
    122 #define _BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_GET(_u_, _identifier_) \
    123         SHR_BITGET(VFT_QOS_INFO(_u_)->egr_vsan_intpri_map, (_identifier_))
    124 #define _BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_SET(_u_, _identifier_) \
    125         SHR_BITSET(VFT_QOS_INFO((_u_))->egr_vsan_intpri_map, (_identifier_))
    126 #define _BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_CLR(_u_, _identifier_) \
    127         SHR_BITCLR(VFT_QOS_INFO((_u_))->egr_vsan_intpri_map, (_identifier_))
    128 
    129 #define _BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_GET(_u_, _identifier_) \
    130         SHR_BITGET(VFT_QOS_INFO(_u_)->egr_l2_vlan_etag_map, (_identifier_))
    131 #define _BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_SET(_u_, _identifier_) \
    132         SHR_BITSET(VFT_QOS_INFO((_u_))->egr_l2_vlan_etag_map, (_identifier_))
    133 #define _BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_CLR(_u_, _identifier_) \
    134         SHR_BITCLR(VFT_QOS_INFO((_u_))->egr_l2_vlan_etag_map, (_identifier_))
    135 
    136 
    137 #define QOS_LOCK(unit) \
    138         sal_mutex_take(VFT_QOS_INFO(unit)->qos_mutex, sal_mutex_FOREVER);
    139 #define QOS_UNLOCK(unit) \
    140         sal_mutex_give(VFT_QOS_INFO(unit)->qos_mutex);
    141 
    142 #define QOS_INIT(unit)                                    \
    143     do {                                                  \
    144         if ((unit < 0) || (unit >= BCM_MAX_NUM_UNITS)) {  \
    145             return BCM_E_UNIT;                            \
    146         }                                                 \
    147         if (!_bcm_td2_qos_initialized[unit]) {            \
    148             return BCM_E_INIT;                            \
    149         }                                                 \
    150     } while (0)
    151 
    152 
    153 #define TD2_HW_COLOR_GREEN   0
    154 #define TD2_HW_COLOR_YELLOW  3
    155 #define TD2_HW_COLOR_RED     1
    156 #define TD2_HW_COLOR_ERROR  -1
    157 
    158 
    159 /*
    160  * Function: 
    161  *     _bcm_td2_qos_map_id_alloc
    162  * Purpose:
    163  *     Allocate a new QOS map ID.  The bitmap given contains bits set for 
    164  *     existing IDs, so find the first empty one, set it, and return it.
    165  * Parameters:
    166  *     unit   - (IN) Unit to be operated on
    167  *     bitmap - (IN/OUT)
    168  *     id     - (OUT)
    169  * Returns:
    170  *     BCM_E_XXX
    171  */
    172 STATIC int
    173 _bcm_td2_qos_map_id_alloc(int unit, SHR_BITDCL *bitmap, int *id, 
    174                           int map_size)
    175 {
    176     int i;
    177 
    178     for (i = 0; i < map_size; i++) {
    179         if (!SHR_BITGET(bitmap, i)) {
    180             SHR_BITSET(bitmap, i);
    181             *id = i;
    182             return BCM_E_NONE;
    183         }
    184     }
    185 
    186     return BCM_E_RESOURCE;
    187 }
    188 
    189 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP
    190 /* 
    191  * Function:
    192  *      _bcm_td2_qos_sw_dump
    193  * Purpose:
    194  *      Displays QOS software state info
    195  * Parameters:
    196  *      unit        : (IN) Device Unit Number
    197  * Returns:
    198  *      NONE
    199  */
    200 void
    201 _bcm_td2_qos_sw_dump(int unit)
    202 {
    203     int i;
    204     if (!_bcm_td2_qos_initialized[unit]) {
    205         LOG_CLI((BSL_META_U(unit,
    206                      "ERROR: QOS module not initialized on Unit:%d \n"), unit));
    207         return;
    208     }
    209 
    210     LOG_CLI((BSL_META_U(unit,
    211                         "QOS: ING_L2_VLAN_ETAG_MAP info \n")));
    212     for (i = 0; i < _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS; i++) {
    213         if (_BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, i)) {
    214             LOG_CLI((BSL_META_U(unit,
    215                          "    map id:%4d    HW index:%4d\n"), i, 
    216                          VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx[i]));                         
    217         }
    218     }
    219 
    220     LOG_CLI((BSL_META_U(unit,
    221                         "QOS: EGR_L2_VLAN_ETAG_MAP info \n")));
    222     for (i = 0; i < _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS; i++) {
    223         if (_BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, i)) {
    224             LOG_CLI((BSL_META_U(unit,
    225                          "    map id:%4d    HW index:%4d\n"), i, 
    226                          VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx[i]));                         
    227         }
    228     }    
    229 
    230     LOG_CLI((BSL_META_U(unit,
    231                         "QOS: ING_VFT_PRI_MAP info \n")));
    232     for (i = 0; i < _BCM_QOS_MAX_VFT_PRI_MAPS; i++) {
    233         if (_BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_GET(unit, i)) {
    234             LOG_CLI((BSL_META_U(unit,
    235                          "    map id:%4d    HW index:%4d\n"), i, 
    236                          VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx[i]));                         
    237         }
    238     } 
    239     
    240     LOG_CLI((BSL_META_U(unit,
    241                         "QOS: EGR_VFT_PRI_MAP info \n")));
    242     for (i = 0; i < _BCM_QOS_MAX_VFT_PRI_MAPS; i++) {
    243         if (_BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_GET(unit, i)) {
    244             LOG_CLI((BSL_META_U(unit,
    245                          "    map id:%4d    HW index:%4d\n"), i, 
    246                          VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx[i]));                         
    247         }
    248     }
    249     
    250     LOG_CLI((BSL_META_U(unit,
    251                         "QOS: EGR_VSAN_PRI_MAP info \n")));
    252     for (i = 0; i < _BCM_QOS_MAX_VSAN_PRI_MAPS; i++) {
    253         if (_BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_GET(unit, i)) {
    254             LOG_CLI((BSL_META_U(unit,
    255                          "    map id:%4d    HW index:%4d\n"), i, 
    256                          VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx[i]));                         
    257         }
    258     }     
    259 }
    260 
    261 #endif
    262 #ifdef BCM_WARM_BOOT_SUPPORT
    263 
    264 #define _BCM_TD2_REINIT_INVALID_HW_IDX  0xff    /* used as an invalid hw idx */
    265 
    266 /* 
    267  * Function:
    268  *      _bcm_td2_qos_reinit_scache_len_get
    269  * Purpose:
    270  *      Helper utility to determine scache details.
    271  * Parameters:
    272  *      unit        : (IN) Device Unit Number
    273  *      scache_len  : (OUT) Total required scache length
    274  * Returns:
    275  *      BCM_E_XXX
    276  */
    277 int
    278 _bcm_td2_qos_reinit_scache_len_get(int unit, uint32 *scache_len)
    279 {
    280     if (scache_len == NULL) {
    281         return BCM_E_PARAM;
    282     }
    283 
    284     /* TD2 wb will store bookeeping data as 4 bytes per hw_index */
    285     *scache_len += _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS * sizeof(uint32);
    286     *scache_len += _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS * sizeof(uint32);
    287     *scache_len += _BCM_QOS_MAX_VFT_PRI_MAPS * 2 * sizeof(uint32);
    288     *scache_len += _BCM_QOS_MAX_VSAN_PRI_MAPS * sizeof(uint32);
    289     
    290     return BCM_E_NONE;
    291 }
    292 
    293 int
    294 _bcm_td2_qos_reinit_from_hw_state(int unit, soc_mem_t mem, soc_field_t field,
    295                                   uint8 map_type, SHR_BITDCL *hw_idx_bmp, 
    296                                   int hw_idx_bmp_len)
    297 {
    298     int         rv = BCM_E_NONE;
    299     int         idx, min_idx, max_idx, map_size, map_id, hw_prof_idx;
    300     uint32      buf[SOC_MAX_MEM_FIELD_WORDS];
    301     uint32      *hw_idx_table;
    302     SHR_BITDCL  *map_bmp;
    303 
    304     switch (map_type) {
    305     case _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP:
    306         map_bmp = VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map;
    307         hw_idx_table = VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx;
    308         map_size = _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS;
    309         break;
    310     case _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP:
    311         map_bmp = VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map;
    312         hw_idx_table = VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx;
    313         map_size = _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS;
    314         break;
    315     case _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP:
    316         map_bmp = VFT_QOS_INFO(unit)->ing_vft_pri_map;
    317         hw_idx_table = VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx;
    318         map_size = _BCM_QOS_MAX_VFT_PRI_MAPS;    
    319         break;
    320     case _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP:
    321         map_bmp = VFT_QOS_INFO(unit)->egr_vft_pri_map;
    322         hw_idx_table = VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx;
    323         map_size = _BCM_QOS_MAX_VFT_PRI_MAPS;    
    324         break;
    325     case _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP:
    326         map_bmp = VFT_QOS_INFO(unit)->egr_vsan_intpri_map;
    327         hw_idx_table = VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx;
    328         map_size = _BCM_QOS_MAX_VSAN_PRI_MAPS;    
    329         break;
    330     default:
    331         return BCM_E_PARAM;
    332     }
    333 
    334     min_idx = soc_mem_index_min(unit, mem);
    335     max_idx = soc_mem_index_max(unit, mem);
    336 
    337     for (idx = min_idx; idx <= max_idx; idx++) {
    338         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, idx, &buf);
    339         if (SOC_FAILURE(rv)) {
    340             LOG_ERROR(BSL_LS_BCM_QOS,
    341                       (BSL_META_U(unit,
    342                                   "Error(%s) reading mem(%d) at "
    343                                   "index:%d \n"), soc_errmsg(rv), mem, idx));
    344             return rv;
    345         }
    346 
    347         hw_prof_idx = soc_mem_field32_get(unit, mem, &buf, field);
    348 
    349         if (hw_prof_idx > (hw_idx_bmp_len - 1)) {
    350             LOG_ERROR(BSL_LS_BCM_QOS,
    351                       (BSL_META_U(unit,
    352                                   "Invalid profile(%d) in mem(%d) "
    353                                   "at index:%d\n"), hw_prof_idx, mem, idx));
    354             return BCM_E_INTERNAL;
    355         }
    356         if (hw_prof_idx && (!SHR_BITGET(hw_idx_bmp, hw_prof_idx))) {
    357             /* non-zero profile id and not stored previously */
    358             BCM_IF_ERROR_RETURN(_bcm_td2_qos_map_id_alloc(unit, map_bmp, &map_id,
    359                                      map_size));
    360             if (map_id < 0) {
    361                 LOG_ERROR(BSL_LS_BCM_QOS,
    362                           (BSL_META_U(unit,
    363                                       "Invalid profile(%d) in mem"
    364                                       "(%d) at index:%d\n"), hw_prof_idx, mem, idx));
    365                 return BCM_E_RESOURCE;
    366             }
    367             hw_idx_table[map_id] = hw_prof_idx;
    368             SHR_BITSET(hw_idx_bmp, hw_prof_idx);
    369             SHR_BITSET(map_bmp, map_id);
    370         }
    371     }
    372     
    373     return rv;
    374 }
    375 
    376 /* 
    377  * Function:
    378  *      _bcm_td2_qos_unsynchronized_reinit
    379  * Purpose:
    380  *      This routine handles Level 1 Warmboot init. In this style of reinit, the 
    381  *      map-ids allocated previously are not guaranteed to be the same.
    382  *      Cold-boot: Does nothing
    383  *      Warm-boot: The data-structures are populated by reading the HW tables. 
    384  * Parameters:
    385  *      unit    : (IN) Device Unit Number
    386  * Returns:
    387  *      BCM_E_XXX
    388  */
    389 int
    390 _bcm_td2_qos_unsynchronized_reinit(int unit)
    391 {
    392     int                 rv = BCM_E_NONE;
    393     int                 bmp_len;
    394     SHR_BITDCL          *temp_bmp;
    395 
    396     if (SOC_IS_TRIDENT3X(unit)) {
    397         VFT_QOS_INFO(unit)->egr_etag_mem = EGR_ZONE_3_DOT1P_MAPPING_TABLE_2m;
    398     } else {
    399         VFT_QOS_INFO(unit)->egr_etag_mem = EGR_ETAG_PCP_MAPPINGm;
    400     }
    401 
    402     /* read hw tables and populate the state */
    403     bmp_len = _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS;
    404     temp_bmp = NULL; 
    405     temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp");
    406     if (temp_bmp == NULL) {
    407         return BCM_E_MEMORY;
    408     }
    409     sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len));
    410 
    411     if (SOC_IS_TRIDENT3X(unit)) {
    412             rv = _bcm_td2_qos_reinit_from_hw_state(unit, LPORT_TABm,
    413                          ETAG_PCP_DE_MAPPING_PTRf,
    414                          _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP,
    415                          temp_bmp, bmp_len);
    416     } else {
    417         if (soc_mem_is_valid(unit, PORT_TABm)) {
    418             rv = _bcm_td2_qos_reinit_from_hw_state(unit, PORT_TABm,
    419                          ETAG_PCP_DE_MAPPING_PTRf,
    420                          _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP,
    421                          temp_bmp, bmp_len);
    422         }
    423     }
    424     sal_free(temp_bmp);
    425 
    426     /* now extract EGR_MPLS_PRI_MAPPING state */
    427     if (BCM_SUCCESS(rv)) {
    428         bmp_len = _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS;
    429         temp_bmp = NULL; 
    430         temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp");
    431         if (temp_bmp == NULL) {
    432             return BCM_E_MEMORY;
    433         }
    434         sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len));
    435         if (SOC_IS_TRIDENT3X(unit)) {
    436             rv = _bcm_td2_qos_reinit_from_hw_state(unit, LPORT_TABm,
    437                      ETAG_DOT1P_MAPPING_PTRf,
    438                      _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP,
    439                      temp_bmp, bmp_len);
    440         } else {
    441             if (soc_mem_field_valid(unit, PORT_TABm,
    442                                     ETAG_DOT1P_MAPPING_PTRf)) {
    443                 rv = _bcm_td2_qos_reinit_from_hw_state(unit, PORT_TABm,
    444                          ETAG_DOT1P_MAPPING_PTRf,
    445                          _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP,
    446                          temp_bmp, bmp_len);
    447             }
    448         }
    449         sal_free(temp_bmp);
    450     }
    451 
    452     /* now extract ING_VFT_PRI_MAPPING state */
    453     if (BCM_SUCCESS(rv)) {
    454         bmp_len = _BCM_QOS_MAX_VFT_PRI_MAPS;
    455         temp_bmp = NULL; 
    456         temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp");
    457         if (temp_bmp == NULL) {
    458             return BCM_E_MEMORY;
    459         }
    460         sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len));
    461         if (SOC_IS_TRIDENT3X(unit)) {
    462             rv = _bcm_td2_qos_reinit_from_hw_state(unit, LPORT_TABm,
    463                      FCOE_VFT_PRI_MAP_PROFILEf,
    464                      _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP,
    465                      temp_bmp, bmp_len);
    466         } else {
    467             if (soc_mem_field_valid(unit, PORT_TABm,
    468                                     FCOE_VFT_PRI_MAP_PROFILEf)) {
    469                 rv = _bcm_td2_qos_reinit_from_hw_state(unit, PORT_TABm,
    470                          FCOE_VFT_PRI_MAP_PROFILEf,
    471                          _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP,
    472                          temp_bmp, bmp_len);
    473             }
    474         }
    475         sal_free(temp_bmp);
    476     }    
    477 
    478     /* now extract EGR_VFT_PRI_MAPPING state */
    479     if (BCM_SUCCESS(rv)) {
    480         bmp_len = _BCM_QOS_MAX_VFT_PRI_MAPS;
    481         temp_bmp = NULL; 
    482         temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp");
    483         if (temp_bmp == NULL) {
    484             return BCM_E_MEMORY;
    485         }
    486         sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len));
    487 
    488         if (SOC_IS_TRIDENT3X(unit)) {
    489             rv = _bcm_td2_qos_reinit_from_hw_state(unit, EGR_LPORT_PROFILEm,
    490                      FCOE_VFT_PRI_MAP_PROFILEf,
    491                      _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP,
    492                      temp_bmp, bmp_len);
    493         } else {
    494             if (soc_mem_field_valid(unit, EGR_PORTm,
    495                                     FCOE_VFT_PRI_MAP_PROFILEf)) {
    496                 rv = _bcm_td2_qos_reinit_from_hw_state(unit, EGR_PORTm,
    497                          FCOE_VFT_PRI_MAP_PROFILEf,
    498                          _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP,
    499                          temp_bmp, bmp_len);
    500             }
    501         }
    502         sal_free(temp_bmp);
    503     }   
    504     
    505     /* now extract EGR_VSAN_PRI_MAPPING state */
    506     if (BCM_SUCCESS(rv)) {
    507         bmp_len = _BCM_QOS_MAX_VSAN_PRI_MAPS;
    508         temp_bmp = NULL; 
    509         temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp");
    510         if (temp_bmp == NULL) {
    511             return BCM_E_MEMORY;
    512         }
    513         sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len));
    514         if (soc_mem_field_valid(unit, EGR_L3_INTFm, 
    515                                 FCOE_VSAN_PRI_MAPPING_PROFILEf)) {
    516             rv = _bcm_td2_qos_reinit_from_hw_state(unit, EGR_L3_INTFm,                      
    517                      FCOE_VSAN_PRI_MAPPING_PROFILEf, 
    518                      _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP,
    519                      temp_bmp, bmp_len);
    520         }
    521         sal_free(temp_bmp);
    522     }
    523 
    524     return rv;
    525 }
    526 
    527 /* 
    528  * Function:
    529  *      _bcm_td2_qos_extended_reinit
    530  * Purpose:
    531  *      This routine handles Level 2 Warmboot init. 
    532  *      Cold-boot: scache location is allocated.
    533  *      Warm-boot: The data-structs are populated from recovered scache state
    534  * Parameters:
    535  *      unit    : (IN) Device Unit Number
    536  * Returns:
    537  *      BCM_E_XXX
    538  */
    539 int
    540 _bcm_td2_qos_extended_reinit(int unit, uint8 **scache_ptr)
    541 {
    542     uint32              hw_idx;
    543     int                 idx;
    544 
    545     for (idx = 0; idx < _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS; idx++) {
    546         sal_memcpy(&hw_idx, (*scache_ptr), sizeof(uint32));
    547         (*scache_ptr) += sizeof(hw_idx);
    548         if (hw_idx != _BCM_TD2_REINIT_INVALID_HW_IDX) {
    549             _BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_SET(unit, idx);
    550             VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx[idx] = hw_idx;
    551         }
    552     }
    553     for (idx = 0; idx < _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS; idx++) {
    554         sal_memcpy(&hw_idx, (*scache_ptr), sizeof(uint32));
    555         (*scache_ptr) += sizeof(hw_idx);
    556         if (hw_idx != _BCM_TD2_REINIT_INVALID_HW_IDX) {
    557             _BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_SET(unit, idx);
    558             VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx[idx] = hw_idx;
    559         }
    560     }
    561     for (idx = 0; idx < _BCM_QOS_MAX_VFT_PRI_MAPS; idx++) {
    562         sal_memcpy(&hw_idx, (*scache_ptr), sizeof(uint32));
    563         (*scache_ptr) += sizeof(hw_idx);
    564         if (hw_idx != _BCM_TD2_REINIT_INVALID_HW_IDX) {
    565             _BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_SET(unit, idx);
    566             VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx[idx] = hw_idx;
    567         }
    568     }
    569     for (idx = 0; idx < _BCM_QOS_MAX_VFT_PRI_MAPS; idx++) {
    570         sal_memcpy(&hw_idx, (*scache_ptr), sizeof(uint32));
    571         (*scache_ptr) += sizeof(hw_idx);
    572         if (hw_idx != _BCM_TD2_REINIT_INVALID_HW_IDX) {
    573             _BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_SET(unit, idx);
    574             VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx[idx] = hw_idx;
    575         }
    576     }
    577     for (idx = 0; idx < _BCM_QOS_MAX_VSAN_PRI_MAPS; idx++) {
    578         sal_memcpy(&hw_idx, (*scache_ptr), sizeof(uint32));
    579         (*scache_ptr) += sizeof(hw_idx);
    580         if (hw_idx != _BCM_TD2_REINIT_INVALID_HW_IDX) {
    581             _BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_SET(unit, idx);
    582             VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx[idx] = hw_idx;
    583         }
    584     }
    585 
    586     return BCM_E_NONE;
    587 }
    588 
    589 
    590 /* 
    591  * Function:
    592  *      _bcm_td2_qos_reinit_hw_profiles_update
    593  * Purpose:
    594  *      Updates the shared memory profile tables reference counts
    595  * Parameters:
    596  *      unit    : (IN) Device Unit Number
    597  * Returns:
    598  *      BCM_E_XXX
    599  */
    600 int
    601 _bcm_td2_qos_reinit_hw_profiles_update(int unit)
    602 {
    603     int     i;
    604 
    605     for (i = 0; i < _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS; i++) {
    606         if (_BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, i)) {
    607             BCM_IF_ERROR_RETURN(_bcm_ing_l2_vlan_etag_map_entry_reference(unit, 
    608                               ((VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx[i]) * 
    609                                _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP), 
    610                                _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP));
    611         }
    612     }
    613     for (i = 0; i < _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS; i++) {
    614         if (_BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, i)) {
    615             BCM_IF_ERROR_RETURN(_bcm_egr_l2_vlan_etag_map_entry_reference(unit, 
    616                               ((VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx[i]) * 
    617                                _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP), 
    618                                _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP));
    619         }
    620     } 
    621     for (i = 0; i < _BCM_QOS_MAX_VFT_PRI_MAPS; i++) {
    622         if (_BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_GET(unit, i)) {
    623             BCM_IF_ERROR_RETURN(_bcm_ing_vft_pri_map_entry_reference(unit, 
    624                                ((VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx[i]) * 
    625                                _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP),
    626                                _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP));
    627         }
    628     }
    629     for (i = 0; i < _BCM_QOS_MAX_VFT_PRI_MAPS; i++) {
    630         if (_BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_GET(unit, i)) {
    631             BCM_IF_ERROR_RETURN(_bcm_egr_vft_pri_map_entry_reference(unit, 
    632                                ((VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx[i]) * 
    633                                _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP),
    634                                _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP));        
    635         }
    636     }
    637     for (i = 0; i < _BCM_QOS_MAX_VSAN_PRI_MAPS; i++) {
    638         if (_BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_GET(unit, i)) {
    639             BCM_IF_ERROR_RETURN(_bcm_egr_vsan_intpri_map_entry_reference(unit, 
    640                                ((VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx[i]) * 
    641                                _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP),
    642                                _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP));         
    643         }
    644     }    
    645  
    646     return BCM_E_NONE;
    647 }
    648 
    649 
    650 /* 
    651  * Function:
    652  *      bcm_td2_qos_sync
    653  * Purpose:
    654  *      This routine extracts the state that needs to be stored from the 
    655  *      book-keeping structs and stores it in the allocated scache location 
    656  * Compression format:  0   - A     l2_vlan_etag table
    657  *                      A+1 - B     egr_l2_vlan_etag table
    658  * Parameters:
    659  *      unit    : (IN) Device Unit Number
    660  * Returns:
    661  *      BCM_E_XXX
    662  */
    663 int
    664 _bcm_td2_qos_sync(int unit, uint8 **scache_ptr)
    665 {
    666     uint32              hw_idx;
    667     int                 idx;    
    668 
    669     /* now store the state into the compressed format */
    670     for (idx = 0; idx < _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS; idx++) {
    671         if (_BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, idx)) {
    672             hw_idx = VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx[idx];
    673         } else {
    674             hw_idx = _BCM_TD2_REINIT_INVALID_HW_IDX;
    675         }
    676         sal_memcpy((*scache_ptr), &hw_idx, sizeof(uint32));
    677         (*scache_ptr) += sizeof(hw_idx);
    678     }
    679     for (idx = 0; idx < _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS; idx++) {
    680         if (_BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, idx)) {
    681             hw_idx = VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx[idx];
    682         } else {
    683             hw_idx = _BCM_TD2_REINIT_INVALID_HW_IDX;
    684         }
    685         sal_memcpy((*scache_ptr), &hw_idx, sizeof(uint32));
    686         (*scache_ptr) += sizeof(hw_idx);
    687     }
    688     for (idx = 0; idx < _BCM_QOS_MAX_VFT_PRI_MAPS; idx++) {
    689         if (_BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_GET(unit, idx)) {
    690             hw_idx = VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx[idx];
    691         } else {
    692             hw_idx = _BCM_TD2_REINIT_INVALID_HW_IDX;
    693         }
    694         sal_memcpy((*scache_ptr), &hw_idx, sizeof(uint32));
    695         (*scache_ptr) += sizeof(hw_idx);
    696     }
    697     for (idx = 0; idx < _BCM_QOS_MAX_VFT_PRI_MAPS; idx++) {
    698         if (_BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_GET(unit, idx)) {
    699             hw_idx = VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx[idx];
    700         } else {
    701             hw_idx = _BCM_TD2_REINIT_INVALID_HW_IDX;
    702         }
    703         sal_memcpy((*scache_ptr), &hw_idx, sizeof(uint32));
    704         (*scache_ptr) += sizeof(hw_idx);
    705     }
    706     for (idx = 0; idx < _BCM_QOS_MAX_VSAN_PRI_MAPS; idx++) {
    707         if (_BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_GET(unit, idx)) {
    708             hw_idx = VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx[idx];
    709         } else {
    710             hw_idx = _BCM_TD2_REINIT_INVALID_HW_IDX;
    711         }
    712         sal_memcpy((*scache_ptr), &hw_idx, sizeof(uint32));
    713         (*scache_ptr) += sizeof(hw_idx);
    714     }    
    715 
    716     return BCM_E_NONE;
    717 }
    718 
    719 #endif /* BCM_WARM_BOOT_SUPPORT */
    720 
    721 /*
    722  * Function: 
    723  *     _bcm_td2_qos_free_resources
    724  * Purpose:
    725  *     Free TD2 QOS bookkeeping resources associated with a given unit.  This
    726  *     happens either during an error initializing or during a detach operation.
    727  * Parameters:
    728  *     unit - (IN) Unit to free resources of
    729  * Returns:
    730  *     BCM_E_XXX
    731  */
    732 STATIC void
    733 _bcm_td2_qos_free_resources(int unit)
    734 {
    735     _bcm_td2_qos_bookkeeping_t *qos_info = VFT_QOS_INFO(unit);
    736 
    737     if (!qos_info) {
    738     /*
    739      * Coverity
    740      * This is defencive statement.
    741      */
    742     /* coverity[dead_error_line] */
    743         return;
    744     }
    745 
    746     if (qos_info->ing_vft_pri_map) {
    747         sal_free(qos_info->ing_vft_pri_map);
    748         qos_info->ing_vft_pri_map = NULL;
    749     }
    750 
    751     if (qos_info->ing_vft_pri_map_hwidx) {
    752         sal_free(qos_info->ing_vft_pri_map_hwidx);
    753         qos_info->ing_vft_pri_map_hwidx = NULL;
    754     }
    755 
    756     if (qos_info->ing_l2_vlan_etag_map) {
    757         sal_free(qos_info->ing_l2_vlan_etag_map);
    758         qos_info->ing_l2_vlan_etag_map = NULL;
    759     }
    760 
    761     if (qos_info->ing_l2_vlan_etag_map_hwidx) {
    762         sal_free(qos_info->ing_l2_vlan_etag_map_hwidx);
    763         qos_info->ing_l2_vlan_etag_map_hwidx = NULL;
    764     }
    765 
    766     if (qos_info->egr_vft_pri_map) {
    767         sal_free(qos_info->egr_vft_pri_map);
    768         qos_info->egr_vft_pri_map = NULL;
    769     }
    770 
    771     if (qos_info->egr_vft_pri_map_hwidx) {
    772         sal_free(qos_info->egr_vft_pri_map_hwidx);
    773         qos_info->egr_vft_pri_map_hwidx = NULL;
    774     }
    775 
    776     if (qos_info->egr_vsan_intpri_map) {
    777         sal_free(qos_info->egr_vsan_intpri_map);
    778         qos_info->egr_vsan_intpri_map = NULL;
    779     }
    780 
    781     if (qos_info->egr_vft_pri_map_hwidx) {
    782         sal_free(qos_info->egr_vft_pri_map_hwidx);
    783         qos_info->egr_vft_pri_map_hwidx = NULL;
    784     }
    785 
    786     if (qos_info->egr_l2_vlan_etag_map) {
    787         sal_free(qos_info->egr_l2_vlan_etag_map);
    788         qos_info->egr_l2_vlan_etag_map = NULL;
    789     }
    790 
    791     if (qos_info->egr_l2_vlan_etag_map_hwidx) {
    792         sal_free(qos_info->egr_l2_vlan_etag_map_hwidx);
    793         qos_info->egr_l2_vlan_etag_map_hwidx = NULL;
    794     }
    795     
    796     if (qos_info->egr_vsan_intpri_map_hwidx) {
    797         sal_free(qos_info->egr_vsan_intpri_map_hwidx);
    798         qos_info->egr_vsan_intpri_map_hwidx = NULL;
    799     }
    800 
    801     if (qos_info->qos_mutex) {
    802         sal_mutex_destroy(qos_info->qos_mutex);
    803         qos_info->qos_mutex = NULL;
    804     }
    805 
    806 }
    807 
    808 /*
    809  * Function: 
    810  *     bcm_td2_qos_detach
    811  * Purpose:
    812  *     Detach the QOS module.  Called when the module should de-initialize.
    813  * Parameters:
    814  *     unit - (IN) Unit being detached.
    815  * Returns:
    816  *     BCM_E_XXX
    817  */
    818 int 
    819 bcm_td2_qos_detach(int unit)
    820 {
    821     if (_bcm_td2_qos_initialized[unit]) {
    822         _bcm_td2_qos_initialized[unit] = 0;
    823         _bcm_td2_qos_free_resources(unit);
    824     }
    825 
    826     return BCM_E_NONE;
    827 }
    828 
    829 /*
    830  * Function: 
    831  *     bcm_td2_qos_init
    832  * Purpose:
    833  *     Initialize the TD2 QOS module.  Allocate bookkeeping information.
    834  * Parameters:
    835  *     unit - (IN) Unit being initialized
    836  * Returns:
    837  *     BCM_E_XXX
    838  */
    839 int
    840 bcm_td2_qos_init(int unit)
    841 {
    842     _bcm_td2_qos_bookkeeping_t *qos_info = VFT_QOS_INFO(unit);
    843     int vft_map_size = 0;
    844     int vsan_map_size = _BCM_QOS_MAX_VSAN_PRI_MAPS;
    845     int l2_vlan_tag_map_size  = _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS;
    846     int egr_l2_vlan_tag_map_size;
    847 
    848     if (_bcm_td2_qos_initialized[unit]) {
    849         BCM_IF_ERROR_RETURN(bcm_td2_qos_detach(unit));
    850     }
    851 
    852     memset(qos_info, 0, sizeof *qos_info);
    853 
    854     if (SOC_IS_TRIDENT3X(unit)) {
    855         qos_info->egr_etag_mem = EGR_ZONE_3_DOT1P_MAPPING_TABLE_2m;
    856     } else {
    857         qos_info->egr_etag_mem = EGR_ETAG_PCP_MAPPINGm;
    858     }
    859     /* Macro relies on above code to enable */
    860     egr_l2_vlan_tag_map_size  = _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS;
    861 
    862     /* ingress priority map bitmap */
    863     if (soc_mem_is_valid(unit, ING_VFT_PRI_MAPm)) {
    864         vft_map_size  = _BCM_QOS_MAX_VFT_PRI_MAPS;
    865         qos_info->ing_vft_pri_map = sal_alloc(SHR_BITALLOCSIZE(vft_map_size), 
    866                                              "ing_vft_pri_map");
    867         if (qos_info->ing_vft_pri_map == NULL) {
    868             _bcm_td2_qos_free_resources(unit);
    869             return BCM_E_MEMORY;
    870         }
    871         sal_memset(qos_info->ing_vft_pri_map, 0, SHR_BITALLOCSIZE(vft_map_size));
    872 
    873         /* ingress priority map hardware indexes */
    874         qos_info->ing_vft_pri_map_hwidx = sal_alloc(sizeof(uint32) * vft_map_size, 
    875                                                    "ing_vft_pri_map_hwidx");
    876         if (qos_info->ing_vft_pri_map_hwidx == NULL) {
    877             _bcm_td2_qos_free_resources(unit);
    878             return BCM_E_MEMORY;
    879         }
    880         sal_memset(qos_info->ing_vft_pri_map_hwidx, 0, 
    881                    sizeof(uint32) * vft_map_size);
    882     }
    883     /* ingress l2 vlan etag map bitmap */
    884     qos_info->ing_l2_vlan_etag_map = 
    885                             sal_alloc(SHR_BITALLOCSIZE(l2_vlan_tag_map_size), 
    886                             "ing_l2_vlan_etag_map");
    887     if (qos_info->ing_l2_vlan_etag_map == NULL) {
    888         _bcm_td2_qos_free_resources(unit);
    889         return BCM_E_MEMORY;
    890     }
    891     sal_memset(qos_info->ing_l2_vlan_etag_map, 0, 
    892                SHR_BITALLOCSIZE(l2_vlan_tag_map_size));
    893 
    894     /* ingress l2 vlan etag map hardware indexes */
    895     qos_info->ing_l2_vlan_etag_map_hwidx = 
    896                             sal_alloc(sizeof(uint32) * l2_vlan_tag_map_size, 
    897                             "ing_l2_vlan_etag_map_hwidx");
    898     if (qos_info->ing_l2_vlan_etag_map_hwidx == NULL) {
    899         _bcm_td2_qos_free_resources(unit);
    900         return BCM_E_MEMORY;
    901     }
    902     sal_memset(qos_info->ing_l2_vlan_etag_map_hwidx, 0, 
    903                sizeof(uint32) * l2_vlan_tag_map_size);
    904 
    905     /* egress priority map bitmap */
    906     if (soc_mem_is_valid(unit, ING_VFT_PRI_MAPm)) {
    907         qos_info->egr_vft_pri_map = sal_alloc(SHR_BITALLOCSIZE(vft_map_size), 
    908                                               "egr_vft_pri_map");
    909         if (qos_info->egr_vft_pri_map == NULL) {
    910             _bcm_td2_qos_free_resources(unit);
    911             return BCM_E_MEMORY;
    912         }
    913         sal_memset(qos_info->egr_vft_pri_map, 0, SHR_BITALLOCSIZE(vft_map_size));
    914 
    915         /* egress priority map hardware indexes */
    916         qos_info->egr_vft_pri_map_hwidx = sal_alloc(sizeof(uint32) * vft_map_size, 
    917                                                    "egr_vft_pri_map_hwidx");
    918         if (qos_info->egr_vft_pri_map_hwidx == NULL) {
    919             _bcm_td2_qos_free_resources(unit);
    920             return BCM_E_MEMORY;
    921         }
    922         sal_memset(qos_info->egr_vft_pri_map_hwidx, 0, 
    923                    sizeof(uint32) * vft_map_size);
    924     }
    925     /* egress vsan priority map bitmap */
    926     qos_info->egr_vsan_intpri_map = sal_alloc(SHR_BITALLOCSIZE(vsan_map_size), 
    927                                               "egr_vsan_intpri_map");
    928     if (qos_info->egr_vsan_intpri_map == NULL) {
    929         _bcm_td2_qos_free_resources(unit);
    930         return BCM_E_MEMORY;
    931     }
    932     sal_memset(qos_info->egr_vsan_intpri_map, 0, 
    933                SHR_BITALLOCSIZE(vsan_map_size));
    934 
    935     /* egress vsan priority map hardware indexes */
    936     qos_info->egr_vsan_intpri_map_hwidx = 
    937         sal_alloc(sizeof(uint32) * vsan_map_size, "egr_vsan_intpri_map_hwidx");
    938     if (qos_info->egr_vsan_intpri_map_hwidx == NULL) {
    939         _bcm_td2_qos_free_resources(unit);
    940         return BCM_E_MEMORY;
    941     }
    942     sal_memset(qos_info->egr_vsan_intpri_map_hwidx, 0, 
    943                sizeof(uint32) * vsan_map_size);
    944 
    945     /* egress l2 vlan etag priority map bitmap */
    946     qos_info->egr_l2_vlan_etag_map = sal_alloc(SHR_BITALLOCSIZE(egr_l2_vlan_tag_map_size), 
    947                                               "egr_l2_vlan_etag_map");
    948     if (qos_info->egr_l2_vlan_etag_map == NULL) {
    949         _bcm_td2_qos_free_resources(unit);
    950         return BCM_E_MEMORY;
    951     }
    952     sal_memset(qos_info->egr_l2_vlan_etag_map, 0, 
    953                SHR_BITALLOCSIZE(egr_l2_vlan_tag_map_size));
    954 
    955 	/* egress l2 vlan etag map hardware indexes */
    956     qos_info->egr_l2_vlan_etag_map_hwidx = 
    957                             sal_alloc(sizeof(uint32) * egr_l2_vlan_tag_map_size, 
    958                             "egr_l2_vlan_etag_map_hwidx");
    959     if (qos_info->egr_l2_vlan_etag_map_hwidx == NULL) {
    960         _bcm_td2_qos_free_resources(unit);
    961         return BCM_E_MEMORY;
    962     }
    963     sal_memset(qos_info->egr_l2_vlan_etag_map_hwidx, 0, 
    964                sizeof(uint32) * egr_l2_vlan_tag_map_size);
    965 
    966     /* accessor mutex */
    967     qos_info->qos_mutex = sal_mutex_create("vft qos_mutex");
    968     if (qos_info->qos_mutex == NULL) {
    969         _bcm_td2_qos_free_resources(unit);
    970         return BCM_E_MEMORY;
    971     }
    972 
    973 #if defined(BCM_TRIDENT3_SUPPORT)
    974     if (SOC_WARM_BOOT(unit)) {
    975         if (SOC_IS_TRIDENT3X(unit)) {
    976             BCM_IF_ERROR_RETURN(bcm_td3_qos_reinit(unit));
    977         }
    978     }
    979 #endif
    980 
    981     _bcm_td2_qos_initialized[unit] = 1;
    982     return BCM_E_NONE;
    983 }
    984 
    985 /*
    986  * Function: 
    987  *     _bcm_td2_qos_map_create_with_id
    988  * Purpose:
    989  *     Allocate a new QOS map ID where the app has specified the ID.  So just
    990  *     check that the requested ID is available, and mark it as used.
    991  * Parameters:
    992  *     unit       - (IN) Unit to be operated on
    993  *     flags      - (IN) Used only to test if BCM_QOS_MAP_REPLACE is set
    994  *     bitmap     - (IN/OUT) Bitmap containing the set of used IDs
    995  *     map_id     - (IN) The ID requested by the application
    996  *     is_ingress - (IN) 1=ingress map, 0=egress map
    997  * Returns:
    998  *     BCM_E_XXX
    999  */
   1000 STATIC int
   1001 _bcm_td2_qos_map_create_with_id(int unit, int flags, SHR_BITDCL *bitmap, 
   1002                                     int *map_id, int is_ingress, int max_ids)
   1003 {
   1004     int id = 0, map_type = 0, rv = BCM_E_NONE;
   1005 
   1006     id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   1007     map_type = *map_id >> _BCM_QOS_MAP_SHIFT;
   1008 
   1009     if (id < 0 || id >= max_ids) {
   1010         return BCM_E_BADID;
   1011     }
   1012 
   1013     if ((map_type == _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP && is_ingress)
   1014         || (map_type == _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP && is_ingress)
   1015         || (map_type == _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP && !is_ingress)
   1016         || (map_type == _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP && !is_ingress)
   1017         || (map_type == _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP && !is_ingress)) {
   1018 
   1019         if (SHR_BITGET(bitmap, id) == 1) {
   1020             if (!(flags & BCM_QOS_MAP_REPLACE)) {
   1021                 rv = BCM_E_EXISTS;
   1022             }
   1023         }
   1024 
   1025         if (BCM_SUCCESS(rv)) {
   1026             SHR_BITSET(bitmap, id);
   1027         }
   1028     } else {
   1029         rv = BCM_E_PARAM;
   1030     }
   1031 
   1032     return rv;
   1033 }
   1034 
   1035 /*
   1036  * Function: 
   1037  *     _bcm_td2_qos_count_used_maps
   1038  * Purpose:
   1039  *     Count the number maps currently used in hardware.  Since IDs in app-space
   1040  *     can point to the same hardware index, count how many hardware indexes are
   1041  *     used, ignoring duplicates.
   1042  * Parameters:
   1043  *     unit   - (IN) Unit to be operated on
   1044  *     bitmap - (IN) Bitmap of used map IDs
   1045  *     hwmap  - (IN) Array that maps userspace IDs to hardware IDs
   1046  * Returns:
   1047  *     integer containing the number of used hardware indexes
   1048  */
   1049 STATIC int
   1050 _bcm_td2_qos_count_used_maps(int unit, SHR_BITDCL *bitmap, uint32 *hwmap, 
   1051                              int map_size, int max_maps) 
   1052 {
   1053     uint8 *hw_used = sal_alloc(map_size, "td2_qos_used_maps");
   1054     int total_used = 0;
   1055     int i = 0;
   1056     
   1057     if (hw_used == NULL) {
   1058         return max_maps;
   1059     }
   1060 
   1061     memset(hw_used, 0, map_size);
   1062 
   1063     for (i = 0; i < map_size; i++) {
   1064         if (SHR_BITGET(bitmap, i) && hw_used[hwmap[i]] == 0) {
   1065             hw_used[hwmap[i]] = 1;
   1066             total_used++;
   1067         }
   1068     }
   1069 
   1070     sal_free(hw_used);
   1071     return total_used;
   1072 }
   1073 
   1074 /*
   1075  * Function: 
   1076  *     _bcm_td2_qos_flags_sanity_check
   1077  * Purpose:
   1078  *     Check that the combination of flags specified is valid.
   1079  * Parameters:
   1080  *     flags  - (IN) BCM_QOS_MAP_* flags (eg. ingress/egress/with_id/replace)
   1081   * Returns:
   1082  *     BCM_E_XXX
   1083  */
   1084 STATIC int
   1085 _bcm_td2_qos_flags_sanity_check(uint32 flags)
   1086 {
   1087     int rv = BCM_E_NONE;
   1088 
   1089     /* must be ingress or egress, not both */
   1090     if ((flags & BCM_QOS_MAP_INGRESS) && (flags & BCM_QOS_MAP_EGRESS)) {
   1091         rv = BCM_E_PARAM;
   1092     }
   1093 
   1094     /* must be ingress or egress, not neither */
   1095     if (!(flags & BCM_QOS_MAP_INGRESS) && !(flags & BCM_QOS_MAP_EGRESS)) {
   1096         rv = BCM_E_PARAM;
   1097     }
   1098 
   1099     /* must be VFT or VSAN, not both */
   1100     if ((flags & BCM_QOS_MAP_VFT) && (flags & BCM_QOS_MAP_VSAN)) {
   1101         rv = BCM_E_PARAM;
   1102     }
   1103 
   1104     /* must be VFT or VSAN, not neither */
   1105     if (!(flags & BCM_QOS_MAP_VFT) && !(flags & BCM_QOS_MAP_VSAN)
   1106         && !(flags & BCM_QOS_MAP_L2_VLAN_ETAG)) {
   1107         rv = BCM_E_PARAM;
   1108     }
   1109 
   1110     /* VSAN maps can only be egress */
   1111     if ((flags & BCM_QOS_MAP_INGRESS) && (flags & BCM_QOS_MAP_VSAN)) {
   1112         rv = BCM_E_PARAM;
   1113     }
   1114 
   1115     return rv;
   1116 }
   1117 
   1118 /*
   1119  * Function: 
   1120  *     _bcm_td2_qos_assign_creation_table_vars
   1121  * Purpose:
   1122  *     Assign the various pointers to tables and table sizes and bitmaps used
   1123  *     for the bcm_td2_qos_map_create so that it can create the different types
   1124  *     of maps with common logic.  
   1125  * 
   1126  *     Assumes "flags" has already been validated.
   1127  * Parameters:
   1128  *     unit       - (IN)  Unit to be operated on
   1129  *     flags      - (IN)  BCM_QOS_MAP_* flags (eg. ingress/egress/with_id/etc)
   1130  *     is_ingress - (OUT) 1 for ingress, 0 for egress map
   1131  *     bitmap     - (OUT) pointer to priority map's bitmap
   1132  *     hwmap      - (OUT) pointer to priority map's hwidx mapping
   1133  *     map_type   - (OUT) _BCM_QOS_MAP_TYPE_*
   1134  *     map_size   - (OUT) size of the selected map
   1135  *     max_maps   - (OUT) maximum number of maps available for the selected type
   1136  * Returns:
   1137  *     None
   1138  */
   1139 STATIC void
   1140 _bcm_td2_qos_assign_creation_table_vars(int unit, int flags, int *is_ingress, 
   1141                                         SHR_BITDCL **bitmap,
   1142                                         uint32 **hwmap, int *map_type, 
   1143                                         int *map_size, int *max_maps)
   1144 {
   1145     if (flags & BCM_QOS_MAP_INGRESS) {
   1146         *is_ingress = 1;
   1147         if (flags & BCM_QOS_MAP_VFT) {
   1148             *bitmap     = VFT_QOS_INFO(unit)->ing_vft_pri_map;
   1149             *hwmap      = VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx;
   1150             *map_type   = _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP;
   1151             *map_size   = _BCM_QOS_MAX_VFT_PRI_MAPS;
   1152             *max_maps   = _BCM_QOS_MAX_VFT_PRI_MAPS;
   1153         } else if (flags & BCM_QOS_MAP_L2_VLAN_ETAG) {
   1154             *bitmap     = VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map;
   1155             *hwmap      = VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx;
   1156             *map_type   = _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP;
   1157             *map_size   = _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS;
   1158             *max_maps   = _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS;
   1159         }        
   1160     } else if (flags & BCM_QOS_MAP_EGRESS) {
   1161         *is_ingress = 0;
   1162 
   1163         if (flags & BCM_QOS_MAP_VFT) {
   1164             *bitmap     = VFT_QOS_INFO(unit)->egr_vft_pri_map;
   1165             *hwmap      = VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx;
   1166             *map_type   = _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP;
   1167             *map_size   = _BCM_QOS_MAX_VFT_PRI_MAPS; 
   1168             *max_maps   = _BCM_QOS_MAX_VFT_PRI_MAPS;
   1169         } else if (flags & BCM_QOS_MAP_VSAN) {
   1170             *bitmap     = VFT_QOS_INFO(unit)->egr_vsan_intpri_map;
   1171             *hwmap      = VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx;
   1172             *map_type   = _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP;
   1173             *map_size   = _BCM_QOS_MAX_VSAN_PRI_MAPS; 
   1174             *max_maps   = _BCM_QOS_MAX_VSAN_PRI_MAPS;
   1175         } else if (flags & BCM_QOS_MAP_L2_VLAN_ETAG) {
   1176             *bitmap     = VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map;
   1177             *hwmap      = VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx;
   1178             *map_type   = _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP;
   1179             *map_size   = _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS;
   1180             *max_maps   = _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS;
   1181         }
   1182     }
   1183 
   1184 }
   1185 
   1186 /*
   1187  * Function: 
   1188  *     bcm_td2_qos_map_create
   1189  * Purpose:
   1190  *     Create a new QOS map.
   1191  * Parameters:
   1192  *     unit   - (IN) Unit to be operated on
   1193  *     flags  - (IN) BCM_QOS_MAP_* flags (eg. ingress/egress/with_id/replace)
   1194  *     map_id - (IN/OUT) If BCM_QOS_MAP_WITH_ID is set, then this is the ID
   1195  *                       being requested.  Otherwise, it's assigned as the ID
   1196  *                       allocated.
   1197  * Returns:
   1198  *     BCM_E_XXX
   1199  */
   1200 int
   1201 bcm_td2_qos_map_create(int unit, uint32 flags, int *map_id)
   1202 {
   1203     int        is_ingress = 0;
   1204     int        map_type = 0;
   1205     SHR_BITDCL *bitmap = NULL;
   1206     uint32     index = 0;
   1207     int        rv    = BCM_E_NONE;
   1208     int        id    = 0;
   1209     void       *entries[2] = {NULL};
   1210     uint32     *hwmap = NULL;
   1211     int        map_size = 0;
   1212     int        max_maps = 0;
   1213 
   1214     QOS_INIT(unit);
   1215     QOS_LOCK(unit);
   1216 
   1217     rv = _bcm_td2_qos_flags_sanity_check(flags);
   1218 
   1219     if (BCM_SUCCESS(rv)) {
   1220         _bcm_td2_qos_assign_creation_table_vars(unit, flags, &is_ingress, 
   1221                                                 &bitmap, &hwmap, &map_type, 
   1222                                                 &map_size, &max_maps);
   1223     }
   1224 
   1225     if (BCM_SUCCESS(rv)) {
   1226         if (_bcm_td2_qos_count_used_maps(unit, bitmap, hwmap, map_size, 
   1227                                          max_maps) >= max_maps) {
   1228             rv = BCM_E_MEMORY;
   1229         }
   1230     }
   1231 
   1232     if (BCM_SUCCESS(rv)) {
   1233         if (flags & BCM_QOS_MAP_WITH_ID) {
   1234             rv = _bcm_td2_qos_map_create_with_id(unit, flags, bitmap, map_id, 
   1235                                                  is_ingress, map_size);
   1236             id = *map_id & _BCM_QOS_MAP_TYPE_MASK;
   1237         } else {
   1238             rv = _bcm_td2_qos_map_id_alloc(unit, bitmap, &id, map_size);
   1239             if (BCM_SUCCESS(rv)) {
   1240                 *map_id = id | (map_type << _BCM_QOS_MAP_SHIFT);
   1241             }
   1242         }
   1243     }
   1244 
   1245     if (BCM_SUCCESS(rv)) {
   1246         if (flags & BCM_QOS_MAP_VSAN) {
   1247             egr_vsan_intpri_map_entry_t table[_BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP];
   1248             memset(&table, 0, sizeof table);
   1249             entries[0] = &table;
   1250 
   1251             rv = _bcm_egr_vsan_intpri_map_entry_add(unit, entries,
   1252                                                 _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP, 
   1253                                                 &index);
   1254 
   1255             if (BCM_SUCCESS(rv)) {
   1256                 VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx[id] = index / 
   1257                                                 _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP;
   1258             }
   1259         }
   1260         else if ((flags & BCM_QOS_MAP_INGRESS) && (flags & BCM_QOS_MAP_VFT)) {
   1261             ing_vft_pri_map_entry_t table[_BCM_QOS_MAP_CHUNK_VFT_PRI_MAP];
   1262             memset(&table, 0, sizeof table);
   1263             entries[0] = &table;
   1264 
   1265             rv = _bcm_ing_vft_pri_map_entry_add(unit, entries,
   1266                                                 _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP, 
   1267                                                 &index);
   1268 
   1269             if (BCM_SUCCESS(rv)) {
   1270                 VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx[id] = index /
   1271                                                 _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP;
   1272             }
   1273         } else if ((flags & BCM_QOS_MAP_EGRESS) && (flags & BCM_QOS_MAP_VFT)){
   1274             egr_vft_pri_map_entry_t table[_BCM_QOS_MAP_CHUNK_VFT_PRI_MAP];
   1275             memset(&table, 0, sizeof table);
   1276             entries[0] = &table;
   1277 
   1278             rv = _bcm_egr_vft_pri_map_entry_add(unit, entries, 
   1279                                                 _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP, 
   1280                                                 &index);
   1281 
   1282             if (BCM_SUCCESS(rv)) {
   1283                 VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx[id] = index / 
   1284                                                 _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP;
   1285             }
   1286         } 
   1287         else if ((flags & BCM_QOS_MAP_INGRESS) 
   1288                   && (flags & BCM_QOS_MAP_L2_VLAN_ETAG)) {
   1289             ing_etag_pcp_mapping_entry_t 
   1290                                 table[_BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP];
   1291             memset(&table, 0, sizeof table);
   1292             entries[0] = &table;
   1293 
   1294             rv = _bcm_ing_l2_vlan_etag_map_entry_add(unit, entries,
   1295                                            _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP, 
   1296                                            &index);
   1297 
   1298             if (BCM_SUCCESS(rv)) {
   1299                 VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx[id] = index /
   1300                                            _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP;
   1301             }
   1302         } else if ((flags & BCM_QOS_MAP_EGRESS)
   1303                     && (flags & BCM_QOS_MAP_L2_VLAN_ETAG)) {
   1304             egr_zone_3_dot1p_mapping_table_2_entry_t
   1305                                 td3_etag_table[2][_BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP];
   1306             egr_etag_pcp_mapping_entry_t 
   1307                                 table[_BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP];
   1308 
   1309             if (SOC_IS_TRIDENT3X(unit)) {
   1310                 memset(&td3_etag_table, 0, sizeof(td3_etag_table));
   1311                 entries[0] = &td3_etag_table[0];
   1312                 entries[1] = &td3_etag_table[1];
   1313             } else {
   1314             memset(&table, 0, sizeof table);
   1315                 entries[0] = &table;
   1316             }
   1317 
   1318             rv = _bcm_egr_l2_vlan_etag_map_entry_add(unit, entries,
   1319                                            _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP, 
   1320                                            &index);
   1321 
   1322             if (BCM_SUCCESS(rv)) {
   1323                 VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx[id] = index /
   1324                                            _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP;
   1325             }
   1326         }
   1327     }
   1328 
   1329     QOS_UNLOCK(unit);
   1330 
   1331     return rv;
   1332 }
   1333 
   1334 /*
   1335  * Function: 
   1336  *     _bcm_td2_qos_map_destroy
   1337  * Purpose:
   1338  *     Destroy a map ID by removing it from hardware.
   1339  * Parameters:
   1340  *     unit  - (IN) The unit being operated on
   1341  *     table - (IN) Indicates either ingress or egress
   1342  *     id    - (IN) The map ID being destroyed
   1343  * Returns:
   1344  *     BCM_E_XXX
   1345  */
   1346 STATIC int
   1347 _bcm_td2_qos_map_destroy(int unit, int table, int id)
   1348 {
   1349     int rv = BCM_E_NONE;
   1350     _bcm_td2_qos_bookkeeping_t *qos_info = VFT_QOS_INFO(unit);
   1351 
   1352     if (table == _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP) {
   1353         rv = _bcm_ing_vft_pri_map_entry_del(unit, 
   1354                                         qos_info->ing_vft_pri_map_hwidx[id] *
   1355                                         _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP);
   1356     } else if (table == _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP) {
   1357         rv = _bcm_egr_vft_pri_map_entry_del(unit,
   1358                                         qos_info->egr_vft_pri_map_hwidx[id] *
   1359                                         _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP);
   1360     } else if (table == _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP) {
   1361         rv = _bcm_egr_vsan_intpri_map_entry_del(unit, 
   1362                                     qos_info->egr_vsan_intpri_map_hwidx[id] *
   1363                                     _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP);
   1364     } else if (table == _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP) {
   1365         rv = _bcm_ing_l2_vlan_etag_map_entry_del(unit, 
   1366                                     qos_info->ing_l2_vlan_etag_map_hwidx[id] *
   1367                                     _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP);
   1368     } else if (table == _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP) {
   1369         rv = _bcm_egr_l2_vlan_etag_map_entry_del(unit, 
   1370                                     qos_info->egr_l2_vlan_etag_map_hwidx[id] *
   1371                                     _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP);
   1372     }
   1373 
   1374     return rv;
   1375 }
   1376 
   1377 /*
   1378  * Function: 
   1379  *     bcm_td2_qos_map_destroy
   1380  * Purpose:
   1381  *     Destroy a VFT QOS map ID by removing it from hardware and deleting the
   1382  *     associated software state info.
   1383  * Parameters:
   1384  *     unit   - (IN) Unit being operated on
   1385  *     map_id - (IN) QOS map ID to be destroyed
   1386  * Returns:
   1387  *     BCM_E_XXX
   1388  */
   1389 int
   1390 bcm_td2_qos_map_destroy(int unit, int map_id)
   1391 {
   1392     int id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   1393     int rv = BCM_E_UNAVAIL;
   1394 
   1395     QOS_INIT(unit);
   1396     QOS_LOCK(unit);
   1397 
   1398     switch (map_id >> _BCM_QOS_MAP_SHIFT) {
   1399         case _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP:
   1400             if (!_BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_GET(unit, id)) {
   1401                 rv = BCM_E_NOT_FOUND;
   1402             } else {
   1403                 rv = _bcm_td2_qos_map_destroy(unit, 
   1404                         _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP, id);
   1405 
   1406                 if (BCM_SUCCESS(rv)) {
   1407                     _BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_CLR(unit, id);
   1408                 }
   1409             }
   1410             break;
   1411 
   1412         case _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP:
   1413             if (!_BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_GET(unit, id)) {
   1414                 rv = BCM_E_NOT_FOUND;
   1415             } else {
   1416                 rv = _bcm_td2_qos_map_destroy(unit, 
   1417                         _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP, id);
   1418 
   1419                 if (BCM_SUCCESS(rv)) {
   1420                     _BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_CLR(unit, id);
   1421                 }
   1422             }
   1423             break;
   1424 
   1425         case _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP:
   1426             if (!_BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_GET(unit, id)) {
   1427                 rv = BCM_E_NOT_FOUND;
   1428             } else {
   1429                 rv = _bcm_td2_qos_map_destroy(unit, 
   1430                         _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP, id);
   1431 
   1432                 if (BCM_SUCCESS(rv)) {
   1433                     _BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_CLR(unit, id);
   1434                 }
   1435             }
   1436             break;
   1437         case _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP:
   1438             if (!_BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, id)) {
   1439                 rv = BCM_E_NOT_FOUND;
   1440             } else {
   1441                 rv = _bcm_td2_qos_map_destroy(unit, 
   1442                         _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP, id);
   1443         
   1444                 if (BCM_SUCCESS(rv)) {
   1445                     _BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_CLR(unit, id);
   1446                 }
   1447             }
   1448             break;
   1449         case _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP:
   1450             if (!_BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, id)) {
   1451                 rv = BCM_E_NOT_FOUND;
   1452             } else {
   1453                 rv = _bcm_td2_qos_map_destroy(unit, 
   1454                         _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP, id);
   1455         
   1456                 if (BCM_SUCCESS(rv)) {
   1457                     _BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_CLR(unit, id);
   1458                 }
   1459             }
   1460             break;
   1461         default:
   1462             rv = BCM_E_PARAM;
   1463     }
   1464 
   1465     QOS_UNLOCK(unit);
   1466 
   1467     return rv;
   1468 }
   1469 
   1470 /*
   1471  * Function: 
   1472  *     _bcm_td2_qos_map_add_sanity_check
   1473  * Purpose:
   1474  *     Check that all the paramters given to the bcm_qos_map_add() function make
   1475  *     sense and are internally consistent.
   1476  * Parameters:
   1477  *     unit   - (IN) The unit being operated on
   1478  *     flags  - (IN) BCM_QOS_MAP_* flags sent in by the app
   1479  *     map    - (IN) The map structure sent in by the app
   1480  *     map_id - (IN) The map ID sent in by the app
   1481  * Returns:
   1482  *     BCM_E_XXX
   1483  */
   1484 STATIC int
   1485 _bcm_td2_qos_map_add_sanity_check(int unit, uint32 flags, bcm_qos_map_t *map, 
   1486                                   int map_id)
   1487 {
   1488     int map_type = map_id >> _BCM_QOS_MAP_SHIFT;
   1489     int id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   1490     int rv;
   1491 
   1492     rv = _bcm_td2_qos_flags_sanity_check(flags);
   1493     if (BCM_FAILURE(rv)) {
   1494         return rv;
   1495     }
   1496 
   1497     if ((flags & BCM_QOS_MAP_INGRESS) 
   1498         && ((map_type != _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP)
   1499              && (map_type != _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP))) {
   1500         return BCM_E_PARAM;
   1501     }
   1502 
   1503     if ((flags & BCM_QOS_MAP_EGRESS) 
   1504         && ((map_type != _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP)
   1505              && (map_type != _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP)
   1506              && (map_type != _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP))
   1507            ) {
   1508         return BCM_E_PARAM;
   1509     }
   1510 
   1511     if ((flags & BCM_QOS_MAP_INGRESS) 
   1512         && (map_type == _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP) 
   1513         && (_BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_GET(unit, id) == 0)) {
   1514         return BCM_E_BADID;
   1515     }
   1516 
   1517     if ((flags & BCM_QOS_MAP_INGRESS) 
   1518         && (map_type == _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP) 
   1519         && (_BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, id) == 0)) {
   1520         return BCM_E_BADID;
   1521     }
   1522 
   1523     if ((flags & BCM_QOS_MAP_EGRESS) 
   1524         && (map_type == _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP)
   1525         && (_BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_GET(unit, id) == 0)) {
   1526         return BCM_E_BADID;
   1527     }
   1528 
   1529     if ((flags & BCM_QOS_MAP_EGRESS) 
   1530         && (map_type == _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP)
   1531         && (_BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_GET(unit, id) == 0)) {
   1532         return BCM_E_BADID;
   1533     }
   1534 
   1535     if ((flags & BCM_QOS_MAP_EGRESS) 
   1536         && (map_type == _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP)
   1537         && (_BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, id) == 0)) {
   1538         return BCM_E_BADID;
   1539     }
   1540 	
   1541     if (!(flags & BCM_QOS_MAP_L2_VLAN_ETAG)) {
   1542         if (map->int_pri < 0) {
   1543             return BCM_E_PARAM;
   1544         }
   1545     }
   1546 
   1547     if (flags & BCM_QOS_MAP_VFT) {
   1548         if (map->int_pri >= _BCM_QOS_MAX_VFT_PRIORITIES) {
   1549             return BCM_E_PARAM;
   1550         }
   1551     } else if (flags & BCM_QOS_MAP_VSAN) {
   1552         if (map->int_pri >= _BCM_QOS_MAX_VSAN_PRIORITIES) {
   1553             return BCM_E_PARAM;
   1554         }
   1555     }
   1556 
   1557     if (map->pkt_pri >= _BCM_QOS_MAX_PKT_PRIORITIES) {
   1558         return BCM_E_PARAM;
   1559     }
   1560 
   1561     if (flags & BCM_QOS_MAP_VSAN) {
   1562         if (map->color != bcmColorGreen && map->color != bcmColorYellow
   1563             && map->color != bcmColorRed) {
   1564             return BCM_E_PARAM;
   1565         }
   1566     }
   1567 
   1568     if (flags & BCM_QOS_MAP_L2_VLAN_ETAG) {
   1569         if ((map->etag_pcp >= _BCM_QOS_MAX_PKT_PRIORITIES)
   1570             || (map->etag_de >= _BCM_QOS_MAX_PKT_DES)
   1571             || (map->pkt_cfi >= _BCM_QOS_MAX_PKT_DES)) {
   1572             return BCM_E_PARAM;
   1573         }
   1574     } 
   1575 
   1576     if ((flags & BCM_QOS_MAP_L2_VLAN_ETAG)
   1577         && (flags & BCM_QOS_MAP_EGRESS)) {
   1578         if (map->color != bcmColorGreen && map->color != bcmColorYellow
   1579             && map->color != bcmColorRed) {
   1580             return BCM_E_PARAM;
   1581         }
   1582         if (map->int_pri >= _BCM_QOS_MAX_INT_PRIORITIES) {
   1583             return BCM_E_PARAM;
   1584         }
   1585     } 
   1586 
   1587     return BCM_E_NONE;
   1588 }
   1589 
   1590 /*
   1591  * Function: 
   1592  *     _bcm_td2_ing_qos_map_update_index
   1593  * Purpose:
   1594  *     Update an existing profile (or a newly created one) in the hardware's
   1595  *     table with a new mapping.  
   1596  *   
   1597  *     The structure is: (1) get existing profile for this map from hardware, 
   1598  *     (2) update the profile in RAM, (3) delete the old profile from hardware, 
   1599  *     and (4) push the updated profile in RAM to hardware.
   1600  * Parameters:
   1601  *     unit   - (IN) The unit being operated on
   1602  *     map    - (IN) Map structure sent in by app to be applied to hardware
   1603  *     map_id - (IN) Map ID sent in by app to be applied to hardware
   1604  * Returns:
   1605  *     BCM_E_XXX
   1606  */
   1607 STATIC int
   1608 _bcm_td2_ing_qos_map_update_index(int unit, bcm_qos_map_t *map, int map_id)
   1609 {
   1610     void    *entries[1];
   1611     int     rv = 0;
   1612     uint32  index;
   1613     int     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   1614 
   1615     if (QOS_MAP_IS_L2_VLAN_ETAG(map_id)) {
   1616         ing_etag_pcp_mapping_entry_t table[_BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP];        
   1617         index = VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx[id] *
   1618                                            _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP;
   1619 
   1620         entries[0] = &table;
   1621         rv = _bcm_ing_l2_vlan_etag_map_entry_get(unit, index, 
   1622                                             _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP, 
   1623                                             entries);
   1624 
   1625         if (BCM_SUCCESS(rv)) {
   1626             ing_etag_pcp_mapping_entry_t *entry = 
   1627                                     &table[(map->pkt_pri << 1) | map->pkt_cfi];
   1628 
   1629             soc_mem_field32_set(unit, ING_ETAG_PCP_MAPPINGm, 
   1630                                 entry, PCPf, map->etag_pcp);
   1631             soc_mem_field32_set(unit, ING_ETAG_PCP_MAPPINGm, 
   1632                                 entry, DEf, map->etag_de);
   1633             
   1634             rv = _bcm_ing_l2_vlan_etag_map_entry_del(unit, (int)index);
   1635         }
   1636 
   1637         if (BCM_SUCCESS(rv)) {
   1638             rv = _bcm_ing_l2_vlan_etag_map_entry_add(unit, entries,
   1639                                             _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP,
   1640                                             &index);
   1641             VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx[id] = index /
   1642                                             _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP;  
   1643         }
   1644     } else if (soc_mem_is_valid(unit, ING_VFT_PRI_MAPm)) {
   1645         ing_vft_pri_map_entry_t table[_BCM_QOS_MAP_CHUNK_VFT_PRI_MAP];    
   1646         index = VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx[id] *
   1647                                             _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP;
   1648 
   1649         entries[0] = &table;
   1650         rv = _bcm_ing_vft_pri_map_entry_get(unit, index, 
   1651                                             _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP, 
   1652                                             entries);
   1653 
   1654         if (BCM_SUCCESS(rv)) {
   1655             ing_vft_pri_map_entry_t *entry = &table[map->pkt_pri];
   1656 
   1657             soc_mem_field32_set(unit, ING_VFT_PRI_MAPm, entry, FCOE_VFT_PRIf, 
   1658                                 map->int_pri);
   1659 
   1660             rv = _bcm_ing_vft_pri_map_entry_del(unit, (int)index);
   1661         }
   1662 
   1663         if (BCM_SUCCESS(rv)) {
   1664             rv = _bcm_ing_vft_pri_map_entry_add(unit, entries,
   1665                                                 _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP, 
   1666                                                 &index);
   1667             VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx[id] = index /
   1668                                                 _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP;
   1669         }
   1670     }
   1671     return rv;
   1672 }
   1673 
   1674 /*
   1675  * Function: 
   1676  *     _bcm_td2_egr_qos_map_update_index
   1677  * Purpose:
   1678  *     Update an existing profile (or a newly created one) in the hardware's
   1679  *     table with a new mapping.  
   1680  *   
   1681  *     The structure is: (1) get existing profile for this map from hardware, 
   1682  *     (2) update the profile in RAM, (3) delete the old profile from hardware, 
   1683  *     and (4) push the updated profile in RAM to hardware.
   1684  * Parameters:
   1685  *     unit   - (IN) The unit being operated on
   1686  *     map    - (IN) Map structure sent in by app to be applied to hardware
   1687  *     map_id - (IN) Map ID sent in by app to be applied to hardware
   1688  * Returns:
   1689  *     BCM_E_XXX
   1690  */
   1691 STATIC int
   1692 _bcm_td2_egr_qos_map_update_index(int unit, bcm_qos_map_t *map, int map_id)
   1693 {
   1694     void    *entries[2];
   1695     int     rv = 0, cng;
   1696     uint32  index;
   1697     int     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   1698     egr_zone_3_dot1p_mapping_table_2_entry_t td3_etag_table[2][_BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP];
   1699         egr_etag_pcp_mapping_entry_t table[_BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP];
   1700     egr_etag_pcp_mapping_entry_t *entry;
   1701     egr_zone_3_dot1p_mapping_table_2_entry_t *td3_entry;
   1702 
   1703     if (QOS_MAP_IS_L2_VLAN_ETAG(map_id)) {
   1704         index = VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx[id] *
   1705                                            _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP;
   1706         if (SOC_IS_TRIDENT3X(unit)) {
   1707             entries[0] = td3_etag_table[0];
   1708             entries[1] = td3_etag_table[1];
   1709         } else {
   1710         entries[0] = &table;
   1711         }
   1712         rv = _bcm_egr_l2_vlan_etag_map_entry_get(unit, index, 
   1713                                             _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP,
   1714                                             entries);
   1715         if (BCM_SUCCESS(rv)) {
   1716             cng = _BCM_COLOR_ENCODING(unit, map->color);
   1717             if (SOC_IS_TRIDENT3X(unit)) {
   1718                 /* Outer Tag */
   1719                 td3_entry = &td3_etag_table[0][(map->int_pri << 2) | cng];
   1720                 soc_mem_field32_set(unit, EGR_ZONE_3_DOT1P_MAPPING_TABLE_2m,
   1721                                     td3_entry, PRIf, map->etag_pcp);
   1722                 soc_mem_field32_set(unit, EGR_ZONE_3_DOT1P_MAPPING_TABLE_2m,
   1723                                     td3_entry, CFIf, map->etag_de);
   1724                 /* Inner Tag */
   1725                 td3_entry = &td3_etag_table[1][(map->int_pri << 2) | cng];
   1726                 soc_mem_field32_set(unit, EGR_ZONE_1_DOT1P_MAPPING_TABLE_2m,
   1727                                     td3_entry, PRIf, map->etag_pcp);
   1728                 soc_mem_field32_set(unit, EGR_ZONE_1_DOT1P_MAPPING_TABLE_2m,
   1729                                     td3_entry, CFIf, map->etag_de);
   1730 
   1731             } else {
   1732             cng = _BCM_COLOR_ENCODING(unit, map->color);
   1733             entry = &table[(map->int_pri << 2) | cng];
   1734 
   1735             soc_mem_field32_set(unit, EGR_ETAG_PCP_MAPPINGm, 
   1736                                 entry, PCPf, map->etag_pcp);
   1737             soc_mem_field32_set(unit, EGR_ETAG_PCP_MAPPINGm, 
   1738                                 entry, DEf, map->etag_de);
   1739            }
   1740             rv = _bcm_egr_l2_vlan_etag_map_entry_del(unit, (int)index);
   1741         }
   1742 
   1743         if (BCM_SUCCESS(rv)) {
   1744             rv = _bcm_egr_l2_vlan_etag_map_entry_add(unit, entries,
   1745                                             _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP,
   1746                                             &index);
   1747             VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx[id] = index /
   1748                                             _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP;  
   1749         }
   1750     } else if (soc_mem_is_valid(unit, ING_VFT_PRI_MAPm)) {
   1751         egr_vft_pri_map_entry_t table[_BCM_QOS_MAP_CHUNK_VFT_PRI_MAP];
   1752         index = VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx[id] *
   1753                                              _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP;
   1754 
   1755         entries[0] = &table;
   1756         rv = _bcm_egr_vft_pri_map_entry_get(unit, index, 
   1757                                             _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP, 
   1758                                             entries);
   1759 
   1760         if (BCM_SUCCESS(rv)) {
   1761             egr_vft_pri_map_entry_t *entry = &table[map->int_pri];
   1762 
   1763             soc_mem_field32_set(unit, EGR_VFT_PRI_MAPm, entry, FCOE_VFT_PRIf,
   1764                                 map->pkt_pri);
   1765 
   1766             rv = _bcm_egr_vft_pri_map_entry_del(unit, index);
   1767         }
   1768 
   1769         if (BCM_SUCCESS(rv)) {
   1770             rv = _bcm_egr_vft_pri_map_entry_add(unit, entries,
   1771                                                 _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP, 
   1772                                                 &index);
   1773             VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx[id] = index /
   1774                                                 _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP;
   1775         }
   1776     }
   1777 
   1778     return rv;
   1779 }
   1780 
   1781 /*
   1782  * Function: 
   1783  *     _bcm_td2_color_to_hw_color
   1784  * Purpose:
   1785  *      Convert from bcm_color_t enum to hardware color values for VSAN QOS
   1786  *      mapping
   1787  * Parameters:
   1788  *      color    - (IN)  Value to convert from
   1789  *      hw_color - (OUT) Converted hardware color value
   1790  * Returns:
   1791  *     BCM_E_XXX
   1792  */
   1793 STATIC int
   1794 _bcm_td2_color_to_hw_color(bcm_color_t color, int *hw_color)
   1795 {
   1796     int rv = BCM_E_NONE;
   1797 
   1798     switch (color) {
   1799         case bcmColorRed:    *hw_color = TD2_HW_COLOR_RED;    break;
   1800         case bcmColorYellow: *hw_color = TD2_HW_COLOR_YELLOW; break;
   1801         case bcmColorGreen:  *hw_color = TD2_HW_COLOR_GREEN;  break;
   1802         default:
   1803             rv = BCM_E_PARAM;
   1804             break;
   1805     }
   1806 
   1807     return rv;
   1808 }
   1809 
   1810 /*
   1811  * Function: 
   1812  *     _bcm_td2_egr_vsan_map_update_index
   1813  * Purpose:
   1814  *     Update an existing profile (or a newly created one) in the hardware's
   1815  *     EGR_VSAN_INTPRI_MAP table with a new mapping.  
   1816  *   
   1817  *     The structure is: (1) get existing profile for this map from hardware, 
   1818  *     (2) update the profile in RAM, (3) delete the old profile from hardware, 
   1819  *     and (4) push the updated profile in RAM to hardware.
   1820  * Parameters:
   1821  *     unit   - (IN) The unit being operated on
   1822  *     map    - (IN) Map structure sent in by app to be applied to hardware
   1823  *     map_id - (IN) Map ID sent in by app to be applied to hardware
   1824  * Returns:
   1825  *     BCM_E_XXX
   1826  */
   1827 STATIC int
   1828 _bcm_td2_egr_vsan_map_update_index(int unit, bcm_qos_map_t *map, int map_id)
   1829 {
   1830     void    *entries[1];
   1831     int     rv;
   1832     uint32  index;
   1833     int     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   1834     egr_vsan_intpri_map_entry_t table[_BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP];
   1835 
   1836     index = VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx[id] *
   1837                                       _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP;
   1838 
   1839     entries[0] = &table;
   1840     rv = _bcm_egr_vsan_intpri_map_entry_get(unit, index, 
   1841                                            _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP, 
   1842                                            entries);
   1843 
   1844     if (BCM_SUCCESS(rv)) {
   1845         int hw_color = TD2_HW_COLOR_ERROR;
   1846         egr_vsan_intpri_map_entry_t *entry = NULL;
   1847 
   1848         rv = _bcm_td2_color_to_hw_color(map->color, &hw_color);
   1849         if (BCM_SUCCESS(rv)) {
   1850             entry = &table[(map->int_pri << _BCM_QOS_PRI_BIT_SHIFT) | hw_color];
   1851 
   1852             soc_mem_field32_set(unit, EGR_VSAN_INTPRI_MAPm, entry, PRIf, 
   1853                                 map->pkt_pri);
   1854 
   1855             rv = _bcm_egr_vsan_intpri_map_entry_del(unit, index);
   1856         }
   1857     }
   1858 
   1859     if (BCM_SUCCESS(rv)) {
   1860         rv = _bcm_egr_vsan_intpri_map_entry_add(unit, entries,
   1861                                             _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP, 
   1862                                             &index);
   1863         VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx[id] = index /
   1864                                             _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP;
   1865     }
   1866 
   1867     return rv;
   1868 }
   1869 /*
   1870  * Function: 
   1871  *     bcm_td2_qos_map_add
   1872  * Purpose:
   1873  *     Add a new QOS mapping to hardware.
   1874  * Parameters:
   1875  *     unit   - (IN) The unit being operated on
   1876  *     flags  - (IN) BCM_QOS_MAP_* flags
   1877  *     map    - (IN) Structure containing the priorities to be mapped
   1878  *     map_id - (IN) The ID of the map to add the new information to
   1879  * Returns:
   1880  *     BCM_E_XXX
   1881  */
   1882 int
   1883 bcm_td2_qos_map_add(int unit, uint32 flags, bcm_qos_map_t *map, int map_id)
   1884 {
   1885     int rv = BCM_E_NONE;
   1886 
   1887     QOS_INIT(unit);
   1888     QOS_LOCK(unit);
   1889 
   1890     rv = _bcm_td2_qos_map_add_sanity_check(unit, flags, map, map_id);
   1891     if (BCM_SUCCESS(rv)) {
   1892         if (flags & BCM_QOS_MAP_VSAN) {
   1893             rv = _bcm_td2_egr_vsan_map_update_index(unit, map, map_id);
   1894         } else if ((flags & BCM_QOS_MAP_INGRESS) 
   1895                     && ((flags & BCM_QOS_MAP_L2_VLAN_ETAG) 
   1896                     || (flags & BCM_QOS_MAP_VFT))) {
   1897             rv = _bcm_td2_ing_qos_map_update_index(unit, map, map_id);
   1898         } else {
   1899             rv = _bcm_td2_egr_qos_map_update_index(unit, map, map_id);
   1900         }
   1901     }
   1902 
   1903     QOS_UNLOCK(unit);
   1904 
   1905     return rv;
   1906 }
   1907 
   1908 /*
   1909  * Function: 
   1910  *     bcm_td2_qos_map_delete
   1911  * Purpose:
   1912  *     Delete a mapping (for example, the map from 7 to 3).  This is equivalent
   1913  *     to changing it to a map from 7 to 0, so this function maps the call into
   1914  *     bcm_td2_qos_map_add().
   1915  * Parameters:
   1916  *     unit   - (IN) The unit being operated on
   1917  *     flags  - (IN) BCM_QOS_MAP_* flags
   1918  *     map    - (IN) Structure containing the priorities to be mapped
   1919  *     map_id - (IN) The ID of the map to add the new information to
   1920  * Returns:
   1921  *     BCM_E_XXX
   1922  */
   1923 int
   1924 bcm_td2_qos_map_delete(int unit, uint32 flags, bcm_qos_map_t *map, int map_id)
   1925 {
   1926     int rv = BCM_E_NONE;
   1927     bcm_qos_map_t clr_map;
   1928     
   1929     QOS_INIT(unit);
   1930 
   1931     sal_memcpy(&clr_map, map, sizeof clr_map);
   1932 
   1933     rv = _bcm_td2_qos_flags_sanity_check(flags);
   1934     if (BCM_SUCCESS(rv)) {
   1935         if (flags & BCM_QOS_MAP_INGRESS) {
   1936             if (flags & BCM_QOS_MAP_VFT) {
   1937                 clr_map.int_pri = 0;
   1938             } else if (flags & BCM_QOS_MAP_L2_VLAN_ETAG) {
   1939                 clr_map.etag_pcp = 0;
   1940                 clr_map.etag_de = 0;
   1941             }
   1942         } else {
   1943             if(flags & BCM_QOS_MAP_L2_VLAN_ETAG) {
   1944                 clr_map.etag_pcp = 0;
   1945                 clr_map.etag_de = 0;
   1946             } else {
   1947                 clr_map.pkt_pri = 0;
   1948             }
   1949         }
   1950     }
   1951 
   1952     if (BCM_SUCCESS(rv)) {
   1953         rv = bcm_td2_qos_map_add(unit, flags, &clr_map, map_id);
   1954     }
   1955 
   1956     return rv;
   1957 }
   1958 
   1959 /*
   1960  * Function: 
   1961  *     _bcm_td2_qos_apply_ing_map_to_port
   1962  * Purpose:
   1963  *     Apply a fully created ingress map to a hardware port.  This is the final
   1964  *     step in the process, where the mapping becomes operational.
   1965  * Parameters:
   1966  *     unit       - (IN) Unit being operated on
   1967  *     ing_map         - (IN) ID of the map to be applied
   1968  *     local_port - (IN) Local port number to apply map to
   1969  * Returns:
   1970  *     BCM_E_XXX
   1971  */
   1972 STATIC int
   1973 _bcm_td2_qos_apply_ing_map_to_port(int unit, int ing_map, bcm_port_t local_port)
   1974 {
   1975     int rv = BCM_E_PARAM;
   1976     int id = ing_map & _BCM_QOS_MAP_TYPE_MASK;    
   1977 
   1978     soc_mem_lock(unit, PORT_TABm);
   1979     
   1980     if ((ing_map >> _BCM_QOS_MAP_SHIFT) == _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP) {
   1981         if (SOC_IS_TRIDENT3X(unit)) {
   1982             rv = _bcm_esw_port_tab_set(unit, local_port, _BCM_CPU_TABS_BOTH,
   1983                                        FCOE_VFT_PRI_MAP_PROFILEf,
   1984                                        VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx[id]);
   1985         } else {
   1986         rv = _bcm_tr2_port_tab_set(unit, local_port, FCOE_VFT_PRI_MAP_PROFILEf,
   1987                                  VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx[id]);
   1988         }
   1989     } else if ((ing_map >> _BCM_QOS_MAP_SHIFT) == 
   1990         _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP) {
   1991         if (SOC_IS_TRIDENT3X(unit)) {
   1992             rv = _bcm_esw_port_tab_set(unit, local_port, _BCM_CPU_TABS_BOTH,
   1993                                        ETAG_PCP_DE_MAPPING_PTRf,
   1994                                        VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx[id]);
   1995         } else {
   1996         rv = _bcm_tr2_port_tab_set(unit, local_port, ETAG_PCP_DE_MAPPING_PTRf,
   1997                                  VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx[id]);
   1998     }
   1999     }
   2000 
   2001     soc_mem_unlock(unit, PORT_TABm);
   2002 
   2003     return rv;
   2004 }
   2005 
   2006 /*
   2007  * Function: 
   2008  *     _bcm_td2_qos_apply_egr_map_to_port
   2009  * Purpose:
   2010  *     Apply a fully created egress map to a hardware port.  This is the final
   2011  *     step in the process, where the mapping becomes operational.
   2012  * Parameters:
   2013  *     unit       - (IN) Unit being operated on
   2014  *     id         - (IN) ID of the map to be applied
   2015  *     local_port - (IN) Local port number to apply map to
   2016  * Returns:
   2017  *     BCM_E_XXX
   2018  */
   2019 STATIC int
   2020 _bcm_td2_qos_apply_egr_map_to_port(int unit, int id, bcm_port_t local_port)
   2021 {
   2022     int rv;
   2023 
   2024     soc_mem_lock(unit, PORT_TABm);
   2025 
   2026     if (SOC_IS_TRIDENT3X(unit)) {
   2027         rv = _bcm_esw_egr_port_tab_set(unit, local_port, FCOE_VFT_PRI_MAP_PROFILEf,
   2028                                    VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx[id]);
   2029     } else {
   2030     rv = _bcm_td2_egr_port_set(unit, local_port, FCOE_VFT_PRI_MAP_PROFILEf,
   2031                                VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx[id]);
   2032     }
   2033 
   2034     soc_mem_unlock(unit, PORT_TABm);
   2035 
   2036     return rv;
   2037 }
   2038 
   2039 /*
   2040  * Function:
   2041  *     _bcm_td2_qos_port_ing_profile_get
   2042  * Purpose:
   2043  *     Retrieve a specific ingress QoS map index from given port.
   2044  * Parameters:
   2045  *     unit               - (IN) Unit being operated on
   2046  *     local_port         - (IN) Local port number to apply map to
   2047  *     ing_map_type       - (IN) type of the map to be retrieved
   2048  *     profile_idx        - (OUT) Hardware index
   2049  * Returns:
   2050  *     BCM_E_XXX
   2051  */
   2052 STATIC int
   2053 _bcm_td2_qos_port_ing_profile_get(int unit, bcm_port_t local_port,
   2054                                   int ing_map_type, int *profile_idx)
   2055 {
   2056     int rv = BCM_E_PARAM;
   2057 
   2058     if (profile_idx == NULL) {
   2059         return BCM_E_PARAM;
   2060     }
   2061 
   2062     if (ing_map_type == _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP) {
   2063         if (SOC_IS_TRIDENT3X(unit)) {
   2064             rv = _bcm_esw_port_tab_get(unit, local_port, FCOE_VFT_PRI_MAP_PROFILEf,
   2065                                        profile_idx);
   2066         } else {
   2067         rv = _bcm_tr2_port_tab_get(unit, local_port, FCOE_VFT_PRI_MAP_PROFILEf,
   2068                                    profile_idx);
   2069 
   2070         }
   2071     } else if (ing_map_type == _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP) {
   2072         if (SOC_IS_TRIDENT3X(unit)) {
   2073             rv = _bcm_esw_port_tab_get(unit, local_port, ETAG_PCP_DE_MAPPING_PTRf,
   2074                                        profile_idx);
   2075         } else {
   2076         rv = _bcm_tr2_port_tab_get(unit, local_port, ETAG_PCP_DE_MAPPING_PTRf,
   2077                                    profile_idx);
   2078     }
   2079     }
   2080 
   2081     return rv;
   2082 }
   2083 
   2084 /*
   2085  * Function:
   2086  *     _bcm_td2_qos_port_egr_profile_get
   2087  * Purpose:
   2088  *     Retrieve a specific egress QoS map index from given port.
   2089  * Parameters:
   2090  *     unit                 - (IN) Unit being operated on
   2091  *     local_port           - (IN) Local port number to apply map to
   2092  *     egr_map_type         - (IN) type of the map to be retrieved
   2093  *     profile_idx          - (OUT) Hardware index
   2094  * Returns:
   2095  *     BCM_E_XXX
   2096  */
   2097 STATIC int
   2098 _bcm_td2_qos_port_egr_profile_get(int unit, bcm_port_t local_port,
   2099                                         int egr_map_type, int *profile_idx)
   2100 {
   2101     int rv = BCM_E_PARAM;
   2102 
   2103     if (profile_idx == NULL) {
   2104         return BCM_E_PARAM;
   2105     }
   2106 
   2107     if (egr_map_type == _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP) {
   2108         if (SOC_IS_TRIDENT3X(unit)) {
   2109             rv = _bcm_esw_egr_port_tab_get(unit, local_port, FCOE_VFT_PRI_MAP_PROFILEf,
   2110                                            profile_idx);
   2111         } else {
   2112         rv = _bcm_td2_egr_port_get(unit, local_port, FCOE_VFT_PRI_MAP_PROFILEf,
   2113                                    profile_idx);
   2114     }
   2115     }
   2116 
   2117     return rv;
   2118 }
   2119 
   2120 /*
   2121  * Function: 
   2122  *     bcm_td2_qos_get_egr_vsan_hw_idx
   2123  * Purpose:
   2124  *     Given a QOS map ID for a VSAN mapping profile, return the hardware index
   2125  *     into the EGR_VSAN_INTPRI_MAP table.
   2126  * Parameters:
   2127  *     unit       - (IN) Unit being operated on
   2128  *     egr_map_id - (IN) ID of the map to be retrieved
   2129  *     hw_index   - (OUT) Hardware index that egr_map_id maps to
   2130  * Returns:
   2131  *     BCM_E_XXX
   2132  */
   2133 int
   2134 bcm_td2_qos_get_egr_vsan_hw_idx(int unit, int egr_map_id, int *hw_index)
   2135 {
   2136     int map_type = egr_map_id >> _BCM_QOS_MAP_SHIFT;
   2137     int id       = egr_map_id & _BCM_QOS_MAP_TYPE_MASK;
   2138 
   2139     if ((map_type != _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP) 
   2140         || (_BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_GET(unit, id) == 0)) {
   2141         return BCM_E_BADID;
   2142     }
   2143 
   2144     *hw_index = VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx[id]; 
   2145 
   2146     return BCM_E_NONE;
   2147 }
   2148 
   2149 /*
   2150  * Function: 
   2151  *     bcm_td2_vsan_profile_to_qos_id
   2152  * Purpose:
   2153  *     Given a hardware profile number index, find the QOS map ID which maps to it
   2154  * Parameters:
   2155  *     unit        - (IN) Unit being operated on
   2156  *     profile_num - (IN) profile number of the map to be retrieved
   2157  *     egr_map     - (OUT) Map ID that points to profile_num
   2158  * Returns:
   2159  *     BCM_E_XXX
   2160  */
   2161 int
   2162 bcm_td2_vsan_profile_to_qos_id(int unit, int profile_num, int *egr_map)
   2163 {
   2164     int i;
   2165 
   2166     for (i = 0; i < _BCM_QOS_MAX_VSAN_PRI_MAP_IDS; i++) {
   2167         if (VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx[i] == profile_num) { 
   2168             *egr_map = (_BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP << _BCM_QOS_MAP_SHIFT) 
   2169                        | i;
   2170             return BCM_E_NONE;
   2171         }
   2172     }
   2173 
   2174     return BCM_E_BADID;
   2175 }
   2176 
   2177 /*
   2178  * Function: 
   2179  *     bcm_td2_qos_port_map_set
   2180  * Purpose:
   2181  *     Apply a fully created ingress and/or egress map to a given port.  If
   2182  *     either map is given as -1 (_BCM_QOS_NO_MAP), then the parameter should be
   2183  *     ignored.
   2184  * Parameters:
   2185  *     unit    - (IN) The unit to be operated on
   2186  *     port    - (IN) The port number for the map to be applied to
   2187  *     ing_map - (IN) The ID of an ingress map to be applied
   2188  *     egr_map - (IN) The ID of an egress map to be applied
   2189  * Returns:
   2190  *     BCM_E_XXX
   2191  */
   2192 int
   2193 bcm_td2_qos_port_map_set(int unit, bcm_gport_t port, int ing_map, int egr_map)
   2194 {
   2195     int rv = BCM_E_NONE;
   2196     bcm_port_t local_port;
   2197     
   2198     QOS_INIT(unit);
   2199     QOS_LOCK(unit);
   2200 
   2201     if (!BCM_GPORT_IS_SET(port)) {
   2202         rv = BCM_E_PARAM;
   2203     }
   2204 
   2205     if (BCM_SUCCESS(rv)) {
   2206         rv = bcm_esw_port_local_get(unit, port, &local_port);
   2207     }
   2208 
   2209     if (BCM_SUCCESS(rv) && !SOC_PORT_VALID(unit, local_port)) {
   2210         rv = BCM_E_PARAM;
   2211     }
   2212 
   2213     if (BCM_SUCCESS(rv) && ing_map != _BCM_QOS_NO_MAP) {
   2214         int id = ing_map & _BCM_QOS_MAP_TYPE_MASK;
   2215 
   2216         if (((ing_map >> _BCM_QOS_MAP_SHIFT) != 
   2217             _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP)
   2218             && ((ing_map >> _BCM_QOS_MAP_SHIFT) != 
   2219             _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP)){
   2220             rv = BCM_E_PARAM;
   2221         }
   2222 
   2223         if (BCM_SUCCESS(rv) 
   2224             && ((((ing_map >> _BCM_QOS_MAP_SHIFT) == 
   2225             _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP) 
   2226             && (_BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, id) == 0))
   2227             || (((ing_map >> _BCM_QOS_MAP_SHIFT) == 
   2228             _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP) 
   2229             && (_BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_GET(unit, id) == 0)))) {
   2230             rv = BCM_E_PARAM;
   2231         }
   2232 
   2233         if (BCM_SUCCESS(rv)) {
   2234             rv = _bcm_td2_qos_apply_ing_map_to_port(unit, ing_map, local_port);
   2235         }
   2236     }
   2237 
   2238     if (BCM_SUCCESS(rv) && egr_map != _BCM_QOS_NO_MAP) {
   2239         int id = egr_map & _BCM_QOS_MAP_TYPE_MASK;
   2240 
   2241         if ((egr_map >> _BCM_QOS_MAP_SHIFT) ==
   2242             _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP) {
   2243             if (_BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_GET(unit, id) != 0) {
   2244                 rv = _bcm_td2_qos_apply_egr_map_to_port(unit, id,
   2245                                                         local_port);
   2246             } else {
   2247                 rv = BCM_E_PARAM;
   2248             }
   2249         } else if ((egr_map >> _BCM_QOS_MAP_SHIFT) ==
   2250                  _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP) {
   2251             rv = BCM_E_PARAM; /* should use bcm_td2_fcoe_intf_config_set */
   2252         }
   2253     }
   2254 
   2255     QOS_UNLOCK(unit);
   2256 
   2257     return rv;
   2258 }
   2259 
   2260 
   2261 /*
   2262  * Function:
   2263  *     bcm_td2_qos_port_map_type_get
   2264  * Purpose:
   2265  *     Retrieve ingress or egress map from a given port.
   2266  * Parameters:
   2267  *     unit         - (IN) The unit to be operated on
   2268  *     port         - (IN) The port number for the map to be retrieved from
   2269  *     flags        - (IN) type of the map which is of interest
   2270  *     map_id       - (OUT) The ID of map returned
   2271  * Returns:
   2272  *     BCM_E_XXX
   2273  */
   2274 int
   2275 bcm_td2_qos_port_map_type_get(int unit, bcm_gport_t port, uint32 flags,
   2276                               int *map_id)
   2277 {
   2278     int rv = BCM_E_NONE;
   2279     bcm_port_t local_port;
   2280     int map_type;
   2281     int profile_idx;
   2282 
   2283     QOS_INIT(unit);
   2284 
   2285     if (map_id == NULL) {
   2286         rv = BCM_E_PARAM;
   2287     }
   2288     if (!BCM_GPORT_IS_SET(port)) {
   2289         rv = BCM_E_PARAM;
   2290     }
   2291 
   2292     if (BCM_SUCCESS(rv)) {
   2293         rv = bcm_esw_port_local_get(unit, port, &local_port);
   2294     }
   2295 
   2296     if (BCM_SUCCESS(rv) && !SOC_PORT_VALID(unit, local_port)) {
   2297         rv = BCM_E_PARAM;
   2298     }
   2299 
   2300     BCM_IF_ERROR_RETURN(rv);
   2301 
   2302     if (flags & BCM_QOS_MAP_INGRESS) {
   2303         if (flags & BCM_QOS_MAP_VFT) {
   2304             map_type = _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP;
   2305         } else if (flags & BCM_QOS_MAP_L2_VLAN_ETAG) {
   2306             map_type = _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP;
   2307         } else {
   2308            rv = BCM_E_PARAM;
   2309            BCM_IF_ERROR_RETURN(rv);
   2310         }
   2311         rv = _bcm_td2_qos_port_ing_profile_get(unit, local_port, map_type,
   2312                                                &profile_idx);
   2313     } else if (flags & BCM_QOS_MAP_EGRESS) {
   2314         if (flags & BCM_QOS_MAP_VFT) {
   2315             map_type = _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP;
   2316         } else if (flags & BCM_QOS_MAP_VSAN) {
   2317             map_type = _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP;
   2318         } else if (flags & BCM_QOS_MAP_L2_VLAN_ETAG) {
   2319             map_type = _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP;
   2320         } else {
   2321             rv = BCM_E_PARAM;
   2322             BCM_IF_ERROR_RETURN(rv);
   2323         }
   2324         rv = _bcm_td2_qos_port_egr_profile_get(unit, local_port, map_type,
   2325                                                &profile_idx);
   2326     } else {
   2327         rv = BCM_E_PARAM;
   2328         BCM_IF_ERROR_RETURN(rv);
   2329     }
   2330 
   2331     if(BCM_SUCCESS(rv)) {
   2332     /* map H/W profile ID to API QoS map ID */
   2333         rv = _bcm_td2_qos_idx2id(unit, profile_idx, map_type, map_id);
   2334     }
   2335 
   2336     return rv;
   2337 }
   2338 
   2339 
   2340 /* bcm_td2_qos_map_multi_get */
   2341 int
   2342 bcm_td2_qos_map_multi_get(int unit, uint32 flags,
   2343                           int map_id, int array_size,
   2344                           bcm_qos_map_t *array, int *array_count)
   2345 {
   2346     int             rv = BCM_E_NONE;
   2347     int             num_entries, idx, id, hw_id, alloc_size, entry_size, count;
   2348     uint8           *dma_buf;
   2349     void            *entry;
   2350     soc_mem_t       mem;
   2351     bcm_qos_map_t   *map;
   2352     int cng = 0;
   2353     int hw_color = TD2_HW_COLOR_ERROR;
   2354 
   2355     /* ignore with_id & replace flags */
   2356     flags &= (~(BCM_QOS_MAP_WITH_ID | BCM_QOS_MAP_REPLACE));
   2357     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   2358     mem = INVALIDm;
   2359     hw_id = 0;
   2360     num_entries = 0;
   2361     entry_size = 0;
   2362     QOS_LOCK(unit);
   2363     switch (map_id >> _BCM_QOS_MAP_SHIFT) {
   2364     case _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP:
   2365         if ((flags != (BCM_QOS_MAP_L2_VLAN_ETAG | BCM_QOS_MAP_INGRESS)) ||
   2366             (!_BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, id))) {
   2367             rv = BCM_E_PARAM;
   2368         }
   2369         num_entries = _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP;
   2370         entry_size = sizeof(ing_etag_pcp_mapping_entry_t);
   2371         hw_id = VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx[id] *
   2372                                            _BCM_QOS_MAP_CHUNK_L2_VLAN_ETAG_MAP;
   2373         mem = ING_ETAG_PCP_MAPPINGm;
   2374         break;
   2375 
   2376     case _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP:
   2377         if ((flags != (BCM_QOS_MAP_L2_VLAN_ETAG | BCM_QOS_MAP_EGRESS)) ||
   2378             (!_BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, id))) {
   2379             rv = BCM_E_PARAM;
   2380             break;
   2381         }
   2382         num_entries = _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP;
   2383         if (SOC_IS_TRIDENT3X(unit)) {
   2384             entry_size = sizeof(egr_zone_3_dot1p_mapping_table_2_entry_t);
   2385             mem = EGR_ZONE_3_DOT1P_MAPPING_TABLE_2m;
   2386         } else {
   2387         entry_size = sizeof(egr_etag_pcp_mapping_entry_t);
   2388         mem = EGR_ETAG_PCP_MAPPINGm;
   2389         }
   2390         hw_id = VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx[id] *
   2391                                        _BCM_QOS_MAP_CHUNK_EGR_L2_VLAN_ETAG_MAP;
   2392         break;
   2393 
   2394     case _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP:
   2395         if ((flags != (BCM_QOS_MAP_VSAN | BCM_QOS_MAP_EGRESS)) ||
   2396             (!_BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_GET(unit, id))) {
   2397             rv = BCM_E_PARAM;
   2398             break;
   2399         }
   2400         num_entries = _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP;
   2401         entry_size = sizeof(egr_vsan_intpri_map_entry_t);
   2402         hw_id = VFT_QOS_INFO(unit)->egr_vsan_intpri_map_hwidx[id] *
   2403                                        _BCM_QOS_MAP_CHUNK_VSAN_PRI_MAP;
   2404         mem = EGR_VSAN_INTPRI_MAPm;
   2405         break;
   2406 
   2407     case _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP:
   2408         if ((flags != (BCM_QOS_MAP_VFT | BCM_QOS_MAP_INGRESS)) ||
   2409             (!_BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_GET(unit, id))) {
   2410             rv = BCM_E_PARAM;
   2411             break;
   2412         }
   2413         num_entries = _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP;
   2414         entry_size = sizeof(ing_vft_pri_map_entry_t);
   2415         hw_id = VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx[id] *
   2416                                            _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP;
   2417         mem = ING_VFT_PRI_MAPm;
   2418         break;
   2419 
   2420     case _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP:
   2421         if ((flags != (BCM_QOS_MAP_VFT | BCM_QOS_MAP_EGRESS)) ||
   2422             (!_BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_GET(unit, id))) {
   2423             rv = BCM_E_PARAM;
   2424         }
   2425         num_entries = _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP;
   2426         entry_size = sizeof(egr_vft_pri_map_entry_t);
   2427         hw_id = VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx[id] *
   2428                                        _BCM_QOS_MAP_CHUNK_VFT_PRI_MAP;
   2429         mem = EGR_VFT_PRI_MAPm;
   2430         break;
   2431 
   2432     default:
   2433         rv = BCM_E_PARAM;
   2434     }
   2435     QOS_UNLOCK(unit);
   2436     BCM_IF_ERROR_RETURN(rv);
   2437 
   2438     if (array_size == 0) { /* querying the size of map-chunk */
   2439         *array_count = num_entries;
   2440         return BCM_E_NONE;
   2441     }
   2442     if (!array || !array_count) {
   2443         return BCM_E_PARAM;
   2444     }
   2445 
   2446     /* Allocate memory for DMA & regular */
   2447     alloc_size = num_entries * entry_size;
   2448     dma_buf = soc_cm_salloc(unit, alloc_size, "TD2 qos multi get DMA buf");
   2449     if (!dma_buf) {
   2450         return BCM_E_MEMORY;
   2451     }
   2452     sal_memset(dma_buf, 0, alloc_size);
   2453 
   2454     /* Read the profile chunk */
   2455     rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, hw_id,
   2456                             (hw_id + num_entries - 1), dma_buf);
   2457     if (BCM_FAILURE(rv)) {
   2458         soc_cm_sfree(unit, dma_buf);
   2459         return rv;
   2460     }
   2461 
   2462     count = 0;
   2463     QOS_LOCK(unit);
   2464     switch (map_id >> _BCM_QOS_MAP_SHIFT) {
   2465     case _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP:
   2466         for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) {
   2467             map = &array[idx];
   2468             sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   2469             map->pkt_pri = ((idx & 0xe) >> 1);
   2470             map->pkt_cfi = (idx & 0x1);
   2471             entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
   2472                                                  dma_buf, idx);
   2473             map->etag_pcp = soc_mem_field32_get(unit, mem, entry, PCPf);
   2474             map->etag_de = soc_mem_field32_get(unit, mem, entry, DEf);
   2475             count++;
   2476         }
   2477         break;
   2478 
   2479     case _BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP:
   2480         for (idx = 0; ((idx < num_entries) && (count < array_size)); idx++) {
   2481             map = &array[idx];
   2482             sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   2483             map->int_pri = (idx >> 2) & 0xf;
   2484             cng = idx & 0x3;
   2485             map->color = _BCM_COLOR_DECODING(unit, cng);
   2486             entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
   2487                                                  dma_buf, idx);
   2488             if (SOC_IS_TRIDENT3X(unit)) {
   2489                map->etag_pcp = soc_mem_field32_get(unit, mem, entry, PRIf);
   2490                map->etag_de = soc_mem_field32_get(unit, mem, entry, CFIf);
   2491             } else {
   2492             map->etag_pcp = soc_mem_field32_get(unit, mem, entry, PCPf);
   2493             map->etag_de = soc_mem_field32_get(unit, mem, entry, DEf);
   2494             }
   2495             count++;
   2496         }
   2497         break;
   2498 
   2499     case _BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP:
   2500         for (idx = 0; ((idx < num_entries) && (count < array_size)); idx++) {
   2501             map = &array[idx];
   2502             sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   2503             map->int_pri = ((idx & 0x3c) >> 2);
   2504             hw_color = (idx & 0x3);
   2505             map->color = _BCM_COLOR_DECODING(unit, hw_color);
   2506             entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
   2507                                                  dma_buf, idx);
   2508             map->pkt_pri = soc_mem_field32_get(unit, mem, entry, PRIf);
   2509             count++;
   2510         }
   2511         break;
   2512 
   2513      case _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP:
   2514          for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) {
   2515              map = &array[idx];
   2516              sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   2517              map->pkt_pri = idx;
   2518              entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
   2519                                                   dma_buf, idx);
   2520              map->int_pri = soc_mem_field32_get(unit, mem, entry, FCOE_VFT_PRIf);
   2521              count++;
   2522          }
   2523          break;
   2524 
   2525      case _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP:
   2526          for (idx = 0; ((idx < num_entries) && (count < array_size)); idx++) {
   2527              map = &array[idx];
   2528              sal_memset(map, 0x0, sizeof(bcm_qos_map_t));
   2529              map->int_pri = idx;
   2530              entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
   2531                                                   dma_buf, idx);
   2532              map->pkt_pri = soc_mem_field32_get(unit, mem, entry, FCOE_VFT_PRIf);
   2533              count++;
   2534          }
   2535          break;
   2536 
   2537     default:
   2538         rv = BCM_E_INTERNAL; /* should not hit this */
   2539     }
   2540     QOS_UNLOCK(unit);
   2541     soc_cm_sfree(unit, dma_buf);
   2542 
   2543     BCM_IF_ERROR_RETURN(rv);
   2544 
   2545     *array_count = count;
   2546     return BCM_E_NONE;
   2547 }
   2548 
   2549 #undef DSCP_CODE_POINT_CNT
   2550 #define DSCP_CODE_POINT_CNT 64
   2551 #undef DSCP_CODE_POINT_MAX
   2552 #define DSCP_CODE_POINT_MAX (DSCP_CODE_POINT_CNT - 1)
   2553 #define _BCM_QOS_MAP_CHUNK_DSCP  64
   2554 
   2555  /* Function:
   2556  *      bcm_td2_port_dscp_map_set
   2557  * Purpose:
   2558  *      Internal implementation for bcm_td2_port_dscp_map_set
   2559  * Parameters:
   2560  *      unit - switch device
   2561  *      port - switch port or -1 for global table
   2562  *      srccp - src code point or -1
   2563  *      mapcp - mapped code point or -1
   2564  *      prio - priority value for mapped code point
   2565  *              -1 to use port default untagged priority
   2566  *              BCM_PRIO_RED    can be or'ed into the priority
   2567  *              BCM_PRIO_YELLOW can be or'ed into the priority
   2568  * Returns:
   2569  *      BCM_E_XXX
   2570  */
   2571 
   2572 int
   2573 bcm_td2_port_dscp_map_set(int unit, bcm_port_t port, int srccp,
   2574                             int mapcp, int prio, int cng)
   2575 {
   2576     port_tab_entry_t         pent;
   2577     void                     *entries[2];
   2578     uint32                   old_profile_index = 0;
   2579     int                      index = 0;
   2580     int                      rv = BCM_E_NONE;
   2581     dscp_table_entry_t dscp_table[64];
   2582     phb_mapping_tbl_2_entry_t phb_map_tbl[64];
   2583     int  offset = 0, i = 0;
   2584     void *entry = NULL;
   2585     soc_mem_t               dscpm = DSCP_TABLEm;
   2586     soc_field_t             prifd = PRIf;
   2587     int port_count = 0, ref_count = 0;
   2588     /* Lock the port table */
   2589     PORT_LOCK(unit);
   2590 
   2591     if (SOC_IS_TRIDENT3X(unit)) {
   2592         rv = _bcm_esw_port_tab_get(unit, port, TRUST_DSCP_PTRf,
   2593                                    (void *)&old_profile_index);
   2594         if (BCM_FAILURE(rv)) {
   2595             goto cleanup_bcm_td2_port_dscp_map_set;
   2596         }
   2597         old_profile_index = old_profile_index * DSCP_CODE_POINT_CNT;
   2598     } else {
   2599     /* Get profile index from port table. */
   2600         rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port, &pent);
   2601     if (BCM_FAILURE(rv)) {
   2602         goto cleanup_bcm_td2_port_dscp_map_set;
   2603     }
   2604     old_profile_index =
   2605             soc_mem_field32_get(unit, PORT_TABm, &pent, TRUST_DSCP_PTRf) * \
   2606             DSCP_CODE_POINT_CNT;
   2607     }
   2608 
   2609     sal_memset(dscp_table, 0, sizeof(dscp_table));
   2610     sal_memset(phb_map_tbl, 0, sizeof(phb_map_tbl));
   2611 
   2612             /* Base index of table in hardware */
   2613     if (SOC_MEM_IS_VALID(unit, PHB_MAPPING_TBL_2m)) {
   2614         entries[0] = &phb_map_tbl;
   2615         dscpm = PHB_MAPPING_TBL_2m;
   2616         prifd = INT_PRIf;
   2617     } else {
   2618     entries[0] = &dscp_table;
   2619     }
   2620 
   2621     rv =  _bcm_dscp_table_entry_get(unit, old_profile_index, 64, entries);
   2622     if (BCM_FAILURE(rv)) {
   2623         goto cleanup_bcm_td2_port_dscp_map_set;
   2624     }
   2625     offset = srccp;
   2626             /* Modify what's needed */
   2627 
   2628     if (offset < 0) {
   2629         for (i = 0; i <= DSCP_CODE_POINT_MAX; i++) {
   2630             if (dscpm == DSCP_TABLEm) {
   2631              entry = &dscp_table[i];
   2632             } else {
   2633                 entry = &phb_map_tbl[i];
   2634                 soc_mem_field32_set(unit, dscpm, entry, DSCP_VALIDf, 1);
   2635             }
   2636             soc_mem_field32_set(unit, dscpm, entry, DSCPf, mapcp);
   2637             soc_mem_field32_set(unit, dscpm, entry, prifd, prio);
   2638             soc_mem_field32_set(unit, dscpm, entry, CNGf, cng);
   2639         }
   2640     } else {
   2641         if (dscpm == DSCP_TABLEm) {
   2642         entry = &dscp_table[offset];
   2643         } else {
   2644             entry = &phb_map_tbl[offset];
   2645             soc_mem_field32_set(unit, dscpm, entry, DSCP_VALIDf, 1);
   2646         }
   2647         soc_mem_field32_set(unit, dscpm, entry, DSCPf, mapcp);
   2648         soc_mem_field32_set(unit, dscpm, entry, prifd, prio);
   2649         soc_mem_field32_set(unit, dscpm, entry, CNGf, cng);
   2650     }
   2651 
   2652             /* Add new chunk and store new HW index */
   2653     rv = _bcm_dscp_table_entry_add(unit, entries, _BCM_QOS_MAP_CHUNK_DSCP, 
   2654                                            (uint32 *)&index);
   2655     if (BCM_FAILURE(rv)) {
   2656         goto cleanup_bcm_td2_port_dscp_map_set;
   2657     }
   2658 
   2659     if (index != old_profile_index) {
   2660         if (SOC_IS_TRIDENT3X(unit)) {
   2661             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
   2662                             TRUST_DSCP_PTRf, index / _BCM_QOS_MAP_CHUNK_DSCP);
   2663             if (BCM_FAILURE(rv)) {
   2664                 goto cleanup_bcm_td2_port_dscp_map_set;
   2665             }
   2666         } else {
   2667             soc_mem_field32_set(unit, PORT_TABm, &pent, TRUST_DSCP_PTRf,
   2668                             index / _BCM_QOS_MAP_CHUNK_DSCP);
   2669             rv = soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port,
   2670                             &pent);
   2671             if (BCM_FAILURE(rv)) {
   2672                 goto cleanup_bcm_td2_port_dscp_map_set;
   2673             }
   2674         }
   2675     }
   2676     if (!old_profile_index) {
   2677         BCM_PBMP_COUNT(PBMP_ALL(unit), port_count);
   2678         rv = _bcm_dscp_table_entry_ref_count_get(unit, old_profile_index,
   2679                                                      &ref_count);
   2680         if (BCM_FAILURE(rv)) {
   2681             goto cleanup_bcm_td2_port_dscp_map_set;
   2682         }
   2683         /* DSCP_TABLE default profile index 0 is referenced by all active
   2684          * ports in the cosq init time. Reference count for profile index 0
   2685          * should be decremented only when it is greater than active port
   2686          * count.
   2687          */
   2688         if (ref_count > port_count) {
   2689            rv = _bcm_dscp_table_entry_delete(unit, old_profile_index);
   2690         }
   2691     } else {
   2692         rv = _bcm_dscp_table_entry_delete(unit, old_profile_index);
   2693     }
   2694 
   2695     cleanup_bcm_td2_port_dscp_map_set:
   2696     /* Release port table lock */
   2697     PORT_UNLOCK(unit);
   2698         return rv;
   2699 }
   2700 
   2701 /* Function:
   2702 *	   bcm_td2_qos_egr_etag_id2profile
   2703 * Purpose:
   2704 *	 Given a QOS map ID for a egress etag mapping profile, return the profile number
   2705  *     into the EGR_ETAG_PCP_MAPPING table.
   2706 * Parameters:
   2707 *      unit - (IN) Unit being operated on
   2708 *      map_id - (IN) ID of the map to be retrieved
   2709 *      profile_num - (OUT) Hardware profile number that map_id maps to
   2710 * Returns:
   2711 *	   BCM_E_XXX
   2712 */	   
   2713 int
   2714 bcm_td2_qos_egr_etag_id2profile(int unit, int map_id, int *profile_num)
   2715 {
   2716     int id;
   2717 
   2718     QOS_INIT(unit);
   2719     id = map_id & _BCM_QOS_MAP_TYPE_MASK;
   2720 
   2721     QOS_LOCK(unit);
   2722     if (!_BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, id)) {
   2723         QOS_UNLOCK(unit);
   2724         return BCM_E_NOT_FOUND;
   2725     } else {
   2726         *profile_num = VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx[id];
   2727     }
   2728 
   2729     QOS_UNLOCK(unit);
   2730     return BCM_E_NONE;
   2731 }
   2732 
   2733 /* Function:
   2734 *	   bcm_td2_qos_egr_etag_profile2id
   2735 * Purpose:
   2736 *	   Given a EGR_ETAG_PCP_MAPPING table profile number, find the QOS map ID which maps to it.
   2737 * Parameters:
   2738 *      unit - (IN) Unit being operated on
   2739 *      profile_num - (IN) profile number of the map to be retrieved
   2740  *     map_id       - (OUT) Map ID that points to profile_num
   2741 * Returns:
   2742 *	   BCM_E_XXX
   2743 */	   
   2744 int
   2745 bcm_td2_qos_egr_etag_profile2id(int unit, int profile_num, int *map_id)
   2746 {
   2747     int i;
   2748 
   2749     QOS_INIT(unit);
   2750 
   2751     QOS_LOCK(unit);
   2752     for (i = 0; i < _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAP_IDS; i++) {
   2753         if (VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map_hwidx[i] == profile_num) {
   2754                 *map_id = (_BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP << _BCM_QOS_MAP_SHIFT) | i;
   2755                  QOS_UNLOCK(unit);
   2756                  return BCM_E_NONE;
   2757         }
   2758     }
   2759     
   2760     QOS_UNLOCK(unit);
   2761     return BCM_E_BADID;
   2762 }
   2763 
   2764 /* Function:
   2765 *     _bcm_td2_qos_id2idx
   2766 * Purpose:
   2767 *    Translate hardware table index into map ID used by API
   2768 * Parameters:
   2769 * Returns:
   2770 *    BCM_E_XXX
   2771 */   
   2772 int
   2773 _bcm_td2_qos_idx2id(int unit, int hw_idx, int type, int *map_id)
   2774 {
   2775     int idx;
   2776     int rv = BCM_E_NOT_FOUND;
   2777 
   2778     if (map_id == NULL) {
   2779         return BCM_E_PARAM;
   2780     }
   2781 
   2782     QOS_INIT(unit);
   2783 
   2784     QOS_LOCK(unit);
   2785 
   2786     switch (type) {
   2787     case _BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP:
   2788         for (idx = 0; idx < _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS; idx++) {
   2789             if (_BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, idx)) {
   2790                 if (VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map_hwidx[idx]
   2791                         == hw_idx) {
   2792                     *map_id = idx | (_BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP
   2793                                          << _BCM_QOS_MAP_SHIFT);
   2794                     rv = BCM_E_NONE;
   2795                     break;
   2796                 }
   2797             }
   2798         }
   2799 
   2800         break;
   2801 
   2802     case _BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP:
   2803         for (idx = 0; idx < _BCM_QOS_MAX_VFT_PRI_MAPS; idx++) {
   2804             if (_BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_GET(unit, idx)) {
   2805                 if (VFT_QOS_INFO(unit)->ing_vft_pri_map_hwidx[idx] == hw_idx) {
   2806                     *map_id = idx | (_BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP
   2807                                         << _BCM_QOS_MAP_SHIFT);
   2808                     rv = BCM_E_NONE;
   2809                     break;
   2810                 }
   2811             }
   2812         }
   2813 
   2814         break;
   2815 
   2816     case _BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP:
   2817         for (idx = 0; idx < _BCM_QOS_MAX_VFT_PRI_MAPS; idx++) {
   2818             if (_BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_GET(unit, idx)) {
   2819                 if (VFT_QOS_INFO(unit)->egr_vft_pri_map_hwidx[idx] == hw_idx) {
   2820                     *map_id = idx | (_BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP
   2821                                          << _BCM_QOS_MAP_SHIFT);
   2822                     rv = BCM_E_NONE;
   2823                     break;
   2824                 }
   2825             }
   2826         }
   2827 
   2828         break;
   2829 
   2830     default:
   2831         rv = BCM_E_NOT_FOUND;
   2832     }
   2833 
   2834     QOS_UNLOCK(unit);
   2835 
   2836     return rv;
   2837 }
   2838 
   2839 /* Get the list of all created fcoe Map-ids along with corresponding flags */
   2840 void
   2841 _bcm_td2_qos_fcoe_get(int unit, int array_size, int *map_ids_array,
   2842                        int *flags_array, int *array_count)
   2843 {
   2844     int idx, count;
   2845 
   2846     if (array_size == 0) {
   2847         *array_count = 0;
   2848         count = 0;
   2849         SHR_BITCOUNT_RANGE(VFT_QOS_INFO(unit)->egr_vsan_intpri_map, count,
   2850                            0, _BCM_QOS_MAX_VSAN_PRI_MAPS);
   2851         *array_count += count;
   2852         SHR_BITCOUNT_RANGE(VFT_QOS_INFO(unit)->ing_vft_pri_map, count,
   2853                            0, _BCM_QOS_MAX_VFT_PRI_MAPS);
   2854         *array_count += count;
   2855         SHR_BITCOUNT_RANGE(VFT_QOS_INFO(unit)->egr_vft_pri_map, count,
   2856                            0, _BCM_QOS_MAX_VFT_PRI_MAPS);
   2857         *array_count += count;
   2858     } else {
   2859         for (idx = 0; ((idx < _BCM_QOS_MAX_VSAN_PRI_MAPS) &&
   2860              (*array_count < array_size)); idx++) {
   2861             if (_BCM_QOS_EGR_VSAN_PRI_MAP_TABLE_USED_GET(unit, idx)) {
   2862                 *(map_ids_array + *array_count) =
   2863                     idx | (_BCM_QOS_MAP_TYPE_EGR_VSAN_PRI_MAP <<
   2864                            _BCM_QOS_MAP_SHIFT);
   2865                 *(flags_array + *array_count) = BCM_QOS_MAP_VSAN | BCM_QOS_MAP_EGRESS;
   2866                 (*array_count)++;
   2867             }
   2868         }
   2869         for (idx = 0; ((idx < _BCM_QOS_MAX_VFT_PRI_MAPS) &&
   2870              (*array_count < array_size)); idx++) {
   2871             if (_BCM_QOS_ING_VFT_PRI_MAP_TABLE_USED_GET(unit, idx)) {
   2872                 *(map_ids_array + *array_count) =
   2873                     idx | (_BCM_QOS_MAP_TYPE_ING_VFT_PRI_MAP <<
   2874                            _BCM_QOS_MAP_SHIFT);
   2875                 *(flags_array + *array_count) = BCM_QOS_MAP_VFT | BCM_QOS_MAP_INGRESS;
   2876                 (*array_count)++;
   2877             }
   2878         }
   2879         for (idx = 0; ((idx < _BCM_QOS_MAX_VFT_PRI_MAPS) &&
   2880              (*array_count < array_size)); idx++) {
   2881             if (_BCM_QOS_EGR_VFT_PRI_MAP_TABLE_USED_GET(unit, idx)) {
   2882                 *(map_ids_array + *array_count) =
   2883                     idx | (_BCM_QOS_MAP_TYPE_EGR_VFT_PRI_MAP <<
   2884                            _BCM_QOS_MAP_SHIFT);
   2885                 *(flags_array + *array_count) = BCM_QOS_MAP_VFT | BCM_QOS_MAP_EGRESS;
   2886                 (*array_count)++;
   2887             }
   2888         }
   2889     }
   2890     return;
   2891 }
   2892 
   2893 /* Get the list of all created L2 VLAN ETAG Map-ids along with corresponding flags */
   2894 int
   2895 _bcm_td2_qos_multi_get(int unit, int array_size, int *map_ids_array,
   2896                        int *flags_array, int *array_count)
   2897 {
   2898     /* Assume that QoS lock has been taken */
   2899 
   2900     int idx, count;
   2901     int rv = BCM_E_NONE;
   2902 
   2903     if (array_size == 0) {
   2904         if (array_count == NULL) {
   2905             rv = BCM_E_PARAM;
   2906         }
   2907 
   2908         if (BCM_SUCCESS(rv)) {
   2909             *array_count = 0;
   2910             count = 0;
   2911             SHR_BITCOUNT_RANGE(VFT_QOS_INFO(unit)->ing_l2_vlan_etag_map, count,
   2912                                0, _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS);
   2913             *array_count += count;
   2914             count = 0;
   2915             SHR_BITCOUNT_RANGE(VFT_QOS_INFO(unit)->egr_l2_vlan_etag_map, count,
   2916                                0, _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS);
   2917             *array_count += count;
   2918         }
   2919     } else {
   2920         if ((map_ids_array == NULL) || (flags_array == NULL) ||
   2921             (array_count == NULL)) {
   2922             rv = BCM_E_PARAM;
   2923         }
   2924 
   2925         if (BCM_SUCCESS(rv)) {
   2926             count = 0;
   2927             for (idx = 0; ((idx < _BCM_QOS_MAX_L2_VLAN_ETAG_MAPS) &&
   2928                  (count < array_size)); idx++) {
   2929                 if (_BCM_QOS_ING_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, idx)) {
   2930                     *(map_ids_array + count) =
   2931                         idx | (_BCM_QOS_MAP_TYPE_ING_L2_VLAN_ETAG_MAP <<
   2932                                _BCM_QOS_MAP_SHIFT);
   2933                     *(flags_array + count) = BCM_QOS_MAP_L2_VLAN_ETAG | BCM_QOS_MAP_INGRESS;
   2934                     count++;
   2935                 }
   2936             }
   2937             for (idx = 0; ((idx < _BCM_QOS_MAX_EGR_L2_VLAN_ETAG_MAPS) &&
   2938                  (count < array_size)); idx++) {
   2939                 if (_BCM_QOS_EGR_L2_VLAN_ETAG_MAP_TABLE_USED_GET(unit, idx)) {
   2940                     *(map_ids_array + count) =
   2941                         idx | (_BCM_QOS_MAP_TYPE_EGR_L2_VLAN_ETAG_MAP <<
   2942                                _BCM_QOS_MAP_SHIFT);
   2943                     *(flags_array + count) = BCM_QOS_MAP_L2_VLAN_ETAG | BCM_QOS_MAP_EGRESS;
   2944                     count++;
   2945                 }
   2946             }
   2947 
   2948             *array_count = count;
   2949         }
   2950 
   2951     }
   2952 
   2953     return rv;
   2954 }
   2955 
   2956 #endif /* BCM_TRIDENT2_SUPPORT */