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

trunk.c (121619B)


      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:    trunk.c
      8  * Purpose: Tomahawk2 HGT LAG dynamic load balancing
      9  */
     10 
     11 #include <soc/defs.h>
     12 #include <sal/core/libc.h>
     13 #include <shared/bsl.h>
     14 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
     15 
     16 #include <soc/drv.h>
     17 #include <soc/mem.h>
     18 #include <soc/profile_mem.h>
     19 
     20 #include <bcm/error.h>
     21 
     22 #include <bcm_int/esw/mbcm.h>
     23 #include <bcm_int/esw/trunk.h>
     24 #include <bcm_int/esw_dispatch.h>
     25 
     26 /* ------------------------------------------------- */
     27 /* Bookkeeping info for HGT_LAG dynamic load balancing */
     28 /* ------------------------------------------------- */
     29 
     30 typedef struct _th2_hgt_lag_dlb_bookkeeping_s {
     31     SHR_BITDCL *hgt_lag_dlb_id_used_bitmap;
     32     SHR_BITDCL *hgt_lag_dlb_flowset_block_bitmap; /* Each block corresponds to
     33                                                  512 entries */
     34     int hgt_lag_dlb_sample_rate;
     35     int hgt_lag_dlb_tx_load_min_th;
     36     int hgt_lag_dlb_tx_load_max_th;
     37     int hgt_lag_dlb_qsize_min_th;
     38     int hgt_lag_dlb_qsize_max_th;
     39     int hgt_lag_dlb_physical_qsize_min_th;
     40     int hgt_lag_dlb_physical_qsize_max_th;
     41     uint8 *hgt_lag_dlb_load_weight;
     42     uint8 *hgt_lag_dlb_qsize_weight;
     43     soc_profile_mem_t *hgt_lag_dlb_quality_map_profile;
     44 #ifdef BCM_WARM_BOOT_SUPPORT
     45     uint8 recovered_from_scache; /* Indicates if the following members of this
     46                                     structure have been recovered from scached:
     47                                     hgt_lag_dlb_sample_rate,
     48                                     hgt_lag_dlb_tx_load_min_th,
     49                                     hgt_lag_dlb_tx_load_max_th,
     50                                     hgt_lag_dlb_qsize_min_th,
     51                                     hgt_lag_dlb_qsize_max_th,
     52                                     hgt_lag_dlb_physical_qsize_min_th,
     53                                     hgt_lag_dlb_physical_qsize_max_th,
     54                                     hgt_lag_dlb_load_weight,
     55                                     hgt_lag_dlb_qsize_weight*/
     56 #endif /* BCM_WARM_BOOT_SUPPORT */
     57 } _th2_hgt_lag_dlb_bookkeeping_t;
     58 
     59 static _th2_hgt_lag_dlb_bookkeeping_t *_th2_hgt_lag_dlb_bk[BCM_MAX_NUM_UNITS];
     60 
     61 #define _BCM_HGT_LAG_DLB_CELL_BYTES 208
     62 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT 9
     63 #define _BCM_HGT_LAG_DLB_DEFAULT_SCALING_FACTOR        10
     64 #define _BCM_HGT_LAG_DLB_DEFAULT_PORT_LOAD_WEIGHT      100
     65 #define _BCM_HGT_LAG_DLB_DEFAULT_QUEUE_SIZE_WEIGHT     0
     66 
     67 #define HGT_LAG_DLB_INFO(_unit_) (_th2_hgt_lag_dlb_bk[_unit_])
     68 
     69 #define _BCM_HGT_LAG_DLB_ID_USED_GET(_u_, _idx_) \
     70     SHR_BITGET(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_id_used_bitmap, _idx_)
     71 #define _BCM_HGT_LAG_DLB_ID_USED_SET(_u_, _idx_) \
     72     SHR_BITSET(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_id_used_bitmap, _idx_)
     73 #define _BCM_HGT_LAG_DLB_ID_USED_CLR(_u_, _idx_) \
     74     SHR_BITCLR(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_id_used_bitmap, _idx_)
     75 
     76 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_GET(_u_, _idx_) \
     77     SHR_BITGET(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_)
     78 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_SET(_u_, _idx_) \
     79     SHR_BITSET(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_)
     80 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_CLR(_u_, _idx_) \
     81     SHR_BITCLR(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_)
     82 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_SET_RANGE(_u_, _idx_, _count_) \
     83     SHR_BITSET_RANGE(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_, _count_)
     84 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_CLR_RANGE(_u_, _idx_, _count_) \
     85     SHR_BITCLR_RANGE(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_, _count_)
     86 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_TEST_RANGE(_u_, _idx_, _count_, _result_) \
     87     SHR_BITTEST_RANGE(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_, _count_, _result_)
     88 
     89 /*
     90  * Function:
     91  *      _bcm_th2_hgt_lag_dlb_quality_assign
     92  * Purpose:
     93  *      Assign quality based on loading, total queue size and Physical queue size.
     94  * Parameters:
     95  *      unit - (IN)SOC unit number.
     96  *      tx_load_percent - (IN) Percent weight of loading in determing quality.
     97  *      qsize_percent   - (IN) Percent weight of total queue size in determing
     98  *                             quality.
     99  *                             The remaining percentage is the weight of Physical
    100  *                             queue size.
    101  *      entry_arr - (IN) Array of 512 quality map table entries.
    102  * Returns:
    103  *      BCM_X_XXX
    104  */
    105 STATIC int
    106 _bcm_th2_hgt_lag_dlb_quality_assign(int unit, int tx_load_percent,
    107                                     int qsize_percent, uint32 *entry_arr)
    108 {
    109     int quantized_tx_load;
    110     int quantized_qsize;
    111     int quantized_physical_qsize;
    112     int quality;
    113     int entry_index;
    114     int physical_qsize_percent = 100 - tx_load_percent - qsize_percent;
    115 
    116     if (entry_arr == NULL) {
    117         return BCM_E_PARAM;
    118     }
    119 
    120     for (quantized_tx_load = 0; quantized_tx_load < 8; quantized_tx_load++) {
    121         for (quantized_physical_qsize = 0; quantized_physical_qsize < 8; quantized_physical_qsize++) {
    122             for (quantized_qsize = 0; quantized_qsize < 8; quantized_qsize++) {
    123                 quality = (quantized_tx_load * tx_load_percent +
    124                            quantized_qsize * qsize_percent +
    125                            quantized_physical_qsize * physical_qsize_percent) / 100;
    126                 entry_index = (quantized_tx_load << 6) +
    127                             (quantized_physical_qsize << 3) +
    128                                       quantized_qsize;
    129                 soc_DLB_HGT_LAG_PORT_QUALITY_MAPPINGm_field32_set(unit,
    130                     &entry_arr[entry_index], ASSIGNED_QUALITYf, quality);
    131             }
    132         }
    133     }
    134 
    135     return BCM_E_NONE;
    136 }
    137 
    138 
    139 
    140 /*
    141  * Function:
    142  *      _bcm_th2_hgt_lag_dlb_member_quality_map_set
    143  * Purpose:
    144  *      Set per-member HGT_LAG DLB quality mapping table.
    145  * Parameters:
    146  *      unit - (IN) SOC unit number.
    147  *      port - (IN) Port, not Gport.
    148  *      tx_load_percent - (IN) Percent weight of loading in determing quality.
    149  *      qsize_percent   - (IN) Percent weight of total queue size in determing
    150  *                             quality.
    151  *                             The remaining percentage is the weight of Physical
    152  *                             queue size.
    153  * Returns:
    154  *      BCM_E_xxx
    155  */
    156 STATIC int
    157 _bcm_th2_hgt_lag_dlb_member_quality_map_set(int unit, int port,
    158                                         int tx_load_percent, int qsize_percent)
    159 {
    160     soc_profile_mem_t *profile;
    161     soc_mem_t mem;
    162     int entry_bytes;
    163     int entries_per_profile;
    164     int alloc_size;
    165     uint32 *entry_arr;
    166     int rv = BCM_E_NONE;
    167     void *entries;
    168     uint32 base_index;
    169     uint32 old_base_index;
    170     dlb_hgt_lag_quantize_control_entry_t quantize_control_entry;
    171     int num_quality_map_profiles;
    172 
    173     profile = _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile;
    174     num_quality_map_profiles = 1 << soc_mem_field_length(unit,
    175         DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf);
    176     entries_per_profile =
    177         soc_mem_index_count(unit, DLB_HGT_LAG_PORT_QUALITY_MAPPINGm)/
    178         num_quality_map_profiles;
    179 
    180     entry_bytes = sizeof(dlb_hgt_lag_port_quality_mapping_entry_t);
    181     alloc_size  = entries_per_profile * entry_bytes;
    182     entry_arr   = sal_alloc(alloc_size, "HGT_LAG DLB Quality Map entries");
    183     if (entry_arr == NULL) {
    184         return BCM_E_MEMORY;
    185     }
    186     sal_memset(entry_arr, 0, alloc_size);
    187 
    188     /* Assign quality in the entry array */
    189     rv = _bcm_th2_hgt_lag_dlb_quality_assign(unit, tx_load_percent,
    190                                          qsize_percent, entry_arr);
    191     if (BCM_FAILURE(rv)) {
    192         sal_free(entry_arr);
    193         return rv;
    194     }
    195 
    196     mem = DLB_HGT_LAG_PORT_QUALITY_MAPPINGm;
    197     soc_mem_lock(unit, mem);
    198 
    199     /* Add profile */
    200     entries = entry_arr;
    201     rv = soc_profile_mem_add(unit, profile, &entries, entries_per_profile,
    202                              &base_index);
    203     sal_free(entry_arr);
    204     if (BCM_FAILURE(rv)) {
    205         soc_mem_unlock(unit, mem);
    206         return rv;
    207     }
    208 
    209     /* Update member profile pointer */
    210     rv = READ_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ANY, port,
    211                                             &quantize_control_entry);
    212     if (BCM_FAILURE(rv)) {
    213         soc_mem_unlock(unit, mem);
    214         return rv;
    215     }
    216     old_base_index = entries_per_profile * soc_mem_field32_get(unit,
    217             DLB_HGT_LAG_QUANTIZE_CONTROLm, &quantize_control_entry,
    218             PORT_QUALITY_MAPPING_PROFILE_PTRf);
    219     soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_set(unit, &quantize_control_entry,
    220             PORT_QUALITY_MAPPING_PROFILE_PTRf, base_index / entries_per_profile);
    221     rv = WRITE_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ALL, port,
    222             &quantize_control_entry);
    223     if (BCM_FAILURE(rv)) {
    224         soc_mem_unlock(unit, mem);
    225         return rv;
    226     }
    227 
    228     /* Delete old profile */
    229     rv = soc_profile_mem_delete(unit, profile, old_base_index);
    230     soc_mem_unlock(unit, mem);
    231 
    232     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[base_index/entries_per_profile] =
    233         tx_load_percent;
    234     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[base_index/entries_per_profile] =
    235         qsize_percent;
    236 
    237     return rv;
    238 }
    239 
    240 
    241 /*
    242  * Function:
    243  *      _bcm_th2_hgt_lag_dlb_scaling_factor_encode
    244  * Purpose:
    245  *      Check valid scaling factors, and encode them.
    246  * Parameters:
    247  *      unit      - (IN) SOC unit number.
    248  *      scaling_factor - (IN) Threshold scaling factor.
    249  * Returns:
    250  *      1: check success
    251  *      0: check fail
    252  */
    253 STATIC int
    254 _bcm_th2_hgt_lag_dlb_scaling_factor_encode(int unit, int scaling_factor,
    255                                            int *scaling_factor_hw)
    256 {
    257     int bcm_factors[] = {10, 25, 40, 50, 75, 100};
    258     int hw_factors[]  = { 0,  1,  2,  3,  4,   5};
    259     int i;
    260 
    261     for (i = 0; i < COUNTOF(bcm_factors); i++ ) {
    262         if (scaling_factor == bcm_factors[i]) {
    263             break;
    264         }
    265     }
    266 
    267     if (i < COUNTOF(bcm_factors)) {
    268         if (scaling_factor_hw) {
    269             *scaling_factor_hw = hw_factors[i];
    270         }
    271         return 1;
    272     }
    273     return 0;
    274 }
    275 
    276 
    277 
    278 /*
    279  * Function:
    280  *      _bcm_th2_hgt_lag_dlb_scaling_factor_decode
    281  * Purpose:
    282  *      Decode scaling factors.
    283  * Parameters:
    284  *      unit      - (IN) SOC unit number.
    285  *      scaling_factor - (IN) Threshold scaling factor.
    286  * Returns:
    287  *      BCM_E_xxx
    288  */
    289 STATIC int
    290 _bcm_th2_hgt_lag_dlb_scaling_factor_decode(int unit, int scaling_factor_hw,
    291                                            int *scaling_factor)
    292 {
    293     int bcm_factors[] = {10, 25, 40, 50, 75, 100};
    294     int hw_factors[]  = { 0,  1,  2,  3,  4,   5};
    295     int i;
    296 
    297     for (i = 0; i < COUNTOF(hw_factors); i++ ) {
    298         if (scaling_factor_hw == hw_factors[i]) {
    299             break;
    300         }
    301     }
    302 
    303     if (i == COUNTOF(hw_factors)) {
    304         return BCM_E_INTERNAL;
    305     }
    306 
    307     *scaling_factor = bcm_factors[i];
    308     return BCM_E_NONE;
    309 }
    310 
    311 
    312 /*
    313  * Function:
    314  *      _bcm_th2_hgt_lag_dlb_random_seed_set
    315  * Purpose:
    316  *      Set HGT_LAG DLB random seed.
    317  * Parameters:
    318  *      unit - (IN) SOC unit number.
    319  *      seed - (IN) Random seed.
    320  * Returns:
    321  *      BCM_E_xxx
    322  */
    323 STATIC int
    324 _bcm_th2_hgt_lag_dlb_random_seed_set(int unit, int seed)
    325 {
    326 
    327     uint32 rval;
    328     uint32 hw_limit;
    329 
    330     hw_limit = (1 << soc_reg_field_length(unit, DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr,
    331                                           SEEDf)) - 1;
    332     if (seed < 0 ||
    333         seed > hw_limit) {
    334         /* Hardware limits */
    335         return BCM_E_PARAM;
    336     }
    337 
    338     BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr(unit, &rval));
    339     soc_reg_field_set(unit, DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr, &rval, SEEDf,
    340                       seed);
    341     BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr(unit, rval));
    342 
    343     return BCM_E_NONE;
    344 }
    345 
    346 
    347 
    348 
    349 /*
    350  * Function:
    351  *      _bcm_th2_hgt_lag_dlb_random_seed_get
    352  * Purpose:
    353  *      Set HGT_LAG DLB random seed.
    354  * Parameters:
    355  *      unit - (IN) SOC unit number.
    356  *      seed - (IN) Random seed.
    357  * Returns:
    358  *      BCM_E_xxx
    359  */
    360 STATIC int
    361 _bcm_th2_hgt_lag_dlb_random_seed_get(int unit, int *seed)
    362 {
    363 
    364     uint32 rval;
    365 
    366     BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr(unit, &rval));
    367     *seed = soc_reg_field_get(unit, DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr, rval,
    368                               SEEDf);
    369     return BCM_E_NONE;
    370 }
    371 
    372 
    373 /*
    374  * Function:
    375  *      _bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set
    376  * Purpose:
    377  *      Set HGT_LAG DLB sample period and physical link accounting thresholds.
    378  * Parameters:
    379  *      unit - (IN) SOC unit number.
    380  *      sample_rate - (IN) Number of samplings per second.
    381  *      min_th      - (IN) Minimum port load threshold, in mbps.
    382  *      max_th      - (IN) Maximum port load threshold, in mbps.
    383  * Returns:
    384  *      BCM_E_xxx
    385  */
    386 STATIC int
    387 _bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set(int unit, int sample_rate,
    388         int min_th, int max_th)
    389 {
    390     int num_time_units;
    391     uint32 measure_control_reg;
    392     int max_th_bytes;
    393     int th_increment;
    394     dlb_hgt_lag_glb_quantize_threshold_entry_t quantize_threshold_entry;
    395     int i;
    396     int th_bytes[7];
    397     uint32 hw_limit;
    398 
    399     if (sample_rate <= 0 || min_th < 0 || max_th < 0) {
    400         return BCM_E_PARAM;
    401     }
    402 
    403     if (min_th > max_th) {
    404         max_th = min_th;
    405     }
    406 
    407     /* Compute sampling period in units of 1us:
    408      *     number of 1us time units = 10^6 / sample_rate
    409      */
    410     num_time_units = 1000000 / sample_rate;
    411     hw_limit = (1 << soc_reg_field_length(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    412                                           SAMPLING_PERIODf)) - 1;
    413     if (num_time_units < 1 ||
    414         num_time_units > hw_limit) {
    415         /* Hardware limits */
    416         return BCM_E_PARAM;
    417     }
    418     BCM_IF_ERROR_RETURN
    419         (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
    420     soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    421             &measure_control_reg, SAMPLING_PERIODf, num_time_units);
    422     BCM_IF_ERROR_RETURN
    423         (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg));
    424     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate = sample_rate;
    425 
    426     /* Compute threshold in bytes per sampling period:
    427      * bytes per 1us = (million bits per sec) * 10^6 / 8 * 10^(-6),
    428      * bytes per sampling period = (bytes per 1us) * (number of 1us
    429      *                             time units in sampling period)
    430      *                           = mbps * num_time_units / 8
    431      */
    432     max_th_bytes = max_th * num_time_units / 8;
    433     hw_limit = (1 << soc_mem_field_length(unit, DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm,
    434                                           PORT_LOADING_THRESHOLDf)) - 1;
    435     if (max_th_bytes > hw_limit) {
    436         /* Hardware limits */
    437         return BCM_E_PARAM;
    438     }
    439 
    440     /* Use min threshold as threshold 0, and max threshold as threshold 6.
    441      * Thresholds 1 to 5 will be evenly spread out between min and max
    442      * thresholds.
    443      */
    444     th_increment = (max_th - min_th) / 6;
    445     for (i = 0; i < 7; i++) {
    446         BCM_IF_ERROR_RETURN
    447             (READ_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ANY, i,
    448                                               &quantize_threshold_entry));
    449         th_bytes[i] = (min_th + i * th_increment) * num_time_units / 8;
    450         soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_set
    451             (unit, &quantize_threshold_entry, PORT_LOADING_THRESHOLDf,
    452              th_bytes[i]);
    453         BCM_IF_ERROR_RETURN
    454             (WRITE_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ALL, i,
    455                                                &quantize_threshold_entry));
    456     }
    457 
    458     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th = min_th;
    459     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th = max_th;
    460 
    461     return BCM_E_NONE;
    462 }
    463 
    464 
    465 /*
    466  * Function:
    467  *      _bcm_th2_hgt_lag_dlb_sample_rate_set
    468  * Purpose:
    469  *      Set HGT_LAG dynamic load balancing sample rate.
    470  * Parameters:
    471  *      unit - (IN) SOC unit number.
    472  *      sample_rate - (IN) Number of samplings per second.
    473  * Returns:
    474  *      BCM_E_xxx
    475  */
    476 STATIC int
    477 _bcm_th2_hgt_lag_dlb_sample_rate_set(int unit, int sample_rate)
    478 {
    479     BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set(unit,
    480                 sample_rate,
    481                 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th,
    482                 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th));
    483 
    484     return BCM_E_NONE;
    485 }
    486 
    487 
    488 
    489 /*
    490  * Function:
    491  *      _bcm_th2_hgt_lag_dlb_tx_load_min_th_set
    492  * Purpose:
    493  *      Set HGT_LAG DLB port load minimum threshold.
    494  * Parameters:
    495  *      unit - (IN) SOC unit number.
    496  *      min_th - (IN) Minimum port loading threshold.
    497  * Returns:
    498  *      BCM_E_xxx
    499  */
    500 STATIC int
    501 _bcm_th2_hgt_lag_dlb_tx_load_min_th_set(int unit, int min_th)
    502 {
    503     BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set(unit,
    504                 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate,
    505                 min_th,
    506                 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th));
    507     return BCM_E_NONE;
    508 }
    509 
    510 /*
    511  * Function:
    512  *      _bcm_trident_hgt_lag_dlb_tx_load_max_th_set
    513  * Purpose:
    514  *      Set HGT_LAG DLB port load maximum threshold.
    515  * Parameters:
    516  *      unit - (IN) SOC unit number.
    517  *      max_th - (IN) Maximum port loading threshold.
    518  * Returns:
    519  *      BCM_E_xxx
    520  */
    521 STATIC int
    522 _bcm_th2_hgt_lag_dlb_tx_load_max_th_set(int unit, int max_th)
    523 {
    524     BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set(unit,
    525                 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate,
    526                 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th,
    527                 max_th));
    528     return BCM_E_NONE;
    529 }
    530 
    531 /*
    532  * Function:
    533  *      _bcm_th2_hgt_lag_dlb_qsize_thresholds_set
    534  * Purpose:
    535  *      Set HGT_LAG DLB queue size thresholds.
    536  * Parameters:
    537  *      unit - (IN) SOC unit number.
    538  *      min_th - (IN) Minimum queue size threshold, in bytes.
    539  *      max_th - (IN) Maximum queue size threshold, in bytes.
    540  * Returns:
    541  *      BCM_E_xxx
    542  */
    543 STATIC int
    544 _bcm_th2_hgt_lag_dlb_qsize_thresholds_set(int unit, int min_th, int max_th)
    545 {
    546     int max_th_cells;
    547     int th_increment;
    548     dlb_hgt_lag_glb_quantize_threshold_entry_t quantize_threshold_entry;
    549     int i;
    550     int th_cells[7];
    551     uint32 hw_limit;
    552 
    553     if (min_th < 0 || max_th < 0) {
    554         return BCM_E_PARAM;
    555     }
    556 
    557     if (min_th > max_th) {
    558         max_th = min_th;
    559     }
    560 
    561     /* Convert threshold to number of cells */
    562     max_th_cells = max_th / _BCM_HGT_LAG_DLB_CELL_BYTES;
    563     hw_limit = (1 << soc_mem_field_length(unit, DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm,
    564                                           TOTAL_PORT_QSIZE_THRESHOLDf)) - 1;
    565     if (max_th_cells > hw_limit) {
    566         /* Hardware limits */
    567         return BCM_E_PARAM;
    568     }
    569 
    570     /* Use min threshold as threshold 0, and max threshold as threshold 6.
    571      * Thresholds 1 to 5 will be evenly spread out between min and max
    572      * thresholds.
    573      */
    574     th_increment = (max_th - min_th) / 6;
    575     for (i = 0; i < 7; i++) {
    576         BCM_IF_ERROR_RETURN
    577             (READ_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ANY, i,
    578                                               &quantize_threshold_entry));
    579         th_cells[i] = (min_th + i * th_increment) / _BCM_HGT_LAG_DLB_CELL_BYTES;
    580         soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_set
    581             (unit, &quantize_threshold_entry, TOTAL_PORT_QSIZE_THRESHOLDf,
    582              th_cells[i]);
    583         BCM_IF_ERROR_RETURN
    584             (WRITE_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ALL, i,
    585                                                &quantize_threshold_entry));
    586     }
    587 
    588     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th = min_th;
    589     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th = max_th;
    590 
    591     return BCM_E_NONE;
    592 }
    593 
    594 /*
    595  * Function:
    596  *      _bcm_th2_hgt_lag_dlb_qsize_min_th_set
    597  * Purpose:
    598  *      Set HGT_LAG DLB queue size minimum threshold.
    599  * Parameters:
    600  *      unit - (IN) SOC unit number.
    601  *      min_th - (IN) Minimum queue size threshold, in bytes.
    602  * Returns:
    603  *      BCM_E_xxx
    604  */
    605 STATIC int
    606 _bcm_th2_hgt_lag_dlb_qsize_min_th_set(int unit, int min_th)
    607 {
    608     BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_qsize_thresholds_set(unit,
    609                 min_th, HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th));
    610 
    611     return BCM_E_NONE;
    612 }
    613 
    614 /*
    615  * Function:
    616  *      _bcm_th2_hgt_lag_dlb_qsize_max_th_set
    617  * Purpose:
    618  *      Set HGT_LAG DLB queue size maximum threshold.
    619  * Parameters:
    620  *      unit - (IN) SOC unit number.
    621  *      max_th - (IN) Maximum queue size threshold, in bytes.
    622  * Returns:
    623  *      BCM_E_xxx
    624  */
    625 STATIC int
    626 _bcm_th2_hgt_lag_dlb_qsize_max_th_set(int unit, int max_th)
    627 {
    628     BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_qsize_thresholds_set(unit,
    629                 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th, max_th));
    630 
    631     return BCM_E_NONE;
    632 }
    633 
    634 
    635 /*
    636  * Function:
    637  *      _bcm_th2_hgt_lag_dlb_physical_qsize_thresholds_set
    638  * Purpose:
    639  *      Set HGT_LAG DLB Physical queue size thresholds.
    640  * Parameters:
    641  *      unit - (IN) SOC unit number.
    642  *      min_th - (IN) Minimum Physical queue size threshold, in bytes.
    643  *      max_th - (IN) Maximum Physical queue size threshold, in bytes.
    644  * Returns:
    645  *      BCM_E_xxx
    646  */
    647 STATIC int
    648 _bcm_th2_hgt_lag_dlb_physical_qsize_thresholds_set(int unit, int min_th, int max_th)
    649 {
    650     int max_th_cells;
    651     int th_increment;
    652     dlb_hgt_lag_glb_quantize_threshold_entry_t quantize_threshold_entry;
    653     int i;
    654     int th_cells[7];
    655     uint32 hw_limit;
    656 
    657     if (min_th < 0 || max_th < 0) {
    658         return BCM_E_PARAM;
    659     }
    660 
    661     if (min_th > max_th) {
    662         max_th = min_th;
    663     }
    664 
    665     /* Convert threshold to number of cells */
    666     max_th_cells = max_th / _BCM_HGT_LAG_DLB_CELL_BYTES;
    667     hw_limit = (1 << soc_mem_field_length(unit, DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm,
    668                                           XPE_PORT_QSIZE_THRESHOLDf)) - 1;
    669     if (max_th_cells > hw_limit) {
    670         /* Hardware limits */
    671         return BCM_E_PARAM;
    672     }
    673 
    674     /* Use min threshold as threshold 0, and max threshold as threshold 6.
    675      * Thresholds 1 to 5 will be evenly spread out between min and max
    676      * thresholds.
    677      */
    678     th_increment = (max_th - min_th) / 6;
    679     for (i = 0; i < 7; i++) {
    680         BCM_IF_ERROR_RETURN
    681             (READ_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ANY, i,
    682                                               &quantize_threshold_entry));
    683         th_cells[i] = (min_th + i * th_increment) / _BCM_HGT_LAG_DLB_CELL_BYTES;
    684         soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_set
    685             (unit, &quantize_threshold_entry, XPE_PORT_QSIZE_THRESHOLDf,
    686              th_cells[i]);
    687         BCM_IF_ERROR_RETURN
    688             (WRITE_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ALL, i,
    689                                                &quantize_threshold_entry));
    690     }
    691 
    692     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th = min_th;
    693     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th = max_th;
    694 
    695     return BCM_E_NONE;
    696 }
    697 
    698 /*
    699  * Function:
    700  *      _bcm_th2_hgt_lag_dlb_physical_qsize_min_th_set
    701  * Purpose:
    702  *      Set HGT_LAG DLB Physical queue size minimum threshold.
    703  * Parameters:
    704  *      unit - (IN) SOC unit number.
    705  *      min_th - (IN) Minimum Physical queue size threshold, in bytes.
    706  * Returns:
    707  *      BCM_E_xxx
    708  */
    709 STATIC int
    710 _bcm_th2_hgt_lag_dlb_physical_qsize_min_th_set(int unit, int min_th)
    711 {
    712     BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_physical_qsize_thresholds_set(unit,
    713                 min_th, HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th));
    714 
    715     return BCM_E_NONE;
    716 }
    717 
    718 /*
    719  * Function:
    720  *      _bcm_th2_hgt_lag_dlb_physical_qsize_max_th_set
    721  * Purpose:
    722  *      Set HGT_LAG DLB Physical queue size maximum threshold.
    723  * Parameters:
    724  *      unit - (IN) SOC unit number.
    725  *      max_th - (IN) Maximum Physical queue size threshold, in bytes.
    726  * Returns:
    727  *      BCM_E_xxx
    728  */
    729 STATIC int
    730 _bcm_th2_hgt_lag_dlb_physical_qsize_max_th_set(int unit, int max_th)
    731 {
    732     BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_physical_qsize_thresholds_set(unit,
    733                 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th, max_th));
    734 
    735     return BCM_E_NONE;
    736 }
    737 
    738 
    739 /*
    740  * Function:
    741  *      _bcm_th2_hgt_lag_dlb_tx_load_weight_set
    742  * Purpose:
    743  *      Set HGT_LAG DLB port load weight.
    744  * Parameters:
    745  *      unit - (IN) SOC unit number.
    746  *      weight - (IN) Port load weight.
    747  * Returns:
    748  *      BCM_E_xxx
    749  */
    750 STATIC int
    751 _bcm_th2_hgt_lag_dlb_tx_load_weight_set(int unit, int weight)
    752 {
    753     uint32 measure_control_reg;
    754     uint32 hw_limit;
    755 
    756     hw_limit = (1 << soc_reg_field_length(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    757                                           PORT_LOADING_WEIGHTf)) - 1;
    758     if (weight < 0 ||
    759         weight > hw_limit) {
    760         /* Hardware limits */
    761         return BCM_E_PARAM;
    762     }
    763 
    764     BCM_IF_ERROR_RETURN
    765         (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
    766     soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    767         &measure_control_reg, PORT_LOADING_WEIGHTf, weight);
    768     BCM_IF_ERROR_RETURN
    769         (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg));
    770     return BCM_E_NONE;
    771 }
    772 
    773 /*
    774  * Function:
    775  *      _bcm_th2_hgt_lag_dlb_tx_load_weight_get
    776  * Purpose:
    777  *      Get HGT_LAG DLB port load weight.
    778  * Parameters:
    779  *      unit - (IN) SOC unit number.
    780  *      weight - (OUT) Port load weight.
    781  * Returns:
    782  *      BCM_E_xxx
    783  */
    784 STATIC int
    785 _bcm_th2_hgt_lag_dlb_tx_load_weight_get(int unit, int *weight)
    786 {
    787     uint32 measure_control_reg;
    788 
    789     BCM_IF_ERROR_RETURN
    790         (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
    791     *weight = soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    792         measure_control_reg, PORT_LOADING_WEIGHTf);
    793 
    794     return BCM_E_NONE;
    795 }
    796 
    797 /*
    798  * Function:
    799  *      _bcm_th2_hgt_lag_dlb_qsize_weight_set
    800  * Purpose:
    801  *      Set HGT_LAG DLB qsize weight.
    802  * Parameters:
    803  *      unit - (IN) SOC unit number.
    804  *      weight - (IN) Qsize weight.
    805  * Returns:
    806  *      BCM_E_xxx
    807  */
    808 STATIC int
    809 _bcm_th2_hgt_lag_dlb_qsize_weight_set(int unit, int weight)
    810 {
    811     uint32 measure_control_reg;
    812     uint32 hw_limit;
    813 
    814     hw_limit = (1 << soc_reg_field_length(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    815                                           TOTAL_QSIZE_WEIGHTf)) - 1;
    816     if (weight < 0 ||
    817         weight > hw_limit) {
    818         /* Hardware limits */
    819         return BCM_E_PARAM;
    820     }
    821 
    822     if (!soc_feature(unit, soc_feature_td3_dlb)) {
    823         BCM_IF_ERROR_RETURN
    824             (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
    825         soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    826                 &measure_control_reg, TOTAL_QSIZE_WEIGHTf, weight);
    827         BCM_IF_ERROR_RETURN
    828             (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg));
    829     }
    830     return BCM_E_NONE;
    831 }
    832 
    833 /*
    834  * Function:
    835  *      _bcm_th2_hgt_lag_dlb_qsize_weight_get
    836  * Purpose:
    837  *      Get HGT_LAG DLB qsize weight.
    838  * Parameters:
    839  *      unit - (IN) SOC unit number.
    840  *      weight - (OUT) Qsize weight.
    841  * Returns:
    842  *      BCM_E_xxx
    843  */
    844 STATIC int
    845 _bcm_th2_hgt_lag_dlb_qsize_weight_get(int unit, int *weight)
    846 {
    847     uint32 measure_control_reg;
    848 
    849     BCM_IF_ERROR_RETURN
    850         (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
    851     *weight = soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    852         measure_control_reg, TOTAL_QSIZE_WEIGHTf);
    853 
    854     return BCM_E_NONE;
    855 }
    856 
    857 
    858 /*
    859  * Function:
    860  *      _bcm_th2_hgt_lag_dlb_physical_qsize_weight_set
    861  * Purpose:
    862  *      Set HGT_LAG DLB Physical qsize weight.
    863  * Parameters:
    864  *      unit - (IN) SOC unit number.
    865  *      weight - (IN) Physical Queue size weight.
    866  * Returns:
    867  *      BCM_E_xxx
    868  */
    869 STATIC int
    870 _bcm_th2_hgt_lag_dlb_physical_qsize_weight_set(int unit, int weight)
    871 {
    872     uint32 measure_control_reg;
    873     uint32 hw_limit;
    874 
    875     hw_limit = (1 << soc_reg_field_length(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    876                                           XPE_PORT_QSIZE_WEIGHTf)) - 1;
    877 
    878     if (weight < 0 ||
    879         weight > hw_limit) {
    880         /* Hardware limits */
    881         return BCM_E_PARAM;
    882     }
    883 
    884     BCM_IF_ERROR_RETURN
    885         (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
    886     soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    887         &measure_control_reg, XPE_PORT_QSIZE_WEIGHTf, weight);
    888     BCM_IF_ERROR_RETURN
    889         (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg));
    890     return BCM_E_NONE;
    891 }
    892 
    893 /*
    894  * Function:
    895  *      _bcm_th2_hgt_lag_dlb_physical_qsize_weight_get
    896  * Purpose:
    897  *      Get HGT_LAG DLB Physical qsize weight.
    898  * Parameters:
    899  *      unit - (IN) SOC unit number.
    900  *      weight - (OUT) Physical Queue size weight.
    901  * Returns:
    902  *      BCM_E_xxx
    903  */
    904 STATIC int
    905 _bcm_th2_hgt_lag_dlb_physical_qsize_weight_get(int unit, int *weight)
    906 {
    907     uint32 measure_control_reg;
    908 
    909     BCM_IF_ERROR_RETURN
    910         (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
    911     *weight = soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    912         measure_control_reg, XPE_PORT_QSIZE_WEIGHTf);
    913 
    914     return BCM_E_NONE;
    915 }
    916 
    917 
    918 /*
    919  * Function:
    920  *      _bcm_th2_hgt_lag_dlb_tx_load_cap_set
    921  * Purpose:
    922  *      Set HGT_LAG DLB port load cap control.
    923  * Parameters:
    924  *      unit - (IN) SOC unit number.
    925  *      cap - (IN) Port load cap control.
    926  * Returns:
    927  *      BCM_E_xxx
    928  */
    929 STATIC int
    930 _bcm_th2_hgt_lag_dlb_tx_load_cap_set(int unit, int cap)
    931 {
    932     uint32 measure_control_reg;
    933 
    934     if (cap < 0 ||
    935         cap > 1) {
    936         /* Hardware limits port load cap control to 1 bit */
    937         return BCM_E_PARAM;
    938     }
    939 
    940     BCM_IF_ERROR_RETURN
    941         (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
    942     soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    943         &measure_control_reg, CAP_PORT_LOADING_AVERAGEf, cap);
    944     BCM_IF_ERROR_RETURN
    945         (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg));
    946     return BCM_E_NONE;
    947 }
    948 
    949 /*
    950  * Function:
    951  *      _bcm_th2_hgt_lag_dlb_tx_load_cap_get
    952  * Purpose:
    953  *      Get HGT_LAG DLB port load cap control.
    954  * Parameters:
    955  *      unit - (IN) SOC unit number.
    956  *      cap - (OUT) Cap control.
    957  * Returns:
    958  *      BCM_E_xxx
    959  */
    960 STATIC int
    961 _bcm_th2_hgt_lag_dlb_tx_load_cap_get(int unit, int *cap)
    962 {
    963     uint32 measure_control_reg;
    964 
    965     BCM_IF_ERROR_RETURN
    966         (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
    967     *cap= soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    968         measure_control_reg, CAP_PORT_LOADING_AVERAGEf);
    969 
    970     return BCM_E_NONE;
    971 }
    972 /*
    973  * Function:
    974  *      _bcm_th2_hgt_lag_dlb_qsize_cap_set
    975  * Purpose:
    976  *      Set HGT_LAG DLB queue size cap control.
    977  * Parameters:
    978  *      unit - (IN) SOC unit number.
    979  *      cap - (IN) Queue size cap control.
    980  * Returns:
    981  *      BCM_E_xxx
    982  */
    983 STATIC int
    984 _bcm_th2_hgt_lag_dlb_qsize_cap_set(int unit, int cap)
    985 {
    986     uint32 measure_control_reg;
    987 
    988     if (cap < 0 ||
    989         cap > 1) {
    990         /* Hardware limits port load cap control to 1 bit */
    991         return BCM_E_PARAM;
    992     }
    993 
    994     if (!soc_feature(unit, soc_feature_td3_dlb)) {
    995         BCM_IF_ERROR_RETURN
    996             (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
    997         soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
    998                 &measure_control_reg, CAP_TOTAL_PORT_QSIZE_AVERAGEf, cap);
    999         BCM_IF_ERROR_RETURN
   1000             (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg));
   1001     }
   1002     return BCM_E_NONE;
   1003 }
   1004 
   1005 /*
   1006  * Function:
   1007  *      _bcm_th2_hgt_lag_dlb_qsize_cap_get
   1008  * Purpose:
   1009  *      Get HGT_LAG DLB queue size cap control.
   1010  * Parameters:
   1011  *      unit - (IN) SOC unit number.
   1012  *      cap - (OUT) Cap control.
   1013  * Returns:
   1014  *      BCM_E_xxx
   1015  */
   1016 STATIC int
   1017 _bcm_th2_hgt_lag_dlb_qsize_cap_get(int unit, int *cap)
   1018 {
   1019     uint32 measure_control_reg;
   1020 
   1021     BCM_IF_ERROR_RETURN
   1022         (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
   1023     *cap= soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
   1024         measure_control_reg, CAP_TOTAL_PORT_QSIZE_AVERAGEf);
   1025 
   1026     return BCM_E_NONE;
   1027 }
   1028 
   1029 /*
   1030  * Function:
   1031  *      _bcm_th2_hgt_lag_dlb_physical_qsize_cap_set
   1032  * Purpose:
   1033  *      Set HGT_LAG DLB Physical queue size cap control.
   1034  * Parameters:
   1035  *      unit - (IN) SOC unit number.
   1036  *      cap - (IN) Physical Queue size cap control.
   1037  * Returns:
   1038  *      BCM_E_xxx
   1039  */
   1040 STATIC int
   1041 _bcm_th2_hgt_lag_dlb_physical_qsize_cap_set(int unit, int cap)
   1042 {
   1043     uint32 measure_control_reg;
   1044 
   1045     if (cap < 0 ||
   1046         cap > 1) {
   1047         /* Hardware limits port load cap control to 1 bit */
   1048         return BCM_E_PARAM;
   1049     }
   1050 
   1051     BCM_IF_ERROR_RETURN
   1052         (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
   1053     soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
   1054         &measure_control_reg, CAP_XPE_PORT_QSIZE_AVERAGEf, cap);
   1055     BCM_IF_ERROR_RETURN
   1056         (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg));
   1057     return BCM_E_NONE;
   1058 }
   1059 
   1060 /*
   1061  * Function:
   1062  *      _bcm_th2_hgt_lag_dlb_physical_qsize_cap_get
   1063  * Purpose:
   1064  *      Get HGT_LAG DLB Physical queue size cap control.
   1065  * Parameters:
   1066  *      unit - (IN) SOC unit number.
   1067  *      cap - (OUT) Physical Queue size cap control.
   1068  * Returns:
   1069  *      BCM_E_xxx
   1070  */
   1071 STATIC int
   1072 _bcm_th2_hgt_lag_dlb_physical_qsize_cap_get(int unit, int *cap)
   1073 {
   1074     uint32 measure_control_reg;
   1075 
   1076     BCM_IF_ERROR_RETURN
   1077         (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg));
   1078     *cap= soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
   1079         measure_control_reg, CAP_XPE_PORT_QSIZE_AVERAGEf);
   1080 
   1081     return BCM_E_NONE;
   1082 }
   1083 
   1084 
   1085 
   1086 /*
   1087  * Function:
   1088  *      bcm_th2_hgt_lag_dlb_config_set
   1089  * Purpose:
   1090  *      Set per-chip HGT_LAG dynamic load balancing configuration parameters.
   1091  * Parameters:
   1092  *      unit - (IN) SOC unit number.
   1093  *      type - (IN) Configuration parameter type.
   1094  *      arg  - (IN) Configuration paramter value.
   1095  * Returns:
   1096  *      BCM_E_xxx
   1097  */
   1098 int
   1099 bcm_th2_hgt_lag_dlb_config_set(int unit, bcm_switch_control_t type, int arg)
   1100 {
   1101     switch (type) {
   1102         case bcmSwitchTrunkDynamicSampleRate:
   1103         case bcmSwitchFabricTrunkDynamicSampleRate:
   1104             return _bcm_th2_hgt_lag_dlb_sample_rate_set(unit, arg);
   1105 
   1106         case bcmSwitchTrunkDynamicEgressBytesExponent:
   1107         case bcmSwitchFabricTrunkDynamicEgressBytesExponent:
   1108             return _bcm_th2_hgt_lag_dlb_tx_load_weight_set(unit, arg);
   1109 
   1110         case bcmSwitchTrunkDynamicQueuedBytesExponent:
   1111         case bcmSwitchFabricTrunkDynamicQueuedBytesExponent:
   1112             if (soc_feature(unit, soc_feature_td3_dlb)) {
   1113                 return BCM_E_UNAVAIL;
   1114             } else {
   1115                 return _bcm_th2_hgt_lag_dlb_qsize_weight_set(unit, arg);
   1116             }
   1117         case bcmSwitchTrunkDynamicPhysicalQueuedBytesExponent:
   1118         case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesExponent:
   1119             return _bcm_th2_hgt_lag_dlb_physical_qsize_weight_set(unit, arg);
   1120 
   1121         case bcmSwitchTrunkDynamicEgressBytesDecreaseReset:
   1122         case bcmSwitchFabricTrunkDynamicEgressBytesDecreaseReset:
   1123             return _bcm_th2_hgt_lag_dlb_tx_load_cap_set(unit, arg);
   1124 
   1125         case bcmSwitchTrunkDynamicQueuedBytesDecreaseReset:
   1126         case bcmSwitchFabricTrunkDynamicQueuedBytesDecreaseReset:
   1127             if (soc_feature(unit, soc_feature_td3_dlb)) {
   1128                 return BCM_E_UNAVAIL;
   1129             } else {
   1130                 return _bcm_th2_hgt_lag_dlb_qsize_cap_set(unit, arg);
   1131             }
   1132         case bcmSwitchTrunkDynamicPhysicalQueuedBytesDecreaseReset:
   1133         case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesDecreaseReset:
   1134             return _bcm_th2_hgt_lag_dlb_physical_qsize_cap_set(unit, arg);
   1135 
   1136         case bcmSwitchTrunkDynamicEgressBytesMinThreshold:
   1137         case bcmSwitchFabricTrunkDynamicEgressBytesMinThreshold:
   1138             return _bcm_th2_hgt_lag_dlb_tx_load_min_th_set(unit, arg);
   1139 
   1140         case bcmSwitchTrunkDynamicEgressBytesMaxThreshold:
   1141         case bcmSwitchFabricTrunkDynamicEgressBytesMaxThreshold:
   1142             return _bcm_th2_hgt_lag_dlb_tx_load_max_th_set(unit, arg);
   1143 
   1144         case bcmSwitchTrunkDynamicQueuedBytesMinThreshold:
   1145         case bcmSwitchFabricTrunkDynamicQueuedBytesMinThreshold:
   1146             if (soc_feature(unit, soc_feature_td3_dlb)) {
   1147                 return BCM_E_UNAVAIL;
   1148             } else {
   1149                 return _bcm_th2_hgt_lag_dlb_qsize_min_th_set(unit, arg);
   1150             }
   1151         case bcmSwitchTrunkDynamicQueuedBytesMaxThreshold:
   1152         case bcmSwitchFabricTrunkDynamicQueuedBytesMaxThreshold:
   1153             if (soc_feature(unit, soc_feature_td3_dlb)) {
   1154                 return BCM_E_UNAVAIL;
   1155             } else {
   1156                 return _bcm_th2_hgt_lag_dlb_qsize_max_th_set(unit, arg);
   1157             }
   1158         case bcmSwitchTrunkDynamicPhysicalQueuedBytesMinThreshold:
   1159         case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesMinThreshold:
   1160             return _bcm_th2_hgt_lag_dlb_physical_qsize_min_th_set(unit, arg);
   1161 
   1162         case bcmSwitchTrunkDynamicPhysicalQueuedBytesMaxThreshold:
   1163         case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesMaxThreshold:
   1164             return _bcm_th2_hgt_lag_dlb_physical_qsize_max_th_set(unit, arg);
   1165 
   1166         case bcmSwitchTrunkDynamicRandomSeed:
   1167         case bcmSwitchFabricTrunkDynamicRandomSeed:
   1168             return _bcm_th2_hgt_lag_dlb_random_seed_set(unit, arg);
   1169 
   1170         default:
   1171             return BCM_E_PARAM;
   1172     }
   1173     return BCM_E_NONE;
   1174 }
   1175 
   1176 /*
   1177  * Function:
   1178  *      bcm_th2_hgt_lag_dlb_config_get
   1179  * Purpose:
   1180  *      Get per-chip HGT_LAG dynamic load balancing configuration parameters.
   1181  * Parameters:
   1182  *      unit - (IN) SOC unit number.
   1183  *      type - (IN) Configuration parameter type.
   1184  *      arg  - (OUT) Configuration paramter value.
   1185  * Returns:
   1186  *      BCM_E_xxx
   1187  */
   1188 int
   1189 bcm_th2_hgt_lag_dlb_config_get(int unit, bcm_switch_control_t type, int *arg)
   1190 {
   1191     switch (type) {
   1192         case bcmSwitchTrunkDynamicSampleRate:
   1193         case bcmSwitchFabricTrunkDynamicSampleRate:
   1194             *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate;
   1195             break;
   1196 
   1197         case bcmSwitchTrunkDynamicEgressBytesExponent:
   1198         case bcmSwitchFabricTrunkDynamicEgressBytesExponent:
   1199             return _bcm_th2_hgt_lag_dlb_tx_load_weight_get(unit, arg);
   1200 
   1201         case bcmSwitchTrunkDynamicQueuedBytesExponent:
   1202         case bcmSwitchFabricTrunkDynamicQueuedBytesExponent:
   1203             if (soc_feature(unit, soc_feature_td3_dlb)) {
   1204                 return BCM_E_UNAVAIL;
   1205             } else {
   1206                 return _bcm_th2_hgt_lag_dlb_qsize_weight_get(unit, arg);
   1207             }
   1208         case bcmSwitchTrunkDynamicPhysicalQueuedBytesExponent:
   1209         case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesExponent:
   1210             return _bcm_th2_hgt_lag_dlb_physical_qsize_weight_get(unit, arg);
   1211 
   1212         case bcmSwitchTrunkDynamicEgressBytesDecreaseReset:
   1213         case bcmSwitchFabricTrunkDynamicEgressBytesDecreaseReset:
   1214             return _bcm_th2_hgt_lag_dlb_tx_load_cap_get(unit, arg);
   1215 
   1216         case bcmSwitchTrunkDynamicQueuedBytesDecreaseReset:
   1217         case bcmSwitchFabricTrunkDynamicQueuedBytesDecreaseReset:
   1218             if (soc_feature(unit, soc_feature_td3_dlb)) {
   1219                 return BCM_E_UNAVAIL;
   1220             } else {
   1221                 return _bcm_th2_hgt_lag_dlb_qsize_cap_get(unit, arg);
   1222             }
   1223         case bcmSwitchTrunkDynamicPhysicalQueuedBytesDecreaseReset:
   1224         case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesDecreaseReset:
   1225             return _bcm_th2_hgt_lag_dlb_physical_qsize_cap_get(unit, arg);
   1226 
   1227         case bcmSwitchTrunkDynamicEgressBytesMinThreshold:
   1228         case bcmSwitchFabricTrunkDynamicEgressBytesMinThreshold:
   1229             *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th;
   1230             break;
   1231 
   1232         case bcmSwitchTrunkDynamicEgressBytesMaxThreshold:
   1233         case bcmSwitchFabricTrunkDynamicEgressBytesMaxThreshold:
   1234             *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th;
   1235             break;
   1236 
   1237         case bcmSwitchTrunkDynamicQueuedBytesMinThreshold:
   1238         case bcmSwitchFabricTrunkDynamicQueuedBytesMinThreshold:
   1239             *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th;
   1240             break;
   1241 
   1242         case bcmSwitchTrunkDynamicQueuedBytesMaxThreshold:
   1243         case bcmSwitchFabricTrunkDynamicQueuedBytesMaxThreshold:
   1244             *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th;
   1245             break;
   1246 
   1247         case bcmSwitchTrunkDynamicPhysicalQueuedBytesMinThreshold:
   1248         case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesMinThreshold:
   1249             *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th;
   1250             break;
   1251 
   1252         case bcmSwitchTrunkDynamicPhysicalQueuedBytesMaxThreshold:
   1253         case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesMaxThreshold:
   1254             *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th;
   1255             break;
   1256 
   1257         case bcmSwitchTrunkDynamicRandomSeed:
   1258         case bcmSwitchFabricTrunkDynamicRandomSeed:
   1259             return _bcm_th2_hgt_lag_dlb_random_seed_get(unit, arg);
   1260 
   1261         default:
   1262             return BCM_E_PARAM;
   1263     }
   1264 
   1265     return BCM_E_NONE;
   1266 }
   1267 
   1268 /*
   1269  * Function:
   1270  *      _bcm_th2_hgt_lag_dlb_dynamic_size_encode
   1271  * Purpose:
   1272  *      Encode HGT_LAG dynamic load balancing flow set size.
   1273  * Parameters:
   1274  *      dynamic_size - (IN) Number of flow sets.
   1275  *      encoded_value - (OUT) Encoded value.
   1276  * Returns:
   1277  *      BCM_E_xxx
   1278  */
   1279 int
   1280 bcm_th2_hgt_lag_dlb_dynamic_size_encode(int dynamic_size,
   1281         int *encoded_value)
   1282 {
   1283     switch (dynamic_size) {
   1284         case 512:
   1285             *encoded_value = 1;
   1286             break;
   1287         case 1024:
   1288             *encoded_value = 2;
   1289             break;
   1290         case 2048:
   1291             *encoded_value = 3;
   1292             break;
   1293         case 4096:
   1294             *encoded_value = 4;
   1295             break;
   1296         case 8192:
   1297             *encoded_value = 5;
   1298             break;
   1299         case 16384:
   1300             *encoded_value = 6;
   1301             break;
   1302         case 32768:
   1303             *encoded_value = 7;
   1304             break;
   1305         default:
   1306             return BCM_E_PARAM;
   1307     }
   1308 
   1309     return BCM_E_NONE;
   1310 }
   1311 
   1312 /*
   1313  * Function:
   1314  *      _bcm_th2_hgt_lag_dlb_dynamic_size_decode
   1315  * Purpose:
   1316  *      Decode HGT_LAG trunk dynamic load balancing flow set size.
   1317  * Parameters:
   1318  *      encoded_value - (IN) Encoded value.
   1319  *      dynamic_size - (OUT) Number of flow sets.
   1320  * Returns:
   1321  *      BCM_E_xxx
   1322  */
   1323 STATIC int
   1324 _bcm_th2_hgt_lag_dlb_dynamic_size_decode(int encoded_value,
   1325         int *dynamic_size)
   1326 {
   1327     switch (encoded_value) {
   1328         case 1:
   1329             *dynamic_size = 512;
   1330             break;
   1331         case 2:
   1332             *dynamic_size = 1024;
   1333             break;
   1334         case 3:
   1335             *dynamic_size = 2048;
   1336             break;
   1337         case 4:
   1338             *dynamic_size = 4096;
   1339             break;
   1340         case 5:
   1341             *dynamic_size = 8192;
   1342             break;
   1343         case 6:
   1344             *dynamic_size = 16384;
   1345             break;
   1346         case 7:
   1347             *dynamic_size = 32768;
   1348             break;
   1349         default:
   1350             return BCM_E_INTERNAL;
   1351     }
   1352 
   1353     return BCM_E_NONE;
   1354 }
   1355 
   1356 /*
   1357  * Function:
   1358  *      _bcm_th2_hgt_lag_dlb_id_alloc
   1359  * Purpose:
   1360  *      Get a free HGT_LAG DLB ID and mark it used.
   1361  * Parameters:
   1362  *      unit - (IN) SOC unit number.
   1363  *      dlb_id - (OUT) Allocated DLB ID.
   1364  * Returns:
   1365  *      BCM_E_xxx
   1366  */
   1367 STATIC int
   1368 _bcm_th2_hgt_lag_dlb_id_alloc(int unit, int *dlb_id)
   1369 {
   1370     int i;
   1371 
   1372     for (i = 0; i < soc_mem_index_count(unit, DLB_HGT_LAG_GROUP_CONTROLm); i++) {
   1373         if (!_BCM_HGT_LAG_DLB_ID_USED_GET(unit, i)) {
   1374             _BCM_HGT_LAG_DLB_ID_USED_SET(unit, i);
   1375             *dlb_id = i;
   1376             return BCM_E_NONE;
   1377         }
   1378     }
   1379 
   1380     return BCM_E_RESOURCE;
   1381 }
   1382 
   1383 /*
   1384  * Function:
   1385  *      _bcm_th2_hgt_lag_dlb_id_free
   1386  * Purpose:
   1387  *      Free a HGT_LAG DLB ID.
   1388  * Parameters:
   1389  *      unit - (IN) SOC unit number.
   1390  *      dlb_id - (IN) DLB ID to be freed.
   1391  * Returns:
   1392  *      BCM_E_xxx
   1393  */
   1394 STATIC int
   1395 _bcm_th2_hgt_lag_dlb_id_free(int unit, int dlb_id)
   1396 {
   1397     if (dlb_id < 0 ||
   1398         dlb_id > soc_mem_index_max(unit, DLB_HGT_LAG_GROUP_CONTROLm)) {
   1399         return BCM_E_PARAM;
   1400     }
   1401 
   1402     _BCM_HGT_LAG_DLB_ID_USED_CLR(unit, dlb_id);
   1403 
   1404     return BCM_E_NONE;
   1405 }
   1406 
   1407 /*
   1408  * Function:
   1409  *      bcm_th2_hgt_lag_dlb_member_attr_set
   1410  * Purpose:
   1411  *      Set each HGT_LAG member's attributes.
   1412  * Parameters:
   1413  *      unit   - (IN) SOC unit number.
   1414  *      num_dlb_ports  - (IN) Number of DLB ports.
   1415  *      port_array     - (IN) Array of port numbers.
   1416  *      scaling_factor_array - (IN) Array of scaling factors.
   1417  *      load_weight_array    - (IN) Array of load weights.
   1418  *      qsize_weight_array    - (IN) Array of Queue size weights.
   1419  * Returns:
   1420  *      BCM_E_xxx
   1421  */
   1422 STATIC int
   1423 bcm_th2_hgt_lag_dlb_member_attr_set(int unit,
   1424                                     bcm_port_t port,
   1425                                     int scaling_factor,
   1426                                     int load_weight,
   1427                                     int qsize_weight)
   1428 {
   1429     int scaling_factor_hw;
   1430     dlb_hgt_lag_quantize_control_entry_t quantize_control_entry;
   1431 
   1432     /* Set member quality mapping profile */
   1433 
   1434     BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_member_quality_map_set(unit,
   1435                 port, load_weight, qsize_weight));
   1436 
   1437     /* Set threshold scaling factors */
   1438 
   1439     if (!_bcm_th2_hgt_lag_dlb_scaling_factor_encode(unit,
   1440              scaling_factor, &scaling_factor_hw)) {
   1441         return BCM_E_PARAM;
   1442     }
   1443     BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ANY,
   1444                 port, &quantize_control_entry));
   1445     soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_set(unit,
   1446             &quantize_control_entry,
   1447             PORT_LOADING_THRESHOLD_SCALING_FACTORf,
   1448             scaling_factor_hw);
   1449     if (!soc_feature(unit, soc_feature_td3_dlb)) {
   1450         soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_set(unit,
   1451                 &quantize_control_entry,
   1452                 TOTAL_PORT_QSIZE_THRESHOLD_SCALING_FACTORf,
   1453                 scaling_factor_hw);
   1454     }
   1455     soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_set(unit,
   1456             &quantize_control_entry,
   1457             XPE_PORT_QSIZE_THRESHOLD_SCALING_FACTORf,
   1458             scaling_factor_hw);
   1459     BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ALL,
   1460                 port, &quantize_control_entry));
   1461 
   1462     return BCM_E_NONE;
   1463 }
   1464 /*
   1465  * Function:
   1466  *      bcm_th2_hgt_lag_dlb_member_attr_get
   1467  * Purpose:
   1468  *      Get attributes of a HGT_LAG DLB member.
   1469  * Parameters:
   1470  *      unit - (IN) SOC unit number.
   1471  *      port - (IN) Port number of the member.
   1472  *      scaling_factor - (OUT) Member's scaling factor.
   1473  *      load_weight    - (OUT) Member's load weight.
   1474  *      qsize_weight   - (OUT) Member's Queue size weight.
   1475  * Returns:
   1476  *      BCM_E_xxx
   1477  */
   1478 int
   1479 bcm_th2_hgt_lag_dlb_member_attr_get(int unit, bcm_port_t port,
   1480         int *scaling_factor, int *load_weight, int *qsize_weight)
   1481 {
   1482     dlb_hgt_lag_quantize_control_entry_t quantize_control_entry;
   1483     int profile_ptr;
   1484     int scaling_factor_hw;
   1485 
   1486     BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ANY,
   1487                 port, &quantize_control_entry));
   1488 
   1489     /* Get load weight, qsize weight */
   1490     profile_ptr = soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_get(unit,
   1491             &quantize_control_entry, PORT_QUALITY_MAPPING_PROFILE_PTRf);
   1492     *load_weight  = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[profile_ptr];
   1493     *qsize_weight = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[profile_ptr];
   1494 
   1495     /* Get scaling factor */
   1496     scaling_factor_hw = soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_get(unit,
   1497             &quantize_control_entry, PORT_LOADING_THRESHOLD_SCALING_FACTORf);
   1498     BCM_IF_ERROR_RETURN
   1499         (_bcm_th2_hgt_lag_dlb_scaling_factor_decode(unit, scaling_factor_hw,
   1500                                                  scaling_factor));
   1501 
   1502     return BCM_E_NONE;
   1503 }
   1504 
   1505 
   1506 /*
   1507  * Function:
   1508  *      bcm_th2_hgt_lag_dlb_free_resource
   1509  * Purpose:
   1510  *      Free resources for a HGT_LAG dynamic load balancing group.
   1511  * Parameters:
   1512  *      unit   - (IN) SOC unit number.
   1513  *      tid  - (IN) Trunk/HiGig Trunk group ID.
   1514  *      hgt  - (IN) Is HiGig Trunk
   1515  * Returns:
   1516  *      BCM_E_xxx
   1517  */
   1518 int
   1519 bcm_th2_hgt_lag_dlb_free_resource(int unit, int tid, int hgt)
   1520 {
   1521     int rv = BCM_E_NONE;
   1522     int dlb_enable;
   1523     int dlb_id;
   1524     dlb_hgt_lag_group_control_entry_t dlb_hgt_lag_group_control_entry;
   1525     int entry_base_ptr;
   1526     int flow_set_size;
   1527     int num_entries;
   1528     int block_base_ptr;
   1529     int membership_pointer;
   1530     int num_blocks;
   1531     dlb_hgt_lag_group_membership_entry_t dlb_hgt_lag_group_membership_entry;
   1532     int port_map_width;
   1533     int alloc_size;
   1534     SHR_BITDCL *port_map = NULL;
   1535     SHR_BITDCL *status_bitmap = NULL;
   1536     SHR_BITDCL *override_bitmap = NULL;
   1537     int port;
   1538     hgt_dlb_control_entry_t hgt_dlb_control;
   1539     lag_dlb_control_entry_t lag_dlb_control;
   1540 #ifdef BCM_TRIDENT3_SUPPORT
   1541     hg_trunk_mode_entry_t   hgt_trunk_mode;
   1542     trunk_group_entry_t     tg_entry;
   1543 #endif
   1544     dlb_hgt_lag_link_control_entry_t link_control_entry;
   1545 
   1546     if (hgt) {
   1547         BCM_IF_ERROR_RETURN(READ_HGT_DLB_CONTROLm(unit, MEM_BLOCK_ANY,
   1548                 tid, &hgt_dlb_control));
   1549         dlb_enable = soc_HGT_DLB_CONTROLm_field32_get(unit, &hgt_dlb_control,
   1550                                                       GROUP_ENABLEf);
   1551         dlb_id = soc_HGT_DLB_CONTROLm_field32_get(unit, &hgt_dlb_control, DLB_IDf);
   1552     } else {
   1553         BCM_IF_ERROR_RETURN(READ_LAG_DLB_CONTROLm(unit, MEM_BLOCK_ANY,
   1554                 tid, &lag_dlb_control));
   1555         dlb_enable = soc_LAG_DLB_CONTROLm_field32_get(unit, &lag_dlb_control,
   1556                                                       GROUP_ENABLEf);
   1557         dlb_id = soc_LAG_DLB_CONTROLm_field32_get(unit, &lag_dlb_control, DLB_IDf);
   1558     }
   1559     if (!dlb_enable) {
   1560         return BCM_E_NONE;
   1561     }
   1562 
   1563     /* Clear DLB fields in HGT/LAG_DLB_CONTROL table */
   1564 
   1565     if (hgt) {
   1566         soc_HGT_DLB_CONTROLm_field32_set(unit, &hgt_dlb_control, GROUP_ENABLEf, 0);
   1567         soc_HGT_DLB_CONTROLm_field32_set(unit, &hgt_dlb_control, DLB_IDf, 0);
   1568         BCM_IF_ERROR_RETURN
   1569         (WRITE_HGT_DLB_CONTROLm(unit, MEM_BLOCK_ALL, tid, &hgt_dlb_control));
   1570 #ifdef BCM_TRIDENT3_SUPPORT
   1571         if (soc_feature(unit, soc_feature_td3_dlb)) {
   1572             BCM_IF_ERROR_RETURN(READ_HG_TRUNK_MODEm(unit, MEM_BLOCK_ANY, tid, &hgt_trunk_mode));
   1573             soc_HG_TRUNK_MODEm_field32_set(unit, &hgt_trunk_mode,
   1574                     HG_TRUNK_LB_MODEf, 0x0);
   1575             BCM_IF_ERROR_RETURN
   1576                 (WRITE_HG_TRUNK_MODEm(unit, MEM_BLOCK_ALL, tid,  &hgt_trunk_mode));
   1577         }
   1578 #endif
   1579     } else {
   1580         soc_LAG_DLB_CONTROLm_field32_set(unit, &lag_dlb_control, GROUP_ENABLEf, 0);
   1581         soc_LAG_DLB_CONTROLm_field32_set(unit, &lag_dlb_control, DLB_IDf, 0);
   1582         BCM_IF_ERROR_RETURN
   1583         (WRITE_LAG_DLB_CONTROLm(unit, MEM_BLOCK_ALL, tid, &lag_dlb_control));
   1584 #ifdef BCM_TRIDENT3_SUPPORT
   1585         if (soc_feature(unit, soc_feature_td3_dlb)) {
   1586             BCM_IF_ERROR_RETURN(READ_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tid, &tg_entry));
   1587             soc_TRUNK_GROUPm_field32_set(unit, &tg_entry, TRUNK_MODEf, 0x0);
   1588             BCM_IF_ERROR_RETURN
   1589                 (WRITE_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tid, &tg_entry));
   1590         }
   1591 #endif
   1592     }
   1593 
   1594     /* Free flow set table resources */
   1595 
   1596     BCM_IF_ERROR_RETURN
   1597         (READ_DLB_HGT_LAG_GROUP_CONTROLm(unit, MEM_BLOCK_ANY, dlb_id,
   1598                                          &dlb_hgt_lag_group_control_entry));
   1599     entry_base_ptr = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit,
   1600                         &dlb_hgt_lag_group_control_entry, FLOW_SET_BASEf);
   1601     flow_set_size  = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit,
   1602                         &dlb_hgt_lag_group_control_entry, FLOW_SET_SIZEf);
   1603     BCM_IF_ERROR_RETURN
   1604         (_bcm_th2_hgt_lag_dlb_dynamic_size_decode(flow_set_size, &num_entries));
   1605     block_base_ptr = entry_base_ptr >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT;
   1606     num_blocks     = num_entries >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT;
   1607     _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_CLR_RANGE(unit, block_base_ptr, num_blocks);
   1608 
   1609     /* Clear HGT_LAG DLB group control */
   1610 
   1611     BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_GROUP_CONTROLm(unit,
   1612                 MEM_BLOCK_ALL, dlb_id,
   1613                 soc_mem_entry_null(unit, DLB_HGT_LAG_GROUP_CONTROLm)));
   1614 
   1615     /* Allocate port map */
   1616     port_map_width = soc_mem_field_length(unit,
   1617             DLB_HGT_LAG_GROUP_MEMBERSHIPm, PORT_MAPf);
   1618     alloc_size = SHR_BITALLOCSIZE(port_map_width);
   1619     port_map = sal_alloc(alloc_size, "DLB HGT_LAG port map");
   1620     if (NULL == port_map) {
   1621         return BCM_E_MEMORY;
   1622     }
   1623     sal_memset(port_map, 0, alloc_size);
   1624 
   1625     membership_pointer = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit,
   1626             &dlb_hgt_lag_group_control_entry, GROUP_MEMBERSHIP_POINTERf);
   1627     rv = READ_DLB_HGT_LAG_GROUP_MEMBERSHIPm(unit, MEM_BLOCK_ANY, membership_pointer,
   1628             &dlb_hgt_lag_group_membership_entry);
   1629     if (BCM_FAILURE(rv)) {
   1630         goto error;
   1631     }
   1632     soc_DLB_HGT_LAG_GROUP_MEMBERSHIPm_field_get(unit,
   1633             &dlb_hgt_lag_group_membership_entry, PORT_MAPf, port_map);
   1634 
   1635     for (port = 0; port < port_map_width; port++) {
   1636         if (!SHR_BITGET(port_map, port)) {
   1637             continue;
   1638         }
   1639 
   1640         rv = bcm_th2_hgt_lag_dlb_member_attr_set(unit, port,
   1641                                  _BCM_HGT_LAG_DLB_DEFAULT_SCALING_FACTOR,
   1642                                  _BCM_HGT_LAG_DLB_DEFAULT_PORT_LOAD_WEIGHT,
   1643                                  _BCM_HGT_LAG_DLB_DEFAULT_QUEUE_SIZE_WEIGHT);
   1644         if (BCM_FAILURE(rv)) {
   1645             goto error;
   1646         }
   1647     }
   1648 
   1649     /* Clear member software state */
   1650 
   1651     rv = READ_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1652                                         &link_control_entry);
   1653     if (BCM_FAILURE(rv)) {
   1654         goto error;
   1655     }
   1656 
   1657     status_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG member status bitmap");
   1658     if (NULL == status_bitmap) {
   1659         rv = BCM_E_MEMORY;
   1660         goto error;
   1661     }
   1662     sal_memset(status_bitmap, 0, alloc_size);
   1663     soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit,
   1664             &link_control_entry, SW_PORT_STATEf, status_bitmap);
   1665     SHR_BITREMOVE_RANGE(status_bitmap, port_map, 0, port_map_width,
   1666             status_bitmap);
   1667     soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit,
   1668             &link_control_entry, SW_PORT_STATEf, status_bitmap);
   1669 
   1670     override_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG member override bitmap");
   1671     if (NULL == override_bitmap) {
   1672         rv = BCM_E_MEMORY;
   1673         goto error;
   1674     }
   1675     sal_memset(override_bitmap, 0, alloc_size);
   1676     soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit,
   1677             &link_control_entry, SW_OVERRIDE_PORT_MAPf, override_bitmap);
   1678     SHR_BITREMOVE_RANGE(override_bitmap, port_map, 0, port_map_width,
   1679             override_bitmap);
   1680     soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit,
   1681             &link_control_entry, SW_OVERRIDE_PORT_MAPf, override_bitmap);
   1682 
   1683     rv = WRITE_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1684                                          &link_control_entry);
   1685     if (BCM_FAILURE(rv)) {
   1686         goto error;
   1687     }
   1688 
   1689     sal_free(port_map);
   1690     sal_free(status_bitmap);
   1691     sal_free(override_bitmap);
   1692 
   1693     /* Clear group membership */
   1694     BCM_IF_ERROR_RETURN
   1695     (WRITE_DLB_HGT_LAG_GROUP_MEMBERSHIPm(unit, MEM_BLOCK_ANY, membership_pointer,
   1696             soc_mem_entry_null(unit, DLB_HGT_LAG_GROUP_MEMBERSHIPm)));
   1697 
   1698     /* Free DLB ID */
   1699     BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_id_free(unit, dlb_id));
   1700 
   1701     return BCM_E_NONE;
   1702 
   1703 error:
   1704     if (NULL != port_map) {
   1705         sal_free(port_map);
   1706     }
   1707     if (NULL != status_bitmap) {
   1708         sal_free(status_bitmap);
   1709     }
   1710     if (NULL != override_bitmap) {
   1711         sal_free(override_bitmap);
   1712     }
   1713     return rv;
   1714 }
   1715 
   1716 
   1717 
   1718 /*
   1719  * Function:
   1720  *      bcm_th2_hgt_lag_dlb_set
   1721  * Purpose:
   1722  *      Configure a HGT_LAG dynamic load balancing group. For Lag.
   1723  * Parameters:
   1724  *      unit       - (IN) SOC unit number.
   1725  *      tid        - (IN) Trunk/HiGig Trunk group ID.
   1726  *      hgt        - (IN) Is HiGig Trunk
   1727  *      add_info   - (IN) Pointer to trunk add info structure.
   1728  *      num_dlb_ports  - (IN) Number of trunk member ports eligible for
   1729  *                        HGT_LAG DLB
   1730  *      mod_array  - (IN) Array of module IDs
   1731  *      port_array - (IN) Array of port IDs
   1732  *      scaling_factor_array - (IN) Array of scaling factors.
   1733  *      load_weight_array    - (IN) Array of load weights.
   1734  *      qsize_weight_array    - (IN) Array of Queue size weights.
   1735  * Returns:
   1736  *      BCM_E_xxx
   1737  */
   1738 int
   1739 bcm_th2_hgt_lag_dlb_set(int unit, int tid, int hgt, _esw_trunk_add_info_t *add_info,
   1740         int num_dlb_ports, int *mod_array, int *port_array,
   1741         int *scaling_factor_array, int *load_weight_array, int *qsize_weight_array)
   1742 {
   1743     int rv = BCM_E_NONE;
   1744     int dlb_enable;
   1745     int dlb_id;
   1746     soc_mem_t flowset_mem;
   1747     int flowset_entry_size;
   1748     dlb_hgt_lag_flowset_entry_t *flowset_entry;
   1749     int num_blocks;
   1750     int total_blocks;
   1751     int max_block_base_ptr;
   1752     int block_base_ptr;
   1753     int occupied;
   1754     int entry_base_ptr;
   1755     int num_entries_per_block;
   1756     int port_map_width;
   1757     int alloc_size;
   1758     uint32 *block_ptr = NULL;
   1759     int i, k;
   1760     int index_min, index_max;
   1761     int flow_set_size;
   1762     int dlb_mode;
   1763     SHR_BITDCL *port_map = NULL;
   1764     SHR_BITDCL *status_bitmap = NULL;
   1765     SHR_BITDCL *override_bitmap = NULL;
   1766     uint32 membership_pointer;
   1767     hgt_dlb_control_entry_t hgt_dlb_control;
   1768     lag_dlb_control_entry_t lag_dlb_control;
   1769 #ifdef BCM_TRIDENT3_SUPPORT
   1770     hg_trunk_mode_entry_t   hgt_trunk_mode;
   1771     trunk_group_entry_t     tg_entry;
   1772 #endif
   1773     dlb_hgt_lag_group_control_entry_t dlb_hgt_lag_group_control_entry;
   1774     dlb_hgt_lag_group_membership_entry_t dlb_hgt_lag_group_membership_entry;
   1775     dlb_hgt_lag_link_control_entry_t link_control_entry;
   1776     int is_local;
   1777 
   1778     dlb_enable = (add_info->psc == BCM_TRUNK_PSC_DYNAMIC) ||
   1779         (add_info->psc == BCM_TRUNK_PSC_DYNAMIC_ASSIGNED) ||
   1780         (add_info->psc == BCM_TRUNK_PSC_DYNAMIC_OPTIMAL);
   1781 
   1782     if (!dlb_enable) {
   1783         return BCM_E_NONE;
   1784     }
   1785 
   1786     /* Both HiGig Trunk and LAG supports local port only,
   1787      * For HiGig Trunk, mod_array[] are all -1.
   1788      */
   1789     if (soc_feature(unit, soc_feature_lag_dlb)) {
   1790         for (i = 0; i< num_dlb_ports; i++) {
   1791             BCM_IF_ERROR_RETURN
   1792                 (_bcm_esw_modid_is_local(unit, mod_array[i], &is_local));
   1793             if (!is_local) {
   1794                 return BCM_E_PARAM;
   1795             }
   1796         }
   1797     }
   1798 
   1799     for (i = 0; i < num_dlb_ports; i++) {
   1800         if (!_bcm_th2_hgt_lag_dlb_scaling_factor_encode(unit,
   1801                  scaling_factor_array[i], NULL)) {
   1802             return BCM_E_PARAM;
   1803         }
   1804         if (load_weight_array[i] < 0 ||
   1805             load_weight_array[i] > 100) {
   1806             return BCM_E_PARAM;
   1807         }
   1808         if (qsize_weight_array[i] < 0 ||
   1809             qsize_weight_array[i] > 100) {
   1810             return BCM_E_PARAM;
   1811         }
   1812         if ((load_weight_array[i] + qsize_weight_array[i]) < 0 ||
   1813             (load_weight_array[i] + qsize_weight_array[i]) > 100) {
   1814             return BCM_E_PARAM;
   1815         }
   1816     }
   1817 
   1818     /* Allocate a DLB ID */
   1819     BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_id_alloc(unit, &dlb_id));
   1820 
   1821     for (i = 0; i < num_dlb_ports; i++) {
   1822         BCM_IF_ERROR_RETURN
   1823             (bcm_th2_hgt_lag_dlb_member_attr_set(unit, port_array[i],
   1824                                                  scaling_factor_array[i],
   1825                                                  load_weight_array[i],
   1826                                                  qsize_weight_array[i]));
   1827     }
   1828 
   1829     port_map_width = soc_mem_field_length(unit,
   1830             DLB_HGT_LAG_GROUP_MEMBERSHIPm, PORT_MAPf);
   1831     alloc_size = SHR_BITALLOCSIZE(port_map_width);
   1832     port_map = sal_alloc(alloc_size, "DLB HGT_LAG port map");
   1833     if (NULL == port_map) {
   1834         rv = BCM_E_MEMORY;
   1835         goto error;
   1836     }
   1837     sal_memset(port_map, 0, alloc_size);
   1838     for (i = 0; i < num_dlb_ports; i++) {
   1839         SHR_BITSET(port_map, port_array[i]);
   1840     }
   1841 
   1842     /* Set member software state */
   1843     rv = READ_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   1844                 &link_control_entry);
   1845     if (BCM_FAILURE(rv)) {
   1846         goto error;
   1847     }
   1848     status_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG member status bitmap");
   1849     if (NULL == status_bitmap) {
   1850         rv = BCM_E_MEMORY;
   1851         goto error;
   1852     }
   1853     sal_memset(status_bitmap, 0, alloc_size);
   1854     soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit,
   1855             &link_control_entry, SW_PORT_STATEf, status_bitmap);
   1856 
   1857     SHR_BITREMOVE_RANGE(status_bitmap, port_map, 0, port_map_width,
   1858             status_bitmap);
   1859     soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit,
   1860             &link_control_entry, SW_PORT_STATEf, status_bitmap);
   1861 
   1862     override_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG member override bitmap");
   1863     if (NULL == override_bitmap) {
   1864         rv = BCM_E_MEMORY;
   1865         goto error;
   1866     }
   1867     sal_memset(override_bitmap, 0, alloc_size);
   1868     soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit,
   1869             &link_control_entry, SW_OVERRIDE_PORT_MAPf,
   1870             override_bitmap);
   1871 
   1872     SHR_BITREMOVE_RANGE(override_bitmap, port_map, 0, port_map_width,
   1873             override_bitmap);
   1874     soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit,
   1875             &link_control_entry, SW_OVERRIDE_PORT_MAPf, override_bitmap);
   1876 
   1877     rv = WRITE_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   1878                 &link_control_entry);
   1879     if (BCM_FAILURE(rv)) {
   1880         goto error;
   1881     }
   1882 
   1883     /* Set group membership table */
   1884     sal_memset(&dlb_hgt_lag_group_membership_entry, 0,
   1885             sizeof(dlb_hgt_lag_group_membership_entry_t));
   1886     soc_DLB_HGT_LAG_GROUP_MEMBERSHIPm_field_set(unit,
   1887             &dlb_hgt_lag_group_membership_entry, PORT_MAPf, port_map);
   1888     membership_pointer = dlb_id;
   1889     rv = WRITE_DLB_HGT_LAG_GROUP_MEMBERSHIPm(unit, MEM_BLOCK_ALL, membership_pointer,
   1890             &dlb_hgt_lag_group_membership_entry);
   1891 
   1892     if (BCM_FAILURE(rv)) {
   1893         goto error;
   1894     }
   1895 
   1896     /* Set DLB flow set table */
   1897 
   1898     flowset_mem = DLB_HGT_LAG_FLOWSETm;
   1899     flowset_entry_size = sizeof(dlb_hgt_lag_flowset_entry_t);
   1900     num_blocks = add_info->dynamic_size >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT;
   1901     total_blocks = soc_mem_index_count(unit, flowset_mem) >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT;
   1902     max_block_base_ptr = total_blocks - num_blocks;
   1903     for (block_base_ptr = 0;
   1904             block_base_ptr <= max_block_base_ptr;
   1905             block_base_ptr++) {
   1906         /* Check if the contiguous region of flow set table from
   1907          * block_base_ptr to (block_base_ptr + num_blocks - 1) is free.
   1908          */
   1909         _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_TEST_RANGE(unit, block_base_ptr, num_blocks,
   1910                 occupied);
   1911         if (!occupied) {
   1912             break;
   1913         }
   1914     }
   1915     if (block_base_ptr > max_block_base_ptr) {
   1916         /* A contiguous region of the desired size could not be found in
   1917          * flow set table.
   1918          */
   1919         rv = BCM_E_RESOURCE;
   1920         goto error;
   1921     }
   1922 
   1923     entry_base_ptr = block_base_ptr << _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT;
   1924     num_entries_per_block = 1 << _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT;
   1925     alloc_size = num_entries_per_block * flowset_entry_size;
   1926     block_ptr = soc_cm_salloc(unit, alloc_size,
   1927             "Block of DLB_HGT_LAG_FLOWSET entries");
   1928     if (NULL == block_ptr) {
   1929         rv = BCM_E_MEMORY;
   1930         goto error;
   1931     }
   1932     sal_memset(block_ptr, 0, alloc_size);
   1933     for (i = 0; i < num_blocks; i++) {
   1934         for (k = 0; k < num_entries_per_block; k++) {
   1935             flowset_entry = soc_mem_table_idx_to_pointer(unit,
   1936                     DLB_HGT_LAG_FLOWSETm, dlb_hgt_lag_flowset_entry_t *,
   1937                     block_ptr, k);
   1938             soc_DLB_HGT_LAG_FLOWSETm_field32_set(unit, flowset_entry,
   1939                     VALIDf, 1);
   1940             soc_DLB_HGT_LAG_FLOWSETm_field32_set(unit, flowset_entry,
   1941                     PORT_MEMBER_ASSIGNMENTf,
   1942                     port_array[(i * num_entries_per_block + k)
   1943                     % num_dlb_ports]);
   1944         }
   1945         index_min = entry_base_ptr + i * num_entries_per_block;
   1946         index_max = index_min + num_entries_per_block - 1;
   1947         rv = soc_mem_write_range(unit, flowset_mem, MEM_BLOCK_ALL,
   1948                 index_min, index_max, block_ptr);
   1949         if (BCM_FAILURE(rv)) {
   1950             goto error;
   1951         }
   1952     }
   1953 
   1954     _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_SET_RANGE(unit, block_base_ptr, num_blocks);
   1955 
   1956     /* Set HGT_LAG DLB group control table */
   1957 
   1958     sal_memset(&dlb_hgt_lag_group_control_entry, 0,
   1959             sizeof(dlb_hgt_lag_group_control_entry_t));
   1960     soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry,
   1961             GROUP_MEMBERSHIP_POINTERf, membership_pointer);
   1962     soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry,
   1963             ENABLE_OPTIMAL_CANDIDATE_UPDATEf, 1);
   1964     soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry,
   1965             FLOW_SET_BASEf, entry_base_ptr);
   1966 
   1967     rv = bcm_th2_hgt_lag_dlb_dynamic_size_encode(add_info->dynamic_size,
   1968             &flow_set_size);
   1969     if (BCM_FAILURE(rv)) {
   1970         goto error;
   1971     }
   1972     soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry,
   1973             FLOW_SET_SIZEf, flow_set_size);
   1974 
   1975     switch (add_info->psc) {
   1976         case BCM_TRUNK_PSC_DYNAMIC:
   1977             dlb_mode = 0;
   1978             break;
   1979         case BCM_TRUNK_PSC_DYNAMIC_ASSIGNED:
   1980             dlb_mode = 1;
   1981             break;
   1982         case BCM_TRUNK_PSC_DYNAMIC_OPTIMAL:
   1983             dlb_mode = 2;
   1984             break;
   1985         default:
   1986             rv = BCM_E_PARAM;
   1987             goto error;
   1988     }
   1989     soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry,
   1990             PORT_ASSIGNMENT_MODEf, dlb_mode);
   1991 
   1992     soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry,
   1993             INACTIVITY_DURATIONf, add_info->dynamic_age);
   1994 
   1995     rv = WRITE_DLB_HGT_LAG_GROUP_CONTROLm(unit, MEM_BLOCK_ALL, dlb_id,
   1996             &dlb_hgt_lag_group_control_entry);
   1997     if (BCM_FAILURE(rv)) {
   1998         goto error;
   1999     }
   2000 
   2001     /* Update trunk group table */
   2002     if (hgt) {
   2003         rv = READ_HGT_DLB_CONTROLm(unit, MEM_BLOCK_ANY, tid, &hgt_dlb_control);
   2004         if (BCM_FAILURE(rv)) {
   2005             goto error;
   2006         }
   2007         soc_HGT_DLB_CONTROLm_field32_set(unit, &hgt_dlb_control, GROUP_ENABLEf, 1);
   2008         soc_HGT_DLB_CONTROLm_field32_set(unit, &hgt_dlb_control, DLB_IDf, dlb_id);
   2009         rv = WRITE_HGT_DLB_CONTROLm(unit, MEM_BLOCK_ALL, tid, &hgt_dlb_control);
   2010 #ifdef BCM_TRIDENT3_SUPPORT
   2011         if (soc_feature(unit, soc_feature_td3_dlb)) {
   2012             rv = READ_HG_TRUNK_MODEm(unit, MEM_BLOCK_ANY, tid, &hgt_trunk_mode);
   2013             if (BCM_FAILURE(rv)) {
   2014                 goto error;
   2015             }
   2016             soc_HG_TRUNK_MODEm_field32_set(unit, &hgt_trunk_mode, HG_TRUNK_LB_MODEf, 0x1);
   2017             rv = WRITE_HG_TRUNK_MODEm(unit, MEM_BLOCK_ANY, tid, &hgt_trunk_mode);
   2018         }
   2019 #endif
   2020     } else {
   2021         rv = READ_LAG_DLB_CONTROLm(unit, MEM_BLOCK_ANY, tid, &lag_dlb_control);
   2022         if (BCM_FAILURE(rv)) {
   2023             goto error;
   2024         }
   2025         soc_LAG_DLB_CONTROLm_field32_set(unit, &lag_dlb_control, GROUP_ENABLEf, 1);
   2026         soc_LAG_DLB_CONTROLm_field32_set(unit, &lag_dlb_control, DLB_IDf, dlb_id);
   2027         rv = WRITE_LAG_DLB_CONTROLm(unit, MEM_BLOCK_ALL, tid, &lag_dlb_control);
   2028 #ifdef BCM_TRIDENT3_SUPPORT
   2029         if (soc_feature(unit, soc_feature_td3_dlb)) {
   2030             rv = READ_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tid, &tg_entry);
   2031             if (BCM_FAILURE(rv)) {
   2032                 goto error;
   2033             }
   2034             soc_TRUNK_GROUPm_field32_set(unit, &tg_entry, TRUNK_MODEf, 0x3);
   2035             rv = WRITE_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tid, &tg_entry);
   2036         }
   2037 #endif
   2038     }
   2039     if (BCM_FAILURE(rv)) {
   2040         goto error;
   2041     }
   2042 
   2043     soc_cm_sfree(unit, block_ptr);
   2044     sal_free(port_map);
   2045     sal_free(status_bitmap);
   2046     sal_free(override_bitmap);
   2047 
   2048     return rv;
   2049 
   2050 error:
   2051     if (NULL != block_ptr) {
   2052         soc_cm_sfree(unit, block_ptr);
   2053     }
   2054     if (NULL != port_map) {
   2055         sal_free(port_map);
   2056     }
   2057     if (NULL != status_bitmap) {
   2058         sal_free(status_bitmap);
   2059     }
   2060     if (NULL != override_bitmap) {
   2061         sal_free(override_bitmap);
   2062     }
   2063     return rv;
   2064 }
   2065 
   2066 
   2067 /*
   2068  * Function:
   2069  *      bcm_th2_hgt_lag_dlb_member_status_set
   2070  * Purpose:
   2071  *      Set HGT_LAG DLB member status.
   2072  * Parameters:
   2073  *      unit   - (IN) SOC unit number.
   2074  *      port   - (IN) Member port number.
   2075  *      status - (IN) Member status.
   2076  * Returns:
   2077  *      BCM_E_xxx
   2078  */
   2079 int
   2080 bcm_th2_hgt_lag_dlb_member_status_set(int unit, bcm_port_t port, int status)
   2081 {
   2082     dlb_hgt_lag_link_control_entry_t link_control_entry;
   2083     int status_width, alloc_size;
   2084     SHR_BITDCL *status_bitmap = NULL;
   2085     SHR_BITDCL *override_bitmap = NULL;
   2086 
   2087     /* Get status bitmap */
   2088     BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   2089                 &link_control_entry));
   2090     status_width = soc_mem_field_length(unit, DLB_HGT_LAG_LINK_CONTROLm,
   2091                                         SW_PORT_STATEf);
   2092     alloc_size = SHR_BITALLOCSIZE(status_width);
   2093     status_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG port status bitmap");
   2094     if (NULL == status_bitmap) {
   2095         return BCM_E_MEMORY;
   2096     }
   2097     sal_memset(status_bitmap, 0, alloc_size);
   2098     soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, &link_control_entry,
   2099             SW_PORT_STATEf, status_bitmap);
   2100 
   2101     /* Get override bitmap */
   2102     override_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG port override bitmap");
   2103     if (NULL == override_bitmap) {
   2104         sal_free(status_bitmap);
   2105         return BCM_E_MEMORY;
   2106     }
   2107     sal_memset(override_bitmap, 0, alloc_size);
   2108     soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, &link_control_entry,
   2109             SW_OVERRIDE_PORT_MAPf, override_bitmap);
   2110 
   2111     /* Update status and override bitmaps */
   2112     switch (status) {
   2113         case BCM_TRUNK_DYNAMIC_MEMBER_FORCE_DOWN:
   2114             SHR_BITSET(override_bitmap, port);
   2115             SHR_BITCLR(status_bitmap, port);
   2116             break;
   2117         case BCM_TRUNK_DYNAMIC_MEMBER_FORCE_UP:
   2118             SHR_BITSET(override_bitmap, port);
   2119             SHR_BITSET(status_bitmap, port);
   2120             break;
   2121         case BCM_TRUNK_DYNAMIC_MEMBER_HW:
   2122             SHR_BITCLR(override_bitmap, port);
   2123             SHR_BITCLR(status_bitmap, port);
   2124             break;
   2125         default:
   2126             sal_free(status_bitmap);
   2127             sal_free(override_bitmap);
   2128             return BCM_E_PARAM;
   2129     }
   2130 
   2131     /* Write status and override bitmaps to hardware */
   2132     soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit, &link_control_entry,
   2133             SW_PORT_STATEf, status_bitmap);
   2134     soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit, &link_control_entry,
   2135             SW_OVERRIDE_PORT_MAPf, override_bitmap);
   2136     sal_free(status_bitmap);
   2137     sal_free(override_bitmap);
   2138     BCM_IF_ERROR_RETURN
   2139         (WRITE_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ALL, 0,
   2140                                          &link_control_entry));
   2141 
   2142     return BCM_E_NONE;
   2143 }
   2144 
   2145 /*
   2146  * Function:
   2147  *      bcm_th2_hgt_lag_dlb_member_status_get
   2148  * Purpose:
   2149  *      Get HGT_LAG DLB member status.
   2150  * Parameters:
   2151  *      unit - (IN) SOC unit number.
   2152  *      port   - (IN) Member port number.
   2153  *      status - (OUT) Member status.
   2154  * Returns:
   2155  *      BCM_E_xxx
   2156  */
   2157 int
   2158 bcm_th2_hgt_lag_dlb_member_status_get(int unit, bcm_port_t port, int *status)
   2159 {
   2160     int rv = BCM_E_NONE;
   2161     dlb_hgt_lag_link_control_entry_t link_control_entry;
   2162     int status_width, alloc_size;
   2163     SHR_BITDCL *status_bitmap    = NULL;
   2164     SHR_BITDCL *override_bitmap  = NULL;
   2165     SHR_BITDCL *hw_status_bitmap = NULL;
   2166     dlb_hgt_lag_port_state_entry_t hw_state;
   2167 
   2168     /* Get status bitmap */
   2169     BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ANY, 0,
   2170                 &link_control_entry));
   2171     status_width = soc_mem_field_length(unit, DLB_HGT_LAG_LINK_CONTROLm,
   2172                                         SW_PORT_STATEf);
   2173     alloc_size = SHR_BITALLOCSIZE(status_width);
   2174     status_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG port status bitmap");
   2175     if (NULL == status_bitmap) {
   2176         return BCM_E_MEMORY;
   2177     }
   2178     sal_memset(status_bitmap, 0, alloc_size);
   2179     soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, &link_control_entry,
   2180             SW_PORT_STATEf, status_bitmap);
   2181 
   2182     /* Get override bitmap */
   2183     override_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG port override bitmap");
   2184     if (NULL == override_bitmap) {
   2185         sal_free(status_bitmap);
   2186         return BCM_E_MEMORY;
   2187     }
   2188     sal_memset(override_bitmap, 0, alloc_size);
   2189     soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, &link_control_entry,
   2190             SW_OVERRIDE_PORT_MAPf, override_bitmap);
   2191 
   2192     /* Derive status from software override and status bitmaps or
   2193      * hardware state bitmap.
   2194      */
   2195     if (SHR_BITGET(override_bitmap, port)) {
   2196         if (SHR_BITGET(status_bitmap, port)) {
   2197             *status = BCM_TRUNK_DYNAMIC_MEMBER_FORCE_UP;
   2198         } else {
   2199             *status = BCM_TRUNK_DYNAMIC_MEMBER_FORCE_DOWN;
   2200         }
   2201     } else {
   2202         /* Get hardware bitmap */
   2203         hw_status_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG member hw status bitmap");
   2204         if (NULL == hw_status_bitmap) {
   2205             sal_free(status_bitmap);
   2206             sal_free(override_bitmap);
   2207             return BCM_E_MEMORY;
   2208         }
   2209         sal_memset(hw_status_bitmap, 0, alloc_size);
   2210 
   2211         rv = READ_DLB_HGT_LAG_PORT_STATEm(unit, MEM_BLOCK_ANY, 0, &hw_state);
   2212         if (BCM_FAILURE(rv)) {
   2213             sal_free(status_bitmap);
   2214             sal_free(override_bitmap);
   2215             sal_free(hw_status_bitmap);
   2216             return rv;
   2217         }
   2218         soc_DLB_HGT_LAG_PORT_STATEm_field_get(unit, &hw_state,
   2219                 BITMAPf, hw_status_bitmap);
   2220         if (SHR_BITGET(hw_status_bitmap, port)) {
   2221             *status = BCM_TRUNK_DYNAMIC_MEMBER_HW_UP;
   2222         } else {
   2223             *status = BCM_TRUNK_DYNAMIC_MEMBER_HW_DOWN;
   2224         }
   2225     }
   2226 
   2227     sal_free(status_bitmap);
   2228     sal_free(override_bitmap);
   2229     if (NULL != hw_status_bitmap) {
   2230         sal_free(hw_status_bitmap);
   2231     }
   2232 
   2233     return BCM_E_NONE;
   2234 }
   2235 
   2236 /*
   2237  * Function:
   2238  *      bcm_th2_hgt_lag_dlb_ethertype_set
   2239  * Purpose:
   2240  *      Set the Ethertypes that are eligible or ineligible for
   2241  *      HGT_LAG dynamic load balancing.
   2242  * Parameters:
   2243  *      unit - (IN) Unit number.
   2244  *      flags - (IN) BCM_TRUNK_DYNAMIC_ETHERTYPE_xxx flags.
   2245  *      ethertype_count - (IN) Number of elements in ethertype_array.
   2246  *      ethertype_array - (IN) Array of Ethertypes.
   2247  * Returns:
   2248  *      BCM_E_XXX
   2249  */
   2250 int
   2251 bcm_th2_hgt_lag_dlb_ethertype_set(int unit,
   2252                                   uint32 flags,
   2253                                   int ethertype_count,
   2254                                   int *ethertype_array)
   2255 {
   2256     int i, j;
   2257     dlb_hgt_lag_eem_configuration_entry_t eem_entry;
   2258     dlb_hgt_lag_ethertype_eligibility_map_entry_t ethertype_entry;
   2259 #ifdef BCM_TRIDENT3_SUPPORT
   2260     uint32 reg_val = 0;
   2261 #endif
   2262     /* Input check */
   2263     if ((ethertype_count > 0) && (NULL == ethertype_array)) {
   2264         return BCM_E_PARAM;
   2265     }
   2266     if (ethertype_count > soc_mem_index_count(unit,
   2267                 DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm)) {
   2268         return BCM_E_RESOURCE;
   2269     }
   2270 
   2271     /* Update quality measure control register */
   2272 #ifdef BCM_TRIDENT3_SUPPORT
   2273     if (soc_feature(unit, soc_feature_td3_dlb)) {
   2274         BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr(unit,
   2275                     &reg_val));
   2276         soc_reg_field_set(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr,
   2277                 &reg_val, CONFIGURATIONf,
   2278                 flags & BCM_TRUNK_DYNAMIC_ETHERTYPE_ELIGIBLE ? 1 : 0);
   2279         soc_reg_field_set(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr,
   2280                 &reg_val, INNER_OUTER_ETHERTYPE_SELECTIONf,
   2281                 flags & BCM_TRUNK_DYNAMIC_ETHERTYPE_INNER ? 1 : 0);
   2282         BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr(unit,
   2283                     reg_val));
   2284     } else
   2285 #endif
   2286     {
   2287         BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_EEM_CONFIGURATIONm(unit,
   2288                     MEM_BLOCK_ANY, 0, &eem_entry));
   2289         soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_set(unit,
   2290                 &eem_entry, CONFIGURATIONf,
   2291                 flags & BCM_TRUNK_DYNAMIC_ETHERTYPE_ELIGIBLE ? 1 : 0);
   2292         soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_set(unit,
   2293                 &eem_entry, INNER_OUTER_ETHERTYPE_SELECTIONf,
   2294                 flags & BCM_TRUNK_DYNAMIC_ETHERTYPE_INNER ? 1 : 0);
   2295         BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_EEM_CONFIGURATIONm(unit,
   2296                     MEM_BLOCK_ALL, 0, &eem_entry));
   2297     }
   2298 
   2299     /* Update Ethertype eligibility map table */
   2300     for (i = 0; i < ethertype_count; i++) {
   2301         sal_memset(&ethertype_entry, 0,
   2302                 sizeof(dlb_hgt_lag_ethertype_eligibility_map_entry_t));
   2303         soc_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm_field32_set(unit,
   2304                 &ethertype_entry, VALIDf, 1);
   2305         soc_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm_field32_set(unit,
   2306                 &ethertype_entry, ETHERTYPEf, ethertype_array[i]);
   2307         BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm(unit,
   2308                     MEM_BLOCK_ALL, i, &ethertype_entry));
   2309     }
   2310 
   2311     /* Zero out remaining entries of Ethertype eligibility map table */
   2312     for (j = i; j < soc_mem_index_count(unit,
   2313                 DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm); j++) {
   2314         BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm(unit,
   2315                     MEM_BLOCK_ALL, j, soc_mem_entry_null(unit,
   2316                         DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm)));
   2317     }
   2318 
   2319     return BCM_E_NONE;
   2320 }
   2321 
   2322 /*
   2323  * Function:
   2324  *      bcm_th2_hgt_lag_dlb_ethertype_get
   2325  * Purpose:
   2326  *      Get the Ethertypes that are eligible or ineligible for
   2327  *      HGT_LAG dynamic load balancing.
   2328  * Parameters:
   2329  *      unit - (IN) Unit number.
   2330  *      flags - (INOUT) BCM_TRUNK_DYNAMIC_ETHERTYPE_xxx flags.
   2331  *      ethertype_max - (IN) Number of elements in ethertype_array.
   2332  *      ethertype_array - (OUT) Array of Ethertypes.
   2333  *      ethertype_count - (OUT) Number of elements returned in ethertype_array.
   2334  * Returns:
   2335  *      BCM_E_XXX
   2336  */
   2337 int
   2338 bcm_th2_hgt_lag_dlb_ethertype_get(int unit,
   2339                                   uint32 *flags,
   2340                                   int ethertype_max,
   2341                                   int *ethertype_array,
   2342                                   int *ethertype_count)
   2343 {
   2344     int i;
   2345     int ethertype;
   2346     dlb_hgt_lag_ethertype_eligibility_map_entry_t ethertype_entry;
   2347     dlb_hgt_lag_eem_configuration_entry_t eem_entry;
   2348 #ifdef BCM_TRIDENT3_SUPPORT
   2349     uint32 reg_val = 0;
   2350 #endif
   2351     /* Input check */
   2352     if (NULL == flags) {
   2353         return BCM_E_PARAM;
   2354     }
   2355     if ((ethertype_max > 0) && (NULL == ethertype_array)) {
   2356         return BCM_E_PARAM;
   2357     }
   2358     if (NULL == ethertype_count) {
   2359         return BCM_E_PARAM;
   2360     }
   2361 
   2362     *ethertype_count = 0;
   2363 
   2364     /* Get flags */
   2365 #ifdef BCM_TRIDENT3_SUPPORT
   2366     if (soc_feature(unit, soc_feature_td3_dlb)) {
   2367         BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr(unit,
   2368                     &reg_val));
   2369         if (soc_reg_field_get(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr,
   2370                     reg_val, CONFIGURATIONf)) {
   2371             *flags |= BCM_TRUNK_DYNAMIC_ETHERTYPE_ELIGIBLE;
   2372         }
   2373         if (soc_reg_field_get(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr,
   2374                     reg_val, INNER_OUTER_ETHERTYPE_SELECTIONf)) {
   2375             *flags |= BCM_TRUNK_DYNAMIC_ETHERTYPE_INNER;
   2376         }
   2377     } else
   2378 #endif
   2379     {
   2380         BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_EEM_CONFIGURATIONm(unit,
   2381                     MEM_BLOCK_ANY, 0, &eem_entry));
   2382         if (soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_get(unit,
   2383                     &eem_entry, CONFIGURATIONf)) {
   2384             *flags |= BCM_TRUNK_DYNAMIC_ETHERTYPE_ELIGIBLE;
   2385         }
   2386         if (soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_get(unit,
   2387                     &eem_entry, INNER_OUTER_ETHERTYPE_SELECTIONf)) {
   2388             *flags |= BCM_TRUNK_DYNAMIC_ETHERTYPE_INNER;
   2389         }
   2390     }
   2391     /* Get Ethertypes */
   2392     for (i = 0; i < soc_mem_index_count(unit,
   2393                 DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm); i++) {
   2394         BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm(unit,
   2395                     MEM_BLOCK_ANY, i, &ethertype_entry));
   2396         if (soc_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm_field32_get(unit,
   2397                     &ethertype_entry, VALIDf)) {
   2398             ethertype = soc_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm_field32_get(unit,
   2399                     &ethertype_entry, ETHERTYPEf);
   2400             if (NULL != ethertype_array) {
   2401                 ethertype_array[*ethertype_count] = ethertype;
   2402             }
   2403             (*ethertype_count)++;
   2404             if ((ethertype_max > 0) && (*ethertype_count == ethertype_max)) {
   2405                 break;
   2406             }
   2407         }
   2408     }
   2409 
   2410     return BCM_E_NONE;
   2411 }
   2412 
   2413 
   2414 /*
   2415  * Function:
   2416  *      _bcm_th2_hgt_lag_dlb_quality_map_profile_init
   2417  * Purpose:
   2418  *      Initialize HGT_LAG DLB quality mapping profile.
   2419  * Parameters:
   2420  *      unit - (IN)SOC unit number.
   2421  * Returns:
   2422  *      BCM_X_XXX
   2423  */
   2424 STATIC int
   2425 _bcm_th2_hgt_lag_dlb_quality_map_profile_init(int unit)
   2426 {
   2427     soc_profile_mem_t *profile;
   2428     soc_mem_t mem;
   2429     int entry_words;
   2430     int entries_per_profile;
   2431     int tx_load_percent;
   2432     int qsize_percent;
   2433     int alloc_size;
   2434     uint32 *entry_arr;
   2435     int rv = BCM_E_NONE;
   2436     void *entries;
   2437     uint32 base_index;
   2438     int i;
   2439     int port;
   2440     dlb_hgt_lag_quantize_control_entry_t quantize_control_entry;
   2441     int num_quality_map_profiles;
   2442     int idx_min, idx_max;
   2443     uint8 *table_chunk = NULL;
   2444     void *table_entry;
   2445 
   2446     if (NULL == _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile) {
   2447         _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile =
   2448             sal_alloc(sizeof(soc_profile_mem_t),
   2449                       "HGT_LAG DLB Quality Map Profile Mem");
   2450         if (NULL == _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile) {
   2451             return BCM_E_MEMORY;
   2452         }
   2453     } else {
   2454         soc_profile_mem_destroy(unit,
   2455                 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile);
   2456     }
   2457     profile = _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile;
   2458     soc_profile_mem_t_init(profile);
   2459 
   2460     mem = DLB_HGT_LAG_PORT_QUALITY_MAPPINGm;
   2461     entry_words = sizeof(dlb_hgt_lag_port_quality_mapping_entry_t) / sizeof(uint32);
   2462     BCM_IF_ERROR_RETURN
   2463         (soc_profile_mem_create(unit, &mem, &entry_words, 1, profile));
   2464 
   2465     num_quality_map_profiles = 1 << soc_mem_field_length(unit,
   2466         DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf);
   2467     entries_per_profile =
   2468         soc_mem_index_count(unit, DLB_HGT_LAG_PORT_QUALITY_MAPPINGm) /
   2469         num_quality_map_profiles;
   2470 
   2471     if (!SOC_WARM_BOOT(unit)) {
   2472         alloc_size = entries_per_profile * entry_words * sizeof(uint32);
   2473         entry_arr = sal_alloc(alloc_size, "HGT_LAG DLB Quality Map entries");
   2474         if (entry_arr == NULL) {
   2475             return BCM_E_MEMORY;
   2476         }
   2477         sal_memset(entry_arr, 0, alloc_size);
   2478 
   2479         /* Assign quality in the entry array, with 100% weight for port load,
   2480          * 0% for queue size.
   2481          */
   2482         tx_load_percent = 100;
   2483         qsize_percent   = 0;
   2484         rv = _bcm_th2_hgt_lag_dlb_quality_assign(unit, tx_load_percent,
   2485                                              qsize_percent, entry_arr);
   2486         if (BCM_FAILURE(rv)) {
   2487             sal_free(entry_arr);
   2488             return rv;
   2489         }
   2490 
   2491         entries = entry_arr;
   2492         rv = soc_profile_mem_add(unit, profile, &entries, entries_per_profile,
   2493                                  &base_index);
   2494         sal_free(entry_arr);
   2495         if (BCM_FAILURE(rv)) {
   2496             return rv;
   2497         }
   2498 
   2499         mem = DLB_HGT_LAG_QUANTIZE_CONTROLm;
   2500         idx_min = soc_mem_index_min(unit, mem);
   2501         idx_max = soc_mem_index_max(unit, mem);
   2502         table_chunk = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem),
   2503                                     "DLB table buffer");
   2504         if (table_chunk == NULL) {
   2505             return BCM_E_MEMORY;
   2506         }
   2507 
   2508         sal_memset(table_chunk, 0, SOC_MEM_TABLE_BYTES(unit, mem));
   2509         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max,
   2510                                 table_chunk);
   2511         if (SOC_FAILURE(rv)) {
   2512             soc_cm_sfree(unit, table_chunk);
   2513             return rv;
   2514         }
   2515         for(port = idx_min; port <= idx_max; port++) {
   2516             table_entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
   2517                                                        table_chunk, port);
   2518             soc_mem_field32_set(unit, mem, table_entry,
   2519                                 PORT_QUALITY_MAPPING_PROFILE_PTRf,
   2520                                 base_index / entries_per_profile);
   2521         }
   2522         rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max,
   2523                                 table_chunk);
   2524         if (SOC_FAILURE(rv)) {
   2525             soc_cm_sfree(unit, table_chunk);
   2526             return rv;
   2527         }
   2528         soc_cm_sfree(unit, table_chunk);
   2529 
   2530         for (i = 0; i < entries_per_profile; i++) {
   2531             SOC_PROFILE_MEM_REFERENCE(unit, profile, base_index + i,
   2532                                       port - 1);
   2533         }
   2534 
   2535         HGT_LAG_DLB_INFO(unit)->
   2536             hgt_lag_dlb_load_weight[base_index/entries_per_profile] =
   2537                 tx_load_percent;
   2538         HGT_LAG_DLB_INFO(unit)->
   2539             hgt_lag_dlb_qsize_weight[base_index/entries_per_profile] =
   2540                 qsize_percent;
   2541 
   2542     } else { /* Warm boot, recover reference counts and entries_per_set */
   2543 
   2544         for (port = 0;
   2545                 port < soc_mem_index_count(unit,
   2546                     DLB_HGT_LAG_QUANTIZE_CONTROLm);
   2547                 port++) {
   2548             BCM_IF_ERROR_RETURN
   2549                 (READ_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ANY,
   2550                                                port,
   2551                                                &quantize_control_entry));
   2552             base_index = soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_get(unit,
   2553                     &quantize_control_entry, PORT_QUALITY_MAPPING_PROFILE_PTRf);
   2554             base_index *= entries_per_profile;
   2555             for (i = 0; i < entries_per_profile; i++) {
   2556                 SOC_PROFILE_MEM_REFERENCE(unit, profile, base_index + i, 1);
   2557                 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, profile,
   2558                         base_index + i, entries_per_profile);
   2559             }
   2560         }
   2561     }
   2562 
   2563     return BCM_E_NONE;
   2564 }
   2565 
   2566 
   2567 
   2568 /*
   2569  * Function:
   2570  *      bcm_th2_hgt_lag_dlb_deinit
   2571  * Purpose:
   2572  *      Deallocate _th2_hgt_lag_dlb_bk
   2573  * Parameters:
   2574  *      unit - (IN)SOC unit number.
   2575  * Returns:
   2576  *      None
   2577  */
   2578 void
   2579 bcm_th2_hgt_lag_dlb_deinit(int unit)
   2580 {
   2581     if (_th2_hgt_lag_dlb_bk[unit]) {
   2582         if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap) {
   2583             sal_free(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap);
   2584             _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap = NULL;
   2585         }
   2586         if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap) {
   2587             sal_free(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap);
   2588             _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap = NULL;
   2589         }
   2590         if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight) {
   2591             sal_free(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight);
   2592             _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight = NULL;
   2593         }
   2594         if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight) {
   2595             sal_free(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight);
   2596             _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight = NULL;
   2597         }
   2598         if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile) {
   2599             soc_profile_mem_destroy(unit,
   2600                     _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile);
   2601             sal_free(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile);
   2602             _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile = NULL;
   2603         }
   2604 
   2605         sal_free(_th2_hgt_lag_dlb_bk[unit]);
   2606         _th2_hgt_lag_dlb_bk[unit] = NULL;
   2607     }
   2608 
   2609     return;
   2610 }
   2611 
   2612 /*
   2613  * Function:
   2614  *      bcm_th2_hgt_lag_dlb_init
   2615  * Purpose:
   2616  *      Allocate and initialize _th2_hgt_lag_dlb_bk
   2617  * Parameters:
   2618  *      unit - (IN)SOC unit number.
   2619  * Returns:
   2620  *      BCM_X_XXX
   2621  */
   2622 int
   2623 bcm_th2_hgt_lag_dlb_init(int unit)
   2624 {
   2625     int rv = BCM_E_NONE;
   2626     int num_hgt_lag_dlb_id;
   2627     int flowset_tbl_size;
   2628     int total_num_blocks;
   2629     int num_quality_map_profiles;
   2630     int port, pipe;
   2631     dlb_hgt_lag_eem_configuration_entry_t eem_entry;
   2632     int sample_rate;
   2633     int qsize_sel[4] = {1, 0, 0, 1};
   2634     soc_reg_t reg;
   2635     uint32 rval;
   2636     int idx_min, idx_max;
   2637     uint8 *table_chunk = NULL;
   2638     void *table_entry;
   2639     soc_mem_t mem;
   2640 #ifdef BCM_TRIDENT3_SUPPORT
   2641     uint32 reg_val = 0;
   2642 #endif
   2643     bcm_th2_hgt_lag_dlb_deinit(unit);
   2644 
   2645     if (_th2_hgt_lag_dlb_bk[unit] == NULL) {
   2646         _th2_hgt_lag_dlb_bk[unit] = sal_alloc(
   2647                 sizeof(_th2_hgt_lag_dlb_bookkeeping_t), "_th2_hgt_lag_dlb_bk");
   2648         if (_th2_hgt_lag_dlb_bk[unit] == NULL) {
   2649             return BCM_E_MEMORY;
   2650         }
   2651     }
   2652     sal_memset(_th2_hgt_lag_dlb_bk[unit], 0, sizeof(_th2_hgt_lag_dlb_bookkeeping_t));
   2653 
   2654     num_hgt_lag_dlb_id = soc_mem_index_count(unit, DLB_HGT_LAG_GROUP_CONTROLm);
   2655     if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap == NULL) {
   2656         _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap =
   2657             sal_alloc(SHR_BITALLOCSIZE(num_hgt_lag_dlb_id),
   2658                     "hgt_lag_dlb_id_used_bitmap");
   2659         if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap == NULL) {
   2660             bcm_th2_hgt_lag_dlb_deinit(unit);
   2661             return BCM_E_MEMORY;
   2662         }
   2663     }
   2664     sal_memset(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap, 0,
   2665             SHR_BITALLOCSIZE(num_hgt_lag_dlb_id));
   2666 
   2667     flowset_tbl_size = soc_mem_index_count(unit, DLB_HGT_LAG_FLOWSETm);
   2668     /* Each bit in hgt_lag_dlb_flowset_block_bitmap corresponds to a block of 512
   2669      * flow set table entries.
   2670      */
   2671     total_num_blocks = flowset_tbl_size >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT;
   2672     if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap == NULL) {
   2673         _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap =
   2674             sal_alloc(SHR_BITALLOCSIZE(total_num_blocks),
   2675                     "hgt_lag_dlb_flowset_block_bitmap");
   2676         if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap == NULL) {
   2677             bcm_th2_hgt_lag_dlb_deinit(unit);
   2678             return BCM_E_MEMORY;
   2679         }
   2680     }
   2681     sal_memset(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap, 0,
   2682             SHR_BITALLOCSIZE(total_num_blocks));
   2683 
   2684     num_quality_map_profiles = 1 << soc_mem_field_length(unit,
   2685             DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf);
   2686     if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight == NULL) {
   2687         _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight =
   2688             sal_alloc(num_quality_map_profiles * sizeof(uint8),
   2689                     "hgt_lag_dlb_load_weight");
   2690         if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight == NULL) {
   2691             bcm_th2_hgt_lag_dlb_deinit(unit);
   2692             return BCM_E_MEMORY;
   2693         }
   2694     }
   2695     sal_memset(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight, 0,
   2696             num_quality_map_profiles * sizeof(uint8));
   2697 
   2698     if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight == NULL) {
   2699         _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight =
   2700             sal_alloc(num_quality_map_profiles * sizeof(uint8),
   2701                     "hgt_lag_dlb_qsize_weight");
   2702         if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight == NULL) {
   2703             bcm_th2_hgt_lag_dlb_deinit(unit);
   2704             return BCM_E_MEMORY;
   2705         }
   2706     }
   2707     sal_memset(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight, 0,
   2708             num_quality_map_profiles * sizeof(uint8));
   2709 
   2710     /* Initialize port quality mapping profile */
   2711     rv = _bcm_th2_hgt_lag_dlb_quality_map_profile_init(unit);
   2712     if (BCM_FAILURE(rv)) {
   2713         bcm_th2_hgt_lag_dlb_deinit(unit);
   2714         return rv;
   2715     }
   2716 
   2717     if (!SOC_WARM_BOOT(unit)) {
   2718 
   2719         /* Set DLB sampling period and thresholds */
   2720         sample_rate = 62500;
   2721         rv = _bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set(unit, sample_rate,
   2722                 65536, (65536 * 7));
   2723         if (BCM_FAILURE(rv)) {
   2724             bcm_th2_hgt_lag_dlb_deinit(unit);
   2725             return rv;
   2726         }
   2727 
   2728         /* Configure HGT_LAG DLB load EWMA weight */
   2729         rv = bcm_th2_hgt_lag_dlb_config_set(unit,
   2730                 bcmSwitchTrunkDynamicEgressBytesExponent, 0);
   2731         if (BCM_FAILURE(rv)) {
   2732             bcm_th2_hgt_lag_dlb_deinit(unit);
   2733             return rv;
   2734         }
   2735 
   2736         /* Configure HGT_LAG DLB queue size EWMA weight */
   2737         if (!soc_feature(unit, soc_feature_td3_dlb)) {
   2738             rv = bcm_th2_hgt_lag_dlb_config_set(unit,
   2739                     bcmSwitchTrunkDynamicQueuedBytesExponent, 0);
   2740             if (BCM_FAILURE(rv)) {
   2741                 bcm_th2_hgt_lag_dlb_deinit(unit);
   2742                 return rv;
   2743             }
   2744         }
   2745 
   2746         /* Configure HGT_LAG DLB Physical queue size EWMA weight */
   2747         rv = bcm_th2_hgt_lag_dlb_config_set(unit,
   2748                 bcmSwitchTrunkDynamicPhysicalQueuedBytesExponent, 0);
   2749         if (BCM_FAILURE(rv)) {
   2750             bcm_th2_hgt_lag_dlb_deinit(unit);
   2751             return rv;
   2752         }
   2753 
   2754         /* Configure HGT_LAG DLB load cap control */
   2755         rv = bcm_th2_hgt_lag_dlb_config_set(unit,
   2756                 bcmSwitchTrunkDynamicEgressBytesDecreaseReset, 0);
   2757         if (BCM_FAILURE(rv)) {
   2758             bcm_th2_hgt_lag_dlb_deinit(unit);
   2759             return rv;
   2760         }
   2761 
   2762         /* Configure HGT_LAG DLB queue size cap control */
   2763         if (!soc_feature(unit, soc_feature_td3_dlb)) {
   2764             rv = bcm_th2_hgt_lag_dlb_config_set(unit,
   2765                     bcmSwitchTrunkDynamicQueuedBytesDecreaseReset, 0);
   2766             if (BCM_FAILURE(rv)) {
   2767                 bcm_th2_hgt_lag_dlb_deinit(unit);
   2768                 return rv;
   2769             }
   2770         }
   2771         /* Configure HGT_LAG DLB Physical queue size cap control */
   2772         rv = bcm_th2_hgt_lag_dlb_config_set(unit,
   2773                 bcmSwitchTrunkDynamicPhysicalQueuedBytesDecreaseReset, 0);
   2774         if (BCM_FAILURE(rv)) {
   2775             bcm_th2_hgt_lag_dlb_deinit(unit);
   2776             return rv;
   2777         }
   2778 
   2779         /* Configure HGT_LAG DLB queue size thresholds */
   2780         if (!soc_feature(unit, soc_feature_td3_dlb)) {
   2781             rv = _bcm_th2_hgt_lag_dlb_qsize_thresholds_set(unit, 0, 0);
   2782             if (BCM_FAILURE(rv)) {
   2783                 bcm_th2_hgt_lag_dlb_deinit(unit);
   2784                 return rv;
   2785             }
   2786         }
   2787 
   2788         /* Configure HGT_LAG DLB Physical queue size thresholds */
   2789         rv = _bcm_th2_hgt_lag_dlb_physical_qsize_thresholds_set(unit, 0, 0);
   2790         if (BCM_FAILURE(rv)) {
   2791             bcm_th2_hgt_lag_dlb_deinit(unit);
   2792             return rv;
   2793         }
   2794 
   2795         /* Disable link status override by software */
   2796         rv = soc_mem_clear(unit, DLB_HGT_LAG_LINK_CONTROLm, MEM_BLOCK_ALL, 0);
   2797         if (BCM_FAILURE(rv)) {
   2798             bcm_th2_hgt_lag_dlb_deinit(unit);
   2799             return rv;
   2800         }
   2801 
   2802         /* Clear group membership */
   2803         rv = soc_mem_clear(unit, DLB_HGT_LAG_GROUP_MEMBERSHIPm, MEM_BLOCK_ALL, 0);
   2804         if (BCM_FAILURE(rv)) {
   2805             bcm_th2_hgt_lag_dlb_deinit(unit);
   2806             return rv;
   2807         }
   2808 
   2809         /* Configure per member quality measure update control. */
   2810         mem = DLB_HGT_LAG_PORT_QUALITY_UPDATE_MEASURE_CONTROLm;
   2811         idx_min = soc_mem_index_min(unit, mem);
   2812         idx_max = soc_mem_index_max(unit, mem);
   2813         table_chunk = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem),
   2814                                     "DLB table buffer");
   2815         if (table_chunk == NULL) {
   2816             bcm_th2_hgt_lag_dlb_deinit(unit);
   2817             return BCM_E_MEMORY;
   2818         }
   2819 
   2820         sal_memset(table_chunk, 0, SOC_MEM_TABLE_BYTES(unit, mem));
   2821         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max,
   2822                                 table_chunk);
   2823         if (SOC_FAILURE(rv)) {
   2824             soc_cm_sfree(unit, table_chunk);
   2825             bcm_th2_hgt_lag_dlb_deinit(unit);
   2826             return rv;
   2827         }
   2828         for(port = idx_min; port <= idx_max; port++) {
   2829             table_entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
   2830                                                        table_chunk, port);
   2831             soc_mem_field32_set(unit, mem, table_entry,
   2832                                 ENABLE_MEASURE_AVERAGE_CALCULATIONf, 1);
   2833             soc_mem_field32_set(unit, mem, table_entry,
   2834                                 ENABLE_PORT_QUALITY_UPDATEf, 1);
   2835             soc_mem_field32_set(unit, mem, table_entry,
   2836                                 ENABLE_CREDIT_COLLECTIONf, 1);
   2837         }
   2838         rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max,
   2839                                  table_chunk);
   2840         if (SOC_FAILURE(rv)) {
   2841             soc_cm_sfree(unit, table_chunk);
   2842             bcm_th2_hgt_lag_dlb_deinit(unit);
   2843             return rv;
   2844         }
   2845         soc_cm_sfree(unit, table_chunk);
   2846 
   2847         /* Configure per member threshold scaling factor  */
   2848         mem = DLB_HGT_LAG_QUANTIZE_CONTROLm;
   2849         idx_min = soc_mem_index_min(unit, mem);
   2850         idx_max = soc_mem_index_max(unit, mem);
   2851         table_chunk = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem),
   2852                                     "DLB table buffer");
   2853         if (table_chunk == NULL) {
   2854             bcm_th2_hgt_lag_dlb_deinit(unit);
   2855             return BCM_E_MEMORY;
   2856         }
   2857 
   2858         sal_memset(table_chunk, 0, SOC_MEM_TABLE_BYTES(unit, mem));
   2859         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max,
   2860                                 table_chunk);
   2861         if (SOC_FAILURE(rv)) {
   2862             soc_cm_sfree(unit, table_chunk);
   2863             bcm_th2_hgt_lag_dlb_deinit(unit);
   2864             return rv;
   2865         }
   2866         for(port = idx_min; port <= idx_max; port++) {
   2867             table_entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
   2868                                                        table_chunk, port);
   2869             soc_mem_field32_set(unit, mem, table_entry,
   2870                                 PORT_LOADING_THRESHOLD_SCALING_FACTORf, 2);
   2871             soc_mem_field32_set(unit, mem, table_entry,
   2872                                 XPE_PORT_QSIZE_THRESHOLD_SCALING_FACTORf, 2);
   2873             if (!soc_feature(unit, soc_feature_td3_dlb)) {
   2874                 soc_mem_field32_set(unit, mem, table_entry,
   2875                                 TOTAL_PORT_QSIZE_THRESHOLD_SCALING_FACTORf, 2);
   2876             }
   2877         }
   2878         rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max,
   2879                                  table_chunk);
   2880         if (SOC_FAILURE(rv)) {
   2881             soc_cm_sfree(unit, table_chunk);
   2882             bcm_th2_hgt_lag_dlb_deinit(unit);
   2883             return rv;
   2884         }
   2885         soc_cm_sfree(unit, table_chunk);
   2886 
   2887         /* Configure Ethertype eligibility */
   2888 
   2889         rv = soc_mem_clear(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm,
   2890                 MEM_BLOCK_ALL, 0);
   2891         if (BCM_FAILURE(rv)) {
   2892             bcm_th2_hgt_lag_dlb_deinit(unit);
   2893             return rv;
   2894         }
   2895 #ifdef BCM_TRIDENT3_SUPPORT
   2896         if (soc_feature(unit, soc_feature_td3_dlb)) {
   2897             rv = READ_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr(unit,
   2898                     &reg_val);
   2899             if (BCM_SUCCESS(rv)) {
   2900                 soc_reg_field_set(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr,
   2901                         &reg_val, CONFIGURATIONf, 0);
   2902                 soc_reg_field_set(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr,
   2903                         &reg_val, INNER_OUTER_ETHERTYPE_SELECTIONf, 0);
   2904                 rv = WRITE_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr(unit,
   2905                         reg_val);
   2906             }
   2907         } else
   2908 #endif
   2909         {
   2910             rv = READ_DLB_HGT_LAG_EEM_CONFIGURATIONm(unit,
   2911                     MEM_BLOCK_ANY, 0, &eem_entry);
   2912             if (BCM_SUCCESS(rv)) {
   2913                 soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_set(unit,
   2914                         &eem_entry,
   2915                         CONFIGURATIONf,
   2916                         0);
   2917                 soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_set(unit,
   2918                         &eem_entry,
   2919                         INNER_OUTER_ETHERTYPE_SELECTIONf,
   2920                         0);
   2921                 rv = WRITE_DLB_HGT_LAG_EEM_CONFIGURATIONm(unit,
   2922                         MEM_BLOCK_ALL, 0, &eem_entry);
   2923             }
   2924         }
   2925         if (BCM_FAILURE(rv)) {
   2926             bcm_th2_hgt_lag_dlb_deinit(unit);
   2927             return rv;
   2928         }
   2929     }
   2930 
   2931     /* Write HGT/LAG selection*/
   2932     if (soc_feature(unit, soc_feature_hg_dlb)) {
   2933         rv = soc_reg_field32_modify(unit,
   2934                 DLB_HGT_LAG_SELECTIONr, REG_PORT_ANY, SELECTION_HGT_LAGf, 0);
   2935     } else {
   2936         rv = soc_reg_field32_modify(unit,
   2937                 DLB_HGT_LAG_SELECTIONr, REG_PORT_ANY, SELECTION_HGT_LAGf, 1);
   2938     }
   2939     if (BCM_FAILURE(rv)) {
   2940         bcm_th2_hgt_lag_dlb_deinit(unit);
   2941         return rv;
   2942     }
   2943 
   2944     /* Write XPE pipe selector, if set represents XPE A */
   2945     if (!soc_feature(unit, soc_feature_td3_dlb)) {
   2946         for (pipe = 0; pipe < NUM_PIPE(unit); pipe ++) {
   2947             reg = SOC_REG_UNIQUE_ACC(unit, DLB_HGT_LAG_PORT_XPE_A_B_SELECTORr)[pipe];
   2948             rv = soc_reg_field32_modify(unit, reg,
   2949                     REG_PORT_ANY, CAP_SINGLE_QSIZE_SELECTORf, qsize_sel[pipe]);
   2950             if (BCM_FAILURE(rv)) {
   2951                 bcm_th2_hgt_lag_dlb_deinit(unit);
   2952                 return rv;
   2953             }
   2954         }
   2955     }
   2956 
   2957     READ_AUX_ARB_CONTROLr(unit,&rval);
   2958     if (soc_reg_field_valid(unit, AUX_ARB_CONTROLr,
   2959                 DLB_HGT_256NS_REFRESH_ENABLEf)) {
   2960         soc_reg_field_set(unit, AUX_ARB_CONTROLr, &rval,
   2961                 DLB_HGT_256NS_REFRESH_ENABLEf, 1);
   2962     }
   2963     WRITE_AUX_ARB_CONTROLr(unit,rval);
   2964 
   2965     return rv;
   2966 }
   2967 
   2968 
   2969 #ifdef BCM_WARM_BOOT_SUPPORT
   2970 
   2971 /*
   2972  * Function:
   2973  *      bcm_th2_hgt_lag_dlb_wb_alloc_size_get
   2974  * Purpose:
   2975  *      Get level 2 warm boot scache size for HGT_LAG DLB.
   2976  * Parameters:
   2977  *      unit - (IN) SOC unit number.
   2978  *      size - (OUT) Allocation size.
   2979  * Returns:
   2980  *      BCM_E_XXX
   2981  */
   2982 int
   2983 bcm_th2_hgt_lag_dlb_wb_alloc_size_get(int unit, int *size)
   2984 {
   2985     int alloc_size = 0;
   2986     int num_elements;
   2987 
   2988     /* Allocate size for the following HGT_LAG DLB parameters:
   2989      * int hgt_lag_dlb_sample_rate;
   2990      * int hgt_lag_dlb_tx_load_min_th;
   2991      * int hgt_lag_dlb_tx_load_max_th;
   2992      * int hgt_lag_dlb_qsize_min_th;
   2993      * int hgt_lag_dlb_qsize_max_th;
   2994      * int hgt_lag_dlb_physical_qsize_min_th;
   2995      * int hgt_lag_dlb_physical_qsize_max_th;
   2996      */
   2997     alloc_size += sizeof(int) * 7;
   2998 
   2999     /* Allocate size of hgt_lag_dlb_load_weight & hgt_lag_dlb_qsize_weight array */
   3000     num_elements = 1 << soc_mem_field_length(unit,
   3001             DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf);
   3002     alloc_size += sizeof(uint8) * 2 * num_elements;
   3003 
   3004     *size = alloc_size;
   3005 
   3006     return BCM_E_NONE;
   3007 }
   3008 
   3009 /*
   3010  * Function:
   3011  *      bcm_th2_hgt_lag_dlb_sync
   3012  * Purpose:
   3013  *      Store HGT_LAG DLB parameters into scache.
   3014  * Parameters:
   3015  *      unit - (IN) SOC unit number.
   3016  *      scache_ptr - (IN/OUT) Scache pointer
   3017  * Returns:
   3018  *      BCM_E_XXX
   3019  */
   3020 int
   3021 bcm_th2_hgt_lag_dlb_sync(int unit, uint8 **scache_ptr)
   3022 {
   3023     int value;
   3024     int num_elements;
   3025     int i;
   3026     uint8 load_weight;
   3027     uint8 qsize_weight;
   3028 
   3029     /* Store the following HGT_LAG DLB parameters:
   3030      * int hgt_lag_dlb_sample_rate;
   3031      * int hgt_lag_dlb_tx_load_min_th;
   3032      * int hgt_lag_dlb_tx_load_max_th;
   3033      * int hgt_lag_dlb_qsize_min_th;
   3034      * int hgt_lag_dlb_qsize_max_th;
   3035      * int hgt_lag_dlb_physical_qsize_min_th;
   3036      * int hgt_lag_dlb_physical_qsize_max_th;
   3037      */
   3038     value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate;
   3039     sal_memcpy((*scache_ptr), &value, sizeof(int));
   3040     (*scache_ptr) += sizeof(int);
   3041 
   3042     value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th;
   3043     sal_memcpy((*scache_ptr), &value, sizeof(int));
   3044     (*scache_ptr) += sizeof(int);
   3045 
   3046     value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th;
   3047     sal_memcpy((*scache_ptr), &value, sizeof(int));
   3048     (*scache_ptr) += sizeof(int);
   3049 
   3050     value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th;
   3051     sal_memcpy((*scache_ptr), &value, sizeof(int));
   3052     (*scache_ptr) += sizeof(int);
   3053 
   3054     value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th;
   3055     sal_memcpy((*scache_ptr), &value, sizeof(int));
   3056     (*scache_ptr) += sizeof(int);
   3057 
   3058     value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th;
   3059     sal_memcpy((*scache_ptr), &value, sizeof(int));
   3060     (*scache_ptr) += sizeof(int);
   3061 
   3062     value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th;
   3063     sal_memcpy((*scache_ptr), &value, sizeof(int));
   3064     (*scache_ptr) += sizeof(int);
   3065 
   3066     /* Store hgt_lag_dlb_load_weight & hgt_lag_dlb_qsize_weight array */
   3067     num_elements = 1 << soc_mem_field_length(unit,
   3068             DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf);
   3069     for (i = 0; i < num_elements; i++) {
   3070         load_weight = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[i];
   3071         qsize_weight = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[i];
   3072         sal_memcpy((*scache_ptr), &load_weight, sizeof(uint8));
   3073         (*scache_ptr) += sizeof(uint8);
   3074         sal_memcpy((*scache_ptr), &qsize_weight, sizeof(uint8));
   3075         (*scache_ptr) += sizeof(uint8);
   3076     }
   3077 
   3078     return BCM_E_NONE;
   3079 }
   3080 
   3081 /*
   3082  * Function:
   3083  *      bcm_th2_hgt_lag_dlb_scache_recover
   3084  * Purpose:
   3085  *      Recover HGT_LAG DLB parameters from scache.
   3086  * Parameters:
   3087  *      unit - (IN) SOC unit number.
   3088  *      scache_ptr - (IN/OUT) Scache pointer
   3089  * Returns:
   3090  *      BCM_E_XXX
   3091  */
   3092 int
   3093 bcm_th2_hgt_lag_dlb_scache_recover(int unit, uint8 **scache_ptr)
   3094 {
   3095     int value;
   3096     int num_elements;
   3097     int i;
   3098     uint8 load_weight;
   3099     uint8 qsize_weight;
   3100 
   3101     /* Recover the following HGT_LAG DLB parameters:
   3102      * int hgt_lag_dlb_sample_rate;
   3103      * int hgt_lag_dlb_tx_load_min_th;
   3104      * int hgt_lag_dlb_tx_load_max_th;
   3105      * int hgt_lag_dlb_qsize_min_th;
   3106      * int hgt_lag_dlb_qsize_max_th;
   3107      * int hgt_lag_dlb_physical_qsize_min_th;
   3108      * int hgt_lag_dlb_physical_qsize_max_th;
   3109      */
   3110     sal_memcpy(&value, (*scache_ptr), sizeof(int));
   3111     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate = value;
   3112     (*scache_ptr) += sizeof(int);
   3113 
   3114     sal_memcpy(&value, (*scache_ptr), sizeof(int));
   3115     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th = value;
   3116     (*scache_ptr) += sizeof(int);
   3117 
   3118     sal_memcpy(&value, (*scache_ptr), sizeof(int));
   3119     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th = value;
   3120     (*scache_ptr) += sizeof(int);
   3121 
   3122     sal_memcpy(&value, (*scache_ptr), sizeof(int));
   3123     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th = value;
   3124     (*scache_ptr) += sizeof(int);
   3125 
   3126     sal_memcpy(&value, (*scache_ptr), sizeof(int));
   3127     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th = value;
   3128     (*scache_ptr) += sizeof(int);
   3129 
   3130     sal_memcpy(&value, (*scache_ptr), sizeof(int));
   3131     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th = value;
   3132     (*scache_ptr) += sizeof(int);
   3133 
   3134     sal_memcpy(&value, (*scache_ptr), sizeof(int));
   3135     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th = value;
   3136     (*scache_ptr) += sizeof(int);
   3137 
   3138     /* Recover hgt_lag_dlb_load_weight & hgt_lag_dlb_qsize_weight array */
   3139     num_elements = 1 << soc_mem_field_length(unit,
   3140             DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf);
   3141     for (i = 0; i < num_elements; i++) {
   3142         sal_memcpy(&load_weight, (*scache_ptr), sizeof(uint8));
   3143         HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[i] = load_weight;
   3144         (*scache_ptr) += sizeof(uint8);
   3145         sal_memcpy(&qsize_weight, (*scache_ptr), sizeof(uint8));
   3146         HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[i] = qsize_weight;
   3147         (*scache_ptr) += sizeof(uint8);
   3148     }
   3149 
   3150     HGT_LAG_DLB_INFO(unit)->recovered_from_scache = TRUE;
   3151 
   3152     return BCM_E_NONE;
   3153 }
   3154 
   3155 /*
   3156  * Function:
   3157  *      bcm_th2_hgt_lag_dlb_group_recover
   3158  * Purpose:
   3159  *      Recover HGT_LAG DLB group usage and flowset table usage.
   3160  * Parameters:
   3161  *      unit - (IN) SOC unit number.
   3162  *      tid  - (IN) Trunk/HiGig Trunk group ID.
   3163  *      hgt  - (IN) Is HiGig Trunk
   3164  *      trunk_info - (OUT) Per trunk group DLB info.
   3165  * Returns:
   3166  *      BCM_E_XXX
   3167  */
   3168 int
   3169 bcm_th2_hgt_lag_dlb_group_recover(int unit, bcm_trunk_t tid, int hgt,
   3170                                   trunk_private_t *trunk_info)
   3171 {
   3172     hgt_dlb_control_entry_t hgt_dlb_control_entry;
   3173     lag_dlb_control_entry_t lag_dlb_control_entry;
   3174     int dlb_enable, dlb_id;
   3175     dlb_hgt_lag_group_control_entry_t group_control_entry;
   3176     int dlb_mode;
   3177     int dynamic_size_encode, dynamic_size;
   3178     int entry_base_ptr;
   3179     int block_base_ptr, num_blocks;
   3180 
   3181     if (hgt) {
   3182         BCM_IF_ERROR_RETURN
   3183             (READ_HGT_DLB_CONTROLm(unit, MEM_BLOCK_ANY,
   3184                                   tid, &hgt_dlb_control_entry));
   3185         dlb_enable = soc_HGT_DLB_CONTROLm_field32_get
   3186                         (unit, &hgt_dlb_control_entry, GROUP_ENABLEf);
   3187         dlb_id = soc_HGT_DLB_CONTROLm_field32_get
   3188                         (unit, &hgt_dlb_control_entry, DLB_IDf);
   3189     } else {
   3190         BCM_IF_ERROR_RETURN
   3191             (READ_LAG_DLB_CONTROLm(unit, MEM_BLOCK_ANY,
   3192                                    tid, &lag_dlb_control_entry));
   3193         dlb_enable = soc_LAG_DLB_CONTROLm_field32_get
   3194                             (unit, &lag_dlb_control_entry, GROUP_ENABLEf);
   3195         dlb_id = soc_LAG_DLB_CONTROLm_field32_get
   3196                             (unit, &lag_dlb_control_entry, DLB_IDf);
   3197     }
   3198     if (0 == dlb_enable) {
   3199         /* DLB not enabled */
   3200         return BCM_E_NONE;
   3201     }
   3202 
   3203     /* Mark DLB group ID as used */
   3204     _BCM_HGT_LAG_DLB_ID_USED_SET(unit, dlb_id);
   3205 
   3206     BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_GROUP_CONTROLm(unit,
   3207                 MEM_BLOCK_ANY, dlb_id, &group_control_entry));
   3208 
   3209     /* Recover DLB mode */
   3210     dlb_mode = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit,
   3211             &group_control_entry, PORT_ASSIGNMENT_MODEf);
   3212     switch (dlb_mode) {
   3213         case 0:
   3214             trunk_info->psc = BCM_TRUNK_PSC_DYNAMIC;
   3215             break;
   3216         case 1:
   3217             trunk_info->psc = BCM_TRUNK_PSC_DYNAMIC_ASSIGNED;
   3218             break;
   3219         case 2:
   3220             trunk_info->psc = BCM_TRUNK_PSC_DYNAMIC_OPTIMAL;
   3221             break;
   3222         default:
   3223             return BCM_E_INTERNAL;
   3224     }
   3225 
   3226     /* Recover dynamic_size */
   3227     dynamic_size_encode = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit,
   3228             &group_control_entry, FLOW_SET_SIZEf);
   3229     BCM_IF_ERROR_RETURN
   3230         (_bcm_th2_hgt_lag_dlb_dynamic_size_decode(dynamic_size_encode,
   3231                                               &dynamic_size));
   3232     trunk_info->dynamic_size = dynamic_size;
   3233 
   3234     /* Recover dynamic_age */
   3235     trunk_info->dynamic_age = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit,
   3236             &group_control_entry, INACTIVITY_DURATIONf);
   3237 
   3238     /* Recover flow set table usage */
   3239     entry_base_ptr = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit,
   3240             &group_control_entry, FLOW_SET_BASEf);
   3241     block_base_ptr = entry_base_ptr >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT;
   3242     num_blocks = dynamic_size >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT;
   3243     _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_SET_RANGE(unit, block_base_ptr,
   3244             num_blocks);
   3245 
   3246     return BCM_E_NONE;
   3247 }
   3248 
   3249 /*
   3250  * Function:
   3251  *      bcm_th2_hgt_lag_dlb_quality_parameters_recover
   3252  * Purpose:
   3253  *      Recover HGT_LAG DLB parameters used to derive a member's quality.
   3254  * Parameters:
   3255  *      unit - (IN) SOC unit number.
   3256  * Returns:
   3257  *      BCM_E_XXX
   3258  */
   3259 int
   3260 bcm_th2_hgt_lag_dlb_quality_parameters_recover(int unit)
   3261 {
   3262     uint32 measure_control_reg;
   3263     int num_time_units;
   3264     dlb_hgt_lag_glb_quantize_threshold_entry_t quantize_threshold_entry;
   3265     int min_th_bytes, min_th_cells;
   3266     int max_th_bytes, max_th_cells;
   3267     int entries_per_profile;
   3268     int profile_ptr, base_index;
   3269     dlb_hgt_lag_port_quality_mapping_entry_t quality_mapping_entry;
   3270     int quality;
   3271     int num_profile;
   3272 
   3273     if (HGT_LAG_DLB_INFO(unit)->recovered_from_scache) {
   3274         /* If already recovered from scache, do nothing. */
   3275         return BCM_E_NONE;
   3276     }
   3277 
   3278     /* Recover sampling rate */
   3279     BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit,
   3280                 &measure_control_reg));
   3281     num_time_units = soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr,
   3282             measure_control_reg, SAMPLING_PERIODf);
   3283     if (num_time_units > 0) {
   3284         HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate = 1000000 / num_time_units;
   3285     }
   3286 
   3287     /* Recover min and max load, queue size and Physical queue size thresholds:
   3288      * Load threshold (in mbps)
   3289      *     = (bytes per sampling period) * 8 bits per byte /
   3290      *       (sampling period in seconds) / 10^6
   3291      *     = (bytes per sampling period) * 8 bits per byte /
   3292      *       (num_time_units * 1 us per time unit * 10^-6) / 10^6
   3293      *     = (bytes per sampling period) * 8 / num_time_units
   3294      */
   3295     BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit,
   3296                 MEM_BLOCK_ANY, 0, &quantize_threshold_entry));
   3297     min_th_bytes = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get
   3298         (unit, &quantize_threshold_entry, PORT_LOADING_THRESHOLDf);
   3299     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th = (min_th_bytes << 3) /
   3300         num_time_units;
   3301 
   3302     if (!soc_feature(unit, soc_feature_td3_dlb)) {
   3303         min_th_cells = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get
   3304             (unit, &quantize_threshold_entry, TOTAL_PORT_QSIZE_THRESHOLDf);
   3305         HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th =
   3306             min_th_cells * _BCM_HGT_LAG_DLB_CELL_BYTES;
   3307     }
   3308 
   3309     min_th_cells = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get
   3310         (unit, &quantize_threshold_entry, XPE_PORT_QSIZE_THRESHOLDf);
   3311     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th =
   3312         min_th_cells * _BCM_HGT_LAG_DLB_CELL_BYTES;
   3313 
   3314     BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit,
   3315                 MEM_BLOCK_ANY, soc_mem_index_max(unit,
   3316                     DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm),
   3317                 &quantize_threshold_entry));
   3318     max_th_bytes = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get
   3319         (unit, &quantize_threshold_entry, PORT_LOADING_THRESHOLDf);
   3320     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th = (max_th_bytes << 3) /
   3321         num_time_units;
   3322 
   3323     if (!soc_feature(unit, soc_feature_td3_dlb)) {
   3324         max_th_cells = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get
   3325             (unit, &quantize_threshold_entry, TOTAL_PORT_QSIZE_THRESHOLDf);
   3326         HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th =
   3327             max_th_cells * _BCM_HGT_LAG_DLB_CELL_BYTES;
   3328     }
   3329 
   3330     max_th_cells = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get
   3331         (unit, &quantize_threshold_entry, XPE_PORT_QSIZE_THRESHOLDf);
   3332     HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th =
   3333         max_th_cells * _BCM_HGT_LAG_DLB_CELL_BYTES;
   3334 
   3335     /* Recover load weights and qsize weights */
   3336     num_profile = 1 << soc_mem_field_length(unit, DLB_HGT_LAG_QUANTIZE_CONTROLm,
   3337                                             PORT_QUALITY_MAPPING_PROFILE_PTRf);
   3338     entries_per_profile =
   3339         soc_mem_index_count(unit, DLB_HGT_LAG_PORT_QUALITY_MAPPINGm) / num_profile;
   3340     for (profile_ptr = 0; profile_ptr < num_profile; profile_ptr++) {
   3341         base_index = profile_ptr * entries_per_profile;
   3342         /* quality = (quantized_tx_load * tx_load_percent +
   3343          *            quantized_qsize * qsize_percent +
   3344          *            quantized_physical_qsize *
   3345          *            (100 - tx_load_percent - qsize_percent)) / 100;
   3346          * The index to DLB_HGT_LAG_PORT_QUALITY_MAPPING table consists of
   3347          * base_index + quantized_tx_load * 64 +
   3348          * quantized_qsize * 8 + quantized_physical_qsize,
   3349          * where quantized_tx_load, quantized_qsize and quantized_physical_qsize
   3350          * range from 0 to 7.
   3351          *
   3352          * With quantized_tx_load = 7, quantized_qsize = quantized_physical_qsize = 0,
   3353          * the index to DLB_HGT_LAG_PORT_QUALITY_MAPPING table is
   3354          * base_index + 448, and the tx_load_percent expression
   3355          * simplifies to quality * 100 / 7;
   3356          *
   3357          * With quantized_qsize = 7, quantized_tx_load = quantized_physical_qsize = 0,
   3358          * the index to DLB_HGT_LAG_PORT_QUALITY_MAPPING table is
   3359          * base_index + 56, and the qsize_percent expression
   3360          * simplifies to quality * 100 / 7;
   3361          */
   3362         BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_PORT_QUALITY_MAPPINGm(unit,
   3363                     MEM_BLOCK_ANY, base_index + 448,
   3364                     &quality_mapping_entry));
   3365         quality = soc_DLB_HGT_LAG_PORT_QUALITY_MAPPINGm_field32_get(unit,
   3366                 &quality_mapping_entry, ASSIGNED_QUALITYf);
   3367         HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[profile_ptr] =
   3368             quality * 100 / 7;
   3369         BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_PORT_QUALITY_MAPPINGm(unit,
   3370                     MEM_BLOCK_ANY, base_index + 56,
   3371                     &quality_mapping_entry));
   3372         quality = soc_DLB_HGT_LAG_PORT_QUALITY_MAPPINGm_field32_get(unit,
   3373                 &quality_mapping_entry, ASSIGNED_QUALITYf);
   3374         HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[profile_ptr] =
   3375             quality * 100 / 7;
   3376     }
   3377 
   3378     return BCM_E_NONE;
   3379 }
   3380 
   3381 #endif /* BCM_WARM_BOOT_SUPPORT */
   3382 
   3383 #ifndef BCM_SW_STATE_DUMP_DISABLE
   3384 
   3385 /*
   3386  * Function:
   3387  *     bcm_th2_hgt_lag_dlb_sw_dump
   3388  * Purpose:
   3389  *     Displays HGT_LAG DLB information maintained by software.
   3390  * Parameters:
   3391  *     unit - Device unit number
   3392  * Returns:
   3393  *     None
   3394  */
   3395 void
   3396 bcm_th2_hgt_lag_dlb_sw_dump(int unit)
   3397 {
   3398     int i;
   3399     int num_entries_per_profile;
   3400     int num_profiles;
   3401     int rv;
   3402     int ref_count;
   3403 
   3404     LOG_CLI((BSL_META_U(unit,
   3405                         "HGT_LAG DLB Info -\n")));
   3406 
   3407     /* Print HGT_LAG DLB group usage */
   3408     LOG_CLI((BSL_META_U(unit,
   3409                         "    HGT_LAG DLB Groups Used:")));
   3410     for (i = 0; i < soc_mem_index_count(unit, DLB_HGT_LAG_GROUP_CONTROLm); i++) {
   3411         if (_BCM_HGT_LAG_DLB_ID_USED_GET(unit, i)) {
   3412             LOG_CLI((BSL_META_U(unit,
   3413                                 " %d"), i));
   3414         }
   3415     }
   3416     LOG_CLI((BSL_META_U(unit,
   3417                         "\n")));
   3418 
   3419     /* Print HGT_LAG DLB flowset table usage */
   3420     LOG_CLI((BSL_META_U(unit,
   3421                         "    HGT_LAG DLB Flowset Table Blocks Used:")));
   3422     for (i = 0; i < soc_mem_index_count(unit, DLB_HGT_LAG_FLOWSETm) >>
   3423                     _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT; i++) {
   3424         if (_BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_GET(unit, i)) {
   3425             LOG_CLI((BSL_META_U(unit,
   3426                                 " %d"), i));
   3427         }
   3428     }
   3429     LOG_CLI((BSL_META_U(unit,
   3430                         "\n")));
   3431 
   3432     /* Print sample rate and threshold parameters */
   3433     LOG_CLI((BSL_META_U(unit,
   3434                         "    Sample rate: %d per second\n"),
   3435              HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate));
   3436     LOG_CLI((BSL_META_U(unit,
   3437                         "    Tx load min threshold: %d mbps\n"),
   3438              HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th));
   3439     LOG_CLI((BSL_META_U(unit,
   3440                         "    Tx load max threshold: %d mbps\n"),
   3441              HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th));
   3442     LOG_CLI((BSL_META_U(unit,
   3443                         "    Queue size min threshold: %d cells\n"),
   3444              HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th));
   3445     LOG_CLI((BSL_META_U(unit,
   3446                         "    Queue size max threshold: %d cells\n"),
   3447              HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th));
   3448     LOG_CLI((BSL_META_U(unit,
   3449                         "    Physical Queue size min threshold: %d cells\n"),
   3450              HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th));
   3451     LOG_CLI((BSL_META_U(unit,
   3452                         "    Physical Queue size max threshold: %d cells\n"),
   3453              HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th));
   3454 
   3455     /* Print quality mapping profiles */
   3456     LOG_CLI((BSL_META_U(unit,
   3457                         "    Quality mapping profiles:\n")));
   3458 
   3459     num_profiles = 1 << soc_mem_field_length(unit, DLB_HGT_LAG_QUANTIZE_CONTROLm,
   3460                                              PORT_QUALITY_MAPPING_PROFILE_PTRf);
   3461     num_entries_per_profile = soc_mem_index_count(unit, DLB_HGT_LAG_PORT_QUALITY_MAPPINGm)/
   3462                               num_profiles;
   3463     for (i = 0; i < num_profiles; i++) {
   3464         LOG_CLI((BSL_META_U(unit,
   3465                             "      Profile %d: load weight %d percent, "\
   3466                             "qsize weight %d percent, "),
   3467                  i, HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[i],
   3468                  HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[i]));
   3469         rv = soc_profile_mem_ref_count_get(unit,
   3470                 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_quality_map_profile,
   3471                 i * num_entries_per_profile, &ref_count);
   3472         if (BCM_FAILURE(rv)) {
   3473             LOG_CLI((BSL_META_U(unit,
   3474                                 "\n")));
   3475             continue;
   3476         }
   3477         LOG_CLI((BSL_META_U(unit,
   3478                             "ref count %d\n"), ref_count));
   3479     }
   3480 
   3481     return;
   3482 }
   3483 
   3484 #endif /* BCM_SW_STATE_DUMP_DISABLE */
   3485 
   3486 
   3487 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */
   3488 
   3489