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

l3.c (56999B)


      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:        l3.c
      8  * Purpose:     Trident L3 function implementations
      9  */
     10 
     11 
     12 #include <soc/defs.h>
     13 
     14 #include <assert.h>
     15 
     16 #include <sal/core/libc.h>
     17 #if defined(BCM_TRIDENT_SUPPORT)  && defined(INCLUDE_L3)
     18 
     19 #include <shared/util.h>
     20 #include <soc/mem.h>
     21 #include <soc/cm.h>
     22 #include <soc/drv.h>
     23 #include <soc/register.h>
     24 #include <soc/memory.h>
     25 #include <soc/l3x.h>
     26 #include <soc/lpm.h>
     27 #include <soc/tnl_term.h>
     28 
     29 #include <bcm/l3.h>
     30 #include <bcm/tunnel.h>
     31 #include <bcm/debug.h>
     32 #include <bcm/error.h>
     33 #include <bcm/stack.h>
     34 
     35 #include <bcm_int/esw/mbcm.h>
     36 #include <bcm_int/esw/firebolt.h>
     37 #include <bcm_int/esw/trx.h>
     38 #include <bcm_int/esw/trident.h>
     39 #if defined(BCM_TRIUMPH2_SUPPORT)
     40 #include <bcm_int/esw/triumph2.h>
     41 #endif /* BCM_TRIUMPH2_SUPPORT */
     42 #if defined(BCM_TOMAHAWK_SUPPORT)
     43 #include <bcm_int/esw/tomahawk.h>
     44 #endif /* BCM_TOMAHAWK_SUPPORT */
     45 #if defined(BCM_TRIDENT3_SUPPORT)
     46 #include <bcm_int/esw/trident3.h>
     47 #endif /* BCM_TOMAHAWK_SUPPORT */
     48 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
     49 #include <bcm_int/esw/trident2plus.h>
     50 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
     51 #include <bcm_int/esw/l3.h>
     52 #include <bcm_int/esw/xgs3.h>
     53 
     54 #include <bcm_int/esw_dispatch.h>
     55 
     56 extern int ecmp_mode_hierarchical;
     57 extern int ecmp_mode_single;
     58 
     59 /*
     60  * Function:
     61  *      _bcm_td_l3_ecmp_grp_get
     62  * Purpose:
     63  *      Get ecmp group next hop members by index.
     64  * Parameters:
     65  *      unit       - (IN)SOC unit number.
     66  *      ecmp_grp - (IN)Ecmp group id to read. 
     67  *      ecmp_count - (IN)Maximum number of entries to read.
     68  *      nh_idx     - (OUT)Next hop indexes. 
     69  * Returns:
     70  *      BCM_E_XXX
     71  */
     72 int
     73 _bcm_td_l3_ecmp_grp_get (int unit, int ecmp_grp, int ecmp_group_size, int *nh_idx)
     74 {
     75     int idx; /* Iteration index. */
     76     int max_ent_count=0; /* Number of entries to read.*/
     77     uint32 hw_buf[SOC_MAX_MEM_FIELD_WORDS]; /* Buffer to read hw entry. */
     78     int one_entry_grp = TRUE; /* Single next hop entry group.  */ 
     79     int rv = BCM_E_UNAVAIL; /* Operation return status.  */
     80     int ecmp_idx = 0;
     81     char *l3_ecmp_tbl_ptr; /* Dma L3 ECMP table pointer. */
     82     uint32 *ecmp_entry_ptr = NULL; /* ECMP entry pointer.*/
     83     uint32 dest_type = SOC_MEM_FIF_DEST_INVALID;
     84 
     85     /* Input parameters sanity check. */
     86     if ((NULL == nh_idx) || (ecmp_group_size < 1)) {
     87          return (BCM_E_PARAM);
     88     }
     89 
     90 
     91     /* Zero all next hop indexes first. */
     92     sal_memset(nh_idx, 0, ecmp_group_size * sizeof(int));
     93     sal_memset(hw_buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
     94 
     95     /* Calculate Base_ptr table index. */
     96     if (SOC_MEM_IS_VALID(unit, L3_ECMP_COUNTm)) {
     97         BCM_IF_ERROR_RETURN(
     98             _bcm_xgs3_l3_ecmp_grp_info_get(unit, ecmp_grp,
     99                                            &max_ent_count, &ecmp_idx));
    100 
    101     }
    102 
    103     if (max_ent_count > L3_ECMP_MEM_DMA_THRESHOLD) {
    104         rv = bcm_xgs3_l3_tbl_range_dma(unit, L3_ECMPm, sizeof(ecmp_entry_t),
    105                                        "l3_ecmp_tbl", ecmp_idx,
    106                                        ecmp_idx + max_ent_count - 1,
    107                                        &l3_ecmp_tbl_ptr);
    108         BCM_IF_ERROR_RETURN(rv);
    109     }
    110 
    111     /* Read all the indexes from hw. */
    112     for (idx = 0; idx < max_ent_count; idx++) {
    113 
    114          /* Read next hop index. */
    115          if (max_ent_count > L3_ECMP_MEM_DMA_THRESHOLD) {
    116              ecmp_entry_ptr =
    117                  soc_mem_table_idx_to_pointer(unit, L3_ECMPm, uint32 *,
    118                                               l3_ecmp_tbl_ptr, idx);
    119          } else {
    120              rv = soc_mem_read(unit, L3_ECMPm, MEM_BLOCK_ANY,
    121                                  (ecmp_idx + idx), hw_buf);
    122              if (rv < 0) {
    123                   break;
    124              }
    125              ecmp_entry_ptr = hw_buf;
    126          }
    127          if (SOC_IS_TRIDENT3X(unit)) {
    128              nh_idx[idx] = soc_mem_field32_dest_get(unit, L3_ECMPm, ecmp_entry_ptr,
    129                                           DESTINATIONf, &dest_type);
    130          } else {
    131              nh_idx[idx] = soc_mem_field32_get(unit, L3_ECMPm,
    132                                           ecmp_entry_ptr, NEXT_HOP_INDEXf);
    133          }
    134 #ifdef BCM_TOMAHAWK_SUPPORT
    135          /* Calculate the multipath intf index if ecmp member is a group id */
    136          if (soc_feature(unit, soc_feature_hierarchical_ecmp)) {
    137              /* Read ecmp flag and check if NH index is a group id */
    138              if (SOC_IS_TRIDENT3X(unit)) {
    139                  if (dest_type == SOC_MEM_FIF_DEST_ECMP) {
    140                      nh_idx[idx] += BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
    141                  }
    142              } else if (soc_feature(unit, soc_feature_l3_ecmp_hier_tbl)) {
    143                  if (BCM_XGS3_L3_TBL(unit, ecmp_info).ecmp_mode ==
    144                                          ecmp_mode_hierarchical) {
    145                      if ((nh_idx[idx]) &&
    146                          (ecmp_idx < (BCM_XGS3_L3_ECMP_TBL_SIZE(unit) / 2))) {
    147                          nh_idx[idx] += BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
    148                      }
    149                  }
    150              } else if (soc_mem_field32_get(unit, L3_ECMPm,
    151                                             ecmp_entry_ptr, ECMP_FLAGf)) {
    152                  nh_idx[idx] += BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
    153              }
    154          }
    155 #endif /* BCM_TOMAHAWK_SUPPORT */
    156 
    157 #ifdef BCM_MULTI_LEVEL_ECMP_SUPPORT
    158          /* Calculate the multipath intf index if ecmp member is a group id */
    159          if (soc_feature(unit, soc_feature_multi_level_ecmp)) {
    160              /* Read ecmp flag and check if NH index is a group id */
    161 #ifdef BCM_TRIDENT3_SUPPORT
    162              if (SOC_IS_TRIDENT3X(unit)) {
    163                  if (dest_type == SOC_MEM_FIF_DEST_ECMP) {
    164                      nh_idx[idx] += BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
    165                  }
    166              } else 
    167 #endif
    168              if (soc_mem_field32_get(unit, L3_ECMPm,
    169                                             ecmp_entry_ptr, ECMPf)) {
    170                  nh_idx[idx] += BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
    171              }
    172          }
    173 #endif /* BCM_MULTI_LEVEL_ECMP_SUPPORT */
    174 
    175 
    176          /* Check if group contains . */ 
    177          if (idx && (nh_idx[idx] != nh_idx[0])) { 
    178               one_entry_grp = FALSE;
    179          }
    180 
    181         if (0 == soc_feature(unit, soc_feature_l3_dynamic_ecmp_group)) {
    182             /* Next hops popuplated in cycle,stop once you read first entry again */
    183             if (idx && (FALSE == one_entry_grp) && (nh_idx[idx] == nh_idx[0])) {
    184                 nh_idx[idx] = 0;
    185                 break;
    186             }
    187         } else {
    188              one_entry_grp = FALSE;
    189         }
    190     }
    191     /* Reset rest of the group if only 1 next hop is present. */
    192     if (one_entry_grp) {
    193          sal_memset(nh_idx + 1, 0, (ecmp_group_size - 1) * sizeof(int)); 
    194     }
    195     if (max_ent_count > L3_ECMP_MEM_DMA_THRESHOLD) {
    196         soc_cm_sfree(unit, l3_ecmp_tbl_ptr);
    197     }
    198     return rv;
    199 }
    200 
    201 
    202 /*
    203  * Function:
    204  *      _bcm_td_l3_ecmp_grp_add
    205  * Purpose:
    206  *      Add ecmp group next hop members, or reset ecmp group entry.  
    207  *      NOTE: Function always writes all the entries in ecmp group.
    208  *            If there is not enough nh indexes - next hops written
    209  *            in cycle. 
    210  * Parameters:
    211  *      unit       - (IN)SOC unit number.
    212  *      ecmp_grp   - (IN)ecmp group id to write.
    213  *      buf        - (IN)Next hop indexes or NULL for entry reset.
    214  *      info       - (IN)ECMP additional info
    215  * Returns:
    216  *      BCM_E_XXX
    217  */
    218 int
    219 _bcm_td_l3_ecmp_grp_add (int unit, int ecmp_grp, void *buf, void *info)
    220 {
    221     uint32 l3_ecmp[SOC_MAX_MEM_FIELD_WORDS];
    222     uint32 initial_l3_ecmp[SOC_MAX_MEM_FIELD_WORDS];
    223     uint32 l3_ecmp_count[SOC_MAX_MEM_FIELD_WORDS];
    224     uint32 hw_buf[SOC_MAX_MEM_FIELD_WORDS];
    225     initial_l3_ecmp_group_entry_t initial_l3_ecmp_group_entry;
    226     int max_grp_size = 0;  /* Maximum ecmp group size.*/
    227     int ecmpf = 0;
    228     int ecmp_idx; /* Ecmp table entry index. */
    229     int *nh_idx; /* Ecmp group nh indexes.  */
    230     int nh_cycle_idx;
    231     int idx = 0;  /* Iteration index.  */
    232     int rv = BCM_E_NONE; /* Operation return value. */
    233     int entry_type;
    234     int max_subgrp_cnt, subgrp_cnt, intf_count = 0;
    235     int l3_ecmp_oif_flds[8] = {  L3_OIF_0f, 
    236                              L3_OIF_1f, 
    237                              L3_OIF_2f, 
    238                              L3_OIF_3f, 
    239                              L3_OIF_4f, 
    240                              L3_OIF_5f, 
    241                              L3_OIF_6f, 
    242                              L3_OIF_7f }; 
    243     int l3_ecmp_oif_type_flds[8] = {  L3_OIF_0_TYPEf, 
    244                              L3_OIF_1_TYPEf, 
    245                              L3_OIF_2_TYPEf, 
    246                              L3_OIF_3_TYPEf, 
    247                              L3_OIF_4_TYPEf, 
    248                              L3_OIF_5_TYPEf, 
    249                              L3_OIF_6_TYPEf, 
    250                              L3_OIF_7_TYPEf };
    251     ing_l3_next_hop_entry_t ing_nh;
    252     uint32 reg_val, value;
    253     _bcm_l3_tbl_op_t data;
    254     soc_mem_t grp_mem = L3_ECMP_COUNTm;
    255 
    256 #ifdef BCM_TOMAHAWK_SUPPORT
    257     soc_field_t _initial_l3_ecmp_flag = ECMP_FLAGf;
    258     int defragment_direction = 0;
    259 #endif
    260     int ecmp_table_incr = 0;
    261     _bcm_l3_ecmp_group_info_t *ecmp_info = info;
    262     _bcm_l3_ecmp_group_buffer_t *ecmp_buffer = buf;
    263 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 
    264     int dgm_zero_hit = 0;
    265 #endif /* BCM_TOMAHAWK2_SUPPORT */
    266 
    267     char *l3_ecmp_tbl_ptr; /* Dma L3 ECMP table pointer. */
    268     uint32 *ecmp_entry_ptr = NULL; /* ECMP entry pointer.*/
    269     char *initial_l3_ecmp_tbl_ptr = NULL; /* Dma INITIAL L3 ECMP table pointer. */
    270     uint32 *initial_ecmp_entry_ptr = NULL; /* INITIAL ECMP entry pointer.*/
    271     void *ecmp_null_entry = NULL, *initial_ecmp_null_entry = NULL;
    272 
    273     /* Input parameters check. */
    274     if (NULL == ecmp_buffer || NULL == ecmp_info ||
    275         NULL == ecmp_buffer->group_buffer) {
    276         return (BCM_E_PARAM);
    277     }
    278 
    279 #ifdef BCM_TRIDENT3_SUPPORT
    280     if (SOC_IS_TRIDENT3X(unit)) {
    281        _initial_l3_ecmp_flag = ECMPf;
    282     }
    283 #endif
    284 
    285 #ifdef BCM_TOMAHAWK3_SUPPORT
    286     if ((soc_feature(unit, soc_feature_l3_ecmp_hier_tbl)) &&
    287          (ecmp_info->ecmp_flags & BCM_L3_ECMP_OVERLAY)) {
    288         grp_mem = ECMP_GROUP_HIERARCHICALm;
    289     }
    290 #endif
    291     /* Cast input buffer. */
    292     nh_idx = ecmp_buffer->group_buffer;
    293     max_grp_size = ecmp_info->max_paths;
    294 
    295     if (BCM_XGS3_L3_ENT_REF_CNT(BCM_XGS3_L3_TBL_PTR(unit,
    296                                 ecmp_grp), ecmp_grp)
    297 #ifdef BCM_TOMAHAWK3_SUPPORT
    298         || ((soc_feature(unit, soc_feature_l3_ecmp_hier_tbl)) &&
    299          (ecmp_info->ecmp_flags & BCM_L3_ECMP_OVERLAY) &&
    300         BCM_XGS3_L3_ENT_REF_CNT(BCM_XGS3_L3_TBL_PTR(unit,
    301                                 hecmp_grp), ecmp_grp))
    302 #endif
    303       ) {
    304         /* Group already exists, get base ptr from group table */ 
    305         BCM_IF_ERROR_RETURN(
    306             _bcm_xgs3_l3_ecmp_grp_info_get(unit, ecmp_grp, NULL, &ecmp_idx));
    307     } else {
    308         /* Get index to the first slot in the ECMP table
    309          * that can accomodate max_grp_size */
    310         data.width = ecmp_info->max_paths;
    311         data.tbl_ptr = BCM_XGS3_L3_TBL_PTR(unit, ecmp); 
    312         data.oper_flags = _BCM_L3_SHR_TABLE_TRAVERSE_CONTROL; 
    313 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
    314         /* 
    315          * we can look into the ecmp_grp index to know if this 
    316          * is overlay entry or underlay entry.
    317          */
    318         if (BCMI_L3_ECMP_IS_MULTI_LEVEL(unit)) {
    319             if (ecmp_grp < BCMI_L3_ECMP_OVERLAY_ENTRIES(unit)) {
    320 
    321                data.oper_flags |= _BCM_L3_SHR_OVERLAY_OBJECT;
    322             }
    323         }
    324 #endif
    325         data.entry_index = -1;
    326         rv = _bcm_xgs3_tbl_free_idx_get(unit, &data);
    327         if (rv == BCM_E_FULL) {
    328             /* Defragment ECMP table */
    329 #ifdef BCM_TOMAHAWK_SUPPORT
    330             /* Pass ECMP level so the defragmentation can happen in the
    331                right part of the ECMP table */
    332             if (soc_feature(unit, soc_feature_hierarchical_ecmp) &&
    333                 (BCM_XGS3_L3_TBL(unit, ecmp_info).ecmp_mode ==
    334                                      ecmp_mode_hierarchical)) {
    335                 if (data.tbl_ptr->idx_min > 0) {
    336                     /* De-fragment Level 2 or Underlay ECMP table */
    337                     BCM_IF_ERROR_RETURN(bcm_tr2_l3_ecmp_defragment_no_lock(unit, 2));
    338                     /* Further De-fragment if possible */
    339                     defragment_direction = 0;
    340                 } else if ((data.tbl_ptr->idx_min == 0) &&
    341                            (data.tbl_ptr->idx_max <
    342                             soc_mem_index_max(unit,L3_ECMPm))) {
    343                     /* De-fragment Level 1 or Overlay ECMP table */
    344                     BCM_IF_ERROR_RETURN(bcm_tr2_l3_ecmp_defragment_no_lock(unit, 1));
    345                     /* Further De-fragment if possible */
    346                     defragment_direction = 1;
    347                 } else {
    348                     /* 
    349                      * The current entry can go in anywhere in the ECMP table. 
    350                      * De-fragment the entire ECMP table
    351                      */
    352                     BCM_IF_ERROR_RETURN(bcm_tr2_l3_ecmp_defragment_no_lock(unit, 2));
    353                     BCM_IF_ERROR_RETURN(bcm_tr2_l3_ecmp_defragment_no_lock(unit, 1));
    354                     /* Further De-fragment if possible */
    355                     defragment_direction = 0;
    356                 }
    357             } else
    358 #endif /* BCM_TOMAHAWK_SUPPORT */
    359 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
    360             if (BCMI_L3_ECMP_IS_MULTI_LEVEL(unit)) {
    361                 if (data.oper_flags & _BCM_L3_SHR_OVERLAY_OBJECT) {
    362                     BCM_IF_ERROR_RETURN(
    363                         bcm_tr2_l3_ecmp_defragment_no_lock(unit, 2));
    364                 } else {
    365                     BCM_IF_ERROR_RETURN(
    366                         bcm_tr2_l3_ecmp_defragment_no_lock(unit, 1));
    367                 }
    368             } else
    369 #endif
    370             {
    371                 BCM_IF_ERROR_RETURN(bcm_tr2_l3_ecmp_defragment_no_lock(unit, 0));
    372             }
    373             /* Attempt to get free index again */
    374             rv = _bcm_xgs3_tbl_free_idx_get(unit, &data);
    375 #ifdef BCM_TOMAHAWK_SUPPORT
    376             if (soc_feature(unit, soc_feature_hierarchical_ecmp) &&
    377                 (BCM_XGS3_L3_TBL(unit, ecmp_info).ecmp_mode ==
    378                      ecmp_mode_hierarchical) && (rv == BCM_E_FULL)) {
    379                 /*
    380                  * Move the ECMP tables (which have flags 0)
    381                  * across two layers
    382                  */
    383                 BCM_IF_ERROR_RETURN(
    384                     _bcm_th_l3_ecmp_across_layers_move(unit, max_grp_size,
    385                                                        defragment_direction));
    386                 if (defragment_direction) {
    387                     /* L1 -> L2: further de-fragment on L1 */
    388                     BCM_IF_ERROR_RETURN(
    389                         bcm_tr2_l3_ecmp_defragment_no_lock(unit, 1));
    390                 } else {
    391                     /* L2 -> L1: further de-fragment on L2*/
    392                     BCM_IF_ERROR_RETURN(
    393                         bcm_tr2_l3_ecmp_defragment_no_lock(unit, 2));
    394                 }
    395 
    396                 BCM_IF_ERROR_RETURN(_bcm_xgs3_tbl_free_idx_get(unit, &data));
    397             } else
    398 #endif
    399             if (BCM_FAILURE(rv)) {
    400                 return rv;
    401             }
    402         } else if (BCM_FAILURE(rv)) {
    403             return rv;
    404         }
    405 
    406         ecmp_idx = data.entry_index;
    407         BCM_XGS3_L3_ENT_REF_CNT_INC(data.tbl_ptr, ecmp_idx, max_grp_size);
    408         ecmp_table_incr = 1;
    409 
    410     }
    411 
    412     sal_memset (hw_buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
    413     sal_memset (&initial_l3_ecmp_group_entry, 0,
    414             sizeof(initial_l3_ecmp_group_entry_t));
    415 
    416     if (max_grp_size > L3_ECMP_MEM_DMA_THRESHOLD) {
    417         rv = bcm_xgs3_l3_tbl_range_dma(unit, L3_ECMPm, sizeof(ecmp_entry_t),
    418                                        "l3_ecmp_tbl", ecmp_idx,
    419                                        ecmp_idx + max_grp_size - 1,
    420                                        &l3_ecmp_tbl_ptr);
    421         BCM_IF_ERROR_RETURN(rv);
    422         if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    423             rv = bcm_xgs3_l3_tbl_range_dma(unit, INITIAL_L3_ECMPm,
    424                                            sizeof(initial_l3_ecmp_entry_t),
    425                                            "initial_l3_ecmp_tbl", ecmp_idx,
    426                                            ecmp_idx + max_grp_size - 1,
    427                                            &initial_l3_ecmp_tbl_ptr);
    428             if (BCM_FAILURE(rv)) {
    429                 soc_cm_sfree(unit, l3_ecmp_tbl_ptr);
    430                 return rv;
    431             }
    432             initial_ecmp_null_entry = soc_mem_entry_null(unit, INITIAL_L3_ECMPm);
    433         }
    434 
    435         ecmp_null_entry = soc_mem_entry_null(unit, L3_ECMPm);
    436     }
    437 
    438     /* Write all the indexes to hw. */
    439     for (idx = 0, nh_cycle_idx = 0; idx < max_grp_size; idx++, nh_cycle_idx++) {
    440          /* Set next hop index. */
    441          if (max_grp_size > L3_ECMP_MEM_DMA_THRESHOLD) {
    442              ecmp_entry_ptr =
    443                  soc_mem_table_idx_to_pointer(unit, L3_ECMPm, uint32 *,
    444                                               l3_ecmp_tbl_ptr, idx);
    445              if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    446                  initial_ecmp_entry_ptr =
    447                      soc_mem_table_idx_to_pointer(unit, INITIAL_L3_ECMPm, uint32 *,
    448                                                   initial_l3_ecmp_tbl_ptr, idx);
    449                      sal_memcpy(initial_ecmp_entry_ptr, initial_ecmp_null_entry,
    450                                 sizeof(initial_l3_ecmp_entry_t));
    451              }
    452              sal_memcpy(ecmp_entry_ptr, ecmp_null_entry, sizeof(ecmp_entry_t));
    453          } else {
    454              sal_memset (l3_ecmp, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
    455              if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    456                  sal_memset (initial_l3_ecmp, 0,
    457                              SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
    458                  initial_ecmp_entry_ptr = initial_l3_ecmp;
    459              }
    460              ecmp_entry_ptr = l3_ecmp;
    461          }
    462 
    463         /* If this is the last nhop then program black-hole. */
    464 #ifdef BCM_TOMAHAWK_SUPPORT
    465         if (!(soc_feature(unit, soc_feature_ecmp_resilient_hash_optimized) &&
    466               (ecmp_info->ecmp_flags & BCM_L3_ECMP_RH_OPT)))
    467 #endif /* BCM_TOMAHAWK_SUPPORT */
    468         {
    469             if (!nh_idx[nh_cycle_idx]) {
    470                 if (!idx) {
    471                   nh_cycle_idx = 0;
    472                 } else {
    473 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
    474                     if (soc_feature(unit, soc_feature_dgm) &&
    475                         (ecmp_info->ecmp_flags & BCM_L3_ECMP_DGM_OPT)) {
    476                         /* primay entry exists or one more entry zeroed */
    477                         if (idx > ecmp_info->alternate_cnt || dgm_zero_hit) {
    478                             if (dgm_zero_hit) {
    479                             /* decrease idx to get real count */
    480                                 idx--;
    481                             }
    482                             break;
    483                         } else {
    484                             /* If there is no primary entry, zero one more entry */
    485                             dgm_zero_hit = 1;
    486                         }
    487                     } else
    488 #endif /* BCM_TOMAHAWK2_SUPPORT */
    489                     {
    490                         break;
    491                     }
    492                 }
    493             }
    494         }
    495         ecmpf = 0;
    496 #ifdef BCM_TOMAHAWK_SUPPORT
    497         /* Set ecmp flag if member is an ecmp group */
    498         if (soc_feature(unit, soc_feature_hierarchical_ecmp)) {
    499             if (BCM_XGS3_L3_MPATH_EGRESS_IDX_VALID(unit,
    500                                            nh_idx[nh_cycle_idx])) {
    501                 ecmpf = 1;
    502                 nh_idx[nh_cycle_idx] -= BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
    503                 if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    504                     soc_mem_field32_set(unit, L3_ECMPm, ecmp_entry_ptr,
    505                                         ECMP_FLAGf, 1);
    506                     soc_mem_field32_set(unit, INITIAL_L3_ECMPm,
    507                                         initial_ecmp_entry_ptr, _initial_l3_ecmp_flag, 1);
    508                 }
    509             }
    510         }
    511 #endif /* BCM_TOMAHAWK_SUPPORT */
    512 
    513 #ifdef BCM_MULTI_LEVEL_ECMP_SUPPORT
    514         /* Set ecmp flag if member is an ecmp group */
    515         if (soc_feature(unit, soc_feature_multi_level_ecmp)) {
    516             if (BCM_XGS3_L3_MPATH_EGRESS_IDX_VALID(unit,
    517                                            nh_idx[nh_cycle_idx])) {
    518                 nh_idx[nh_cycle_idx] -= BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
    519 #ifdef BCM_TRIDENT3_SUPPORT
    520                 if (SOC_IS_TRIDENT3X(unit)) {
    521                     soc_mem_field32_set(unit, L3_ECMPm, ecmp_entry_ptr, ECMP_FLAGf, 1);
    522                     ecmpf = 1;
    523                     soc_mem_field32_set(unit, INITIAL_L3_ECMPm,
    524                                     initial_ecmp_entry_ptr, ECMPf, 1);
    525                 } else 
    526 #endif
    527                 {
    528                     soc_mem_field32_set(unit, L3_ECMPm, ecmp_entry_ptr, ECMPf, 1);
    529                     if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    530                         soc_mem_field32_set(unit, INITIAL_L3_ECMPm,
    531                                             initial_ecmp_entry_ptr, ECMPf, 1);
    532                     }
    533                 }
    534             }
    535         }
    536 #endif /* BCM_MULTI_LEVEL_ECMP_SUPPORT */
    537 
    538 
    539          if (SOC_IS_TRIDENT3X(unit)) {
    540              soc_mem_field32_dest_set(unit, L3_ECMPm, ecmp_entry_ptr, DESTINATIONf, 
    541                                       ecmpf ? SOC_MEM_FIF_DEST_ECMP : SOC_MEM_FIF_DEST_NEXTHOP, 
    542                                       nh_idx[nh_cycle_idx]);
    543              soc_mem_field32_dest_set(unit, INITIAL_L3_ECMPm, initial_ecmp_entry_ptr, DESTINATIONf, 
    544                                       ecmpf ? SOC_MEM_FIF_DEST_ECMP : SOC_MEM_FIF_DEST_NEXTHOP, 
    545                                       nh_idx[nh_cycle_idx]);
    546          } else {
    547 
    548              soc_mem_field32_set(unit, L3_ECMPm, ecmp_entry_ptr, 
    549                                       NEXT_HOP_INDEXf, nh_idx[nh_cycle_idx]);
    550              if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    551                  soc_mem_field32_set(unit, INITIAL_L3_ECMPm, initial_ecmp_entry_ptr,
    552                                           NEXT_HOP_INDEXf, nh_idx[nh_cycle_idx]);
    553              }
    554          }
    555 
    556          /* Write buffer to hw L3_ECMPm table. */
    557          if (max_grp_size <= L3_ECMP_MEM_DMA_THRESHOLD) {
    558              rv = soc_mem_write(unit, L3_ECMPm, MEM_BLOCK_ALL,
    559                                     (ecmp_idx + idx), ecmp_entry_ptr);
    560 
    561              if (BCM_FAILURE(rv)) {
    562                   break;
    563              }
    564 
    565              if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    566                   /* Write buffer to hw INITIAL_L3_ECMPm table. */
    567                   rv = soc_mem_write(unit, INITIAL_L3_ECMPm, MEM_BLOCK_ALL,
    568                                            (ecmp_idx + idx), initial_ecmp_entry_ptr);
    569 
    570                   if (BCM_FAILURE(rv)) {
    571                        break;
    572                   }
    573              }
    574          }
    575 
    576          if (soc_feature(unit, soc_feature_urpf)) {
    577               /* Check if URPF is enabled on device */
    578               rv = READ_L3_DEFIP_RPF_CONTROLr(unit, &reg_val);
    579               if (BCM_FAILURE(rv)) {
    580                   if (max_grp_size > L3_ECMP_MEM_DMA_THRESHOLD) {
    581                       soc_cm_sfree(unit, l3_ecmp_tbl_ptr);
    582                       soc_cm_sfree(unit, initial_l3_ecmp_tbl_ptr);
    583                   }
    584                   return rv;
    585               }
    586 
    587               if (reg_val) {
    588                    if (idx < 8) {
    589                        rv = soc_mem_read(unit, ING_L3_NEXT_HOPm, MEM_BLOCK_ANY,
    590                                          nh_idx[idx], &ing_nh);
    591                        if (BCM_FAILURE(rv)) {
    592                            if (max_grp_size > L3_ECMP_MEM_DMA_THRESHOLD) {
    593                                soc_cm_sfree(unit, l3_ecmp_tbl_ptr);
    594                                soc_cm_sfree(unit, initial_l3_ecmp_tbl_ptr);
    595                            }
    596                            return rv;
    597                        }
    598 
    599                         entry_type = 
    600                           soc_ING_L3_NEXT_HOPm_field32_get(unit, 
    601                                &ing_nh, ENTRY_TYPEf);
    602 
    603                         if (entry_type == 0x0) {
    604                             if (SOC_MEM_FIELD_VALID(unit, ING_L3_NEXT_HOPm,
    605                                                     L3_OIFf)) {
    606                                 value = soc_ING_L3_NEXT_HOPm_field32_get(
    607                                             unit, &ing_nh, L3_OIFf);
    608                             } else {
    609                                 value = soc_ING_L3_NEXT_HOPm_field32_get(
    610                                             unit, &ing_nh, VLAN_IDf);
    611                             }
    612                              soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, 
    613                                             l3_ecmp_oif_type_flds[idx], entry_type);
    614                              soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, 
    615                                             l3_ecmp_oif_flds[idx], value);
    616                         } else if (entry_type == 0x1) {
    617                              value  = soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, L3_OIFf);
    618                              soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, 
    619                                             l3_ecmp_oif_type_flds[idx], entry_type);
    620                              soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, 
    621                                             l3_ecmp_oif_flds[idx], value);
    622                         }
    623                         soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, URPF_COUNTf, idx);
    624                    }else {
    625                        /* Inorder to avoid TRAP_TO_CPU, urpf_mode on L3_IIF/PORT must be set 
    626                            to STRICT_MODE / LOOSE_MODE */
    627                         soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, ECMP_GT8f , 1);
    628                    }
    629               }
    630          }
    631     }
    632     intf_count = idx;
    633     if (max_grp_size > L3_ECMP_MEM_DMA_THRESHOLD) {
    634         rv = soc_mem_write_range(unit, L3_ECMPm, MEM_BLOCK_ALL, ecmp_idx,
    635                                  ecmp_idx + max_grp_size - 1, l3_ecmp_tbl_ptr);
    636         if (BCM_SUCCESS(rv)) {
    637             if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    638                 rv = soc_mem_write_range(unit, INITIAL_L3_ECMPm, MEM_BLOCK_ALL,
    639                                          ecmp_idx, ecmp_idx + max_grp_size - 1,
    640                                          initial_l3_ecmp_tbl_ptr);
    641                 soc_cm_sfree(unit, initial_l3_ecmp_tbl_ptr);
    642             }
    643         }
    644         soc_cm_sfree(unit, l3_ecmp_tbl_ptr);
    645     }
    646 
    647     if (BCM_SUCCESS(rv)) {
    648         /* mode 0 = 512 ecmp groups */
    649         if (!BCM_XGS3_L3_MAX_ECMP_MODE(unit)) {
    650             /* Set Max Group Size. */
    651             sal_memset (l3_ecmp_count, 0,
    652                     SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
    653             if (soc_feature(unit, soc_feature_l3_ecmp_1k_groups) ||
    654                     SOC_IS_MONTEREY(unit)) {
    655                 rv = _bcm_xgs3_l3_ecmp_grp_info_set(unit, (ecmp_grp + 1),
    656                                                     l3_ecmp_count,
    657                                                     NULL, 0,
    658                                                     max_grp_size, -1, 0,
    659                                                     ecmp_info->ecmp_flags);
    660                 if (BCM_FAILURE(rv)) {
    661                     if (ecmp_table_incr == 1) {
    662                         BCM_XGS3_L3_ENT_REF_CNT_DEC(BCM_XGS3_L3_TBL_PTR(unit, ecmp),
    663                                                     ecmp_idx, max_grp_size);
    664                     }
    665                     return rv;
    666                 }
    667             } else {
    668                 if (soc_feature(unit, soc_feature_ecmp_1k_paths_4_subgroups) &&
    669                         (max_grp_size >= 256)) {
    670                     max_subgrp_cnt = ((max_grp_size + 3) / 4);
    671                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    672                             l3_ecmp_count, COUNT_0f, (max_subgrp_cnt - 1));
    673                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    674                             l3_ecmp_count, COUNT_1f, (max_subgrp_cnt - 1));
    675                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    676                             l3_ecmp_count, COUNT_2f, (max_subgrp_cnt - 1));
    677                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    678                             l3_ecmp_count, COUNT_3f,
    679                             ((max_grp_size - (3 * max_subgrp_cnt) - 1)));
    680 
    681                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    682                             l3_ecmp_count, BASE_PTR_0f, ecmp_idx);
    683                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    684                             l3_ecmp_count, BASE_PTR_1f,
    685                             (ecmp_idx + max_subgrp_cnt));
    686                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    687                             l3_ecmp_count, BASE_PTR_2f,
    688                             (ecmp_idx + (2 * max_subgrp_cnt)));
    689                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    690                             l3_ecmp_count, BASE_PTR_3f,
    691                             (ecmp_idx + (3 * max_subgrp_cnt)));
    692                 } else {
    693                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    694                             l3_ecmp_count, COUNT_0f, max_grp_size-1);
    695                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    696                             l3_ecmp_count, COUNT_1f, max_grp_size-1);
    697                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    698                             l3_ecmp_count, COUNT_2f, max_grp_size-1);
    699                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    700                             l3_ecmp_count, COUNT_3f, max_grp_size-1);
    701                 }
    702             }
    703             rv = soc_mem_write(unit, grp_mem, MEM_BLOCK_ALL,
    704                     (ecmp_grp+1), l3_ecmp_count);
    705 
    706             if (BCM_FAILURE(rv)) {
    707                 if (ecmp_table_incr == 1) {
    708                     BCM_XGS3_L3_ENT_REF_CNT_DEC(BCM_XGS3_L3_TBL_PTR(unit, ecmp),
    709                                                 ecmp_idx, max_grp_size);
    710                 }
    711                 return rv;
    712             }
    713         }
    714         if (soc_feature(unit, soc_feature_l3_ecmp_1k_groups) ||
    715                 SOC_IS_MONTEREY(unit)) {
    716             rv = _bcm_xgs3_l3_ecmp_grp_info_set(unit, ecmp_grp, hw_buf,
    717                                             &initial_l3_ecmp_group_entry, !soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp),
    718                                             idx, ecmp_idx, ecmp_info->alternate_cnt,
    719                                             ecmp_info->ecmp_flags);
    720             if (BCM_FAILURE(rv)) {
    721                 if (ecmp_table_incr == 1) {
    722                     BCM_XGS3_L3_ENT_REF_CNT_DEC(BCM_XGS3_L3_TBL_PTR(unit, ecmp),
    723                                                 ecmp_idx, max_grp_size);
    724                 }
    725                 return rv;
    726             }
    727         } else {
    728             if (!idx) {
    729                 soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, COUNT_0f, idx );
    730                 soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, COUNT_1f, idx );
    731                 soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, COUNT_2f, idx );
    732                 soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, COUNT_3f, idx );
    733 
    734                 if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    735                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    736                             &initial_l3_ecmp_group_entry, COUNT_0f, idx);
    737                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    738                             &initial_l3_ecmp_group_entry, COUNT_1f, idx);
    739                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    740                             &initial_l3_ecmp_group_entry, COUNT_2f, idx);
    741                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    742                             &initial_l3_ecmp_group_entry, COUNT_3f, idx);
    743                 }
    744             } else {
    745                 if (soc_feature(unit, soc_feature_ecmp_1k_paths_4_subgroups) &&
    746                         (intf_count >= 256)) {
    747                     subgrp_cnt = ((intf_count + 3) / 4);
    748                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    749                             hw_buf, COUNT_0f, (subgrp_cnt - 1));
    750                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    751                             hw_buf, COUNT_1f, (subgrp_cnt - 1));
    752                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    753                             hw_buf, COUNT_2f, (subgrp_cnt - 1));
    754                     soc_mem_field32_set(unit, L3_ECMP_COUNTm,
    755                             hw_buf, COUNT_3f,
    756                             (intf_count - (3 * subgrp_cnt) - 1));
    757 
    758                     if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    759                         soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    760                                 &initial_l3_ecmp_group_entry, COUNT_0f,
    761                                 (subgrp_cnt - 1));
    762                         soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    763                                 &initial_l3_ecmp_group_entry, COUNT_1f,
    764                                 (subgrp_cnt - 1));
    765                         soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    766                                 &initial_l3_ecmp_group_entry, COUNT_2f,
    767                                 (subgrp_cnt - 1));
    768                         soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    769                                 &initial_l3_ecmp_group_entry, COUNT_3f,
    770                                 (intf_count - (3 * subgrp_cnt) - 1));
    771                     }
    772                 } else {
    773 
    774                     soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, COUNT_0f, idx - 1);
    775                     soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, COUNT_1f, idx - 1);
    776                     soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, COUNT_2f, idx - 1);
    777                     soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf, COUNT_3f, idx - 1);
    778 
    779                     if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    780                         soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    781                                 &initial_l3_ecmp_group_entry, COUNT_0f, idx - 1);
    782                         soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    783                                 &initial_l3_ecmp_group_entry, COUNT_1f, idx - 1);
    784                         soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    785                                 &initial_l3_ecmp_group_entry, COUNT_2f, idx - 1);
    786                         soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    787                                 &initial_l3_ecmp_group_entry, COUNT_3f, idx - 1);
    788                     }
    789                 }
    790             }
    791 
    792             if (soc_feature(unit, soc_feature_ecmp_1k_paths_4_subgroups) &&
    793                     (intf_count >= 256)) {
    794                 subgrp_cnt = ((intf_count + 3) / 4);
    795                 soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    796                         BASE_PTR_0f, ecmp_idx);
    797                 soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    798                         BASE_PTR_1f, (ecmp_idx + subgrp_cnt));
    799                 soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    800                         BASE_PTR_2f, (ecmp_idx + (2 * subgrp_cnt)));
    801                 soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    802                         BASE_PTR_3f, (ecmp_idx + (3 * subgrp_cnt)));
    803 
    804                 if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    805                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm, &initial_l3_ecmp_group_entry,
    806                             BASE_PTR_0f, ecmp_idx);
    807                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm, &initial_l3_ecmp_group_entry,
    808                             BASE_PTR_1f, (ecmp_idx + subgrp_cnt));
    809                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm, &initial_l3_ecmp_group_entry,
    810                             BASE_PTR_2f, (ecmp_idx + (2 * subgrp_cnt)));
    811                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm, &initial_l3_ecmp_group_entry,
    812                             BASE_PTR_3f, (ecmp_idx + (3 * subgrp_cnt)));
    813                 }
    814             } else {
    815                 /* Set group base pointer. */
    816                 if (SOC_MEM_FIELD_VALID(unit, L3_ECMP_COUNTm, BASE_PTR_0f)) {
    817                     soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    818                             BASE_PTR_0f, ecmp_idx);
    819                 }
    820                 if (SOC_MEM_FIELD_VALID(unit, L3_ECMP_COUNTm, BASE_PTR_1f)) {
    821                     soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    822                             BASE_PTR_1f, ecmp_idx);
    823                 }
    824                 if (SOC_MEM_FIELD_VALID(unit, L3_ECMP_COUNTm, BASE_PTR_2f)) {
    825                     soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    826                             BASE_PTR_2f, ecmp_idx);
    827                 }
    828                 if (SOC_MEM_FIELD_VALID(unit, L3_ECMP_COUNTm, BASE_PTR_3f)) {
    829                     soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    830                             BASE_PTR_3f, ecmp_idx);
    831                 }
    832 
    833                 if (SOC_MEM_FIELD_VALID(unit, INITIAL_L3_ECMP_GROUPm, BASE_PTR_0f)) {
    834                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    835                             &initial_l3_ecmp_group_entry, BASE_PTR_0f, ecmp_idx);
    836                 }
    837                 if (SOC_MEM_FIELD_VALID(unit, INITIAL_L3_ECMP_GROUPm, BASE_PTR_1f)) {
    838                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    839                             &initial_l3_ecmp_group_entry, BASE_PTR_1f, ecmp_idx);
    840                 }
    841                 if (SOC_MEM_FIELD_VALID(unit, INITIAL_L3_ECMP_GROUPm, BASE_PTR_2f)) {
    842                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    843                             &initial_l3_ecmp_group_entry, BASE_PTR_2f, ecmp_idx);
    844                 }
    845                 if (SOC_MEM_FIELD_VALID(unit, INITIAL_L3_ECMP_GROUPm, BASE_PTR_3f)) {
    846                     soc_mem_field32_set(unit, INITIAL_L3_ECMP_GROUPm,
    847                             &initial_l3_ecmp_group_entry, BASE_PTR_3f, ecmp_idx);
    848                 }
    849             }
    850         }
    851 
    852         if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    853             rv = soc_mem_write(unit, INITIAL_L3_ECMP_GROUPm, MEM_BLOCK_ALL,
    854                     ecmp_grp, &initial_l3_ecmp_group_entry);
    855             if (BCM_FAILURE(rv) && (ecmp_table_incr == 1)) {
    856                 BCM_XGS3_L3_ENT_REF_CNT_DEC
    857                     (BCM_XGS3_L3_TBL_PTR(unit, ecmp), ecmp_idx, max_grp_size);
    858                 return rv;
    859             }
    860         }
    861 
    862 #ifdef BCM_TRIDENT2_SUPPORT
    863         /* Preserve the fields related to resilient hashing */
    864         if (soc_feature(unit, soc_feature_ecmp_resilient_hash)) {
    865             ecmp_count_entry_t old_ecmp_count_entry;
    866             int enhanced_hashing_enable;
    867             int rh_flow_set_base;
    868             int rh_flow_set_size;
    869 
    870             SOC_IF_ERROR_RETURN(READ_L3_ECMP_COUNTm(unit, MEM_BLOCK_ANY,
    871                         ecmp_grp, &old_ecmp_count_entry));
    872             if (soc_feature(unit, soc_feature_td3_style_dlb_rh)){
    873                 enhanced_hashing_enable = soc_mem_field32_get(unit, L3_ECMP_COUNTm,
    874                         &old_ecmp_count_entry, LB_MODEf);
    875             } else {
    876                 enhanced_hashing_enable = soc_mem_field32_get(unit, L3_ECMP_COUNTm,
    877                         &old_ecmp_count_entry, ENHANCED_HASHING_ENABLEf);
    878             }
    879             rh_flow_set_base = soc_mem_field32_get(unit, L3_ECMP_COUNTm,
    880                     &old_ecmp_count_entry, RH_FLOW_SET_BASEf);
    881             rh_flow_set_size = soc_mem_field32_get(unit, L3_ECMP_COUNTm,
    882                     &old_ecmp_count_entry, RH_FLOW_SET_SIZEf);
    883             if (soc_feature(unit, soc_feature_td3_style_dlb_rh)){
    884                 soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    885                         LB_MODEf, enhanced_hashing_enable);
    886             } else {
    887                 soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    888                         ENHANCED_HASHING_ENABLEf, enhanced_hashing_enable);
    889             }
    890             soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    891                     RH_FLOW_SET_BASEf, rh_flow_set_base);
    892             soc_mem_field32_set(unit, L3_ECMP_COUNTm, hw_buf,
    893                     RH_FLOW_SET_SIZEf, rh_flow_set_size);
    894         }
    895 #endif /* BCM_TRIDENT2_SUPPORT */
    896 
    897 #ifdef BCM_TOMAHAWK_SUPPORT
    898 /* Write Load Balancing Mode fields */
    899         if (soc_feature(unit, soc_feature_ecmp_resilient_hash_optimized)
    900             && !(ecmp_info->ecmp_flags & BCM_L3_ECMP_WEIGHTED)) {
    901             ecmp_count_entry_t old_ecmp_count_entry;
    902             int lb_mode;
    903             SOC_IF_ERROR_RETURN(soc_mem_read(unit, grp_mem, MEM_BLOCK_ANY,
    904                          ecmp_grp, &old_ecmp_count_entry));
    905             lb_mode = soc_mem_field32_get(unit, grp_mem,
    906                      &old_ecmp_count_entry, LB_MODEf);
    907             soc_mem_field32_set(unit, grp_mem, hw_buf,
    908                      LB_MODEf, lb_mode);
    909         }
    910 #endif /* BCM_TOMAHAWK_SUPPORT */
    911 
    912         rv = soc_mem_write(unit, grp_mem, MEM_BLOCK_ALL,
    913                 ecmp_grp, hw_buf);
    914 
    915         /* mode 1 = max possible ecmp groups */
    916         if (BCM_XGS3_L3_MAX_ECMP_MODE(unit)) {
    917             /* Save the max possible paths for this ECMP group in s/w */ 
    918             BCM_XGS3_L3_MAX_PATHS_PERGROUP_PTR(unit)[ecmp_grp] = ecmp_info->max_paths;
    919         }
    920     }
    921 
    922     if (BCM_FAILURE(rv)) {
    923         if (ecmp_table_incr == 1) {
    924             BCM_XGS3_L3_ENT_REF_CNT_DEC(BCM_XGS3_L3_TBL_PTR(unit, ecmp), 
    925                                         ecmp_idx, max_grp_size);
    926         }
    927     }
    928     return rv;
    929 }
    930 
    931 
    932 /*
    933  * Function:
    934  *      _bcm_td_l3_ecmp_grp_del
    935  * Purpose:
    936  *      Reset ecmp group next hop members
    937  * Parameters:
    938  *      unit       - (IN)SOC unit number.
    939  *      ecmp_grp   - (IN)ecmp group id to write.
    940  *      info       - (IN)ECMP additional info
    941  * Returns:
    942  *      BCM_E_XXX
    943  */
    944 int
    945 _bcm_td_l3_ecmp_grp_del (int unit, int ecmp_grp, void *info)
    946 {
    947     uint32 hw_buf[SOC_MAX_MEM_FIELD_WORDS]; /* Buffer to write hw entry.*/
    948     int ecmp_idx = 0; /* Ecmp table entry index. */
    949     int idx; /* Iteration index. */
    950     int rv = BCM_E_UNAVAIL; /* Operation return value. */
    951     _bcm_l3_tbl_op_t data;
    952     soc_mem_t mem = L3_ECMP_COUNTm;
    953 
    954     data.tbl_ptr = BCM_XGS3_L3_TBL_PTR(unit, ecmp); 
    955 
    956     if (NULL == info) {
    957         return BCM_E_INTERNAL;
    958     }
    959     /* Initialize ecmp entry. */
    960     sal_memset (hw_buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
    961 
    962     /* Calculate table index. */
    963 #ifdef BCM_TOMAHAWK3_SUPPORT
    964     if ((soc_feature(unit, soc_feature_l3_ecmp_hier_tbl)) &&
    965         (BCM_XGS3_L3_TBL(unit, ecmp_info).ecmp_mode ==
    966                                          ecmp_mode_hierarchical) &&
    967         (ecmp_grp < (BCM_XGS3_L3_ECMP_MAX_GROUPS(unit) / 2))) {
    968         mem = ECMP_GROUP_HIERARCHICALm;
    969     }
    970 #endif
    971 
    972     BCM_IF_ERROR_RETURN(
    973         _bcm_xgs3_l3_ecmp_grp_info_get(unit, ecmp_grp, NULL, &ecmp_idx));
    974 
    975     /* Write all the indexes to hw. */
    976     for (idx = 0; idx < ((_bcm_l3_ecmp_group_info_t*)info)->max_paths; idx++) {
    977         /* Write buffer to hw. */
    978         rv = soc_mem_write(unit, L3_ECMPm, MEM_BLOCK_ALL, 
    979                 (ecmp_idx + idx), hw_buf);
    980         if (BCM_FAILURE(rv)) {
    981             return rv;
    982         }
    983         /* Write buffer to hw INITIAL_L3_ECMPm table. */
    984         if (!soc_feature(unit, soc_feature_post_ifp_single_stage_ecmp)) {
    985             rv = soc_mem_write(unit, INITIAL_L3_ECMPm, MEM_BLOCK_ALL,
    986                     (ecmp_idx + idx), hw_buf);
    987 
    988             if (BCM_FAILURE(rv)) {
    989                 return rv;
    990             }
    991         }
    992     }
    993 
    994     /* Decrement ref count for the entries in ecmp table
    995      * Ref count for ecmp_group table is decremented in common table del func. */
    996     BCM_XGS3_L3_ENT_REF_CNT_DEC(data.tbl_ptr, ecmp_idx,
    997                                 ((_bcm_l3_ecmp_group_info_t*)info)->max_paths);
    998 
    999     if (SOC_MEM_IS_VALID(unit, mem)) {
   1000         /* Set group base pointer. */
   1001         ecmp_idx = ecmp_grp;
   1002 
   1003         if (SOC_MEM_IS_VALID(unit, INITIAL_L3_ECMP_GROUPm)) {
   1004             rv = soc_mem_write(unit, INITIAL_L3_ECMP_GROUPm, MEM_BLOCK_ALL,
   1005                     ecmp_idx, hw_buf);
   1006             BCM_IF_ERROR_RETURN(rv);
   1007         }
   1008 
   1009         if (!BCM_XGS3_L3_MAX_ECMP_MODE(unit)) {
   1010             rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   1011                     (ecmp_idx+1), hw_buf);
   1012             BCM_IF_ERROR_RETURN(rv);
   1013         }
   1014 
   1015 #ifdef BCM_TRIDENT2_SUPPORT
   1016         /* Preserve the fields related to resilient hashing */
   1017         if (soc_feature(unit, soc_feature_ecmp_resilient_hash)) {
   1018             ecmp_count_entry_t old_ecmp_count_entry;
   1019             int enhanced_hashing_enable;
   1020             int rh_flow_set_base;
   1021             int rh_flow_set_size;
   1022 
   1023             SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   1024                         ecmp_grp, &old_ecmp_count_entry));
   1025             if (soc_feature(unit, soc_feature_td3_style_dlb_rh)){
   1026                 enhanced_hashing_enable = soc_mem_field32_get(unit, mem,
   1027                          &old_ecmp_count_entry, LB_MODEf);
   1028             } else {
   1029                 enhanced_hashing_enable = soc_mem_field32_get(unit, mem,
   1030                          &old_ecmp_count_entry, ENHANCED_HASHING_ENABLEf);
   1031             }
   1032             rh_flow_set_base = soc_mem_field32_get(unit, mem,
   1033                     &old_ecmp_count_entry, RH_FLOW_SET_BASEf);
   1034             rh_flow_set_size = soc_mem_field32_get(unit, mem,
   1035                     &old_ecmp_count_entry, RH_FLOW_SET_SIZEf);
   1036             if (soc_feature(unit, soc_feature_td3_style_dlb_rh)){
   1037                 soc_mem_field32_set(unit, mem, hw_buf,
   1038                         LB_MODEf, enhanced_hashing_enable);
   1039             } else {
   1040                 soc_mem_field32_set(unit, mem, hw_buf,
   1041                         ENHANCED_HASHING_ENABLEf, enhanced_hashing_enable);
   1042             }
   1043             soc_mem_field32_set(unit, mem, hw_buf,
   1044                     RH_FLOW_SET_BASEf, rh_flow_set_base);
   1045             soc_mem_field32_set(unit, mem, hw_buf,
   1046                     RH_FLOW_SET_SIZEf, rh_flow_set_size);
   1047         }
   1048 #endif /* BCM_TRIDENT2_SUPPORT */
   1049 
   1050 #ifdef BCM_TOMAHAWK_SUPPORT
   1051         /* LB field set */
   1052         if (soc_feature(unit, soc_feature_ecmp_resilient_hash_optimized)) {
   1053             ecmp_count_entry_t old_ecmp_count_entry;
   1054             int lb_mode;
   1055 
   1056             SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   1057                         ecmp_grp, &old_ecmp_count_entry));
   1058             lb_mode = soc_mem_field32_get(unit, mem,
   1059                     &old_ecmp_count_entry, LB_MODEf);
   1060             soc_mem_field32_set(unit, mem, hw_buf,
   1061                     LB_MODEf, lb_mode);
   1062         }
   1063 #endif /* BCM_TOMAHAWK_SUPPORT */
   1064 
   1065         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   1066                 ecmp_idx, hw_buf);
   1067         BCM_IF_ERROR_RETURN(rv);
   1068     }
   1069 
   1070     if (BCM_XGS3_L3_MAX_ECMP_MODE(unit) &&
   1071         BCM_XGS3_L3_MAX_PATHS_PERGROUP_PTR(unit)) {
   1072         /* Reset max paths of the deleted group */
   1073         BCM_XGS3_L3_MAX_PATHS_PERGROUP_PTR(unit)[ecmp_grp] = 0;
   1074     }
   1075 
   1076     return rv;
   1077 }
   1078 
   1079 /*
   1080  * Function:
   1081  *      _bcm_td_l3_intf_qos_set
   1082  * Purpose:
   1083  *      Set L3 Interface QoS parameters
   1084  * Parameters:
   1085  *      unit      - (IN)SOC unit number.
   1086  *      l3_if_entry_p - (IN) Pointer to buffer
   1087  *      vid       - (IN) Intf_info
   1088  * Returns:
   1089  *      BCM_E_XXX.
   1090  */
   1091 int
   1092 _bcm_td_l3_intf_qos_set(int unit, uint32 *l3_if_entry_p, _bcm_l3_intf_cfg_t *intf_info)
   1093 {
   1094     int hw_map_idx=0;
   1095 
   1096     /* Input parameters check */
   1097     if (NULL == intf_info) {
   1098         return (BCM_E_PARAM);
   1099     }
   1100 
   1101     if (intf_info->vlan_qos.flags & BCM_L3_INTF_QOS_OUTER_VLAN_PRI_COPY) {
   1102          if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) {
   1103               soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, OPRI_OCFI_SELf, 0x0);
   1104          }
   1105     } else if (intf_info->vlan_qos.flags & BCM_L3_INTF_QOS_OUTER_VLAN_PRI_SET) {
   1106          if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) {
   1107               soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, OPRI_OCFI_SELf, 0x1);
   1108               soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, OPRIf,
   1109                                             intf_info->vlan_qos.pri);
   1110               soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, OCFIf,
   1111                                             intf_info->vlan_qos.cfi);
   1112          }
   1113     } else if (intf_info->vlan_qos.flags & BCM_L3_INTF_QOS_OUTER_VLAN_PRI_REMARK) {
   1114 
   1115          if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) {
   1116               soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, OPRI_OCFI_SELf, 0x2);
   1117          }
   1118          if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_MAPPING_PROFILEf)) {
   1119               BCM_IF_ERROR_RETURN
   1120                (_bcm_tr2_qos_id2idx(unit, intf_info->vlan_qos.qos_map_id, &hw_map_idx));
   1121               soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, 
   1122                              OPRI_OCFI_MAPPING_PROFILEf, hw_map_idx);
   1123          }
   1124     }
   1125 
   1126     if (intf_info->inner_vlan_qos.flags & BCM_L3_INTF_QOS_INNER_VLAN_PRI_COPY) {
   1127        if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, IPRI_ICFI_SELf)) {
   1128            soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, IPRI_ICFI_SELf, 0x0);
   1129        }
   1130    } else if (intf_info->inner_vlan_qos.flags & BCM_L3_INTF_QOS_INNER_VLAN_PRI_SET) {
   1131        if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, IPRI_ICFI_SELf)) {
   1132            soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, IPRI_ICFI_SELf, 0x1);
   1133            soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, IPRIf,
   1134                         intf_info->inner_vlan_qos.pri);
   1135            soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, ICFIf,
   1136                         intf_info->inner_vlan_qos.cfi);
   1137        }
   1138    } else if (intf_info->inner_vlan_qos.flags & BCM_L3_INTF_QOS_INNER_VLAN_PRI_REMARK) {
   1139        if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, IPRI_ICFI_SELf)) {
   1140            soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, IPRI_ICFI_SELf, 0x2);
   1141        }
   1142        if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, IPRI_ICFI_MAPPING_PROFILEf)) {
   1143            BCM_IF_ERROR_RETURN
   1144               (_bcm_tr2_qos_id2idx(unit, intf_info->inner_vlan_qos.qos_map_id, &hw_map_idx));
   1145            soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, 
   1146                         IPRI_ICFI_MAPPING_PROFILEf, hw_map_idx);
   1147        }
   1148    }
   1149 
   1150     if (intf_info->dscp_qos.flags & BCM_L3_INTF_QOS_DSCP_COPY) {
   1151          if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, DSCP_SELf)) {
   1152               soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, DSCP_SELf, 0x0);
   1153          }
   1154     } else if (intf_info->dscp_qos.flags & BCM_L3_INTF_QOS_DSCP_SET) {
   1155          if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, DSCP_SELf)) {
   1156               soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, DSCP_SELf, 0x1);
   1157               soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, DSCPf,
   1158                                             intf_info->dscp_qos.dscp);
   1159          }
   1160     } else if (intf_info->dscp_qos.flags & BCM_L3_INTF_QOS_DSCP_REMARK) {
   1161          if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, DSCP_SELf)) {
   1162               soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, DSCP_SELf, 0x2);
   1163          }
   1164          if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, DSCP_MAPPING_PTRf)) {
   1165               BCM_IF_ERROR_RETURN
   1166                (_bcm_tr2_qos_id2idx(unit, intf_info->dscp_qos.qos_map_id, &hw_map_idx));
   1167               soc_mem_field32_set(unit, EGR_L3_INTFm, l3_if_entry_p, 
   1168                              DSCP_MAPPING_PTRf, hw_map_idx);
   1169          }
   1170     }
   1171     return BCM_E_NONE;
   1172 }
   1173 
   1174 /*
   1175  * Function:
   1176  *      _bcm_td_l3_intf_qos_get
   1177  * Purpose:
   1178  *      Get L3 Interface QoS parameters
   1179  * Parameters:
   1180  *      unit      - (IN)SOC unit number.
   1181 *       l3_if_entry_p - entry buffer
   1182  *      vid       - (IN) Intf_info
   1183  * Returns:
   1184  *      BCM_E_XXX.
   1185  */
   1186 int
   1187 _bcm_td_l3_intf_qos_get(int unit, uint32 *l3_if_entry_p, _bcm_l3_intf_cfg_t *intf_info)
   1188 {
   1189 
   1190     /* Input parameters check */
   1191     if (NULL == intf_info) {
   1192         return (BCM_E_PARAM);
   1193     }
   1194 
   1195     if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) {
   1196        if (soc_mem_field32_get(unit, EGR_L3_INTFm,
   1197                 l3_if_entry_p, OPRI_OCFI_SELf) == 0x0) {
   1198               intf_info->vlan_qos.flags |= BCM_L3_INTF_QOS_OUTER_VLAN_PRI_COPY;
   1199        } else if (soc_mem_field32_get(unit, EGR_L3_INTFm,
   1200                 l3_if_entry_p, OPRI_OCFI_SELf) == 0x1) {
   1201               intf_info->vlan_qos.flags |= BCM_L3_INTF_QOS_OUTER_VLAN_PRI_SET;
   1202               intf_info->vlan_qos.pri = 
   1203                    soc_mem_field32_get(unit, EGR_L3_INTFm, l3_if_entry_p, OPRIf);
   1204               intf_info->vlan_qos.cfi = 
   1205                    soc_mem_field32_get(unit, EGR_L3_INTFm, l3_if_entry_p, OCFIf);
   1206        } else if (soc_mem_field32_get(unit, EGR_L3_INTFm,
   1207                 l3_if_entry_p, OPRI_OCFI_SELf) == 0x2) {
   1208               intf_info->vlan_qos.flags |= BCM_L3_INTF_QOS_OUTER_VLAN_PRI_REMARK;
   1209               BCM_IF_ERROR_RETURN
   1210                    (_bcm_tr2_qos_idx2id(unit, 
   1211                         soc_mem_field32_get(unit, EGR_L3_INTFm, l3_if_entry_p,
   1212                                 OPRI_OCFI_MAPPING_PROFILEf), 0x2,
   1213                         &intf_info->vlan_qos.qos_map_id));
   1214         }
   1215     }
   1216 
   1217     if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, IPRI_ICFI_SELf)) {
   1218        if (soc_mem_field32_get(unit, EGR_L3_INTFm,
   1219                 l3_if_entry_p, IPRI_ICFI_SELf) == 0x0) {
   1220               intf_info->inner_vlan_qos.flags |= BCM_L3_INTF_QOS_INNER_VLAN_PRI_COPY;
   1221        } else if (soc_mem_field32_get(unit, EGR_L3_INTFm,
   1222                 l3_if_entry_p, IPRI_ICFI_SELf) == 0x1) {
   1223               intf_info->inner_vlan_qos.flags |= BCM_L3_INTF_QOS_INNER_VLAN_PRI_SET;
   1224               intf_info->inner_vlan_qos.pri = 
   1225                    soc_mem_field32_get(unit, EGR_L3_INTFm, l3_if_entry_p, IPRIf);
   1226               intf_info->inner_vlan_qos.cfi = 
   1227                    soc_mem_field32_get(unit, EGR_L3_INTFm, l3_if_entry_p, ICFIf);
   1228        } else if (soc_mem_field32_get(unit, EGR_L3_INTFm,
   1229                 l3_if_entry_p, IPRI_ICFI_SELf) == 0x2) {
   1230               intf_info->inner_vlan_qos.flags |= BCM_L3_INTF_QOS_INNER_VLAN_PRI_REMARK;
   1231               BCM_IF_ERROR_RETURN
   1232                    (_bcm_tr2_qos_idx2id(unit, 
   1233                         soc_mem_field32_get(unit, EGR_L3_INTFm, l3_if_entry_p,
   1234                                 IPRI_ICFI_MAPPING_PROFILEf), 0x2,
   1235                         &intf_info->inner_vlan_qos.qos_map_id));
   1236         }
   1237     }
   1238 
   1239 
   1240     if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, DSCP_SELf)) {
   1241          if (soc_mem_field32_get(unit, EGR_L3_INTFm,
   1242                   l3_if_entry_p, DSCP_SELf) == 0x0) {
   1243               intf_info->dscp_qos.flags |= BCM_L3_INTF_QOS_DSCP_COPY;
   1244          } else if (soc_mem_field32_get(unit, EGR_L3_INTFm,
   1245                   l3_if_entry_p, DSCP_SELf) == 0x1) {
   1246               intf_info->dscp_qos.flags |= BCM_L3_INTF_QOS_DSCP_SET;
   1247               intf_info->dscp_qos.dscp = 
   1248                    soc_mem_field32_get(unit, EGR_L3_INTFm, l3_if_entry_p, DSCPf);
   1249          } else if (soc_mem_field32_get(unit, EGR_L3_INTFm,
   1250                   l3_if_entry_p, DSCP_SELf) == 0x2) {
   1251               intf_info->dscp_qos.flags |= BCM_L3_INTF_QOS_DSCP_REMARK;
   1252               BCM_IF_ERROR_RETURN
   1253                    (_bcm_tr2_qos_idx2id(unit, 
   1254                         soc_mem_field32_get(unit, EGR_L3_INTFm, l3_if_entry_p,
   1255                                 DSCP_MAPPING_PTRf), 0x4,
   1256                         &intf_info->dscp_qos.qos_map_id));
   1257          }
   1258     } 
   1259     return BCM_E_NONE;
   1260 }
   1261 
   1262 /*
   1263  * Function:
   1264  *      _bcm_td_l3_routed_int_pri_init
   1265  * Purpose:
   1266  *      Set L3 Routed Internal Priority
   1267  * Parameters:
   1268  *      unit      - (IN)SOC unit number.
   1269  * Returns:
   1270  *      BCM_E_XXX.
   1271  */
   1272 
   1273 int
   1274 _bcm_td_l3_routed_int_pri_init (int unit)
   1275 {
   1276    int rv=BCM_E_NONE;
   1277    int idx; /* Iteration index. */
   1278    int max_ent_count=0; /* Number of entries to read.*/
   1279    ing_routed_int_pri_mapping_entry_t   int_pri_entry;
   1280 
   1281 
   1282     if(soc_mem_is_valid(unit, ING_ROUTED_INT_PRI_MAPPINGm)) {
   1283        max_ent_count = soc_mem_index_count(unit, ING_ROUTED_INT_PRI_MAPPINGm);
   1284 
   1285        for(idx=0; idx<max_ent_count; idx++) {
   1286 
   1287             sal_memset(&int_pri_entry, 0, sizeof(ing_routed_int_pri_mapping_entry_t));
   1288 
   1289             soc_mem_field32_set(unit, ING_ROUTED_INT_PRI_MAPPINGm, &int_pri_entry,
   1290                        NEW_INT_PRIf, idx);
   1291 
   1292             rv = soc_mem_write(unit, ING_ROUTED_INT_PRI_MAPPINGm,
   1293                        MEM_BLOCK_ALL, idx, &int_pri_entry);
   1294 
   1295             if (rv < 0) {
   1296                 return rv;
   1297             }
   1298        }
   1299     }
   1300     return rv;
   1301 }
   1302 
   1303 #else /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
   1304 int bcm_esw_trident_l3_not_empty;
   1305 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
   1306