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


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  * All Rights Reserved.$
      7  *
      8  * QoS module
      9  */
     10 #include <soc/defs.h>
     11 #include <shared/bsl.h>
     12 #include <assert.h>
     13 
     14 #include <sal/core/libc.h>
     15 #include <shared/util.h>
     16 #include <soc/cm.h>
     17 #include <soc/drv.h>
     18 #include <soc/scache.h>
     19 #include <bcm/qos.h>
     20 #include <bcm/error.h>
     21 #include <bcm_int/esw/triumph2.h>
     22 #include <bcm_int/esw/qos.h>
     23 
     24 #if defined(BCM_TRIUMPH3_SUPPORT)
     25 #include <bcm_int/esw/triumph3.h>
     26 #endif /* BCM_TRIUMPH3_SUPPORT */
     27 
     28 #include <bcm_int/esw/triumph.h>
     29 #include <bcm_int/esw/port.h>
     30 #include <bcm_int/esw/firebolt.h>
     31 #include <bcm_int/esw/trx.h>
     32 #include <bcm_int/esw/virtual.h>
     33 #include <bcm_int/esw/xgs3.h>
     34 #include <bcm_int/esw_dispatch.h>
     35 #include <bcm_int/esw/switch.h>
     36 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
     37 #include <bcm_int/esw/mpls.h>
     38 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */
     39 
     40 #define TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE    8
     41 #define EGR_MPLS_COMBO_MAP_ENTRY_TOTAL       TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE
     42 #define EGR_OUTER_ZONE_TABLE_OFFSET          2
     43 #define EGR_INNER_ZONE_TABLE_OFFSET          1
     44 #define EGR_MPLS_EXP_MEM_TABLE_OFFSET        5
     45 
     46 #define EGR_MPLS_PRI_ENTRY_TOTAL             1
     47 #define EGR_MPLS_ZONE_ENTRY_TOTAL            4
     48 #define EGR_MPLS_EXP_ENTRY_TOTAL             3
     49 
     50 #ifdef BCM_TRIDENT3_SUPPORT
     51 #define _BCM_QOS_PROFILE_ENTRIES_PER_SET 64
     52 
     53 soc_mem_t  egr_mpls_combo_map_info[BCM_MAX_NUM_UNITS][EGR_MPLS_COMBO_MAP_ENTRY_TOTAL];
     54 int egr_mpls_combo_map_entry_total[BCM_MAX_NUM_UNITS];
     55 
     56 void bcm_td3_egr_mpls_combo_map_info_init(uint32 unit)
     57 {
     58     if (SOC_IS_TRIDENT3X(unit)) {
     59         egr_mpls_combo_map_entry_total[unit] = TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE;
     60         egr_mpls_combo_map_info[unit][0] = EGR_MPLS_PRI_MAPPINGm;
     61         egr_mpls_combo_map_info[unit][1] = EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m;
     62         egr_mpls_combo_map_info[unit][2] = EGR_ZONE_3_DOT1P_MAPPING_TABLE_4m;
     63         egr_mpls_combo_map_info[unit][3] = EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m;
     64         egr_mpls_combo_map_info[unit][4] = EGR_ZONE_1_DOT1P_MAPPING_TABLE_4m;
     65         egr_mpls_combo_map_info[unit][5] = EGR_MPLS_EXP_MAPPING_1m;
     66         egr_mpls_combo_map_info[unit][6] = EGR_MPLS_EXP_MAPPING_2m;
     67         egr_mpls_combo_map_info[unit][7] = EGR_MPLS_EXP_MAPPING_3m;
     68     }
     69 }
     70 
     71 void bcm_td3_egr_mpls_combo_create_zone_entry(int unit,
     72                                               soc_mem_t mem, 
     73                                               int mems_cnt, 
     74                                               int *mem_words, 
     75                                               soc_mem_t *mems)
     76 {
     77     if (SOC_MEM_IS_VALID(unit, mem)) {
     78         *(mems + mems_cnt) = mem;
     79         /* Since Zone memory are the same, we use first one as template */
     80         if (EGR_MPLS_PRI_MAPPINGm == mem) {
     81             *(mem_words + mems_cnt) = sizeof(egr_mpls_pri_mapping_entry_t) /
     82                                     sizeof(uint32);
     83 	} else if ((EGR_MPLS_EXP_MAPPING_1m == mem) || 
     84                    (EGR_MPLS_EXP_MAPPING_2m == mem) ||
     85                    (EGR_MPLS_EXP_MAPPING_3m == mem)) {
     86             *(mem_words + mems_cnt) = sizeof(egr_mpls_exp_mapping_1_entry_t) /
     87                                     sizeof(uint32);
     88         } else {
     89             /* Those entry share the same size */
     90             *(mem_words + mems_cnt) = sizeof(egr_zone_1_dot1p_mapping_table_1_entry_t) /
     91                                     sizeof(uint32);
     92 	}
     93     }
     94 }
     95 
     96 int bcm_td3_combo_entry_size(int unit,
     97                              soc_mem_t mem)
     98 {
     99     int mem_size = 0;
    100 
    101     if (SOC_MEM_IS_VALID(unit, mem)) {
    102         /* Since Zone memory are the same, we use first one as template */
    103         if (EGR_MPLS_PRI_MAPPINGm == mem) {
    104             mem_size = sizeof(egr_mpls_pri_mapping_entry_t);
    105         } else if ((EGR_MPLS_EXP_MAPPING_1m == mem) ||
    106                    (EGR_MPLS_EXP_MAPPING_2m == mem) ||
    107                    (EGR_MPLS_EXP_MAPPING_3m == mem)) {
    108             mem_size = sizeof(egr_mpls_exp_mapping_1_entry_t);
    109         } else {
    110             /* Those entry share the same size */
    111             mem_size = sizeof(egr_zone_3_dot1p_mapping_table_3_entry_t);
    112         }
    113     }
    114 
    115     return mem_size;
    116 }
    117 
    118 void bcm_td3_egr_mpls_map_entry_default(int unit, soc_mem_t mem, uint32 *map_buf, uint32 entry_size)
    119 {
    120     int int_pri;
    121     int cng;
    122     uint32 *buf;
    123 
    124     if ((EGR_MPLS_EXP_MAPPING_1m == mem) || 
    125         (EGR_MPLS_EXP_MAPPING_2m == mem) ||
    126         (EGR_MPLS_EXP_MAPPING_3m == mem)) {
    127        /* Those 3 memory don't need default */
    128        return;
    129     }
    130 
    131     if (SOC_MEM_IS_VALID(unit, mem)) {
    132         for (int_pri = 0; int_pri < 16; int_pri++) {
    133             for (cng = 0; cng < 4; cng++) {
    134 	        /* This loops altogher 6 bits - yet we only support up to 4 bits */
    135                 buf = (uint32 *)((char *)map_buf + (((int_pri << 2) | cng) * entry_size));
    136 	        if (EGR_MPLS_PRI_MAPPINGm == mem) {
    137                     soc_mem_field32_set(unit, mem, buf, NEW_PRIf, int_pri > 7? 7: int_pri);
    138                     soc_mem_field32_set(unit, mem, buf, NEW_CFIf, cng > 1?1:cng);
    139 		} else {
    140                     soc_mem_field32_set(unit, mem, buf, PRIf, int_pri > 7? 7: int_pri);
    141                     soc_mem_field32_set(unit, mem, buf, CFIf, cng > 1?1:cng);
    142                 }
    143             }
    144         }
    145     }
    146 
    147     return;
    148 }
    149 
    150 int bcm_td3_egr_mpls_combo_map_create(uint32 unit, 
    151                                       int *egr_mpls_combo_map_created,
    152                                       soc_profile_mem_t **egr_mpls_combo_map)
    153 {
    154     soc_mem_t mem;
    155     soc_mem_t mems[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE];
    156     int mem_words[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE];
    157     int ix;
    158     int rv = BCM_E_NONE;
    159 
    160     if (NULL == *egr_mpls_combo_map) {
    161         *egr_mpls_combo_map = sal_alloc(sizeof(soc_profile_mem_t),
    162                                              "MPLS Combo Profile Mem");
    163         if (*egr_mpls_combo_map == NULL) {
    164             return BCM_E_MEMORY;
    165         }
    166         soc_profile_mem_t_init(*egr_mpls_combo_map);
    167 
    168         /* Prevent entries from moving around in the tables */
    169         (*egr_mpls_combo_map)->flags = SOC_PROFILE_MEM_F_NO_SHARE;
    170 
    171         for (ix=0; ix < egr_mpls_combo_map_entry_total[unit]; ix++) {
    172             /* First memory entry of the combo */
    173             mem = egr_mpls_combo_map_info[unit][ix]; /* Read out mem ID from book keeping info */
    174             bcm_td3_egr_mpls_combo_create_zone_entry(unit, mem, ix, mem_words, mems);
    175         }
    176 
    177         rv = soc_profile_mem_create(unit, mems, mem_words, egr_mpls_combo_map_entry_total[unit],
    178                                         *egr_mpls_combo_map);
    179         if (BCM_FAILURE(rv)) {
    180             sal_free(*egr_mpls_combo_map);
    181             return rv;
    182         }
    183         *egr_mpls_combo_map_created = TRUE;
    184     }
    185 
    186     return rv;
    187 }
    188 
    189 int bcm_td3_egr_mpls_combo_map_default(uint32 unit)
    190 {
    191     soc_mem_t mem;
    192     int ix;
    193     int rv = BCM_E_NONE;
    194     void *entries[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE];
    195     uint32 index;
    196     uint32 *map_buf[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE] = {NULL}; 
    197     uint32 alloc_size;
    198     uint32 entry_size;
    199 
    200     for (ix=0; ix < egr_mpls_combo_map_entry_total[unit]; ix++) {
    201         /* First memory entry of the combo */
    202         mem = egr_mpls_combo_map_info[unit][ix]; /* Read out mem ID from book keeping info */
    203         entry_size = bcm_td3_combo_entry_size(unit, mem);
    204         alloc_size = entry_size * _BCM_QOS_PROFILE_ENTRIES_PER_SET;
    205 
    206         map_buf[ix] = sal_alloc(alloc_size, "TD3 EGR MPLS map");
    207         if (map_buf[ix] == NULL) {
    208             rv = BCM_E_MEMORY;
    209             goto cleanup;
    210         }
    211         sal_memset(map_buf[ix], 0, alloc_size);
    212         bcm_td3_egr_mpls_map_entry_default(unit, mem, map_buf[ix], entry_size);
    213         entries[ix] = (void *)map_buf[ix];
    214     }
    215 
    216     rv = _bcm_egr_mpls_combo_map_entry_add(unit, entries,
    217                                            _BCM_QOS_PROFILE_ENTRIES_PER_SET, &index);
    218 
    219 cleanup:
    220     for (ix=0; ix < egr_mpls_combo_map_entry_total[unit]; ix++) {
    221        if (map_buf[ix] != NULL) {
    222            sal_free(map_buf[ix]);
    223        }
    224     }
    225    
    226     return rv;
    227 }
    228 
    229 
    230 int bcm_td3_egr_mpls_combo_dump(int unit, soc_profile_mem_t *mpls_profile)
    231 {
    232     egr_mpls_pri_mapping_entry_t egr_mpls_pri_map[_BCM_QOS_PROFILE_ENTRIES_PER_SET];
    233     egr_zone_1_dot1p_mapping_table_1_entry_t  egr_mpls_zone_map[4][_BCM_QOS_PROFILE_ENTRIES_PER_SET];
    234     egr_mpls_exp_mapping_1_entry_t  egr_mpls_exp_map[3][_BCM_QOS_PROFILE_ENTRIES_PER_SET];
    235     int ix, jx;
    236     void *entries[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE];
    237     int pri, cfi, exp, new_pri, new_cfi;
    238     soc_mem_t mem;
    239     int num_entries;
    240     int rv = BCM_E_NONE;
    241     int entries_per_set;
    242     int ref_count;
    243 
    244     mem = EGR_MPLS_PRI_MAPPINGm;
    245     num_entries = soc_mem_index_count(unit, mem);
    246 
    247     LOG_CLI((BSL_META_U(unit,
    248                   "  EGR_MPLS_PRI_MAPPING & EGR_MPLS_EXP_MAP & EGR ZONE_1/3 PRI Combo Mem\n")));
    249     LOG_CLI((BSL_META_U(unit,
    250                  "    Number of entries: %d\n"), num_entries));
    251     LOG_CLI((BSL_META_U(unit,
    252                  "    Index RefCount EntriesPerSet - PRI CFI MPLS_EXP\n")));
    253 
    254     for (jx = 0; jx < num_entries;
    255         jx += _BCM_QOS_PROFILE_ENTRIES_PER_SET) {
    256         rv = soc_profile_mem_ref_count_get(unit,
    257                                            mpls_profile,
    258                                            jx, &ref_count);
    259         if (SOC_FAILURE(rv)) {
    260             LOG_CLI((BSL_META_U(unit,
    261                         " *** Error retrieving profile reference: %d ***\n"), rv));
    262             break;
    263         }
    264 
    265         if (ref_count <= 0) {
    266             continue;
    267         }
    268 
    269         /* Add new chunk and store new HW index */
    270         entries[0] = &egr_mpls_pri_map;
    271         /* 4 DOT1P zone entry */
    272         for (ix=0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) {
    273             entries[ix+EGR_INNER_ZONE_TABLE_OFFSET] = &egr_mpls_zone_map[ix];
    274         }
    275 
    276         /* 3 MPLS EXP entry */
    277         for (ix=0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) {
    278             entries[ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET] = &egr_mpls_exp_map[ix];
    279         }
    280 
    281         rv = soc_profile_mem_get(unit, mpls_profile,
    282                                  jx, _BCM_QOS_PROFILE_ENTRIES_PER_SET, entries);
    283         if (SOC_FAILURE(rv)) {
    284              LOG_CLI((BSL_META_U(unit,
    285                                 " *** Error retrieving profile data: %d ***\n"), rv));
    286              break;
    287         }
    288 
    289         for (ix = 0; ix < _BCM_QOS_PROFILE_ENTRIES_PER_SET; ix++) {
    290             entries_per_set = mpls_profile->tables[0].entries[jx+ix].entries_per_set;
    291 
    292             new_pri = soc_mem_field32_get(unit, EGR_MPLS_PRI_MAPPINGm,
    293                                          &(egr_mpls_pri_map[ix]),
    294                                          NEW_PRIf);
    295             new_cfi = soc_mem_field32_get(unit, EGR_MPLS_PRI_MAPPINGm,
    296                                           &(egr_mpls_pri_map[ix]),
    297                                           NEW_CFIf);
    298             cfi = -1;
    299             pri = -1;
    300             exp = -1;
    301 
    302             cfi = soc_mem_field32_get(unit, EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m,
    303                                       &(egr_mpls_zone_map[0][ix]),
    304                                       CFIf);
    305             pri = soc_mem_field32_get(unit, EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m,
    306                                       &(egr_mpls_zone_map[0][ix]),
    307                                       PRIf);
    308 
    309             exp = soc_mem_field32_get(unit, EGR_MPLS_EXP_MAPPING_1m,
    310                                       &(egr_mpls_exp_map[0][ix]),
    311                                       MPLS_EXPf);
    312             LOG_CLI((BSL_META_U(unit,
    313                                 "  %5d %8d %13d     %2d  %2d  %2d %2d %2d"),
    314                                 ix + jx, ref_count, entries_per_set,
    315                                 pri, cfi, new_pri, new_cfi, exp));
    316             LOG_CLI((BSL_META_U(unit,
    317                                 "\n")));
    318         }
    319     }
    320 
    321     return rv;
    322 }
    323 
    324 
    325 int bcm_td3_l2_egr_combo_add(int unit,
    326                              uint32 flags,
    327                              bcm_qos_map_t *map, 
    328                              int map_id,
    329                              uint32 *hw_idx,
    330                              uint32 entry_per_index)
    331 {
    332     egr_mpls_pri_mapping_entry_t *egr_mpls_pri_map = NULL;
    333     egr_zone_1_dot1p_mapping_table_1_entry_t  *egr_mpls_zone_map[EGR_MPLS_ZONE_ENTRY_TOTAL]={NULL};
    334     egr_mpls_exp_mapping_1_entry_t  *egr_mpls_exp_map[EGR_MPLS_EXP_ENTRY_TOTAL] = {NULL};
    335     int ix;
    336     void *entries[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE], *entry;
    337     int alloc_size, offset, cng, index;
    338     int rv = BCM_E_NONE;
    339 
    340 
    341     if (!((flags & BCM_QOS_MAP_L2) ||
    342          (flags & BCM_QOS_MAP_L2_INNER_TAG)||
    343          (flags & BCM_QOS_MAP_MPLS))||
    344          !(flags & BCM_QOS_MAP_EGRESS)) {
    345          return BCM_E_PARAM;
    346     }
    347 
    348     if ((map->int_pri > 15) || (map->int_pri < 0) || 
    349         (map->pkt_pri > 7) || (map->pkt_cfi > 1) || 
    350         ((map->color != bcmColorGreen) && 
    351         (map->color != bcmColorYellow) && 
    352         (map->color != bcmColorRed))) {
    353         return BCM_E_PARAM;
    354     }
    355 
    356     if (flags & BCM_QOS_MAP_MPLS) {
    357         if ((map->exp > 7) || (map->exp < 0)) {
    358              return BCM_E_PARAM;
    359         }
    360     }
    361 
    362     /* Base index of table in hardware */
    363     index = (*hw_idx * entry_per_index);
    364     
    365     /* We total have 64 entries, based on the given CNG and PRI, 
    366      * Map to only one of them */
    367     /* Offset within table */
    368     cng = _BCM_COLOR_ENCODING(unit, map->color);
    369     offset = (map->int_pri << 2) | cng;
    370 
    371     /* Allocate memory for DMA */
    372     /* For table EGR_MPLS_PRI_MAP */
    373     alloc_size = (entry_per_index * sizeof(egr_mpls_pri_mapping_entry_t));
    374     egr_mpls_pri_map = soc_cm_salloc(unit, alloc_size,
    375                                              "TD3 egr mpls pri map");
    376     if (NULL == egr_mpls_pri_map) {
    377          return (BCM_E_MEMORY);
    378     }
    379 
    380     sal_memset(egr_mpls_pri_map, 0, alloc_size);
    381  
    382     /* Read the old profile chunk */
    383     rv = soc_mem_read_range(unit, EGR_MPLS_PRI_MAPPINGm, MEM_BLOCK_ANY,
    384                             index,
    385                             (index + (entry_per_index -1)),
    386                             egr_mpls_pri_map);
    387     if (BCM_FAILURE(rv)) {
    388         goto cleanup;
    389     }
    390 
    391     /* Modify what's needed for EGR_MPLS_PRI_MAPPINGm */
    392     entry = &egr_mpls_pri_map[offset];
    393     soc_mem_field32_set(unit, EGR_MPLS_PRI_MAPPINGm, entry,
    394                         NEW_PRIf, map->pkt_pri);
    395     soc_mem_field32_set(unit, EGR_MPLS_PRI_MAPPINGm, entry,
    396                         NEW_CFIf, map->pkt_cfi);
    397 
    398 
    399     /* For table
    400      *  EGR_ZONE_3_DOT1P_MAPPING_TABLE_3/4
    401      *  EGR_ZONE_1_DOT1P_MAPPING_TABLE_3/4
    402      */
    403     for (ix=0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) {
    404         /* Allocate memory */
    405         alloc_size = (entry_per_index * 
    406                       sizeof(egr_zone_1_dot1p_mapping_table_1_entry_t));
    407         egr_mpls_zone_map[ix] = soc_cm_salloc(unit, alloc_size,
    408                                              "TD3 egr mpls zone map");
    409         if (NULL == egr_mpls_zone_map[ix]) {
    410             goto cleanup;
    411         }
    412         sal_memset(egr_mpls_zone_map[ix], 0, alloc_size);
    413 
    414         /* Read out old entry */
    415         if (SOC_MEM_IS_VALID(unit, egr_mpls_combo_map_info[unit][ix+EGR_INNER_ZONE_TABLE_OFFSET])) {
    416             rv = soc_mem_read_range(unit, egr_mpls_combo_map_info[unit][ix+EGR_INNER_ZONE_TABLE_OFFSET],
    417                                     MEM_BLOCK_ANY,
    418                                     index,
    419                                      (index + (entry_per_index -1)),
    420                                     egr_mpls_zone_map[ix]);
    421             if (BCM_FAILURE(rv)) {
    422                 goto cleanup;
    423             }
    424         }
    425 
    426         /* We combo inner and outer tag in one profile - so set them the same */
    427         entry = &egr_mpls_zone_map[ix][offset];
    428         soc_mem_field32_set(unit, egr_mpls_combo_map_info[unit][ix+1], entry,
    429                             PRIf, map->pkt_pri);
    430         soc_mem_field32_set(unit, egr_mpls_combo_map_info[unit][ix+1], entry,
    431                             CFIf, map->pkt_cfi);
    432     }
    433 
    434     for (ix=0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) {
    435         /* Allocate memory */
    436         alloc_size = (entry_per_index *
    437                       sizeof(egr_mpls_exp_mapping_1_entry_t));
    438         egr_mpls_exp_map[ix] = soc_cm_salloc(unit, alloc_size,
    439                                              "TD3 egr mpls exp map");
    440         if (NULL == egr_mpls_exp_map[ix]) {
    441             goto cleanup;
    442         }
    443         sal_memset(egr_mpls_exp_map[ix], 0, alloc_size);
    444 
    445         /* Read out old entry */
    446         if (SOC_MEM_IS_VALID(unit, egr_mpls_combo_map_info[unit][ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET])) {
    447             rv = soc_mem_read_range(unit, egr_mpls_combo_map_info[unit][ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET],
    448                                     MEM_BLOCK_ANY,
    449                                     index,
    450                                     (index + (entry_per_index -1)),
    451                                     egr_mpls_exp_map[ix]);
    452             if (BCM_FAILURE(rv)) {
    453                 goto cleanup;
    454             }
    455         }
    456       
    457         /* Modify entry */
    458         entry = &egr_mpls_exp_map[ix][offset];
    459         if (flags & BCM_QOS_MAP_MPLS) {
    460             soc_mem_field32_set(unit, egr_mpls_combo_map_info[unit][ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET],
    461                                entry, MPLS_EXPf, map->exp);
    462         }
    463     }
    464 
    465     /* Delete the old profile chunk */
    466     rv = _bcm_egr_mpls_combo_map_entry_delete(unit, index);
    467     if (BCM_FAILURE(rv)) {
    468         goto cleanup;
    469     }
    470 
    471     /* Add new chunk and store new HW index */
    472     entries[0] = egr_mpls_pri_map;
    473     for (ix=0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) {
    474         entries[ix+EGR_INNER_ZONE_TABLE_OFFSET] = egr_mpls_zone_map[ix];
    475     }
    476     for (ix=0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) {
    477         entries[ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET] = egr_mpls_exp_map[ix];
    478     }
    479     rv = _bcm_egr_mpls_combo_map_entry_add(unit, entries,
    480                                            entry_per_index,
    481                                            (uint32 *)&index);
    482     if (BCM_FAILURE(rv)) {
    483         goto cleanup;
    484     }
    485 
    486     *hw_idx = (index / entry_per_index);
    487 
    488     cleanup:
    489         /* Free the DMA memory */
    490         if (egr_mpls_pri_map != NULL) {
    491             soc_cm_sfree(unit, egr_mpls_pri_map);
    492         }
    493 
    494         for (ix = 0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) {
    495            if (egr_mpls_zone_map[ix] != NULL) {
    496                soc_cm_sfree(unit, egr_mpls_zone_map[ix]);
    497            }
    498         }
    499         for (ix = 0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) {
    500            if (egr_mpls_exp_map[ix] != NULL) {
    501                soc_cm_sfree(unit, egr_mpls_exp_map[ix]);
    502            }
    503         }
    504 
    505     return rv;
    506 }
    507 
    508 int bcm_td3_qos_map_create(uint32 unit, uint32 *index, int entry_per_index)
    509 {
    510     egr_mpls_pri_mapping_entry_t *egr_mpls_pri_map = NULL;
    511     egr_zone_1_dot1p_mapping_table_1_entry_t  *egr_mpls_zone_map[EGR_MPLS_ZONE_ENTRY_TOTAL] = {NULL};
    512     egr_mpls_exp_mapping_1_entry_t  *egr_mpls_exp_map[EGR_MPLS_EXP_ENTRY_TOTAL]={NULL};
    513     int ix;
    514     void *entries[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE];
    515     int rv = BCM_E_NONE;
    516     int alloc_size;
    517    
    518     /* Entries for EGR_MPLS_PRI_MAP */
    519     alloc_size = (entry_per_index * sizeof(egr_mpls_pri_mapping_entry_t));
    520     egr_mpls_pri_map = soc_cm_salloc(unit, alloc_size,
    521                                              "TD3 egr mpls pri map");
    522     if (NULL == egr_mpls_pri_map) {
    523          return (BCM_E_MEMORY);
    524     }
    525  
    526     sal_memset(egr_mpls_pri_map, 0, alloc_size);
    527    
    528     /* Entries for Zone 1 and Zone 3 table */
    529     for (ix=0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) {
    530         /* Allocate memory */
    531         alloc_size = (entry_per_index *
    532                       sizeof(egr_zone_1_dot1p_mapping_table_1_entry_t));
    533         egr_mpls_zone_map[ix] = soc_cm_salloc(unit, alloc_size,
    534                                              "TD3 egr mpls zone map");
    535         if (NULL == egr_mpls_zone_map[ix]) {
    536             goto cleanup;
    537         }
    538         sal_memset(egr_mpls_zone_map[ix], 0, alloc_size);
    539     }
    540 
    541     /* Entries for EGR_MPLS_EXP_MAPPING_1&2*/
    542     for (ix=0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) {
    543         /* Allocate memory */
    544         alloc_size = (entry_per_index *
    545                       sizeof(egr_mpls_exp_mapping_1_entry_t));
    546         egr_mpls_exp_map[ix] = soc_cm_salloc(unit, alloc_size,
    547                                              "TD3 egr mpls exp map");
    548         if (NULL == egr_mpls_exp_map[ix]) {
    549             goto cleanup;
    550         }
    551         sal_memset(egr_mpls_exp_map[ix], 0, alloc_size);
    552     }
    553 
    554     /* Add new chunk and store new HW index */
    555     entries[0] = egr_mpls_pri_map;
    556     for (ix=0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) {
    557         entries[ix+EGR_INNER_ZONE_TABLE_OFFSET] = egr_mpls_zone_map[ix];
    558     }
    559     for (ix=0; ix <EGR_MPLS_EXP_ENTRY_TOTAL; ix++) {
    560         entries[ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET] = egr_mpls_exp_map[ix];
    561     }
    562     rv = _bcm_egr_mpls_combo_map_entry_add(unit, entries,
    563                                             entry_per_index, index);
    564     if (BCM_FAILURE(rv)) {
    565         goto cleanup;
    566     }
    567     return rv;
    568   
    569 cleanup:
    570     /* Free the DMA memory */
    571     if (egr_mpls_pri_map != NULL) {
    572         soc_cm_sfree(unit, egr_mpls_pri_map);
    573     } 
    574 
    575     for (ix = 0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) {
    576        if (egr_mpls_zone_map[ix] != NULL) {
    577            soc_cm_sfree(unit, egr_mpls_zone_map[ix]);
    578        }
    579     }
    580     for (ix = 0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) {
    581        if (egr_mpls_exp_map[ix] != NULL) {
    582            soc_cm_sfree(unit, egr_mpls_exp_map[ix]);
    583        }
    584     }
    585 
    586    return rv;
    587 }
    588 
    589 /*
    590  * Function:
    591  *     bcm_td3_qos_reinit
    592  * Purpose:
    593  *     Initialize the TD2 QOS module for logics not covered by td2 and tr2.
    594  * Parameters:
    595  *     unit - (IN) Unit being initialized
    596  * Returns:
    597  *     BCM_E_XXX
    598  */
    599 int bcm_td3_qos_reinit(int unit)
    600 {
    601     bcm_pbmp_t all_pbmp;
    602     bcm_port_t port;
    603     int index;
    604     int rv = BCM_E_NONE;
    605 
    606     /* Update reference counts for DSCP_TABLE profile, TD2 did it in cosq_reinit */
    607     BCM_PBMP_CLEAR(all_pbmp);
    608     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
    609 
    610     PBMP_ITER(all_pbmp, port) {
    611         if (IS_LB_PORT(unit, port)) {
    612             /* Loopback port base starts from 64 */
    613             continue;
    614         }
    615 
    616         rv = _bcm_esw_port_tab_get(unit, port, TRUST_DSCP_PTRf, &index);
    617         if (BCM_FAILURE(rv)) {
    618             return rv;
    619         }
    620 
    621         SOC_IF_ERROR_RETURN(_bcm_dscp_table_entry_reference(unit, index * 64,
    622                                                             64));
    623     }
    624 
    625     return rv;
    626 }
    627 #endif /* End of BCM_TRIDENT3_SUPPORT */
    628